最近找到国外一大神做的利用LLVM和Clang写的修改源代码的例子,恰好项目需要做一个source-to-source的编译器与此相关,所以部分翻译一下这位大神的文章。
在几年前Eli-Bendersky在博客上写过一篇关于如何利用Clang制作source-to-source编译器的文章(文章链接) ,在那篇旧的博文里他写了一小段如何利用Clang改写C++源码的完整代码,据说那篇文章非常火,但LLVM在这几年已经取得了很大的进步,所以Eli-Bendersky利用最新的LLVM与Clang重写了那些代码。
实例代码的效果如下:
输入源文件:
void foo(int* a, int *b) {
if (a[0] > 1) {
b[0] = 2;
}
}
输出源文件:
// Begin function foo returning void
void foo(int* a, int *b) {
if (a[0] > 1) // the 'if' part
{
b[0] = 2;
}
}
// End function foo
将这个例子的代码作为蓝本进行改造,就可以很快地做出属于自己的source-to-source编译器。
先说说代码的思路:
1.ASTConsumer负责读取Clang解析出来的AST树
2.在ASTConsumer中重写HandleTopLevelDecl函数用以检测源码中的函数声明语句(见上面效果代码)
3. RecursiveASTVisitor类负责实际对源码的改写
4. 在RecursiveASTVisitor中重写VisitStmt函数与VisitFunctionDecl函数实现源码中目标语素的检测以及改写动作
5. 改写好的源码送入Rewriter类中,进行写入源代码文件的动作
代码:
//------------------------------------------------------------------------------
// Tooling sample. Demonstrates:
//
// * How to write a simple source tool using libTooling.
// * How to use RecursiveASTVisitor to find interesting AST nodes.
// * How to use the Rewriter API to rewrite the source code.
//
// Eli Bendersky (eliben@gmail.com)
// This code is in the public domain
//-----------------