On Sun, Nov 25, 2012 at 8:11 AM, Aaron Ballman <[email protected]>wrote:
> Thanks for working on this! Comments about the patch below: > > On Fri, Nov 23, 2012 at 2:40 PM, Ryan Molden <[email protected]> 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
Support-For-MSVC-2012-Type-Traits-For-STL.patch
Description: Binary data
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
