ASTMatchers: isVirtual and isOverride

Hi,

Thank you for all your explanations, now everything is much clearer. But, please, let me ask you another last question regarding:

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?

Well, you exclude just the system header files in the match callback, as I’ve showed before, using SourceManager :: isInSystemHeader and isInExternCSystemHeader.

Ok, I see that i can exclude all the system headers, but imagine the next cpp:

#include “A.h”
#include “B.h”

… …
}

int A::m() {
B b; //B.h header has been included because it’s needed in a member function of A
… …
}

… …

And I only want to retrieve nodes inside class A (in A.h and A.cpp), but not inside B.h because I’m not interested in this class. How can I avoid this?

In addition, in the matcher we’ve working on, we looked for default constructors declarations defined inline. But several options more were possible:

  1. I have both declaration and definition inline in A.h
  2. I have both declaration and definition inline in A.cpp
  3. I have declaration in A.h and definition in A.cpp (the example above)
  4. I have declaration and definition (but not inline) in A.cpp

We have considered 1 and 2, but not 3 nor 4. Imagine that we have the case 3 and I want to delete the constructor both in A.h(declaration) and A.cpp(definition). Do I have to prepare two different matchers to look for them? Or is there a way that, for example, I find the definition and then I can refer its declaration? Of course, I need to make sure that both, definition and declaration are deleted.

I hope you know what I mean.

Thanks for everything Gábor,

Pedro.

El dia 22 abr 2013 21:52, Gábor Kozár kozargabor@gmail.com escribió:

Hi,

Thank you for all your explanations, now everything is much clearer. But,
please, let me ask you another last question regarding:

*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?*
*
*
Well, you exclude just the system header files in the match callback, as
I've showed before, using SourceManager :: isInSystemHeader and
isInExternCSystemHeader.

Ok, I see that i can exclude all the system headers, but imagine the next
cpp:

#include "A.h"
#include "B.h"

A::A() {
... ...
}

int A::m() {
B b; //B.h header has been included because it's needed in a member
function of A
... ...
}

... ...

And I only want to retrieve nodes inside class A (in A.h and A.cpp), but
not inside B.h because I'm not interested in this class. How can I avoid
this?

What I usually do is: in the callback, take the source location of the
node, look at the file name, and do a regexp on the file to determine
whether you want to examine the node or not.

In addition, in the matcher we've working on, we looked for default
constructors declarations defined inline. But several options more were
possible:
1. I have both declaration and definition inline in A.h
2. I have both declaration and definition inline in A.cpp
3. I have declaration in A.h and definition in A.cpp (the example above)
4. I have declaration and definition (but not inline) in A.cpp

We have considered 1 and 2, but not 3 nor 4. Imagine that we have the case
3 and I want to delete the constructor both in A.h(declaration) and
A.cpp(definition). Do I have to prepare two different matchers to look for
them? Or is there a way that, for example, I find the definition and then I
can refer its declaration? Of course, I need to make sure that both,
definition and declaration are deleted.

I'd say you'd want to delete all declarations of A::A() (and as such, look
for all constructor declarations), and then use
isThisDeclarationADefinition() to figure out whether there's a body to
delete, too...

Cheers,
/Manuel

Hi,

And I only want to retrieve nodes inside class A (in A.h and A.cpp), but not inside B.h because I’m not interested in this class. How can I avoid this?

This is something you can’t express with matchers, as you can only run them on AST nodes, and there is no AST node to represent header files (there is only TranslationUnitDecl, but that represents a whole translation unit, i.e. a cpp file with all included files).

What you can do, as Manuel suggested, is to perform the check in the callback. The SourceManager classs has various methods that are available for you to figure out where exactly a given SourceLocation is, and we’ve already mentioned several of them. I suggest you read through the documentation to find out what’s the best way to do what you’re trying to do.

We have considered 1 and 2, but not 3 nor 4. Imagine that we have the case 3 and I want to delete the constructor both in A.h(declaration) and A.cpp(definition). Do I have to prepare two different matchers to look for them? Or is there a way that, for example, I find the definition and then I can refer its declaration? Of course, I need to make sure that both, definition and declaration are deleted.

The functionDecl() matcher in itself will match any FunctionDecl nodes, regardless of whether it is a definition or only a declaration. In addition, there is a method called FunctionDecl :: isDefinition, which also gives you the FunctionDecl object that represents the definition belonging to the current declaration.
Now I think the simplest solution would be to create a matcher for this, that would allow you to express constraints on the actual definition of the function, and then you’d be able to modify your existing matcher expression to accommodate for this.

Gabor