[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