2013-01-10 3 views
4

나는, 출력은 AST의 계층 구조가 어떻게 libclang 작품입니다 볼 교류 소스 파일 (tt.c를) 구문 분석하는 테스트 프로그램 (parse_ast.c)를 작성했습니다 :libclang : AST의 일부 문장이 누락 되었습니까? 여기 <p></p> 테스트 파일입니다

... 
... 
inclusion directive at tt.c (2, 1) to (2, 20) 
inclusion directive at tt.c (3, 1) to (3, 19) 
TypedefDecl at tt.c (5, 1) to (5, 57) 
TypeRef at tt.c (5, 9) to (5, 16) 
ParmDecl at tt.c (5, 31) to (5, 35) 
ParmDecl at tt.c (5, 36) to (5, 49) 
ParmDecl at tt.c (5, 50) to (5, 56) 
FunctionDecl at tt.c (7, 1) to (9, 2) 
ParmDecl at tt.c (7, 21) to (7, 40) 
    TypeRef at tt.c (7, 21) to (7, 31) 
CompoundStmt at tt.c (7, 42) to (9, 2) 
    CallExpr at tt.c (8, 5) to (8, 42) 
    UnexposedExpr at tt.c (8, 5) to (8, 16) 
    ParenExpr at tt.c (8, 5) to (8, 16) 
    UnaryOperator at tt.c (8, 6) to (8, 15) 
     UnexposedExpr at tt.c (8, 7) to (8, 15) 
     DeclRefExpr at tt.c (8, 7) to (8, 15) 
    IntegerLiteral at tt.c (8, 17) to (8, 18) 
    UnexposedExpr at tt.c (8, 20) to (8, 37) 
    UnexposedExpr at tt.c (8, 20) to (8, 37) 
    StringLiteral at tt.c (8, 20) to (8, 37) 
    IntegerLiteral at tt.c (8, 39) to (8, 41) 
FunctionDecl at tt.c (11, 1) to (13, 2) 
CompoundStmt at tt.c (11, 21) to (13, 2)  <- XXX no line 12? 
FunctionDecl at tt.c (15, 1) to (20, 2) 
CompoundStmt at tt.c (15, 12) to (20, 2) 
    CallExpr at tt.c (16, 5) to (16, 19) 
    UnexposedExpr at tt.c (16, 5) to (16, 17) 
    DeclRefExpr at tt.c (16, 5) to (16, 17)  <- XXX no line 17? 
    ReturnStmt at tt.c (19, 5) to (19, 13) 
    IntegerLiteral at tt.c (19, 12) to (19, 13) 

우리는 (라인 라인 15에서 11/메인 라인에서 7/indirect_write에서 direct_write) 세 가지 기능이 대부분 문 것을 볼 수 있습니다

/* tt.c */         // line 1 
#include <unistd.h> 
#include <stdio.h> 

typedef ssize_t (*write_fn_t)(int, const void *, size_t); 

void indirect_write(write_fn_t write_fn) { // line 7 
    (*write_fn)(1, "indirect call\n", 14); 
} 

void direct_write() {       // line 11 
    write(1, "direct call\n", 12);   // line 12 mising in the ast? 
} 

int main() {         // line 15 
    direct_write(); 
    indirect_write(write);     // line 17 missing in the ast? 

    return 0; 
} 

출력은 다음과 같이 표시됩니다 A에서 찾을 수 있습니다. ST, 12 행 17 행에있는 진술을 나타내는 것은 아무것도 찾을 수 없습니다. 이유를 아는 사람이 있습니까?

나는 (소스에서 컴파일 된) 3.1 및 3.2에서 모두 테스트 된 debian 2.6.32를 사용하고 있습니다.

#include <stddef.h> 
#include <stdio.h> 
#include <clang-c/Index.h> 

enum CXChildVisitResult visit_fn(CXCursor cr, CXCursor parent, 
     CXClientData client_data) { 

    unsigned depth; 
    unsigned line, column, offset; 
    enum CXCursorKind kind; 
    CXSourceRange extent; 
    CXSourceLocation start, end; 
    CXString kind_spelling, filename; 
    CXFile file; 

    depth = (unsigned)client_data; 

    // print cursor kind 
    kind = clang_getCursorKind(cr); 
    kind_spelling = clang_getCursorKindSpelling(kind); 
    fprintf(stdout, "%*s%s at", depth, " ", clang_getCString(kind_spelling)); 
    clang_disposeString(kind_spelling); 

    // get extent 
    extent = clang_getCursorExtent(cr); 
    start = clang_getRangeStart(extent); 
    end = clang_getRangeEnd(extent); 

    // print start position 
    clang_getExpansionLocation(start, &file, &line, &column, &offset); 
    filename = clang_getFileName(file); 
    fprintf(stdout, " %s (%u, %u) to", clang_getCString(filename), line, 
      column); 
    clang_disposeString(filename); 

    // print end position 
    clang_getExpansionLocation(end, &file, &line, &column, &offset); 
    fprintf(stdout, " (%u, %u)\n", line, column); 

    // recursive 
    clang_visitChildren(cr, visit_fn, (CXClientData)(depth + 1)); 

    return CXChildVisit_Continue; 

} 

int main(int argc, const char * const *argv) { 
    CXIndex Index = clang_createIndex(0, 0); 
    CXTranslationUnit TU = clang_parseTranslationUnit(Index, NULL, 
      argv, argc, 0, 0, CXTranslationUnit_DetailedPreprocessingRecord); 

    clang_visitChildren(clang_getTranslationUnitCursor(TU), 
      visit_fn, 0); 
    clang_disposeTranslationUnit(TU); 
    clang_disposeIndex(Index); 

    return 0; 
} 

업데이트 : 여기

는 프로그램 parse_ast.c입니다

이 문제는 헤더 파일 stddef.h와 누락으로 인해, 그것은 libclang의 메일 목록에 대답 것 http://clang-developers.42468.n3.nabble.com/libclang-missing-some-statements-in-the-AST-td4029641.html

답변

4

clang_parseTranslationUnit()에 의해 생성 된 진단 확인 - 오류가 발생하더라도 AST가 생성되지만 의미있는 것으로 보장 될 수는 없습니다.

#include 행을 주석 처리하면 컴파일 오류가 발생하지만 사용자의 것과 닮은 AST가 생성되었습니다 (특히 17 행이 누락 되었음). 그러므로 나는 당신의 헤더에 문제가있는 가정

(int 등) size_tssize_t에 대한 형식 정의와 #include 라인 교체는 write()의 암시 적 선언에 대한 컴파일 경고에 나 섰으나 AST 라인 (17)

포함 진단 파일에서 밝혀야하는 파일입니다. 진단은 예 :

for (unsigned I = 0, N = clang_getNumDiagnostics(TU); I != N; ++I) { 
    CXDiagnostic Diag = clang_getDiagnostic(TU, I); 
    CXString String = clang_formatDiagnostic(Diag, clang_defaultDiagnosticDisplayOptions()); 
    fprintf(stderr, "%s\n", clang_getCString(String)); 
    clang_disposeString(String); 
} 
+0

죄송합니다. 문제를 해결하는 것을 잊었습니다. 대답은 libclang의 maillist http://clang-developers.42468.n3.nabble.com/libclang-missing-some-statements-in-the-AST-td4029641.html에서 찾을 수 있습니다. – jayven

0

내가 구문 분석 및 C 코드를 최적화 할 수 libclang를 사용하지만 코드를 C 소스 파일을 구문 분석하고있어 내가 예를

void OCTS_C_TimerMiliseconds_reset_Timers(OCTS_outC_C_TimerMiliseconds_Timers *outC) 
{ 
    outC->init = kcg_true; 
    /* 1 */ OCTS_Sign_INT_reset_Math(&outC->_1_Context_1); 
    /* 2 */ OCTS_Sign_INT_reset_Math(&outC->Context_2); 
    /* 1 */ OCTS_FallingEdge_reset_Edge(&outC->Context_1); 
} 

를 들어 CompoundStmt

내부의 CXCursor_BinaryOperator를 참조 할수 없어 결과는 다음과 같습니다.

FunctionDecl at s.cpp (10, 1) to (17, 2) OCTS_C_TimerMiliseconds_reset_Timers 
ParmDecl at s.cpp (11, 3) to (11, 44) outC 
TypeRef at s.cpp (11, 3) to (11, 38) OCTS_outC_C_TimerMiliseconds_Timers 
CompoundStmt at s.cpp (12, 1) to (17, 2)