[cfe-commits] r116186 - in /cfe/trunk: lib/CodeGen/CGRTTI.cpp lib/CodeGen/CGVTables.cpp lib/CodeGen/CGVTables.h test/CodeGenCXX/vtable-linkage.cpp
Argyrios Kyrtzidis
akyrtzi at gmail.com
Sun Oct 10 20:25:57 PDT 2010
Author: akirtzidis
Date: Sun Oct 10 22:25:57 2010
New Revision: 116186
URL: http://llvm.org/viewvc/llvm-project?rev=116186&view=rev
Log:
Make sure the VTables for template instantiations are emitted even if the key function doesn't have a body.
Modified:
cfe/trunk/lib/CodeGen/CGRTTI.cpp
cfe/trunk/lib/CodeGen/CGVTables.cpp
cfe/trunk/lib/CodeGen/CGVTables.h
cfe/trunk/test/CodeGenCXX/vtable-linkage.cpp
Modified: cfe/trunk/lib/CodeGen/CGRTTI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRTTI.cpp?rev=116186&r1=116185&r2=116186&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRTTI.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRTTI.cpp Sun Oct 10 22:25:57 2010
@@ -270,8 +270,9 @@
/// the given type exists somewhere else, and that we should not emit the type
/// information in this translation unit. Assumes that it is not a
/// standard-library type.
-static bool ShouldUseExternalRTTIDescriptor(ASTContext &Context,
- QualType Ty) {
+static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty) {
+ ASTContext &Context = CGM.getContext();
+
// If RTTI is disabled, don't consider key functions.
if (!Context.getLangOptions().RTTI) return false;
@@ -283,13 +284,7 @@
if (!RD->isDynamicClass())
return false;
- // Get the key function.
- const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD);
- if (KeyFunction && !KeyFunction->hasBody()) {
- // The class has a key function, but it is not defined in this translation
- // unit, so we should use the external descriptor for it.
- return true;
- }
+ return !CGM.getVTables().ShouldEmitVTableInThisTU(RD);
}
return false;
@@ -528,8 +523,7 @@
// Check if there is already an external RTTI descriptor for this type.
bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty);
- if (!Force &&
- (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM.getContext(), Ty)))
+ if (!Force && (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM, Ty)))
return GetAddrOfExternalRTTIDescriptor(Ty);
// Emit the standard library with external linkage.
Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=116186&r1=116185&r2=116186&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Sun Oct 10 22:25:57 2010
@@ -2336,6 +2336,27 @@
NumVirtualFunctionPointers[RD] = CurrentIndex;
}
+bool CodeGenVTables::ShouldEmitVTableInThisTU(const CXXRecordDecl *RD) {
+ assert(RD->isDynamicClass() && "Non dynamic classes have no VTable.");
+
+ TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind();
+ if (TSK == TSK_ExplicitInstantiationDeclaration)
+ return false;
+
+ const CXXMethodDecl *KeyFunction = CGM.getContext().getKeyFunction(RD);
+ if (!KeyFunction)
+ return true;
+
+ // Itanium C++ ABI, 5.2.6 Instantiated Templates:
+ // An instantiation of a class template requires:
+ // - In the object where instantiated, the virtual table...
+ if (TSK == TSK_ImplicitInstantiation ||
+ TSK == TSK_ExplicitInstantiationDefinition)
+ return true;
+
+ return KeyFunction->hasBody();
+}
+
uint64_t CodeGenVTables::getNumVirtualFunctionPointers(const CXXRecordDecl *RD) {
llvm::DenseMap<const CXXRecordDecl *, uint64_t>::iterator I =
NumVirtualFunctionPointers.find(RD);
@@ -2703,9 +2724,7 @@
// We may need to generate a definition for this vtable.
if (RequireVTable && !Entry.getInt()) {
- if (!isKeyFunctionInAnotherTU(CGM.getContext(), RD) &&
- RD->getTemplateSpecializationKind()
- != TSK_ExplicitInstantiationDeclaration)
+ if (ShouldEmitVTableInThisTU(RD))
CGM.DeferredVTables.push_back(RD);
Entry.setInt(true);
Modified: cfe/trunk/lib/CodeGen/CGVTables.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.h?rev=116186&r1=116185&r2=116186&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.h (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.h Sun Oct 10 22:25:57 2010
@@ -295,14 +295,9 @@
CodeGenVTables(CodeGenModule &CGM)
: CGM(CGM) { }
- // isKeyFunctionInAnotherTU - True if this record has a key function and it is
- // in another translation unit.
- static bool isKeyFunctionInAnotherTU(ASTContext &Context,
- const CXXRecordDecl *RD) {
- assert (RD->isDynamicClass() && "Non dynamic classes have no key.");
- const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD);
- return KeyFunction && !KeyFunction->hasBody();
- }
+ /// \brief True if the VTable of this record must be emitted in the
+ /// translation unit.
+ bool ShouldEmitVTableInThisTU(const CXXRecordDecl *RD);
/// needsVTTParameter - Return whether the given global decl needs a VTT
/// parameter, which it does if it's a base constructor or destructor with
Modified: cfe/trunk/test/CodeGenCXX/vtable-linkage.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vtable-linkage.cpp?rev=116186&r1=116185&r2=116186&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/vtable-linkage.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/vtable-linkage.cpp Sun Oct 10 22:25:57 2010
@@ -197,3 +197,18 @@
template <typename T>
void G<T>::f0() {}
void G_f0() { new G<int>(); }
+
+// RUN: FileCheck --check-prefix=CHECK-H %s < %t
+
+// H<int> has a key function without a body but it's a template instantiation
+// so its VTable must be emmitted.
+// CHECK-H: @_ZTV1HIiE = weak_odr constant
+template <typename T>
+class H {
+public:
+ virtual ~H();
+};
+
+void use_H() {
+ H<int> h;
+}
More information about the cfe-commits
mailing list