<div class="gmail_quote">Also, your snippet looks light it could profit from the refactoring libs we have in clang.</div><div class="gmail_quote">A nice intro is:</div><div class="gmail_quote"><a href="http://eli.thegreenplace.net/2014/07/29/ast-matchers-and-clang-refactoring-tools">http://eli.thegreenplace.net/2014/07/29/ast-matchers-and-clang-refactoring-tools</a><br></div><div class="gmail_quote"><br></div><div class="gmail_quote">On Fri Dec 05 2014 at 11:37:27 AM Nikola Smiljanic <<a href="mailto:popizdeh@gmail.com">popizdeh@gmail.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Anna, if StringData is a C++ class you can call getAsCXXRecordDecl on QualType to get the class declaration. Call getQualifier (defined in TagDecl base class) on the declaration to access the NestedNameSpecifier.</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Dec 5, 2014 at 6:33 AM, Anna Herlihy <span dir="ltr"><<a href="mailto:anna.herlihy@mongodb.com" target="_blank">anna.herlihy@mongodb.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi,<div><br></div><div>I'm trying to write a clang compiler tool that will change any functions that take an argument of type StringData by const ref to taking it by value.  <span style="font-family:arial,helvetica,sans-serif">I would like to have the transformed argument have the same naming format as the original (i.e. if it's declared without a namespace qualifier, then the rewritten argument should not have one and vice versa). StringData is my string wrapper class.</span></div><div><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif">For example, I want to transform: </span></div><div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace">void example(const StringData& d);</font></blockquote></div></div><div>into:</div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><span style="font-family:monospace">void example(StringData);</span></div><div><span style="font-family:monospace"><br></span></div></blockquote><font face="arial, helvetica, sans-serif">And I <i>also</i> want to be able to transform:</font><div><div><div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace">void example_ns(const ns::StringData& d);</font></blockquote></div><div>into:</div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><span style="font-family:monospace">void example_ns(ns::StringData);</span></blockquote><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">I'm using RecursiveASTVisitor, and in my </font><font face="monospace">VisitFunctionDecl</font><font face="arial, helvetica, sans-serif"> function I check for arguments </font><span style="font-family:arial,helvetica,sans-serif">that match my criteria then use the Rewriter class to change the argument from const ref to a value. My problem is that the transformation always writes the full elaborated type, so for </span><span style="font-family:monospace">const StringData&, </span><span style="font-family:arial,helvetica,sans-serif">instead of changing the argument type </span><font face="arial, helvetica, sans-serif">to simply </font><font face="monospace">StringData</font><font face="arial, helvetica, sans-serif">, it changes it to </font><font face="monospace">class ns::StringData</font><font face="arial, helvetica, sans-serif">.</font></div><div><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div><span style="font-family:arial,helvetica,sans-serif">My code currently looks like this:</span></div><div><span style="font-family:arial,helvetica,sans-serif"><br></span></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><span style="font-family:monospace">bool VisitFunctionDecl(FunctionDecl *f) {</span><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><span style="font-family:monospace">    for (unsigned int i=0; i<f->getNumParams(); i++) {</span><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><font face="monospace"><br></font><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><span style="font-family:monospace">        ParmVarDecl* p = f->getParamDecl(i);</span><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><span style="font-family:monospace">        QualType original_type = p->getOriginalType();</span><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><span style="font-family:monospace">        QualType original_nr = original_type.getNonReferenceType();</span><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><span style="font-family:monospace">        const IdentifierInfo* id = original_type.getBaseTypeIdentifier();</span><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><span style="font-family:monospace">        if (id == NULL) { continue; }</span><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><font face="monospace"><br></font><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><span style="font-family:monospace">        if (!id->getName().compare("StringData") &&</span><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><span style="font-family:monospace">            original_type->isReferenceType() &&</span><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><span style="font-family:monospace">            original_nr.isConstQualified()) {</span><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><font face="monospace"><br></font><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><span style="font-family:monospace">            original_nr.removeLocalConst();</span><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><span style="font-family:monospace">            TheRewriter.ReplaceText(p->getSourceRange(), original_nr.getAsString());</span><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><span style="font-family:monospace">        }</span><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><span style="font-family:monospace">    }</span><br><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><span style="font-family:monospace">    return true;</span><br><font face="monospace">  }</font></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace"><br></font><font face="monospace"><br></font></blockquote></blockquote>If I run this code on the following example: </div><div><font face="monospace"><br></font></div><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div><div><font face="monospace">void example_ns(const ns::StringData& d);</font></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div><div><font face="monospace">using namespace ns;</font></div><div><font face="monospace">void example(const StringData& d);</font></div></div></div></blockquote></div><div><br></div><div>The result looks like:</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace">void example_ns(ns::StringData);<br>using namespace ns;<br>void example(class ns::StringData);<br><br></font></blockquote><div>But I want the result to look like:</div><div><br></div></div></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><div><div><span style="font-family:monospace">void example_ns(ns::StringData);</span></div></div></div></div><div><div><div><div><span style="font-family:monospace">using namespace ns;</span></div></div></div></div><div><div><div><div><span style="font-family:monospace">void example(StringData);</span></div></div></div></div><div><span style="font-family:monospace"><br></span></div></blockquote><div><div><div><div>Is there a way of finding out if a declaration is made with an explicit namespace qualifier? Is there any way to determine what the actual namespace of a type is? How can I extract the name of the argument type in the same format as it's declared in the original source?</div><div><br></div><div>I am also working on another tool for identifying namespace dependencies so any advice involving namespaces and RecursiveASTVisitors is welcome :)</div><div><br></div><div>Thank you!</div><span><font color="#888888"><div><br></div><div>Anna</div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div></div></blockquote></font></span></div></div></div></div>
<br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div>
______________________________<u></u>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/cfe-dev</a><br>
</blockquote></div>