[cfe-commits] [Patch] Implement compiler intrinsics for MSVC 2012 type_traits
Ryan Molden
ryanmolden at gmail.com
Sun Nov 25 16:54:23 PST 2012
On Sun, Nov 25, 2012 at 8:11 AM, Aaron Ballman <aaron at aaronballman.com>wrote:
> Thanks for working on this! Comments about the patch below:
>
> On Fri, Nov 23, 2012 at 2:40 PM, Ryan Molden <ryanmolden at gmail.com> wrote:
> > Index: lib/Sema/SemaExprCXX.cpp
> > ===================================================================
> > --- lib/Sema/SemaExprCXX.cpp (revision 168503)
> > +++ lib/Sema/SemaExprCXX.cpp (working copy)
> > @@ -2920,10 +2920,13 @@
> > // 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:
> > @@ -3071,6 +3074,15 @@
> > 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. Specifically this is used as the logic
> > + // behind std::has_trivial_move_constructor (20.9.4.3).
> > + if (T.isPODType(Self.Context))
> > + return true;
> > + 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
> > @@ -3082,6 +3094,15 @@
> > if (const RecordType *RT = T->getAs<RecordType>())
> > return
> cast<CXXRecordDecl>(RT->getDecl())->hasTrivialCopyConstructor();
> > return false;
> > + case UTT_HasTrivialMoveAssign:
> > + // This trait is implemented by MSVC 2012 and needed to parse the
> > + // standard library headers. Specifically it is used as the logic
> > + // behind std::is_trivially_move_assignable (20.9.4.3)
> > + if (T.isPODType(Self.Context))
> > + return true;
> > + if (const RecordType *RT =
> C.getBaseElementType(T)->getAs<RecordType>())
> > + return
> cast<CXXRecordDecl>(RT->getDecl())->hasTrivialMoveAssignment();
> > + return false;
> > case UTT_HasTrivialAssign:
> > // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
> > // If type is const qualified or is a reference type then the
> > @@ -3169,6 +3190,46 @@
> > return FoundAssign;
> > }
> > return false;
> > + case UTT_HasNothrowMoveAssign:
> > + // This trait is implemented by MSVC 2012 and needed to parse the
> > + // standard library headers. Specifically this is used as the logic
> > + // behind std::is_nothrow_move_assignable (20.9.4.3).
> > + if (T.isPODType(Self.Context))
> > + return true;
> > +
> > + 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);
> > + DeclarationNameInfo NameInfo(Name, KeyLoc);
> > + LookupResult Res(Self, NameInfo, 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;
>
> Very minor nit: you can move the FoundAssign logic into the
> LookupQualifiedName if block.
>
> Given the similarity between the other HasNothrow case statements, I
> wonder if there's a way we can consolidate this logic. For instance,
> UTT_HasNothrowAssign looks to be identical with the exception of
> calling isCopyAssignmentOperator or isMoveAssignmentOperator.
>
> Otherwise, the patch LGTM.
>
> Thanks!
>
> ~Aaron
>
Something more like this? It isn't ultimately generic, but it does allow
for re-use of the general logic between UTT_HasNoThrowAssign and
UTT_HasNoThrowMoveAssign.
Ryan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20121125/43e03351/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Support-For-MSVC-2012-Type-Traits-For-STL.patch
Type: application/octet-stream
Size: 20026 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20121125/43e03351/attachment.obj>
More information about the cfe-commits
mailing list