t/clang/type-traits
Patch authored by John Wiegley.
These type traits are used for parsing code that employs certain features of
the Embarcadero C++ compiler. Several of these constructs are also desired by
libc++, according to its project pages (such as __is_standard_layout).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130342 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index f593028..c41798e 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -731,22 +731,19 @@
// styles of attributes?
MaybeParseCXX0XAttributes(attrs);
- if (TagType == DeclSpec::TST_struct && Tok.is(tok::kw___is_pod)) {
- // GNU libstdc++ 4.2 uses __is_pod as the name of a struct template, but
- // __is_pod is a keyword in GCC >= 4.3. Therefore, when we see the
- // token sequence "struct __is_pod", make __is_pod into a normal
- // identifier rather than a keyword, to allow libstdc++ 4.2 to work
- // properly.
- Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
- Tok.setKind(tok::identifier);
- }
-
- if (TagType == DeclSpec::TST_struct && Tok.is(tok::kw___is_empty)) {
- // GNU libstdc++ 4.2 uses __is_empty as the name of a struct template, but
- // __is_empty is a keyword in GCC >= 4.3. Therefore, when we see the
- // token sequence "struct __is_empty", make __is_empty into a normal
- // identifier rather than a keyword, to allow libstdc++ 4.2 to work
- // properly.
+ if (TagType == DeclSpec::TST_struct &&
+ (Tok.is(tok::kw___is_pod) ||
+ Tok.is(tok::kw___is_empty) ||
+ Tok.is(tok::kw___is_void) ||
+ Tok.is(tok::kw___is_pointer) ||
+ Tok.is(tok::kw___is_arithmetic) ||
+ Tok.is(tok::kw___is_fundamental) ||
+ Tok.is(tok::kw___is_scalar))) {
+ // GNU libstdc++ 4.2 uses certain intrinsic names as the name of
+ // struct templates, but these are keywords in GCC >= 4.3 and
+ // Clang. Therefore, when we see the token sequence "struct X", make
+ // X into a normal identifier rather than a keyword, to allow
+ // libstdc++ 4.2 to work properly.
Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
Tok.setKind(tok::identifier);
}
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index c990c52..1c4a942 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -519,6 +519,34 @@
/// '::'[opt] 'delete' cast-expression
/// '::'[opt] 'delete' '[' ']' cast-expression
///
+/// [GNU/Embarcadero] unary-type-trait:
+/// '__is_arithmetic'
+/// '__is_floating_point'
+/// '__is_integral'
+/// '__is_lvalue_expr'
+/// '__is_rvalue_expr'
+/// '__is_complete_type'
+/// '__is_void'
+/// '__is_array'
+/// '__is_function'
+/// '__is_reference'
+/// '__is_lvalue_reference'
+/// '__is_rvalue_reference'
+/// '__is_fundamental'
+/// '__is_object'
+/// '__is_scalar'
+/// '__is_compound'
+/// '__is_pointer'
+/// '__is_member_object_pointer'
+/// '__is_member_function_pointer'
+/// '__is_member_pointer'
+/// '__is_const'
+/// '__is_volatile'
+/// '__is_trivial'
+/// '__is_standard_layout'
+/// '__is_signed'
+/// '__is_unsigned'
+///
/// [GNU] unary-type-trait:
/// '__has_nothrow_assign'
/// '__has_nothrow_copy'
@@ -540,6 +568,8 @@
/// binary-type-trait:
/// [GNU] '__is_base_of'
/// [MS] '__is_convertible_to'
+/// '__is_convertible'
+/// '__is_same'
///
/// [Embarcadero] expression-trait:
/// '__is_lvalue_expr'
@@ -997,6 +1027,29 @@
case tok::kw___is_empty:
case tok::kw___is_enum:
case tok::kw___is_literal:
+ case tok::kw___is_arithmetic:
+ case tok::kw___is_integral:
+ case tok::kw___is_floating_point:
+ case tok::kw___is_complete_type:
+ case tok::kw___is_void:
+ case tok::kw___is_array:
+ case tok::kw___is_function:
+ case tok::kw___is_reference:
+ case tok::kw___is_lvalue_reference:
+ case tok::kw___is_rvalue_reference:
+ case tok::kw___is_fundamental:
+ case tok::kw___is_object:
+ case tok::kw___is_scalar:
+ case tok::kw___is_compound:
+ case tok::kw___is_pointer:
+ case tok::kw___is_member_object_pointer:
+ case tok::kw___is_member_function_pointer:
+ case tok::kw___is_member_pointer:
+ case tok::kw___is_const:
+ case tok::kw___is_volatile:
+ case tok::kw___is_standard_layout:
+ case tok::kw___is_signed:
+ case tok::kw___is_unsigned:
case tok::kw___is_literal_type:
case tok::kw___is_pod:
case tok::kw___is_polymorphic:
@@ -1014,6 +1067,8 @@
case tok::kw___builtin_types_compatible_p:
case tok::kw___is_base_of:
+ case tok::kw___is_same:
+ case tok::kw___is_convertible:
case tok::kw___is_convertible_to:
return ParseBinaryTypeTrait();
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 7bf76a9..aade050 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -1912,25 +1912,50 @@
static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) {
switch(kind) {
- default: llvm_unreachable("Not a known unary type trait");
+ default: assert(false && "Not a known unary type trait.");
case tok::kw___has_nothrow_assign: return UTT_HasNothrowAssign;
- case tok::kw___has_nothrow_copy: return UTT_HasNothrowCopy;
case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor;
+ case tok::kw___has_nothrow_copy: return UTT_HasNothrowCopy;
case tok::kw___has_trivial_assign: return UTT_HasTrivialAssign;
- case tok::kw___has_trivial_copy: return UTT_HasTrivialCopy;
case tok::kw___has_trivial_constructor: return UTT_HasTrivialConstructor;
+ case tok::kw___has_trivial_copy: return UTT_HasTrivialCopy;
case tok::kw___has_trivial_destructor: return UTT_HasTrivialDestructor;
case tok::kw___has_virtual_destructor: return UTT_HasVirtualDestructor;
case tok::kw___is_abstract: return UTT_IsAbstract;
+ case tok::kw___is_arithmetic: return UTT_IsArithmetic;
+ case tok::kw___is_array: return UTT_IsArray;
case tok::kw___is_class: return UTT_IsClass;
+ case tok::kw___is_complete_type: return UTT_IsCompleteType;
+ case tok::kw___is_compound: return UTT_IsCompound;
+ case tok::kw___is_const: return UTT_IsConst;
case tok::kw___is_empty: return UTT_IsEmpty;
case tok::kw___is_enum: return UTT_IsEnum;
+ case tok::kw___is_floating_point: return UTT_IsFloatingPoint;
+ case tok::kw___is_function: return UTT_IsFunction;
+ case tok::kw___is_fundamental: return UTT_IsFundamental;
+ case tok::kw___is_integral: return UTT_IsIntegral;
+ case tok::kw___is_lvalue_expr: return UTT_IsLvalueExpr;
+ case tok::kw___is_lvalue_reference: return UTT_IsLvalueReference;
+ case tok::kw___is_member_function_pointer: return UTT_IsMemberFunctionPointer;
+ case tok::kw___is_member_object_pointer: return UTT_IsMemberObjectPointer;
+ case tok::kw___is_member_pointer: return UTT_IsMemberPointer;
+ case tok::kw___is_object: return UTT_IsObject;
case tok::kw___is_literal: return UTT_IsLiteral;
case tok::kw___is_literal_type: return UTT_IsLiteral;
case tok::kw___is_pod: return UTT_IsPOD;
+ case tok::kw___is_pointer: return UTT_IsPointer;
case tok::kw___is_polymorphic: return UTT_IsPolymorphic;
- case tok::kw___is_trivial: return UTT_IsTrivial;
+ case tok::kw___is_reference: return UTT_IsReference;
+ case tok::kw___is_rvalue_expr: return UTT_IsRvalueExpr;
+ case tok::kw___is_rvalue_reference: return UTT_IsRvalueReference;
+ case tok::kw___is_scalar: return UTT_IsScalar;
+ case tok::kw___is_signed: return UTT_IsSigned;
+ case tok::kw___is_standard_layout: return UTT_IsStandardLayout;
+ case tok::kw___is_trivial: return UTT_IsTrivial;
case tok::kw___is_union: return UTT_IsUnion;
+ case tok::kw___is_unsigned: return UTT_IsUnsigned;
+ case tok::kw___is_void: return UTT_IsVoid;
+ case tok::kw___is_volatile: return UTT_IsVolatile;
}
}
@@ -1938,6 +1963,8 @@
switch(kind) {
default: llvm_unreachable("Not a known binary type trait");
case tok::kw___is_base_of: return BTT_IsBaseOf;
+ case tok::kw___is_convertible: return BTT_IsConvertible;
+ case tok::kw___is_same: return BTT_IsSame;
case tok::kw___builtin_types_compatible_p: return BTT_TypeCompatible;
case tok::kw___is_convertible_to: return BTT_IsConvertibleTo;
}