使用clang API处理C ++函数以插入代码 [英] Handle C++ functions with clang API to insert code
问题描述
我需要预处理一些 C ++ 文件,以自动插入代码进行测试和分析,我需要使用 clang API 。
现在,我想要能够执行以下操作:
如果有一个函数:
int SomeFn(int a,int b,int c){
doStuff();
}
我想对其进行预处理,看起来像这样:
int SomeFn(int a,int b,int c){
cout< SomeFn使用以下参数调用:a =<< a<< ,b =< b<< ,c =< c<< endl;
doStuff();
}
我试图扩展 ASTConsumer
并使用 HandleTopLevelDecl
和 HandleTopLevelSingleDecl
方法并检查传递的 Decls
都是 FunctionDecls
并将它们向下转,所以我可以得到他们的名字和body-locations。
但我不能处理类方法,只有全局函数。
我在 ASTConsumer
class
HandleTagDeclDefinition(TagDecl * D)
。文档说:
这个回调在每次
时调用TagDecl(例如struct,union,enum,
类)。
但是看起来这个方法甚至在我测试的时候没有被调用。
所以我的问题是,什么是正确的方式来完成这项任务?在clang API中如何表示C ++类?也许有人知道,在哪里可以找到例子,因为clang API没有记录。
UPDATE:
我知道还有 Visitors
的概念,还有一个方法 VisitRecordDecl(RecordDecl * D) / code>。该文档说,
RecordDecl
表示类。所以我扩展了 RecursiveASTVisitor
并实现了 VisitRecordDecl(RecordDecl * D)
,但似乎这个方法没有被调用。
而是调用VisitVarDecl
,当类定义为find时,就好像它被看作一个变量声明。
所以我有点困惑。我希望有人可以帮助...
$ b
UPDATE2:
我试图解析另一个文件,这次clang发现一个 RecordDecl
。但是该文件定义了一个结构体和两个类,所以我认为我的clang代码解析 C而不是C ++ 。是否有任何设置在C和C ++之间切换?
是否有任何设置可以在C和C ++之间切换?
最后,我找到了如何处理这个问题:
从
ASTConsumer
和 RecursiveASTVisitor
扩展以遍历AST并实现 VisitCXXRecordDecl(CXXRecordDecl * D)
。然后我必须为预处理器设置 LangOptions
参数,所以它会解析C ++。 langOpts.CPlusPlus = 1;
我的错误是认为它会立即解析C ++,但是不是这样将C解析为默认值,因此无法识别类。
I need to preprocess some C++ files to automatically insert code for testing and profiling, and I need to do it with the clang API.
For now, I want to be able to do the following: If there is a function:
int SomeFn(int a, int b, int c) {
doStuff();
}
I want to preprocess it, that it looks like this:
int SomeFn(int a, int b, int c) {
cout << "SomeFn is invoked with the following arguments: a=" << a << ", b=" << b << ", c=" << c << endl;
doStuff();
}
I've tried to extend ASTConsumer
and use the methods HandleTopLevelDecl
and HandleTopLevelSingleDecl
and check if the passed Decls
are FunctionDecls
and downcast them, so I can get their names and body-locations.
But I can't handle class-methods that way, only global functions.
I found a function in the ASTConsumer
class HandleTagDeclDefinition(TagDecl* D)
. The documentation says:
This callback is invoked each time a TagDecl (e.g. struct, union, enum, class) is completed.
But it looks like this method isn't even invoked, when I test it.
So my question is, what would be the right way to do this task? And how are C++ classes are represented in the clang API? Maybe someone knows, where I can find examples because the clang API is poorly documented.
UPDATE:
I know there is also the concept of Visitors
and there is a method VisitRecordDecl(RecordDecl *D)
. The documentation says that RecordDecl
represents classes. So I extended RecursiveASTVisitor
and implemented VisitRecordDecl(RecordDecl *D)
but it seems, that this method isn't invoked neither.
Instead VisitVarDecl
is invoked, when a class definition is find, as if it is seen as a variable declaration.
So I'm a bit confused. I hope, someone can help...
UPDATE2:
I tried to parse another file and this time clang found one RecordDecl
. But the file defined one struct and two classes, so I think my clang code parses C instead of C++. Are there any settings to switch between C and C++ ?
Are there any settings to switch between C and C++ ?
Finally I found out how to handle this:
I extended from ASTConsumer
and RecursiveASTVisitor<MyConsumer>
to traverse the AST and implemented VisitCXXRecordDecl(CXXRecordDecl* D)
. Then I had to set the LangOptions
parameter for the preprocessor, so it parses C++.
langOpts.CPlusPlus = 1;
My fault was to think that it would parse C++ right away, but that was not the case, it parses C as default and so doesn't recognize classes.
这篇关于使用clang API处理C ++函数以插入代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!