For PR11916: Add support for g++'s __int128 keyword. Unlike __int128_t, this is

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.

llvm-svn: 153999
This commit is contained in:
Richard Smith 2012-04-04 06:24:32 +00:00
parent 0e60cd78cc
commit f016bbcc61
14 changed files with 55 additions and 8 deletions

View 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>

View 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,

View 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)

View 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;

View 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";

View 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:

View 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:

View 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;

View 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:

View 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);

View 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:

View 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:

View 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;

View 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.