[cfe-commits] r116186 - in /cfe/trunk: lib/CodeGen/CGRTTI.cpp lib/CodeGen/CGVTables.cpp lib/CodeGen/CGVTables.h test/CodeGenCXX/vtable-linkage.cpp

Douglas Gregor dgregor at apple.com
Tue Oct 12 10:16:20 PDT 2010


On Oct 11, 2010, at 4:14 PM, Argyrios Kyrtzidis wrote:

> 
> On 11 Oct 2010, at 14:20, Douglas Gregor wrote:
> 
>> 
>>>>> 
>>>>> To be more clear, when using clang, the specific executable being linked fails with linker error because the VTable symbol is not defined in the object files being linked.
>>>>> With gcc, the VTable is emitted (as in the test case I posted) and the key function is resolved dynamically when the executable is run.
>>>> 
>>>> But where does the body of the key function come from? Some other library that's loaded dynamically?
>>> 
>>> Yes, exactly.
>>> 
>>>> 
>>>> More importantly, did the key function get instantiated somewhere and we failed to emit the vtables + RTTI at that point?
>>> 
>>> No, it gets instantiated at a library outside of the executable.
>> 
>> 
>> That is absolutely disgusting :(
>> 
>> Alright, we're stuck with this approach, then. Thanks for fixing this.
> 
> Some more mind-numbing details..
> 
> The VTable symbol cannot be resolved dynamically through the library when using clang because it's compiled with -fvisibility=hidden, resulting in hidden linkage for the VTable symbol.
> 
> On another note, another difference with gcc I noticed is this:
> 
> $ cat t.cpp
> template <typename T>
> struct S  {
> 	virtual void m();
> };
> 
> template<typename T>
> void S<T>::m() { }
> 
> template void S<int>::m();
> 
> $ llvm-gcc -S -emit-llvm t.cpp -o - 
> [...]
> %"struct.S<int>" = type { i32 (...)** }
> 
> define void @_ZN1SIiE1mEv(%"struct.S<int>"* %this) nounwind ssp align 2 {
> entry:
>   %this_addr = alloca %"struct.S<int>"*, align 4
>   %"alloca point" = bitcast i32 0 to i32
>   store %"struct.S<int>"* %this, %"struct.S<int>"** %this_addr
>   br label %return
> 
> return:                                           ; preds = %entry
>   ret void
> }
> 
> 
> $ clang -S -emit-llvm t.cpp -o - 
> [...]
> %0 = type { i8*, i8* }
> %struct.S = type { i32 (...)** }
> 
> @_ZTV1SIiE = weak_odr constant [3 x i8*] [i8* null, i8* bitcast (%0* @_ZTI1SIiE to i8*), i8* bitcast (void (%struct.S*)* @_ZN1SIiE1mEv to i8*)]
> @_ZTVN10__cxxabiv117__class_type_infoE = external global i8*
> @_ZTS1SIiE = weak_odr constant [6 x i8] c"1SIiE\00"
> @_ZTI1SIiE = weak_odr constant %0 { i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv117__class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([6 x i8]* @_ZTS1SIiE, i32 0, i32 0) }
> 
> define weak_odr void @_ZN1SIiE1mEv(%struct.S* %this) nounwind ssp align 2 {
>   %1 = alloca %struct.S*, align 8
>   store %struct.S* %this, %struct.S** %1, align 8
>   %2 = load %struct.S** %1
>   ret void
> }
> 
> So we emit the VTable+RTTI symbols while gcc does not.
> I think this is because gcc doesn't consider that template instantiations have key functions (due to C++ ABI 5.2.6 probably).
> Do we want to have the same behavior ?

GCC is probably emitting the vtable+RTTI symbols wherever they are used, as if an instantiated class never has a key function. I guess we should do the same, but suppressing the vtables+RTTI if the class in question is under the control of an explicit instantiation declaration and forcing emission if it is under the control of an explicit instantiation definition.

	- Doug

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20101012/37103236/attachment.html>


More information about the cfe-commits mailing list