[cfe-commits] [patch] Implement MSVC 2012 type traits
Aaron Ballman
aaron at aaronballman.com
Tue Sep 4 14:17:27 PDT 2012
> From e8799f8d23ee863feb2557942321e5d466fc8f95 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Jo=C3=A3o=20Matos?= <ripzonetriton at gmail.com>
> 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?
> 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.
> + if (const RecordType *RT =
> + C.getBaseElementType(T)->getAs<RecordType>())
> + return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialMoveConstructor();
> + return false;
> case UTT_HasTrivialCopy:
> // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
> // If __is_pod (type) is true or type is a reference type then
> @@ -3123,6 +3135,15 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT,
> if (const RecordType *RT = T->getAs<RecordType>())
> return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyAssignment();
> return false;
> + case UTT_HasTrivialMoveAssign:
> + // This trait is implemented by MSVC 2012 and needed to parse the
> + // standard library headers.
> + if (T.isPODType(Self.Context))
> + return true;
Same is true of this POD check.
> + if (const RecordType *RT =
> + C.getBaseElementType(T)->getAs<RecordType>())
> + return cast<CXXRecordDecl>(RT->getDecl())->hasTrivialMoveAssignment();
> + return false;
> case UTT_HasTrivialDestructor:
> // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
> // If __is_pod (type) is true or type is a reference type
> @@ -3190,6 +3211,44 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT,
> return FoundAssign;
> }
> return false;
> + case UTT_HasNothrowMoveAssign:
> + // This trait is implemented by MSVC 2012 and needed to parse the
> + // standard library headers.
> + if (T.isPODType(Self.Context))
> + return true;
Same here
> + if (const RecordType *RT = C.getBaseElementType(T)->getAs<RecordType>()) {
> + CXXRecordDecl* RD = cast<CXXRecordDecl>(RT->getDecl());
> + if (RD->hasTrivialMoveAssignment())
> + return true;
> +
> + bool FoundAssign = false;
> + DeclarationName Name = C.DeclarationNames.getCXXOperatorName(OO_Equal);
> + LookupResult Res(Self, DeclarationNameInfo(Name, KeyLoc),
> + Sema::LookupOrdinaryName);
> + if (Self.LookupQualifiedName(Res, RD)) {
> + Res.suppressDiagnostics();
> + for (LookupResult::iterator Op = Res.begin(), OpEnd = Res.end();
> + Op != OpEnd; ++Op) {
> + if (isa<FunctionTemplateDecl>(*Op))
> + continue;
> +
> + CXXMethodDecl *Operator = cast<CXXMethodDecl>(*Op);
> + if (Operator->isMoveAssignmentOperator()) {
> + FoundAssign = true;
> + const FunctionProtoType *CPT
> + = Operator->getType()->getAs<FunctionProtoType>();
> + CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
> + if (!CPT)
> + return false;
> + if (!CPT->isNothrow(Self.Context))
> + return false;
> + }
> + }
> + }
> +
> + return FoundAssign;
> + }
> + return false;
> case UTT_HasNothrowCopy:
> // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
> // If __has_trivial_copy (type) is true then the trait is true, else
> --
> 1.7.11
>
> From fec722607d7daab121dbd319b9017f8c40abc15c Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Jo=C3=A3o=20Matos?= <ripzonetriton at gmail.com>
> Date: Sat, 25 Aug 2012 22:00:10 +0100
> Subject: [PATCH] Added has_ type traits feature macros for MSVC 2012
> extensions.
> ---
> lib/Lex/PPMacroExpansion.cpp | 3 +++
> 1 file changed, 3 insertions(+)
> diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
> index 96d6b2c..eb4da22 100644
> --- a/lib/Lex/PPMacroExpansion.cpp
> +++ b/lib/Lex/PPMacroExpansion.cpp
> @@ -700,11 +700,14 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
> .Case("cxx_variadic_templates", LangOpts.CPlusPlus0x)
> // Type traits
> .Case("has_nothrow_assign", LangOpts.CPlusPlus)
> + .Case("has_nothrow_move_assign", LangOpts.CPlusPlus)
> .Case("has_nothrow_copy", LangOpts.CPlusPlus)
> .Case("has_nothrow_constructor", LangOpts.CPlusPlus)
> .Case("has_trivial_assign", LangOpts.CPlusPlus)
> + .Case("has_trivial_move_assign", LangOpts.CPlusPlus)
> .Case("has_trivial_copy", LangOpts.CPlusPlus)
> .Case("has_trivial_constructor", LangOpts.CPlusPlus)
> + .Case("has_trivial_move_constructor", LangOpts.CPlusPlus)
> .Case("has_trivial_destructor", LangOpts.CPlusPlus)
> .Case("has_virtual_destructor", LangOpts.CPlusPlus)
> .Case("is_abstract", LangOpts.CPlusPlus)
> --
> 1.7.11
~Aaron
More information about the cfe-commits
mailing list