[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 16:14:41 PDT 2010


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 ?

-Argiris

> 
> 	- Doug

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


More information about the cfe-commits mailing list