clang 插件:在编译过程中修改 AST
clang plugin: modify AST during compilation
我正在开发一个用于外部化日志字符串的 clang 插件(为了减少嵌入式项目的二进制大小(,它需要修改 AST(所以在预处理器之后,在编译之前(。
目前,我能够成功地匹配要替换的节点(使用RecursiveASTVisitor<T>
(,并正确提取构建替换所需的数据。
在访问者的VisitStmt
方法中,我正在迭代子节点,当找到匹配项时,我尝试通过迭代器分配将匹配的表达式节点(CallExpr
,返回int(替换为新节点(IntegerLiteral
(:
*it = clang::IntegerLiteral::Create(context, { 32, value, false }, context.IntTy, old->getLocStart()).
但是,当我尝试使用我的插件编译示例程序时,clang 返回成功状态代码,但没有生成任何对象文件:
$ clang -std=c11 -Xclang -load -Xclang /tmp/plugin.so -Xclang -plugin -Xclang string-externalise -Xclang -plugin-arg-string-externalise -Xclang -lut-file=lut.txt -c -o example.o example.c
$ echo $?
0
$ stat example.o
stat: cannot stat 'example.o': No such file or directory
如果我尝试转储 AST 以验证我是否正确修改了它,那么 clang 也不会提供任何输出。 但是,如果我禁用我的插件(删除与它相关的所有参数(,那么我可以转储(原始的、未修改的(AST。
我尝试进行的特定 AST 修改是用整数文字(由插件确定的值(替换对占位符函数(返回 int(的调用。
例如,将此CallExpr
子树替换为IntegerLiteral
:
| |-CallExpr 0x556d460b3ab8 <line:7:42, col:78> 'int'
| | |-ImplicitCastExpr 0x556d460b3aa0 <col:42> 'int (*)(const char *, int)' <FunctionToPointerDecay>
| | | `-DeclRefExpr 0x556d460b3a20 <col:42> 'int (const char *, int)' Function 0x556d460b22d8 '__externalise_location' 'int (const char *, int)'
| | |-ImplicitCastExpr 0x556d460b3b08 <<scratch space>:26:1> 'const char *' <BitCast>
| | | `-ImplicitCastExpr 0x556d460b3af0 <col:1> 'char *' <ArrayToPointerDecay>
| | | `-StringLiteral 0x556d460b3a48 <col:1> 'char [10]' lvalue "example.c"
| | `-IntegerLiteral 0x556d460b3a80 <line:27:1> 'int' 22
或者用IntegerLiteral
替换这个CallExpr
子树:
| |-CallExpr 0x556d460b3b98 <example.c:6:26, col:46> 'int'
| | |-ImplicitCastExpr 0x556d460b3b80 <col:26> 'int (*)(const char *)' <FunctionToPointerDecay>
| | | `-DeclRefExpr 0x556d460b3b20 <col:26> 'int (const char *)' Function 0x556d460b20c0 '__externalise' 'int (const char *)'
| | `-ImplicitCastExpr 0x556d460b3be0 <line:22:6> 'const char *' <BitCast>
| | `-ImplicitCastExpr 0x556d460b3bc8 <col:6> 'char *' <ArrayToPointerDecay>
| | `-StringLiteral 0x556d460b3b48 <col:6> 'char [10]' lvalue "hello %sn"
虽然已经很多年了,我再也无法访问原始代码库了,但我最近正在为其他人研究这个问题。
根据我记得的,加上Clang文档,以及我多年前投票支持的另一个SO答案,解决方案基本上是:
- 使用
-add-plugin
代替-plugin
(2018 年的原始解决方案(,或 - 以公开
getActionType
,如链接的 Clang 文档中所述。
相关文章:
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 是否删除在对象构造过程中创建的对象
- 如何在鼠标挂钩过程中检测拖动
- clang 插件:在编译过程中修改 AST
- 在 RAII 构造中修改 RVO 值是否安全?
- 在 C++ 中修改 Grpc 双向流式处理期间的元数据
- 当使用我在一个函数、另一个函数中修改的数组时,在我的输出中得到一个奇怪的负数
- Adafruit 羽毛RFM69HCW在使用过程中会冻结,需要硬重置
- 线程过程中的线程同步问题
- MySQL 连接器/C++.尝试在此过程中停止连接到数据库
- C++ 在编译过程中 strtok 函数 Eclipse 说没有在范围内声明?
- 在调用过程中删除 std::函数
- 动态矩阵特征分解过程中的误差
- cmake在构建过程中使用另一个工具检测标志
- 在模板参数推导过程中丢失限定符
- 升压过程中的管道缓冲区大小
- 如何在插入过程中更改插入的值
- 使用process_vm_readv从另一个过程中修改整数值
- 通过构造过程中获得的指针修改const对象
- 通过引用,源在操作过程中被修改