使用clang进行源到源的转换(最新技术)

时间:2017-10-11 15:31:50

标签: c++ clang

使用clang进行源到源转换的最新技术状态如何?

我几乎跟踪了Web上的所有资源,我可以通过clang插件实现源代码重写(Rewriter),但最终的二进制文件没有更新(CodeGen是主要的活动,它是编译的无论我在插件中修改了什么,即使在AddBeforeMainAction中使用getActionType

我已经看过一些关于libTooling的文档以及如何创建一个使用clang作为库的独立程序,但我的目的是创建一个插件(FrontendPluginRegistry::Add<>,一些“简单”插入非自定义clang binary)并实现源到源的修改(对用户透明,避免覆盖他们的源文件)。

修改:如果不清楚: 我需要像“插件”这样的东西来轻松扩展clang。我需要在编译过程中“集成”的东西。为什么?因为我需要在编译阶段修改源代码,注入新代码,一步修改用户的源代码(我不想创建工具来解析用户源代码然后编译输出文件) 。另外,我想分发我的代码(插件)以允许用户自己使用它。

必须在clang(clang $FLAGS $PLUGIN $ETC -o program source_files...)的编译阶段。

1 个答案:

答案 0 :(得分:1)

  

CodeGen是主要活动,无论我在插件中修改了什么,它都会被编译

是的,这是因为Clang AST被设计为不可变的。解析后无法更改它。

因此,Clang最先进的s2s转型看起来像这样:

  • 将C ++源代码解析为AST
  • 将文本替换应用于原始源代码,生成新的源代码
  • 解析新的源代码以创建新的AST

您可以“在内存中”执行所有步骤,因此最终用户不会注意到。

<强>更新 我自己从未写过clang插件。但这是我注意到的: 如果你运行Clang前端实际生成目标代码:

  clang -cc1 -emit-obj main.c

它将运行EmitObjAction。 EmitObjAction是一个FrontEnd Action,因此它将解析输入源并运行codegen。因此,如果您并行运行其他FrontEnd操作,它们将对EmitObjAction没有影响。因为每个FrontEnd操作都会解析原始输入源代码。

你可以做的是用你自己的fork替换EmitObjAction,它将根据你的需要进行尽可能多的重新解析。

如果你将PluginASTAction :: ActionType设置为ReplaceAction,它应该用你自己提供的插件替换内置的Codegen动作。