clang llvm用于调试信息的中间表示

时间:2011-08-09 18:54:32

标签: c++ inheritance llvm clang

您好我有以下c ++代码


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(); }

我使用以下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.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
}

为什么没有对基类的引用?(对于类型生成的clang代码,我觉得应该引用基类类型。

更新 这说得通 但是,如果我使用模板定义

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);
}

我得到了铿锵输出

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
}

虽然我对它进行了初始化,但仍然没有对模板类的引用。

2 个答案:

答案 0 :(得分:2)

它未导出甚至未编译的原因是因为类声明中的函数是内联的。这意味着它们只在特定的代码文件中被知道并编译。

如果要将类声明放入头文件中,每个.cpp文件将单独编译get1()和get2()函数的代码(因此它将在最终的可执行文件中出现两次)。

ClassBase :: get1()和ClassBase :: get2()从不被引用,因此它们被省略了。 这同样适用于类重载的可能性:编译器知道,没有任何类的派生,因为他看到了可能存在的所有类。

答案 1 :(得分:1)

为什么不通过-g期望调试信息?这会输出许多元数据节点:

// clang++ -g3 -S -emit-llvm main1.cpp
// ...

!0 = metadata !{i32 589841, i32 0, i32 4, metadata !"main1.cpp", metadata !"/home/js/cpp", metadata !"clang version 3.0 (trunk 134121)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"f", metadata !"f", metadata !"_Z1fv", metadata !2, i32 16, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, i32 ()* @_Z1fv, null, null} ; [ DW_TAG_subprogram ]
!2 = metadata !{i32 589865, metadata !"main1.cpp", metadata !"/home/js/cpp", metadata !0} ; [ DW_TAG_file_type ]
!3 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
!4 = metadata !{metadata !5}
!5 = metadata !{i32 589860, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
!6 = metadata !{i32 589870, i32 0, metadata !7, metadata !"get1", metadata !"get1", metadata !"_ZN9classBase4get1Ev", metadata !2, i32 5, metadata !10, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null} ; [ DW_TAG_subprogram ]
!7 = metadata !{i32 589826, metadata !0, metadata !"classBase", metadata !2, i32 2, i64 8, i64 8, i32 0, i32 0, null, metadata !8, i32 0, null, null} ; [ DW_TAG_class_type ]
!8 = metadata !{metadata !6, metadata !9, metadata !13}
!9 = metadata !{i32 589870, i32 0, metadata !7, metadata !"get2", metadata !"get2", metadata !"_ZN9classBase4get2Ev", metadata !2, i32 6, metadata !10, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null} ; [ DW_TAG_subprogram ]
!10 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !11, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
!11 = metadata !{metadata !5, metadata !12}
!12 = metadata !{i32 589839, metadata !0, metadata !"", i32 0, i32 0, i64 32, i64 32, i64 0, i32 64, metadata !7} ; [ DW_TAG_pointer_type ]
!13 = metadata !{i32 589870, i32 0, metadata !7, metadata !"classBase", metadata !"classBase", metadata !"", metadata !2, i32 2, metadata !14, i1 false, i1 false, i32 0, i32 0, null, i32 320, i1 false, null, null} ; [ DW_TAG_subprogram ]
!14 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !15, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
!15 = metadata !{null, metadata !12}
!16 = metadata !{i32 589870, i32 0, metadata !17, metadata !"get1", metadata !"get1", metadata !"_ZN8classDer4get1Ev", metadata !2, i32 11, metadata !24, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null} ; [ DW_TAG_subprogram ]
!17 = metadata !{i32 589826, metadata !0, metadata !"classDer", metadata !2, i32 8, i64 8, i64 8, i32 0, i32 0, null, metadata !18, i32 0, null, null} ; [ DW_TAG_class_type ]
!18 = metadata !{metadata !19, metadata !16, metadata !20}
!19 = metadata !{i32 589852, metadata !17, null, metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !7} ; [ DW_TAG_inheritance ]
!20 = metadata !{i32 589870, i32 0, metadata !17, metadata !"classDer", metadata !"classDer", metadata !"", metadata !2, i32 8, metadata !21, i1 false, i1 false, i32 0, i32 0, null, i32 320, i1 false, null, null} ; [ DW_TAG_subprogram ]
!21 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !22, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
!22 = metadata !{null, metadata !23}
!23 = metadata !{i32 589839, metadata !0, metadata !"", i32 0, i32 0, i64 32, i64 32, i64 0, i32 64, metadata !17} ; [ DW_TAG_pointer_type ]
!24 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !25, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
!25 = metadata !{metadata !5, metadata !23}
!26 = metadata !{i32 589870, i32 0, metadata !0, metadata !"get1", metadata !"get1", metadata !"_ZN8classDer4get1Ev", metadata !2, i32 11, metadata !24, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, i32 (%class.classDer*)* @_ZN8classDer4get1Ev, null, metadata !16} ; [ DW_TAG_subprogram ]
!27 = metadata !{i32 590080, metadata !28, metadata !"x", metadata !2, i32 17, metadata !17, i32 0} ; [ DW_TAG_auto_variable ]
!28 = metadata !{i32 589835, metadata !1, i32 16, i32 1, metadata !2, i32 0} ; [ DW_TAG_lexical_block ]
!29 = metadata !{i32 17, i32 14, metadata !28, null}
!30 = metadata !{i32 18, i32 5, metadata !28, null}
!31 = metadata !{i32 590081, metadata !26, metadata !"this", metadata !2, i32 16777227, metadata !23, i32 64} ; [ DW_TAG_arg_variable ]
!32 = metadata !{i32 11, i32 9, metadata !26, null}
!33 = metadata !{i32 11, i32 16, metadata !34, null}
!34 = metadata !{i32 589835, metadata !26, i32 11, i32 15, metadata !2, i32 1} ; [ DW_TAG_lexical_block ]

寻找类型标签,找到

!7 = metadata !{i32 589826, metadata !0, metadata !"classBase", metadata !2, i32 2, i64 8, i64 8, i32 0, i32 0, null, metadata !8, i32 0, null, null} ; [ DW_TAG_class_type ]
!17 = metadata !{i32 589826, metadata !0, metadata !"classDer", metadata !2, i32 8, i64 8, i64 8, i32 0, i32 0, null, metadata !18, i32 0, null, null} ; [ DW_TAG_class_type ]