[cfe-commits] [patch] Implement MSVC 2012 type traits

Richard Smith richard at metafoo.co.uk
Wed Sep 5 16:58:38 PDT 2012


Hi,

On Tue, Sep 4, 2012 at 2:17 PM, Aaron Ballman <aaron at aaronballman.com>wrote:

> > 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?
>

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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120905/24d46ab7/attachment.html>


More information about the cfe-commits mailing list