使用 Clang 查找特定函数调用的函数定义

Find a function definition for a specific function call with Clang

本文关键字:函数 定义 函数调用 Clang 查找 使用      更新时间:2023-10-16

我正在尝试使用libclang构建一个小程序,该程序检索特定函数调用的函数/方法的定义。

例如,我有以下main.cpp

int add(int x, int y)
{
    return x + y;
}
int main()
{
    int a = 1;
    int b = 1;
    int c = add(a, b);
    return 0;
}

我想以这样的方式调用我的程序:

./find_definition main.cpp add

我希望它返回:

Definition of add in main.cpp:1 - int add(int x, int y)

我已经在这个SO问题中读到clang_getCursorUSR()可能会对我有所帮助,到目前为止,我已经有了该代码:

#include <clang-c/Index.h>
#include <iostream>
#include <string>
CXChildVisitResult visitor(CXCursor cursor, CXCursor /* parent */, CXClientData clientData)
{
    CXSourceLocation location = clang_getCursorLocation(cursor);
    if(clang_Location_isFromMainFile(location) == 0)
    {
        // Continue the cursor traversal with the next sibling of the cursor just visited, without visiting its children.
        return CXChildVisit_Continue;
    }
    CXCursorKind cursorKind     = clang_getCursorKind(cursor);
    CXString     cursorSpelling = clang_getCursorSpelling(cursor);
    if (cursorKind == CXCursor_CallExpr && clang_getCString(cursorSpelling) == "add") {
        CXString cursorUsr = clang_getCursorUSR(cursor);
        std::cout << "Cursor USR is " << clang_getCString(cursorUsr) << std::endl;
        clang_disposeString(cursorUsr);
    }
    clang_disposeString(cursorSpelling);
    // Visit children nodes
    unsigned int curLevel  = *(reinterpret_cast<unsigned int*>(clientData));
    unsigned int nextLevel = curLevel + 1;
    clang_visitChildren(cursor, visitor, &nextLevel);
    return CXChildVisit_Continue;
}
int main(int argc, char** argv)
{
    if(argc < 2)
    return -1;
    CXIndex           index = clang_createIndex(0, 1);
    CXTranslationUnit tu    = clang_createTranslationUnitFromSourceFile(index, argv[1], 0, 0, 0, 0);
    if(!tu)
    {
        std::cout << "TU not found! Aborting...";
        return -1;
    }
    CXCursor rootCursor  = clang_getTranslationUnitCursor(tu);
    unsigned int treeLevel = 0;
    clang_visitChildren(rootCursor, visitor, &treeLevel);
    clang_disposeTranslationUnit(tu);
    clang_disposeIndex(index);
    return 0;
}

当我在我的main.cpp上运行它时,它只打印:

Cursor USR is 

但我没有得到任何其他信息。

我认为如果您的函数定义位于同一文件中,您可以使用 callexpr 匹配器来获取调用站点。 然后使用 getDirectCallee 获取 FunctionDecl。在 FunctionDecl 上,您可以调用 getBody