5

acソースファイル(tt.c)を解析してlibclangがどのように機能するかを確認するためのテストプログラム(parse_ast.c)を作成しました。出力は、ASTの階層構造です。

テストファイルは次のとおりです。

/* 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;
}

出力は次のようになります。

 ...
 ...
 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)

3つの関数(7行目のdirect_write/11行目のindirect_write/15行目のmain)があり、ほとんどのステートメントはASTにありますが、12行目のステートメントを表すものは見つかりません。 17行目。理由を知っている人はいますか?

私はdebian2.6.32squeezeを使用しており、clang 3.1と3.2(ソースからコンパイル)の両方でテストされています。

プログラムparse_ast.cは次のとおりです。

#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;
}

更新

問題はヘッダーファイルstddef.hが欠落しているためであり、libclangのメールリストhttp://clang-developers.42468.n3.nabble.com/libclang-missing-some-statements-in-the-AST-td4029641で回答されています。 .html

4

2 に答える 2

4

によって生成された診断を確認してくださいclang_parseTranslationUnit()-エラーが発生した場合でも、ASTが生成されますが、明らかに意味があるとは限りません。

行をコメントアウトする#includeとコンパイルエラーが発生することがわかりましたが、あなたに似たASTが生成されました(具体的には、17行目が欠落しています)。

行をand (as )#includeのtypedefに置き換えると、の暗黙の宣言に関するコンパイル警告が発生しましたが、ASTには行17が含まれていました。size_tssize_tintwrite()

したがって、診断で明らかになるはずのヘッダーファイルに問題があると思います。診断は、例えばによって取得することができます

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);
}
于 2013-05-12T09:10:51.430 に答える
0

libclangを使用してcコードを解析および最適化していますが、コードを使用してcソースファイルを解析すると、CompoundStmt内にCXCursor_BinaryOperatorが表示されません。

例えば

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);
} 

結果は次のとおりです。

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)  
于 2014-05-27T14:14:35.417 に答える