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++ ?