[cfe-commits] r133581 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaLookup.cpp
Chad Rosier
mcrosier at apple.com
Tue Jun 21 18:26:25 PDT 2011
Sean,
This looks to be breaking one of our internal buildbots (x86_64 Snow Leopard 10.6 Release Build) with the following errors:
llvm[4]: Compiling ScratchBuffer.cpp for Release build
0 clang 0x0000000100e98942 PrintStackTrace(void*) + 34
1 clang 0x0000000100e98e49 SignalHandler(int) + 697
2 libSystem.B.dylib 0x00007fff806fd66a _sigtramp + 26
3 libSystem.B.dylib 0x00000001021be8d0 _sigtramp + 2175537792
4 clang 0x00000001006973c2 clang::FunctionDecl::getMinRequiredArguments() const + 18
5 clang 0x00000001003db57a clang::Sema::DeduceTemplateArguments(clang::FunctionTemplateDecl*, clang::TemplateArgumentListInfo*, clang::Expr**, unsigned int, clang::FunctionDecl*&, clang::sema::TemplateDeductionInfo&) + 74
6 clang 0x0000000100380e7d clang::Sema::AddTemplateOverloadCandidate(clang::FunctionTemplateDecl*, clang::DeclAccessPair, clang::TemplateArgumentListInfo*, clang::Expr**, unsigned int, clang::OverloadCandidateSet&, bool) + 253
7 clang 0x000000010036841c clang::Sema::LookupSpecialMember(clang::CXXRecordDecl*, clang::Sema::CXXSpecialMember, bool, bool, bool, bool, bool) + 2028
8 clang 0x00000001003686d1 clang::Sema::LookupCopyingAssignment(clang::CXXRecordDecl*, unsigned int, bool, unsigned int, bool*) + 65
9 clang 0x00000001002e69a2 clang::Sema::ComputeDefaultedCopyAssignmentExceptionSpecAndConst(clang::CXXRecordDecl*) + 690
10 clang 0x00000001002df233 clang::Sema::DeclareImplicitCopyAssignment(clang::CXXRecordDecl*) + 211
11 clang 0x0000000100364917 DeclareImplicitMemberFunctionsWithName(clang::Sema&, clang::DeclarationName, clang::DeclContext const*) + 375
12 clang 0x0000000100364260 clang::Sema::CppLookupName(clang::LookupResult&, clang::Scope*) + 1248
13 clang 0x0000000100365daa clang::Sema::LookupName(clang::LookupResult&, clang::Scope*, bool) + 922
14 clang 0x0000000100367875 clang::Sema::LookupOverloadedOperatorName(clang::OverloadedOperatorKind, clang::Scope*, clang::QualType, clang::QualType, clang::UnresolvedSetImpl&) + 245
15 clang 0x0000000100320313 clang::Sema::BuildBinOp(clang::Scope*, clang::SourceLocation, clang::BinaryOperatorKind, clang::Expr*, clang::Expr*) + 371
16 clang 0x0000000100301fc3 clang::Sema::ActOnBinOp(clang::Scope*, clang::SourceLocation, clang::tok::TokenKind, clang::Expr*, clang::Expr*) + 2019
17 clang 0x0000000100200423 clang::Parser::ParseRHSOfBinaryExpression(clang::ActionResult<clang::Expr*, true>, clang::prec::Level) + 1459
18 clang 0x00000001001ffe65 clang::Parser::ParseAssignmentExpression() + 165
19 clang 0x00000001001ffda4 clang::Parser::ParseExpression() + 20
20 clang 0x0000000100217dde clang::Parser::ParseExprStatement(clang::ParsedAttributes&) + 62
21 clang 0x0000000100217860 clang::Parser::ParseStatementOrDeclaration(clang::ASTOwningVector<clang::Stmt*, 32u>&, bool) + 1552
22 clang 0x000000010021b58f clang::Parser::ParseCompoundStatementBody(bool) + 351
23 clang 0x000000010021c4a6 clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) + 166
24 clang 0x00000001001e994c clang::Parser::ParseLexedMethodDef(clang::Parser::LexedMethod&) + 460
25 clang 0x00000001001e93fd clang::Parser::ParseLexedMethodDefs(clang::Parser::ParsingClass&) + 141
26 clang 0x00000001001fbf75 clang::Parser::ParseCXXMemberSpecification(clang::SourceLocation, unsigned int, clang::Decl*) + 1909
27 clang 0x00000001001fb431 clang::Parser::ParseClassSpecifier(clang::tok::TokenKind, clang::SourceLocation, clang::DeclSpec&, clang::Parser::ParsedTemplateInfo const&, clang::AccessSpecifier, bool) + 4497
28 clang 0x00000001001edce5 clang::Parser::ParseDeclarationSpecifiers(clang::DeclSpec&, clang::Parser::ParsedTemplateInfo const&, clang::AccessSpecifier, clang::Parser::DeclSpecContext) + 2053
29 clang 0x000000010022551b clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsingDeclSpec&, clang::AccessSpecifier) + 75
30 clang 0x0000000100225914 clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::AccessSpecifier) + 388
31 clang 0x0000000100224faf clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange&, clang::Parser::ParsingDeclSpec*) + 2511
32 clang 0x00000001001f863e clang::Parser::ParseInnerNamespace(std::vector<clang::SourceLocation, std::allocator<clang::SourceLocation> >&, std::vector<clang::IdentifierInfo*, std::allocator<clang::IdentifierInfo*> >&, std::vector<clang::SourceLocation, std::allocator<clang::SourceLocation> >&, unsigned int, clang::SourceLocation&, clang::SourceLocation&, clang::ParsedAttributes&, clang::SourceLocation&) + 206
33 clang 0x00000001001f832b clang::Parser::ParseNamespace(unsigned int, clang::SourceLocation&, clang::SourceLocation) + 3195
34 clang 0x00000001001ed086 clang::Parser::ParseDeclaration(clang::ASTOwningVector<clang::Stmt*, 32u>&, unsigned int, clang::SourceLocation&, clang::Parser::ParsedAttributesWithRange&) + 646
35 clang 0x0000000100224b55 clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange&, clang::Parser::ParsingDeclSpec*) + 1397
36 clang 0x00000001002245b1 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&) + 241
37 clang 0x00000001001e837d clang::ParseAST(clang::Sema&, bool) + 589
38 clang 0x00000001001cac1e clang::CodeGenAction::ExecuteAction() + 686
39 clang 0x000000010002c0ba clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 858
40 clang 0x000000010000a0b8 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 2648
41 clang 0x0000000100002abb cc1_main(char const**, char const**, char const*, void*) + 5755
42 clang 0x00000001000066c7 main + 679
43 clang 0x0000000100001434 start + 52
44 clang 0x0000000000000054 start + 4294962260
Similar errors for:
llvm[4]: Compiling ParsePragma.cpp for Release build
llvm[4]: Compiling SemaAttr.cpp for Release build
Please try and resolve these issues (by reverting or otherwise) in a timely manner.
Regards,
Chad
On Jun 21, 2011, at 4:42 PM, Sean Hunt wrote:
> Author: coppro
> Date: Tue Jun 21 18:42:56 2011
> New Revision: 133581
>
> URL: http://llvm.org/viewvc/llvm-project?rev=133581&view=rev
> Log:
> Attempt to reapply this patch for caching copy assignment operator
> lookup. Previously, it was breaking self-host, but it's been a week and
> a half and I can't reproduce, so I need to see if it's still failing.
>
> Modified:
> cfe/trunk/include/clang/Sema/Sema.h
> cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> cfe/trunk/lib/Sema/SemaLookup.cpp
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=133581&r1=133580&r2=133581&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Tue Jun 21 18:42:56 2011
> @@ -1683,9 +1683,12 @@
>
> DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class);
> CXXConstructorDecl *LookupDefaultConstructor(CXXRecordDecl *Class);
> - CXXConstructorDecl *LookupCopyConstructor(CXXRecordDecl *Class,
> - unsigned Quals,
> - bool *ConstParam = 0);
> + CXXConstructorDecl *LookupCopyingConstructor(CXXRecordDecl *Class,
> + unsigned Quals,
> + bool *ConstParam = 0);
> + CXXMethodDecl *LookupCopyingAssignment(CXXRecordDecl *Class, unsigned Quals,
> + bool RValueThis, unsigned ThisQuals,
> + bool *ConstParam = 0);
> CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class);
>
> void ArgumentDependentLookup(DeclarationName Name, bool Operator,
>
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=133581&r1=133580&r2=133581&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Jun 21 18:42:56 2011
> @@ -3637,7 +3637,7 @@
> // resolution, as applied to B's [copy] constructor, results in an
> // ambiguity or a function that is deleted or inaccessible from the
> // defaulted constructor
> - CXXConstructorDecl *BaseCtor = LookupCopyConstructor(BaseDecl, ArgQuals);
> + CXXConstructorDecl *BaseCtor = LookupCopyingConstructor(BaseDecl, ArgQuals);
> if (!BaseCtor || BaseCtor->isDeleted())
> return true;
> if (CheckConstructorAccess(Loc, BaseCtor, BaseCtor->getAccess(), PDiag()) !=
> @@ -3665,7 +3665,7 @@
> // resolution, as applied to B's [copy] constructor, results in an
> // ambiguity or a function that is deleted or inaccessible from the
> // defaulted constructor
> - CXXConstructorDecl *BaseCtor = LookupCopyConstructor(BaseDecl, ArgQuals);
> + CXXConstructorDecl *BaseCtor = LookupCopyingConstructor(BaseDecl, ArgQuals);
> if (!BaseCtor || BaseCtor->isDeleted())
> return true;
> if (CheckConstructorAccess(Loc, BaseCtor, BaseCtor->getAccess(), PDiag()) !=
> @@ -3727,8 +3727,8 @@
> // cannot be [copied] because overload resolution, as applied to B's
> // [copy] constructor, results in an ambiguity or a function that is
> // deleted or inaccessible from the defaulted constructor
> - CXXConstructorDecl *FieldCtor = LookupCopyConstructor(FieldRecord,
> - ArgQuals);
> + CXXConstructorDecl *FieldCtor = LookupCopyingConstructor(FieldRecord,
> + ArgQuals);
> if (!FieldCtor || FieldCtor->isDeleted())
> return true;
> if (CheckConstructorAccess(Loc, FieldCtor, FieldCtor->getAccess(),
> @@ -3753,19 +3753,15 @@
>
> bool Union = RD->isUnion();
>
> - bool ConstArg =
> - MD->getParamDecl(0)->getType()->getPointeeType().isConstQualified();
> + unsigned ArgQuals =
> + MD->getParamDecl(0)->getType()->getPointeeType().isConstQualified() ?
> + Qualifiers::Const : 0;
>
> // We do this because we should never actually use an anonymous
> // union's constructor.
> if (Union && RD->isAnonymousStructOrUnion())
> return false;
>
> - DeclarationName OperatorName =
> - Context.DeclarationNames.getCXXOperatorName(OO_Equal);
> - LookupResult R(*this, OperatorName, Loc, LookupOrdinaryName);
> - R.suppressDiagnostics();
> -
> // FIXME: We should put some diagnostic logic right into this function.
>
> // C++0x [class.copy]/11
> @@ -3787,37 +3783,11 @@
> // resolution, as applied to B's [copy] assignment operator, results in
> // an ambiguity or a function that is deleted or inaccessible from the
> // assignment operator
> -
> - LookupQualifiedName(R, BaseDecl, false);
> -
> - // Filter out any result that isn't a copy-assignment operator.
> - LookupResult::Filter F = R.makeFilter();
> - while (F.hasNext()) {
> - NamedDecl *D = F.next();
> - if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))
> - if (Method->isCopyAssignmentOperator())
> - continue;
> -
> - F.erase();
> - }
> - F.done();
> -
> - // Build a fake argument expression
> - QualType ArgType = BaseType;
> - QualType ThisType = BaseType;
> - if (ConstArg)
> - ArgType.addConst();
> - Expr *Args[] = { new (Context) OpaqueValueExpr(Loc, ThisType, VK_LValue)
> - , new (Context) OpaqueValueExpr(Loc, ArgType, VK_LValue)
> - };
> -
> - OverloadCandidateSet OCS((Loc));
> - OverloadCandidateSet::iterator Best;
> -
> - AddFunctionCandidates(R.asUnresolvedSet(), Args, 2, OCS);
> -
> - if (OCS.BestViableFunction(*this, Loc, Best, false) !=
> - OR_Success)
> + CXXMethodDecl *CopyOper = LookupCopyingAssignment(BaseDecl, ArgQuals, false,
> + 0);
> + if (!CopyOper || CopyOper->isDeleted())
> + return true;
> + if (CheckDirectMemberAccess(Loc, CopyOper, PDiag()) != AR_accessible)
> return true;
> }
>
> @@ -3832,37 +3802,11 @@
> // resolution, as applied to B's [copy] assignment operator, results in
> // an ambiguity or a function that is deleted or inaccessible from the
> // assignment operator
> -
> - LookupQualifiedName(R, BaseDecl, false);
> -
> - // Filter out any result that isn't a copy-assignment operator.
> - LookupResult::Filter F = R.makeFilter();
> - while (F.hasNext()) {
> - NamedDecl *D = F.next();
> - if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))
> - if (Method->isCopyAssignmentOperator())
> - continue;
> -
> - F.erase();
> - }
> - F.done();
> -
> - // Build a fake argument expression
> - QualType ArgType = BaseType;
> - QualType ThisType = BaseType;
> - if (ConstArg)
> - ArgType.addConst();
> - Expr *Args[] = { new (Context) OpaqueValueExpr(Loc, ThisType, VK_LValue)
> - , new (Context) OpaqueValueExpr(Loc, ArgType, VK_LValue)
> - };
> -
> - OverloadCandidateSet OCS((Loc));
> - OverloadCandidateSet::iterator Best;
> -
> - AddFunctionCandidates(R.asUnresolvedSet(), Args, 2, OCS);
> -
> - if (OCS.BestViableFunction(*this, Loc, Best, false) !=
> - OR_Success)
> + CXXMethodDecl *CopyOper = LookupCopyingAssignment(BaseDecl, ArgQuals, false,
> + 0);
> + if (!CopyOper || CopyOper->isDeleted())
> + return true;
> + if (CheckDirectMemberAccess(Loc, CopyOper, PDiag()) != AR_accessible)
> return true;
> }
>
> @@ -3909,37 +3853,12 @@
> return true;
> }
>
> - LookupQualifiedName(R, FieldRecord, false);
> -
> - // Filter out any result that isn't a copy-assignment operator.
> - LookupResult::Filter F = R.makeFilter();
> - while (F.hasNext()) {
> - NamedDecl *D = F.next();
> - if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))
> - if (Method->isCopyAssignmentOperator())
> - continue;
> -
> - F.erase();
> - }
> - F.done();
> -
> - // Build a fake argument expression
> - QualType ArgType = FieldType;
> - QualType ThisType = FieldType;
> - if (ConstArg)
> - ArgType.addConst();
> - Expr *Args[] = { new (Context) OpaqueValueExpr(Loc, ThisType, VK_LValue)
> - , new (Context) OpaqueValueExpr(Loc, ArgType, VK_LValue)
> - };
> -
> - OverloadCandidateSet OCS((Loc));
> - OverloadCandidateSet::iterator Best;
> -
> - AddFunctionCandidates(R.asUnresolvedSet(), Args, 2, OCS);
> -
> - if (OCS.BestViableFunction(*this, Loc, Best, false) !=
> - OR_Success)
> - return true;
> + CXXMethodDecl *CopyOper = LookupCopyingAssignment(FieldRecord, ArgQuals,
> + false, 0);
> + if (!CopyOper || CopyOper->isDeleted())
> + return false;
> + if (CheckDirectMemberAccess(Loc, CopyOper, PDiag()) != AR_accessible)
> + return false;
> }
> }
>
> @@ -6688,58 +6607,6 @@
> Loc, Copy.take());
> }
>
> -/// \brief Determine whether the given class has a copy assignment operator
> -/// that accepts a const-qualified argument.
> -static bool hasConstCopyAssignment(Sema &S, const CXXRecordDecl *CClass) {
> - CXXRecordDecl *Class = const_cast<CXXRecordDecl *>(CClass);
> -
> - if (!Class->hasDeclaredCopyAssignment())
> - S.DeclareImplicitCopyAssignment(Class);
> -
> - QualType ClassType = S.Context.getCanonicalType(S.Context.getTypeDeclType(Class));
> - DeclarationName OpName
> - = S.Context.DeclarationNames.getCXXOperatorName(OO_Equal);
> -
> - DeclContext::lookup_const_iterator Op, OpEnd;
> - for (llvm::tie(Op, OpEnd) = Class->lookup(OpName); Op != OpEnd; ++Op) {
> - // C++ [class.copy]p9:
> - // A user-declared copy assignment operator is a non-static non-template
> - // member function of class X with exactly one parameter of type X, X&,
> - // const X&, volatile X& or const volatile X&.
> - const CXXMethodDecl* Method = dyn_cast<CXXMethodDecl>(*Op);
> - if (!Method)
> - continue;
> -
> - if (Method->isStatic())
> - continue;
> - if (Method->getPrimaryTemplate())
> - continue;
> - const FunctionProtoType *FnType =
> - Method->getType()->getAs<FunctionProtoType>();
> - assert(FnType && "Overloaded operator has no prototype.");
> - // Don't assert on this; an invalid decl might have been left in the AST.
> - if (FnType->getNumArgs() != 1 || FnType->isVariadic())
> - continue;
> - bool AcceptsConst = true;
> - QualType ArgType = FnType->getArgType(0);
> - if (const LValueReferenceType *Ref = ArgType->getAs<LValueReferenceType>()){
> - ArgType = Ref->getPointeeType();
> - // Is it a non-const lvalue reference?
> - if (!ArgType.isConstQualified())
> - AcceptsConst = false;
> - }
> - if (!S.Context.hasSameUnqualifiedType(ArgType, ClassType))
> - continue;
> -
> - // We have a single argument of type cv X or cv X&, i.e. we've found the
> - // copy assignment operator. Return whether it accepts const arguments.
> - return AcceptsConst;
> - }
> - assert(Class->isInvalidDecl() &&
> - "No copy assignment operator declared in valid code.");
> - return false;
> -}
> -
> std::pair<Sema::ImplicitExceptionSpecification, bool>
> Sema::ComputeDefaultedCopyAssignmentExceptionSpecAndConst(
> CXXRecordDecl *ClassDecl) {
> @@ -6760,11 +6627,28 @@
> for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
> BaseEnd = ClassDecl->bases_end();
> HasConstCopyAssignment && Base != BaseEnd; ++Base) {
> + // We'll handle this below
> + if (LangOpts.CPlusPlus0x && Base->isVirtual())
> + continue;
> +
> assert(!Base->getType()->isDependentType() &&
> "Cannot generate implicit members for class with dependent bases.");
> - const CXXRecordDecl *BaseClassDecl
> - = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
> - HasConstCopyAssignment = hasConstCopyAssignment(*this, BaseClassDecl);
> + CXXRecordDecl *BaseClassDecl = Base->getType()->getAsCXXRecordDecl();
> + LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const, false, 0,
> + &HasConstCopyAssignment);
> + }
> +
> + // In C++0x, the above citation has "or virtual added"
> + if (LangOpts.CPlusPlus0x) {
> + for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
> + BaseEnd = ClassDecl->vbases_end();
> + HasConstCopyAssignment && Base != BaseEnd; ++Base) {
> + assert(!Base->getType()->isDependentType() &&
> + "Cannot generate implicit members for class with dependent bases.");
> + CXXRecordDecl *BaseClassDecl = Base->getType()->getAsCXXRecordDecl();
> + LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const, false, 0,
> + &HasConstCopyAssignment);
> + }
> }
>
> // -- for all the nonstatic data members of X that are of a class
> @@ -6776,10 +6660,9 @@
> HasConstCopyAssignment && Field != FieldEnd;
> ++Field) {
> QualType FieldType = Context.getBaseElementType((*Field)->getType());
> - if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
> - const CXXRecordDecl *FieldClassDecl
> - = cast<CXXRecordDecl>(FieldClassType->getDecl());
> - HasConstCopyAssignment = hasConstCopyAssignment(*this, FieldClassDecl);
> + if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
> + LookupCopyingAssignment(FieldClassDecl, Qualifiers::Const, false, 0,
> + &HasConstCopyAssignment);
> }
> }
>
> @@ -6791,35 +6674,47 @@
> // C++ [except.spec]p14:
> // An implicitly declared special member function (Clause 12) shall have an
> // exception-specification. [...]
> +
> + // It is unspecified whether or not an implicit copy assignment operator
> + // attempts to deduplicate calls to assignment operators of virtual bases are
> + // made. As such, this exception specification is effectively unspecified.
> + // Based on a similar decision made for constness in C++0x, we're erring on
> + // the side of assuming such calls to be made regardless of whether they
> + // actually happen.
> ImplicitExceptionSpecification ExceptSpec(Context);
> + unsigned ArgQuals = HasConstCopyAssignment ? Qualifiers::Const : 0;
> for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
> BaseEnd = ClassDecl->bases_end();
> Base != BaseEnd; ++Base) {
> + if (Base->isVirtual())
> + continue;
> +
> CXXRecordDecl *BaseClassDecl
> = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
> -
> - if (!BaseClassDecl->hasDeclaredCopyAssignment())
> - DeclareImplicitCopyAssignment(BaseClassDecl);
> + if (CXXMethodDecl *CopyAssign = LookupCopyingAssignment(BaseClassDecl,
> + ArgQuals, false, 0))
> + ExceptSpec.CalledDecl(CopyAssign);
> + }
>
> - if (CXXMethodDecl *CopyAssign
> - = BaseClassDecl->getCopyAssignmentOperator(HasConstCopyAssignment))
> + for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
> + BaseEnd = ClassDecl->vbases_end();
> + Base != BaseEnd; ++Base) {
> + CXXRecordDecl *BaseClassDecl
> + = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
> + if (CXXMethodDecl *CopyAssign = LookupCopyingAssignment(BaseClassDecl,
> + ArgQuals, false, 0))
> ExceptSpec.CalledDecl(CopyAssign);
> }
> +
> for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
> FieldEnd = ClassDecl->field_end();
> Field != FieldEnd;
> ++Field) {
> QualType FieldType = Context.getBaseElementType((*Field)->getType());
> - if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) {
> - CXXRecordDecl *FieldClassDecl
> - = cast<CXXRecordDecl>(FieldClassType->getDecl());
> -
> - if (!FieldClassDecl->hasDeclaredCopyAssignment())
> - DeclareImplicitCopyAssignment(FieldClassDecl);
> -
> - if (CXXMethodDecl *CopyAssign
> - = FieldClassDecl->getCopyAssignmentOperator(HasConstCopyAssignment))
> - ExceptSpec.CalledDecl(CopyAssign);
> + if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
> + if (CXXMethodDecl *CopyAssign =
> + LookupCopyingAssignment(FieldClassDecl, ArgQuals, false, 0))
> + ExceptSpec.CalledDecl(CopyAssign);
> }
> }
>
> @@ -7206,8 +7101,8 @@
>
> CXXRecordDecl *BaseClassDecl
> = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
> - LookupCopyConstructor(BaseClassDecl, Qualifiers::Const,
> - &HasConstCopyConstructor);
> + LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const,
> + &HasConstCopyConstructor);
> }
>
> for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
> @@ -7216,8 +7111,8 @@
> ++Base) {
> CXXRecordDecl *BaseClassDecl
> = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
> - LookupCopyConstructor(BaseClassDecl, Qualifiers::Const,
> - &HasConstCopyConstructor);
> + LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const,
> + &HasConstCopyConstructor);
> }
>
> // -- for all the nonstatic data members of X that are of a
> @@ -7230,8 +7125,8 @@
> ++Field) {
> QualType FieldType = Context.getBaseElementType((*Field)->getType());
> if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
> - LookupCopyConstructor(FieldClassDecl, Qualifiers::Const,
> - &HasConstCopyConstructor);
> + LookupCopyingConstructor(FieldClassDecl, Qualifiers::Const,
> + &HasConstCopyConstructor);
> }
> }
> // Otherwise, the implicitly declared copy constructor will have
> @@ -7255,7 +7150,7 @@
> CXXRecordDecl *BaseClassDecl
> = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
> if (CXXConstructorDecl *CopyConstructor =
> - LookupCopyConstructor(BaseClassDecl, Quals))
> + LookupCopyingConstructor(BaseClassDecl, Quals))
> ExceptSpec.CalledDecl(CopyConstructor);
> }
> for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
> @@ -7265,7 +7160,7 @@
> CXXRecordDecl *BaseClassDecl
> = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
> if (CXXConstructorDecl *CopyConstructor =
> - LookupCopyConstructor(BaseClassDecl, Quals))
> + LookupCopyingConstructor(BaseClassDecl, Quals))
> ExceptSpec.CalledDecl(CopyConstructor);
> }
> for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
> @@ -7275,7 +7170,7 @@
> QualType FieldType = Context.getBaseElementType((*Field)->getType());
> if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
> if (CXXConstructorDecl *CopyConstructor =
> - LookupCopyConstructor(FieldClassDecl, Quals))
> + LookupCopyingConstructor(FieldClassDecl, Quals))
> ExceptSpec.CalledDecl(CopyConstructor);
> }
> }
>
> Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=133581&r1=133580&r2=133581&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaLookup.cpp Tue Jun 21 18:42:56 2011
> @@ -2269,7 +2269,8 @@
> (SM == CXXCopyConstructor &&
> cast<CXXConstructorDecl>(M)->isCopyConstructor())) {
> QualType ArgType = M->getType()->getAs<FunctionProtoType>()->getArgType(0);
> - if (ArgType->getPointeeType().isConstQualified())
> + if (!ArgType->isReferenceType() ||
> + ArgType->getPointeeType().isConstQualified())
> Result->setConstParamMatch(true);
> }
> } else {
> @@ -2310,10 +2311,10 @@
> return cast_or_null<CXXConstructorDecl>(Result->getMethod());
> }
>
> -/// \brief Look up the copy constructor for the given class.
> -CXXConstructorDecl *Sema::LookupCopyConstructor(CXXRecordDecl *Class,
> - unsigned Quals,
> - bool *ConstParamMatch) {
> +/// \brief Look up the copying constructor for the given class.
> +CXXConstructorDecl *Sema::LookupCopyingConstructor(CXXRecordDecl *Class,
> + unsigned Quals,
> + bool *ConstParamMatch) {
> assert(!(Quals & ~(Qualifiers::Const | Qualifiers::Volatile)) &&
> "non-const, non-volatile qualifiers for copy ctor arg");
> SpecialMemberOverloadResult *Result =
> @@ -2341,6 +2342,27 @@
> return Class->lookup(Name);
> }
>
> +/// \brief Look up the copying assignment operator for the given class.
> +CXXMethodDecl *Sema::LookupCopyingAssignment(CXXRecordDecl *Class,
> + unsigned Quals, bool RValueThis,
> + unsigned ThisQuals,
> + bool *ConstParamMatch) {
> + assert(!(Quals & ~(Qualifiers::Const | Qualifiers::Volatile)) &&
> + "non-const, non-volatile qualifiers for copy assignment arg");
> + assert(!(ThisQuals & ~(Qualifiers::Const | Qualifiers::Volatile)) &&
> + "non-const, non-volatile qualifiers for copy assignment this");
> + SpecialMemberOverloadResult *Result =
> + LookupSpecialMember(Class, CXXCopyAssignment, Quals & Qualifiers::Const,
> + Quals & Qualifiers::Volatile, RValueThis,
> + ThisQuals & Qualifiers::Const,
> + ThisQuals & Qualifiers::Volatile);
> +
> + if (ConstParamMatch)
> + *ConstParamMatch = Result->hasConstParamMatch();
> +
> + return Result->getMethod();
> +}
> +
> /// \brief Look for the destructor of the given class.
> ///
> /// During semantic analysis, this routine should be used in lieu of
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20110621/d62e8e46/attachment.html>
More information about the cfe-commits
mailing list