1 Meatadata 介绍
1.1什么是 Metadata?
在 LLVM 中,我们使用 Clang 进行编译的时候,加上“-g”参数可以在 IR 文件中额外可以得到一些源代码级别的信息。例如:
clang -emit-llvm -S -g test.c -o test.ll
LLVM 把这些调试信息称为 Metadata。在 IR 层次上的分析遍或者转换遍可以使用这些信息。
1.2 Metadata 的格式
需要指出的是 LLVM Metadata 只是按照一定的格式保存数据。它不关心这些数据的意义。ll 文件中的格式
Metadata 在 IR 文件中是以“记录”的形式的组织的。每一条 Metadata 记录都单独占有一行。Metadata 记录可以看成“结构体变量”。它可以包含整形数据、字符串数据或者其他 Metada 数据。例如:
!24 = metadata !{i32 16, i32 0, metadata !4, null}
!24 Metadata 包 含 了 i32 类 型 的 数 据 32 和 0,以 及 一 个 其 他 的Metadata !4 和一个空的 Metadata。• 内部表示格式Metadata 是以 MDNode 对象的形式保存。
1.3调试信息的格式
上节中已经提到过,Metadata 只是要求数据按照一定的格式组织,它不关心数据的代表的具体含义(信息的具体格式)。所以理论上来说,前端开发者可以使用 Metadata 向 IR 层代传递任何他认为有用信息。Clang 对一些常用调试信息的格式进行约定,他们的格式可以查看官方文档http://llvm.org/docs/SourceLevelDebugging.html#debugging-information-format
1.4 Metadata 的访问接口
• MDNode我们可以直接使用MDNode 类提供的接口访问其各个分量数据。它是直接在MDNode 上操作。比如,如果我们已知mdn 是一个变量的Metadata,我们可以使用以下二行代码获得变量的名字:
MDString*mds=dyn_cast_or_null<MDString>(mdn->getOperand(2));
std::string varName=mds->getString();
具体接口可以参考 llvm 中的头文件“llvm/IR/Metadata.h”。
• DIDescriptor
DIDescriptor 是 LLVM 提供的高层接口。它对MDNode 进行了封装。例如,果我们已知mdn 是一个变量的 Metadata,可以用如下代码获得变量的名字:
DIVariable *div(mdn)
std::string varName=div.getName();
需要指出的是,DIDescriptor 只能用于访问格式满足 Clang 调试信息约定的信息。开发者自己定义的信息,需要使用MDNode 来访问,或者自己编写接口进行封装。具体接口可以参考 llvm 中的头文件“llvm/IR/DebugInfo.h”。