[cfe-commits] r151352 - in /cfe/trunk: docs/ include/clang/AST/ include/clang/Basic/ include/clang/Parse/ include/clang/Sema/ include/clang/Serialization/ lib/AST/ lib/Lex/ lib/Parse/ lib/Sema/ lib/Serialization/ lib/StaticAnalyzer/Core/ test/Index/ test/PCH/ test/SemaCXX/ tools/libclang/

Douglas Gregor dgregor at apple.com
Thu Feb 23 23:38:35 PST 2012


Author: dgregor
Date: Fri Feb 24 01:38:34 2012
New Revision: 151352

URL: http://llvm.org/viewvc/llvm-project?rev=151352&view=rev
Log:
Implement a new type trait __is_trivially_constructible(T, Args...)
that provides the behavior of the C++11 library trait
std::is_trivially_constructible<T, Args...>, which can't be
implemented purely as a library.

Since __is_trivially_constructible can have zero or more arguments, I
needed to add Yet Another Type Trait Expression Class, this one
handling arbitrary arguments. The next step will be to migrate
UnaryTypeTrait and BinaryTypeTrait over to this new, more general
TypeTrait class.

Fixes the Clang side of <rdar://problem/10895483> / PR12038.

Modified:
    cfe/trunk/docs/LanguageExtensions.html
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/include/clang/AST/Stmt.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Basic/StmtNodes.td
    cfe/trunk/include/clang/Basic/TokenKinds.def
    cfe/trunk/include/clang/Basic/TypeTraits.h
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/ExprCXX.cpp
    cfe/trunk/lib/AST/ExprClassification.cpp
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/lib/AST/ItaniumMangle.cpp
    cfe/trunk/lib/AST/StmtPrinter.cpp
    cfe/trunk/lib/AST/StmtProfile.cpp
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Parse/ParseTentative.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
    cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
    cfe/trunk/test/Index/annotate-tokens-cxx0x.cpp
    cfe/trunk/test/PCH/cxx-traits.cpp
    cfe/trunk/test/PCH/cxx-traits.h
    cfe/trunk/test/SemaCXX/type-traits.cpp
    cfe/trunk/tools/libclang/CIndex.cpp
    cfe/trunk/tools/libclang/CXCursor.cpp

Modified: cfe/trunk/docs/LanguageExtensions.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.html?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/docs/LanguageExtensions.html (original)
+++ cfe/trunk/docs/LanguageExtensions.html Fri Feb 24 01:38:34 2012
@@ -889,6 +889,8 @@
   <li><code>__is_literal(type)</code>: Determines whether the given type is a literal type</li>
   <li><code>__is_final</code>: Determines whether the given type is declared with a <code>final</code> class-virt-specifier.</li>
   <li><code>__underlying_type(type)</code>: Retrieves the underlying type for a given <code>enum</code> type. This trait is required to implement the C++11 standard library.</li>
+  <li><code>__is_trivially_assignable(totype, fromtype)</code>: Determines whether a value of type <tt>totype</tt> can be assigned to from a value of type <tt>fromtype</tt> such that no non-trivial functions are called as part of that assignment. This trait is required to implement the C++11 standard library.</li>
+  <li><code>__is_trivially_constructible(type, argtypes...)</code>: Determines whether a value of type <tt>type</tt> can be direct-initialized with arguments of types <tt>argtypes...</tt> such that no non-trivial functions are called as part of that initialization. This trait is required to implement the C++11 standard library.</li>
 </ul>
 
 <!-- ======================================================================= -->

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Fri Feb 24 01:38:34 2012
@@ -1926,6 +1926,102 @@
   friend class ASTStmtReader;
 };
 
+/// \brief A type trait used in the implementation of various C++11 and
+/// Library TR1 trait templates.
+///
+/// \code
+///   __is_trivially_constructible(vector<int>, int*, int*)
+/// \endcode
+class TypeTraitExpr : public Expr {
+  /// \brief The location of the type trait keyword.
+  SourceLocation Loc;
+  
+  /// \brief  The location of the closing parenthesis.
+  SourceLocation RParenLoc;
+  
+  // Note: The TypeSourceInfos for the arguments are allocated after the
+  // TypeTraitExpr.
+  
+  TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
+                ArrayRef<TypeSourceInfo *> Args,
+                SourceLocation RParenLoc,
+                bool Value);
+
+  TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) { }
+
+  /// \brief Retrieve the argument types.
+  TypeSourceInfo **getTypeSourceInfos() {
+    return reinterpret_cast<TypeSourceInfo **>(this+1);
+  }
+  
+  /// \brief Retrieve the argument types.
+  TypeSourceInfo * const *getTypeSourceInfos() const {
+    return reinterpret_cast<TypeSourceInfo * const*>(this+1);
+  }
+  
+public:
+  /// \brief Create a new type trait expression.
+  static TypeTraitExpr *Create(ASTContext &C, QualType T, SourceLocation Loc, 
+                               TypeTrait Kind,
+                               ArrayRef<TypeSourceInfo *> Args,
+                               SourceLocation RParenLoc,
+                               bool Value);
+
+  static TypeTraitExpr *CreateDeserialized(ASTContext &C, unsigned NumArgs);
+  
+  /// \brief Determine which type trait this expression uses.
+  TypeTrait getTrait() const {
+    return static_cast<TypeTrait>(TypeTraitExprBits.Kind);
+  }
+
+  bool getValue() const { 
+    assert(!isValueDependent()); 
+    return TypeTraitExprBits.Value; 
+  }
+  
+  /// \brief Determine the number of arguments to this type trait.
+  unsigned getNumArgs() const { return TypeTraitExprBits.NumArgs; }
+  
+  /// \brief Retrieve the Ith argument.
+  TypeSourceInfo *getArg(unsigned I) const {
+    assert(I < getNumArgs() && "Argument out-of-range");
+    return getArgs()[I];
+  }
+  
+  /// \brief Retrieve the argument types.
+  ArrayRef<TypeSourceInfo *> getArgs() const { 
+    return ArrayRef<TypeSourceInfo *>(getTypeSourceInfos(), getNumArgs());
+  }
+  
+  typedef TypeSourceInfo **arg_iterator;
+  arg_iterator arg_begin() { 
+    return getTypeSourceInfos(); 
+  }
+  arg_iterator arg_end() { 
+    return getTypeSourceInfos() + getNumArgs(); 
+  }
+
+  typedef TypeSourceInfo const * const *arg_const_iterator;
+  arg_const_iterator arg_begin() const { return getTypeSourceInfos(); }
+  arg_const_iterator arg_end() const { 
+    return getTypeSourceInfos() + getNumArgs(); 
+  }
+
+  SourceRange getSourceRange() const { return SourceRange(Loc, RParenLoc); }
+  
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == TypeTraitExprClass;
+  }
+  static bool classof(const TypeTraitExpr *) { return true; }
+  
+  // Iterators
+  child_range children() { return child_range(); }
+  
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+
+};
+  
 /// ArrayTypeTraitExpr - An Embarcadero array type trait, as used in the
 /// implementation of __array_rank and __array_extent.
 /// Example:

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Fri Feb 24 01:38:34 2012
@@ -1946,6 +1946,11 @@
     TRY_TO(TraverseTypeLoc(S->getRhsTypeSourceInfo()->getTypeLoc()));
   })
 
+DEF_TRAVERSE_STMT(TypeTraitExpr, {
+  for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
+    TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
+})
+
 DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
     TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
   })

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Fri Feb 24 01:38:34 2012
@@ -227,6 +227,24 @@
     unsigned InitializesStdInitializerList : 1;
   };
 
+  class TypeTraitExprBitfields {
+    friend class TypeTraitExpr;
+    friend class ASTStmtReader;
+    friend class ASTStmtWriter;
+    
+    unsigned : NumExprBits;
+    
+    /// \brief The kind of type trait, which is a value of a TypeTrait enumerator.
+    unsigned Kind : 8;
+    
+    /// \brief If this expression is not value-dependent, this indicates whether
+    /// the trait evaluated true or false.
+    unsigned Value : 1;
+
+    /// \brief The number of arguments to this type trait.
+    unsigned NumArgs : 32 - 8 - 1 - NumExprBits;
+  };
+  
   union {
     // FIXME: this is wasteful on 64-bit platforms.
     void *Aligner;
@@ -241,9 +259,11 @@
     PseudoObjectExprBitfields PseudoObjectExprBits;
     ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
     InitListExprBitfields InitListExprBits;
+    TypeTraitExprBitfields TypeTraitExprBits;
   };
 
   friend class ASTStmtReader;
+  friend class ASTStmtWriter;
 
 public:
   // Only allow allocation of Stmts using the allocator in ASTContext

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Feb 24 01:38:34 2012
@@ -4438,6 +4438,10 @@
 
 def err_incomplete_type_used_in_type_trait_expr : Error<
   "incomplete type %0 used in type trait expression">;
+def err_type_trait_arity : Error<
+  "type trait requires %0%select{| or more}1 argument%select{|s}2; have "
+  "%3 argument%s3">;
+  
 def err_dimension_expr_not_constant_integer : Error<
   "dimension expression does not evaluate to a constant unsigned int">;
 def err_expected_ident_or_lparen : Error<"expected identifier or '('">;

Modified: cfe/trunk/include/clang/Basic/StmtNodes.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/StmtNodes.td?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/StmtNodes.td (original)
+++ cfe/trunk/include/clang/Basic/StmtNodes.td Fri Feb 24 01:38:34 2012
@@ -107,6 +107,7 @@
 def CXXNewExpr : DStmt<Expr>;
 def CXXDeleteExpr : DStmt<Expr>;
 def CXXPseudoDestructorExpr : DStmt<Expr>;
+def TypeTraitExpr : DStmt<Expr>;
 def UnaryTypeTraitExpr : DStmt<Expr>;
 def BinaryTypeTraitExpr : DStmt<Expr>;
 def ArrayTypeTraitExpr : DStmt<Expr>;

Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Fri Feb 24 01:38:34 2012
@@ -365,6 +365,7 @@
 KEYWORD(__is_union                  , KEYCXX)
 
 // Clang-only C++ Type Traits
+KEYWORD(__is_trivially_constructible, KEYCXX)
 KEYWORD(__is_trivially_copyable     , KEYCXX)
 KEYWORD(__is_trivially_assignable   , KEYCXX)
 KEYWORD(__underlying_type           , KEYCXX)

Modified: cfe/trunk/include/clang/Basic/TypeTraits.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TypeTraits.h?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TypeTraits.h (original)
+++ cfe/trunk/include/clang/Basic/TypeTraits.h Fri Feb 24 01:38:34 2012
@@ -84,6 +84,12 @@
     UETT_AlignOf,
     UETT_VecStep
   };
+  
+  /// \brief Names for type traits that operate specifically on types.
+  enum TypeTrait {
+    TT_IsTriviallyConstructible
+  };
+  
 }
 
 #endif

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Feb 24 01:38:34 2012
@@ -2170,7 +2170,8 @@
   // GNU G++: Type Traits [Type-Traits.html in the GCC manual]
   ExprResult ParseUnaryTypeTrait();
   ExprResult ParseBinaryTypeTrait();
-
+  ExprResult ParseTypeTrait();
+  
   //===--------------------------------------------------------------------===//
   // Embarcadero: Arary and Expression Traits
   ExprResult ParseArrayTypeTrait();

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Feb 24 01:38:34 2012
@@ -3317,6 +3317,14 @@
                                   TypeSourceInfo *RhsT,
                                   SourceLocation RParen);
 
+  /// \brief Parsed one of the type trait support pseudo-functions.
+  ExprResult ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
+                            ArrayRef<ParsedType> Args,
+                            SourceLocation RParenLoc);
+  ExprResult BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
+                            ArrayRef<TypeSourceInfo *> Args,
+                            SourceLocation RParenLoc);
+  
   /// ActOnArrayTypeTrait - Parsed one of the bianry type trait support
   /// pseudo-functions.
   ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT,

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Fri Feb 24 01:38:34 2012
@@ -1156,6 +1156,7 @@
       EXPR_OPAQUE_VALUE,          // OpaqueValueExpr
       EXPR_BINARY_CONDITIONAL_OPERATOR,  // BinaryConditionalOperator
       EXPR_BINARY_TYPE_TRAIT,     // BinaryTypeTraitExpr
+      EXPR_TYPE_TRAIT,            // TypeTraitExpr
       EXPR_ARRAY_TYPE_TRAIT,      // ArrayTypeTraitIntExpr
       
       EXPR_PACK_EXPANSION,        // PackExpansionExpr

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Fri Feb 24 01:38:34 2012
@@ -2169,6 +2169,7 @@
   case AddrLabelExprClass:
   case ArrayTypeTraitExprClass:
   case BinaryTypeTraitExprClass:
+  case TypeTraitExprClass:
   case CXXBoolLiteralExprClass:
   case CXXNoexceptExprClass:
   case CXXNullPtrLiteralExprClass:

Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Fri Feb 24 01:38:34 2012
@@ -199,7 +199,6 @@
   return SourceRange(Base->getLocStart(), End);
 }
 
-
 // UnresolvedLookupExpr
 UnresolvedLookupExpr *
 UnresolvedLookupExpr::Create(ASTContext &C, 
@@ -1262,4 +1261,51 @@
   return TemplateArgument(Arguments, NumArguments);
 }
 
+TypeTraitExpr::TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
+                             ArrayRef<TypeSourceInfo *> Args,
+                             SourceLocation RParenLoc,
+                             bool Value)
+  : Expr(TypeTraitExprClass, T, VK_RValue, OK_Ordinary,
+         /*TypeDependent=*/false,
+         /*ValueDependent=*/false,
+         /*InstantiationDependent=*/false,
+         /*ContainsUnexpandedParameterPack=*/false),
+    Loc(Loc), RParenLoc(RParenLoc)
+{
+  TypeTraitExprBits.Kind = Kind;
+  TypeTraitExprBits.Value = Value;
+  TypeTraitExprBits.NumArgs = Args.size();
+
+  TypeSourceInfo **ToArgs = getTypeSourceInfos();
+  
+  for (unsigned I = 0, N = Args.size(); I != N; ++I) {
+    if (Args[I]->getType()->isDependentType())
+      setValueDependent(true);
+    if (Args[I]->getType()->isInstantiationDependentType())
+      setInstantiationDependent(true);
+    if (Args[I]->getType()->containsUnexpandedParameterPack())
+      setContainsUnexpandedParameterPack(true);
+    
+    ToArgs[I] = Args[I];
+  }
+}
+
+TypeTraitExpr *TypeTraitExpr::Create(ASTContext &C, QualType T, 
+                                     SourceLocation Loc, 
+                                     TypeTrait Kind,
+                                     ArrayRef<TypeSourceInfo *> Args,
+                                     SourceLocation RParenLoc,
+                                     bool Value) {
+  unsigned Size = sizeof(TypeTraitExpr) + sizeof(TypeSourceInfo*) * Args.size();
+  void *Mem = C.Allocate(Size);
+  return new (Mem) TypeTraitExpr(T, Loc, Kind, Args, RParenLoc, Value);
+}
+
+TypeTraitExpr *TypeTraitExpr::CreateDeserialized(ASTContext &C,
+                                                 unsigned NumArgs) {
+  unsigned Size = sizeof(TypeTraitExpr) + sizeof(TypeSourceInfo*) * NumArgs;
+  void *Mem = C.Allocate(Size);
+  return new (Mem) TypeTraitExpr(EmptyShell());
+}
+
 void ArrayTypeTraitExpr::anchor() { }

Modified: cfe/trunk/lib/AST/ExprClassification.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprClassification.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprClassification.cpp (original)
+++ cfe/trunk/lib/AST/ExprClassification.cpp Fri Feb 24 01:38:34 2012
@@ -151,6 +151,7 @@
   case Expr::CXXScalarValueInitExprClass:
   case Expr::UnaryTypeTraitExprClass:
   case Expr::BinaryTypeTraitExprClass:
+  case Expr::TypeTraitExprClass:
   case Expr::ArrayTypeTraitExprClass:
   case Expr::ExpressionTraitExprClass:
   case Expr::ObjCSelectorExprClass:

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Fri Feb 24 01:38:34 2012
@@ -4119,6 +4119,10 @@
     return Success(E->getValue(), E);
   }
 
+  bool VisitTypeTraitExpr(const TypeTraitExpr *E) {
+    return Success(E->getValue(), E);
+  }
+
   bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
     return Success(E->getValue(), E);
   }
@@ -6360,6 +6364,7 @@
   case Expr::CXXScalarValueInitExprClass:
   case Expr::UnaryTypeTraitExprClass:
   case Expr::BinaryTypeTraitExprClass:
+  case Expr::TypeTraitExprClass:
   case Expr::ArrayTypeTraitExprClass:
   case Expr::ExpressionTraitExprClass:
   case Expr::CXXNoexceptExprClass:

Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Fri Feb 24 01:38:34 2012
@@ -2383,6 +2383,7 @@
   case Expr::StmtExprClass:
   case Expr::UnaryTypeTraitExprClass:
   case Expr::BinaryTypeTraitExprClass:
+  case Expr::TypeTraitExprClass:
   case Expr::ArrayTypeTraitExprClass:
   case Expr::ExpressionTraitExprClass:
   case Expr::VAArgExprClass:

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Fri Feb 24 01:38:34 2012
@@ -1555,6 +1555,13 @@
   llvm_unreachable("Binary type trait not covered by switch");
 }
 
+static const char *getTypeTraitName(TypeTrait TT) {
+  switch (TT) {
+  case clang::TT_IsTriviallyConstructible:return "__is_trivially_constructible";
+  }
+  llvm_unreachable("Type trait not covered by switch");
+}
+
 static const char *getTypeTraitName(ArrayTypeTrait ATT) {
   switch (ATT) {
   case ATT_ArrayRank:        return "__array_rank";
@@ -1582,6 +1589,16 @@
      << E->getRhsType().getAsString(Policy) << ")";
 }
 
+void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
+  OS << getTypeTraitName(E->getTrait()) << "(";
+  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
+    if (I > 0)
+      OS << ", ";
+    OS << E->getArg(I)->getType().getAsString(Policy);
+  }
+  OS << ")";
+}
+
 void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
   OS << getTypeTraitName(E->getTrait()) << "("
      << E->getQueriedType().getAsString(Policy) << ")";

Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Fri Feb 24 01:38:34 2012
@@ -868,6 +868,14 @@
   VisitType(S->getRhsType());
 }
 
+void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) {
+  VisitExpr(S);
+  ID.AddInteger(S->getTrait());
+  ID.AddInteger(S->getNumArgs());
+  for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
+    VisitType(S->getArg(I)->getType());
+}
+
 void StmtProfiler::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *S) {
   VisitExpr(S);
   ID.AddInteger(S->getTrait());

Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Fri Feb 24 01:38:34 2012
@@ -701,6 +701,7 @@
            .Case("is_polymorphic", LangOpts.CPlusPlus)
            .Case("is_trivial", LangOpts.CPlusPlus)
            .Case("is_trivially_assignable", LangOpts.CPlusPlus)
+           .Case("is_trivially_constructible", LangOpts.CPlusPlus)
            .Case("is_trivially_copyable", LangOpts.CPlusPlus)
            .Case("is_union", LangOpts.CPlusPlus)
            .Case("modules", LangOpts.Modules)

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Fri Feb 24 01:38:34 2012
@@ -1143,6 +1143,9 @@
   case tok::kw___is_trivially_assignable:
     return ParseBinaryTypeTrait();
 
+  case tok::kw___is_trivially_constructible:
+    return ParseTypeTrait();
+      
   case tok::kw___array_rank:
   case tok::kw___array_extent:
     return ParseArrayTypeTrait();

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Fri Feb 24 01:38:34 2012
@@ -2458,6 +2458,14 @@
   }
 }
 
+static TypeTrait TypeTraitFromTokKind(tok::TokenKind kind) {
+  switch (kind) {
+  default: llvm_unreachable("Not a known type trait");
+  case tok::kw___is_trivially_constructible: 
+    return TT_IsTriviallyConstructible;
+  }
+}
+
 static ArrayTypeTrait ArrayTypeTraitFromTokKind(tok::TokenKind kind) {
   switch(kind) {
   default: llvm_unreachable("Not a known binary type trait");
@@ -2540,6 +2548,58 @@
                                       T.getCloseLocation());
 }
 
+/// \brief Parse the built-in type-trait pseudo-functions that allow 
+/// implementation of the TR1/C++11 type traits templates.
+///
+///       primary-expression:
+///          type-trait '(' type-id-seq ')'
+///
+///       type-id-seq:
+///          type-id ...[opt] type-id-seq[opt]
+///
+ExprResult Parser::ParseTypeTrait() {
+  TypeTrait Kind = TypeTraitFromTokKind(Tok.getKind());
+  SourceLocation Loc = ConsumeToken();
+  
+  BalancedDelimiterTracker Parens(*this, tok::l_paren);
+  if (Parens.expectAndConsume(diag::err_expected_lparen))
+    return ExprError();
+
+  llvm::SmallVector<ParsedType, 2> Args;
+  do {
+    // Parse the next type.
+    TypeResult Ty = ParseTypeName();
+    if (Ty.isInvalid()) {
+      Parens.skipToEnd();
+      return ExprError();
+    }
+
+    // Parse the ellipsis, if present.
+    if (Tok.is(tok::ellipsis)) {
+      Ty = Actions.ActOnPackExpansion(Ty.get(), ConsumeToken());
+      if (Ty.isInvalid()) {
+        Parens.skipToEnd();
+        return ExprError();
+      }
+    }
+    
+    // Add this type to the list of arguments.
+    Args.push_back(Ty.get());
+    
+    if (Tok.is(tok::comma)) {
+      ConsumeToken();
+      continue;
+    }
+    
+    break;
+  } while (true);
+  
+  if (Parens.consumeClose())
+    return ExprError();
+  
+  return Actions.ActOnTypeTrait(Kind, Loc, Args, Parens.getCloseLocation());
+}
+
 /// ParseArrayTypeTrait - Parse the built-in array type-trait
 /// pseudo-functions.
 ///

Modified: cfe/trunk/lib/Parse/ParseTentative.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTentative.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTentative.cpp Fri Feb 24 01:38:34 2012
@@ -690,6 +690,7 @@
   case tok::kw___is_polymorphic:
   case tok::kw___is_trivial:
   case tok::kw___is_trivially_assignable:
+  case tok::kw___is_trivially_constructible:
   case tok::kw___is_trivially_copyable:
   case tok::kw___is_union:
   case tok::kw___uuidof:

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Feb 24 01:38:34 2012
@@ -3212,6 +3212,127 @@
   return BuildBinaryTypeTrait(BTT, KWLoc, LhsTSInfo, RhsTSInfo, RParen);
 }
 
+static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc,
+                              ArrayRef<TypeSourceInfo *> Args,
+                              SourceLocation RParenLoc) {
+  switch (Kind) {
+  case clang::TT_IsTriviallyConstructible: {
+    // C++11 [meta.unary.prop]:
+    //   is_trivially_constructor is defined as:
+    //
+    //     is_constructible<T, Args...>::value is true and the variable 
+    //
+    ///  definition for is_constructible, as defined below, is known to call no
+    //   operation that is not trivial.
+    //
+    //   The predicate condition for a template specialization 
+    //   is_constructible<T, Args...> shall be satisfied if and only if the 
+    //   following variable definition would be well-formed for some invented 
+    //   variable t:
+    //
+    //     T t(create<Args>()...);
+    if (Args.empty()) {
+      S.Diag(KWLoc, diag::err_type_trait_arity)
+        << 1 << 1 << 1 << (int)Args.size();
+      return false;
+    }
+    
+    bool SawVoid = false;
+    for (unsigned I = 0, N = Args.size(); I != N; ++I) {
+      if (Args[I]->getType()->isVoidType()) {
+        SawVoid = true;
+        continue;
+      }
+      
+      if (!Args[I]->getType()->isIncompleteType() &&
+        S.RequireCompleteType(KWLoc, Args[I]->getType(), 
+          diag::err_incomplete_type_used_in_type_trait_expr))
+        return false;
+    }
+    
+    // If any argument was 'void', of course it won't type-check.
+    if (SawVoid)
+      return false;
+    
+    llvm::SmallVector<OpaqueValueExpr, 2> OpaqueArgExprs;
+    llvm::SmallVector<Expr *, 2> ArgExprs;
+    ArgExprs.reserve(Args.size() - 1);
+    for (unsigned I = 1, N = Args.size(); I != N; ++I) {
+      QualType T = Args[I]->getType();
+      if (T->isObjectType() || T->isFunctionType())
+        T = S.Context.getRValueReferenceType(T);
+      OpaqueArgExprs.push_back(
+        OpaqueValueExpr(Args[I]->getTypeLoc().getSourceRange().getBegin(), 
+                        T.getNonLValueExprType(S.Context),
+                        Expr::getValueKindForType(T)));
+      ArgExprs.push_back(&OpaqueArgExprs.back());
+    }
+    
+    // Perform the initialization in an unevaluated context within a SFINAE 
+    // trap at translation unit scope.
+    EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+    Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true);
+    Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl());
+    InitializedEntity To(InitializedEntity::InitializeTemporary(Args[0]));
+    InitializationKind InitKind(InitializationKind::CreateDirect(KWLoc, KWLoc,
+                                                                 RParenLoc));
+    InitializationSequence Init(S, To, InitKind, 
+                                ArgExprs.begin(), ArgExprs.size());
+    if (Init.Failed())
+      return false;
+    
+    ExprResult Result = Init.Perform(S, To, InitKind, 
+                                     MultiExprArg(ArgExprs.data(), 
+                                                  ArgExprs.size()));
+    if (Result.isInvalid() || SFINAE.hasErrorOccurred())
+      return false;
+    
+    // The initialization succeeded; not make sure there are no non-trivial 
+    // calls.
+    return !Result.get()->hasNonTrivialCall(S.Context);
+  }
+  }
+  
+  return false;
+}
+
+ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc, 
+                                ArrayRef<TypeSourceInfo *> Args, 
+                                SourceLocation RParenLoc) {
+  bool Dependent = false;
+  for (unsigned I = 0, N = Args.size(); I != N; ++I) {
+    if (Args[I]->getType()->isDependentType()) {
+      Dependent = true;
+      break;
+    }
+  }
+  
+  bool Value = false;
+  if (!Dependent)
+    Value = evaluateTypeTrait(*this, Kind, KWLoc, Args, RParenLoc);
+  
+  return TypeTraitExpr::Create(Context, Context.BoolTy, KWLoc, Kind,
+                               Args, RParenLoc, Value);
+}
+
+ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc, 
+                                ArrayRef<ParsedType> Args, 
+                                SourceLocation RParenLoc) {
+  llvm::SmallVector<TypeSourceInfo *, 4> ConvertedArgs;
+  ConvertedArgs.reserve(Args.size());
+  
+  for (unsigned I = 0, N = Args.size(); I != N; ++I) {
+    TypeSourceInfo *TInfo;
+    QualType T = GetTypeFromParser(Args[I], &TInfo);
+    if (!TInfo)
+      TInfo = Context.getTrivialTypeSourceInfo(T, KWLoc);
+    
+    ConvertedArgs.push_back(TInfo);    
+  }
+  
+  return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc);
+}
+
 static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT,
                                     QualType LhsT, QualType RhsT,
                                     SourceLocation KeyLoc) {

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Fri Feb 24 01:38:34 2012
@@ -2022,6 +2022,17 @@
     return getSema().BuildBinaryTypeTrait(Trait, StartLoc, LhsT, RhsT, RParenLoc);
   }
 
+  /// \brief Build a new type trait expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  ExprResult RebuildTypeTrait(TypeTrait Trait,
+                              SourceLocation StartLoc,
+                              ArrayRef<TypeSourceInfo *> Args,
+                              SourceLocation RParenLoc) {
+    return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
+  }
+  
   /// \brief Build a new array type trait expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
@@ -7436,6 +7447,128 @@
 
 template<typename Derived>
 ExprResult
+TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
+  bool ArgChanged = false;
+  llvm::SmallVector<TypeSourceInfo *, 4> Args;
+  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
+    TypeSourceInfo *From = E->getArg(I);
+    TypeLoc FromTL = From->getTypeLoc();
+    if (!isa<PackExpansionTypeLoc>(FromTL)) {
+      TypeLocBuilder TLB;
+      TLB.reserve(FromTL.getFullDataSize());
+      QualType To = getDerived().TransformType(TLB, FromTL);
+      if (To.isNull())
+        return ExprError();
+      
+      if (To == From->getType())
+        Args.push_back(From);
+      else {
+        Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
+        ArgChanged = true;
+      }
+      continue;
+    }
+    
+    ArgChanged = true;
+    
+    // We have a pack expansion. Instantiate it.
+    PackExpansionTypeLoc ExpansionTL = cast<PackExpansionTypeLoc>(FromTL);      
+    TypeLoc PatternTL = ExpansionTL.getPatternLoc();
+    SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+    SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);
+    
+    // Determine whether the set of unexpanded parameter packs can and should
+    // be expanded.
+    bool Expand = true;
+    bool RetainExpansion = false;
+    llvm::Optional<unsigned> OrigNumExpansions
+      = ExpansionTL.getTypePtr()->getNumExpansions();
+    llvm::Optional<unsigned> NumExpansions = OrigNumExpansions;
+    if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
+                                             PatternTL.getSourceRange(),
+                                             Unexpanded,
+                                             Expand, RetainExpansion,
+                                             NumExpansions))
+      return ExprError();
+    
+    if (!Expand) {
+      // The transform has determined that we should perform a simple
+      // transformation on the pack expansion, producing another pack 
+      // expansion.
+      Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
+      
+      TypeLocBuilder TLB;
+      TLB.reserve(From->getTypeLoc().getFullDataSize());
+
+      QualType To = getDerived().TransformType(TLB, PatternTL);
+      if (To.isNull())
+        return ExprError();
+
+      To = getDerived().RebuildPackExpansionType(To, 
+                                                 PatternTL.getSourceRange(),
+                                                 ExpansionTL.getEllipsisLoc(),
+                                                 NumExpansions);
+      if (To.isNull())
+        return ExprError();
+      
+      PackExpansionTypeLoc ToExpansionTL
+        = TLB.push<PackExpansionTypeLoc>(To);
+      ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
+      Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
+      continue;
+    }
+
+    // Expand the pack expansion by substituting for each argument in the
+    // pack(s).
+    for (unsigned I = 0; I != *NumExpansions; ++I) {
+      Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
+      TypeLocBuilder TLB;
+      TLB.reserve(PatternTL.getFullDataSize());
+      QualType To = getDerived().TransformType(TLB, PatternTL);
+      if (To.isNull())
+        return ExprError();
+
+      Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
+    }
+    
+    if (!RetainExpansion)
+      continue;
+    
+    // If we're supposed to retain a pack expansion, do so by temporarily
+    // forgetting the partially-substituted parameter pack.
+    ForgetPartiallySubstitutedPackRAII Forget(getDerived());
+
+    TypeLocBuilder TLB;
+    TLB.reserve(From->getTypeLoc().getFullDataSize());
+    
+    QualType To = getDerived().TransformType(TLB, PatternTL);
+    if (To.isNull())
+      return ExprError();
+    
+    To = getDerived().RebuildPackExpansionType(To, 
+                                               PatternTL.getSourceRange(),
+                                               ExpansionTL.getEllipsisLoc(),
+                                               NumExpansions);
+    if (To.isNull())
+      return ExprError();
+    
+    PackExpansionTypeLoc ToExpansionTL
+      = TLB.push<PackExpansionTypeLoc>(To);
+    ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
+    Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
+  }
+  
+  if (!getDerived().AlwaysRebuild() && !ArgChanged)
+    return SemaRef.Owned(E);
+
+  return getDerived().RebuildTypeTrait(E->getTrait(),
+                                       E->getLocStart(),
+                                       Args,
+                                       E->getLocEnd());
+}
+
+template<typename Derived>
+ExprResult
 TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
   TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
   if (!T)

Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Fri Feb 24 01:38:34 2012
@@ -1327,6 +1327,17 @@
   E->RhsType = GetTypeSourceInfo(Record, Idx);
 }
 
+void ASTStmtReader::VisitTypeTraitExpr(TypeTraitExpr *E) {
+  VisitExpr(E);
+  E->TypeTraitExprBits.NumArgs = Record[Idx++];
+  E->TypeTraitExprBits.Kind = Record[Idx++];
+  E->TypeTraitExprBits.Value = Record[Idx++];
+  
+  TypeSourceInfo **Args = E->getTypeSourceInfos();
+  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
+    Args[I] = GetTypeSourceInfo(Record, Idx);
+}
+
 void ASTStmtReader::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
   VisitExpr(E);
   E->ATT = (ArrayTypeTrait)Record[Idx++];
@@ -2046,6 +2057,11 @@
       S = new (Context) BinaryTypeTraitExpr(Empty);
       break;
 
+    case EXPR_TYPE_TRAIT:
+      S = TypeTraitExpr::CreateDeserialized(Context, 
+            Record[ASTStmtReader::NumExprFields]);
+      break;
+        
     case EXPR_ARRAY_TYPE_TRAIT:
       S = new (Context) ArrayTypeTraitExpr(Empty);
       break;

Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Fri Feb 24 01:38:34 2012
@@ -1341,6 +1341,16 @@
   Code = serialization::EXPR_BINARY_TYPE_TRAIT;
 }
 
+void ASTStmtWriter::VisitTypeTraitExpr(TypeTraitExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->TypeTraitExprBits.NumArgs);
+  Record.push_back(E->TypeTraitExprBits.Kind); // FIXME: Stable encoding
+  Record.push_back(E->TypeTraitExprBits.Value);
+  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
+    Writer.AddTypeSourceInfo(E->getArg(I), Record);
+  Code = serialization::EXPR_TYPE_TRAIT;
+}
+
 void ASTStmtWriter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
   VisitExpr(E);
   Record.push_back(E->getTrait());

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Fri Feb 24 01:38:34 2012
@@ -478,6 +478,7 @@
     case Stmt::DependentScopeDeclRefExprClass:
     case Stmt::UnaryTypeTraitExprClass:
     case Stmt::BinaryTypeTraitExprClass:
+    case Stmt::TypeTraitExprClass:
     case Stmt::ArrayTypeTraitExprClass:
     case Stmt::ExpressionTraitExprClass:
     case Stmt::UnresolvedLookupExprClass:

Modified: cfe/trunk/test/Index/annotate-tokens-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/annotate-tokens-cxx0x.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/test/Index/annotate-tokens-cxx0x.cpp (original)
+++ cfe/trunk/test/Index/annotate-tokens-cxx0x.cpp Fri Feb 24 01:38:34 2012
@@ -6,6 +6,11 @@
 void test() {
   int a;
   decltype(a) b;
+
+  typedef int Integer;
+  typedef float Float;
+  typedef bool Bool;
+  bool b2 = __is_trivially_constructible(Integer, Float, Bool);
 }
 
 // RUN: c-index-test -test-annotate-tokens=%s:1:1:5:1 -fno-delayed-template-parsing -std=c++11 %s | FileCheck %s
@@ -14,3 +19,9 @@
 
 // RUN: c-index-test -test-annotate-tokens=%s:8:1:9:1 -std=c++11 %s | FileCheck -check-prefix=CHECK-DECLTYPE %s
 // CHECK-DECLTYPE: Identifier: "a" [8:12 - 8:13] DeclRefExpr=a:7:7
+
+// RUN: c-index-test -test-annotate-tokens=%s:13:1:14:1 -std=c++11 %s | FileCheck -check-prefix=CHECK-TRAIT %s
+// CHECK-TRAIT: Identifier: "Integer" [13:42 - 13:49] TypeRef=Integer:10:15
+// CHECK-TRAIT: Identifier: "Float" [13:51 - 13:56] TypeRef=Float:11:17
+// CHECK-TRAIT: Identifier: "Bool" [13:58 - 13:62] TypeRef=Bool:12:16
+

Modified: cfe/trunk/test/PCH/cxx-traits.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-traits.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx-traits.cpp (original)
+++ cfe/trunk/test/PCH/cxx-traits.cpp Fri Feb 24 01:38:34 2012
@@ -1,8 +1,11 @@
 // Test this without pch.
-// RUN: %clang_cc1 -include %S/cxx-traits.h -fsyntax-only -verify %s
+// RUN: %clang_cc1 -include %S/cxx-traits.h -std=c++11 -fsyntax-only -verify %s
 
-// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-traits.h
-// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c++-header -std=c++11 -emit-pch -o %t %S/cxx-traits.h
+// RUN: %clang_cc1 -std=c++11 -include-pch %t -fsyntax-only -verify %s
 
 bool _Is_pod_comparator = __is_pod<int>::__value;
 bool _Is_empty_check = __is_empty<int>::__value;
+
+bool default_construct_int = is_trivially_constructible<int>::value;
+bool copy_construct_int = is_trivially_constructible<int, const int&>::value;

Modified: cfe/trunk/test/PCH/cxx-traits.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-traits.h?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/test/PCH/cxx-traits.h (original)
+++ cfe/trunk/test/PCH/cxx-traits.h Fri Feb 24 01:38:34 2012
@@ -9,3 +9,8 @@
 struct __is_empty {
   enum { __value };
 };
+
+template<typename T, typename ...Args>
+struct is_trivially_constructible {
+  static const bool value = __is_trivially_constructible(T, Args...);
+};

Modified: cfe/trunk/test/SemaCXX/type-traits.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/type-traits.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/type-traits.cpp (original)
+++ cfe/trunk/test/SemaCXX/type-traits.cpp Fri Feb 24 01:38:34 2012
@@ -47,6 +47,10 @@
   TrivialMoveButNotCopy &operator=(TrivialMoveButNotCopy&&) = default;
   TrivialMoveButNotCopy &operator=(const TrivialMoveButNotCopy&);
 };
+struct NonTrivialDefault {
+  NonTrivialDefault();
+};
+
 struct HasDest { ~HasDest(); };
 class  HasPriv { int priv; };
 class  HasProt { protected: int prot; };
@@ -104,6 +108,10 @@
   ~AllPrivate() throw();
 };
 
+struct ThreeArgCtor {
+  ThreeArgCtor(int*, char*, int);
+};
+
 void is_pod()
 {
   { int arr[T(__is_pod(int))]; }
@@ -1602,7 +1610,7 @@
   { int arr[F(__is_trivial(cvoid))]; }
 }
 
-void is_trivially_copyable()
+void trivial_checks()
 {
   { int arr[T(__is_trivially_copyable(int))]; }
   { int arr[T(__is_trivially_copyable(Enum))]; }
@@ -1646,6 +1654,25 @@
   { int arr[F(__is_trivially_copyable(void))]; }
   { int arr[F(__is_trivially_copyable(cvoid))]; }
 
+  { int arr[T((__is_trivially_constructible(int)))]; }
+  { int arr[T((__is_trivially_constructible(int, int)))]; }
+  { int arr[T((__is_trivially_constructible(int, float)))]; }
+  { int arr[T((__is_trivially_constructible(int, int&)))]; }
+  { int arr[T((__is_trivially_constructible(int, const int&)))]; }
+  { int arr[T((__is_trivially_constructible(int, int)))]; }
+  { int arr[T((__is_trivially_constructible(HasCopyAssign, HasCopyAssign)))]; }
+  { int arr[T((__is_trivially_constructible(HasCopyAssign, const HasCopyAssign&)))]; }
+  { int arr[T((__is_trivially_constructible(HasCopyAssign, HasCopyAssign&&)))]; }
+  { int arr[T((__is_trivially_constructible(HasCopyAssign)))]; }
+  { int arr[T((__is_trivially_constructible(NonTrivialDefault,
+                                            const NonTrivialDefault&)))]; }
+  { int arr[T((__is_trivially_constructible(NonTrivialDefault,
+                                            NonTrivialDefault&&)))]; }
+
+  { int arr[F((__is_trivially_constructible(int, int*)))]; }
+  { int arr[F((__is_trivially_constructible(NonTrivialDefault)))]; }
+  { int arr[F((__is_trivially_constructible(ThreeArgCtor, int*, char*, int&)))]; }
+
   { int arr[T((__is_trivially_assignable(int&, int)))]; }
   { int arr[T((__is_trivially_assignable(int&, int&)))]; }
   { int arr[T((__is_trivially_assignable(int&, int&&)))]; }
@@ -1680,6 +1707,33 @@
                                          TrivialMoveButNotCopy&&)))]; }
 }
 
+// Instantiation of __is_trivially_constructible
+template<typename T, typename ...Args>
+struct is_trivially_constructible {
+  static const bool value = __is_trivially_constructible(T, Args...);
+};
+
+void is_trivially_constructible_test() {
+  { int arr[T((is_trivially_constructible<int>::value))]; }
+  { int arr[T((is_trivially_constructible<int, int>::value))]; }
+  { int arr[T((is_trivially_constructible<int, float>::value))]; }
+  { int arr[T((is_trivially_constructible<int, int&>::value))]; }
+  { int arr[T((is_trivially_constructible<int, const int&>::value))]; }
+  { int arr[T((is_trivially_constructible<int, int>::value))]; }
+  { int arr[T((is_trivially_constructible<HasCopyAssign, HasCopyAssign>::value))]; }
+  { int arr[T((is_trivially_constructible<HasCopyAssign, const HasCopyAssign&>::value))]; }
+  { int arr[T((is_trivially_constructible<HasCopyAssign, HasCopyAssign&&>::value))]; }
+  { int arr[T((is_trivially_constructible<HasCopyAssign>::value))]; }
+  { int arr[T((is_trivially_constructible<NonTrivialDefault,
+                                            const NonTrivialDefault&>::value))]; }
+  { int arr[T((is_trivially_constructible<NonTrivialDefault,
+                                            NonTrivialDefault&&>::value))]; }
+
+  { int arr[F((is_trivially_constructible<int, int*>::value))]; }
+  { int arr[F((is_trivially_constructible<NonTrivialDefault>::value))]; }
+  { int arr[F((is_trivially_constructible<ThreeArgCtor, int*, char*, int&>::value))]; }
+}
+
 void array_rank() {
   int t01[T(__array_rank(IntAr) == 1)];
   int t02[T(__array_rank(ConstIntArAr) == 2)];

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Fri Feb 24 01:38:34 2012
@@ -1755,6 +1755,7 @@
   void VisitWhileStmt(WhileStmt *W);
   void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
   void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
+  void VisitTypeTraitExpr(TypeTraitExpr *E);
   void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
   void VisitExpressionTraitExpr(ExpressionTraitExpr *E);
   void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
@@ -2056,6 +2057,11 @@
   AddTypeLoc(E->getLhsTypeSourceInfo());
 }
 
+void EnqueueVisitor::VisitTypeTraitExpr(TypeTraitExpr *E) {
+  for (unsigned I = E->getNumArgs(); I > 0; --I)
+    AddTypeLoc(E->getArg(I-1));
+}
+
 void EnqueueVisitor::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
   AddTypeLoc(E->getQueriedTypeSourceInfo());
 }

Modified: cfe/trunk/tools/libclang/CXCursor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=151352&r1=151351&r2=151352&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)
+++ cfe/trunk/tools/libclang/CXCursor.cpp Fri Feb 24 01:38:34 2012
@@ -206,6 +206,7 @@
   case Stmt::AtomicExprClass:
   case Stmt::BinaryConditionalOperatorClass:
   case Stmt::BinaryTypeTraitExprClass:
+  case Stmt::TypeTraitExprClass:
   case Stmt::CXXBindTemporaryExprClass:
   case Stmt::CXXDefaultArgExprClass:
   case Stmt::CXXScalarValueInitExprClass:





More information about the cfe-commits mailing list