forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			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/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/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 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``:
 | |
| 
 | |
| .. code-block:: console
 | |
| 
 | |
|  (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 :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.
 |