[cfe-dev] ASTMatchers: isVirtual and isOverride

Gábor Kozár kozargabor at gmail.com
Fri Apr 19 04:17:58 PDT 2013


Hi,

Indeed, there are matchers that are not currently implemented, although
their implementation would be fairly trivial. Check out the documentation
about writing AST matchers: http://clang.llvm.org/docs/LibASTMatchers.html

Sorry, you're correct, argumentCountIs wrong here, I meant
parameterCountIs(). By the way, the list of available matchers is listed
here: http://clang.llvm.org/docs/LibASTMatchersReference.html - try looking
through the list to find if what you need it available.

As for your further requirement that the constructor not be empty, I'm
fairly sure that there is no such matcher readily available for you to use,
but it shouldn't be too difficult to implement one, all the information you
need is in the documentation for CXXConstructorDecl:
http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html

I have put together quickly the matcher that I believe suits your needs,
just so that you can see how it works:

namespace clang {
namespace ast_matchers {

using namespace clang::ast_matchers::internal;

AST_MATCHER(CXXConstructorDecl, defaultNonTrivialCtor)
{
    return Node.isThisDeclarationADefinition()
        && Node.isDefaultConstructor()
        && (Node.getNumCtorInitializers() != 0 || !Node.hasTrivialBody());
}

} // ast_matchers
} // clang

(Don't forget to include ASTMatchers.h, ASTMatchersInternal.h and
ASTMatchersMacros.h)

Meanwhile I found that you can actually put this together using existing
matchers, which should be the preferred method:

constructorDecl(isDefinition(), parameterCountIs(0),
        anyOf(hasAnyConstructorInitializer(anything()),
has(compoundStmt(has(stmt())))));

(I did a quick test, and seems to work as intended, but you should make
sure to test it thoroughly yourself.)

The matcher you put together looks good, and those macros are there for you
to use when implementing matchers.
You can, of course, use AST visitors (RecursiveASTVisitor<Derived>) to find
the node that satisfies these conditions, but usually matchers are
preferred, as a higher-level and (usually) much less messy solution.
However, in some situations AST Visitors are preferred - this is your
choice to make, depending on your use case.

Don't worry about matcher performance: if you're using MatchFinder to run
your matchers, then it is guaranteed that all matchers will be executed in
just one traversal of the AST, i.e. two matchers won't need two traversals.

Hope this helps,

Gabor


2013/4/19 Pedro Delgado Perez <pedro.delgadoperez at mail.uca.es>

>  Hi again,
>
> Well, I've just understood that not all the methods in a class have a
> matcher related. For instance, I'm trying to match the default constructor
> declaration of a class:
>
> class Foo {
> public:
> *Foo(){}*
> Foo(int a){... ...}
> }
>
> And in CXXConstructorDecl we have isDefaultConstructor(), but I can't find
> an AST_MATCHER to do this. So, I suppose I would have to implement a new
> AST_MATCHER like this:
>
> *AST_MATCHER(CXXConstructorDecl, isDefaultConstructor){*
> *return Node.isDefaultConstructor();*
> *}*
>
> Wouldn't it? But, this happens often, so... would you recommend me use
> AST_MATCHERS? Or it would be better to do something like it is explained in
> http://clang.llvm.org/docs/RAVFrontendAction.html ? This way, I can
> directly use the methods in the classes. For instance:
>
>  bool VisitCXXConstructorDecl(CXXConstructorDecl *Declaration) {    if (Declaration->isDefaultConstructor()) {
>
> I have to visit a lot of kind of nodes with different features, not only
> this.
>
> Please, I need a path to get down to work.
>
> Thanks in advance,
>
> Pedro.
>
> *El dia 19 abr 2013 01:58, Gábor Kozár <kozargabor at gmail.com> escribió:*
>
> Hi,
>
> What version are you using? The matchers isOverride() and isVirtual() I
> know for certain were not in version 3.2, and can only be found on SVN (in
> this file:
> http://llvm.org/svn/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
> ).
>
> Nonetheless, you can implement them all very easily manually, or just
> indeed copy their implementation from the link above. Also, instead of
> isDefaultConstructor(), you could use argumentCountIs(0).
>
> Gabor
>
>
> 2013/4/18 Pedro Delgado Perez <pedro.delgadoperez at mail.uca.es>
>
>> Hi,
>>
>> I'm newbie using ASTMatchers and I'm trying to learn little by little how
>> to use them.
>>
>> I was basing on the matcher recordDecl(hasName("Foo"), isDerivedFrom("Bar"))
>> shown in http://clang.llvm.org/docs/LibASTMatchers.html trying to
>> include new features. For instance, I tried to look for classes which have
>> at least one virtual method:
>>
>> recordDecl(hasName("Foo"), isDerivedFrom("Bar"), hasMethod(isVirtual()))
>>
>> Or I tried to match protected overriden methods:
>>
>> methodDecl(allOf(isProtected(), isOverride());
>>
>> But neither of them worked as it couldn't find "isOverride" and
>> "isVirtual" identifiers. I was trying a lot of combinations, but I can't
>> understand this well.
>>
>> Finally, I tried to look for the the default constructor of a certain
>> class:
>>
>> constructorDecl(hasName("Foo"), isDefaultConstructor())
>>
>> but this is wrong. What I'm doing bad? Please, any information you give
>> me will be fine to me to understand how to use matchers.
>>
>> Thanks in advance,
>>
>> Pedro.
>>
>>
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at cs.uiuc.edu
>>
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130419/080b4367/attachment.html>


More information about the cfe-dev mailing list