From: Chandler Carruth Date: Sun, 1 May 2011 06:11:07 +0000 (+0000) Subject: Order the type traits according to the standard's listing of unary type X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c41d6b57f3a42fbe29e33b73e670b398fade4718;p=clang Order the type traits according to the standard's listing of unary type traits where possible. For the rest, group them and add some documentation regarding their origins. No functionality change intended. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130639 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index ef6e2c35d3..5e1c6ba162 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2364,70 +2364,52 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, QualType T, ASTContext &C = Self.Context; switch(UTT) { default: assert(false && "Unknown type trait or not implemented"); - case UTT_IsPOD: - return T->isPODType(); - case UTT_IsLiteral: - return T->isLiteralType(); - case UTT_IsTrivial: - return T->isTrivialType(); - case UTT_IsClass: - if (const RecordType *Record = T->getAs()) - return !Record->getDecl()->isUnion(); - return false; - case UTT_IsUnion: - if (const RecordType *Record = T->getAs()) - return Record->getDecl()->isUnion(); - return false; - case UTT_IsEnum: - return T->isEnumeralType(); - case UTT_IsPolymorphic: - if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) - return RD->isPolymorphic(); - return false; - case UTT_IsAbstract: - if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) - return RD->isAbstract(); - return false; - case UTT_IsEmpty: - if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) - return !RD->isUnion() && RD->isEmpty(); - return false; + + // Type trait expressions corresponding to the primary type category + // predicates in C++0x [meta.unary.cat]. + case UTT_IsVoid: + return T->isVoidType(); 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_IsPointer: + return T->isPointerType(); case UTT_IsLvalueReference: return T->isLValueReferenceType(); + case UTT_IsRvalueReference: + return T->isRValueReferenceType(); case UTT_IsMemberFunctionPointer: return T->isMemberFunctionPointerType(); case UTT_IsMemberObjectPointer: return T->isMemberDataPointerType(); - case UTT_IsMemberPointer: - return T->isMemberPointerType(); + case UTT_IsEnum: + return T->isEnumeralType(); + case UTT_IsUnion: + if (const RecordType *Record = T->getAs()) + return Record->getDecl()->isUnion(); + return false; + case UTT_IsClass: + if (const RecordType *Record = T->getAs()) + return !Record->getDecl()->isUnion(); + return false; + case UTT_IsFunction: + return T->isFunctionType(); + + // Type trait expressions which correspond to the convenient composition + // predicates in C++0x [meta.unary.comp]. + case UTT_IsReference: + return T->isReferenceType(); + case UTT_IsArithmetic: + return T->isArithmeticType() && ! T->isEnumeralType(); + case UTT_IsFundamental: + return T->isVoidType() || (T->isArithmeticType() && ! T->isEnumeralType()); 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: @@ -2435,16 +2417,50 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, QualType 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_IsCompound: + return ! (T->isVoidType() || T->isArithmeticType()) || T->isEnumeralType(); + case UTT_IsMemberPointer: + return T->isMemberPointerType(); + + // Type trait expressions which correspond to the type property predicates + // in C++0x [meta.unary.prop]. + case UTT_IsConst: + return T.isConstQualified(); + case UTT_IsVolatile: + return T.isVolatileQualified(); + case UTT_IsTrivial: + return T->isTrivialType(); case UTT_IsStandardLayout: return T->isStandardLayoutType(); + case UTT_IsPOD: + return T->isPODType(); + case UTT_IsLiteral: + return T->isLiteralType(); + case UTT_IsEmpty: + if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) + return !RD->isUnion() && RD->isEmpty(); + return false; + case UTT_IsPolymorphic: + if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) + return RD->isPolymorphic(); + return false; + case UTT_IsAbstract: + if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) + return RD->isAbstract(); + return false; + case UTT_IsSigned: + return T->isSignedIntegerType(); case UTT_IsUnsigned: return T->isUnsignedIntegerType(); - case UTT_IsVoid: - return T->isVoidType(); - case UTT_IsVolatile: - return T.isVolatileQualified(); + + // Type trait expressions which query classes regarding their construction, + // destruction, and copying. Rather than being based directly on the + // related type predicates in the standard, they are specified by both + // GCC[1] and the Embarcadero C++ compiler[2], and Clang implements those + // specifications. + // + // 1: http://gcc.gnu/.org/onlinedocs/gcc/Type-Traits.html + // 2: http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index 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 @@ -2625,6 +2641,15 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, QualType T, return Destructor->isVirtual(); } return false; + + // These type trait expressions are modeled on the specifications for the + // Embarcadero C++0x type trait functions: + // http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index + case UTT_IsCompleteType: + // http://docwiki.embarcadero.com/RADStudio/XE/en/Is_complete_type_(typename_T_): + // Returns True if and only if T is a complete type at the point of the + // function call. + return !T->isIncompleteType(); } }