[cfe-dev] Clang tooling namespace issues

Nikola Smiljanic popizdeh at gmail.com
Fri Dec 5 02:31:19 PST 2014


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.

On Fri, Dec 5, 2014 at 6:33 AM, Anna Herlihy <anna.herlihy at mongodb.com>
wrote:

> Hi,
>
> 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.  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.
>
> For example, I want to transform:
>
> void example(const StringData& d);
>
> into:
>
> void example(StringData);
>
> And I *also* want to be able to transform:
>
> void example_ns(const ns::StringData& d);
>
> into:
>
> void example_ns(ns::StringData);
>
>
> I'm using RecursiveASTVisitor, and in my VisitFunctionDecl function I
> check for arguments 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 const
> StringData&, instead of changing the argument type to simply StringData,
> it changes it to class ns::StringData.
>
> My code currently looks like this:
>
> bool VisitFunctionDecl(FunctionDecl *f) {
>
>     for (unsigned int i=0; i<f->getNumParams(); i++) {
>
>
>         ParmVarDecl* p = f->getParamDecl(i);
>
>         QualType original_type = p->getOriginalType();
>
>         QualType original_nr = original_type.getNonReferenceType();
>
>         const IdentifierInfo* id = original_type.getBaseTypeIdentifier();
>
>         if (id == NULL) { continue; }
>
>
>         if (!id->getName().compare("StringData") &&
>
>             original_type->isReferenceType() &&
>
>             original_nr.isConstQualified()) {
>
>
>             original_nr.removeLocalConst();
>
>             TheRewriter.ReplaceText(p->getSourceRange(),
> original_nr.getAsString());
>
>         }
>
>     }
>
>     return true;
>   }
>
>
>
> If I run this code on the following example:
>
> void example_ns(const ns::StringData& d);
>
> using namespace ns;
> void example(const StringData& d);
>
>
> The result looks like:
>
> void example_ns(ns::StringData);
> using namespace ns;
> void example(class ns::StringData);
>
> But I want the result to look like:
>
> void example_ns(ns::StringData);
> using namespace ns;
> void example(StringData);
>
> 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?
>
> I am also working on another tool for identifying namespace dependencies
> so any advice involving namespaces and RecursiveASTVisitors is welcome :)
>
> Thank you!
>
> Anna
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20141205/82271d4c/attachment.html>


More information about the cfe-dev mailing list