【发布时间】:2013-05-08 18:44:04
【问题描述】:
我有一个输入文件 (.ll),我想用 LLVM 对其进行解析,从而生成程序的内存表示,然后它应该不被解析并转储到标准输出,但纯粹来自生成的AST。我成功了一部分。 LLVM 解析程序并将模块转储到标准输出。然而,原始源代码的格式被保留。这让人认为 LLVM 并没有真正解析 AST 以转储模块,而是 LLVM 将文本表示与内存中的 AST 一起存储,如果没有进行任何更改,则更喜欢转储此文本表示,这不是我想要的。
std::cout << "Reading IR ...\n";
LLVMContext &Context = getGlobalContext();
SMDiagnostic Err;
Module *Mod = ParseIRFile(argv[1], Err, Context);
if (!Mod) {
std::cerr << "Problems reading IR\n";
return 1;
}
Mod->dump();
我的问题是:为什么在转储模块时保留原始源代码的格式,有没有办法让 LLVM 删除程序的文本表示并让它实际上解开 AST?
【问题讨论】:
-
只是一种理论,但一些工具旨在保留他们可以“往返”的一切,因为这通常是正确的做法。这并不意味着生成不是从 AST 发生的——我没有这方面的经验,但我猜这要么意味着 AST 中的内容比你看到的要多,要么输出端引用原始源以及 AST。无论哪种方式,为了确保输出包含您想要的内容,一种方法是首先复制 AST - 仅复制您想要的那些节点和详细信息,并将任何链接断开回源。
-
不过,这可能不是一个好方法,因为它假设你知道你想要的 AST 节点不仅是完美的,而且它会保持完美——新的 AST 节点类型和新的 LLVM 版本可能很容易被忽视。
-
有趣的问题!我从来没有注意到转储模块会保留格式,你能附上一个例子吗?另外,请注意:虽然解析 IR 时可能会使用 AST,但 LLVM IR 本身并不是 AST -
Module中没有隐藏树。 -
你是对的!格式实际上有一些细微的变化,例如与输入中的 1 个空格相比缩进 2 个空格。快速概览看起来与我确信实际上没有发生任何事情的输入非常接近。但上面的代码确实解析了 IR,至少看起来,没有格式与 IR 一起存储(在内存中)。
-
@Frank 很高兴我能帮上忙。我添加了我的评论作为答案,所以它会更明显。