<div dir="ltr"><div><div><div><div><div><div><div><div><div><div><div>Hi All,<br><br></div>Recently I am using clang++ (3.8.0) to compile some c++ programs and find that some type names will be changed after linking different modules. Here is a simple example:<br><br></div>I have two files: main.cpp and b.cpp<br><br></div>main.cpp<br>#include <iostream><br>using namespace std;<br><br>class A {<br>  public:<br>    virtual void f() {<br>      cout << "A:\tf\n";<br>    }<br>};<br><br>int main ()<br>{<br>  A *p = new A;<br>  p->f();<br>  return 0;<br>}<br><br></div>b.cpp<br>#include <iostream><br>using namespace std;<br><br>class X {<br>public:<br>    virtual int g();<br>};<br><br>int X::g()<br>{<br>    cout << "X:\tg\n";<br>    return 0;<br>}<br><br></div>I use the following commands to compile these two files separately and then link them tegother:<br></div>clang++ -c -emit-llvm -o b.bc b.cpp<br></div>clang++ -c -emit-llvm -o main.bc main.cpp<br></div>llvm-link -o whole.bc b.bc main.bc<br></div>opt -mem2reg -o whole.mem2reg.bc whole.bc<br></div>llvm-dis -o whole.mem2reg.ll whole.mem2reg.bc<br><br></div>In the file whole.mem2reg.ll, type "class.A" has been replaced by "class.X" in function main, the constructor of class A and the virtual member function f of class A:<br><br clear="all"><div><div><div><div><div><div><div><div><div><div><div><div><div>; Function Attrs: norecurse uwtable<br>define i32 @main() #3 {<br>  %1 = call noalias i8* @_Znwm(i64 8) #6<br>  %2 = bitcast i8* %1 to %class.X*<br>  call void @_ZN1AC2Ev(%class.X* %2) #2<br>  %3 = bitcast %class.X* %2 to void (%class.X*)***<br>  %4 = load void (%class.X*)**, void (%class.X*)*** %3, align 8<br>  %5 = getelementptr inbounds void (%class.X*)*, void (%class.X*)** %4, i64 0<br>  %6 = load void (%class.X*)*, void (%class.X*)** %5, align 8<br>  call void %6(%class.X* %2)<br>  ret i32 0<br>}<br><br>; Function Attrs: inlinehint nounwind uwtable<br>define linkonce_odr void @_ZN1AC2Ev(%class.X* %this) unnamed_addr #5 comdat align 2 {<br>  %1 = bitcast %class.X* %this to i32 (...)***<br>  store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**), i32 (...)*** %1, align 8<br>  ret void<br>}<br><br>; Function Attrs: uwtable<br>define linkonce_odr void @_ZN1A1fEv(%class.X* %this) unnamed_addr #0 comdat align 2 {<br>  %1 = call dereferenceable(272) %"class.std::basic_ostream"* @_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(%"class.std::basic_ostream"* dereferenceable(272) @_ZSt4cout, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.4, i32 0, i32 0))<br>  ret void<br>}<br><br></div><div>Does anyone know why llvm replace the type name and how to stop llvm from doing this?<br><br></div><div>Thanks<br><br></div><div>-- <br><div class="gmail_signature"><div dir="ltr"><div style="color:rgb(136,136,136)">Xiaokang Fan</div><div style="color:rgb(136,136,136)"><br></div><div style="color:rgb(136,136,136)">PhD Student</div><div style="color:rgb(136,136,136)">School of Computer Science and Engineering</div><div style="color:rgb(136,136,136)">The University of New South Wales</div><div style="color:rgb(136,136,136)">Sydney 2052 Australia</div></div></div>
</div></div></div></div></div></div></div></div></div></div></div></div></div></div>