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 _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
