【问题标题】:Changing the source code with a clang plugin使用 clang 插件更改源代码
【发布时间】:2015-10-05 05:35:15
【问题描述】:

我有一个使用 libtooling 的现有且有效的源代码到源代码修改工具。现在我想把这个工具集成到clang中,这样用户就可以编译修改后的源代码,而无需实际保存在某个地方。

修改部分没有问题,Matchers + Rewriters 与 clang 的工作方式相同,我的问题是如何告诉编译器在我更改后重新解析源代码。

我目前的进展:

  • 我在 cve-dev 上找到了一个对话,但没有具体信息如何进行
  • 我也找到了clang::ASTUnit::Reparse,但我不知道怎么称呼它。在铿锵声源中,没有人使用它,我的每一次尝试都以崩溃为回报。
  • StackOverflow 中有一个类似的问题,但没有很好的答案
  • 有一些像traces这样的插件工具,它们做同样的源代码修改,但它只是调用编译器两次。

我希望基于前两个我最终找到一个可行的解决方案,但也许有人已经知道答案,并且可以帮助我举个例子,或者至少更具体的说明如何实现它?

【问题讨论】:

    标签: c++ clang


    【解决方案1】:

    您可以使用WrapperFrontendAction 包装生成目标文件的 EmitObjAction。在包装器操作中,您可以覆盖函数 BeginInvocation()。在此函数中,您可以创建自己的 ASTFrontendAction 遍历 AST 并使用 Rewriter 类执行文本更改。

    当您的操作完成后,您可以访问 Rewriter 类中的缓冲区。您可以复制这些缓冲区并将它们添加到 PreprocessorOptions 并使用addRemappedFile()。由于 PreprocessorOptions 附加到 CompilerInstance,它们也被您包装的以下 EmitObjAction 使用。

    这意味着 EmitObjAction 将实际读取更改的源文件。

    您可以从 Clang 中如何使用 FixItRecompile 类获得一些灵感。

    【讨论】:

    • 不幸的是,我不能用 WrapperFrontendAction 包装 EmitObjAction 而不实际修改 clang 的源(FixItRecompile 也被硬连线到其中)。还是我错过了什么?
    • 就个人而言,我更改了 clang 源来执行此操作,因此我编译了一个特殊用途的 clang 可执行文件。据我所知,如果您想使用 clang 插件或 libtooling,您确实必须向 clang 添加一些代码,以暴露包装 EmitObjAction 的可能性。您也可以随时尝试通过cfe-dev mailing list 询问。
    • 我想出了一个类似的解决方案(从我的 clang 工具调用 clang 编译器)。您的版本当然更易于使用,但它仍然需要我为每个 clang 版本进行维护,并且用户必须下载并指定不同的编译器而不仅仅是插件。我也在邮件列表上问过这个问题,并在那里得到了类似的答案。但看起来目前没有办法做到这一点,所以我会问他们是否接受将这种可能性添加到插件的补丁。
    猜你喜欢
    • 2013-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-04
    • 2015-01-15
    • 1970-01-01
    相关资源
    最近更新 更多