Hi, On Tue, Sep 4, 2012 at 2:17 PM, Aaron Ballman <[email protected]>wrote:
> > From e8799f8d23ee863feb2557942321e5d466fc8f95 Mon Sep 17 00:00:00 2001 > > From: =?UTF-8?q?Jo=C3=A3o=20Matos?= <[email protected]> > > Date: Sat, 25 Aug 2012 20:41:44 +0100 > > Subject: [PATCH] Added support for MSVC 2012 type traits used in standard > > library. > > --- > > include/clang/Basic/TokenKinds.def | 3 ++ > > include/clang/Basic/TypeTraits.h | 3 ++ > > lib/AST/StmtPrinter.cpp | 3 ++ > > lib/Parse/ParseExpr.cpp | 3 ++ > > lib/Parse/ParseExprCXX.cpp | 4 +++ > > lib/Sema/SemaExprCXX.cpp | 59 > ++++++++++++++++++++++++++++++++++++++ > > 6 files changed, 75 insertions(+) > > diff --git a/include/clang/Basic/TokenKinds.def > b/include/clang/Basic/TokenKinds.def > > index fc03191..c5623ff 100644 > > --- a/include/clang/Basic/TokenKinds.def > > +++ b/include/clang/Basic/TokenKinds.def > > @@ -350,11 +350,14 @@ KEYWORD(L__FUNCTION__ , KEYMS) > > > > // GNU and MS Type Traits > > KEYWORD(__has_nothrow_assign , KEYCXX) > > +KEYWORD(__has_nothrow_move_assign , KEYCXX) > > KEYWORD(__has_nothrow_copy , KEYCXX) > > KEYWORD(__has_nothrow_constructor , KEYCXX) > > KEYWORD(__has_trivial_assign , KEYCXX) > > +KEYWORD(__has_trivial_move_assign , KEYCXX) > > KEYWORD(__has_trivial_copy , KEYCXX) > > KEYWORD(__has_trivial_constructor , KEYCXX) > > +KEYWORD(__has_trivial_move_constructor, KEYCXX) > > KEYWORD(__has_trivial_destructor , KEYCXX) > > KEYWORD(__has_virtual_destructor , KEYCXX) > > KEYWORD(__is_abstract , KEYCXX) > > If it is explicit to MSVC, do we also want to OR in KEYMS? > IIRC, some of the others in that section are also MSVC-only. I think this is OK. I find it surprising that there's no __has_nothrow_move_constructor here. Does MSVC's standard library not use that? > > diff --git a/include/clang/Basic/TypeTraits.h > b/include/clang/Basic/TypeTraits.h > > index 0a5a864..9f27fa0 100644 > > --- a/include/clang/Basic/TypeTraits.h > > +++ b/include/clang/Basic/TypeTraits.h > > @@ -20,11 +20,14 @@ namespace clang { > > /// \brief Names for the unary type traits. > > enum UnaryTypeTrait { > > UTT_HasNothrowAssign, > > + UTT_HasNothrowMoveAssign, > > UTT_HasNothrowCopy, > > UTT_HasNothrowConstructor, > > UTT_HasTrivialAssign, > > + UTT_HasTrivialMoveAssign, > > UTT_HasTrivialCopy, > > UTT_HasTrivialDefaultConstructor, > > + UTT_HasTrivialMoveConstructor, > > UTT_HasTrivialDestructor, > > UTT_HasVirtualDestructor, > > UTT_IsAbstract, > > diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp > > index 9a31416..badb46e 100644 > > --- a/lib/AST/StmtPrinter.cpp > > +++ b/lib/AST/StmtPrinter.cpp > > @@ -1510,9 +1510,12 @@ void > StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { > > static const char *getTypeTraitName(UnaryTypeTrait UTT) { > > switch (UTT) { > > case UTT_HasNothrowAssign: return "__has_nothrow_assign"; > > + case UTT_HasNothrowMoveAssign: return "__has_nothrow_move_assign"; > > case UTT_HasNothrowConstructor: return "__has_nothrow_constructor"; > > case UTT_HasNothrowCopy: return "__has_nothrow_copy"; > > case UTT_HasTrivialAssign: return "__has_trivial_assign"; > > + case UTT_HasTrivialMoveAssign: return > "__has_trivial_move_assign"; > > + case UTT_HasTrivialMoveConstructor: return > "__has_trivial_move_constructor"; > > case UTT_HasTrivialDefaultConstructor: return > "__has_trivial_constructor"; > > case UTT_HasTrivialCopy: return "__has_trivial_copy"; > > case UTT_HasTrivialDestructor: return "__has_trivial_destructor"; > > diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp > > index 8df08b8..728a3d5 100644 > > --- a/lib/Parse/ParseExpr.cpp > > +++ b/lib/Parse/ParseExpr.cpp > > @@ -1171,10 +1171,13 @@ ExprResult Parser::ParseCastExpression(bool > isUnaryExpression, > > case tok::kw___is_union: > > case tok::kw___is_final: > > case tok::kw___has_trivial_constructor: > > + case tok::kw___has_trivial_move_constructor: > > case tok::kw___has_trivial_copy: > > case tok::kw___has_trivial_assign: > > + case tok::kw___has_trivial_move_assign: > > case tok::kw___has_trivial_destructor: > > case tok::kw___has_nothrow_assign: > > + case tok::kw___has_nothrow_move_assign: > > case tok::kw___has_nothrow_copy: > > case tok::kw___has_nothrow_constructor: > > case tok::kw___has_virtual_destructor: > > diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp > > index e02cb7a..93cc182 100644 > > --- a/lib/Parse/ParseExprCXX.cpp > > +++ b/lib/Parse/ParseExprCXX.cpp > > @@ -2435,11 +2435,15 @@ static UnaryTypeTrait > UnaryTypeTraitFromTokKind(tok::TokenKind kind) { > > switch(kind) { > > default: llvm_unreachable("Not a known unary type trait."); > > case tok::kw___has_nothrow_assign: return UTT_HasNothrowAssign; > > + case tok::kw___has_nothrow_move_assign: return > UTT_HasNothrowMoveAssign; > > case tok::kw___has_nothrow_constructor: return > UTT_HasNothrowConstructor; > > case tok::kw___has_nothrow_copy: return UTT_HasNothrowCopy; > > case tok::kw___has_trivial_assign: return UTT_HasTrivialAssign; > > + case tok::kw___has_trivial_move_assign: return > UTT_HasTrivialMoveAssign; > > case tok::kw___has_trivial_constructor: > > return > UTT_HasTrivialDefaultConstructor; > > + case tok::kw___has_trivial_move_constructor: > > + return > UTT_HasTrivialMoveConstructor; > > case tok::kw___has_trivial_copy: return UTT_HasTrivialCopy; > > case tok::kw___has_trivial_destructor: return > UTT_HasTrivialDestructor; > > case tok::kw___has_virtual_destructor: return > UTT_HasVirtualDestructor; > > diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp > > index 4fc9abd..9501af8 100644 > > --- a/lib/Sema/SemaExprCXX.cpp > > +++ b/lib/Sema/SemaExprCXX.cpp > > @@ -2945,10 +2945,13 @@ static bool > CheckUnaryTypeTraitTypeCompleteness(Sema &S, > > // type due to the overarching C++0x type predicates being > implemented > > // requiring the complete type. > > case UTT_HasNothrowAssign: > > + case UTT_HasNothrowMoveAssign: > > case UTT_HasNothrowConstructor: > > case UTT_HasNothrowCopy: > > case UTT_HasTrivialAssign: > > + case UTT_HasTrivialMoveAssign: > > case UTT_HasTrivialDefaultConstructor: > > + case UTT_HasTrivialMoveConstructor: > > case UTT_HasTrivialCopy: > > case UTT_HasTrivialDestructor: > > case UTT_HasVirtualDestructor: > > @@ -3092,6 +3095,15 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, > UnaryTypeTrait UTT, > > C.getBaseElementType(T)->getAs<RecordType>()) > > return > cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDefaultConstructor(); > > return false; > > + case UTT_HasTrivialMoveConstructor: > > + // This trait is implemented by MSVC 2012 and needed to parse the > > + // standard library headers. > > + if (T.isPODType(Self.Context)) > > + return true; > > I think this is redundant with the hasTrivialMoveConstructor call > since that defaults to true and is only set to false when we know it's > non-trivial. > This isn't redundant -- not all POD types are record types. But I have no idea whether this trait is supposed to produce true or false for such types, since this patch has no tests! João: any semantic change to Clang should come with accompanying test cases. Please add some, and send a new patch out for review! Thanks, Richard
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
