Как получить имена аргументов указателей на функции, используя clang LibTooling? - PullRequest
0 голосов
/ 24 декабря 2018

Скажем, я анализирую код, подобный следующему:

struct Foo
{
    void(*setParam)(const char* name, int value);
};

Я использую Clang LibTooling и получаю FieldDecl на setParam.

Я подумал, что могу получить типы аргументов примерно так:

auto ft = fieldDecl->getFunctionType()->getAs<FunctionProtoType>();
for (size_t i = 0; i < fpt->getNumParams(); i++)
{
    QualType paramType = fpt->getParamType(i);
    ....
}

Но как мне получить имена аргументов?(в этом случае «name» и «value») Это вообще возможно, или мне нужно вручную посмотреть источник (с SourceManager)?

1 Ответ

0 голосов
/ 24 декабря 2018

Я не думаю, что можно получить имена параметров непосредственно из типа, так как они не являются частью информации о типе.

Но ваша задача может быть выполнена еще одним посещением функцииобъявление указателя:

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;
};

Тогда вызывающий сайт:

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;
}

Обратите внимание на часть getFunctionScopeDepth(), это необходимо, потому что параметр функции может быть сам указатель на функцию, что-тонапример:

void(*setParam)(const char* name, int value, void(*evil)(int evil_name, int evil_value));

getFunctionScopeDepth(), будучи равным 0, гарантирует, что этот параметр не находится во вложенном контексте.

...