aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaLookup.cpp
diff options
context:
space:
mode:
authorSean Hunt <scshunt@csclub.uwaterloo.ca>2011-06-03 18:36:49 +0000
committerSean Hunt <scshunt@csclub.uwaterloo.ca>2011-06-03 18:36:49 +0000
commit8fd7722fce4e4f9549897699ec3a4c752613b214 (patch)
treee08eefef1b148b8f7732d7921e5a77019fa5c0d8 /lib/Sema/SemaLookup.cpp
parentee22697a56f3035419e71762134ff7ea0d8f1eb8 (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.cpp58
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) {