Shens
Shens

Reputation: 43

How to get function pointer arguments names using clang LibTooling?

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

Answers (1)

llllllllll
llllllllll

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

Related Questions