2017-03-31 140 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