clang can't parse my .h file standalone

一曲冷凌霜 提交于 2021-02-07 03:00:53

问题


I'm using python binding of libclang but I think this problem is caused by libclang not by python binding.

I have a header object.h

#ifndef OBJECT_H
#define OBJECT_H

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

#endif

And a implementation object.cpp

#include "object.h"

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

If I visit AST of the translation unit of object.h, the last AST node is VAR_DECL class Object and that's it. It won't visit public:... part. If I use clang to check syntax directly is would complain about my header file is wrong.

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

If I use clang to dump ast of object.cpp, I won't have that error.

$ 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'

It seems like clang combine object.h object.cpp together then do the parsing. If that's so, how do I get the ast node of Object in thrid line of object.cpp int Object::run() {? Is there a ast node for that?

It also confuses me a lot like when I visit the run() method in object.cpp, it will say current location is in object.cpp but the extent is in object.h. What does the extent mean exactly? Any easier tutorial documents other than libclang API document?


回答1:


Clang doesn't know that you have C++ code in your .h file. By default, it treats a .h file as plain C. When you run clang on your .cpp file, it knows that it's parsing C++.

There are two ways to fix this.

  1. Tell clang what language is in the file using the -x flag:

    clang -x c++ -Xclang -ast-dump -fsyntax-only object/object.h
    
  2. Rename your file to use a .hh or .hpp suffix. These suffixes tell clang to assume the file contains C++ code.

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

    If you rename your header file, you'll need to change your #include statement to match.



来源:https://stackoverflow.com/questions/19413156/clang-cant-parse-my-h-file-standalone

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!