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

llvm-svn: 130342
This commit is contained in:
John Wiegley 2011-04-27 23:09:49 +00:00
parent 08704349da
commit 65497cce20
13 changed files with 1231 additions and 42 deletions

View File

@ -306,6 +306,21 @@ class CXXRecordDecl : public RecordDecl {
/// 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 @@ public:
/// 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; }

View File

@ -1171,7 +1171,7 @@ public:
/// (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 @@ public:
// 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); }

View File

@ -350,6 +350,35 @@ KEYWORD(__is_union , KEYCXX)
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)

View File

@ -27,21 +27,48 @@ namespace clang {
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.

View File

@ -926,6 +926,10 @@ CXXDestructorDecl *CXXRecordDecl::getDestructor() const {
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) {

View File

@ -1251,23 +1251,48 @@ void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
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(UnaryTypeTrait UTT) {
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";
}

View File

@ -1385,6 +1385,109 @@ bool RecordType::classof(const TagType *TT) {
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());
}

View File

@ -731,22 +731,19 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// 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);
}

View File

@ -519,6 +519,34 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
/// '::'[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 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
/// 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 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
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 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
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();

View File

@ -1912,25 +1912,50 @@ Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {
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 @@ static BinaryTypeTrait BinaryTypeTraitFromTokKind(tok::TokenKind kind) {
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;
}

View File

@ -2379,6 +2379,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, QualType T,
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 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, QualType T,
&& 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 @@ ExprResult Sema::BuildUnaryTypeTrait(UnaryTypeTrait UTT,
// 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 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT,
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 @@ ExprResult Sema::BuildBinaryTypeTrait(BinaryTypeTrait BTT,
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;
}

View File

@ -183,7 +183,7 @@ template <typename T> typename T::U ft6(const T&) { return 0; }
// 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 @@ template<typename T> struct __enable_if<true, T> {
};
// 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 @@ struct S7 {
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<bool, typename> struct __enable_if {};
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>(); }
}

View File

@ -244,6 +244,773 @@ void is_polymorphic()
{ 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 @@ void is_base_of() {
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();