2017-03-31 30 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の質問には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

この単純な例では、regexが行うかもしれませんが、実際にはより大きなコードベースでこれを使用し、後で関数定義と対話する必要があるため、* libclang *を使用するように強制されています* – filaton

答えて

0

あなたの関数定義が同じファイルにある場合は、呼び出し元サイトを取得するためにcallexprマッチャーを使うことができると思います。次に、getDirectCalleeを使用してFunctionDeclを取得します。 FunctionDeclでgetBodyを呼び出すことができます

+0

ありがとうございます。できるだけ早く試してみてください。定義が別のファイルにある場合はどうなりますか? – filaton

+0

私は正確な解決策がわかりません。私は前に次のことをしていました。しかし、クリーナーソリューションがあるかもしれません。そのファイルが異なる場合は、そのファイルも解析して、関数定義のマップとそれぞれの呼び出しを自分で作成する必要があります。 (このマッピングの側面では、clangが何らかの方法を提供するかどうかはわかりません) – user8210314

関連する問題