使用clang API处理C ++函数以插入代码 [英] Handle C++ functions with clang API to insert code

查看:687
本文介绍了使用clang API处理C ++函数以插入代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要预处理一些 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆