]> granicus.if.org Git - clang/commitdiff
For PR11916: Add support for g++'s __int128 keyword. Unlike __int128_t, this is
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 4 Apr 2012 06:24:32 +0000 (06:24 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 4 Apr 2012 06:24:32 +0000 (06:24 +0000)
a type specifier and can be combined with unsigned. This allows libstdc++4.7 to
be used with clang in c++98 mode.

Several other changes are still required for libstdc++4.7 to work with clang in
c++11 mode.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153999 91177308-0d34-0410-b5e6-96231b3b80d8

14 files changed:
INPUTS/all-std-headers.cpp
include/clang/Basic/Specifiers.h
include/clang/Basic/TokenKinds.def
include/clang/Sema/DeclSpec.h
lib/AST/Type.cpp
lib/Parse/ParseDecl.cpp
lib/Parse/ParseExpr.cpp
lib/Parse/ParseExprCXX.cpp
lib/Parse/ParseTentative.cpp
lib/Sema/DeclSpec.cpp
lib/Sema/SemaTemplateVariadic.cpp
lib/Sema/SemaType.cpp
test/Sema/128bitint.c
test/Sema/types.c

index 13e378dfc9f1d605c46554a30a61103aa5b8a77b..5f13b9d5e8a4d1840c02499ca4f19ba04d239749 100644 (file)
@@ -44,7 +44,9 @@
 #include <stdexcept>
 #include <streambuf>
 #include <string>
-#include <strstream> 
+#if __has_include(<strstream>)
+#include <strstream>
+#endif
 #include <typeinfo>
 #include <utility>
 #include <valarray>
index ec0cd333f893aaf196d3bcd5ca3c8f7bb09bdc05..9e71827b67bce28eeec1a9b5bdbe7bbc0057f4f6 100644 (file)
@@ -40,6 +40,7 @@ namespace clang {
     TST_char16,       // C++0x char16_t
     TST_char32,       // C++0x char32_t
     TST_int,
+    TST_int128,
     TST_half,         // OpenCL half, ARM NEON __fp16
     TST_float,
     TST_double,
index d7e081f834f0218079de5b2872f3d74737b46cbb..2e4d34dff0ba5596366440b2722604481e2e2133 100644 (file)
@@ -332,6 +332,7 @@ KEYWORD(__builtin_types_compatible_p, KEYALL)
 KEYWORD(__builtin_va_arg            , KEYALL)
 KEYWORD(__extension__               , KEYALL)
 KEYWORD(__imag                      , KEYALL)
+KEYWORD(__int128                    , KEYALL)
 KEYWORD(__label__                   , KEYALL)
 KEYWORD(__real                      , KEYALL)
 KEYWORD(__thread                    , KEYALL)
index f147950f18e3eac069753f4aaf6bc31ef4f5b60f..67fd3939f35de392343fbb55d71c6cc383eccf15 100644 (file)
@@ -245,6 +245,7 @@ public:
   static const TST TST_char16 = clang::TST_char16;
   static const TST TST_char32 = clang::TST_char32;
   static const TST TST_int = clang::TST_int;
+  static const TST TST_int128 = clang::TST_int128;
   static const TST TST_half = clang::TST_half;
   static const TST TST_float = clang::TST_float;
   static const TST TST_double = clang::TST_double;
index c61f34f254d17f4913b4d04f87412f77ffc182fb..c82aeaadd492294c7dd84858c5f9d1a3c8196772 100644 (file)
@@ -1428,13 +1428,13 @@ const char *BuiltinType::getName(const PrintingPolicy &Policy) const {
   case Int:               return "int";
   case Long:              return "long";
   case LongLong:          return "long long";
-  case Int128:            return "__int128_t";
+  case Int128:            return "__int128";
   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 UInt128:           return "unsigned __int128";
   case Half:              return "half";
   case Float:             return "float";
   case Double:            return "double";
index 03f41a098051b0b706383ed36022e99fef58ef59..9216b23d316b2b1f54ef60e04fc246cb0ef322c5 100644 (file)
@@ -207,6 +207,7 @@ void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
   case tok::kw_int:
   case tok::kw_long:
   case tok::kw___int64:
+  case tok::kw___int128:
   case tok::kw_signed:
   case tok::kw_unsigned:
   case tok::kw_float:
@@ -2228,10 +2229,14 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec,
                                      DiagID);
       break;
-     case tok::kw_half:
-       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec,
-                                      DiagID);
-       break;
+    case tok::kw___int128:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec,
+                                     DiagID);
+      break;
+    case tok::kw_half:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec,
+                                     DiagID);
+      break;
     case tok::kw_float:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec,
                                      DiagID);
@@ -3039,6 +3044,7 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
   case tok::kw_short:
   case tok::kw_long:
   case tok::kw___int64:
+  case tok::kw___int128:
   case tok::kw_signed:
   case tok::kw_unsigned:
   case tok::kw__Complex:
@@ -3109,6 +3115,7 @@ bool Parser::isTypeSpecifierQualifier() {
   case tok::kw_short:
   case tok::kw_long:
   case tok::kw___int64:
+  case tok::kw___int128:
   case tok::kw_signed:
   case tok::kw_unsigned:
   case tok::kw__Complex:
@@ -3244,6 +3251,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
   case tok::kw_short:
   case tok::kw_long:
   case tok::kw___int64:
+  case tok::kw___int128:
   case tok::kw_signed:
   case tok::kw_unsigned:
   case tok::kw__Complex:
index 752e5c502d4b6b47e05f61930527605adec8c2b8..f68359b8d2f85ea783f391a37565dc64488b40c8 100644 (file)
@@ -987,6 +987,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
   case tok::kw_int:
   case tok::kw_long:
   case tok::kw___int64:
+  case tok::kw___int128:
   case tok::kw_signed:
   case tok::kw_unsigned:
   case tok::kw_half:
index 9d1038e241278e1b618199c40c6f056013897805..0b7b2d9668cc3322607bcedcc54a6f5d35943251 100644 (file)
@@ -1389,6 +1389,7 @@ bool Parser::isCXXSimpleTypeSpecifier() const {
   case tok::kw_short:
   case tok::kw_long:
   case tok::kw___int64:
+  case tok::kw___int128:
   case tok::kw_signed:
   case tok::kw_unsigned:
   case tok::kw_void:
@@ -1499,6 +1500,9 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
   case tok::kw_int:
     DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID);
     break;
+  case tok::kw___int128:
+    DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, DiagID);
+    break;
   case tok::kw_half:
     DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, DiagID);
     break;
index e3b922500fc08362fc419657970d1ee54d86858e..73501e58ca30befd1a747566037598a1504388de 100644 (file)
@@ -707,6 +707,7 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
   case tok::kw_int:
   case tok::kw_long:
   case tok::kw___int64:
+  case tok::kw___int128:
   case tok::kw_restrict:
   case tok::kw_short:
   case tok::kw_signed:
@@ -1038,6 +1039,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult) {
   case tok::kw_int:
   case tok::kw_long:
   case tok::kw___int64:
+  case tok::kw___int128:
   case tok::kw_signed:
   case tok::kw_unsigned:
   case tok::kw_half:
index 97e00f0c56978543d9f71d121762706485f4174f..b531accf868ae632843b0979860d84d6387d3a47 100644 (file)
@@ -264,6 +264,7 @@ bool Declarator::isDeclarationOfFunction() const {
     case TST_float:
     case TST_half:
     case TST_int:
+    case TST_int128:
     case TST_struct:
     case TST_union:
     case TST_unknown_anytype:
@@ -379,6 +380,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
   case DeclSpec::TST_char16:      return "char16_t";
   case DeclSpec::TST_char32:      return "char32_t";
   case DeclSpec::TST_int:         return "int";
+  case DeclSpec::TST_int128:      return "__int128";
   case DeclSpec::TST_half:        return "half";
   case DeclSpec::TST_float:       return "float";
   case DeclSpec::TST_double:      return "double";
@@ -818,7 +820,7 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) {
   if (TypeSpecSign != TSS_unspecified) {
     if (TypeSpecType == TST_unspecified)
       TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
-    else if (TypeSpecType != TST_int  &&
+    else if (TypeSpecType != TST_int  && TypeSpecType != TST_int128 &&
              TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
       Diag(D, TSSLoc, diag::err_invalid_sign_spec)
         << getSpecifierName((TST)TypeSpecType);
index 87c8b4d40e576c087e9824f85165329981f9b9f5..a40100c7a726279254606bd038740ca9328478ff 100644 (file)
@@ -667,6 +667,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
   case TST_char16:
   case TST_char32:
   case TST_int:
+  case TST_int128:
   case TST_half:
   case TST_float:
   case TST_double:
index e83e9eff9e6c1155cb6ba9cb19340bef014f7a37..711ff08ce17d4b54900d0139aa164d0bd569f518 100644 (file)
@@ -720,6 +720,12 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
     }
     break;
   }
+  case DeclSpec::TST_int128:
+    if (DS.getTypeSpecSign() == DeclSpec::TSS_unsigned)
+      Result = Context.UnsignedInt128Ty;
+    else
+      Result = Context.Int128Ty;
+    break;
   case DeclSpec::TST_half: Result = Context.HalfTy; break;
   case DeclSpec::TST_float: Result = Context.FloatTy; break;
   case DeclSpec::TST_double:
index fe83d97ca4fc56275c7ff8b75a43103d5f13da8c..89d3ee201283eaff9e20985573558dc1083158d0 100644 (file)
@@ -7,3 +7,7 @@ int a[(u128)-1 > 1LL ? 1 : -1];
 
 // PR5435
 __uint128_t b = (__uint128_t)-1;
+
+// PR11916: Support for libstdc++ 4.7
+__int128 i = (__int128)0;
+unsigned __int128 u = (unsigned __int128)-1;
index 332b525e33a84483f0bd89ee59cbf7894d5c1609..3bec83e528b2d7cfd940acad6019d491a3766f79 100644 (file)
@@ -19,7 +19,21 @@ int b() {
   int __int128_t;
   int __uint128_t;
 }
+// __int128 is a keyword
+int c() {
+  __int128 i;
+  unsigned __int128 j;
+  long unsigned __int128 k; // expected-error {{'long __int128' is invalid}}
+  int __int128; // expected-error {{cannot combine with previous}} expected-warning {{does not declare anything}}
+}
+// __int128_t is __int128; __uint128_t is unsigned __int128.
+typedef __int128 check_int_128; // expected-note {{here}}
+typedef __int128_t check_int_128; // expected-note {{here}} expected-warning {{redefinition}}
+typedef int check_int_128; // expected-error {{different types ('int' vs '__int128_t' (aka '__int128'))}}
 
+typedef unsigned __int128 check_uint_128; // expected-note {{here}}
+typedef __uint128_t check_uint_128; // expected-note {{here}} expected-warning {{redefinition}}
+typedef int check_uint_128; // expected-error {{different types ('int' vs '__uint128_t' (aka 'unsigned __int128'))}}
 
 // Array type merging should convert array size to whatever matches the target
 // pointer size.