]> granicus.if.org Git - clang/commitdiff
Order the type traits according to the standard's listing of unary type
authorChandler Carruth <chandlerc@gmail.com>
Sun, 1 May 2011 06:11:07 +0000 (06:11 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Sun, 1 May 2011 06:11:07 +0000 (06:11 +0000)
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

lib/Sema/SemaExprCXX.cpp

index ef6e2c35d3a99a3f5b8387143d97aae8dcdd51d3..5e1c6ba16261473ff5d632b34ec8f8986969c2e3 100644 (file)
@@ -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<RecordType>())
-      return !Record->getDecl()->isUnion();
-    return false;
-  case UTT_IsUnion:
-    if (const RecordType *Record = T->getAs<RecordType>())
-      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<RecordType>())
+      return Record->getDecl()->isUnion();
+    return false;
+  case UTT_IsClass:
+    if (const RecordType *Record = T->getAs<RecordType>())
+      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();
   }
 }