aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGVtable.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2010-03-10 02:19:29 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2010-03-10 02:19:29 +0000
commitbbf58bb1b8dd8c5e0f07547a6c20ffd55385fcf6 (patch)
tree3e25a743c7e7f0c466912150f246887d2d37a60d /lib/CodeGen/CGVtable.cpp
parent9a2a69f60898f771d44af0e40e7b4cf37b565d21 (diff)
Delay codegen of vtables when handling implicit instantiations.
This fixes PR6474. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98123 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGVtable.cpp')
-rw-r--r--lib/CodeGen/CGVtable.cpp38
1 files changed, 23 insertions, 15 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp
index 932bd079e9..a77a28ccdd 100644
--- a/lib/CodeGen/CGVtable.cpp
+++ b/lib/CodeGen/CGVtable.cpp
@@ -3405,7 +3405,22 @@ void CGVtableInfo::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0,
/*IsVirtual=*/false,
AddressPoints);
- GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);
+ GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);
+
+ for (CXXRecordDecl::method_iterator i = RD->method_begin(),
+ e = RD->method_end(); i != e; ++i) {
+ if (!(*i)->isVirtual())
+ continue;
+ if(!(*i)->hasInlineBody() && !(*i)->isImplicit())
+ continue;
+
+ if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(*i)) {
+ CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Complete));
+ CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Deleting));
+ } else {
+ CGM.BuildThunksForVirtual(GlobalDecl(*i));
+ }
+ }
}
llvm::GlobalVariable *CGVtableInfo::getVtable(const CXXRecordDecl *RD) {
@@ -3438,19 +3453,12 @@ void CGVtableInfo::MaybeEmitVtable(GlobalDecl GD) {
return;
}
- // Emit the data.
- GenerateClassData(CGM.getVtableLinkage(RD), RD);
+ if (Vtables.count(RD))
+ return;
- for (CXXRecordDecl::method_iterator i = RD->method_begin(),
- e = RD->method_end(); i != e; ++i) {
- if ((*i)->isVirtual() && ((*i)->hasInlineBody() || (*i)->isImplicit())) {
- if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(*i)) {
- CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Complete));
- CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Deleting));
- } else {
- CGM.BuildThunksForVirtual(GlobalDecl(*i));
- }
- }
- }
+ TemplateSpecializationKind kind = RD->getTemplateSpecializationKind();
+ if (kind == TSK_ImplicitInstantiation)
+ CGM.DeferredVtables.push_back(RD);
+ else
+ GenerateClassData(CGM.getVtableLinkage(RD), RD);
}
-