diff options
author | Sean Hunt <scshunt@csclub.uwaterloo.ca> | 2011-06-03 18:36:49 +0000 |
---|---|---|
committer | Sean Hunt <scshunt@csclub.uwaterloo.ca> | 2011-06-03 18:36:49 +0000 |
commit | 8fd7722fce4e4f9549897699ec3a4c752613b214 (patch) | |
tree | e08eefef1b148b8f7732d7921e5a77019fa5c0d8 /lib/Sema/SemaLookup.cpp | |
parent | ee22697a56f3035419e71762134ff7ea0d8f1eb8 (diff) |
Begin implementing a cache of special member lookups. Currently only
destructors are implemented but other special members are on the way,
which is where the real benefits of this will be visible.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132572 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaLookup.cpp')
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 2bfa86cb55..6a441a38d0 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -14,6 +14,7 @@ #include "clang/Sema/Sema.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/Lookup.h" +#include "clang/Sema/Overload.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" @@ -2136,6 +2137,51 @@ void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S, } } +Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *D, + CXXSpecialMember SM, + bool ConstArg, + bool VolatileArg, + bool RValueThis, + bool ConstThis, + bool VolatileThis) { + D = D->getDefinition(); + assert((D && !D->isBeingDefined()) && + "doing special member lookup into record that isn't fully complete"); + if (RValueThis || ConstThis || VolatileThis) + assert((SM == CXXCopyAssignment || SM == CXXMoveAssignment) && + "constructors and destructors always have unqualified lvalue this"); + if (ConstArg || VolatileArg) + assert((SM != CXXDefaultConstructor && SM != CXXDestructor) && + "parameter-less special members can't have qualified arguments"); + + // Check the cache for this member + SpecialMemberID ID = {D, SM, ConstArg, VolatileArg, RValueThis, ConstThis, + VolatileThis}; + SpecialMemberOverloadResult Blank; + llvm::DenseMap<SpecialMemberID, SpecialMemberOverloadResult>::iterator It; + bool New; + + llvm::tie(It, New) = SpecialMemberCache.insert(std::make_pair(ID, Blank)); + SpecialMemberOverloadResult &Result = It->second; + + // This was already cached + if (!New) + return Result; + + if (SM == CXXDestructor) { + if (!D->hasDeclaredDestructor()) + DeclareImplicitDestructor(D); + CXXDestructorDecl *DD = D->getDestructor(); + assert(DD && "record without a destructor"); + Result.setMethod(DD); + Result.setSuccess(DD->isDeleted()); + Result.setConstParamMatch(false); + return Result; + } + + llvm_unreachable("haven't implemented this for non-destructors yet"); +} + /// \brief Look up the constructors for the given class. DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) { // If the copy constructor has not yet been declared, do so now. @@ -2153,17 +2199,13 @@ DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) { /// \brief Look for the destructor of the given class. /// -/// During semantic analysis, this routine should be used in lieu of -/// CXXRecordDecl::getDestructor(). +/// The destructor will be declared if necessary. /// /// \returns The destructor for this class. CXXDestructorDecl *Sema::LookupDestructor(CXXRecordDecl *Class) { - // If the destructor has not yet been declared, do so now. - if (CanDeclareSpecialMemberFunction(Context, Class) && - !Class->hasDeclaredDestructor()) - DeclareImplicitDestructor(Class); - - return Class->getDestructor(); + return cast<CXXDestructorDecl>(LookupSpecialMember(Class, CXXDestructor, + false, false, false, + false, false).getMethod()); } void ADLResult::insert(NamedDecl *New) { |