Add custom markdownlint config and update docs to be markdownlint clean

This commit is contained in:
Scott Ramsby 2018-05-25 14:12:20 -07:00 committed by Kim Gräsman
parent e8066f0032
commit d1babfe532
8 changed files with 121 additions and 165 deletions

7
.markdownlint.json Normal file
View File

@ -0,0 +1,7 @@
{
"default": true,
"MD013": false,
"MD014": false,
"MD026": false,
"MD038": false
}

View File

@ -1,7 +1,6 @@
## Instructions for Developers ##
# Instructions for Developers #
### Submitting Patches ###
## Submitting Patches ##
We welcome patches and rely on your contributions to make IWYU smarter.
@ -9,8 +8,7 @@ Use GitHub's [pull request system](https://github.com/include-what-you-use/inclu
It's usually a good idea to run ideas by the [IWYU mailing list](http://groups.google.com/group/include-what-you-use) to get general agreement on directions before you start hacking.
### Running the Tests ###
## Running the Tests ##
If fixing a bug in clang, please add a test to the test suite! You can create a file called `whatever.cc` (_not_ .cpp), and, if necessary, `whatever.h`, and `whatever-<extension>.h`. You may be able to get away without adding any `.h` files, and just including `direct.h` -- see, for instance, `tests/remove_fwd_decl_when_including.cc`.
@ -36,27 +34,25 @@ When fixing `fix_includes.py`, add a test case to `fix_includes_test.py` and run
python fix_includes_test.py
### Debugging ###
## Debugging ##
It's possible to run include-what-you-use in `gdb`, to debug that way. Another useful tool -- especially in combination with `gdb` -- is to get the verbose include-what-you-use output. See `iwyu_output.h` for a description of the verbose levels. Level 7 is very verbose -- it dumps basically the entire AST as it's being traversed, along with IWYU decisions made as it goes -- but very useful for that:
env IWYU_VERBOSE=7 make -k CXX=/path/to/llvm/Debug+Asserts/bin/include-what-you-use 2>&1 > /tmp/iwyu.verbose
### A Quick Tour of the Codebase ###
## A Quick Tour of the Codebase ##
The codebase is strewn with TODOs of known problems, and also language constructs that aren't adequately tested yet. So there's plenty to do! Here's a brief guide through the codebase:
* `iwyu.cc`: the main file, it includes the logic for deciding when a symbol has been 'used', and whether it's a full use (definition required) or forward-declare use (only a declaration required). It also includes the logic for following uses through template instantiations.
* `iwyu_driver.cc`: responsible for creating and configuring a Clang compiler from command-line arguments.
* `iwyu_output.cc`: the file that translates from 'uses' into IWYU violations. This has the logic for deciding if a use is covered by an existing `#include` (or is a built-in). It also, as the name suggests, prints the IWYU output.
* `iwyu_preprocessor.cc`: handles the preprocessor directives, the `#includes` and `#ifdefs`, to construct the existing include-tree. This is obviously essential for include-what-you-use analysis. This file also handles the IWYU pragma-comments.
* `iwyu_include_picker.cc`: this finds canonical `#includes`, handling private->public mappings (like `bits/stl_vector.h` -> `vector`) and symbols with multiple possible #includes (like `NULL`). Additional mappings are maintained in a set of .imp files separately, for easier per-platform/-toolchain customization.
* `iwyu_cache.cc`: holds the cache of instantiated templates (may hold other cached info later). This is data that is expensive to compute and may be used more than once.
* `iwyu_globals.cc`: holds various global variables. We used to think globals were bad, until we saw how much having this file simplified the code...
* `iwyu_*_util(s).h` and `.cc`: utility functions of various types. The most interesting, perhaps, is `iwyu_ast_util.h`, which has routines that make it easier to navigate and analyze the clang AST. There are also some STL helpers, string helpers, filesystem helpers, etc.
* `iwyu_verrs.cc`: debug logging for IWYU.
* `port.h`: shim header for various non-portable constructs.
* `iwyu_getopt.cc`: portability shim for GNU `getopt(_long)`. Custom `getopt(_long)` implementation for Windows.
* `fix_includes.py`: the helper script that edits a file based on the IWYU recommendations.
* `iwyu.cc`: the main file, it includes the logic for deciding when a symbol has been 'used', and whether it's a full use (definition required) or forward-declare use (only a declaration required). It also includes the logic for following uses through template instantiations.
* `iwyu_driver.cc`: responsible for creating and configuring a Clang compiler from command-line arguments.
* `iwyu_output.cc`: the file that translates from 'uses' into IWYU violations. This has the logic for deciding if a use is covered by an existing `#include` (or is a built-in). It also, as the name suggests, prints the IWYU output.
* `iwyu_preprocessor.cc`: handles the preprocessor directives, the `#includes` and `#ifdefs`, to construct the existing include-tree. This is obviously essential for include-what-you-use analysis. This file also handles the IWYU pragma-comments.
* `iwyu_include_picker.cc`: this finds canonical `#includes`, handling private->public mappings (like `bits/stl_vector.h` -> `vector`) and symbols with multiple possible #includes (like `NULL`). Additional mappings are maintained in a set of .imp files separately, for easier per-platform/-toolchain customization.
* `iwyu_cache.cc`: holds the cache of instantiated templates (may hold other cached info later). This is data that is expensive to compute and may be used more than once.
* `iwyu_globals.cc`: holds various global variables. We used to think globals were bad, until we saw how much having this file simplified the code...
* `iwyu_*_util(s).h` and `.cc`: utility functions of various types. The most interesting, perhaps, is `iwyu_ast_util.h`, which has routines that make it easier to navigate and analyze the clang AST. There are also some STL helpers, string helpers, filesystem helpers, etc.
* `iwyu_verrs.cc`: debug logging for IWYU.
* `port.h`: shim header for various non-portable constructs.
* `iwyu_getopt.cc`: portability shim for GNU `getopt(_long)`. Custom `getopt(_long)` implementation for Windows.
* `fix_includes.py`: the helper script that edits a file based on the IWYU recommendations.

View File

@ -2,8 +2,7 @@
[![Build Status](https://travis-ci.org/include-what-you-use/include-what-you-use.svg?branch=master)](https://travis-ci.org/include-what-you-use/include-what-you-use)
For more in-depth documentation, see http://github.com/include-what-you-use/include-what-you-use/tree/master/docs.
For more in-depth documentation, see [docs](docs).
## Instructions for Users ##
@ -11,14 +10,12 @@ For more in-depth documentation, see http://github.com/include-what-you-use/incl
This puts us in a state where every file includes the headers it needs to declare the symbols that it uses. When every file includes what it uses, then it is possible to edit any file and remove unused headers, without fear of accidentally breaking the upwards dependencies of that file. It also becomes easy to automatically track and update dependencies in the source code.
### CAVEAT ###
This is alpha quality software -- at best (as of February 2011). It was written to work specifically in the Google source tree, and may make assumptions, or have gaps, that are immediately and embarrassingly evident in other types of code. For instance, we only run this on C++ code, not C or Objective C. Even for Google code, the tool still makes a lot of mistakes.
While we work to get IWYU quality up, we will be stinting new features, and will prioritize reported bugs along with the many existing, known bugs. The best chance of getting a problem fixed is to submit a patch that fixes it (along with a unittest case that verifies the fix)!
### How to Build ###
Include-what-you-use makes heavy use of Clang internals, and will occasionally break when Clang is updated. Usually such discrepancies are detected by build bot and fixed promptly. The master branch follows Clang trunk.
@ -29,48 +26,47 @@ We assume you already have compiled LLVM and Clang libraries on your system, eit
> NOTE: If you use the Debian/Ubuntu packaging available from <https://apt.llvm.org>, you'll need the following packages installed:
>
> - `llvm-<version>-dev`
> - `libclang-<version>-dev`
> - `clang-<version>`
> * `llvm-<version>-dev`
> * `libclang-<version>-dev`
> * `clang-<version>`
>
> Packaging for other platforms will likely be subtly different.
To set up an environment for building:
* Create a directory for IWYU development, e.g. `iwyu`
* Create a directory for IWYU development, e.g. `iwyu`
* Clone the IWYU Git repo:
* Clone the IWYU Git repo:
iwyu$ git clone https://github.com/include-what-you-use/include-what-you-use.git
iwyu$ git clone https://github.com/include-what-you-use/include-what-you-use.git
* Presumably, you'll be building IWYU with a released version of LLVM and Clang, so check out the corresponding branch. For example, if you have Clang 6.0 installed, use the `clang_6.0` branch. IWYU `master` tracks LLVM & Clang trunk:
* Presumably, you'll be building IWYU with a released version of LLVM and Clang, so check out the corresponding branch. For example, if you have Clang 6.0 installed, use the `clang_6.0` branch. IWYU `master` tracks LLVM & Clang trunk:
iwyu$ cd include-what-you-use
iwyu/include-what-you-use$ git checkout clang_6.0
iwyu$ cd include-what-you-use
iwyu/include-what-you-use$ git checkout clang_6.0
* Create a build root and use CMake to generate a build system linked with LLVM/Clang prebuilts:
* Create a build root and use CMake to generate a build system linked with LLVM/Clang prebuilts:
# This example uses the Makefile generator, but anything should work.
iwyu/include-what-you-use$ cd ..
iwyu$ mkdir build && cd build
# This example uses the Makefile generator, but anything should work.
iwyu/include-what-you-use$ cd ..
iwyu$ mkdir build && cd build
# For IWYU 0.10/Clang 6 and earlier
iwyu/build$ cmake -G "Unix Makefiles" -DIWYU_LLVM_ROOT_PATH=/usr/lib/llvm-6.0 ../include-what-you-use
# For IWYU 0.10/Clang 6 and earlier
iwyu/build$ cmake -G "Unix Makefiles" -DIWYU_LLVM_ROOT_PATH=/usr/lib/llvm-6.0 ../include-what-you-use
# For IWYU 0.11/Clang 7 and later
iwyu/build$ cmake -G "Unix Makefiles" -DCMAKE_PREFIX_PATH=/usr/lib/llvm-7 ../include-what-you-use
# For IWYU 0.11/Clang 7 and later
iwyu/build$ cmake -G "Unix Makefiles" -DCMAKE_PREFIX_PATH=/usr/lib/llvm-7 ../include-what-you-use
or, if you have a local LLVM and Clang build tree, you can specify that as `CMAKE_PREFIX_PATH` for IWYU 0.11 and later:
or, if you have a local LLVM and Clang build tree, you can specify that as `CMAKE_PREFIX_PATH` for IWYU 0.11 and later:
iwyu/build$ cmake -G "Unix Makefiles" -DCMAKE_PREFIX_PATH=/llvm-trunk/build ../include-what-you-use
iwyu/build$ cmake -G "Unix Makefiles" -DCMAKE_PREFIX_PATH=/llvm-trunk/build ../include-what-you-use
* Once CMake has generated a build system, you can invoke it directly from `build`, e.g.
* Once CMake has generated a build system, you can invoke it directly from `build`, e.g.
iwyu/build$ make
iwyu/build$ make
Instructions for building Clang are available at <https://clang.llvm.org/get_started.html>.
### How to Install ###
If you're building IWYU out-of-tree or installing pre-built binaries, you need to make sure it can find Clang built-in headers (`stdarg.h` and friends.)
@ -83,12 +79,10 @@ So for IWYU to function correctly, you need to copy in the Clang headers at a go
This weirdness is tracked in [issue 100](https://github.com/include-what-you-use/include-what-you-use/issues/100), hopefully we can make this more transparent over time.
### How to Run ###
The original design was built for Make, but a number of alternative run modes have come up over the years.
#### Plugging into Make ####
The easiest way to run IWYU over your codebase is to run
@ -103,7 +97,6 @@ or
Include-what-you-use only analyzes .cc (or .cpp) files built by `make`, along with their corresponding .h files. If your project has a .h file with no corresponding .cc file, IWYU will ignore it unless you use the `--check_also` switch to add it for analysis together with a .cc file.
#### Using with CMake ####
CMake has grown native support for IWYU as of version 3.3. See [their documentation](https://cmake.org/cmake/help/latest/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.html) for CMake-side details.
@ -124,7 +117,6 @@ The option appears to be separately supported for both C and C++, so use `CMAKE_
Note that with Microsoft's Visual C++ compiler, IWYU needs the `--driver-mode=cl` argument to understand the MSVC options from CMake.
#### Using with a compilation database ####
The `iwyu_tool.py` script predates the native CMake support, and works off the [compilation database format](https://clang.llvm.org/docs/JSONCompilationDatabase.html). For example, CMake generates such a database named `compile_commands.json` with the `CMAKE_EXPORT_COMPILE_COMMANDS` option enabled.
@ -145,7 +137,6 @@ Unless a source filename is provided, all files in the project will be analyzed.
See `iwyu_tool.py --help` for more options.
#### Applying fixes ####
We also include a tool that automatically fixes up your source files based on the IWYU recommendations. This is also alpha-quality software! Here's how to use it (requires python):
@ -155,15 +146,14 @@ We also include a tool that automatically fixes up your source files based on th
If you don't like the way `fix_includes.py` munges your `#include` lines, you can control its behavior via flags. `fix_includes.py --help` will give a full list, but these are some common ones:
* `-b`: Put blank lines between system and Google includes
* `--nocomments`: Don't add the 'why' comments next to includes
* `-b`: Put blank lines between system and Google includes
* `--nocomments`: Don't add the 'why' comments next to includes
### How to Correct IWYU Mistakes ###
* If `fix_includes.py` has removed an `#include` you actually need, add it back in with the comment '`// IWYU pragma: keep`' at the end of the `#include` line. Note that the comment is case-sensitive.
* If `fix_includes.py` has added an `#include` you don't need, just take it out. We hope to come up with a more permanent way of fixing later.
* If `fix_includes.py` has wrongly added or removed a forward-declare, just fix it up manually.
* If `fix_includes.py` has suggested a private header file (such as `<bits/stl_vector.h>`) instead of the proper public header file (`<vector>`), you can fix this by inserting a specially crafted comment near top of the private file (assuming you can write to it): '`// IWYU pragma: private, include "the/public/file.h"`'.
* If `fix_includes.py` has removed an `#include` you actually need, add it back in with the comment '`// IWYU pragma: keep`' at the end of the `#include` line. Note that the comment is case-sensitive.
* If `fix_includes.py` has added an `#include` you don't need, just take it out. We hope to come up with a more permanent way of fixing later.
* If `fix_includes.py` has wrongly added or removed a forward-declare, just fix it up manually.
* If `fix_includes.py` has suggested a private header file (such as `<bits/stl_vector.h>`) instead of the proper public header file (`<vector>`), you can fix this by inserting a specially crafted comment near top of the private file (assuming you can write to it): '`// IWYU pragma: private, include "the/public/file.h"`'.
Current IWYU pragmas are described in [IWYUPragmas](docs/IWYUPragmas.md).

View File

@ -1,4 +1,4 @@
## IWYU Mappings ##
# IWYU Mappings #
One of the difficult problems for IWYU is distinguishing between which header contains a symbol definition and which header is the actual documented header to include for that symbol.
@ -12,13 +12,11 @@ However, many mappings are toolchain- and version-dependent. Symbol homes and `#
Any mappings outside of the default set can therefore be specified as external *mapping files*.
### Default Mappings ###
## Default Mappings ##
IWYU's default mappings are hard-coded in `iwyu_include_picker.cc`, and are very GCC-centric. There are both symbol- and include mappings for GNU libstdc++ and libc.
### Mapping Files ###
## Mapping Files ##
The mapping files conventionally use the `.imp` file extension, for "Iwyu MaPping" (terrible, I know). They use a [JSON](http://json.org/) meta-format with the following general form:
@ -29,9 +27,9 @@ The mapping files conventionally use the `.imp` file extension, for "Iwyu MaPpin
Directives can be one of the literal strings:
* `include`
* `symbol`
* `ref`
* `include`
* `symbol`
* `ref`
and data varies between the directives, see below.
@ -39,13 +37,12 @@ Note that you can mix directives of different kinds within the same mapping file
IWYU uses LLVM's YAML/JSON parser to interpret the mapping files, and it has some idiosyncrasies:
* Comments use a Python-style `#` prefix, not Javascript's `//`
* Single-word strings can be left un-quoted
* Comments use a Python-style `#` prefix, not Javascript's `//`
* Single-word strings can be left un-quoted
If the YAML parser is ever made more rigorous, it might be wise not to lean on non-standard behavior, so apart from comment style, try to keep mapping files in line with the JSON spec.
#### Include Mappings ####
### Include Mappings ###
The `include` directive specifies a mapping between two include names (relative path, including quotes or angle brackets.)
@ -53,10 +50,10 @@ This is typically used to map from a private implementation detail header to a p
Data for this directive is a list of four strings containing:
* The include name to map from
* The visibility of the include name to map from
* The include name to map to
* The visibility of the include name to map to
* The include name to map from
* The visibility of the include name to map from
* The include name to map to
* The visibility of the include name to map to
For example;
@ -70,17 +67,16 @@ Include mappings support a special wildcard syntax for the first entry:
The `@` prefix is a signal that the remaining content is a regex, and can be used to re-map a whole subdirectory of private headers to a public facade header.
#### Symbol Mappings ####
### Symbol Mappings ###
The `symbol` directive maps from a qualified symbol name to its authoritative header.
Data for this directive is a list of four strings containing:
* The symbol name to map from
* The visibility of the symbol
* The include name to map to
* The visibility of the include name to map to
* The symbol name to map from
* The visibility of the symbol
* The include name to map to
* The visibility of the include name to map to
For example;
@ -90,8 +86,7 @@ The symbol visibility is largely redundant -- it must always be `private`. It is
Unlike `include`, `symbol` directives do not support the `@`-prefixed regex syntax in the first entry. Track the [following bug](https://github.com/include-what-you-use/include-what-you-use/issues/233) for updates.
#### Mapping Refs ####
### Mapping Refs ###
The last kind of directive, `ref`, is used to pull in another mapping file, much like the C preprocessor's `#include` directive. Data for this directive is a single string: the filename to include.
@ -102,8 +97,7 @@ For example;
The rationale for the `ref` directive was to make it easier to compose project-specific mappings from a set of library-oriented mapping files. For example, IWYU might ship with mapping files for [Boost](http://www.boost.org), the SCL, various C standard libraries, the Windows API, the [Poco Library](http://pocoproject.org), etc. Depending on what your specific project uses, you could easily create an aggregate mapping file with refs to the relevant mappings.
#### Specifying Mapping Files ####
### Specifying Mapping Files ###
Mapping files are specified on the command-line using the `--mapping_file` switch:

View File

@ -1,23 +1,21 @@
## IWYU pragmas ##
# IWYU pragmas #
IWYU pragmas are used to give IWYU information that isn't obvious from the source code, such as how different files relate to each other and which includes to never remove or include.
All pragmas start with `// IWYU pragma: ` or `/* IWYU pragma: `. They are case-sensitive and spaces are significant.
### IWYU pragma: keep ###
## IWYU pragma: keep ##
This pragma applies to a single `#include` directive or forward declaration. It forces IWYU to keep an inclusion even if it is deemed unnecessary.
main.cc:
#include <vector> // IWYU pragma: keep
class ForwardDeclaration; // IWYU pragma: keep
In this case, `std::vector` isn't used, so `<vector>` would normally be discarded, but the pragma instructs IWYU to leave it. Similarly the class `ForwardDeclaration` isn't used but is kept because of the pragma on it.
### IWYU pragma: export ###
## IWYU pragma: export ##
This pragma applies to a single `#include` directive. It says that the current file is to be considered the provider of any symbol from the included file.
@ -36,8 +34,7 @@ Here, since `detail/constants.h` and `detail/types.h` have both been exported, I
In contrast, since `<vector>` has not been exported from `facade.h`, it will be suggested as an additional include.
### IWYU pragma: begin_exports/end_exports ###
## IWYU pragma: begin_exports/end_exports ##
This pragma applies to a set of `#include` directives. It declares that the including file is to be considered the provider of any symbol from these included files. This is the same as decorating every `#include` directive with `IWYU pragma: export`.
@ -45,12 +42,11 @@ This pragma applies to a set of `#include` directives. It declares that the incl
// IWYU pragma: begin_exports
#include "detail/constants.h"
#include "detail/types.h"
// IWYU pragma: end_exports
// IWYU pragma: end_exports
#include <vector> // don't export stuff from <vector>
### IWYU pragma: private ###
## IWYU pragma: private ##
This pragma applies to the current header file. It says that any symbol from this file will be provided by another, optionally named, file.
@ -77,8 +73,7 @@ Using the type `Private` in `main.cc` will cause IWYU to suggest that you includ
Using the type `Private2` in `main.cc` will cause IWYU to suggest that you include `private2.h`, but will also result in a warning that there's no public header for `private2.h`.
### IWYU pragma: no_include ###
## IWYU pragma: no_include ##
This pragma applies to the current source file. It declares that the named file should not be suggested for inclusion by IWYU.
@ -101,8 +96,7 @@ This is useful when you know a symbol definition is already available via some u
The `no_include` pragma is somewhat similar to `private`, but is employed at point of use rather than at point of declaration.
### IWYU pragma: no_forward_declare ###
## IWYU pragma: no_forward_declare ##
This pragma applies to the current source file. It says that the named symbol should not be suggested for forward-declaration by IWYU.
@ -123,8 +117,7 @@ IWYU would normally suggest forward-declaring `Public` directly in `main.cc`, bu
This is useful when you know a symbol declaration is already available in a source file via some unrelated header and you want to preserve that implicit dependency, or when IWYU does not correctly understand that the definition is necessary.
### IWYU pragma: friend ###
## IWYU pragma: friend ##
This pragma applies to the current header file. It says that any file matching the given regular expression will be considered a friend, and is allowed to include this header even if it's private. Conceptually similar to `friend` in C++.
@ -147,8 +140,7 @@ If the expression contains spaces, it must be enclosed in quotes.
AlsoPrivate p;
### IWYU pragma: associated ###
## IWYU pragma: associated ##
Associated headers have special significance in IWYU, they're analyzed together with their .cpp file to give an optimal result for the whole component.
@ -169,8 +161,7 @@ You can explicitly mark an arbitrary `#include` directive as denoting the associ
You can mark multiple `#include` directives as associated and they will all be considered as such.
### Which pragma should I use? ###
## Which pragma should I use? ##
Ideally, IWYU should be smart enough to understand your intentions (and intentions of the authors of libraries you use), so the first answer should always be: none.
@ -178,13 +169,13 @@ In practice, intentions are not so clear -- it might be ambiguous whether an `#i
IWYU pragmas have some overlap, so it can sometimes be hard to choose one over the other. Here's a guide based on how I understand them at the moment:
* Use `IWYU pragma: keep` to force IWYU to keep any `#include` directive that would be discarded under its normal policies.
* Use `IWYU pragma: export` to tell IWYU that one header serves as the provider for all symbols in another, included header (e.g. facade headers). Use `IWYU pragma: begin_exports/end_exports` for a whole group of included headers.
* Use `IWYU pragma: no_include` to tell IWYU that the file in which the pragma is defined should never `#include` a specific header (the header may already be included via some other `#include`.)
* Use `IWYU pragma: no_forward_declare` to tell IWYU that the file in which the pragma is defined should never forward-declare a specific symbol (a forward declaration may already be available via some other `#include`.)
* Use `IWYU pragma: private` to tell IWYU that the header in which the pragma is defined is private, and should not be included directly.
* Use `IWYU pragma: private, include "public.h"` to tell IWYU that the header in which the pragma is defined is private, and `public.h` should always be included instead.
* Use `IWYU pragma: friend ".*favorites.*"` to override `IWYU pragma: private` selectively, so that a set of files identified by a regex can include the file even if it's private.
* Use `IWYU pragma: keep` to force IWYU to keep any `#include` directive that would be discarded under its normal policies.
* Use `IWYU pragma: export` to tell IWYU that one header serves as the provider for all symbols in another, included header (e.g. facade headers). Use `IWYU pragma: begin_exports/end_exports` for a whole group of included headers.
* Use `IWYU pragma: no_include` to tell IWYU that the file in which the pragma is defined should never `#include` a specific header (the header may already be included via some other `#include`.)
* Use `IWYU pragma: no_forward_declare` to tell IWYU that the file in which the pragma is defined should never forward-declare a specific symbol (a forward declaration may already be available via some other `#include`.)
* Use `IWYU pragma: private` to tell IWYU that the header in which the pragma is defined is private, and should not be included directly.
* Use `IWYU pragma: private, include "public.h"` to tell IWYU that the header in which the pragma is defined is private, and `public.h` should always be included instead.
* Use `IWYU pragma: friend ".*favorites.*"` to override `IWYU pragma: private` selectively, so that a set of files identified by a regex can include the file even if it's private.
The pragmas come in three different classes;

View File

@ -1,4 +1,4 @@
## What Is a Use? ##
# What Is a Use? #
(*Disclaimer:* the information here is accurate as of 12 May 2011, when it was written. Specifics of IWYU's policy, and even philosophy, may have changed since then. We'll try to remember to update this file as that happens, but may occasionally forget. The further we are from May 2011, the more you should take the below with a grain of salt.)
@ -21,8 +21,7 @@ Does `bar.cc` "use" `std::ostream`, such that it should `#include <ostream>`? Y
But IWYU doesn't (at least, modulo bugs). This is because of its attempt to analyze "author intent".
### Author Intent ###
## Author Intent ##
If code has `typedef Foo MyTypedef`, and you write `MyTypedef var;`, you are using `MyTypedef`, but are you also using `Foo`? The answer depends on the _intent_ of the person who wrote the typedef.
@ -47,8 +46,7 @@ Another case where author intent turns up is in function return types. Consider
If you write `GetSingletonObject()->methodOnFoo()`, are you "using" `Foo::methodOnFoo`, such that you should `#include "foo.h"`? Or are you supposed to be able to operate on the results of `GetSingletonObject` without needing to include the definition of the returned type? The answer is: it depends on the author intent. Sometimes the author is willing to provide the definition of the return type, sometimes it is not.
#### Re-Exporting ####
### Re-Exporting ###
When the author of a file is providing a definition of a symbol from somewhere else, we say that the file is "re-exporting" that symbol. In the first `OutputEmitter` example, we say that `foo.h` is re-exporting `ostream`. As a result, people who `#include "foo.h"` get a definition of `ostream` along for free, even if they don't directly `#include <ostream>` themselves. Another way of thinking about it is: if file A re-exports symbol B, we can pretend that A defines B, even if it doesn't.
@ -56,8 +54,7 @@ When the author of a file is providing a definition of a symbol from somewhere e
A more accurate include-what-you-use rule is this: "If you use a symbol, you must either `#include` the definition of the symbol, or `#include` a file that re-exports the symbol."
### Manual re-export identifiers ###
## Manual re-export identifiers ##
You can mark that one file is re-exporting symbols from another via an IWYU pragma in your source code:
@ -67,13 +64,11 @@ This tells IWYU that if some other file uses symbols defined in `private.h`, the
The full list of IWYU pragmas is defined in [IWYUPragmas.md](IWYUPragmas.md).
### Automatic re-export ###
## Automatic re-export ##
In certain situations, IWYU will decide that one file is exporting a symbol from another even without the use of a pragma. These are places where the author intent is usually to re-export, such as with the `typedef` example above. In each of these cases, a simple technique can be used to override IWYU's decision to re-export.
#### Automatic re-export: typedefs ####
### Automatic re-export: typedefs ###
If you write
@ -81,9 +76,9 @@ If you write
IWYU has to decide whether your file should re-export `Foo` or not. Here is how it gauges author intent:
* If you (the typedef author), directly `#include` the definition of the underlying type, then IWYU assumes you mean to re-export it.
* If you (the typedef author), explicitly provide a forward-declare of the underlying type, but do not directly `#include` its definition, then IWYU assumes you do not mean to re-export it.
* Otherwise, IWYU assumes you do not mean to re-export it.
* If you (the typedef author), directly `#include` the definition of the underlying type, then IWYU assumes you mean to re-export it.
* If you (the typedef author), explicitly provide a forward-declare of the underlying type, but do not directly `#include` its definition, then IWYU assumes you do not mean to re-export it.
* Otherwise, IWYU assumes you do not mean to re-export it.
For example:
@ -100,8 +95,7 @@ If IWYU says you intend to re-export the underlying type, then nobody who uses y
IWYU supports this in its analysis. If you are using `Typedef1` in your code and `#include "foo.h"` anyway, IWYU will suggest you remove it, since you are getting the definition of `Foo` via the typedef.
#### Automatic re-export: Function return values ####
### Automatic re-export: Function return values ###
The same rule applies with the return value in a function declaration:
@ -142,8 +136,7 @@ Here is an example of the rule in action:
In this case, IWYU will say that `baz.cc` does not need to `#include "foo.h"`, since `bar.h` re-exports it.
#### Automatic re-export: Conversion constructors ####
### Automatic re-export: Conversion constructors ###
Consider the following code:

View File

@ -1,23 +1,20 @@
## Why Include What You Use? ##
# Why Include What You Use? #
Are there any concrete benefits to a strict include-what-you-use policy? We like to think so.
### Faster Compiles ###
## Faster Compiles ##
Every .h file you bring in when compiling a source file lengthens the time to compile, as the bytes have to be read, preprocessed, and parsed. If you're not actually using a .h file, you remove that cost. With template code, where entire instantiations have to be in .h files, this can be hundreds of thousands of bytes of code. In one case at Google, running include-what-you-use over a .cc file improved its compile time by 30%.
Here, the main benefit of include-what-you-use comes from the flip side: "don't include what you don't use."
### Fewer Recompiles ###
## Fewer Recompiles ##
Many build tools, such as `make`, provide a mechanism for automatically figuring out what .h files a .cc file depends on. These mechanisms typically look at `#include` lines. When unnecessary `#includes` are listed, the build system is more likely to recompile in cases where it's not necessary.
Again, the main advantage here is from "don't include what you don't use."
### Allow Refactoring ###
## Allow Refactoring ##
Suppose you refactor `foo.h` so it no longer uses vectors. You'd like to remove `#include <vector>` from `foo.h`, to reduce compile time -- template class files such as `vector` can include a lot of code. But can you? In theory yes, but in practice maybe not: some other file may be #including you and using vectors, and depending (probably unknowingly) on your `#include <vector>` to compile. Your refactor could break code far away from you.
@ -25,8 +22,7 @@ This is most compelling for a very large codebase (such as Google's). In a smal
Here, it's the actual 'include what you use' policy that saves the day. If everyone who uses vector is #including `<vector>` themselves, then you can remove `<vector>` without fear of breaking anything.
### Self-documentation ###
## Self-documentation ##
When you can trust the `#include` lines to accurately reflect what is used in the file, you can use them to help you understand the code. Looking at them, in itself, can help you understand what this file needs in order to do its work. If you use the optional 'commenting' feature of `fix_includes.py`, you can see what symbols -- what functions and classes -- are used by this code. It's like a pared-down version of doxygen markup, but totally automated and present where the code is (rather than in a separate web browser).
@ -34,15 +30,13 @@ The 'commented' `#include` lines can also make it simpler to match function call
(The downside, of course, is the comments can get out of date as the code changes, so unless you run IWYU often, you still have to take the comments with a grain of salt. Nothing is free. :-) )
### Dependency Cutting ###
## Dependency Cutting ##
Again, this makes the most sense for large code-bases. Suppose your binaries are larger than you would expect, and upon closer examination use symbols that seem totally irrelevant. Where do they come from? Why are they there? With include-what-you-use, you can easily determine this by seeing who includes the files that define these symbols: those includers, and those alone, are responsible for the use.
Once you know where a symbol is used in your binary, you can see how practical it is to remove that use, perhaps by breaking up the relevant .h files into two parts, and fixing up all callers. Again it's IWYU to the rescue: with include-what-you-use, figuring out the callers that need fixing is easy.
### Why Forward-Declare? ###
## Why Forward-Declare? ##
Include-what-you-use tries very hard to figure out when a forward-declare can be used instead of an `#include` (IWYU would be about 90% less code if it didn't bother with trying to forward-declare).

View File

@ -1,11 +1,10 @@
## Why Include What You Use Is Difficult ##
# Why Include What You Use Is Difficult #
This section is informational, for folks who are wondering why include-what-you-use requires so much code and yet still has so many errors.
Include-what-you-use has the most problems with templates and macros. If your code doesn't use either, IWYU will probably do great. And, you're probably not actually programming in C++...
### Use Versus Forward Declare ###
## Use Versus Forward Declare ##
Include-what-you-use has to be able to tell when a symbol is being used in a way that you can forward-declare it. Otherwise, if you wrote
@ -30,8 +29,7 @@ But that's not enough: when instantiating the templates, we need to keep track o
In this case, the caller of `MyFunc` is not using the full type of `MyClass`, because the template parameter is only used as a pointer. On the other hand, the file that defines `MyFunc` is using the full type information for `MyClass`. The end result is that the caller can forward-declare `MyClass`, but the file defining `MyFunc` has to `#include "myclass.h"`.
### Handling Template Arguments ###
## Handling Template Arguments ##
Even figuring out what types are 'used' with a template can be difficult. Consider the following two declarations:
@ -54,8 +52,7 @@ Even normal template arguments can be confusing. Consider this templated functio
and you call `MyFunc(FunctionReturningAFunctionPointer())`. What types are being used where, in this case?
### Who is Responsible for Dependent Template Types? ###
## Who is Responsible for Dependent Template Types? ##
If you say `vector<MyClass> v;`, it's clear that you, and not `vector.h` are responsible for the use of `MyClass`, even though all the functions that use `MyClass` are defined in `vector.h`. (OK, technically, these functions are not "defined" in a particular location, they're instantiated from template methods written in `vector.h`, but for us it works out the same.)
@ -79,8 +76,7 @@ In C++, `strchr` is a templatized function (different impls for `char*` and `con
As you can imagine, distinguishing all these cases is extremely difficult. To get it exactly right would require re-implementing C++'s (byzantine) lookup rules, which we have not yet tackled.
### Template Template Types ###
## Template Template Types ##
Let's say you have a function
@ -90,8 +86,7 @@ Let's say you have a function
And you call `MyFunc<hash_set>`. Who is responsible for the 'use' of `hash<string>`, and thus needs to `#include "myhash.h"`? I think it has to be the caller, even if the caller never uses the `string` type in its file at all. This is rather counter-intuitive. Luckily, it's also rather rare.
### Typedefs ###
## Typedefs ##
Suppose you `#include` a file `"foo.h"` that has typedef `hash_map<Foo, Bar> MyMap;`. And you have this code:
@ -108,13 +103,11 @@ The compiler sees this as syntactic sugar for `find<hash_map<Foo, Bar, hash<Foo>
Not only is the template argument `hash_map` instead of `MyMap`, it includes all the default template arguments, with no indication they're default arguments. All the tricks we used above to intelligently ignore default template arguments are worthless here. We have to jump through lots of hoops so this code doesn't require you to `#include` not only `<hash_map>`, but `<alloc>` and `<utility>` as well.
### Macros ###
## Macros ##
It's no surprise macros cause a huge problem for include-what-you-use. Basically, all the problems of templates also apply to macros, but worse: with templates you can analyze the uninstantiated template, but with macros, you can't analyze the uninstantiated macro -- it likely doesn't even parse cleanly in isolation. As a result, we have very few tools to distinguish when the author of a macro is responsible for a symbol used in a macro, and when the caller of the macro is responsible.
### Includes with Side Effects ###
## Includes with Side Effects ##
While not a major problem, this indicates the myriad "gotchas" that exist around include-what-you-use: removing an `#include` and replacing it with a forward-declare may be dangerous even if no symbols are fully used from the `#include`. Consider the following code:
@ -136,8 +129,7 @@ Another case is a header file like this:
We might think we can remove an `#include` of `foo.h` and replace it by `#include "module_writer.h"`, but that is likely to break the build if `module_writer.h` requires `MODULE_NAME` be defined. Since my file doesn't participate in this dependency at all, it won't even notice it. IWYU needs to keep track of dependencies between files it's not even trying to analyze!
### Private Includes ###
## Private Includes ##
Suppose you write `vector<int> v;`. You are using vector, and thus have to `#include <vector>`. Even this seemingly easy case is difficult, because vector isn't actually defined in `<vector>`; it's defined in `<bits/stl_vector.h>`. The C++ standard library has hundreds of private files that users are not supposed to `#include` directly. Third party libraries have hundreds more. There's no general way to distinguish private from public headers; we have to manually construct the proper mapping.
@ -145,8 +137,7 @@ In the future, we hope to provide a way for users to annotate if a file is publi
The mappings themselves can be ambiguous. For instance, `NULL` is provided by many files, including `stddef.h`, `stdlib.h`, and more. If you use `NULL`, what header file should IWYU suggest? We have rules to try to minimize the number of `#includes` you have to add; it can get rather involved.
### Unparsed Code ###
## Unparsed Code ##
Conditional `#includes` are a problem for IWYU when the condition is false:
@ -158,14 +149,14 @@ Conditional `#includes` are a problem for IWYU when the condition is false:
void StartProcess() {
#if defined(LOG_VERBOSE)
LogVerbose("Starting process");
LogVerbose("Starting process");
#endif
...
}
If you're running IWYU without that preprocessor definition set, it has no way of telling if `verbose_logger.h` is a necessary `#include` or not.
### Placing New Includes and Forward-Declares ###
## Placing New Includes and Forward-Declares ##
Figuring out where to insert new `#includes` and forward-declares is a complex problem of its own (one that is the responsibility of `fix_includes.py`). In general, we want to put new `#includes` with existing `#includes`. But the existing `#includes` may be broken up into sections, either because of conditional `#includes` (with `#ifdefs`), or macros (such as `#define __GNU_SOURCE`), or for other reasons. Some forward-declares may need to come early in the file, and some may prefer to come later (after we're in an appropriate namespace, for instance).