2017-03-31 109 views
1

我試圖建立一個小程序libclang它檢索特定函數調用的函數/方法的定義。找到與Clang的特定函數調用的函數定義

舉例來說,我有以下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 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 

,但我沒有得到任何額外的信息。

+0

對我來說這似乎是一種矯枉過正,智能正則表達式不會捕獲任何(也是唯一的)函數定義嗎?我知道C++不是普通的語言,但在這種情況下,它可能是一種方式。 –

+0

在這個簡單的例子中,正則表達式可能會做,但我實際上必須在更大的代碼庫上使用它,並在稍後與函數定義進行交互,所以我想我被迫使用* libclang * – filaton

回答

0

我想如果你的函數定義在同一個文件中,你可以使用callexpr匹配器來獲取調用網站。然後使用getDirectCallee來獲取FunctionDecl。在FunctionDecl你可以調用getBody

+0

謝謝你的回答,我會盡快嘗試。如果該定義在另一個文件中呢? – filaton

+0

我不確定確切的解決方案。我早些時候做過以下事情。儘管如此,可能有更清晰的解決方案如果它不同,你還需要解析該文件,並創建一個函數定義和它們各自調用的映射。 (這個映射方面,我不確定clang是否提供了任何方法) – user8210314