initial support for __[u]int128_t, which should be basically
compatible with VC++ and GCC.  The codegen/mangling angle hasn't
been fully ironed out yet.  Note that we accept int128_t even in
32-bit mode, unlike gcc.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70464 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 58fc42b..6cd016c 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -251,6 +251,10 @@
   InitBuiltinType(DoubleTy,            BuiltinType::Double);
   InitBuiltinType(LongDoubleTy,        BuiltinType::LongDouble);
 
+  // GNU extension, 128-bit integers.
+  InitBuiltinType(Int128Ty,            BuiltinType::Int128);
+  InitBuiltinType(UnsignedInt128Ty,    BuiltinType::UInt128);
+
   if (LangOpts.CPlusPlus) // C++ 3.9.1p5
     InitBuiltinType(WCharTy,           BuiltinType::WChar);
   else // C99
@@ -421,6 +425,13 @@
       Width = Target.getLongDoubleWidth();
       Align = Target.getLongDoubleAlign();
       break;
+    case BuiltinType::Int128:
+    case BuiltinType::UInt128:
+      Width = 128;
+          
+      // FIXME: Is this correct for all targets?
+      Align = 128;
+      break;
     }
     break;
   case Type::FixedWidthInt:
@@ -1923,6 +1934,9 @@
   case BuiltinType::LongLong:
   case BuiltinType::ULongLong:
     return 6 + (getIntWidth(LongLongTy) << 3);
+  case BuiltinType::Int128:
+  case BuiltinType::UInt128:
+    return 7 + (getIntWidth(Int128Ty) << 3);
   }
 }
 
@@ -2291,6 +2305,7 @@
           encoding = 
             (const_cast<ASTContext *>(this))->getIntWidth(T) == 32 ? 'L' : 'Q'; 
           break;
+      case BuiltinType::UInt128:    encoding = 'T'; break;
       case BuiltinType::ULongLong:  encoding = 'Q'; break;
       case BuiltinType::Char_S:
       case BuiltinType::SChar:      encoding = 'c'; break;
@@ -2301,6 +2316,7 @@
           (const_cast<ASTContext *>(this))->getIntWidth(T) == 32 ? 'l' : 'q'; 
         break;
       case BuiltinType::LongLong:   encoding = 'q'; break;
+      case BuiltinType::Int128:     encoding = 't'; break;
       case BuiltinType::Float:      encoding = 'f'; break;
       case BuiltinType::Double:     encoding = 'd'; break;
       case BuiltinType::LongDouble: encoding = 'd'; break;
@@ -3244,6 +3260,8 @@
     return UnsignedLongTy;
   case BuiltinType::LongLong:
     return UnsignedLongLongTy;
+  case BuiltinType::Int128:
+    return UnsignedInt128Ty;
   default:
     assert(0 && "Unexpected signed integer type");
     return QualType();
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 0331bbf..d6cf4bd 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -584,7 +584,7 @@
 bool Type::isIntegerType() const {
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
     return BT->getKind() >= BuiltinType::Bool &&
-           BT->getKind() <= BuiltinType::LongLong;
+           BT->getKind() <= BuiltinType::Int128;
   if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
     // Incomplete enum types are not treated as integer types.
     // FIXME: In C++, enum types are never integer types.
@@ -901,11 +901,13 @@
   case Int:               return "int";
   case Long:              return "long";
   case LongLong:          return "long long";
+  case Int128:            return "__int128_t";
   case UChar:             return "unsigned char";
   case UShort:            return "unsigned short";
   case UInt:              return "unsigned int";
   case ULong:             return "unsigned long";
   case ULongLong:         return "unsigned long long";
+  case UInt128:           return "__uint128_t";
   case Float:             return "float";
   case Double:            return "double";
   case LongDouble:        return "long double";