[cfe-commits] r130342 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/AST/Type.h include/clang/Basic/TokenKinds.def include/clang/Basic/TypeTraits.h lib/AST/DeclCXX.cpp lib/AST/StmtPrinter.cpp lib/AST/Type.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/SemaExprCXX.cpp test/CodeGenCXX/mangle.cpp test/SemaCXX/type-traits.cpp
John Wiegley
johnw at boostpro.com
Wed Apr 27 16:09:49 PDT 2011
Author: johnw
Date: Wed Apr 27 18:09:49 2011
New Revision: 130342
URL: http://llvm.org/viewvc/llvm-project?rev=130342&view=rev
Log:
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).
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/Basic/TokenKinds.def
cfe/trunk/include/clang/Basic/TypeTraits.h
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/lib/AST/StmtPrinter.cpp
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/CodeGenCXX/mangle.cpp
cfe/trunk/test/SemaCXX/type-traits.cpp
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=130342&r1=130341&r2=130342&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Wed Apr 27 18:09:49 2011
@@ -306,6 +306,21 @@
/// one pure virtual function, (that can come from a base class).
bool Abstract : 1;
+ /// HasStandardLayout - True when this class has standard layout.
+ ///
+ /// C++0x [class]p7. A standard-layout class is a class that:
+ /// * has no non-static data members of type non-standard-layout class (or
+ /// array of such types) or reference,
+ /// * has no virtual functions (10.3) and no virtual base classes (10.1),
+ /// * has the same access control (Clause 11) for all non-static data members
+ /// * has no non-standard-layout base classes,
+ /// * either has no non-static data members in the most derived class and at
+ /// most one base class with non-static data members, or has no base
+ /// classes with non-static data members, and
+ /// * has no base classes of the same type as the first non-static data
+ /// member.
+ bool HasStandardLayout : 1;
+
/// HasTrivialConstructor - True when this class has a trivial constructor.
///
/// C++ [class.ctor]p5. A constructor is trivial if it is an
@@ -765,6 +780,10 @@
/// which means that the class contains or inherits a pure virtual function.
bool isAbstract() const { return data().Abstract; }
+ // hasStandardLayout - Whether this class has standard layout
+ // (C++ [class]p7)
+ bool hasStandardLayout() const { return data().HasStandardLayout; }
+
// hasTrivialConstructor - Whether this class has a trivial constructor
// (C++ [class.ctor]p5)
bool hasTrivialConstructor() const { return data().HasTrivialConstructor; }
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=130342&r1=130341&r2=130342&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Apr 27 18:09:49 2011
@@ -1171,7 +1171,7 @@
/// (C++0x [basic.types]p10)
bool isLiteralType() const;
- /// isTrivialType - Return true if this is a literal type
+ /// isTrivialType - Return true if this is a trivial type
/// (C++0x [basic.types]p9)
bool isTrivialType() const;
@@ -2832,6 +2832,9 @@
// const, it needs to return false.
bool hasConstFields() const { return false; }
+ /// \brief Whether this class has standard layout
+ bool hasStandardLayout(ASTContext& Ctx) const;
+
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=130342&r1=130341&r2=130342&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Wed Apr 27 18:09:49 2011
@@ -350,6 +350,35 @@
KEYWORD(__is_lvalue_expr , KEYCXX)
KEYWORD(__is_rvalue_expr , KEYCXX)
+// Embarcadero Unary Type Traits
+KEYWORD(__is_arithmetic , KEYCXX)
+KEYWORD(__is_floating_point , KEYCXX)
+KEYWORD(__is_integral , KEYCXX)
+KEYWORD(__is_complete_type , KEYCXX)
+KEYWORD(__is_void , KEYCXX)
+KEYWORD(__is_array , KEYCXX)
+KEYWORD(__is_function , KEYCXX)
+KEYWORD(__is_reference , KEYCXX)
+KEYWORD(__is_lvalue_reference , KEYCXX)
+KEYWORD(__is_rvalue_reference , KEYCXX)
+KEYWORD(__is_fundamental , KEYCXX)
+KEYWORD(__is_object , KEYCXX)
+KEYWORD(__is_scalar , KEYCXX)
+KEYWORD(__is_compound , KEYCXX)
+KEYWORD(__is_pointer , KEYCXX)
+KEYWORD(__is_member_object_pointer , KEYCXX)
+KEYWORD(__is_member_function_pointer, KEYCXX)
+KEYWORD(__is_member_pointer , KEYCXX)
+KEYWORD(__is_const , KEYCXX)
+KEYWORD(__is_volatile , KEYCXX)
+KEYWORD(__is_standard_layout , KEYCXX)
+KEYWORD(__is_signed , KEYCXX)
+KEYWORD(__is_unsigned , KEYCXX)
+
+// Embarcadero Binary Type Traits
+KEYWORD(__is_same , KEYCXX)
+KEYWORD(__is_convertible , KEYCXX)
+
// Apple Extension.
KEYWORD(__private_extern__ , KEYALL)
Modified: cfe/trunk/include/clang/Basic/TypeTraits.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TypeTraits.h?rev=130342&r1=130341&r2=130342&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TypeTraits.h (original)
+++ cfe/trunk/include/clang/Basic/TypeTraits.h Wed Apr 27 18:09:49 2011
@@ -27,21 +27,48 @@
UTT_HasTrivialDestructor,
UTT_HasVirtualDestructor,
UTT_IsAbstract,
+ UTT_IsArithmetic,
+ UTT_IsArray,
UTT_IsClass,
+ UTT_IsCompleteType,
+ UTT_IsCompound,
+ UTT_IsConst,
UTT_IsEmpty,
UTT_IsEnum,
+ UTT_IsFloatingPoint,
+ UTT_IsFunction,
+ UTT_IsFundamental,
+ UTT_IsIntegral,
UTT_IsLiteral,
+ UTT_IsLvalueExpr,
+ UTT_IsLvalueReference,
+ UTT_IsMemberFunctionPointer,
+ UTT_IsMemberObjectPointer,
+ UTT_IsMemberPointer,
+ UTT_IsObject,
UTT_IsPOD,
+ UTT_IsPointer,
UTT_IsPolymorphic,
+ UTT_IsReference,
+ UTT_IsRvalueExpr,
+ UTT_IsRvalueReference,
+ UTT_IsScalar,
+ UTT_IsSigned,
+ UTT_IsStandardLayout,
UTT_IsTrivial,
- UTT_IsUnion
+ UTT_IsUnion,
+ UTT_IsUnsigned,
+ UTT_IsVoid,
+ UTT_IsVolatile
};
/// BinaryTypeTrait - Names for the binary type traits.
enum BinaryTypeTrait {
BTT_IsBaseOf,
- BTT_TypeCompatible,
- BTT_IsConvertibleTo
+ BTT_IsConvertible,
+ BTT_IsConvertibleTo,
+ BTT_IsSame,
+ BTT_TypeCompatible
};
/// UnaryExprOrTypeTrait - Names for the "expression or type" traits.
Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=130342&r1=130341&r2=130342&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Wed Apr 27 18:09:49 2011
@@ -926,6 +926,10 @@
void CXXRecordDecl::completeDefinition() {
completeDefinition(0);
+
+ ASTContext &Context = getASTContext();
+ if (const RecordType *RT = getTypeForDecl()->getAs<RecordType>())
+ data().HasStandardLayout = RT->hasStandardLayout(Context);
}
void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=130342&r1=130341&r2=130342&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Wed Apr 27 18:09:49 2011
@@ -1251,23 +1251,48 @@
static const char *getTypeTraitName(UnaryTypeTrait UTT) {
switch (UTT) {
- default: llvm_unreachable("Unknown unary type trait");
+ default: assert(false && "Unknown type trait");
case UTT_HasNothrowAssign: return "__has_nothrow_assign";
- case UTT_HasNothrowCopy: return "__has_nothrow_copy";
case UTT_HasNothrowConstructor: return "__has_nothrow_constructor";
+ case UTT_HasNothrowCopy: return "__has_nothrow_copy";
case UTT_HasTrivialAssign: return "__has_trivial_assign";
- case UTT_HasTrivialCopy: return "__has_trivial_copy";
case UTT_HasTrivialConstructor: return "__has_trivial_constructor";
+ case UTT_HasTrivialCopy: return "__has_trivial_copy";
case UTT_HasTrivialDestructor: return "__has_trivial_destructor";
case UTT_HasVirtualDestructor: return "__has_virtual_destructor";
case UTT_IsAbstract: return "__is_abstract";
+ case UTT_IsArithmetic: return "__is_arithmetic";
+ case UTT_IsArray: return "__is_array";
case UTT_IsClass: return "__is_class";
+ case UTT_IsCompleteType: return "__is_complete_type";
+ case UTT_IsCompound: return "__is_compound";
+ case UTT_IsConst: return "__is_const";
case UTT_IsEmpty: return "__is_empty";
case UTT_IsEnum: return "__is_enum";
+ case UTT_IsFloatingPoint: return "__is_floating_point";
+ case UTT_IsFunction: return "__is_function";
+ case UTT_IsFundamental: return "__is_fundamental";
+ case UTT_IsIntegral: return "__is_integral";
+ case UTT_IsLvalueExpr: return "__is_lvalue_expr";
+ case UTT_IsLvalueReference: return "__is_lvalue_reference";
+ case UTT_IsMemberFunctionPointer: return "__is_member_function_pointer";
+ case UTT_IsMemberObjectPointer: return "__is_member_object_pointer";
+ case UTT_IsMemberPointer: return "__is_member_pointer";
+ case UTT_IsObject: return "__is_object";
case UTT_IsPOD: return "__is_pod";
+ case UTT_IsPointer: return "__is_pointer";
case UTT_IsPolymorphic: return "__is_polymorphic";
- case UTT_IsTrivial: return "__is_trivial";
+ case UTT_IsReference: return "__is_reference";
+ case UTT_IsRvalueExpr: return "__is_rvalue_expr";
+ case UTT_IsRvalueReference: return "__is_rvalue_reference";
+ case UTT_IsScalar: return "__is_scalar";
+ case UTT_IsSigned: return "__is_signed";
+ case UTT_IsStandardLayout: return "__is_standard_layout";
+ case UTT_IsTrivial: return "__is_trivial";
case UTT_IsUnion: return "__is_union";
+ case UTT_IsUnsigned: return "__is_unsigned";
+ case UTT_IsVoid: return "__is_void";
+ case UTT_IsVolatile: return "__is_volatile";
}
return "";
}
@@ -1275,6 +1300,8 @@
static const char *getTypeTraitName(BinaryTypeTrait BTT) {
switch (BTT) {
case BTT_IsBaseOf: return "__is_base_of";
+ case BTT_IsConvertible: return "__is_convertible";
+ case BTT_IsSame: return "__is_same";
case BTT_TypeCompatible: return "__builtin_types_compatible_p";
case BTT_IsConvertibleTo: return "__is_convertible_to";
}
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=130342&r1=130341&r2=130342&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Wed Apr 27 18:09:49 2011
@@ -1385,6 +1385,109 @@
return isa<RecordDecl>(TT->getDecl());
}
+static uint64_t countBasesWithFields(QualType BaseType) {
+ uint64_t BasesWithFields = 0;
+ if (const RecordType *T = BaseType->getAs<RecordType>()) {
+ CXXRecordDecl *RD = cast<CXXRecordDecl>(T->getDecl());
+ for (CXXRecordDecl::field_iterator Field = RD->field_begin(),
+ E = RD->field_end(); Field != E; ++Field)
+ BasesWithFields = 1;
+ for (CXXRecordDecl::base_class_const_iterator B = RD->bases_begin(),
+ BE = RD->bases_end(); B != BE; ++B)
+ BasesWithFields += countBasesWithFields(B->getType());
+ }
+ return BasesWithFields;
+}
+
+bool RecordType::hasStandardLayout(ASTContext& Context) const {
+ CXXRecordDecl *RD = cast<CXXRecordDecl>(getDecl());
+ if (! RD) {
+ assert(cast<RecordDecl>(getDecl()) &&
+ "RecordType does not have a corresponding RecordDecl");
+ return true;
+ }
+
+ // A standard-layout class is a class that:
+
+ for (CXXRecordDecl::method_iterator M = RD->method_begin(),
+ ME = RD->method_end(); M != ME; ++M) {
+ CXXMethodDecl *Method = *M;
+
+ // C++0x [class]p7:
+ // A standard-layout class is a class that [...]
+ // -- has no virtual functions (10.3) [...]
+ if (Method->isVirtual())
+ return false;
+ }
+
+ AccessSpecifier AS = AS_none;
+ QualType FirstFieldType;
+ bool FirstFieldType_set = false;
+ uint64_t FieldCount = 0;
+
+ for (CXXRecordDecl::field_iterator Field = RD->field_begin(),
+ E = RD->field_end(); Field != E; ++Field, ++FieldCount) {
+ // C++0x [class]p7:
+ // A standard-layout class is a class that [...]
+ // -- has no non-static data members of type non-standard-layout class
+ // (or array of such types) or reference [...]
+ QualType FieldType = Context.getBaseElementType((*Field)->getType());
+ if (const RecordType *T =
+ Context.getBaseElementType(FieldType)->getAs<RecordType>()) {
+ if (! T->hasStandardLayout(Context) || T->isReferenceType())
+ return false;
+ }
+ if (! FirstFieldType_set) {
+ FirstFieldType = FieldType;
+ FirstFieldType_set = true;
+ }
+
+ // C++0x [class]p7:
+ // A standard-layout class is a class that [...]
+ // -- has the same access control (Clause 11) for all non-static data
+ // members [...]
+ if (AS == AS_none)
+ AS = (*Field)->getAccess();
+ else if (AS != (*Field)->getAccess())
+ return false;
+ }
+
+ for (CXXRecordDecl::base_class_const_iterator B = RD->bases_begin(),
+ BE = RD->bases_end(); B != BE; ++B) {
+ // C++0x [class]p7:
+ // A standard-layout class is a class that [...]
+ // -- no virtual base classes (10.1) [...]
+ if (B->isVirtual())
+ return false;
+
+ QualType BT = B->getType();
+
+ // C++0x [class]p7:
+ // A standard-layout class is a class that [...]
+ // -- has no non-standard-layout base classes [...]
+ if (const RecordType *T = BT->getAs<RecordType>())
+ if (! T->hasStandardLayout(Context))
+ return false;
+
+ // C++0x [class]p7:
+ // A standard-layout class is a class that [...]
+ // -- has no base classes of the same type as the first non-static data
+ // member.
+ if (BT == FirstFieldType)
+ return false;
+
+ // C++0x [class]p7:
+ // A standard-layout class is a class that [...]
+ // -- either has no non-static data members in the most derived class
+ // and at most one base class with non-static data members, or has
+ // no base classes with non-static data members [...]
+ if (countBasesWithFields(BT) > (FieldCount == 0 ? 1 : 0))
+ return false;
+ }
+
+ return true;
+}
+
bool EnumType::classof(const TagType *TT) {
return isa<EnumDecl>(TT->getDecl());
}
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=130342&r1=130341&r2=130342&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Wed Apr 27 18:09:49 2011
@@ -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);
}
Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=130342&r1=130341&r2=130342&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Wed Apr 27 18:09:49 2011
@@ -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();
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=130342&r1=130341&r2=130342&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Wed Apr 27 18:09:49 2011
@@ -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;
}
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=130342&r1=130341&r2=130342&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Apr 27 18:09:49 2011
@@ -2379,6 +2379,7 @@
return false;
case UTT_IsAbstract:
if (const RecordType *RT = T->getAs<RecordType>())
+ if (!Self.RequireCompleteType(KeyLoc, T, diag::err_incomplete_typeid))
return cast<CXXRecordDecl>(RT->getDecl())->isAbstract();
return false;
case UTT_IsEmpty:
@@ -2387,6 +2388,74 @@
&& cast<CXXRecordDecl>(Record->getDecl())->isEmpty();
}
return false;
+ case UTT_IsIntegral:
+ return T->isIntegralType(C);
+ case UTT_IsFloatingPoint:
+ return T->isFloatingType();
+ case UTT_IsArithmetic:
+ return T->isArithmeticType() && ! T->isEnumeralType();
+ case UTT_IsArray:
+ return T->isArrayType();
+ case UTT_IsCompleteType:
+ return ! T->isIncompleteType();
+ case UTT_IsCompound:
+ return ! (T->isVoidType() || T->isArithmeticType()) || T->isEnumeralType();
+ case UTT_IsConst:
+ return T.isConstQualified();
+ case UTT_IsFunction:
+ return T->isFunctionType();
+ case UTT_IsFundamental:
+ return T->isVoidType() || (T->isArithmeticType() && ! T->isEnumeralType());
+ case UTT_IsLvalueReference:
+ return T->isLValueReferenceType();
+ case UTT_IsMemberFunctionPointer:
+ return T->isMemberFunctionPointerType();
+ case UTT_IsMemberObjectPointer:
+ return T->isMemberDataPointerType();
+ case UTT_IsMemberPointer:
+ return T->isMemberPointerType();
+ case UTT_IsObject:
+ // Defined in Section 3.9 p8 of the Working Draft, essentially:
+ // !__is_reference(T) && !__is_function(T) && !__is_void(T).
+ return ! (T->isReferenceType() || T->isFunctionType() || T->isVoidType());
+ case UTT_IsPointer:
+ return T->isPointerType();
+ case UTT_IsReference:
+ return T->isReferenceType();
+ case UTT_IsRvalueReference:
+ return T->isRValueReferenceType();
+ case UTT_IsScalar:
+ // Scalar type is defined in Section 3.9 p10 of the Working Draft.
+ // Essentially:
+ // __is_arithmetic( T ) || __is_enumeration(T) ||
+ // __is_pointer(T) || __is_member_pointer(T)
+ return (T->isArithmeticType() || T->isEnumeralType() ||
+ T->isPointerType() || T->isMemberPointerType());
+ case UTT_IsSigned:
+ return T->isSignedIntegerType();
+ case UTT_IsStandardLayout:
+ // Error if T is an incomplete type.
+ if (Self.RequireCompleteType(KeyLoc, T, diag::err_incomplete_typeid))
+ return false;
+
+ // A standard layout type is:
+ // - a scalar type
+ // - an array of standard layout types
+ // - a standard layout class type:
+ if (EvaluateUnaryTypeTrait(Self, UTT_IsScalar, T, KeyLoc))
+ return true;
+ if (EvaluateUnaryTypeTrait(Self, UTT_IsScalar, C.getBaseElementType(T),
+ KeyLoc))
+ return true;
+ if (const RecordType *RT = C.getBaseElementType(T)->getAs<RecordType>())
+ return RT->hasStandardLayout(C);
+ return false;
+ case UTT_IsUnsigned:
+ return T->isUnsignedIntegerType();
+ case UTT_IsVoid:
+ return T->isVoidType();
+ case UTT_IsVolatile:
+ return T.isVolatileQualified();
case UTT_HasTrivialConstructor:
// http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
// If __is_pod (type) is true then the trait is true, else if type is
@@ -2579,11 +2648,12 @@
// According to http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
// all traits except __is_class, __is_enum and __is_union require a the type
// to be complete, an array of unknown bound, or void.
- if (UTT != UTT_IsClass && UTT != UTT_IsEnum && UTT != UTT_IsUnion) {
+ if (UTT != UTT_IsClass && UTT != UTT_IsEnum && UTT != UTT_IsUnion &&
+ UTT != UTT_IsCompleteType) {
QualType E = T;
if (T->isIncompleteArrayType())
E = Context.getAsArrayType(T)->getElementType();
- if (!T->isVoidType() &&
+ if (!T->isVoidType() && ! LangOpts.Borland &&
RequireCompleteType(KWLoc, E,
diag::err_incomplete_type_used_in_type_trait_expr))
return ExprError();
@@ -2651,11 +2721,12 @@
return cast<CXXRecordDecl>(rhsRecord->getDecl())
->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getDecl()));
}
-
+ case BTT_IsSame:
+ return Self.Context.hasSameType(LhsT, RhsT);
case BTT_TypeCompatible:
return Self.Context.typesAreCompatible(LhsT.getUnqualifiedType(),
RhsT.getUnqualifiedType());
-
+ case BTT_IsConvertible:
case BTT_IsConvertibleTo: {
// C++0x [meta.rel]p4:
// Given the following function prototype:
@@ -2730,6 +2801,8 @@
QualType ResultType;
switch (BTT) {
case BTT_IsBaseOf: ResultType = Context.BoolTy; break;
+ case BTT_IsConvertible: ResultType = Context.BoolTy; break;
+ case BTT_IsSame: ResultType = Context.BoolTy; break;
case BTT_TypeCompatible: ResultType = Context.IntTy; break;
case BTT_IsConvertibleTo: ResultType = Context.BoolTy; break;
}
Modified: cfe/trunk/test/CodeGenCXX/mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle.cpp?rev=130342&r1=130341&r2=130342&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle.cpp Wed Apr 27 18:09:49 2011
@@ -183,7 +183,7 @@
// CHECK: @_Z3ft6I1SENT_1UERKS1_
template int ft6<S>(const S&);
-template<typename> struct __is_scalar {
+template<typename> struct __is_scalar_type {
enum { __value = 1 };
};
@@ -194,11 +194,11 @@
};
// PR5063
-template<typename T> typename __enable_if<__is_scalar<T>::__value, void>::__type ft7() { }
+template<typename T> typename __enable_if<__is_scalar_type<T>::__value, void>::__type ft7() { }
-// CHECK: @_Z3ft7IiEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv
+// CHECK: @_Z3ft7IiEN11__enable_ifIXsr16__is_scalar_typeIT_E7__valueEvE6__typeEv
template void ft7<int>();
-// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv
+// CHECK: @_Z3ft7IPvEN11__enable_ifIXsr16__is_scalar_typeIT_E7__valueEvE6__typeEv
template void ft7<void*>();
// PR5144
@@ -225,15 +225,15 @@
S7::S7() {}
// PR5063
-template<typename T> typename __enable_if<(__is_scalar<T>::__value), void>::__type ft8() { }
-// CHECK: @_Z3ft8IiEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv
+template<typename T> typename __enable_if<(__is_scalar_type<T>::__value), void>::__type ft8() { }
+// CHECK: @_Z3ft8IiEN11__enable_ifIXsr16__is_scalar_typeIT_E7__valueEvE6__typeEv
template void ft8<int>();
-// CHECK: @_Z3ft8IPvEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv
+// CHECK: @_Z3ft8IPvEN11__enable_ifIXsr16__is_scalar_typeIT_E7__valueEvE6__typeEv
template void ft8<void*>();
// PR5796
namespace PR5796 {
-template<typename> struct __is_scalar {
+template<typename> struct __is_scalar_type {
enum { __value = 0 };
};
@@ -241,8 +241,8 @@
template<typename T> struct __enable_if<true, T> { typedef T __type; };
template<typename T>
-// CHECK: define linkonce_odr void @_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsrNS_11__is_scalarIT_EE7__valueEvE6__typeEv
-typename __enable_if<!__is_scalar<T>::__value, void>::__type __fill_a() { };
+// CHECK: define linkonce_odr void @_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsrNS_16__is_scalar_typeIT_EE7__valueEvE6__typeEv
+typename __enable_if<!__is_scalar_type<T>::__value, void>::__type __fill_a() { };
void f() { __fill_a<int>(); }
}
Modified: cfe/trunk/test/SemaCXX/type-traits.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/type-traits.cpp?rev=130342&r1=130341&r2=130342&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/type-traits.cpp (original)
+++ cfe/trunk/test/SemaCXX/type-traits.cpp Wed Apr 27 18:09:49 2011
@@ -244,6 +244,773 @@
{ int arr[F(__is_polymorphic(IntArNB))]; }
}
+void is_integral()
+{
+ int t01[T(__is_integral(bool))];
+ int t02[T(__is_integral(char))];
+ int t03[T(__is_integral(signed char))];
+ int t04[T(__is_integral(unsigned char))];
+ //int t05[T(__is_integral(char16_t))];
+ //int t06[T(__is_integral(char32_t))];
+ int t07[T(__is_integral(wchar_t))];
+ int t08[T(__is_integral(short))];
+ int t09[T(__is_integral(unsigned short))];
+ int t10[T(__is_integral(int))];
+ int t11[T(__is_integral(unsigned int))];
+ int t12[T(__is_integral(long))];
+ int t13[T(__is_integral(unsigned long))];
+
+ int t21[F(__is_integral(float))];
+ int t22[F(__is_integral(double))];
+ int t23[F(__is_integral(long double))];
+ int t24[F(__is_integral(Union))];
+ int t25[F(__is_integral(UnionAr))];
+ int t26[F(__is_integral(Derives))];
+ int t27[F(__is_integral(ClassType))];
+ int t28[F(__is_integral(Enum))];
+ int t29[F(__is_integral(void))];
+ int t30[F(__is_integral(cvoid))];
+ int t31[F(__is_integral(IntArNB))];
+}
+
+void is_floating_point()
+{
+ int t01[T(__is_floating_point(float))];
+ int t02[T(__is_floating_point(double))];
+ int t03[T(__is_floating_point(long double))];
+
+ int t11[F(__is_floating_point(bool))];
+ int t12[F(__is_floating_point(char))];
+ int t13[F(__is_floating_point(signed char))];
+ int t14[F(__is_floating_point(unsigned char))];
+ //int t15[F(__is_floating_point(char16_t))];
+ //int t16[F(__is_floating_point(char32_t))];
+ int t17[F(__is_floating_point(wchar_t))];
+ int t18[F(__is_floating_point(short))];
+ int t19[F(__is_floating_point(unsigned short))];
+ int t20[F(__is_floating_point(int))];
+ int t21[F(__is_floating_point(unsigned int))];
+ int t22[F(__is_floating_point(long))];
+ int t23[F(__is_floating_point(unsigned long))];
+ int t24[F(__is_floating_point(Union))];
+ int t25[F(__is_floating_point(UnionAr))];
+ int t26[F(__is_floating_point(Derives))];
+ int t27[F(__is_floating_point(ClassType))];
+ int t28[F(__is_floating_point(Enum))];
+ int t29[F(__is_floating_point(void))];
+ int t30[F(__is_floating_point(cvoid))];
+ int t31[F(__is_floating_point(IntArNB))];
+}
+
+void is_arithmetic()
+{
+ int t01[T(__is_arithmetic(float))];
+ int t02[T(__is_arithmetic(double))];
+ int t03[T(__is_arithmetic(long double))];
+ int t11[T(__is_arithmetic(bool))];
+ int t12[T(__is_arithmetic(char))];
+ int t13[T(__is_arithmetic(signed char))];
+ int t14[T(__is_arithmetic(unsigned char))];
+ //int t15[T(__is_arithmetic(char16_t))];
+ //int t16[T(__is_arithmetic(char32_t))];
+ int t17[T(__is_arithmetic(wchar_t))];
+ int t18[T(__is_arithmetic(short))];
+ int t19[T(__is_arithmetic(unsigned short))];
+ int t20[T(__is_arithmetic(int))];
+ int t21[T(__is_arithmetic(unsigned int))];
+ int t22[T(__is_arithmetic(long))];
+ int t23[T(__is_arithmetic(unsigned long))];
+
+ int t24[F(__is_arithmetic(Union))];
+ int t25[F(__is_arithmetic(UnionAr))];
+ int t26[F(__is_arithmetic(Derives))];
+ int t27[F(__is_arithmetic(ClassType))];
+ int t28[F(__is_arithmetic(Enum))];
+ int t29[F(__is_arithmetic(void))];
+ int t30[F(__is_arithmetic(cvoid))];
+ int t31[F(__is_arithmetic(IntArNB))];
+}
+
+struct ACompleteType {};
+struct AnIncompleteType;
+
+void is_complete_type()
+{
+ int t01[T(__is_complete_type(float))];
+ int t02[T(__is_complete_type(double))];
+ int t03[T(__is_complete_type(long double))];
+ int t11[T(__is_complete_type(bool))];
+ int t12[T(__is_complete_type(char))];
+ int t13[T(__is_complete_type(signed char))];
+ int t14[T(__is_complete_type(unsigned char))];
+ //int t15[T(__is_complete_type(char16_t))];
+ //int t16[T(__is_complete_type(char32_t))];
+ int t17[T(__is_complete_type(wchar_t))];
+ int t18[T(__is_complete_type(short))];
+ int t19[T(__is_complete_type(unsigned short))];
+ int t20[T(__is_complete_type(int))];
+ int t21[T(__is_complete_type(unsigned int))];
+ int t22[T(__is_complete_type(long))];
+ int t23[T(__is_complete_type(unsigned long))];
+ int t24[T(__is_complete_type(ACompleteType))];
+
+ int t30[F(__is_complete_type(AnIncompleteType))];
+}
+
+void is_void()
+{
+ int t01[T(__is_void(void))];
+ int t02[T(__is_void(cvoid))];
+
+ int t10[F(__is_void(float))];
+ int t11[F(__is_void(double))];
+ int t12[F(__is_void(long double))];
+ int t13[F(__is_void(bool))];
+ int t14[F(__is_void(char))];
+ int t15[F(__is_void(signed char))];
+ int t16[F(__is_void(unsigned char))];
+ int t17[F(__is_void(wchar_t))];
+ int t18[F(__is_void(short))];
+ int t19[F(__is_void(unsigned short))];
+ int t20[F(__is_void(int))];
+ int t21[F(__is_void(unsigned int))];
+ int t22[F(__is_void(long))];
+ int t23[F(__is_void(unsigned long))];
+ int t24[F(__is_void(Union))];
+ int t25[F(__is_void(UnionAr))];
+ int t26[F(__is_void(Derives))];
+ int t27[F(__is_void(ClassType))];
+ int t28[F(__is_void(Enum))];
+ int t29[F(__is_void(IntArNB))];
+ int t30[F(__is_void(void*))];
+ int t31[F(__is_void(cvoid*))];
+}
+
+void is_array()
+{
+ int t01[T(__is_array(IntAr))];
+ int t02[T(__is_array(IntArNB))];
+ int t03[T(__is_array(UnionAr))];
+
+ int t10[F(__is_array(void))];
+ int t11[F(__is_array(cvoid))];
+ int t12[F(__is_array(float))];
+ int t13[F(__is_array(double))];
+ int t14[F(__is_array(long double))];
+ int t15[F(__is_array(bool))];
+ int t16[F(__is_array(char))];
+ int t17[F(__is_array(signed char))];
+ int t18[F(__is_array(unsigned char))];
+ int t19[F(__is_array(wchar_t))];
+ int t20[F(__is_array(short))];
+ int t21[F(__is_array(unsigned short))];
+ int t22[F(__is_array(int))];
+ int t23[F(__is_array(unsigned int))];
+ int t24[F(__is_array(long))];
+ int t25[F(__is_array(unsigned long))];
+ int t26[F(__is_array(Union))];
+ int t27[F(__is_array(Derives))];
+ int t28[F(__is_array(ClassType))];
+ int t29[F(__is_array(Enum))];
+ int t30[F(__is_array(void*))];
+ int t31[F(__is_array(cvoid*))];
+}
+
+template <typename T> void tmpl_func(T&) {}
+
+template <typename T> struct type_wrapper {
+ typedef T type;
+ typedef T* ptrtype;
+ typedef T& reftype;
+};
+
+void is_function()
+{
+ int t01[T(__is_function(type_wrapper<void(void)>::type))];
+ int t02[T(__is_function(typeof(tmpl_func<int>)))];
+
+ typedef void (*ptr_to_func_type)(void);
+
+ int t10[F(__is_function(void))];
+ int t11[F(__is_function(cvoid))];
+ int t12[F(__is_function(float))];
+ int t13[F(__is_function(double))];
+ int t14[F(__is_function(long double))];
+ int t15[F(__is_function(bool))];
+ int t16[F(__is_function(char))];
+ int t17[F(__is_function(signed char))];
+ int t18[F(__is_function(unsigned char))];
+ int t19[F(__is_function(wchar_t))];
+ int t20[F(__is_function(short))];
+ int t21[F(__is_function(unsigned short))];
+ int t22[F(__is_function(int))];
+ int t23[F(__is_function(unsigned int))];
+ int t24[F(__is_function(long))];
+ int t25[F(__is_function(unsigned long))];
+ int t26[F(__is_function(Union))];
+ int t27[F(__is_function(Derives))];
+ int t28[F(__is_function(ClassType))];
+ int t29[F(__is_function(Enum))];
+ int t30[F(__is_function(void*))];
+ int t31[F(__is_function(cvoid*))];
+ int t32[F(__is_function(void(*)()))];
+ int t33[F(__is_function(ptr_to_func_type))];
+ int t34[F(__is_function(type_wrapper<void(void)>::ptrtype))];
+ int t35[F(__is_function(type_wrapper<void(void)>::reftype))];
+}
+
+void is_reference()
+{
+ int t01[T(__is_reference(int&))];
+ int t02[T(__is_reference(const int&))];
+ int t03[T(__is_reference(void *&))];
+
+ int t10[F(__is_reference(int))];
+ int t11[F(__is_reference(const int))];
+ int t12[F(__is_reference(void *))];
+}
+
+void is_lvalue_reference()
+{
+ int t01[T(__is_lvalue_reference(int&))];
+ int t02[T(__is_lvalue_reference(void *&))];
+ int t03[T(__is_lvalue_reference(const int&))];
+ int t04[T(__is_lvalue_reference(void * const &))];
+
+ int t10[F(__is_lvalue_reference(int))];
+ int t11[F(__is_lvalue_reference(const int))];
+ int t12[F(__is_lvalue_reference(void *))];
+}
+
+#if __has_feature(cxx_rvalue_references)
+
+void is_rvalue_reference()
+{
+ int t01[T(__is_rvalue_reference(const int&&))];
+ int t02[T(__is_rvalue_reference(void * const &&))];
+
+ int t10[F(__is_rvalue_reference(int&))];
+ int t11[F(__is_rvalue_reference(void *&))];
+ int t12[F(__is_rvalue_reference(const int&))];
+ int t13[F(__is_rvalue_reference(void * const &))];
+ int t14[F(__is_rvalue_reference(int))];
+ int t15[F(__is_rvalue_reference(const int))];
+ int t16[F(__is_rvalue_reference(void *))];
+}
+
+#endif
+
+void is_fundamental()
+{
+ int t01[T(__is_fundamental(float))];
+ int t02[T(__is_fundamental(double))];
+ int t03[T(__is_fundamental(long double))];
+ int t11[T(__is_fundamental(bool))];
+ int t12[T(__is_fundamental(char))];
+ int t13[T(__is_fundamental(signed char))];
+ int t14[T(__is_fundamental(unsigned char))];
+ //int t15[T(__is_fundamental(char16_t))];
+ //int t16[T(__is_fundamental(char32_t))];
+ int t17[T(__is_fundamental(wchar_t))];
+ int t18[T(__is_fundamental(short))];
+ int t19[T(__is_fundamental(unsigned short))];
+ int t20[T(__is_fundamental(int))];
+ int t21[T(__is_fundamental(unsigned int))];
+ int t22[T(__is_fundamental(long))];
+ int t23[T(__is_fundamental(unsigned long))];
+ int t24[T(__is_fundamental(void))];
+ int t25[T(__is_fundamental(cvoid))];
+
+ int t30[F(__is_fundamental(Union))];
+ int t31[F(__is_fundamental(UnionAr))];
+ int t32[F(__is_fundamental(Derives))];
+ int t33[F(__is_fundamental(ClassType))];
+ int t34[F(__is_fundamental(Enum))];
+ int t35[F(__is_fundamental(IntArNB))];
+}
+
+void is_object()
+{
+ int t01[T(__is_object(int))];
+ int t02[T(__is_object(int *))];
+ int t03[T(__is_object(void *))];
+ int t04[T(__is_object(Union))];
+ int t05[T(__is_object(UnionAr))];
+ int t06[T(__is_object(ClassType))];
+ int t07[T(__is_object(Enum))];
+
+ int t10[F(__is_object(type_wrapper<void(void)>::type))];
+ int t11[F(__is_object(int&))];
+ int t12[F(__is_object(void))];
+}
+
+void is_scalar()
+{
+ int t01[T(__is_scalar(float))];
+ int t02[T(__is_scalar(double))];
+ int t03[T(__is_scalar(long double))];
+ int t04[T(__is_scalar(bool))];
+ int t05[T(__is_scalar(char))];
+ int t06[T(__is_scalar(signed char))];
+ int t07[T(__is_scalar(unsigned char))];
+ int t08[T(__is_scalar(wchar_t))];
+ int t09[T(__is_scalar(short))];
+ int t10[T(__is_scalar(unsigned short))];
+ int t11[T(__is_scalar(int))];
+ int t12[T(__is_scalar(unsigned int))];
+ int t13[T(__is_scalar(long))];
+ int t14[T(__is_scalar(unsigned long))];
+ int t15[T(__is_scalar(Enum))];
+ int t16[T(__is_scalar(void*))];
+ int t17[T(__is_scalar(cvoid*))];
+
+ int t20[F(__is_scalar(void))];
+ int t21[F(__is_scalar(cvoid))];
+ int t22[F(__is_scalar(Union))];
+ int t23[F(__is_scalar(UnionAr))];
+ int t24[F(__is_scalar(Derives))];
+ int t25[F(__is_scalar(ClassType))];
+ int t26[F(__is_scalar(IntArNB))];
+}
+
+struct StructWithMembers {
+ int member;
+ void method() {}
+};
+
+void is_compound()
+{
+ int t01[T(__is_compound(void*))];
+ int t02[T(__is_compound(cvoid*))];
+ int t03[T(__is_compound(void (*)()))];
+ int t04[T(__is_compound(int StructWithMembers::*))];
+ int t05[T(__is_compound(void (StructWithMembers::*)()))];
+ int t06[T(__is_compound(int&))];
+ int t07[T(__is_compound(Union))];
+ int t08[T(__is_compound(UnionAr))];
+ int t09[T(__is_compound(Derives))];
+ int t10[T(__is_compound(ClassType))];
+ int t11[T(__is_compound(IntArNB))];
+ int t12[T(__is_compound(Enum))];
+
+ int t20[F(__is_compound(float))];
+ int t21[F(__is_compound(double))];
+ int t22[F(__is_compound(long double))];
+ int t23[F(__is_compound(bool))];
+ int t24[F(__is_compound(char))];
+ int t25[F(__is_compound(signed char))];
+ int t26[F(__is_compound(unsigned char))];
+ int t27[F(__is_compound(wchar_t))];
+ int t28[F(__is_compound(short))];
+ int t29[F(__is_compound(unsigned short))];
+ int t30[F(__is_compound(int))];
+ int t31[F(__is_compound(unsigned int))];
+ int t32[F(__is_compound(long))];
+ int t33[F(__is_compound(unsigned long))];
+ int t34[F(__is_compound(void))];
+ int t35[F(__is_compound(cvoid))];
+}
+
+void is_pointer()
+{
+ StructWithMembers x;
+
+ int t01[T(__is_pointer(void*))];
+ int t02[T(__is_pointer(cvoid*))];
+ int t03[T(__is_pointer(cvoid*))];
+ int t04[T(__is_pointer(char*))];
+ int t05[T(__is_pointer(int*))];
+ int t06[T(__is_pointer(int**))];
+ int t07[T(__is_pointer(ClassType*))];
+ int t08[T(__is_pointer(Derives*))];
+ int t09[T(__is_pointer(Enum*))];
+ int t10[T(__is_pointer(IntArNB*))];
+ int t11[T(__is_pointer(Union*))];
+ int t12[T(__is_pointer(UnionAr*))];
+ int t13[T(__is_pointer(StructWithMembers*))];
+ int t14[T(__is_pointer(void (*)()))];
+
+ int t20[F(__is_pointer(void))];
+ int t21[F(__is_pointer(cvoid))];
+ int t22[F(__is_pointer(cvoid))];
+ int t23[F(__is_pointer(char))];
+ int t24[F(__is_pointer(int))];
+ int t25[F(__is_pointer(int))];
+ int t26[F(__is_pointer(ClassType))];
+ int t27[F(__is_pointer(Derives))];
+ int t28[F(__is_pointer(Enum))];
+ int t29[F(__is_pointer(IntArNB))];
+ int t30[F(__is_pointer(Union))];
+ int t31[F(__is_pointer(UnionAr))];
+ int t32[F(__is_pointer(StructWithMembers))];
+ int t33[F(__is_pointer(int StructWithMembers::*))];
+ int t34[F(__is_pointer(void (StructWithMembers::*) ()))];
+}
+
+void is_member_object_pointer()
+{
+ StructWithMembers x;
+
+ int t01[T(__is_member_object_pointer(int StructWithMembers::*))];
+
+ int t10[F(__is_member_object_pointer(void (StructWithMembers::*) ()))];
+ int t11[F(__is_member_object_pointer(void*))];
+ int t12[F(__is_member_object_pointer(cvoid*))];
+ int t13[F(__is_member_object_pointer(cvoid*))];
+ int t14[F(__is_member_object_pointer(char*))];
+ int t15[F(__is_member_object_pointer(int*))];
+ int t16[F(__is_member_object_pointer(int**))];
+ int t17[F(__is_member_object_pointer(ClassType*))];
+ int t18[F(__is_member_object_pointer(Derives*))];
+ int t19[F(__is_member_object_pointer(Enum*))];
+ int t20[F(__is_member_object_pointer(IntArNB*))];
+ int t21[F(__is_member_object_pointer(Union*))];
+ int t22[F(__is_member_object_pointer(UnionAr*))];
+ int t23[F(__is_member_object_pointer(StructWithMembers*))];
+ int t24[F(__is_member_object_pointer(void))];
+ int t25[F(__is_member_object_pointer(cvoid))];
+ int t26[F(__is_member_object_pointer(cvoid))];
+ int t27[F(__is_member_object_pointer(char))];
+ int t28[F(__is_member_object_pointer(int))];
+ int t29[F(__is_member_object_pointer(int))];
+ int t30[F(__is_member_object_pointer(ClassType))];
+ int t31[F(__is_member_object_pointer(Derives))];
+ int t32[F(__is_member_object_pointer(Enum))];
+ int t33[F(__is_member_object_pointer(IntArNB))];
+ int t34[F(__is_member_object_pointer(Union))];
+ int t35[F(__is_member_object_pointer(UnionAr))];
+ int t36[F(__is_member_object_pointer(StructWithMembers))];
+ int t37[F(__is_member_object_pointer(void (*)()))];
+}
+
+void is_member_function_pointer()
+{
+ StructWithMembers x;
+
+ int t01[T(__is_member_function_pointer(void (StructWithMembers::*) ()))];
+
+ int t10[F(__is_member_function_pointer(int StructWithMembers::*))];
+ int t11[F(__is_member_function_pointer(void*))];
+ int t12[F(__is_member_function_pointer(cvoid*))];
+ int t13[F(__is_member_function_pointer(cvoid*))];
+ int t14[F(__is_member_function_pointer(char*))];
+ int t15[F(__is_member_function_pointer(int*))];
+ int t16[F(__is_member_function_pointer(int**))];
+ int t17[F(__is_member_function_pointer(ClassType*))];
+ int t18[F(__is_member_function_pointer(Derives*))];
+ int t19[F(__is_member_function_pointer(Enum*))];
+ int t20[F(__is_member_function_pointer(IntArNB*))];
+ int t21[F(__is_member_function_pointer(Union*))];
+ int t22[F(__is_member_function_pointer(UnionAr*))];
+ int t23[F(__is_member_function_pointer(StructWithMembers*))];
+ int t24[F(__is_member_function_pointer(void))];
+ int t25[F(__is_member_function_pointer(cvoid))];
+ int t26[F(__is_member_function_pointer(cvoid))];
+ int t27[F(__is_member_function_pointer(char))];
+ int t28[F(__is_member_function_pointer(int))];
+ int t29[F(__is_member_function_pointer(int))];
+ int t30[F(__is_member_function_pointer(ClassType))];
+ int t31[F(__is_member_function_pointer(Derives))];
+ int t32[F(__is_member_function_pointer(Enum))];
+ int t33[F(__is_member_function_pointer(IntArNB))];
+ int t34[F(__is_member_function_pointer(Union))];
+ int t35[F(__is_member_function_pointer(UnionAr))];
+ int t36[F(__is_member_function_pointer(StructWithMembers))];
+ int t37[F(__is_member_function_pointer(void (*)()))];
+}
+
+void is_member_pointer()
+{
+ StructWithMembers x;
+
+ int t01[T(__is_member_pointer(int StructWithMembers::*))];
+ int t02[T(__is_member_pointer(void (StructWithMembers::*) ()))];
+
+ int t10[F(__is_member_pointer(void*))];
+ int t11[F(__is_member_pointer(cvoid*))];
+ int t12[F(__is_member_pointer(cvoid*))];
+ int t13[F(__is_member_pointer(char*))];
+ int t14[F(__is_member_pointer(int*))];
+ int t15[F(__is_member_pointer(int**))];
+ int t16[F(__is_member_pointer(ClassType*))];
+ int t17[F(__is_member_pointer(Derives*))];
+ int t18[F(__is_member_pointer(Enum*))];
+ int t19[F(__is_member_pointer(IntArNB*))];
+ int t20[F(__is_member_pointer(Union*))];
+ int t21[F(__is_member_pointer(UnionAr*))];
+ int t22[F(__is_member_pointer(StructWithMembers*))];
+ int t23[F(__is_member_pointer(void))];
+ int t24[F(__is_member_pointer(cvoid))];
+ int t25[F(__is_member_pointer(cvoid))];
+ int t26[F(__is_member_pointer(char))];
+ int t27[F(__is_member_pointer(int))];
+ int t28[F(__is_member_pointer(int))];
+ int t29[F(__is_member_pointer(ClassType))];
+ int t30[F(__is_member_pointer(Derives))];
+ int t31[F(__is_member_pointer(Enum))];
+ int t32[F(__is_member_pointer(IntArNB))];
+ int t33[F(__is_member_pointer(Union))];
+ int t34[F(__is_member_pointer(UnionAr))];
+ int t35[F(__is_member_pointer(StructWithMembers))];
+ int t36[F(__is_member_pointer(void (*)()))];
+}
+
+void is_const()
+{
+ int t01[T(__is_const(cvoid))];
+ int t02[T(__is_const(const char))];
+ int t03[T(__is_const(const int))];
+ int t04[T(__is_const(const long))];
+ int t05[T(__is_const(const short))];
+ int t06[T(__is_const(const signed char))];
+ int t07[T(__is_const(const wchar_t))];
+ int t08[T(__is_const(const bool))];
+ int t09[T(__is_const(const float))];
+ int t10[T(__is_const(const double))];
+ int t11[T(__is_const(const long double))];
+ int t12[T(__is_const(const unsigned char))];
+ int t13[T(__is_const(const unsigned int))];
+ int t14[T(__is_const(const unsigned long long))];
+ int t15[T(__is_const(const unsigned long))];
+ int t16[T(__is_const(const unsigned short))];
+ int t17[T(__is_const(const void))];
+ int t18[T(__is_const(const ClassType))];
+ int t19[T(__is_const(const Derives))];
+ int t20[T(__is_const(const Enum))];
+ int t21[T(__is_const(const IntArNB))];
+ int t22[T(__is_const(const Union))];
+ int t23[T(__is_const(const UnionAr))];
+
+ int t30[F(__is_const(char))];
+ int t31[F(__is_const(int))];
+ int t32[F(__is_const(long))];
+ int t33[F(__is_const(short))];
+ int t34[F(__is_const(signed char))];
+ int t35[F(__is_const(wchar_t))];
+ int t36[F(__is_const(bool))];
+ int t37[F(__is_const(float))];
+ int t38[F(__is_const(double))];
+ int t39[F(__is_const(long double))];
+ int t40[F(__is_const(unsigned char))];
+ int t41[F(__is_const(unsigned int))];
+ int t42[F(__is_const(unsigned long long))];
+ int t43[F(__is_const(unsigned long))];
+ int t44[F(__is_const(unsigned short))];
+ int t45[F(__is_const(void))];
+ int t46[F(__is_const(ClassType))];
+ int t47[F(__is_const(Derives))];
+ int t48[F(__is_const(Enum))];
+ int t49[F(__is_const(IntArNB))];
+ int t50[F(__is_const(Union))];
+ int t51[F(__is_const(UnionAr))];
+}
+
+void is_volatile()
+{
+ int t02[T(__is_volatile(volatile char))];
+ int t03[T(__is_volatile(volatile int))];
+ int t04[T(__is_volatile(volatile long))];
+ int t05[T(__is_volatile(volatile short))];
+ int t06[T(__is_volatile(volatile signed char))];
+ int t07[T(__is_volatile(volatile wchar_t))];
+ int t08[T(__is_volatile(volatile bool))];
+ int t09[T(__is_volatile(volatile float))];
+ int t10[T(__is_volatile(volatile double))];
+ int t11[T(__is_volatile(volatile long double))];
+ int t12[T(__is_volatile(volatile unsigned char))];
+ int t13[T(__is_volatile(volatile unsigned int))];
+ int t14[T(__is_volatile(volatile unsigned long long))];
+ int t15[T(__is_volatile(volatile unsigned long))];
+ int t16[T(__is_volatile(volatile unsigned short))];
+ int t17[T(__is_volatile(volatile void))];
+ int t18[T(__is_volatile(volatile ClassType))];
+ int t19[T(__is_volatile(volatile Derives))];
+ int t20[T(__is_volatile(volatile Enum))];
+ int t21[T(__is_volatile(volatile IntArNB))];
+ int t22[T(__is_volatile(volatile Union))];
+ int t23[T(__is_volatile(volatile UnionAr))];
+
+ int t30[F(__is_volatile(char))];
+ int t31[F(__is_volatile(int))];
+ int t32[F(__is_volatile(long))];
+ int t33[F(__is_volatile(short))];
+ int t34[F(__is_volatile(signed char))];
+ int t35[F(__is_volatile(wchar_t))];
+ int t36[F(__is_volatile(bool))];
+ int t37[F(__is_volatile(float))];
+ int t38[F(__is_volatile(double))];
+ int t39[F(__is_volatile(long double))];
+ int t40[F(__is_volatile(unsigned char))];
+ int t41[F(__is_volatile(unsigned int))];
+ int t42[F(__is_volatile(unsigned long long))];
+ int t43[F(__is_volatile(unsigned long))];
+ int t44[F(__is_volatile(unsigned short))];
+ int t45[F(__is_volatile(void))];
+ int t46[F(__is_volatile(ClassType))];
+ int t47[F(__is_volatile(Derives))];
+ int t48[F(__is_volatile(Enum))];
+ int t49[F(__is_volatile(IntArNB))];
+ int t50[F(__is_volatile(Union))];
+ int t51[F(__is_volatile(UnionAr))];
+}
+
+struct TrivialStruct {
+ int member;
+};
+
+struct NonTrivialStruct {
+ int member;
+ NonTrivialStruct() {
+ member = 0;
+ }
+};
+
+void is_trivial2()
+{
+ int t01[T(__is_trivial(char))];
+ int t02[T(__is_trivial(int))];
+ int t03[T(__is_trivial(long))];
+ int t04[T(__is_trivial(short))];
+ int t05[T(__is_trivial(signed char))];
+ int t06[T(__is_trivial(wchar_t))];
+ int t07[T(__is_trivial(bool))];
+ int t08[T(__is_trivial(float))];
+ int t09[T(__is_trivial(double))];
+ int t10[T(__is_trivial(long double))];
+ int t11[T(__is_trivial(unsigned char))];
+ int t12[T(__is_trivial(unsigned int))];
+ int t13[T(__is_trivial(unsigned long long))];
+ int t14[T(__is_trivial(unsigned long))];
+ int t15[T(__is_trivial(unsigned short))];
+ int t16[T(__is_trivial(ClassType))];
+ int t17[T(__is_trivial(Derives))];
+ int t18[T(__is_trivial(Enum))];
+ int t19[T(__is_trivial(IntAr))];
+ int t20[T(__is_trivial(Union))];
+ int t21[T(__is_trivial(UnionAr))];
+ int t22[T(__is_trivial(TrivialStruct))];
+
+ int t30[F(__is_trivial(void))];
+ int t31[F(__is_trivial(NonTrivialStruct))];
+}
+
+struct CStruct {
+ int one;
+ int two;
+};
+
+struct CEmptyStruct {};
+
+struct CppEmptyStruct : CStruct {};
+struct CppStructStandard : CEmptyStruct {
+ int three;
+ int four;
+};
+struct CppStructNonStandardByBase : CStruct {
+ int three;
+ int four;
+};
+struct CppStructNonStandardByVirt : CStruct {
+ virtual void method() {}
+};
+struct CppStructNonStandardByMemb : CStruct {
+ CppStructNonStandardByVirt member;
+};
+struct CppStructNonStandardByProt : CStruct {
+ int five;
+protected:
+ int six;
+};
+struct CppStructNonStandardByVirtBase : virtual CStruct {
+};
+struct CppStructNonStandardBySameBase : CEmptyStruct {
+ CEmptyStruct member;
+};
+struct CppStructNonStandardBy2ndVirtBase : CEmptyStruct {
+ CEmptyStruct member;
+};
+
+void is_standard_layout()
+{
+ typedef const int ConstInt;
+ typedef ConstInt ConstIntAr[4];
+ typedef CppStructStandard CppStructStandardAr[4];
+
+ int t01[T(__is_standard_layout(int))];
+ int t02[T(__is_standard_layout(ConstInt))];
+ int t03[T(__is_standard_layout(ConstIntAr))];
+ int t04[T(__is_standard_layout(CStruct))];
+ int t05[T(__is_standard_layout(CppStructStandard))];
+ int t06[T(__is_standard_layout(CppStructStandardAr))];
+
+ typedef CppStructNonStandardByBase CppStructNonStandardByBaseAr[4];
+
+ int t10[F(__is_standard_layout(CppStructNonStandardByVirt))];
+ int t11[F(__is_standard_layout(CppStructNonStandardByMemb))];
+ int t12[F(__is_standard_layout(CppStructNonStandardByProt))];
+ int t13[F(__is_standard_layout(CppStructNonStandardByVirtBase))];
+ int t14[F(__is_standard_layout(CppStructNonStandardByBase))];
+ int t15[F(__is_standard_layout(CppStructNonStandardByBaseAr))];
+ int t16[F(__is_standard_layout(CppStructNonStandardBySameBase))];
+ int t17[F(__is_standard_layout(CppStructNonStandardBy2ndVirtBase))];
+}
+
+void is_signed()
+{
+ //int t01[T(__is_signed(char))];
+ int t02[T(__is_signed(int))];
+ int t03[T(__is_signed(long))];
+ int t04[T(__is_signed(short))];
+ int t05[T(__is_signed(signed char))];
+ int t06[T(__is_signed(wchar_t))];
+
+ int t10[F(__is_signed(bool))];
+ int t11[F(__is_signed(cvoid))];
+ int t12[F(__is_signed(float))];
+ int t13[F(__is_signed(double))];
+ int t14[F(__is_signed(long double))];
+ int t15[F(__is_signed(unsigned char))];
+ int t16[F(__is_signed(unsigned int))];
+ int t17[F(__is_signed(unsigned long long))];
+ int t18[F(__is_signed(unsigned long))];
+ int t19[F(__is_signed(unsigned short))];
+ int t20[F(__is_signed(void))];
+ int t21[F(__is_signed(ClassType))];
+ int t22[F(__is_signed(Derives))];
+ int t23[F(__is_signed(Enum))];
+ int t24[F(__is_signed(IntArNB))];
+ int t25[F(__is_signed(Union))];
+ int t26[F(__is_signed(UnionAr))];
+}
+
+void is_unsigned()
+{
+ int t01[T(__is_unsigned(bool))];
+ int t02[T(__is_unsigned(unsigned char))];
+ int t03[T(__is_unsigned(unsigned short))];
+ int t04[T(__is_unsigned(unsigned int))];
+ int t05[T(__is_unsigned(unsigned long))];
+ int t06[T(__is_unsigned(unsigned long long))];
+ int t07[T(__is_unsigned(Enum))];
+
+ int t10[F(__is_unsigned(void))];
+ int t11[F(__is_unsigned(cvoid))];
+ int t12[F(__is_unsigned(float))];
+ int t13[F(__is_unsigned(double))];
+ int t14[F(__is_unsigned(long double))];
+ int t16[F(__is_unsigned(char))];
+ int t17[F(__is_unsigned(signed char))];
+ int t18[F(__is_unsigned(wchar_t))];
+ int t19[F(__is_unsigned(short))];
+ int t20[F(__is_unsigned(int))];
+ int t21[F(__is_unsigned(long))];
+ int t22[F(__is_unsigned(Union))];
+ int t23[F(__is_unsigned(UnionAr))];
+ int t24[F(__is_unsigned(Derives))];
+ int t25[F(__is_unsigned(ClassType))];
+ int t26[F(__is_unsigned(IntArNB))];
+}
+
typedef Int& IntRef;
typedef const IntAr ConstIntAr;
typedef ConstIntAr ConstIntArAr[4];
@@ -556,6 +1323,64 @@
isBaseOfF<DerivedB<int>, BaseA<int> >();
}
+#if 0
+template<class T, class U>
+class TemplateClass {};
+
+template<class T>
+using TemplateAlias = TemplateClass<T, int>;
+#endif
+
+typedef class Base BaseTypedef;
+
+void is_same()
+{
+ int t01[T(__is_same(Base, Base))];
+ int t02[T(__is_same(Base, BaseTypedef))];
+#if 0
+ int t03[T(__is_same(TemplateClass<int, int>, TemplateAlias<int>))];
+#endif
+
+ int t10[F(__is_same(Base, const Base))];
+ int t11[F(__is_same(Base, Base&))];
+ int t12[F(__is_same(Base, Derived))];
+}
+
+struct IntWrapper
+{
+ int value;
+ IntWrapper(int _value) : value(_value) {}
+ operator int() const {
+ return value;
+ }
+};
+
+struct FloatWrapper
+{
+ float value;
+ FloatWrapper(float _value) : value(_value) {}
+ FloatWrapper(const IntWrapper& obj)
+ : value(static_cast<float>(obj.value)) {}
+ operator float() const {
+ return value;
+ }
+ operator IntWrapper() const {
+ return IntWrapper(static_cast<int>(value));
+ }
+};
+
+void is_convertible()
+{
+ int t01[T(__is_convertible(IntWrapper, IntWrapper))];
+ int t02[T(__is_convertible(IntWrapper, const IntWrapper))];
+ int t03[T(__is_convertible(IntWrapper, int))];
+ int t04[T(__is_convertible(int, IntWrapper))];
+ int t05[T(__is_convertible(IntWrapper, FloatWrapper))];
+ int t06[T(__is_convertible(FloatWrapper, IntWrapper))];
+ int t07[T(__is_convertible(FloatWrapper, float))];
+ int t08[T(__is_convertible(float, FloatWrapper))];
+}
+
struct FromInt { FromInt(int); };
struct ToInt { operator int(); };
typedef void Function();
More information about the cfe-commits
mailing list