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

时间:2017-03-31 13:24:06

标签: c++ abstract-syntax-tree libclang

我正在尝试使用 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)

我已经在this中读到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 

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

1 个答案:

答案 0 :(得分:0)

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