Clang-Include-Fixer — Extra Clang Tools 11 documentation

# Extra Clang Tools 11 documentation

## Clang-Include-Fixer

Contents

- Clang-Include-Fixer

  - Setup

    - Creating a Symbol Index From a Compilation Database

    - Integrate with Vim

    - Integrate with Emacs

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

While inserting missing `#include`, clang-include-fixer adds missing namespace qualifiers to all instances of an unidentified symbol if the symbol is missing some prefix namespace qualifiers.

## 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/clang-tools-extra/clang-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`:

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

This enables clang-include-fixer for NORMAL and VISUAL mode. Change <leader>cf to another binding if you need clang-include-fixer on a different key. The <leader> key is a reference to a specific key defined by the mapleader variable and is bound to backslash by default.

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`

Customized settings in .vimrc:

- `let g:clang_include_fixer_path = "clang-include-fixer"`

  Set clang-include-fixer binary file path.

- `let g:clang_include_fixer_maximum_suggested_headers = 3`

  Set the maximum number of `#includes` to show. Default is 3.

- `let g:clang_include_fixer_increment_num = 5`

  Set the increment number of #includes to show every time when pressing `m`. Default is 5.

- `let g:clang_include_fixer_jump_to_include = 0`

  Set to 1 if you want to jump to the new inserted `#include` line. Default is 0.

- `let g:clang_include_fixer_query_mode = 0`

  Set to 1 if you want to insert `#include` for the symbol under the cursor. Default is 0. Compared to normal mode, this mode won’t parse the source file and only search the symbol from database, which is faster than normal mode.

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

### Integrate with Emacs

To run clang-include-fixer on a potentially unsaved buffer in Emacs. Ensure that Emacs finds `clang-include-fixer.el` by adding the directory containing the file to the `load-path` and requiring the clang-include-fixer in your `.emacs`:

    (add-to-list 'load-path "path/to/llvm/source/clang-tools-extra/clang-include-fixer/tool/"
    (require 'clang-include-fixer)

Within Emacs the tool can be invoked with the command `M-x clang-include-fixer`. This will insert the header that defines the first undefined symbol; if there is more than one header that would define the symbol, the user is prompted to select one.

To include the header that defines the symbol at point, run `M-x clang-include-fixer-at-point`.

Make sure Emacs can find clang-include-fixer:

- Either add the parent directory of clang-include-fixer to the PATH environment variable, or customize the Emacs user option `clang-include-fixer-executable` to point to the file name of the program.

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