Hello I have following c++ code
class classBase
{
public:
int get1(){return 1;}
int get2(){return 2;}
};
class classDer:public classBase
{
public:
int get1(){return 1;}
};
int f()
{
classDer x;
return x.get1();
}
I use following clangExample.cpp -S -emit-llvm -o - command and get
; ModuleID = 'C:\clangParam\clangExample.cpp'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
target triple = "i686-pc-win32"
%class.classDer = type { i8 }
define i32 @_Z1fv() {
entry:
%x = alloca %class.classDer, align 1
%call = call i32 @_ZN8classDer4get1Ev(%class.classDer* %x)
ret i32 %call
}
define linkonce_odr i32 @_ZN8classDer4get1Ev(%class.classDer* %this) nounwind align 2 {
entry:
%this.addr = alloca %class.classDer*, align 4
store %class.classDer* %this, %class.classDer** %this.addr, align 4
%this1 = load %class.classDer** %this.addr
ret i32 1
}
why there is no reference to the base class?(going over clang code for type generation I got the feeling that the base class type should be referenced.
Update
It makes sense
But if I use Template definition
template<class T>
class classTemplate
{
public:
T getMax(T in1,T in2){if(in2 > in1) return in2;return in1;}
};
int f()
{
classTemplate<int> x;
return x.getMax(3,4);
}
I get clang output
C:\Windows\system32>clang C:\clangParam\clangExample.cpp -S -emit-llvm -o -
; ModuleID = 'C:\clangParam\clangExample.cpp'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
target triple = "i686-pc-win32"
%class.classTemplate = type { i8 }
define i32 @_Z1fv() {
entry:
%x = alloca %class.classTemplate, align 1
%call = call i32 @_ZN13classTemplateIiE6getMaxEii(%class.classTemplate* %x, i32 3, i32 4)
ret i32 %call
}
define linkonce_odr i32 @_ZN13classTemplateIiE6getMaxEii(%class.classTemplate* %this, i32 %in1, i32 %in2) nounwind align 2 {
entry:
%retval = alloca i32, align 4
%this.addr = alloca %class.classTemplate*, align 4
%in1.addr = alloca i32, align 4
%in2.addr = alloca i32, align 4
store %class.classTemplate* %this, %class.classTemplate** %this.addr, align 4
store i32 %in1, i32* %in1.addr, align 4
store i32 %in2, i32* %in2.addr, align 4
%this1 = load %class.classTemplate** %this.addr
%tmp = load i32* %in2.addr, align 4
%tmp2 = load i32* %in1.addr, align 4
%cmp = icmp sgt i32 %tmp, %tmp2
br i1 %cmp, label %if.then, label %if.end
if.then: ; preds = %entry
%tmp3 = load i32* %in2.addr, align 4
store i32 %tmp3, i32* %retval
br label %return
if.end: ; preds = %entry
%tmp4 = load i32* %in1.addr, align 4
store i32 %tmp4, i32* %retval
br label %return
return: ; preds = %if.end, %if.then
%0 = load i32* %retval
ret i32 %0
}
There is again no reference to template class though I initialize it.
The reason why it is not exported and not even compiled is because functions inside class-declarations are inlined. That means they are only known and compiled inside that particular codefile.
If you would put the class-declaration into a headerfile each .cpp-file would compile the code for the get1() and get2() functions seperately (so it would be present twice in the final executable).
ClassBase::get1() and ClassBase::get2() are never referenced, and so they are left out.
The same applies for the possibility of class-overloading: The compiler knows, that there is no derivative of any of the classes, because he sees all there could possibly be.