<html>
<head></head>
<body>
<p>Hi again,</p>
<p>Sorry to make so much questions, but I hope a good structure of my tool will save me a lot of time in future.</p>
<p>I'm using something like this in <a href="http://clang.llvm.org/docs/LibASTMatchersTutorial.html" target="_blank">http://clang.llvm.org/docs/LibASTMatchersTutorial.html</a>:</p>
<br/>
<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 class="k" style="color: #007020; font-weight: bold;">class</span> <span class="nc" style="color: #0e84b5; font-weight: bold;">LoopPrinter</span> <span class="o" style="color: #666666;">:</span> <span class="k" style="color: #007020; font-weight: bold;">public</span> <span class="n">MatchFinder</span><span class="o" style="color: #666666;">::</span><span class="n">MatchCallback</span> <span class="p">{</span><span class="k" style="color: #007020; font-weight: bold;">public</span> <span class="o" style="color: #666666;">:</span>  <span class="k" style="color: #007020; font-weight: bold;">virtual</span> <span class="kt" style="color: #902000;">void</span> <span class="n">run</span><span class="p">(</span><span class="k" style="color: #007020; font-weight: bold;">const</span> <span class="n">MatchFinder</span><span class="o" style="color: #666666;">::</span><span class="n">MatchResult</span> <span class="o" style="color: #666666;">&</span><span class="n">Result</span><span class="p">)</span> <span class="p">{</span>    <span class="k" style="color: #007020; font-weight: bold;">if</span> <span class="p">(</span><span class="k" style="color: #007020; font-weight: bold;">const</span> <span class="n">ForStmt</span> <span class="o" style="color: #666666;">*</span><span class="n">FS</span> <span class="o" style="color: #666666;">=</span> <span class="n">Result</span><span class="p">.</span><span class="n">Nodes</span><span class="p">.</span><span class="n">getNodeAs</span><span class="o" style="color: #666666;"><</span><span class="n">clang</span><span class="o" style="color: #666666;">::</span><span class="n">ForStmt</span><span class="o" style="color: #666666;">></span><span class="p">(</span><span class="s" style="color: #4070a0;">"forLoop"</span><span class="p">))</span>      <span class="n">FS</span><span class="o" style="color: #666666;">-></span><span class="n">dump</span><span class="p">();</span>  <span class="p">}</span><span class="p">};</span></pre><br/>
<p>So, now I have two questions:</p>
<p>1. Imagine that I need to print something after <strong>all</strong> the nodes have been matched. For example, the number of nodes matched. How can I do that? </p>
<p>2. Imagine that I have two methods within the run method to separate two kind of nodes I want to bind. Something like this:</p>
<br/>
<br/>
<pre style="color: rgb(51, 51, 51); font-size: 11.818181991577148px; margin: 0px 0px 12px; overflow-x: auto; overflow-y: hidden; border: thin dotted rgb(12, 55, 98); padding: 0.8em; background-color: rgb(240, 240, 240);"><span class="k" style="color: #007020; font-weight: bold;"><br class="Apple-interchange-newline" />class</span> <span class="nc" style="color: #0e84b5; font-weight: bold;">LoopPrinter</span> <span class="o" style="color: #666666;">:</span> <span class="k" style="color: #007020; font-weight: bold;">public</span> <span class="n">MatchFinder</span><span class="o" style="color: #666666;">::</span><span class="n">MatchCallback</span> <span class="p">{</span><span class="k" style="color: #007020; font-weight: bold;">public</span> <span class="o" style="color: #666666;">:</span>  <span class="k" style="color: #007020; font-weight: bold;">virtual</span> <span class="kt" style="color: #902000;">void</span> <span class="n">run</span><span class="p">(</span><span class="k" style="color: #007020; font-weight: bold;">const</span> <span class="n">MatchFinder</span><span class="o" style="color: #666666;">::</span><span class="n">MatchResult</span> <span class="o" style="color: #666666;">&</span><span class="n">Result</span><span class="p">)</span> <span class="p">{</span>    <span class="n">applyMatch1();<br /></span>    applyMatch2();  <span class="p">}<br /><br /></span>void <span class="n" style="color: #000000;">applyMatch1(){<br /> <span class="k" style="color: #007020; font-weight: bold;">if</span> <span class="p">(</span><span class="k" style="color: #007020; font-weight: bold;">const</span> <span class="n">ForStmt</span> <span class="o" style="color: #666666;">*</span><span class="n">FS</span> <span class="o" style="color: #666666;">=</span> <span class="n">Result</span><span class="p">.</span><span class="n">Nodes</span><span class="p">.</span><span class="n">getNodeAs</span><span class="o" style="color: #666666;"><</span><span class="n">clang</span><span class="o" style="color: #666666;">::</span><span class="n">ForStmt</span><span class="o" style="color: #666666;">></span><span class="p">(</span><span class="s" style="color: #4070a0;">"forLoop__1"</span><span class="p">))</span><span class="Apple-tab-span" style="white-space: pre;"><br /></span></span>}<br /><br />void apply2(){</pre><pre style="color: #333333; font-size: 11.818181991577148px; margin: 0px 0px 12px; overflow-x: auto; overflow-y: hidden; border: thin dotted #0c3762; padding: 0.8em;"><span class="n" style="color: #000000;"><span class="k" style="color: #007020; font-weight: bold;">if</span> <span class="p">(</span><span class="k" style="color: #007020; font-weight: bold;">const</span> <span class="n">ForStmt</span> <span class="o" style="color: #666666;">*</span><span class="n">FS</span> <span class="o" style="color: #666666;">=</span> <span class="n">Result</span><span class="p">.</span><span class="n">Nodes</span><span class="p">.</span><span class="n">getNodeAs</span><span class="o" style="color: #666666;"><</span><span class="n">clang</span><span class="o" style="color: #666666;">::</span><span class="n">ForStmt</span><span class="o" style="color: #666666;">></span><span class="p">(</span><span class="s" style="color: #4070a0;">"forLoop_2"</span><span class="p">))</span></span></pre><pre style="color: #333333; font-size: 11.818181991577148px; margin: 0px 0px 12px; overflow-x: auto; overflow-y: hidden; border: thin dotted #0c3762; padding: 0.8em; background-color: #f0f0f0;">}<br /><span class="p">};</span></pre><br/>
<br/>
<p>How does the 'run' method behave in this case? I mean that I don't know if it retrieves, one by one, all the nodes in applyMatch1 and ,after that, all the nodes in applyMatch2 or it matches one in applyMatch1 and then other in applyMatch2 in each iteration. I hope you can understand me because this is very important in my case.</p>
<p>Thanks in advance.</p>
<p>Pedro</p>
<br/>
<br/>
<div><em>El dia 06 may 2013 22:32, "Vane, Edwin" <edwin.vane@intel.com> escribió:</em></div><blockquote class="replyBlock" style="border-left: 2px solid #000083; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><p>Given your description, I'm not sure matchers are what you want. If you just want to print information on certain types of nodes, you could use a RecursiveASTVisitor for that.</p>
<p>However, if what you're looking for is a little more complex then matchers may be what you want after all.</p>
<p>As for the two classes, you want to use tooling::MatchFinder as shown in the tutorial. The other is just an implementation detail of the match finding code.</p>
<p>newASTConsumer() is a function that's required to be defined for objects passed to newFrontendActionFactory(). You don't need to implement it. It's implemented by MatchFinder. Again, it's an implementation detail you don't need to worry about at this point.</p>
<p>The use of ASTConsumers is not necessary if you're using MatchFinder and ClangTool as described in the tutorial. MatchFinder is an abstraction around RecursiveASTVisitor so all that stuff in RecursiveASTVisitor you'd normally have to use is actually hidden away.</p>
<p>I think you should first decide which route you want to go: MatchFinder or RecursiveASTVisitor. The first question I'd ask is: how hard is it to find the nodes I want to print info on in the AST. If all I want is every for loop that's easy. If I want for loops within member functions of a specific class, that's hard and an excellent use case for ASTMatchers.</p>
<blockquote class="replyBlock" style="border-left: 2px solid #000083; margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><p>-----Original Message-----<br/>
From: cfe-dev-bounces@cs.uiuc.edu [<a href="mailto:cfe-dev-bounces@cs.uiuc.edu" target="_blank">mailto:cfe-dev-bounces@cs.uiuc.edu</a>] On<br/>
Behalf Of Pedro Delgado Perez<br/>
Sent: Monday, May 06, 2013 12:58 PM<br/>
To: klimek@google.com; kozargabor@gmail.com<br/>
Cc: cfe-dev@cs.uiuc.edu<br/>
Subject: Re: [cfe-dev] ASTMatchers: isVirtual and isOverride</p>
<p>Hi,</p>
<p>I need your help again. Look, in my tool I was trying to use the syntax that's<br/>
shown here:</p>
<p><a href="http://clang.llvm.org/docs/LibASTMatchersTutorial.html" target="_blank">http://clang.llvm.org/docs/LibASTMatchersTutorial.html</a></p>
<p>Namely I'm referring to this part:</p>
<p>int main(int argc, const char **argv) {<br/>
CommonOptionsParser OptionsParser(argc, argv);<br/>
ClangTool Tool(OptionsParser.getCompilations(),<br/>
OptionsParser.getSourcePathList());</p>
<p>LoopPrinter Printer;<br/>
MatchFinder Finder;<br/>
Finder.addMatcher(LoopMatcher, &Printer);</p>
<p>return Tool.run(newFrontendActionFactory(&Finder));<br/>
}</p>
<p>However, now I want to create a object "Printer" with different features<br/>
depending on the arguments provided in command line. So I was thinking on<br/>
implement a factory method pattern to create a different LoopPrinter object:<br/>
class OptionsFactory {<br/>
public:<br/>
LoopPrinter getOption() {<br/>
if(...)<br/>
return LoopPrinter(attribute1, attribute2);<br/>
else<br/>
return LoopPrinter(attribute1);<br/>
}<br/>
};</p>
<p>I was searching for a better solution and there are some things that I can't<br/>
completely understand.</p>
<p>- Why are there two classes MatchFinder:<br/>
<a href="http://clang.llvm.org/doxygen/classclang_1_1tooling_1_1MatchFinder.html" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1tooling_1_1MatchFinder.html</a><br/>
http://clang.llvm.org/doxygen/classclang_1_1ast__matchers_1_1MatchFinder.<br/>
html</p>
<p>- What the method in ast_matchers:MatchFinder</p>
<p>clang::ASTConsumer<br/>
<<a href="http://clang.llvm.org/doxygen/classclang_1_1ASTConsumer.html>" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1ASTConsumer.html></a> *</p>
<p>newASTConsumer<br/>
<<a href="http://clang.llvm.org/doxygen/classclang_1_1ast__matchers_1_1MatchFinder" target="_blank">http://clang.llvm.org/doxygen/classclang_1_1ast__matchers_1_1MatchFinder</a><br/>
.html#a4807049e6e39572d19ff127406df3d81> ()</p>
<p>is used for? I see we can 'associate' an ASTConsumer to the Frontend as in:<br/>
<a href="http://clang.llvm.org/docs/RAVFrontendAction.html" target="_blank">http://clang.llvm.org/docs/RAVFrontendAction.html</a></p>
<p>but, is this possible using Matchers? Would it have any sense to create an<br/>
ASTConsumer in my class OptionsFactory?</p>
<p>I have improved a lot since you last helped me, but clang is too big!</p>
<p>By the way, do you know how to use CommandLine? I posted a new thread</p>
<p><a href="http://lists.cs.uiuc.edu/pipermail/cfe-dev/2013-May/029473.html" target="_blank">http://lists.cs.uiuc.edu/pipermail/cfe-dev/2013-May/029473.html</a></p>
<p>If you know how to solve that problem, please, let me know.</p>
<p>Thanks in advance,</p>
<p>Pedro.</p>
<br/>
<p>El dia 27 abr 2013 18:39, Manuel Klimek <klimek@google.com> escribió:</p>
<p>On Sat, Apr 27, 2013 at 6:36 PM, Gábor Kozár<br/>
<kozargabor@gmail.com> wrote:</p>
<br/>
<br/>
<p>2013/4/27 Manuel Klimek <klimek@google.com></p>
<br/>
<p>Just use the empty string for binding and getNodeAs :)</p>
<br/>
<p>That would potentially lead to confusion when there are more<br/>
nodes bound, but the programmer forgot to supply the proper name. In my<br/>
suggestion, the parameterless getNodeAs would have an assert to check there is<br/>
exactly one node bound (and whose name is the default name).</p>
<p>If you put everything behind constants, I think it'll be easy enough to see<br/>
what's happening - and that's a generally good strategy anyway, as you get a<br/>
compile error if you mistype...<br/>
Thus, I think it'd not add enough value to special case the interface.</p>
<br/>
<br/>
<br/>
<p>2013/4/27 Manuel Klimek <klimek@google.com></p>
<br/>
<p>On Sat, Apr 27, 2013 at 6:28 PM, Gábor Kozár<br/>
<kozargabor@gmail.com> wrote:</p>
<p>Hi,<br/>
2013/4/26 Pedro Delgado Perez<br/>
<pedro.delgadoperez@mail.uca.es></p>
<br/>
<p>Hehehe... I found the problem with<br/>
this. I was binding wrongly the matcher! I used a id in the matcher thas was<br/>
different from the id in the function that retrieves the nodes... I think this will be<br/>
a typical mistake for newbies...</p>
<p>Ah, yes, that happens a lot to me as well. Now<br/>
that I think about it, it might be worthwhile adding a parameterless .bind() and<br/>
.getNodeAs<T>() for situations where only one node is bound. Should be fairly<br/>
trivial, but also not all that useful...</p>
<p>Just use the empty string for binding and getNodeAs :)</p>
<br/>
<br/>
<p>2013/4/26 Pedro Delgado Perez<br/>
<pedro.delgadoperez@mail.uca.es></p>
<br/>
<p>Thanks both! Now I can see all this<br/>
much clearer and I have the enough knowledge to start out with clang.</p>
<br/>
<p>You're welcome. Good luck!</p>
<br/>
<p>2013/4/25 Manuel Klimek <klimek@google.com></p>
<br/>
<p>And btw thanks a lot for all the great user support you're giving<br/>
here!</p>
<br/>
<p>Thank you, I'm happy to help. Clang is a great project!</p>
<p>As soon as the university term is over, I'm also planning on trying to<br/>
contribute code-wise, mainly to the Static Analyzer but I guess also on just about<br/>
anything that catches my attention. :) I'm quite excited - this is going to be the<br/>
first open source project I contribute to.<br/>
Gabor</p>
</blockquote></blockquote>
</body>
</html>