Clang LLVM调试信息的中间表示
clang llvm intermidiate representation for debug information
你好,我有以下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();
}
I use following clangExample.cpp -S -emit-llvm -o -
command and get
; ModuleID = 'C:clangParamclangExample.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);
}
我得到clang输出
C:Windowssystem32>clang C:clangParamclangExample.cpp -S -emit-llvm -o -
; ModuleID = 'C:clangParamclangExample.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
}
尽管我对模板类进行了初始化,但仍然没有对它的引用。
不导出甚至不编译的原因是类声明中的函数是内联的。这意味着它们只在特定的代码文件中被知道和编译。
如果将类声明放入头文件中,每个. pcp文件将分别编译get1()和get2()函数的代码(因此它将在最终可执行文件中出现两次)。
ClassBase::get1()和ClassBase::get2()从来没有被引用过,所以它们被省略了。这同样适用于类重载的可能性:编译器知道没有任何类的派生,因为他看到了所有可能的派生。
为什么不通过-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 ]
查找class-type标签,可以找到
!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 ]
相关文章:
- 表示"accepting anything for this template argument" C++概念的通配符
- 2D数组来自文本输入,中间有空格
- 如何将ampl中的集合表示为c++中的向量
- std::is_base_of表示ctor编译错误
- 输入中的字符串数未知(以字母表示)
- 我可以信任表示整数的浮点或双精度来保持精度吗
- c++模板来表示多项式
- 询问在设计我的手臂模拟器功能表示格式1
- CMakeLists.txt中的命名空间表示法
- C++射线示踪剂ppm表示没有足够的数据来显示图像
- 如何计算Big-O表示法中的平均渐近运行时间
- 我应该如何表示我拥有的连续元素序列?
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- 表示类模板C++空类型
- 无法使用 Openvino 中间表示文件转发() 网络,但可以使用我正在制作 IR 的 ONNX 文件
- 如何从LLVM的中间表示中获取在程序的每个函数中执行的函数调用列表
- 将c代码的中间表示分解回c
- LLVM中间表示:fptoui与fptosi
- Clang LLVM调试信息的中间表示