-
Notifications
You must be signed in to change notification settings - Fork 2
/
README.txt
1288 lines (901 loc) · 48.8 KB
/
README.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
--------------------------------------------------------------------------------
Include What You Use
--------------------------------------------------------------------------------
This README was generated from the Wiki contents at
http://code.google.com/p/include-what-you-use/w/ on 2014-11-30 10:05:01 UTC.
= Instructions for Users =
"Include what you use" means this: for every symbol (type, function, variable,
or macro) that you use in foo.cc (or foo.cpp), either foo.cc or foo.h should
#include a .h file that exports the declaration of that symbol. (Similarly, for
foo_test.cc, either foo_test.cc or foo.h should do the #including.) Obviously
symbols defined in foo.cc itself are excluded from this requirement.
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. See the include-what-you-use Makefile for
instructions on how to keep them in sync.
IWYU, like Clang, does not yet handle some of the non-standard constructs in
Microsoft's STL headers. A discussion on how to use MinGW or Cygwin headers with
IWYU is available on the mailing list.
We support two build configurations: out-of-tree and in-tree.
=== Building out-of-tree ===
In an out-of-tree configuration, we assume you already have compiled LLVM and
Clang headers and libs somewhere on your filesystem, such as via the libclang-
dev package. Out-of-tree builds are only supported with CMake (patches very
welcome for the Make system).
* Create a directory for IWYU development, e.g. iwyu-trunk
* Get the IWYU source code, either from a published tarball or directly from
svn
# Unpack tarball
iwyu-trunk$ tar xfz include-what-you-use-<version>.tar.gz
# or checkout from SVN
iwyu-trunk$ svn co http://include-what-you-use.googlecode.com/svn/trunk/
include-what-you-use
* Create a build root
iwyu-trunk$ mkdir build && cd build
* Run CMake and specify the location of LLVM/Clang prebuilts
# This example uses the Makefile generator,
# but anything should work.
iwyu-trunk/build$ cmake -G "Unix Makefiles" -DLLVM_PATH=/usr/lib/llvm-3.4
../include-what-you-use
* Once CMake has generated a build system, you can invoke it directly from
build, e.g.
iwyu-trunk/build$ make
This configuration is more useful if you want to get IWYU up and running quickly
without building Clang and LLVM from scratch.
=== Building in-tree ===
You will need the Clang and LLVM trees on your system, such as by checking out
their SVN trees (but don't configure or build before you've done the following.)
* Put include-what-you-use in the source tree. Either download the include-
what-you-use tarball and unpack it your /path/to/llvm/tools/clang/tools
directory, or get the project directly from svn:
# Unpack tarball
llvm/tools/clang/tools$ tar xfz include-what-you-use-<version>.tar.gz
# or checkout from SVN
llvm/tools/clang/tools$ svn co http://include-what-you-
use.googlecode.com/svn/trunk/ include-what-you-use
* Edit tools/clang/tools/Makefile and add include-what-you-use to the DIRS
variable
* Edit tools/clang/tools/CMakeLists.txt and add_subdirectory(include-what-you-
use)
* Once this is done, IWYU is recognized and picked up by both autoconf and
CMake workflows as described in the Clang Getting Started guide
This configuration is more useful if you're actively developing IWYU against
Clang trunk.
== 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.)
Clang's default policy is to look in path/to/clang-
executable/../lib/clang/<clang ver>/include. So if Clang 3.5.0 is installed in
/usr/bin, it will search for built-ins in /usr/lib/clang/3.5.0/include.
Clang tools have the same policy by default, so in order for IWYU to analyze any
non-trivial code, it needs to find Clang's built-ins in
path/to/iwyu/../lib/clang/3.5.0/include where 3.5.0 is a stand-in for the
version of Clang your IWYU was built against.
This weirdness is tracked in issue 100, hopefully we can eliminate the manual
patching.
== How to Run ==
The easiest way to run IWYU over your codebase is to run
make -k CXX=/path/to/llvm/Debug+Asserts/bin/include-what-you-use
or
make -k CXX=/path/to/llvm/Release/bin/include-what-you-use
(include-what-you-use always exits with an error code, so the build system knows
it didn't build a .o file. Hence the need for -k.)
We also include, in this directory, 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):
make -k CXX=/path/to/llvm/Debug+Asserts/bin/include-what-you-use >
/tmp/iwyu.out
python fix_includes.py < /tmp/iwyu.out
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
WARNING: 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. include-what-you-use supports the
AddGlobToReportIWYUViolationsFor() function which can be used to indicate other
files to analyze, but it's not currently exposed to the user in any way.
== 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 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 has wrongly added or removed a forward-declare, just fix it
up manually.
* If fix_includes 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"'.
All current IWYU pragmas (as of July 2012) are described in [IWYUPragmas].
= Instructions for Developers =
== Submitting Patches ==
We're still working this part out. For now, you can create patches against svn-
head and submit them as new issues. Probably, we'll move to a scheme where
people can submit patches directly to the SVN repository.
== 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.
To run the iwyu tests, run
python run_iwyu_tests.py
It runs one test for each .cc file in the tests/ directory. (We have additional
tests in more_tests/, but have not yet gotten the testing framework set up for
those tests.) The output can be a bit hard to read, but if a test fails, the
reason why will be listed after the
ERROR:root:Test failed for xxx line.
When fixing fix_includes.py, add a test case to fix_includes_test.py and run
python fix_includes_test.py
== 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 ==
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). Mappings are maintained in a set of
.imp files separately, for easier per-platform/-toolset 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.
= 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 ==
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 ==
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 ==
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.
This is most compelling for a very large codebase (such as Google's). In a
small codebase, it's practical to just compile everything after a refactor like
this, and clean up any errors you see. When your codebase contains hundreds of
thousands of source files, identifying and cleaning up the errors can be a
project in itself. In practice, people are likely to just leave the #include
<vector> line in there, even though it's unnecessary.
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 ==
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).
The 'commented' #include lines can also make it simpler to match function calls
and classes to the files that define them, without depending on a particular
IDE.
(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 ==
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? ==
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).
The reason for this is simple: if you can replace an #include by a forward-
declare, you reduce the code size, speeding up compiles as described above. You
also make it easier to break dependencies: not only do you not depend on that
#include file, you no longer depend on everything it brings in.
There's a cost to forward-declaring as well: you lose the documentation features
mentioned above, that come with #include lines. (A future version of iwyu may
mitigate this problem.) And if a class changes -- for instance, it adds a new
default template argument -- you need to change many callsites, not just one.
It is also easier to accidentally violate the One Definition Rule when all you
expose is the name of a class (via a forward declare) rather than the full
definition (via an #include).
One compromise approach is to use 'forwarding headers', such as <iosfwd>. These
forwarding headers could have comments saying where the definition of each
forward-declared class is. Include-what-you-use does not currently support
forwarding headers, but may in the future.
= 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.
For example, in GCC's libstdc++, std::unique_ptr<T> is defined in
<bits/unique_ptr.h>, but the documented way to get it is to #include <memory>.
Another example is NULL. Its authoritative header is <cstddef>, but for
practical purposes NULL is more of a keyword, and according to the standard it's
acceptable to assume it comes with <cstring>, <clocale>, <cwchar>, <ctime>,
<cstdio> or <cstdlib>. In fact, almost every standard library header pulls in
NULL one way or another, and we probably shouldn't force people to #include
<cstddef>.
To simplify IWYU deployment and command-line interface, many of these mappings
are compiled into the executable. These constitute the _default mappings_.
However, many mappings are toolchain- and version-dependent. Symbol homes and
#include dependencies change between releases of GCC and are dramatically
different for the standard libraries shipped with Microsoft Visual C++. Also,
mappings such as these are usually necessary for third-party libraries (e.g.
Boost, Qt) or even project-local symbols and headers as well.
Any mappings outside of the default set can therefore be specified as external
_mapping files_.
== 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 ==
The mapping files conventionally use the .imp file extension, for "Iwyu
!MaPping" (terrible, I know). They use a JSON meta-format with the following
general form:
[
{ <directive>: <data> },
{ <directive>: <data> }
]
Directives can be one of the literal strings:
* include
* symbol
* ref
and data varies between the directives, see below.
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
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 ===
The include directive specifies a mapping between two include names (relative
path, including quotes or angle brackets.)
This is typically used to map from a private implementation detail header to a
public facade header, such as our <bits/unique_ptr.h> to <memory> example above.
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
For example;
{ include: ["<bits/unique_ptr.h>", "private", "<memory>", "public"] }
Most of the original mappings were generated with shell scripts (as evident from
the embedded comments) so there are several multi-step mappings from one private
header to another, to a third and finally to a public header. This reflects the
#include chain in the actual library headers. A hand-written mapping could be
reduced to one mapping per private header to its corresponding public header.
Include mappings support a special wildcard syntax for the first entry:
{ include: ["@<internal/.*>", "private", "<public>", "public"] }
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 ===
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
For example;
{ symbol: ["NULL", "private", "<cstddef>", "public"] }
The symbol visibility is largely redundant -- it must always be private. It
isn't entirely clear why symbol visibility needs to be specified, and it might
be removed moving forward.
Like include, symbol directives support the @-prefixed regex syntax in the first
entry.
=== 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.
For example;
{ ref: "more.symbols.imp" },
{ ref: "/usr/lib/other.includes.imp" }
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, the SCL, various C standard
libraries, the Windows API, the Poco Library, 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 ===
Mapping files are specified on the command-line using the --mapping_file switch:
$ include-what-you-use -Xiwyu --mapping_file=foo.imp some_file.cc
The switch can be added multiple times to add more than one mapping file.
If the mapping filename is relative, it will be looked up relative to the
current directory.
ref directives are first looked up relative to the current directory and if not
found, relative to the referring mapping file.
= 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 ==
This pragma applies to a single #include statement. It forces IWYU to keep an
inclusion even if it is deemed unnecessary.
main.cc:
#include <vector> // 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.
== IWYU pragma: export ==
This pragma applies to a single #include statement. It says that the current
file is to be considered the provider of any symbol from the included file.
facade.h:
#include "detail/constants.h" // IWYU pragma: export
#include "detail/types.h" // IWYU pragma: export
#include <vector> // don't export stuff from <vector>
main.cc:
#include "facade.h"
// Assuming Thing comes from detail/types.h and MAX_THINGS from
detail/constants.h
std::vector<Thing> things(MAX_THINGS);
Here, since detail/constants.h and detail/types.h have both been exported, IWYU
is happy with the facade.h include for Thing and MAX_THINGS.
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 ==
This pragma applies to a set of #include statements. 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 statement with
IWYU pragma: export.
facade.h:
// IWYU pragma: begin_exports
#include "detail/constants.h"
#include "detail/types.h"
// IWYU pragma: end_exports
#include <vector> // don't export stuff from <vector>
== 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.
private.h:
// IWYU pragma: private, include "public.h"
struct Private {};
private2.h:
// IWYU pragma: private
struct Private2 {};
public.h:
#include "private.h"
#include "private2.h"
main.cc:
#include "private.h"
#include "private2.h"
Private p;
Private2 i;
Using the type Private in main.cc will cause IWYU to suggest that you include
public.h.
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 ==
This pragma applies to the current source file. It declares that the named file
should not be suggested for inclusion by IWYU.
private.h:
struct Private {};
unrelated.h:
#include "private.h"
...
main.cc:
#include "unrelated.h"
// IWYU pragma: no_include "private.h"
Private i;
The use of Private requires including private.h, but due to the no_include
pragma IWYU will not suggest private.h for inclusion. Note also that if you had
included private.h in main.cc, IWYU would suggest that the #include be removed.
This is useful when you know a symbol definition is already available via some
unrelated header, and you want to preserve that implicit dependency.
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 ==
This pragma applies to the current source file. It says that the named symbol
should not be suggested for forward-declaration by IWYU.
public.h:
struct Public {};
unrelated.h:
struct Public;
...
main.cc:
#include "unrelated.h" // declares Public
// IWYU pragma: no_forward_declare Public
Public* i;
IWYU would normally suggest forward-declaring Public directly in main.cc, but
no_forward_declare suppresses that suggestion. A forward-declaration for Public
is already available from unrelated.h.
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 ==
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++.
If the expression contains spaces, it must be enclosed in quotes.
detail/private.h:
// IWYU pragma: private
// IWYU pragma: friend "detail/.*"
struct Private {};
detail/alsoprivate.h:
#include "detail/private.h"
// IWYU pragma: private
// IWYU pragma: friend "main\.cc"
struct AlsoPrivate : Private {};
main.cc:
#include "detail/alsoprivate.h"
AlsoPrivate p;
== 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.
In practice, intentions are not so clear -- it might be ambiguous whether an
#include is there by clever design or by mistake, whether an #include serves to
export symbols from a private header through a public facade or if it's just a
left-over after some clean-up. Even when intent is obvious, IWYU can make
mistakes due to bugs or not-yet-implemented policies.
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 statement 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;
# Ones that apply to a single #include statement (keep, export)
# Ones that apply to a file being included (private, friend)
# Ones that apply to a file including other headers (no_include,
no_forward_declare)
Some files are both included and include others, so it can make sense to mix and
match.
= 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 wiki page 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.)
IWYU has the policy that you should #include a declaration for every symbol you
"use" in a file, or forward-declare it if possible. But what does it mean to
"use" a symbol?
For the most part, IWYU considers a "use" the same as the compiler does: if you
get a compiler error saying "Unknown symbol 'foo'", then you are using foo.
Whether the use is a 'full' use, that needs the definition of the symbol, or a
'forward-declare' use, that can get by with just a declaration of the symbol,
likewise matches what the compiler allows.
This makes it sound like IWYU does the moral equivalent of taking a source file,
removing #include lines from it, seeing what the compiler complains about, and
marking uses as appropriate. This is not what IWYU does. Instead, IWYU does a
thought experiment: if the definition (or declaration) of a given type were not
available, would the code compile? Here is an example illustrating the
difference:
foo.h:
#include <ostream>
typedef ostream OutputEmitter;
bar.cc:
#include "foo.h"
OutputEmitter oe;
oe << 5;
Does bar.cc "use" ostream, such that it should #include <ostream>? You'd hope
the answer would be no: the whole point of the OutputEmitter typedef,
presumably, is to hide the fact the type is an ostream. Having to have clients
#include <ostream> rather defeats that purpose. But iwyu sees that you're
calling operator<<(ostream, int), which is defined in <ostream>, so naively, it
should say that you need that header.
But IWYU doesn't (at least, modulo bugs). This is because of its attempt to
analyze "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.
In the OutputEmitter example above, while we don't know for sure, we can guess
that the intent of the author was that clients should not be considered to use
the underlying type -- and thus they shouldn't have to #include <ostream>
themselves. In that case, the typedef author takes responsibility for the
underlying type, promising to provide all the definitions needed to make code
compile. The philosophy here is: "As long as you #include foo.h, you can use
OutputEmitter however you want, without worry of compilation errors."
Some typedef authors have a different intent. <iosfwd> has the line
typedef basic_ostream<char> ostream;
but it does *not* promise "as long as you #include <iosfwd>, you can use ostream
however you want, without worry of compilation errors." For most uses of
ostream, you'll get a compiler error unles you #include <ostream> as well.
So take a slightly modified version of the above foo.h:
#include <iosfwd>
typedef ostream OutputEmitter;
This is a self-contained .h file: it's perfectly legal to typedef an incomplete
type (that's what iosfwd itself does). But now iwyu had better tell bar.cc to
#include <ostream>, or it will break the build. The difference is in the author
intent with the typedef.
Another case where author intent turns up is in function return types. Consider
this function declaration:
Foo* GetSingletonObject(); // Foo is defined in foo.h
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 ===
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.
(In an ideal world, we'd have a very fine-grained concept: "File A re-exports
symbol S when it's used in the context of typedef T function F, or ...," but in
reality, we have the much looser concept "file A re-exports all symbols from
file B.")
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 ==
You can mark that one file is re-exporting symbols from another via an IWYU
pragma in your source code:
#include "private.h" // IWYU pragma: export
This tells IWYU that if some other file uses symbols defined in private.h, they
can #include you to get them, if they want.
The full list of IWYU pragmas is defined at the top of iwyu_preprocessor.h.
== 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 ===
If you write
typedef Foo MyTypedef;
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.
#include "foo.h"
typedef Foo Typedef1; // IWYU says you intend to re-export Foo
class Bar;
typedef Bar Typedef2; // IWYU says you do not intend to re-export Bar
#include "file_including_baz.h" // does not define Baz itself
typedef Baz Typedef3; // IWYU says you do not intend to re-export Baz
If iwyu says you intend to re-export the underlying type, then nobody who uses
your typedef needs to #include the definition of the underlying type. In
contrast, if iwyu says you do not intend to re-export the underlying type, then
everybody who uses your typedef needs to #include the definition of the
underlying type.
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 ===
The same rule applies with the return value in a function declaration:
#include "foo.h"
Foo Func1(); // IWYU says you intend to re-export Foo
class Bar;
Bar Func2(); // IWYU says you do not intend to re-export Bar
#include "file_including_baz.h"
Baz Func3(); // IWYU says you do not intend to re-export Baz
(Note that C++ is perfectly happy with a forward-declaration of the return type,
if the function is just being declared, and not defined.)
As of May 2011, the rule does *not* apply when returning a pointer or reference:
#include "foo.h"
Foo* Func1(); // IWYU says you do *not* intend to re-export Foo
#include "bar.h"
Bar& Func2(); // IWYU says you do *not* intend to re-export Bar
This is considered a bug, and the behavior will likely change in the future to
match the case where the functions return a class.
Here is an example of the rule in action:
foo.h:
class Foo { ... }
bar.h:
#include "foo.h"
Foo CreateFoo() { ... }
void ConsumeFoo(const Foo& foo) { ... }
baz.cc:
#include "bar.h"
ConsumeFoo(CreateFoo());
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 ===
Consider the following code:
foo.h:
class Foo {
public:
Foo(int i) { ... }; // note: not an explicit constructor!
};
bar.h:
class Foo;
void MyFunc(Foo foo);
baz.cc:
#include "bar.h"
MyFunc(11);
The above code does not compile, because the code to convert 11 to a Foo is not
visible to baz.cc. Either baz.cc or bar.h needs to #include "foo.h" to make the
conversion constructor visible where MyFunc is being called.
The same rule applies as before:
#include "foo.h"
void Func1(Foo foo); // IWYU says you intend to re-export Foo