summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CGVtable.cpp15
-rw-r--r--clang/test/CodeGenCXX/template-instantiation.cpp14
2 files changed, 26 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp
index 841281cdc42..bae588ab9b8 100644
--- a/clang/lib/CodeGen/CGVtable.cpp
+++ b/clang/lib/CodeGen/CGVtable.cpp
@@ -3138,19 +3138,28 @@ void CodeGenVTables::EmitVTableRelatedData(GlobalDecl 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 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 ||
+ RDKind == TSK_ExplicitInstantiationDeclaration) &&
+ MDKind == TSK_ExplicitInstantiationDefinition)
+ return;
}
if (Vtables.count(RD))
return;
- TemplateSpecializationKind kind = RD->getTemplateSpecializationKind();
- if (kind == TSK_ImplicitInstantiation)
+ if (RDKind == TSK_ImplicitInstantiation)
CGM.DeferredVtables.push_back(RD);
else
GenerateClassData(CGM.getVtableLinkage(RD), RD);
}
-
diff --git a/clang/test/CodeGenCXX/template-instantiation.cpp b/clang/test/CodeGenCXX/template-instantiation.cpp
index 9e0593998bb..416c0a1a207 100644
--- a/clang/test/CodeGenCXX/template-instantiation.cpp
+++ b/clang/test/CodeGenCXX/template-instantiation.cpp
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
// CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant
+// CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE
// CHECK: @_ZTVN5test018stdio_sync_filebufIwEE = constant
// CHECK: define linkonce_odr void @_ZN5test21CIiEC1Ev(
@@ -60,3 +61,16 @@ namespace test2 {
a.zedbar(0.0);
}
}
+
+namespace test3 {
+ template<typename T>
+ class basic_fstreamXX {
+ virtual void foo(){}
+ virtual void is_open() const { }
+ };
+
+ extern template class basic_fstreamXX<char>;
+ // This template instantiation should not cause us to produce a vtable.
+ // (test at the top).
+ template void basic_fstreamXX<char>::is_open() const;
+}
OpenPOWER on IntegriCloud