<div dir="ltr"><div>Hi,<br></div><div><br></div><div>> <em>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?</em></div>

<div><em><br></em></div><div>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).<em><br>

</em></div><div>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.</div>

<div><br></div><div>> <em>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.</em></div>

<div><em><br></em></div><div>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.</div>

<div>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.</div>

<div><br></div><div>Gabor</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/4/24 Pedro Delgado Perez <span dir="ltr"><<a href="mailto:pedro.delgadoperez@mail.uca.es" target="_blank">pedro.delgadoperez@mail.uca.es</a>></span><br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div>
<p>Hi, </p>
<p>Thank you for all your explanations, now everything is much clearer. But, please, let me ask you another last question regarding:</p><div class="im">
<blockquote style="border-left:2px solid #000083;margin:0pt 0pt 0pt 0.8ex;padding-left:1ex"><br>
<div style="font-size:12.727272033691406px"><em>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?</em></div>

<div style="font-size:12.727272033691406px"><em><br></em></div><div style="font-size:12.727272033691406px">Well, you exclude just the system header files in the match callback, as I've showed before, using SourceManager :: isInSystemHeader and isInExternCSystemHeader.</div>

</blockquote></div><p>Ok, I see that i can exclude all the system headers, but imagine the next cpp:</p>
<p>#include "A.h"<br>
#include "B.h"</p>
<p>A::A() {<br>
... ...<br>
}</p>
<p>int A::m() {<br>
B b;  //B.h header has been included because it's needed in a member function of A<br>
... ...<br>
}</p>
<p>... ...</p>
<p>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?</p>
<p>In addition, in the matcher we've working on, we looked for default constructors declarations defined inline. But several options more were possible:<br>
1. I have both declaration and definition inline in A.h<br>
2. I have both declaration and definition inline in A.cpp<br>
3. I have declaration in A.h and definition in A.cpp (the example above)<br>
4. I have declaration and definition (but not inline) in A.cpp</p>
<p>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.</p>


<p>I hope you know what I mean. </p>
<p>Thanks for everything Gábor, </p>
<p>Pedro.</p>
<br>
<br>
<br>
<br>
<div><em>El dia 22 abr 2013 21:52, Gábor Kozár <<a href="mailto:kozargabor@gmail.com" target="_blank">kozargabor@gmail.com</a>> escribió:</em></div><div><div class="h5"><blockquote style="border-left:2px solid #000083;margin:0pt 0pt 0pt 0.8ex;padding-left:1ex">

<div dir="ltr"><div>Hi,</div><div>> <em>I found isWritten() member for CXXCtorInitializer:</em></div><div>Nice find, I actually did not know about this.<em><br></em></div><div>> <em>Ok. But I don't know where I should put or send these matchers to share them. Could you indicate me?</em></div>

<div><em><br></em></div><div>In the source code, the place for these is ASTMatchers.h. When you have something that you would like to propose to be integrated into the clang repository, I think what you need to do is send an e-mail to this mailing list, with the diff attached (that shows what changes you made), and ask for it to reviewed. But you probably should look at the website and see if there's any guideline for this - or just ask it on the mailing list.<em><br>

 </em></div><div>> <em>When you say "they allow you to run a matcher on the specified node, not the whole AST." you mean something like this?:</em></div><div><em><br></em></div><div>The code snippet you sent shows how to retrieve a node that has been accepted and bound by a matcher.<em><br>

 </em></div><div>What I mean is that if you have a CXXRecordDecl* object for example (from whatever source), and you want to find some nodes in it that match a specific condition - for example, you want to check if another type is used anywhere within this specific C++ class - you can use clang::ast_matchers::match, because you only need the nodes that satisfy this condition inside the record declaration that you have, and not anywhere in the AST.</div>

<div>To be honest I'm not sure what causes the confusion here, I think this is fairly self-explanatory.</div><div>> <em>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?</em></div>

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

<div><em><br></em></div><div>You'll need to show me some more code than that. How does your match callback function look like? What is FullLocation?<em><br></em></div><div>> <em>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?:</em></div>

<div><em><br></em></div><div>Both RecursiveASTVisitor and the matchers serve the exact same purpose, and they work in exactly the same way (in fact, the matchers use RecursiveASTVisitor internally) - the only different is that matchers are higher-level concepts, allowing for a more intuitive definition of match conditions. It's like a regular expression for ASTs.</div>

<div><em><br></em></div><div>When you work with matchers, you need two things: a matcher expression, constructed from the matcher functions like functionDecl(), isDefinition(), has(), allOf(), etc. and a match callback, i.e. a function that will be called for every AST node the matcher accepts while it is traversing the AST (i.e. running). You can use the .bind() method of the matchers to bind nodes accepted by the specified matcher to a name, and later retrieve it in the callback using result.Nodes.getNodeAs<T>. For example: <em>functionDecl(has(compoundStmt().bind("c"))).bind("f")</em>. When this matcher expression accepts an AST node, and runs the callback, you can access the matched FunctionDecl and CompoundStmt nodes by <em>result.Nodes.getNodeAs<FunctionDecl>("f")</em> and <em>result.Nodes.getNodeAs<CompoundStmt>("c")</em>, respectively. What you with these afterwards is up to you - if you want, you can even run another matcher on them using clang::ast_matchers::match, as I've already explained above.<em><br>

 </em></div><div>In your example code, the matcher callback retrieves a bound node (a ForStmt) with the name of "forLoop", and then writes its AST to the console. For example you can use with this matcher expression: <em>forStmt(unless(has(compoundStmt())))</em>, which will cause the AST of all for loops whose body is just a single statement with the {} brackets to appear on the screen.</div>

<div>Gabor</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/4/21 Pedro Delgado Perez <span dir="ltr"><<a href="mailto:pedro.delgadoperez@mail.uca.es" target="_blank">pedro.delgadoperez@mail.uca.es</a>></span><br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><p>Hi,</p>
<div><blockquote style="border-left:2px solid #000083;margin:0pt 0pt 0pt 0.8ex;padding-left:1ex"><p>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.</p>


</blockquote></div><p>I found isWritten() member  for CXXCtorInitializer:<br>"<span style="font-family:Verdana,Geneva,Arial,Helvetica,sans-serif;font-size:14px">Returns true if this initializer is explicitly written in the source code."</span><br>

<span style="font-family:Verdana,Geneva,Arial,Helvetica,sans-serif;font-size:14px">And finally, I accomplished what I wanted. Now, only B constructor is matched in:</span></p>
<div><p>class A{<br>    public: A(){}<br>};<br><br>class B: public A{<br>    public: int b, h;<br>        B():A(){b=0; h=0;}<br>};<br><br>class C: public A{<br>    public C(){}<br>};</p>
</div><p>But thanks for the members you have indicated: i'm sure I'll have to use them in the future. </p>
<div><blockquote style="border-left:2px solid #000083;margin:0pt 0pt 0pt 0.8ex;padding-left:1ex"><br><div>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.</div>

</blockquote></div><p>Ok. But I don't know where I should put or send these matchers to share them. Could you indicate me?</p>
<div><blockquote style="border-left:2px solid #000083;margin:0pt 0pt 0pt 0.8ex;padding-left:1ex"><br><div>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.<em><br>

 </em></div><div>> <em>Is it possible to search for nodes only in some files indicated by the user?</em></div><div><em><br></em></div><div>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.</div>

</blockquote></div><p>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?:</p>
<pre style="overflow-x:auto;overflow-y:hidden;border:thin dotted #0c3762;margin:0px 0px 12px;padding:0.8em;background-color:#f0f0f0;color:#333333"><span>Result</span><span>.</span><span>Nodes</span><span>.</span><span>getNodeAs</span><span style="color:#666666"><</span><span>clang</span><span style="color:#666666">::</span><span>ForStmt</span><span style="color:#666666">></span><span>(</span><span style="color:#4070a0">"forLoop"</span><span>))</span></pre>

<p>This is the way I retrieve the nodes I need to match at this moment.</p>
<p>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? </p>


<div><blockquote style="border-left:2px solid #000083;margin:0pt 0pt 0pt 0.8ex;padding-left:1ex"><div><em>> I have seen that every file has "id" and, for instance, instead of using "isInSystemHeader" and "isInExternCSystemHeader" could i do the next?:<br>

 </em></div><div><em><br></em></div><div>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.</div>

</blockquote></div><p>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:<br>

 if (!Context->getSourceManager().isInSystemHeader(FullLocation) && ! Context->getSourceManager().isInExternCSystemHeader(FullLocation)){<br>... <br>}</p>
<p>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.</p>


<div><blockquote style="border-left:2px solid #000083;margin:0pt 0pt 0pt 0.8ex;padding-left:1ex"><div>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).</div>

</blockquote></div><p>Ok. I'm going to check this like you taugth me ;)</p>
<p>And a last question if you don't mind. I based my examples for the moment in the matcher shown in:<br><a href="http://clang.llvm.org/docs/LibASTMatchersTutorial.html" target="_blank">http://clang.llvm.org/docs/LibASTMatchersTutorial.html</a><br>

But you told me that it's possible to merge the usage of Matchers and RecursiveASTVisitor as in:<br><a href="http://clang.llvm.org/docs/RAVFrontendAction.html" target="_blank">http://clang.llvm.org/docs/RAVFrontendAction.html</a><br>

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?:</p>


<pre style="overflow-x:auto;overflow-y:hidden;border:thin dotted #0c3762;margin:0px 0px 12px;padding:0.8em;background-color:#f0f0f0;color:#333333"><span style="color:#007020;font-weight:bold">virtual</span> <span style="color:#902000">void</span> <span>run</span><span>(</span><span style="color:#007020;font-weight:bold">const</span> <span>MatchFinder</span><span style="color:#666666">::</span><span>MatchResult</span> <span style="color:#666666">&</span><span>Result</span><span>)</span> <span>{</span>    <span style="color:#007020;font-weight:bold">if</span> <span>(</span><span style="color:#007020;font-weight:bold">const</span> <span>ForStmt</span> <span style="color:#666666">*</span><span>FS</span> <span style="color:#666666">=</span> <span>Result</span><span>.</span><span>Nodes</span><span>.</span><span>getNodeAs</span><span style="color:#666666"><</span><span>clang</span><span style="color:#666666">::</span><span>ForStmt</span><span style="color:#666666">></span><span>(</span><span style="color:#4070a0">"forLoop"</span><span>))</span>      <span>FS</span><span style="color:#666666">-></span><span>dump</span><span>();</span>  <span>}</span></pre>

<p>I hope you can understand what I mean.</p>
<p>Thank you for all your help,</p>
<p>Pedro</p>
<br>
<div><em>El dia 21 abr 2013 01:43, Gábor Kozár <<a href="mailto:kozargabor@gmail.com" target="_blank">kozargabor@gmail.com</a>> escribió:</em></div><div><div><blockquote style="border-left:2px solid #000083;margin:0pt 0pt 0pt 0.8ex;padding-left:1ex">

<div dir="ltr"><div>Hi,</div><div>> <em>The default constructor of C is also matched as there is an implicit call to the default constructor of class A (and effectively, this is an expression and not a declaration as I said in the last message). So, I've been thinking about it and, though I don't have the solution, I'm quite sure we have to change "anything()" inside "hasAnyConstructorInitializer()" to avoid this exception. Any suggestion?</em></div>

<div><em><br></em></div><div>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.<em><br>

 </em></div><div>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.</div>

<div>> <em>On the other hand, I've been trying to use the methods you told me, but I have to use those methods after the matcher execution, haven't I? This is a bit inefficiently as the mathcer is looking up in some files that are not needed.</em></div>

<div><em><br></em></div><div>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.<em><br>

 </em></div><div>> <em>Is it possible to search for nodes only in some files indicated by the user?</em></div><div><em><br></em></div><div>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.</div>

<div><em><br></em></div><div><em>> I have seen that every file has "id" and, for instance, instead of using "isInSystemHeader" and "isInExternCSystemHeader" could i do the next?:<br></em></div>

<div><em><br></em></div><div>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.</div>

<div>> <em>Umm... What a strange thing... I will get over this one more time and see if I did something wrong.<br>Maybe something is missing or is different in AStMatchersInternal or ASTMatchersMacros.</em></div><div>
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).<em><br>
</em></div><div>Good luck!</div><div>Gabor</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/4/21 Pedro Delgado Perez <span dir="ltr"><<a href="mailto:pedro.delgadoperez@mail.uca.es" target="_blank">pedro.delgadoperez@mail.uca.es</a>></span><br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><p>Hi and thanks again,<br><br>I clearly expressed incorretly the problem. I'll try to explain it more in detail:<br>

 <br>If we have the classes below:<br><br>class A{<br>    public: A(){}<br>};<br><br>class B: public A{<br>     public: int b, h;<br>        B():A(){b=0; h=0;}<br>};<br><br>class C: public A{<br>    public C(){}<br>};<br>

<br>I want my matcher retrieves ONLY the default constructor declaration of B. However this is what happened with the matcher you proposed me:<br> <br>CXXConstructorDecl 0xa1f6080 </home/pedro/clang-llvm/build/testClases.cpp:14:3, col:25> B 'void (void)'<br>

 |-CXXCtorInitializer 'class A'<br>| |-CXXConstructExpr 0xa1f6608 <col:8, col:10> 'class A' 'void (void)'<br> `-CompoundStmt 0xa1f6710 <col:11, col:25><br>  |-BinaryOperator 0xa1f6698 <col:12, col:16> 'int' lvalue '='<br>

   | |-MemberExpr 0xa1f6660 <col:12> 'int' lvalue ->b 0xa1f6100<br>   | | `-CXXThisExpr 0xa1f6650 <col:12> 'class B *' this<br>  | `-IntegerLiteral 0xa1f6680 <col:16> 'int' 0<br>

   `-BinaryOperator 0xa1f66f8 <col:19, col:23> 'int' lvalue '='<br>     |-MemberExpr 0xa1f66c0 <col:19> 'int' lvalue ->h 0xa1f6140<br>    | `-CXXThisExpr 0xa1f66b0 <col:19> 'class B *' this<br>

     `-IntegerLiteral 0xa1f66e0 <col:23> 'int' 0<br> Found declaration at 14:3<br>CXXConstructorDecl 0xa1f68b0 </home/pedro/clang-llvm/build/testClases.cpp:25:3, col:7> C 'void (void)'<br>|-CXXCtorInitializer 'class A'<br>

 | |-CXXConstructExpr 0xa1f6c08 <col:3> 'class A' 'void (void)'<br> `-CompoundStmt 0xa1f6c58 <col:6, col:7><br>Found declaration at 25:3<br><br>The default constructor of C is also matched as there is an implicit call to the default constructor of class A (and effectively, this is an expression and not a declaration as I said in the last message). So, I've been thinking about it and, though I don't have the solution, I'm quite sure we have to change "anything()" inside "hasAnyConstructorInitializer()" to avoid this exception. Any suggestion?<br>

 <br><br>On the other hand, I've been trying to use the methods you told me, but I have to use those methods after the matcher execution, haven't I? This is a bit inefficiently as the mathcer is looking up in some files that are not needed. Is it possible to search for nodes only in some files indicated by the user? Normally, a class is declared in a .h file and defined in the .cpp file and i would like to search in both of them.<br>

 I have seen that every file has "id" and, for instance, instead of using "isInSystemHeader" and "isInExternCSystemHeader" could i do the next?:<br><br>class DefaultConstructor : public MatchFinder::MatchCallback {<br>

 public :<br>  virtual void run(const MatchFinder::MatchResult &Result) {<br>  ASTContext *Context = Result.Context;<br>  FileID mainFileID = Context->getSourceManager.getMainFileID();<br>  if (const CXXConstructorDecl *FS = Result.Nodes.getNodeAs<clang::CXXConstructorDecl>("methods")){<br>

       FullSourceLoc FullLocation = Context->getFullLoc(FS->getLocStart());<br>      if (FullLocation.isValid() && FullLocation.getFileID() == mainFileID)<br>        ... ...<br>    }<br>  }<br>};<br><br>( I got an error with this: reference to non-static member function must be called<br>

   FileID mainFileID = (Context->getSourceManager).getMainFileID();<br>                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~ )</p>
<div><blockquote style="border-left:2px solid #000083;margin:0pt 0pt 0pt 0.8ex;padding-left:1ex"><p>> <em>Thank you for your time Gábor. I have put this, but I don't know why it doesn't fetch any nodes at all... Could you test this?<br>

 <br></em><br>I did test it, and worked fine for me. Not sure what could be the issue.</p>
</blockquote></div><p>Umm... What a strange thing... I will get over this one more time and see if I did something wrong.<br>Maybe something is missing or is different in AStMatchersInternal or ASTMatchersMacros.</p>
<p>Thanks,</p>
<p>Pedro.</p>
<br>
<div><em>El dia 19 abr 2013 16:28, Gábor Kozár <<a href="mailto:kozargabor@gmail.com" target="_blank">kozargabor@gmail.com</a>> escribió:</em></div><div><div><blockquote style="border-left:2px solid #000083;margin:0pt 0pt 0pt 0.8ex;padding-left:1ex">

<div dir="ltr"><div><div><div><div><div><div>Hi,</div><div><br>> <em>Thank you for your time Gábor. I have put this, but I don't know why it doesn't fetch any nodes at all... Could you test this?<br><br></em></div>

<p>I did test it, and worked fine for me. Not sure what could be the issue.</p>
</div><p>> <em>An implicit node is detected: the default constructor of class A in the list of constructors in default constructor of class B. So, I tried to fix this doing  this:</em></p>
</div><p>I believe this is what you need then, as Manuel suggested:</p>
<p>constructorDecl(isDefinition(), parameterCountIs(0), unless(isImplicit()),</p>
<div>        anyOf(hasAnyConstructorInitializer(anything()), has(compoundStmt(has(stmt())))));</div><div>How you compose your matchers dictate how they will behave. Lets take a simple example: functionDecl(isDefinition()). Here the fact that isDefinition() was given as a parameter to functionDecl() indicates that it refines that matcher, i.e. imposes further conditions that have to be met in order for a node to be matched.</div>

<div>Now with this logic, lets look at what you tried: <span style="font-size:12.7273px">withInitializer(constructorDecl(isImplicit()))<br></span></div><p>This means something like "an initializer that is an implicit constructor declaration" - which obviously makes no sense, and thanks to template voodoo magic, it doesn't compile either. The reason is that withInitializer expects a Matcher<Expr>, that is, a matcher that matches certain Exprs (that meet a certain criteria). constructorDecl() yields a Matcher<CXXConstructorDecl>, because it is a matcher that accepts CXXConstructorDecl objects.</p>


</div><p>> <em><span style="font-size:12.7273px">In addition, I would like to work only with the code that is explicit and for example when I try to match "methodDecl(isOverride())" a lot of implicit </span><span style="font-size:12.7273px">methods</span><span style="font-size:12.7273px">  </span><span style="font-size:12.7273px">(and even methods from other files apart of mine) are detected with this matcher. How can I avoid this?</span></em></p>


</div><p>I'm not sure what you mean by "implicit" methods here. Obviously you'll get matches in header files as well, most notably, system header files. SourceManager::isInSystemHeader and isInExternCSystemHeader is what you're looking for if you want to avoid that - you'll place such a check in your matcher callback function.</p>


</div><p>Gabor</p>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/4/19 Pedro Delgado Perez <span dir="ltr"><<a href="mailto:pedro.delgadoperez@mail.uca.es" target="_blank">pedro.delgadoperez@mail.uca.es</a>></span><br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><p>Thank you ver much both of you, it really helps:</p>
<div><blockquote style="border-left:2px solid #000083;margin:0pt 0pt 0pt 0.8ex;padding-left:1ex"><div>All of the ways you cite make sense. What you want really depends on what kind of control you want. Note that you can always easily start with AST matchers to find higher level things you're interested in, and then drill down through the AST nodes by calling the methods or even by using a RecursiveASTVisitor on a node...</div>

</blockquote></div><p> Ok, Manuel. I need to study this a bit more to catch on the best way for me, but it's good to know I can merge both strategies.</p>
<div><blockquote style="border-left:2px solid #000083;margin:0pt 0pt 0pt 0.8ex;padding-left:1ex"><div style="font-size:12.727272033691406px">I have put together quickly the matcher that I believe suits your needs, just so that you can see how it works:<br>

 <br>namespace clang {<br>namespace ast_matchers {<br><br>using namespace clang::ast_matchers::internal;<br><br>AST_MATCHER(CXXConstructorDecl, defaultNonTrivialCtor)<br>{<br>    return Node.isThisDeclarationADefinition()<br>

         && Node.isDefaultConstructor()<br>        && (Node.getNumCtorInitializers() != 0 || !Node.hasTrivialBody());<br>}<br><br>} // ast_matchers<br>} // clang<br><br></div><p><span style="font-size:12.727272033691406px">(Don't forget to include ASTMatchers.h, ASTMatchersInternal.h and ASTMatchersMacros.h)</span></p>


</blockquote></div><p>Thank you for your time Gábor. I have put this, but I don't know why it doesn't fetch any nodes at all... Could you test this?</p>
<div><blockquote style="border-left:2px solid #000083;margin:0pt 0pt 0pt 0.8ex;padding-left:1ex"><div style="font-size:12.727272033691406px">constructorDecl(isDefinition(), parameterCountIs(0),<br>        anyOf(hasAnyConstructorInitializer(anything()), has(compoundStmt(has(stmt())))));</div>

<div style="font-size:12.727272033691406px"><div>(I did a quick test, and seems to work as intended, but you should make sure to test it thoroughly yourself.)</div></div></blockquote></div><p>I have put this as well and this time does it works, but indeed it needs something more, because if we have:</p>


<p>class A{<br>public:<br>A(){}<br>... <br>};</p>
<p>class B: public A{<br>public:<br>B(){}<br>...<br>};</p>
<p>An implicit node is detected: the default constructor of class A in the list of constructors in default constructor of class B. So, I tried to fix this doing  this:</p>
<p><span style="font-size:12.727272033691406px">constructorDecl(isDefinition(), parameterCountIs(0),</span><br style="font-size:12.727272033691406px"><span style="font-size:12.727272033691406px">        anyOf(hasAnyConstructorInitializer(<strong>unless(withInitializer(constructorDecl(isImplicit())))</strong>)), has(compoundStmt(has(stmt())))));</span></p>


<p><span style="font-size:12.727272033691406px">But, I newbie in this and it doesn't work as constructorDecl returns a Decl and withInitializer a Expr (i think). How could I do this? Sorry for this, but I would like to have at least an example complete. </span></p>


<p><span style="font-size:12.727272033691406px">In addition, I would like to work only with the code that is explicit and for example when I try to match "methodDecl(isOverride())" a lot of implicit </span><span style="font-size:12.727272033691406px">methods</span><span style="font-size:12.727272033691406px">  </span><span style="font-size:12.727272033691406px">(and even methods from other files apart of mine) are detected with this matcher. How can I avoid this?</span></p>


<p><span style="font-size:12.727272033691406px">Thanks,</span></p>
<p><span style="font-size:12.727272033691406px">Pedro.</span></p>
<div><em>El dia 19 abr 2013 13:50, Manuel Klimek <<a href="mailto:klimek@google.com" target="_blank">klimek@google.com</a>> escribió:</em></div><div><div><blockquote style="border-left:2px solid #000083;margin:0pt 0pt 0pt 0.8ex;padding-left:1ex">

<div dir="ltr">On Fri, Apr 19, 2013 at 12:18 PM, Pedro Delgado Perez <span dir="ltr"><<a href="mailto:pedro.delgadoperez@mail.uca.es" target="_blank">pedro.delgadoperez@mail.uca.es</a>></span> wrote:<br><div class="gmail_extra">

<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><p>Hi again,</p>
<p>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:</p>
<p>class Foo {<br>public:<br><strong>Foo(){}</strong><br>Foo(int a){... ...}<br>}</p>
<br>
<p>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:</p>
<p><em>AST_MATCHER(CXXConstructorDecl, isDefaultConstructor){</em><br><em>return Node.isDefaultConstructor();</em><br><em>}</em></p>
<p>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 <a href="http://clang.llvm.org/docs/RAVFrontendAction.html" target="_blank">http://clang.llvm.org/docs/RAVFrontendAction.html</a> ? This way, I can directly use the methods in the classes. For instance:</p>


<pre style="overflow-x:auto;overflow-y:hidden;border:thin dotted #0c3762;margin:0px 0px 12px;padding:0.8em;background-color:#f0f0f0;color:#333333"> bool VisitCXXConstructorDecl(CXXConstructorDecl *Declaration) {    if (Declaration->isDefaultConstructor()) {</pre>

<p>I have to visit a lot of kind of nodes with different features, not only this. </p>
</div></blockquote><div>All of the ways you cite make sense. What you want really depends on what kind of control you want. Note that you can always easily start with AST matchers to find higher level things you're interested in, and then drill down through the AST nodes by calling the methods or even by using a RecursiveASTVisitor on a node...</div>

<div>Cheers,</div><div>/Manuel</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><p>Please, I need a path to get down to work.</p>
<p>Thanks in advance,</p>
<div><p>Pedro.</p>
<br>
<div><em>El dia 19 abr 2013 01:58, Gábor Kozár <<a href="mailto:kozargabor@gmail.com" target="_blank">kozargabor@gmail.com</a>> escribió:</em></div><blockquote style="border-left:2px solid #000083;margin:0pt 0pt 0pt 0.8ex;padding-left:1ex">

<div dir="ltr"><div><div><div>Hi,<br><br></div><p>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: <a href="http://llvm.org/svn/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h" target="_blank">http://llvm.org/svn/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h</a>).</p>


</div><p>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).</p>
</div><p>Gabor</p>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/4/18 Pedro Delgado Perez <span dir="ltr"><<a href="mailto:pedro.delgadoperez@mail.uca.es" target="_blank">pedro.delgadoperez@mail.uca.es</a>></span><br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><p>Hi,</p>
<p>I'm newbie using ASTMatchers and I'm trying to learn little by little how to use them.</p>
<p>I was basing on the matcher <span style="color:#333333;font-family:monospace;font-size:12px;line-height:17px;text-align:justify">recordDecl(hasName("Foo"),</span><span style="color:#333333;font-family:monospace;font-size:12px;line-height:17px;text-align:justify;background-color:#e2e2e2"> </span><span style="color:#333333;font-family:monospace;font-size:12px;line-height:17px;text-align:justify">isDerivedFrom("Bar")) </span>shown in <a href="http://clang.llvm.org/docs/LibASTMatchers.html" target="_blank">http://clang.llvm.org/docs/LibASTMatchers.html</a> trying to include new features. For instance, I tried to look for classes which have at least one virtual method:</p>


<p><span style="color:#333333;font-family:monospace;font-size:12px;line-height:17px;text-align:justify">recordDecl(hasName("Foo"),</span><span style="color:#333333;font-family:monospace;font-size:12px;line-height:17px;text-align:justify;background-color:#e2e2e2"> </span><span style="color:#333333;font-family:monospace;font-size:12px;line-height:17px;text-align:justify">isDerivedFrom("Bar"), hasMethod(isVirtual()))</span></p>


<p>Or I tried to match protected overriden methods:</p>
<p><span style="color:#333333;font-family:monospace;font-size:12px;line-height:17px;text-align:justify">methodDecl(allOf(isProtected(), isOverride()</span><span style="color:#333333;font-family:monospace;font-size:12px;line-height:17px;text-align:justify">);</span></p>


<p>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.</p>
<p>Finally, I tried to look for the the default constructor of a certain class:</p>
<p><span style="color:#333333;font-family:monospace;font-size:12px;line-height:17px;text-align:justify">constructorDecl(hasName("Foo"), isDefaultConstructor())</span></p>
<p>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.</p>
<p>Thanks in advance,</p>
<p>Pedro.</p>
<br>
</div><br>
<p>_______________________________________________<br>cfe-dev mailing list<br><a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a></p>
</blockquote></div></div><p><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a></p>
</blockquote></div></div><br>
<p>_______________________________________________<br>cfe-dev mailing list<br><a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a></p>
</blockquote></div></div></div><p><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a></p>
</blockquote></div></div></div></blockquote></div><br>
</div></blockquote></div></div></div></blockquote></div><br>
</div></blockquote></div></div></div></blockquote></div><br>
</div></blockquote>
</div></div></div>
</blockquote></div><br></div>