156 lines
6.4 KiB
ReStructuredText
156 lines
6.4 KiB
ReStructuredText
===================
|
|
Clang-Include-Fixer
|
|
===================
|
|
|
|
.. contents::
|
|
|
|
One of the major nuisances of C++ compared to other languages is the manual
|
|
management of ``#include`` directives in any file.
|
|
:program:`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``, :program:`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 :program:`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 :program:`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.
|
|
|
|
.. _How To Setup Tooling For LLVM: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
|
|
|
|
Creating a Symbol Index From a Compilation Database
|
|
---------------------------------------------------
|
|
|
|
The include fixer contains :program:`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.
|
|
|
|
.. code-block:: console
|
|
|
|
$ 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/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``:
|
|
|
|
.. code-block:: console
|
|
|
|
noremap <leader>cf :pyf path/to/llvm/source/tools/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
|
|
<http://vim.wikia.com/wiki/Mapping_keys_in_Vim_-_Tutorial_(Part_3)#Map_leader>`_
|
|
is a reference to a specific key defined by the mapleader variable and is bound
|
|
to backslash by default.
|
|
|
|
Make sure vim can find :program:`clang-include-fixer`:
|
|
|
|
- Add the path to :program:`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 sysmbol 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``:
|
|
|
|
.. code-block:: console
|
|
|
|
(add-to-list 'load-path "path/to/llvm/source/tools/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 :program:`clang-include-fixer`:
|
|
|
|
- Either add the parent directory of :program:`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,
|
|
:program:`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 :program:`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.
|