[cfe-dev] Clang tooling namespace issues
Anna Herlihy
anna.herlihy at mongodb.com
Thu Dec 4 11:33:41 PST 2014
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20141204/094cc2a5/attachment.html>
More information about the cfe-dev
mailing list