<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Oct 11, 2010, at 4:14 PM, Argyrios Kyrtzidis wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On 11 Oct 2010, at 14:20, Douglas Gregor wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div><br><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">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.<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">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.<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">But where does the body of the key function come from? Some other library that's loaded dynamically?<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Yes, exactly.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">More importantly, did the key function get instantiated somewhere and we failed to emit the vtables + RTTI at that point?<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">No, it gets instantiated at a library outside of the executable.<br></blockquote><br><br>That is absolutely disgusting :(<br><br>Alright, we're stuck with this approach, then. Thanks for fixing this.<br></div></blockquote><div><br></div><div>Some more mind-numbing details..</div><div><br></div><div>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.</div><div><br></div><div>On another note, another difference with gcc I noticed is this:</div><div><br></div><div><b>$ cat t.cpp</b></div><div><div>template <typename T></div><div>struct S  {</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>virtual void m();</div><div>};</div><div><br></div><div>template<typename T></div><div>void S<T>::m() { }</div><div><br></div><div>template void S<int>::m();</div><div><br></div><div><b>$ llvm-gcc -S -emit-llvm t.cpp -o - </b></div><div>[...]</div><div>%"struct.S<int>" = type { i32 (...)** }</div><div><br></div><div>define void @_ZN1SIiE1mEv(%"struct.S<int>"* %this) nounwind ssp align 2 {</div><div>entry:</div><div>  %this_addr = alloca %"struct.S<int>"*, align 4</div><div>  %"alloca point" = bitcast i32 0 to i32</div><div>  store %"struct.S<int>"* %this, %"struct.S<int>"** %this_addr</div><div>  br label %return</div><div><br></div><div>return:                                           ; preds = %entry</div><div>  ret void</div><div>}</div><div><br></div><div><br></div><div><b>$ clang -S -emit-llvm t.cpp -o - </b></div><div>[...]</div><div>%0 = type { i8*, i8* }</div><div>%struct.S = type { i32 (...)** }</div><div><br></div><div>@_ZTV1SIiE = weak_odr constant [3 x i8*] [i8* null, i8* bitcast (%0* @_ZTI1SIiE to i8*), i8* bitcast (void (%struct.S*)* @_ZN1SIiE1mEv to i8*)]</div><div>@_ZTVN10__cxxabiv117__class_type_infoE = external global i8*</div><div>@_ZTS1SIiE = weak_odr constant [6 x i8] c"1SIiE\00"</div><div>@_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) }</div><div><br></div><div>define weak_odr void @_ZN1SIiE1mEv(%struct.S* %this) nounwind ssp align 2 {</div><div>  %1 = alloca %struct.S*, align 8</div><div>  store %struct.S* %this, %struct.S** %1, align 8</div><div>  %2 = load %struct.S** %1</div><div>  ret void</div><div>}</div><div><br></div><div>So we emit the VTable+RTTI symbols while gcc does not.</div><div>I think this is because gcc doesn't consider that template instantiations have key functions (due to C++ ABI 5.2.6 probably).</div><div>Do we want to have the same behavior ?</div></div></div></div></blockquote><div><br></div>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.</div><div><br><span class="Apple-tab-span" style="white-space:pre">     </span>- Doug</div><br></body></html>