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

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to