[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
kyrtzidis at apple.com
Mon Oct 11 11:22:12 PDT 2010
$ cat t.cpp
template <typename T>
struct S {
virtual void m();
};
void f() {
S<int> *s = new S<int>;
}
$ clang -S -emit-llvm t.cpp -o -
[...]
@_ZTV1SIiE = external constant [3 x i8*]
[...]
$ llvm-gcc -S -emit-llvm t.cpp -o -
[...]
%struct.__class_type_info_pseudo = type { %struct.__type_info_pseudo }
%struct.__type_info_pseudo = type { i8*, i8* }
@_ZTV1SIiE = weak_odr constant [3 x i32 (...)*] [i32 (...)* null, i32 (...)* bitcast (%struct.__class_type_info_pseudo* @_ZTI1SIiE to i32 (...)*), i32 (...)* bitcast (void (%"struct.S<int>"*)* @_ZN1SIiE1mEv to i32 (...)*)], align 16 ; <[3 x i32 (...)*]*> [#uses=1]
@_ZTI1SIiE = weak_odr constant %struct.__class_type_info_pseudo { %struct.__type_info_pseudo { i8* inttoptr (i64 add (i64 ptrtoint ([0 x i32 (...)*]* @_ZTVN10__cxxabiv117__class_type_infoE to i64), i64 16) to i8*), i8* getelementptr inbounds ([6 x i8]* @_ZTS1SIiE, i64 0, i64 0) } }, align 16 ; <%struct.__class_type_info_pseudo*> [#uses=1]
@_ZTVN10__cxxabiv117__class_type_infoE = external constant [0 x i32 (...)*] ; <[0 x i32 (...)*]*> [#uses=1]
@_ZTS1SIiE = weak_odr constant [6 x i8] c"1SIiE\00" ; <[6 x i8]*> [#uses=2]
[..]
This resulted in an unresolved symbol linker error in Qt.
"C++ ABI 5.2.6 Instantiated Templates" says that template instantiations emit the virtual table in the object where instantiated, it doesn't mention the key function.
-Argyrios
On Oct 11, 2010, at 11:10 AM, Douglas Gregor wrote:
>
> On Oct 10, 2010, at 8:25 PM, Argyrios Kyrtzidis wrote:
>
>> 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.
>
> This doesn't seem right. The vtables should come with the key function, according to the C++ ABI, whenever/wherever it is instantiated. What prompted this change? I suggest reverting it until we understand the issue that you were seeing.
>
> - Doug
>
>> 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;
>> +}
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
More information about the cfe-commits
mailing list