<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Dec 9, 2014 at 7:52 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">Thank you for getting back to me! Unfortunately, when I call getQualifier() on the CXXRecordDecl it always returns null. I tried calling it for my own class, ns::StringData, but also std::String and both cases return null. </div></blockquote><div><br></div><div>CXXRecordDecl::getQualifier gives you this:</div><div><br></div><div><font face="monospace">struct ns::Foo {};<br></font></div><div><font face="monospace"> ^^^^</font></div><div><br></div><div>You want ElaboratedType::getQualifier(), which gives you this:</div><div><br></div><div><font face="monospace">void f(ns::Foo);</font></div><div><font face="monospace"> ^^^^</font></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>I ran: </div><span class=""><div><font face="monospace"><br></font></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><font face="monospace">QualType original_type = p->getOriginalType();</font></div></blockquote></span><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><div><font face="monospace">QualType nonref_type = original_type.getNonReferenceType();</font></div></div></blockquote><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><font face="monospace">nonref_type.removeLocalConst();<br></font></div><div><font face="monospace">CXXRecordDecl* decl = nonref_type->getAsCXXRecordDecl();<br></font></div><div><font face="monospace">NestedNameSpecifier* name = decl->getQualifier();<br></font></div><div><div><font face="monospace">if( name == NULL ) {</font></div><div><font face="monospace"> printf("null name: %s\n", nonref_type.getAsString().c_str());</font></div><div><font face="monospace">}</font></div></div></blockquote><br></div><div><font face="arial, helvetica, sans-serif">on:</font></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><div><font face="monospace">void std_ns(const std::string& d);</font></div></div><div><div><font face="monospace">void strdata_ns(const mongo::StringData& d);</font></div></div><div><font face="monospace"><br></font></div></blockquote><font face="monospace">name </font><font face="arial, helvetica, sans-serif">is always NULL. Any suggestions on why this might be happening?</font><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">Thank you!</font></div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Dec 5, 2014 at 5:31 AM, Nikola Smiljanic <span dir="ltr"><<a href="mailto:popizdeh@gmail.com" target="_blank">popizdeh@gmail.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 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"><div><div>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></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><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></div></div>_______________________________________________<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>
</blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu">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></div>