aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGVTables.cpp54
-rw-r--r--lib/CodeGen/CGVTables.h10
-rw-r--r--lib/CodeGen/CodeGenModule.cpp10
-rw-r--r--lib/CodeGen/CodeGenModule.h2
-rw-r--r--lib/CodeGen/ModuleBuilder.cpp7
5 files changed, 27 insertions, 56 deletions
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index df0f641a50..368e2483c8 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/lib/CodeGen/CGVTables.cpp
@@ -2788,7 +2788,13 @@ void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD) {
// Check if we've computed this information before.
if (LayoutData)
return;
-
+
+ // We may need to generate a definition for this vtable.
+ if (!isKeyFunctionInAnotherTU(CGM.getContext(), RD) &&
+ RD->getTemplateSpecializationKind()
+ != TSK_ExplicitInstantiationDeclaration)
+ CGM.DeferredVTables.push_back(RD);
+
VTableBuilder Builder(*this, RD, 0, /*MostDerivedClassIsVirtual=*/0, RD);
// Add the VTable layout.
@@ -3119,49 +3125,3 @@ CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
DC->getParent()->isTranslationUnit())
CGM.EmitFundamentalRTTIDescriptors();
}
-
-void CodeGenVTables::EmitVTableRelatedData(GlobalDecl GD) {
- const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
- const CXXRecordDecl *RD = MD->getParent();
-
- // If the class doesn't have a vtable we don't need to emit one.
- if (!RD->isDynamicClass())
- return;
-
- // Check if we need to emit thunks for this function.
- if (MD->isVirtual())
- EmitThunks(GD);
-
- // Get the key function.
- const CXXMethodDecl *KeyFunction = CGM.getContext().getKeyFunction(RD);
-
- TemplateSpecializationKind RDKind = RD->getTemplateSpecializationKind();
- TemplateSpecializationKind MDKind = MD->getTemplateSpecializationKind();
-
- if (KeyFunction) {
- // We don't have the right key function.
- if (KeyFunction->getCanonicalDecl() != MD->getCanonicalDecl())
- return;
- } else {
- // If we have no key function and this is a explicit instantiation
- // declaration, we will produce a vtable at the explicit instantiation. We
- // don't need one here.
- if (RDKind == clang::TSK_ExplicitInstantiationDeclaration)
- return;
-
- // If this is an explicit instantiation of a method, we don't need a vtable.
- // Since we have no key function, we will emit the vtable when we see
- // a use, and just defining a function is not an use.
- if (RDKind == TSK_ImplicitInstantiation &&
- MDKind == TSK_ExplicitInstantiationDefinition)
- return;
- }
-
- if (VTables.count(RD))
- return;
-
- if (RDKind == TSK_ImplicitInstantiation)
- CGM.DeferredVTables.push_back(RD);
- else
- GenerateClassData(CGM.getVTableLinkage(RD), RD);
-}
diff --git a/lib/CodeGen/CGVTables.h b/lib/CodeGen/CGVTables.h
index 6c18ca83f0..e55377f2fa 100644
--- a/lib/CodeGen/CGVTables.h
+++ b/lib/CodeGen/CGVTables.h
@@ -272,9 +272,6 @@ class CodeGenVTables {
/// EmitThunk - Emit a single thunk.
void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk);
- /// EmitThunks - Emit the associated thunks for the given global decl.
- void EmitThunks(GlobalDecl GD);
-
/// ComputeVTableRelatedInformation - Compute and store all vtable related
/// information (vtable layout, vbase offset offsets, thunks etc) for the
/// given record decl.
@@ -349,11 +346,10 @@ public:
VTableAddressPointsMapTy& AddressPoints);
llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);
-
- // EmitVTableRelatedData - Will emit any thunks that the global decl might
- // have, as well as the vtable itself if the global decl is the key function.
- void EmitVTableRelatedData(GlobalDecl GD);
+ /// EmitThunks - Emit the associated thunks for the given global decl.
+ void EmitThunks(GlobalDecl GD);
+
/// GenerateClassData - Generate all the class data required to be generated
/// upon definition of a KeyFunction. This includes the vtable, the
/// rtti data structure and the VTT.
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 6cbc3f67c2..6dd16e73b4 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -727,8 +727,9 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {
Context.getSourceManager(),
"Generating code for declaration");
- if (isa<CXXMethodDecl>(D))
- getVTables().EmitVTableRelatedData(GD);
+ if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))
+ if (Method->isVirtual())
+ getVTables().EmitThunks(GD);
if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))
return EmitCXXConstructor(CD, GD.getCtorType());
@@ -984,6 +985,11 @@ void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) {
EmitGlobalVarDefinition(D);
}
+void CodeGenModule::EmitVTable(CXXRecordDecl *Class, bool DefinitionRequired) {
+ if (DefinitionRequired)
+ getVTables().GenerateClassData(getVTableLinkage(Class), Class);
+}
+
llvm::GlobalVariable::LinkageTypes
CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
if (RD->isInAnonymousNamespace() || !RD->hasLinkage())
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 93d8ddf3e4..0e4f4a932e 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -422,6 +422,8 @@ public:
void EmitTentativeDefinition(const VarDecl *D);
+ void EmitVTable(CXXRecordDecl *Class, bool DefinitionRequired);
+
enum GVALinkage {
GVA_Internal,
GVA_C99Inline,
diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp
index 1e1edc1c48..9905ca6f1d 100644
--- a/lib/CodeGen/ModuleBuilder.cpp
+++ b/lib/CodeGen/ModuleBuilder.cpp
@@ -89,6 +89,13 @@ namespace {
Builder->EmitTentativeDefinition(D);
}
+
+ virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {
+ if (Diags.hasErrorOccurred())
+ return;
+
+ Builder->EmitVTable(RD, DefinitionRequired);
+ }
};
}