Clang-Include-Fixer — Extra Clang Tools 3.9 documentation

# Extra Clang Tools 3.9 documentation

## Clang-Include-Fixer

Contents

- Clang-Include-Fixer
  - Setup
    - Creating a Symbol Index From a Compilation Database
    - Integrate with Vim
  - How it Works

One of the major nuisances of C++ compared to other languages is the manual management of `#include` directives in any file. clang-include-fixer addresses one aspect of this problem by providing an automated way of adding `#include` directives for missing symbols in one translation unit.

## Setup

To use clang-include-fixer two databases are required. Both can be generated with existing tools.

- Compilation database. Contains the compiler commands for any given file in a project and can be generated by CMake, see How To Setup Tooling For LLVM.
- Symbol index. Contains all symbol information in a project to match a given identifier to a header file.

Ideally both databases (`compile_commands.json` and `find_all_symbols_db.yaml`) are linked into the root of the source tree they correspond to. Then the clang-include-fixer can automatically pick them up if called with a source file from that tree. Note that by default `compile_commands.json` as generated by CMake does not include header files, so only implementation files can be handled by tools.

### Creating a Symbol Index From a Compilation Database

The include fixer contains find-all-symbols, a tool to create a symbol database in YAML format from a compilation database by parsing all source files listed in it. The following list of commands shows how to set up a database for LLVM, any project built by CMake should follow similar steps.

    $ cd path/to/llvm-build
    $ ninja find-all-symbols // build find-all-symbols tool.
    $ ninja clang-include-fixer // build clang-include-fixer tool.
    $ ls compile_commands.json # Make sure compile_commands.json exists.
      compile_commands.json
    $ path/to/llvm/source/tools/clang/tools/extra/include-fixer/find-all-symbols/tool/run-find-all-symbols.py
      ... wait as clang indexes the code base ...
    $ ln -s $PWD/find_all_symbols_db.yaml path/to/llvm/source/ # Link database into the source tree.
    $ ln -s $PWD/compile_commands.json path/to/llvm/source/ # Also link compilation database if it's not there already.
    $ cd path/to/llvm/source
    $ /path/to/clang-include-fixer -db=yaml path/to/file/with/missing/include.cpp
      Added #include "foo.h"

### Integrate with Vim

To run clang-include-fixer on a potentially unsaved buffer in Vim. Add the following key binding to your `.vimrc`:

    map ,cf :pyf path/to/llvm/source/tools/clang/tools/extra/include-fixer/tool/clang-include-fixer.py<cr>

This enables clang-include-fixer for NORMAL and VISUAL mode. Change `,cf` to another binding if you need clang-include-fixer on a different key.

Make sure vim can find clang-include-fixer:

- Add the path to clang-include-fixer to the PATH environment variable.
- Or set `g:clang_include_fixer_path` in vimrc: `let g:clang_include_fixer_path=path/to/clang-include-fixer`

You can customize the number of headers being shown by setting `let g:clang_include_fixer_maximum_suggested_headers=5`

See `clang-include-fixer.py` for more details.

## How it Works

To get the most information out of clang at parse time, clang-include-fixer runs in tandem with the parse and receives callbacks from Clang’s semantic analysis. In particular it reuses the existing support for typo corrections. Whenever Clang tries to correct a potential typo it emits a callback to the include fixer which then looks for a corresponding file. At this point rich lookup information is still available, which is not available in the AST at a later stage.

The identifier that should be typo corrected is then sent to the database, if a header file is returned it is added as an include directive at the top of the file.

Currently clang-include-fixer only inserts a single include at a time to avoid getting caught in follow-up errors. If multiple #include additions are desired the program can be rerun until a fix-point is reached.