From 4cc12c6e47a200cf166ac21efc09dd033f34c9b2 Mon Sep 17 00:00:00 2001 From: Sean Hunt Date: Thu, 23 Jun 2011 00:26:20 +0000 Subject: [PATCH] Clean up the heart of the caching code and miss fewer edge cases. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133671 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaLookup.cpp | 30 ++++++++++++++------ test/SemaCXX/using-decl-assignment-cache.cpp | 16 +++++++++++ 2 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 test/SemaCXX/using-decl-assignment-cache.cpp diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 204a697e93..108346a9d1 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -2240,7 +2240,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D, ThisTy.addConst(); if (VolatileThis) ThisTy.addVolatile(); - Expr::Classification ObjectClassification = + Expr::Classification Classification = (new (Context) OpaqueValueExpr(SourceLocation(), ThisTy, RValueThis ? VK_RValue : VK_LValue))-> Classify(Context); @@ -2256,12 +2256,21 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D, assert((I != E) && "lookup for a constructor or assignment operator was empty"); for ( ; I != E; ++I) { - if ((*I)->isInvalidDecl()) + Decl *DD = *I; + + if (UsingShadowDecl *U = dyn_cast(D)) + DD = U->getTargetDecl(); + + if (DD->isInvalidDecl()) continue; - if (CXXMethodDecl *M = dyn_cast(*I)) { - AddOverloadCandidate(M, DeclAccessPair::make(M, AS_public), &Arg, NumArgs, - OCS, true); + if (CXXMethodDecl *M = dyn_cast(DD)) { + if (SM == CXXCopyAssignment || SM == CXXMoveAssignment) + AddMethodCandidate(M, DeclAccessPair::make(M, AS_public), D, ThisTy, + Classification, &Arg, NumArgs, OCS, true); + else + AddOverloadCandidate(M, DeclAccessPair::make(M, AS_public), &Arg, + NumArgs, OCS, true); // Here we're looking for a const parameter to speed up creation of // implicit copy methods. @@ -2274,9 +2283,14 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *D, Result->setConstParamMatch(true); } } else if (FunctionTemplateDecl *Tmpl = - dyn_cast(*I)) { - AddTemplateOverloadCandidate(Tmpl, DeclAccessPair::make(Tmpl, AS_public), - 0, &Arg, NumArgs, OCS, true); + dyn_cast(DD)) { + if (SM == CXXCopyAssignment || SM == CXXMoveAssignment) + AddMethodTemplateCandidate(Tmpl, DeclAccessPair::make(Tmpl, AS_public), + D, 0, ThisTy, Classification, &Arg, NumArgs, + OCS, true); + else + AddTemplateOverloadCandidate(Tmpl, DeclAccessPair::make(Tmpl, AS_public), + 0, &Arg, NumArgs, OCS, true); } } diff --git a/test/SemaCXX/using-decl-assignment-cache.cpp b/test/SemaCXX/using-decl-assignment-cache.cpp new file mode 100644 index 0000000000..a3a50e5d2c --- /dev/null +++ b/test/SemaCXX/using-decl-assignment-cache.cpp @@ -0,0 +1,16 @@ +// 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; +} -- 2.40.0