Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ignore missing headers with clang AST parser

I'm on Windows, using MSVC to compile my project, but I need clang for its neat AST parser, which allow me to write a little code generator.
Problem is, clang cannot parse MSVC headers (a very-well known and understandable problem).

I tried two options :

  1. I include MSVC header folder, parsing the built-in headers included in my code will end-up leading to a fatal error at some point, preventing me from parsing the parts I want correctly.
  2. What I did before is simply not provide any built-in headers and forward declare the types I needed. It worked fine and somehow it doesn't anymore with latest Clang. I don't really know if the parser policy on missing header changed, but it is causing complete failure every time something like <string> is included and not much get parsed.

I am using the python bindings (libclang), but I would consider switching to C/C++ API if there would be a solution there.

Is there anyway I can alter this behavior and make clang continue parsing even when some headers are not found ?

like image 713
N0vember Avatar asked Oct 07 '15 13:10

N0vember


People also ask

Should I use clang for C++ AST parser?

If you like this project, consider supporting me. If you're writing a tool that needs access to the C++ AST (i.e. documentation generator, reflection library, …), your only option apart from writing your own parser is to use clang . It offers three interfaces for tools, but the only one that really works for standalone applications is libclang .

How do I find the system header search in Clang?

As most other compilers clang provides some command line flags to control system header search explicitly. Most important of these is -isystem, which adds a directory to system include search path. Best way to ensure clangd can find your system includes is by putting the directories to be searched into your compile flags via -isystem.

Where does clangd get its headers?

These headers are usually provided either by a custom toolchain, which might be part of the repository, or directly via system installed libraries. Clangd itself only ships with its own built-in headers, because they are tied to the version of clang embedded in clangd. The rest (including C++ STL) must be provided by your system.

How to enable cppast in C++11?

TODO, refer to documentation comments in header file. The library can be used as CMake subdirectory, download it and call add_subdirectory (path/to/cppast), then link to the cppast target and enable C++11 or higher. The parser needs libclang and the clang++ binary, at least version 4.0.0.


2 Answers

Use SetSuppressIncludeNotFoundError. Took me an hour to find! You can imagine how glad I was to find it!

https://clang.llvm.org/doxygen/classclang_1_1Preprocessor.html#ac7bafe67fc32e41460855b39d20ff6af

like image 57
Martin Avatar answered Oct 17 '22 19:10

Martin


One way to ignore the errors due to missing headers is to set SetSuppressIncludeNotFoundError to true in your definition of ASTFrontendAction. An example for the same is given below.

{
public:
    virtual std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(
        clang::CompilerInstance &Compiler, llvm::StringRef InFile)
    {
        Compiler.getPreprocessor().SetSuppressIncludeNotFoundError(true);
        return std::unique_ptr<clang::ASTConsumer>(
            new CustomASTConsumer(&Compiler.getASTContext()));
    }
};

For a complete example using ASTFrontendAction, please visit at https://clang.llvm.org/docs/RAVFrontendAction.html

like image 37
Shivam Kumar Avatar answered Oct 17 '22 18:10

Shivam Kumar