Library interface to the C++ AST — parse source files, synthesize entities, get documentation comments and generate code.
Sponsored by Embarcadero C++Builder.
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. However, libclang has various limitations and does not expose the entire AST.
So there is no feasible option — except for this library. It was originally a part of the standardese documentation generator, but has been extracted into an independent library.
See this blog post for more information about the motiviation and design.
libclang-parserfor a list;
See tool/main.cpp for a simple application of the library that prints the AST.
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.
clang++ binary will be found in
PATH and in the same directory as the program that is being executed.
Note: The project will drop support for older LLVM versions very soon; this minimizes the workaround code when the
libclang API catches up.
The CMake code requires
llvm-config, you may need to install
llvm and not just
clang to get it (e.g. on ArchLinux).
llvm-config is in your path and the version is compatible, it should just work out of the box.
Else you need to set the CMake variable
LLVM_CONFIG_BINARY to the proper path.
If you don't have a proper clang version installed, it can also be downloaded.
For that you need to set
This is the name of the operating system used on the LLVM pre-built binary archive, e.g.
x86_64-linux-gnu-ubuntu-16.10 for Ubuntu 16.10.
You can also set
LLVM_DOWNLOAD_URL to a custom url, to download a specific version or from a mirror.
If you don't have
llvm-config, you need to pass the locations explictly.
For that set the option
LLVM_VERSION_EXPLICIT to the version you're using,
LIBCLANG_LIBRARY to the location of the libclang library file,
LIBCLANG_INCLUDE_DIR to the directory where the header files are located (so they can be included with
CLANG_BINARY to the full path of the
The other dependencies like type_safe are installed automatically with git submodules, if they're not installed already.
If you run into any issues with the installation, please report them.
Similar to the above instructions for
cppast, there are a couple extra requirements for Windows.
The LLVM team does not currently distribute
llvm-config.exe as part of the release binaries, so the only way to get it is through manual compilation or from 3rd parties. To prevent version mismatches, it's best to compile LLVM, libclang, and
llvm-config.exe from source to ensure proper version matching. However, this is a non-trivial task, requiring a lot of time. The easiest way to work with LLVM and
llvm-config.exe is to leverage the Chocolatey
llvm package, and then compile the
llvm-config.exe tool as a standalone binary.
choco install llvm
git clone https://github.com/llvm/llvm-project
git checkout llvmorg-7.0.1
cd llvm-project && mkdir build && cd buildto prep the build environment.
cmake -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_TARGETS_TO_BUILD="X86" -G "Visual Studio 15 2017" -Thost=x64 ..\llvm
LLVM.slnsolution, and set the build type to be "Release".
llvm-config.exe, it should return with it's help message.
cppast based project, if you run into issues with cmake not finding libclang, set
LIBCLANG_LIBRARY to be
C:/Program Files/LLVM/lib in your CMakeLists.txt file.
There are three class hierarchies that represent the AST:
cpp_entity: This is the base class for all C++ entities, i.e. declarations/definitions or things like
static_assert()and function parameters;
cpp_type: This is the base class for the C++ type hierachy. It is used in the
underlying_type(). Derived classes are, for example,
cpp_expression: This is the base class for all C++ expressions. It is used in the
default_value()as expression. Derived classes are currently only
In order to parse a C++ source file, you need an implementation of
The library provides one,
libclang_parser, but you could also write one yourself.
Parsing is as simple as calling the
parse() member function passing it three things:
cpp_entity_index: This is only required to resolve cross-references in the AST (i.e. if you want to get the
cpp_classreferenced in the return type of a
cpp_function); it does not own the entities;
compile_config: It stores the compilation flags used for compiling the file, it needs to match the parser, i.e. use
nullptr on failure and prints diagnostics using a given
diagnostic_logger — note that it will only return
nullptr on fatal parse errors, else it will just skip the one where the error occured.
If everything went succesful, it returns a
std::unique_ptr<cpp_file> which is the top-level AST entity of the current file.
You can then work with it.