[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