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; igetNumParams(); 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