Clang cannot parse my .h file

I am using python binding for libclang, but I think this problem is caused by libclang and not python binding.

I have an object.h header

 #ifndef OBJECT_H #define OBJECT_H class Object { public: int run(); }; #endif 

And the implementation of object.cpp

 #include "object.h" int Object::run() { int a = 0; return a*a; } 

If I visit AST object.h translation object.h , the last AST node will be a VAR_DECL class Object and that is it. He will not visit the public:... part public:... If I use clang to check the syntax directly, I will complain about my header file.

 $ 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 object.cpp , I will not have this 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 that clang combines object.h object.cpp and then does the parsing. If so, how do I get ast node of Object in the string line object.cpp int Object::run() { ? Is there an ast node for this?

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

+6
source share
1 answer

Clang does not know that you have C ++ code in your .h file. By default, it treats the .h file as normal C. When you run clang in your .cpp file, it knows that it parses C ++.

There are two ways to fix this.

  • Say what language is in the file using the -x flag:

     clang -x c++ -Xclang -ast-dump -fsyntax-only object/object.h 
  • Rename the file to use the suffix .hh or .hpp . These suffixes tell clang to assume that 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 will need to modify the #include statement to match.

+8
source

Source: https://habr.com/ru/post/956116/


All Articles