Reputation: 43
Say I analyze a code like this:
struct Foo
{
void(*setParam)(const char* name, int value);
};
I use clang LibTooling and get FieldDecl
on a setParam
.
I figured I can get argument types like so:
auto ft = fieldDecl->getFunctionType()->getAs<FunctionProtoType>();
for (size_t i = 0; i < fpt->getNumParams(); i++)
{
QualType paramType = fpt->getParamType(i);
....
}
But how do I get argument names? ("name" and "value" in that case) Is that even possible or I need to manually look into source (with SourceManager
)?
Upvotes: 3
Views: 1265
Reputation: 16404
I don't think it's possible to get the parameter names directly from the type, since they're not part of the type information.
But your task can be accomplished by one more visiting to the function pointer declaration:
class ParmVisitor
: public RecursiveASTVisitor<ParmVisitor>
{
public:
bool VisitParmVarDecl(ParmVarDecl *d) {
if (d->getFunctionScopeDepth() != 0) return true;
names.push_back(d->getName().str());
return true;
}
std::vector<std::string> names;
};
Then the calling site is:
bool VisitFieldDecl(Decl *d) {
if (!d->getFunctionType()) {
// not a function pointer
return true;
}
ParmVisitor pv;
pv.TraverseDecl(d);
auto names = std::move(pv.names);
// now you get the parameter names...
return true;
}
Pay attention to the getFunctionScopeDepth()
part, it's necessary because a function parameter might be a function pointer itself, something like:
void(*setParam)(const char* name, int value, void(*evil)(int evil_name, int evil_value));
getFunctionScopeDepth()
being 0 ensures that this parameter is not in a nested context.
Upvotes: 1