2017-03-31 11 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() 내게 도움이 될 지금까지, 그 코드를 가지고 :

main.cpp에 그것을 실행
#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; 
} 

, 그것은 단지 인쇄 :

Cursor USR is 

을하지만 추가 정보를 얻을하지 않습니다 .

+0

그것은 과장된 것 같습니다. 스마트 정규식에서는 함수 정의를 잡을 수 없습니까? 나는 C++이 정규 언어가 아니라는 것을 알고 있지만,이 경우에는 갈 길이 될 것입니다. –

+0

그 간단한 예제에서 regex가 할 수는 있지만 더 큰 코드베이스에서 이것을 사용하고 나중에 함수 정의와 상호 작용해야하므로 * libclang *을 사용하도록 강요 받았다. – filaton

답변

0

내 생각에 함수 정의가 호출 사이트를 가져 오기 위해 callexpr 정규식을 사용할 수있는 동일한 파일에 있다고 생각합니다. 그런 다음 getDirectCallee를 사용하여 FunctionDecl을 가져옵니다. FunctionDecl에서 getBody를 호출 할 수 있습니다.

+0

답변 해 주셔서 감사합니다. 최대한 빨리 시도하십시오. 정의가 다른 파일에 있으면 어떻게 될까요? – filaton

+0

정확한 해결책이 확실하지 않습니다. 나는 이전에 다음과 같이했다. 그러나 더 깨끗한 해결책이있을 수 있습니다. 다른 경우에는 해당 파일을 구문 분석하고 함수 정의 및 각자의 호출에 대한 맵을 직접 작성해야합니다. (이 매핑 측면, 나는 clang 할 어떤 방법을 제공하는지 모르겠습니다) – user8210314