From: Sean Hunt Date: Fri, 24 Jun 2011 02:11:39 +0000 (+0000) Subject: This patch started as an attempt to fix up the horrid naming X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c39b6bc958982171b45c658389840a6241739a5e;p=clang This patch started as an attempt to fix up the horrid naming conventions. I then discovered a typo in the using declaration bit in LookupSpecialMember. This led to discovering [namespace.udecl]p15, which clang implements incorrectly. Thus I've added a comment and implemented the code consistently with the rest of clang - that is incorrectly. And because I don't want to include tests of something incorrect, I've ripped the test out. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133784 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 108346a9d1..b25c4cb613 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -2137,15 +2137,15 @@ void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S, } } -Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D, +Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD, CXXSpecialMember SM, bool ConstArg, bool VolatileArg, bool RValueThis, bool ConstThis, bool VolatileThis) { - D = D->getDefinition(); - assert((D && !D->isBeingDefined()) && + RD = RD->getDefinition(); + assert((RD && !RD->isBeingDefined()) && "doing special member lookup into record that isn't fully complete"); if (RValueThis || ConstThis || VolatileThis) assert((SM == CXXCopyAssignment || SM == CXXMoveAssignment) && @@ -2155,7 +2155,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D, "parameter-less special members can't have qualified arguments"); llvm::FoldingSetNodeID ID; - ID.AddPointer(D); + ID.AddPointer(RD); ID.AddInteger(SM); ID.AddInteger(ConstArg); ID.AddInteger(VolatileArg); @@ -2176,9 +2176,9 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D, SpecialMemberCache.InsertNode(Result, InsertPoint); if (SM == CXXDestructor) { - if (!D->hasDeclaredDestructor()) - DeclareImplicitDestructor(D); - CXXDestructorDecl *DD = D->getDestructor(); + if (!RD->hasDeclaredDestructor()) + DeclareImplicitDestructor(RD); + CXXDestructorDecl *DD = RD->getDestructor(); assert(DD && "record without a destructor"); Result->setMethod(DD); Result->setSuccess(DD->isDeleted()); @@ -2188,7 +2188,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D, // Prepare for overload resolution. Here we construct a synthetic argument // if necessary and make sure that implicit functions are declared. - CanQualType CanTy = Context.getCanonicalType(Context.getTagDeclType(D)); + CanQualType CanTy = Context.getCanonicalType(Context.getTagDeclType(RD)); DeclarationName Name; Expr *Arg = 0; unsigned NumArgs; @@ -2196,18 +2196,18 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D, if (SM == CXXDefaultConstructor) { Name = Context.DeclarationNames.getCXXConstructorName(CanTy); NumArgs = 0; - if (D->needsImplicitDefaultConstructor()) - DeclareImplicitDefaultConstructor(D); + if (RD->needsImplicitDefaultConstructor()) + DeclareImplicitDefaultConstructor(RD); } else { if (SM == CXXCopyConstructor || SM == CXXMoveConstructor) { Name = Context.DeclarationNames.getCXXConstructorName(CanTy); - if (!D->hasDeclaredCopyConstructor()) - DeclareImplicitCopyConstructor(D); + if (!RD->hasDeclaredCopyConstructor()) + DeclareImplicitCopyConstructor(RD); // TODO: Move constructors } else { Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal); - if (!D->hasDeclaredCopyAssignment()) - DeclareImplicitCopyAssignment(D); + if (!RD->hasDeclaredCopyAssignment()) + DeclareImplicitCopyAssignment(RD); // TODO: Move assignment } @@ -2252,21 +2252,29 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D, DeclContext::lookup_iterator I, E; Result->setConstParamMatch(false); - llvm::tie(I, E) = D->lookup(Name); + llvm::tie(I, E) = RD->lookup(Name); assert((I != E) && "lookup for a constructor or assignment operator was empty"); for ( ; I != E; ++I) { - Decl *DD = *I; - - if (UsingShadowDecl *U = dyn_cast(D)) - DD = U->getTargetDecl(); + Decl *Cand = *I; - if (DD->isInvalidDecl()) + if (Cand->isInvalidDecl()) continue; - if (CXXMethodDecl *M = dyn_cast(DD)) { + if (UsingShadowDecl *U = dyn_cast(Cand)) { + // FIXME: [namespace.udecl]p15 says that we should only consider a + // using declaration here if it does not match a declaration in the + // derived class. We do not implement this correctly in other cases + // either. + Cand = U->getTargetDecl(); + + if (Cand->isInvalidDecl()) + continue; + } + + if (CXXMethodDecl *M = dyn_cast(Cand)) { if (SM == CXXCopyAssignment || SM == CXXMoveAssignment) - AddMethodCandidate(M, DeclAccessPair::make(M, AS_public), D, ThisTy, + AddMethodCandidate(M, DeclAccessPair::make(M, AS_public), RD, ThisTy, Classification, &Arg, NumArgs, OCS, true); else AddOverloadCandidate(M, DeclAccessPair::make(M, AS_public), &Arg, @@ -2283,15 +2291,19 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D, Result->setConstParamMatch(true); } } else if (FunctionTemplateDecl *Tmpl = - dyn_cast(DD)) { + dyn_cast(Cand)) { if (SM == CXXCopyAssignment || SM == CXXMoveAssignment) AddMethodTemplateCandidate(Tmpl, DeclAccessPair::make(Tmpl, AS_public), - D, 0, ThisTy, Classification, &Arg, NumArgs, + RD, 0, ThisTy, Classification, &Arg, NumArgs, OCS, true); else AddTemplateOverloadCandidate(Tmpl, DeclAccessPair::make(Tmpl, AS_public), 0, &Arg, NumArgs, OCS, true); + } else { + assert(isa(Cand) && "illegal Kind of operator = Decl"); } + + Continue:; } OverloadCandidateSet::iterator Best; diff --git a/test/SemaCXX/using-decl-assignment-cache.cpp b/test/SemaCXX/using-decl-assignment-cache.cpp deleted file mode 100644 index a3a50e5d2c..0000000000 --- a/test/SemaCXX/using-decl-assignment-cache.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %clang_cc1 -std=c++0x -fsyntax-only %s - -struct D; -struct B { - D& operator = (const D&); -}; -struct D : B { - using B::operator=; -}; -struct F : D { -}; - -void H () { - F f; - f = f; -}