aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-12-07 04:35:11 +0000
committerAnders Carlsson <andersca@mac.com>2009-12-07 04:35:11 +0000
commitf53df2398e07d13be9962b95aebc19b31706fa33 (patch)
treea9483fc6f2798e465696bab68b7dfba13e80e965 /lib
parenta93c934af4fbf97cbe8e649d82e68ccacfe57c95 (diff)
Move key functions to a separate map.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90745 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp14
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp68
-rw-r--r--lib/AST/RecordLayoutBuilder.h1
-rw-r--r--lib/CodeGen/CGVtable.cpp4
-rw-r--r--lib/Sema/SemaDeclCXX.cpp8
5 files changed, 57 insertions, 38 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index cc96a5dc0e..490f338d38 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1104,6 +1104,20 @@ const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) {
return *NewEntry;
}
+const CXXMethodDecl *ASTContext::getKeyFunction(const CXXRecordDecl *RD) {
+ RD = cast<CXXRecordDecl>(RD->getDefinition(*this));
+ assert(RD && "Cannot get key function for forward declarations!");
+
+ const CXXMethodDecl *&Entry = KeyFunctions[RD];
+ if (!Entry)
+ Entry = ASTRecordLayoutBuilder::ComputeKeyFunction(RD);
+ else
+ assert(Entry == ASTRecordLayoutBuilder::ComputeKeyFunction(RD) &&
+ "Key function changed!");
+
+ return Entry;
+}
+
//===----------------------------------------------------------------------===//
// Type creation/memoization methods
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index 088673916f..550a32b0d0 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -663,35 +663,6 @@ void ASTRecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment) {
Alignment = NewAlignment;
}
-static const CXXMethodDecl *GetKeyFunction(const CXXRecordDecl *RD) {
- if (!RD->isDynamicClass())
- return 0;
-
- for (CXXRecordDecl::method_iterator I = RD->method_begin(),
- E = RD->method_end(); I != E; ++I) {
- const CXXMethodDecl *MD = *I;
-
- if (!MD->isVirtual())
- continue;
-
- if (MD->isPure())
- continue;
-
- // Ignore implicit member functions, they are always marked as inline, but
- // they don't have a body until they're defined.
- if (MD->isImplicit())
- continue;
-
- if (MD->hasInlineBody())
- continue;
-
- // We found it.
- return MD;
- }
-
- return 0;
-}
-
const ASTRecordLayout *
ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
const RecordDecl *D) {
@@ -715,8 +686,6 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
uint64_t NonVirtualSize =
IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize;
- const CXXMethodDecl *KeyFunction = GetKeyFunction(cast<CXXRecordDecl>(D));
-
return new ASTRecordLayout(Builder.Size, Builder.Alignment, DataSize,
Builder.FieldOffsets.data(),
Builder.FieldOffsets.size(),
@@ -726,8 +695,7 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
Builder.Bases.data(),
Builder.Bases.size(),
Builder.VBases.data(),
- Builder.VBases.size(),
- KeyFunction);
+ Builder.VBases.size());
}
const ASTRecordLayout *
@@ -743,3 +711,37 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
Builder.FieldOffsets.data(),
Builder.FieldOffsets.size());
}
+
+const CXXMethodDecl *
+ASTRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) {
+ assert(RD->isDynamicClass() && "Class does not have any virtual methods!");
+
+ // If a class isnt' polymorphic it doesn't have a key function.
+ if (!RD->isPolymorphic())
+ return 0;
+
+ for (CXXRecordDecl::method_iterator I = RD->method_begin(),
+ E = RD->method_end(); I != E; ++I) {
+ const CXXMethodDecl *MD = *I;
+
+ if (!MD->isVirtual())
+ continue;
+
+ if (MD->isPure())
+ continue;
+
+ // Ignore implicit member functions, they are always marked as inline, but
+ // they don't have a body until they're defined.
+ if (MD->isImplicit())
+ continue;
+
+ if (MD->hasInlineBody())
+ continue;
+
+ // We found it.
+ return MD;
+ }
+
+ return 0;
+}
+
diff --git a/lib/AST/RecordLayoutBuilder.h b/lib/AST/RecordLayoutBuilder.h
index 69e0498917..d4171d3cc9 100644
--- a/lib/AST/RecordLayoutBuilder.h
+++ b/lib/AST/RecordLayoutBuilder.h
@@ -151,6 +151,7 @@ public:
static const ASTRecordLayout *ComputeLayout(ASTContext &Ctx,
const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl);
+ static const CXXMethodDecl *ComputeKeyFunction(const CXXRecordDecl *RD);
};
} // end namespace clang
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp
index 6fda6a4404..d227a5e47e 100644
--- a/lib/CodeGen/CGVtable.cpp
+++ b/lib/CodeGen/CGVtable.cpp
@@ -1433,10 +1433,8 @@ void CGVtableInfo::MaybeEmitVtable(GlobalDecl GD) {
if (!RD->isDynamicClass())
return;
- const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
-
// Get the key function.
- const CXXMethodDecl *KeyFunction = Layout.getKeyFunction();
+ const CXXMethodDecl *KeyFunction = CGM.getContext().getKeyFunction(RD);
if (KeyFunction) {
// We don't have the right key function.
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 2df172e76e..1e96bf525a 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -5090,8 +5090,12 @@ void Sema::MaybeMarkVirtualImplicitMembersReferenced(SourceLocation Loc,
return;
CXXRecordDecl *RD = MD->getParent();
- const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
- const CXXMethodDecl *KeyFunction = Layout.getKeyFunction();
+
+ // Ignore classes without a vtable.
+ if (!RD->isDynamicClass())
+ return;
+
+ const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD);
if (!KeyFunction) {
// This record does not have a key function, so we assume that the vtable