7

我正在使用 libclang 的 python 绑定,但我认为这个问题是由 libclang 而不是 python 绑定引起的。

我有一个标题object.h

#ifndef OBJECT_H
#define OBJECT_H

class Object {
public:
  int run();
};

#endif

和一个实现object.cpp

#include "object.h"

int Object::run() {
  int a = 0;
  return a*a;
}

如果我访问 的翻译单元的object.hAST,最后一个 AST 节点就是VAR_DECL class Object这样。它不会访问public:...部分。如果我使用 clang 直接检查语法会抱怨我的头文件是错误的。

$ clang -Xclang -ast-dump -fsyntax-only object/object.h
object/object.h:4:1: error: unknown type name 'class'
class Object {
^
object/object.h:4:13: error: expected ';' after top level declarator
class Object {
            ^
            ;
TranslationUnitDecl 0x7f816102d2d0 <<invalid sloc>>
|-TypedefDecl 0x7f816102d7d0 <<invalid sloc>> __int128_t '__int128'
|-TypedefDecl 0x7f816102d830 <<invalid sloc>> __uint128_t 'unsigned __int128'
|-TypedefDecl 0x7f816102db80 <<invalid sloc>> __builtin_va_list '__va_list_tag [1]'
`-VarDecl 0x7f816102dbf0 <object/object.h:4:1, col:7> Object 'int' invalid
2 errors generated.

如果我使用 clang 转储 ast of object.cpp,则不会出现该错误。

$ clang -Xclang -ast-dump -fsyntax-only object/object.cpp
TranslationUnitDecl 0x7fc6230302d0 <<invalid sloc>>
|-TypedefDecl 0x7fc623030810 <<invalid sloc>> __int128_t '__int128'
|-TypedefDecl 0x7fc623030870 <<invalid sloc>> __uint128_t 'unsigned __int128'
|-TypedefDecl 0x7fc623030c30 <<invalid sloc>> __builtin_va_list '__va_list_tag [1]'
|-CXXRecordDecl 0x7fc623030c80 <object/object.h:4:1, line:7:1> class Object definition
| |-CXXRecordDecl 0x7fc623030d90 <line:4:1, col:7> class Object
| |-AccessSpecDecl 0x7fc623030e20 <line:5:1, col:7> public
| `-CXXMethodDecl 0x7fc623030ea0 <line:6:3, col:11> run 'int (void)'
`-CXXMethodDecl 0x7fc62307be10 parent 0x7fc623030c80 prev 0x7fc623030ea0 <object/object.cpp:3:1, line:6:1> run 'int (void)'
  `-CompoundStmt 0x7fc62307c058 <line:3:19, line:6:1>
    |-DeclStmt 0x7fc62307bf78 <line:4:3, col:12>
    | `-VarDecl 0x7fc62307bf00 <col:3, col:11> a 'int'
    |   `-IntegerLiteral 0x7fc62307bf58 <col:11> 'int' 0
    `-ReturnStmt 0x7fc62307c038 <line:5:3, col:12>
      `-BinaryOperator 0x7fc62307c010 <col:10, col:12> 'int' '*'
        |-ImplicitCastExpr 0x7fc62307bfe0 <col:10> 'int' <LValueToRValue>
        | `-DeclRefExpr 0x7fc62307bf90 <col:10> 'int' lvalue Var 0x7fc62307bf00 'a' 'int'
        `-ImplicitCastExpr 0x7fc62307bff8 <col:12> 'int' <LValueToRValue>
          `-DeclRefExpr 0x7fc62307bfb8 <col:12> 'int' lvalue Var 0x7fc62307bf00 'a' 'int'

似乎clang结合object.h object.cpp在一起然后进行解析。如果是这样,我如何获得Object第三行的 ast 节点object.cpp int Object::run() {?有一个 ast 节点吗?

它也让我很困惑,当我访问run()方法时object.cpp,它会说当前位置在,object.cpp但范围在object.h。程度究竟是什么意思?除了 libclang API 文档之外还有更简单的教程文档吗?

4

1 回答 1

11

Clang 不知道您的.h文件中有 C++ 代码。默认情况下,它将.h文件视为纯 C。当您对.cpp文件运行 clang 时,它知道它正在解析 C++。

有两种方法可以解决此问题。

  1. -x使用标志告诉 clang 文件中的语言是什么:

    clang -x c++ -Xclang -ast-dump -fsyntax-only object/object.h
    
  2. 重命名文件以使用 a.hh.hpp后缀。这些后缀告诉 clang 假设文件包含 C++ 代码。

    mv object/object.h object/object.hpp
    clang -Xclang -ast-dump -fsyntax-only object/object.hpp
    

    如果重命名头文件,则需要更改#include语句以匹配。

于 2013-10-16T20:34:35.440 回答