我需要预处理一些C++文件以自动插入用于测试和分析的代码,我需要使用clang API来完成.
现在,我希望能够执行以下操作:如果有功能:
int SomeFn(int a, int b, int c) {
doStuff();
}
Run Code Online (Sandbox Code Playgroud)
我想预处理它,它看起来像这样:
int SomeFn(int a, int b, int c) {
cout << "SomeFn is invoked with the following arguments: a=" << a << ", b=" << b << ", c=" << c << endl;
doStuff();
}
Run Code Online (Sandbox Code Playgroud)
我试图扩展ASTConsumer和使用这些方法HandleTopLevelDecl,HandleTopLevelSingleDecl并检查传递的Decls是否是FunctionDecls向下传播它们,所以我可以得到它们的名字和身体位置.但是我不能这样处理类方法,只能处理全局函数.
我在ASTConsumer课堂上找到了一个功能HandleTagDeclDefinition(TagDecl* D).文件说:
每次完成TagDecl(例如struct,union,enum,class)时,都会调用此回调.
但是当我测试它时,看起来甚至没有调用这个方法.
所以我的问题是,做这项任务的正确方法是什么?如何在clang API中表示C++类?也许有人知道,我可以在哪里找到例子,因为clang API记录很差.
更新:
我知道还有一个概念,Visitors并且有一种方法VisitRecordDecl(RecordDecl *D).文档说RecordDecl代表类.所以我扩展RecursiveASTVisitor并实现VisitRecordDecl(RecordDecl *D)但看起来,这个方法也没有被调用.而是VisitVarDecl在找到类定义时调用,就好像它被视为变量声明一样.所以我有点困惑.我希望有人能帮帮忙...
UPDATE2:
我试图解析另一个文件,这次clang发现了一个RecordDecl.但是文件定义了一个结构和两个类,所以我认为我的clang代码解析C而不是C++.是否有任何设置可以在C和C++之间切换?
Bar*_*kar 10
是否有任何设置可以在C和C++之间切换?
最后我发现了如何处理这个问题:
我延伸ASTConsumer并RecursiveASTVisitor<MyConsumer>遍历AST并实施VisitCXXRecordDecl(CXXRecordDecl* D).然后我必须LangOptions为预处理器设置参数,因此它解析C++.
langOpts.CPlusPlus = 1;
Run Code Online (Sandbox Code Playgroud)
我的错是认为它会立即解析C++,但事实并非如此,它将C解析为默认值,因此无法识别类.