clang的源到源转换(最新技术)

Source-to-Source transformation with clang (state of the art)

本文关键字:最新技术 源到源转换 clang      更新时间:2023-10-16

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

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

我看过一些关于libTooling以及如何创建一个使用clang作为库的独立程序的文档,但我的目的是创建一个插件(FrontendPluginRegistry::Add<>,一种"容易"插入非自定义clang二进制文件的东西),并实现源代码到源代码的修改(对用户透明,避免覆盖他们的源文件)。

编辑:如果不清楚:我需要一个类似"插件"的东西来以一种简单的方式扩展clang。我需要一些在编译过程中"集成"的东西。为什么?因为我需要在编译阶段修改源代码,注入新代码,一步修改用户的源代码(我不想创建一个工具来解析用户源代码,然后编译输出文件)。此外,我想分发我的代码(插件),让用户自己使用它。

它是强制性的,在clang(clang $FLAGS $PLUGIN $ETC -o program source_files...)的编译阶段。

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

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

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

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

您可以"在内存中"执行所有步骤,这样最终用户就不会注意到。

更新:我自己从来没有写过clang插件。但我注意到:如果您运行Clang-fronted来实际生成目标代码:

clang -cc1 -emit-obj main.c

它将运行EmitObjAction。EmitObjAction是一个前端操作,因此它将解析输入源并运行codegen。因此,如果并行运行其他前端操作,它们将不会对EmitObjAction产生影响。因为每个前端操作都解析原始输入源代码。

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

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