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