Hi Manuel,<div><br></div><div>this looks pretty cool.</div><div><br></div><div>However, as far as I understand, MatchFinder can only be used in stand-alone tools using the Tooling infrastructure, because the public api is mostly limited to NewFrontendActionFactory(). Do you think it's possible to somehow make MatchASTConsumer public as well (maybe just give MatchFinder a NewASTCosumer() function), so that the DSL can be used in places were ASTConsumers are needed (such as in the "normal" rewriter infrastructure)? I only skimmed the patch, so sorry if that's a superficial question.</div>
<div><br></div><div>Nico<br><br><div class="gmail_quote">On Mon, May 23, 2011 at 3:03 PM, Manuel Klimek <span dir="ltr"><<a href="mailto:klimek@google.com">klimek@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
This patch implements an AST matching framework that allows to write tools that match on the C++ ASTs. The main interface is in ASTMatchers.h, an example implementation of a tool that removes redundant .c_str() calls is in the example RemoveCStrCalls.cpp (patch to llvm/clang produced by running this tool will be sent out shortly in an extra email).<br>

<br>Currently we have an in-language DSL that allows to write expressions such as (taken from the .c_str() example):<br><span style="font-family:Arial, Helvetica, sans-serif;font-size:13px"><table cellpadding="0" cellspacing="0" style="padding-top:5px;padding-right:5px;padding-bottom:5px;padding-left:5px">

<tbody><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">ConstructorCall(
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
     HasDeclaration(Method(HasName(StringConstructor))),
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
     ArgumentCountIs(2),
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
     // The first argument must have the form x.c_str() or p->c_str()
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
     // where the method is string::c_str().  We can use the copy
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
     // constructor of string instead (or the compiler might share
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
     // the string object).
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
     HasArgument(
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
         0,
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
         Id("call", Call(
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
             Callee(Id("member", MemberExpression())),
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
             Callee(Method(HasName(StringCStrMethod))),
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
             On(Id("arg", Expression()))))),
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
     // The second argument is the alloc object which must not be
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
     // present explicitly.
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
     HasArgument(
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
         1,
</td></tr><tr style="background-color:rgb(229, 236, 249)"><td></td></tr><tr><td style="white-space:pre-wrap;font-family:monospace;font-size:12px;vertical-align:top">
         DefaultArgument()))</td></tr></tbody></table></span><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">The next steps will be to build up better support for in-process refactorings based on the Rewriter, to build up higher-level matchers for common patterns, and to extend the low-level matcher library.</font></div>

<div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">(rietveld link: </font><a href="http://codereview.appspot.com/4552059/" target="_blank">http://codereview.appspot.com/4552059/</a>)</div>

<div><br></div><div>Cheers,</div><div>/Manuel</div>
</blockquote></div><br></div>