python调libclang如何打印编译报错与调试信息(采用translation unit的diagnostic)

查询Clang文档,发现是调用C++的clang_getDiagnostic函数接口获取的。同理查询cindex.py发现如下信息:

  ("clang_getDiagnostic",
   [c_object_p, c_uint],
   c_object_p),

其中如下代码引用了:

class TranslationUnit(ClangObject):
    # ... (很多代码) ...
    @property
    def diagnostics(self):
        """
        Return an iterable (and indexable) object containing the diagnostics.
        """
        class DiagIterator(object):
            def __init__(self, tu):
                self.tu = tu

            def __len__(self):
                return int(conf.lib.clang_getNumDiagnostics(self.tu))

            def __getitem__(self, key):
                diag = conf.lib.clang_getDiagnostic(self.tu, key)
                if not diag:
                    raise IndexError
                return Diagnostic(diag)

        return DiagIterator(self)

使用举例:

    code_str = """
#include "tmp.h"
#include "a/b/c.h"

#define int3 int
class ABC{
    public:
        SS s;
        void run() {
            int c = 0;
            auto b = EXIT_CODE_ERR;
        }
};

class APPLE{
    public:
        ABCD abc();
        void run() {
            int a = 0;
            if (a > 1) {
                abc.run();
            } else {
                ;
            }
        }
};

static int fac(int n) {
    int32 a();
    for (a =0; a< 20; a++){
        n += a;
    }
    APPLE apple;
    return (n>1) ? n*fac(n-1) : 1;
}
    """
    idx = Index.create()
    translation_unit = idx.parse('tmp.cpp', args=['-I./',  # tmp.h放在当前python同目录
                                                  '-std=c++11',
                                                  ],
                                 unsaved_files=[('tmp.cpp', code_str)],
                                 options=0x1)
    for diagnostic in translation_unit.diagnostics:
        print(diagnostic)

可打印如下信息:

tmp.cpp:3:10: fatal error: 'a/b/c.h' file not found

注释掉#include "a/b/c.h"后,再次运行打印如下信息:

tmp.cpp:8:9: error: unknown type name 'SS'
tmp.cpp:11:22: error: use of undeclared identifier 'EXIT_CODE_ERR'
tmp.cpp:17:9: error: unknown type name 'ABCD'
tmp.cpp:29:5: error: unknown type name 'int32'
tmp.cpp:29:12: warning: empty parentheses interpreted as a function declaration [-Wvexing-parse]

可以发觉,报错并不是一次性全部暴露出来的,随着一步一步错误处理,深层次的错误才会暴露。只有所有错误都解决了,libclang才能完整解析出正确的C++ AST

上一篇:C# 求高次方程的近似根


下一篇:【VTM10.0】量化之RDOQ技术