【问题标题】:How to force LLVM to unparse the AST?如何强制 LLVM 解析 AST?
【发布时间】: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 很高兴我能帮上忙。我添加了我的评论作为答案,所以它会更明显。

标签: c++ llvm


【解决方案1】:

IR 解析器保留格式。这样做没有任何意义。它只是一个 IR 写入器,用于将模块转储到标准输出,与用于转储到 .ll 文件的写入器完全相同。因此,与输入 .ll 文件相比,转储中的格式始终相同,除非后者是手动生成的。

【讨论】:

    【解决方案2】:

    我从未注意到转储模块会保留格式,您应该再次检查。据我所知,这不应该发生。

    此外,虽然解析 IR 时可能会使用 AST,但 LLVM IR 本身并不是 AST - 模块中没有隐藏树。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-15
      相关资源
      最近更新 更多