Awesome, thanks! Howard
On Feb 24, 2012, at 2:38 AM, Douglas Gregor wrote: > 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: > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
