我正在开发一个用于外部化日志字符串的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也不会给出任何输出。但是如果我禁用我的插件(删除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 %s\n"
1条答案
按热度按时间xxhby3vn1#
虽然已经很多年了,我再也不能访问原始代码库了,但我最近正在为其他人研究这个问题。
根据我所记得的,加上我几年前投票支持的Clang docs和another SO answer,解决方案基本上是:
-add-plugin
代替-plugin
(2018年的原始解决方案),或getActionType
,如链接的Clang文档中所述。