libclang:缺少AST中的一些语句? [英] libclang: missing some statements in the AST?

查看:402
本文介绍了libclang:缺少AST中的一些语句?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个测试程序(parse_ast.c)来解析ac源文件(tt.c),看看libclang是如何工作的,输出是AST的层次结构:

I've wrote a test program (parse_ast.c) to parse a c source file (tt.c) to see how libclang works, the output is the hierarchical structure of the AST:

这里是测试文件:

Here is the test file:

/* 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)

我们可以看到三个函数(direct_write在第7行/ indirect_write在第11行/ main在第15行)在AST中,但我找不到任何代表第12行和第17行的语句。有人知道原因吗?

We can see that the three functions (direct_write at line 7/indirect_write at line 11/main at line 15) are there, most statements can be found in the AST, but i can not find anything that are representing the statements in line 12 and line 17. Does anyone know the reason?

我在debian 2.6。 32挤压,在clang 3.1和3.2(从源代码编译)上测试。

I'm on debian 2.6.32 squeeze, tested both on clang 3.1 and 3.2 (compiled from source).

这里是程序parse_ast.c:

Here is the program 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

the problem is due to missing a header file stddef.h, it's answered in libclang's mail list http://clang-developers.42468.n3.nabble.com/libclang-missing-some-statements-in-the-AST-td4029641.html

推荐答案

检查 clang_parseTranslationUnit code> - 即使遇到错误,也会生成AST,但显然不能保证有意义。

Check the diagnostics generated by clang_parseTranslationUnit() - even if errors are encountered, an AST is generated, but clearly it can't be guaranteed to be meaningful.

我发现注释掉 #include 行导致编译错误,但生成了类似于您的AST(具体来说,缺少第17行)。

I found that commenting out the #include lines resulted in compilation errors, but an AST was generated which resembled yours (specifically, line 17 was missing).

使用 size_t ssize_t #include $ c>( int )导致了关于 write()的隐式声明的编译警告,但AST包含第17行。

Replacing the #include lines with typedefs for size_t and ssize_t (as int) resulted in a compilation warning about the implicit declaration of write(), but the AST included line 17.

因此,我假设你的头文件有一个问题,诊断应该显示。
诊断可以通过例如

Hence I assume there's a problem in your header files, which the diagnostics should reveal. Diagnostics can be retrieved by e.g.

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

这篇关于libclang:缺少AST中的一些语句?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆