Benjamin Kramer | bfcab59 | 2016-05-11 09:44:10 +0000 | [diff] [blame] | 1 | =================== |
| 2 | Clang-Include-Fixer |
| 3 | =================== |
| 4 | |
| 5 | .. contents:: |
| 6 | |
| 7 | One of the major nuisances of C++ compared to other languages is the manual |
| 8 | management of ``#include`` directives in any file. |
| 9 | :program:`clang-include-fixer` addresses one aspect of this problem by providing |
| 10 | an automated way of adding ``#include`` directives for missing symbols in one |
| 11 | translation unit. |
| 12 | |
Haojian Wu | 499375c | 2016-07-27 13:17:16 +0000 | [diff] [blame] | 13 | While inserting missing ``#include``, :program:`clang-include-fixer` adds |
| 14 | missing namespace qualifiers to all instances of an unidentified symbol if |
| 15 | the symbol is missing some prefix namespace qualifiers. |
| 16 | |
Benjamin Kramer | bfcab59 | 2016-05-11 09:44:10 +0000 | [diff] [blame] | 17 | Setup |
| 18 | ===== |
| 19 | |
| 20 | To use :program:`clang-include-fixer` two databases are required. Both can be |
| 21 | generated with existing tools. |
| 22 | |
| 23 | - Compilation database. Contains the compiler commands for any given file in a |
| 24 | project and can be generated by CMake, see `How To Setup Tooling For LLVM`_. |
Benjamin Kramer | a3d8233 | 2016-05-13 09:27:54 +0000 | [diff] [blame] | 25 | - Symbol index. Contains all symbol information in a project to match a given |
Benjamin Kramer | bfcab59 | 2016-05-11 09:44:10 +0000 | [diff] [blame] | 26 | identifier to a header file. |
| 27 | |
| 28 | Ideally both databases (``compile_commands.json`` and |
| 29 | ``find_all_symbols_db.yaml``) are linked into the root of the source tree they |
| 30 | correspond to. Then the :program:`clang-include-fixer` can automatically pick |
| 31 | them up if called with a source file from that tree. Note that by default |
| 32 | ``compile_commands.json`` as generated by CMake does not include header files, |
| 33 | so only implementation files can be handled by tools. |
| 34 | |
| 35 | .. _How To Setup Tooling For LLVM: http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html |
| 36 | |
Benjamin Kramer | a3d8233 | 2016-05-13 09:27:54 +0000 | [diff] [blame] | 37 | Creating a Symbol Index From a Compilation Database |
Haojian Wu | 499375c | 2016-07-27 13:17:16 +0000 | [diff] [blame] | 38 | --------------------------------------------------- |
Benjamin Kramer | bfcab59 | 2016-05-11 09:44:10 +0000 | [diff] [blame] | 39 | |
| 40 | The include fixer contains :program:`find-all-symbols`, a tool to create a |
| 41 | symbol database in YAML format from a compilation database by parsing all |
| 42 | source files listed in it. The following list of commands shows how to set up a |
| 43 | database for LLVM, any project built by CMake should follow similar steps. |
| 44 | |
| 45 | .. code-block:: console |
| 46 | |
| 47 | $ cd path/to/llvm-build |
Haojian Wu | e64cee8 | 2016-06-07 07:50:48 +0000 | [diff] [blame] | 48 | $ ninja find-all-symbols // build find-all-symbols tool. |
| 49 | $ ninja clang-include-fixer // build clang-include-fixer tool. |
Benjamin Kramer | bfcab59 | 2016-05-11 09:44:10 +0000 | [diff] [blame] | 50 | $ ls compile_commands.json # Make sure compile_commands.json exists. |
| 51 | compile_commands.json |
| 52 | $ path/to/llvm/source/tools/clang/tools/extra/include-fixer/find-all-symbols/tool/run-find-all-symbols.py |
| 53 | ... wait as clang indexes the code base ... |
| 54 | $ ln -s $PWD/find_all_symbols_db.yaml path/to/llvm/source/ # Link database into the source tree. |
| 55 | $ ln -s $PWD/compile_commands.json path/to/llvm/source/ # Also link compilation database if it's not there already. |
| 56 | $ cd path/to/llvm/source |
Haojian Wu | e64cee8 | 2016-06-07 07:50:48 +0000 | [diff] [blame] | 57 | $ /path/to/clang-include-fixer -db=yaml path/to/file/with/missing/include.cpp |
Benjamin Kramer | bfcab59 | 2016-05-11 09:44:10 +0000 | [diff] [blame] | 58 | Added #include "foo.h" |
| 59 | |
Eric Liu | c7f3b10 | 2016-05-18 14:10:16 +0000 | [diff] [blame] | 60 | Integrate with Vim |
Haojian Wu | 499375c | 2016-07-27 13:17:16 +0000 | [diff] [blame] | 61 | ------------------ |
Eric Liu | c7f3b10 | 2016-05-18 14:10:16 +0000 | [diff] [blame] | 62 | To run `clang-include-fixer` on a potentially unsaved buffer in Vim. Add the |
| 63 | following key binding to your ``.vimrc``: |
| 64 | |
| 65 | .. code-block:: console |
| 66 | |
Kirill Bobyrev | c4018e2 | 2016-07-27 14:23:47 +0000 | [diff] [blame] | 67 | noremap <leader>cf :pyf path/to/llvm/source/tools/clang/tools/extra/include-fixer/tool/clang-include-fixer.py<cr> |
Eric Liu | c7f3b10 | 2016-05-18 14:10:16 +0000 | [diff] [blame] | 68 | |
Kirill Bobyrev | c4018e2 | 2016-07-27 14:23:47 +0000 | [diff] [blame] | 69 | This enables `clang-include-fixer` for NORMAL and VISUAL mode. Change |
Alexander Kornienko | 053826f | 2016-08-02 20:29:47 +0000 | [diff] [blame] | 70 | `<leader>cf` to another binding if you need clang-include-fixer on a different |
| 71 | key. The `<leader> key |
| 72 | <http://vim.wikia.com/wiki/Mapping_keys_in_Vim_-_Tutorial_(Part_3)#Map_leader>`_ |
Kirill Bobyrev | 5c339ec | 2016-07-27 14:26:03 +0000 | [diff] [blame] | 73 | is a reference to a specific key defined by the mapleader variable and is bound |
Kirill Bobyrev | c4018e2 | 2016-07-27 14:23:47 +0000 | [diff] [blame] | 74 | to backslash by default. |
Eric Liu | c7f3b10 | 2016-05-18 14:10:16 +0000 | [diff] [blame] | 75 | |
Haojian Wu | e64cee8 | 2016-06-07 07:50:48 +0000 | [diff] [blame] | 76 | Make sure vim can find :program:`clang-include-fixer`: |
| 77 | |
| 78 | - Add the path to :program:`clang-include-fixer` to the PATH environment variable. |
| 79 | - Or set ``g:clang_include_fixer_path`` in vimrc: ``let g:clang_include_fixer_path=path/to/clang-include-fixer`` |
| 80 | |
| 81 | You can customize the number of headers being shown by setting |
| 82 | ``let g:clang_include_fixer_maximum_suggested_headers=5`` |
| 83 | |
Haojian Wu | 54f8efa | 2016-09-27 10:43:38 +0000 | [diff] [blame] | 84 | Customized settings in `.vimrc`: |
| 85 | |
| 86 | - ``let g:clang_include_fixer_path = "clang-include-fixer"`` |
| 87 | |
| 88 | Set clang-include-fixer binary file path. |
| 89 | |
| 90 | - ``let g:clang_include_fixer_maximum_suggested_headers = 3`` |
| 91 | |
| 92 | Set the maximum number of ``#includes`` to show. Default is 3. |
| 93 | |
| 94 | - ``let g:clang_include_fixer_increment_num = 5`` |
| 95 | |
| 96 | Set the increment number of #includes to show every time when pressing ``m``. |
| 97 | Default is 5. |
| 98 | |
| 99 | - ``let g:clang_include_fixer_jump_to_include = 0`` |
| 100 | |
| 101 | Set to 1 if you want to jump to the new inserted ``#include`` line. Default is |
| 102 | 0. |
| 103 | |
| 104 | - ``let g:clang_include_fixer_query_mode = 0`` |
| 105 | |
| 106 | Set to 1 if you want to insert ``#include`` for the symbol under the cursor. |
| 107 | Default is 0. Compared to normal mode, this mode won't parse the source file |
| 108 | and only search the sysmbol from database, which is faster than normal mode. |
| 109 | |
Eric Liu | c7f3b10 | 2016-05-18 14:10:16 +0000 | [diff] [blame] | 110 | See ``clang-include-fixer.py`` for more details. |
| 111 | |
Benjamin Kramer | 57d070e | 2016-07-27 10:11:06 +0000 | [diff] [blame] | 112 | Integrate with Emacs |
| 113 | -------------------- |
| 114 | To run `clang-include-fixer` on a potentially unsaved buffer in Emacs. |
Haojian Wu | 54f8efa | 2016-09-27 10:43:38 +0000 | [diff] [blame] | 115 | Ensure that Emacs finds ``clang-include-fixer.el`` by adding the directory |
| 116 | containing the file to the ``load-path`` and requiring the `clang-include-fixer` |
| 117 | in your ``.emacs``: |
Benjamin Kramer | 57d070e | 2016-07-27 10:11:06 +0000 | [diff] [blame] | 118 | |
| 119 | .. code-block:: console |
| 120 | |
| 121 | (add-to-list 'load-path "path/to/llvm/source/tools/clang/tools/extra/include-fixer/tool/" |
| 122 | (require 'clang-include-fixer) |
| 123 | |
Haojian Wu | 0e1a50e | 2016-10-05 10:04:13 +0000 | [diff] [blame] | 124 | Within Emacs the tool can be invoked with the command |
Malcolm Parsons | 5831a00 | 2016-11-17 14:26:45 +0000 | [diff] [blame] | 125 | ``M-x clang-include-fixer``. This will insert the header that defines the |
Haojian Wu | 0e1a50e | 2016-10-05 10:04:13 +0000 | [diff] [blame] | 126 | first undefined symbol; if there is more than one header that would define the |
| 127 | symbol, the user is prompted to select one. |
| 128 | |
| 129 | To include the header that defines the symbol at point, run |
| 130 | ``M-x clang-include-fixer-at-point``. |
Benjamin Kramer | 57d070e | 2016-07-27 10:11:06 +0000 | [diff] [blame] | 131 | |
| 132 | Make sure Emacs can find :program:`clang-include-fixer`: |
| 133 | |
Haojian Wu | 0e1a50e | 2016-10-05 10:04:13 +0000 | [diff] [blame] | 134 | - Either add the parent directory of :program:`clang-include-fixer` to the PATH |
| 135 | environment variable, or customize the Emacs user option |
| 136 | ``clang-include-fixer-executable`` to point to the file name of the program. |
Benjamin Kramer | 57d070e | 2016-07-27 10:11:06 +0000 | [diff] [blame] | 137 | |
Benjamin Kramer | bfcab59 | 2016-05-11 09:44:10 +0000 | [diff] [blame] | 138 | How it Works |
| 139 | ============ |
| 140 | |
Eugene Zelenko | 3ed5011 | 2016-08-10 22:00:49 +0000 | [diff] [blame] | 141 | To get the most information out of Clang at parse time, |
Benjamin Kramer | bfcab59 | 2016-05-11 09:44:10 +0000 | [diff] [blame] | 142 | :program:`clang-include-fixer` runs in tandem with the parse and receives |
| 143 | callbacks from Clang's semantic analysis. In particular it reuses the existing |
| 144 | support for typo corrections. Whenever Clang tries to correct a potential typo |
| 145 | it emits a callback to the include fixer which then looks for a corresponding |
| 146 | file. At this point rich lookup information is still available, which is not |
| 147 | available in the AST at a later stage. |
| 148 | |
| 149 | The identifier that should be typo corrected is then sent to the database, if a |
| 150 | header file is returned it is added as an include directive at the top of the |
| 151 | file. |
| 152 | |
| 153 | Currently :program:`clang-include-fixer` only inserts a single include at a |
| 154 | time to avoid getting caught in follow-up errors. If multiple `#include` |
| 155 | additions are desired the program can be rerun until a fix-point is reached. |