ASTMatchers: isVirtual and isOverride

Hi,

Neither :slight_smile: Just create an object in main(), and hand a pointer to that object to your callback - then call stuff on it from the match callback.

Ok, ok, that was the problem.

1. I create a MatchFinder.
> 2. Then, I add two different matchers to the same callback.
> 3. I call run.
>
> My questions are:
> 1. How many times is called the run method? Every time the MatchFinder finds a node to match?

Yes, each time either matcher accepts a node.

2. The object callback I add to MatchFinder is created more than once? When it is deleted?

You (the user) are the one responsible for creating and destroying the callback object. Usually what we do is allocate it on the stack (and pass it the appropriate arguments, of course), and then pass its address to MatchFinder. MatchFinder doesn’t create, copy or delete your callback object, so it is safe to store state in the callback.

Could you explain better “if the second matcher has no deps on the information collected by matcher1”?

deps = dependencies

Gabor

Thanks for your answers Gabor.

I have decided to follow up the advice of Manuel and I have created a MatchFinder object with all the matchers and a single MatchCallback object. So now, I’m in my run() method and I want to know which matcher was bound. So I think the only way to know this is to ask:
if (Result.Nodes.getNodeAsclang::CXXConstructorDecl(“matcher1”)){

}
else if(Result.Nodes.getNodeAsclang::CXXRecordDecl(“matcher2”)){

}
Notice that I’m retrieving different classes of nodes (clang::CXXConstructorDecl, clang::CXXRecordDecl…) In spite of this fact, I want to process all the nodes in the same way except from a subtle difference and I was asking myself if there is a better way I can do something like this:
if (Result.Nodes.getNodeAsclang::CXXConstructorDecl(“matcher1”)){

process(Result.Nodes.getNodeAsclang::CXXConstructorDecl(“matcher1”))
}
else if(Result.Nodes.getNodeAsclang::CXXRecordDecl(“matcher2”)){

process(Result.Nodes.getNodeAsclang::CXXRecordDecl(“matcher2”))
}

template
void process(const T* Node){

}

Regards,

Pedro

Hi,

1. I create a MatchFinder.
> 2. Then, I add two different matchers to the same callback.
> 3. I call run.
>
> My questions are:
> 1. How many times is called the run method? Every time the MatchFinder finds a node to match?

Yes, each time either matcher accepts a node.

2. The object callback I add to MatchFinder is created more than once? When it is deleted?

You (the user) are the one responsible for creating and destroying the callback object. Usually what we do is allocate it on the stack (and pass it the appropriate arguments, of course), and then pass its address to MatchFinder. MatchFinder doesn’t create, copy or delete your callback object, so it is safe to store state in the callback.

Could you explain better “if the second matcher has no deps on the information collected by matcher1”?

deps = dependencies

Gabor

2013/5/8 Pedro Delgado Perez <pedro.delgadoperez@mail.uca.es>
Hi,
Thanks for all your support. I’m going to respond all your contributions little by little:

You can execute Matcher1 first, and when it returns, you start executing Matcher2. I’m not sure what your problem is exactly. (Of course, this will also mean that you will traverse the whole AST twice, which can potentially be very expensive.)

Ok. What I don’t understand quite well is the order in the execution.

  1. I create a MatchFinder.
  2. Then, I add two different matchers to the same callback.
  3. I call run.
    My questions are:
  4. How many times is called the run method? Every time the MatchFinder finds a node to match?
  5. The object callback I add to MatchFinder is created more than once? When it is deleted? The problem is that I create the object callback with an argument (a constructor method with an argument, not the default constructor) and store it in a variable member. However, when the run method executes, the value of the variable member is lost and I can’t understand the problem.

Sorry, missed the comment in one of your more recent emails. So you basically want all matches by matcher1 to be found before all matchers by matcher2. I think the easiest way to do this is just have two MatchFinder classes. Add matcher1 and its callback to the first MatchFinder and call run(). Add matcher2 and its callback to the second MatchFinder and call run() after the first run() returns. You won’t have to reparse the file but you will have to traverse the AST twice. There’s not much you can do about this given the order you want. However, if the second matcher has no deps on the information collected by matcher1 you could just get away with a single MatchFinder and two callbacks that just store their finds in two vectors which you process after run returns

I’m not sure what order you’re interested in but you can create two match callbacks one to use for each matcher. The callbacks will be called in the order the nodes are found in the tree by doing a depth-first pre-order traversal as is usual for RecursiveASTVisitor. If both matchers match a given node, the callbacks are called in the order they are registered.

What sort of order are you looking for?

I understand what you have explained until you say “two callbacks”. Why could I want to have two different callbacks? Could you explain better “if the second matcher has no deps on the information collected by matcher1”?

What is often faster is to produce a superset of the information needed during the traversal / match phase, and then combine / filter the results after everything’s done…

That is a good solution, I suppose. I will have to study my case more in detail to determine whether this fit my problem or not. But, do you store all that information in global variables or in the callback object?

.

You can just count how many times your match callback is called and then print that number after run() returns.

Again, my problem is that I don’t $when the match callback is called.
I hope I can end up getting the usage of all this with your help.
Pedro.

El dia 08 may 2013 12:10, Gábor Kozár <kozargabor@gmail.com> escribió:

Hi,

Ok, this also helps, but the problem is that I need to print something when all the nodes have been matched. So, is there a way I can check within onStartOfTranslationUnit() method if we have reached the end? I have just found this:

onStartOfTranslationUnit() is - obviously - called at the start of each TU. I.e. this will be called after the previous TU has been completed, i.e. all nodes in it have been matched.

clang::ast_matchers::MatchFinder::ParsingDoneTestCallback

This is for testing purposes only, it’s not recommended to use it.

So, what you are saying is that I can’t control the order the nodes are matched?

No, you can’t. You’ll have to implement a RecursiveASTVisitor manually if you need this fine control.

What I’m trying to explain is that I need all the nodes bound with Matcher1 are treated before the execution of nodes bound with Matcher2 starts.

You can execute Matcher1 first, and when it returns, you start executing Matcher2. I’m not sure what your problem is exactly. (Of course, this will also mean that you will traverse the whole AST twice, which can potentially be very expensive.)

Gabor

2013/5/8 Pedro Delgado Perez <pedro.delgadoperez@mail.uca.es>