Hi,
This is indeed something I haven’t considered, but should be easy to fix. Looking at the documentation for CXXCtorInitializer, you’ll see that there’s a member called isBaseInitializer(). The other thing you’ll need to check (probably, if that is what you need) for is whether the base ctor call is implicit, which is probably done best by constraining the CXXConstructExpr with argumentCountIs(0). Putting together a custom matcher using these should be simple.
I found isWritten() member for CXXCtorInitializer:
“Returns true if this initializer is explicitly written in the source code.”
And finally, I accomplished what I wanted. Now, only B constructor is matched in:
class A{
public: A(){}
};
class B: public A{
public: int b, h;
B():A(){b=0; h=0;}
};
class C: public A{
public C(){}
};
But thanks for the members you have indicated: i’m sure I’ll have to use them in the future.
Also keep in mind that if you put together a generic and useful enough matcher, you should totally contribute it as a patch, so that others in need of a similar thing have it available in the future.
Ok. But I don’t know where I should put or send these matchers to share them. Could you indicate me?
Yes, you need to use these in the matcher callback. It is indeed inefficient, but we’ve been unable to come up with any better solution. The problem is in the underlying compiler technology, i.e. the nature of header files.
Is it possible to search for nodes only in some files indicated by the user?
Sure, take a look at the clang::ast_matchers::match functions - they allow you to run a matcher on the specified node, not the whole AST. Unfortunately I do not think this will help you in this case, as you cannot distinguish the parts of the TU coming from system header files and the parts coming from user files at the AST level.
Ok, that’s a setback i should have in mind. When you say “they allow you to run a matcher on the specified node, not the whole AST.” you mean something like this?:
Result.Nodes.getNodeAs<clang::ForStmt>("forLoop"))
This is the way I retrieve the nodes I need to match at this moment.
The problem for me is that I’ll have to make some source-to-source translations: sometimes I’ll have to modify the .cpp file and sometimes the .h (or even both of them) For instance, if i want to know if a certain method is declared as “virtual”, I would need to examinate the .h file. Thus, I cannot exclude all .h files. So, how can I manage this?
> I have seen that every file has “id” and, for instance, instead of using “isInSystemHeader” and “isInExternCSystemHeader” could i do the next?:
I’m not sure I understand what you’re trying to do here… As the error you’re getting, it’s because getSourceManager is missing the paranthesis, i.e. the () that would indicate it’s a method call.
What I was trying to do is to examinate the nodes only from the file provided by the user in the execution (for instance, if I run bin/default-constructor test.cpp, I only want the nodes from test.cpp) I tought that with member getMainFileID() I would achieve what I wanted, but this isn’t working as expected (sorry for the error of getSourceManager(), but I tested it really quick and late only to write the message). I have also tried with:
if (!Context->getSourceManager().isInSystemHeader(FullLocation) && ! Context->getSourceManager().isInExternCSystemHeader(FullLocation)){
…
}
but it is still matching nodes in other files, such as ostream, bits/basic_ios.h or bits/streambuf_interator.h because I included the iostream header. I need to avoid all these nodes, but I don’t know how to do it.
Yes, that’s quite possible, as I’m using clang 3.2. Nonetheless, you should be able to figure out what the issue is, as I’ve given you a draft (a pattern, if you will).
Ok. I’m going to check this like you taugth me
And a last question if you don’t mind. I based my examples for the moment in the matcher shown in:
http://clang.llvm.org/docs/LibASTMatchersTutorial.html
But you told me that it’s possible to merge the usage of Matchers and RecursiveASTVisitor as in:
http://clang.llvm.org/docs/RAVFrontendAction.html
I see that I can retrieve some nodes using matchers and then use a RecursiveASTVisitor on that nodes, but I can’t clearly see the contrary: if I’m visiting only a kind of node, I know that I can directly use the methods of that class, but how could I use a matcher in the same way as in the example below?:
virtual void run(const MatchFinder::MatchResult &Result) { if (const ForStmt *FS = Result.Nodes.getNodeAs<clang::ForStmt>("forLoop")) FS->dump(); }
I hope you can understand what I mean.
Thank you for all your help,
Pedro
El dia 21 abr 2013 01:43, Gábor Kozár kozargabor@gmail.com escribió: