pombreda / include-what-you-use Goto Github PK
View Code? Open in Web Editor NEWAutomatically exported from code.google.com/p/include-what-you-use
License: Other
Automatically exported from code.google.com/p/include-what-you-use
License: Other
-------------------------------------------------------------------------------- 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 class Foo; void Func2(Foo foo); // IWYU says you do not intend to re-export Foo #include "file_including_foo.h" void Func3(Foo foo); // IWYU says you do not intend to re-export Foo As before, if iwyu decides you do not intend to re-export Foo, then all callers (in this case, baz.cc) need to. The rule here applies even to const references (which can also be automatically converted): #include "foo.h" void Func1(const Foo& foo); // IWYU says you intend to re-export Foo = 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 == 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 vector<MyClass*> foo; iwyu would tell you to #include "myclass.h", when perhaps the whole reason you're using a pointer here is to avoid the need for that #include. In the above case, it's pretty easy for iwyu to tell that we can safely forward- declare MyClass. But now consider vector<MyClass> foo; // requires full definition of MyClass scoped_ptr<MyClass> foo; // forward-declaring MyClass is often ok To distinguish these, clang has to instantiate the vector and scoped_ptr template classes, including analyzing all member variables and the bodies of the constructor and destructor (and recursively for superclasses). But that's not enough: when instantiating the templates, we need to keep track of which symbols come from template arguments and which don't. For instance, suppose you call MyFunc<MyClass>(), where MyFunc looks like this: template<typename T> void MyFunc() { T* t; MyClass myclass; ... } 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 == Even figuring out what types are 'used' with a template can be difficult. Consider the following two declarations: vector<MyClass> v; hash_set<MyClass> h; These both have default template arguments, so are parsed like vector<MyClass, alloc<MyClass> > v; hash_set<MyClass, hash<MyClass>, equal_to<MyClass>, alloc<MyClass> > h; What symbols should we say are used? If we say alloc<MyClass> is used when you declare a vector, then every file that #includes <vector> will also need to #include <memory>. So it's tempting to just ignore default template arguments. But that's not right either. What if hash<MyClass> is defined in some local myhash.h file (as hash<string> often is)? Then we want to make sure iwyu says to #include "myhash.h" when you create the hash_set (otherwise the code won't compile). That requires paying attention to the default template argument. Figuring out how to handle default template arguments can get very complex. Even normal template arguments can be confusing. Consider this templated function: template<typename A, typename B, typename C> void MyFunc(A (*fn)(B,C)) { ... } and you call MyFunc(FunctionReturningAFunctionPointer()). What types are being used where, in this case? == 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.) When you say hash_map<MyClass, int> h;, you are likewise responsible for MyClass (and int), but are you responsible for pair<MyClass, int>? That is the type that hash_map uses to store your entries internally, and it depends on one of your template arguments, but even so it shouldn't be your responsibility -- it's an implementation detail of hash_map. Of course, if you say hash_map<pair<int, int>, int>, then you are responsible for the use of pair. Distinguishing these two cases from each other, and from the vector case, can be difficult. Now suppose there's a template function like this: template<typename T> void MyFunc(T t) { strcat(t, 'a'); strchr(t, 'a'); cerr << t; } If you call MyFunc(some_char_star), which of these symbols are you responsible for, and which is the author of MyFunc responsible for: strcat, strchr, operator<<(ostream&, T)? strcat is a normal function, and the author of MyFunc is responsible for its use. This is an easy case. In C++, strchr is a templatized function (different impls for char* and const char*). Which version is called depends on the template argument. So, naively, we'd conclude that the caller is responsible for the use of strchr. However, that's ridiculous; we don't want caller of MyFunc to have to #include <string.h> just to call MyFunc. We have special code that (usually) handles this kind of case. operator<< is also a templated function, but it's one that may be defined in lots of different files. It would be ridiculous in its own way if MyFunc was responsible for #including every file that defines operator<<(ostream&, T) for all T. So, unlike the two cases above, the caller is the one responsible for the use of operator<<, and will have to #include the file that defines it. It's counter-intuitive, perhaps, but the alternatives are all worse. 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 == Let's say you have a function template<template<typename U> T> void MyFunc() { T<string> t; } 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 == Suppose you #include a file "foo.h" that has typedef hash_map<Foo, Bar> MyMap;. And you have this code: for (MyMap::iterator it = ...) Who, if anyone, is using the symbol hash_map<Foo, Bar>::iterator? If we say you, as the author of the for-loop, are the user, then you must #include <hash_map>, which undoubtedly goes against the goal of the typedef (you shouldn't even have to know you're using a hash_map). So we want to say the author of the typedef is responsible for the use. But how could the author of the typedef know that you were going to use MyMap::iterator? It can't predict that. That means it has to be responsible for every possible use of the typedef type. This can be complicated to figure out. It requires instantiating all methods of the underlying type, some of which might not even be legal C++ (if, say, the class uses SFINAE). Worse, when the language auto-derives template types, it loses typedef information. Suppose you wrote this: MyMap m; find(m.begin(), m.end(), some_foo); The compiler sees this as syntactic sugar for find<hash_map<Foo, Bar, hash<Foo>, equal_to<Foo>, alloc<Foo> >(m.begin(), m.end(), some_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 == 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 == 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: foo.h: namespace ns { class Foo {}; } using ns::Foo; foo.cc: #include "foo.h" Foo* foo; If iwyu just blindly replaces the #include with a forward declare such as namespace ns { class Foo; }, the code will break because of the lost using declaration. Include-what-you-use has to watch out for this case. Another case is a header file like this: foo.h: #define MODULE_NAME MyModule #include "module_writer.h" 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 == 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. In the future, we hope to provide a way for users to annotate if a file is public or private, either a comment or a #pragma. For now, we hard-code it in the iwyu tool. 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 #include 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 == Conditional #includes are a problem for iwyu when the condition is false: #if _MSC_VER #include <foo> #endif If we're not running under windows (and iwyu does not currently run under windows), we have no way of telling if foo is a necessary #include or not. == 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). fix_includes.py tries its best to give pleasant-looking output, while being conservative about putting code in a place where it might not compile. It uses heuristics to do this, which are not yet perfect.
In my setup clang produces a gigantic list of errors and warnings even though
gcc does not. Clang's warnings can be suppressed with command line parameter
but unfortunately not the errors. In such output it is difficult to locate the
messages produced by iwyu. It would be very helpful if iwyu had a command line
parameter for a log file, for ex. --log-file.
Here are the command lines params I am currently using:
make -k CXX="/include-what-you-use -w -ferror-limit=0"
-w suppresses warnings; ferror-limit is needed so clang does not about after
the max of error messages is used.
Original issue reported on code.google.com by [email protected]
on 9 Apr 2011 at 12:10
In my setup clang produces a gigantic list of errors and warnings even though
gcc does not. Clang's warnings can be suppressed with command line parameter
but unfortunately not the errors. In such output it is difficult to locate the
messages produced by iwyu. It would be very helpful if iwyu had a command line
parameter for a log file, for ex. --log-file.
Here are the command lines params I am currently using:
make -k CXX="/include-what-you-use -w -ferror-limit=0"
-w suppresses warnings; ferror-limit is needed so clang does not about after
the max of error messages is used.
Original issue reported on code.google.com by [email protected]
on 9 Apr 2011 at 12:10
IWYU seems to only analyze .cc/.cpp files, however the biggest wins in terms of
compile time are found in the headers. I'm curious what it would take to be
able to analyze header files as well.
Original issue reported on code.google.com by [email protected]
on 5 Mar 2011 at 12:07
It looks like r60 contains some changes which don't compile under MSVC, as
getopt.h is unavailable.
The attached patch provides a temporary workaround. I'll look into providing a
more permanent fix - perhaps moving from getopt to LLVM's Support\CommandLine.h?
Original issue reported on code.google.com by [email protected]
on 12 Mar 2011 at 4:31
Attachments:
There is no include recommendation generated for *.hpp header files. Let me
know where to look I will try to make a patch.
Original issue reported on code.google.com by [email protected]
on 23 Jun 2011 at 3:57
IWYU no longer compiles against the head of Clang.
SizeOfAlignOfExpr was renamed to UnaryExprOrTypeTraitExpr as a part of this
changeset:
http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110307/039891.html
The attached patch resolves the compile errors. More testing might be needed to
verify if any further changes to the logic are required.
Original issue reported on code.google.com by [email protected]
on 12 Mar 2011 at 4:07
Attachments:
For MSVC support, there is 1 error in port.h.
line: # undef interface
must come after
line: # include "Shlwapi.h"
Because "Shlwapi.h" uses interface.
Beside that it is fine.
Original issue reported on code.google.com by [email protected]
on 8 Feb 2011 at 8:34
It would be great if iwyu can avoid false positives like:
should add these lines:
include <A/file_name.h>
should remove these lines:
<B/A/file_name.h>
the add and remove suggestions are for the same header file but different path.
iwyu version - r106.
Original issue reported on code.google.com by [email protected]
on 9 Apr 2011 at 12:02
The attached patch fixes the compile issues. Is it ok to commit?
Original issue reported on code.google.com by [email protected]
on 17 May 2011 at 9:37
Attachments:
When building iwyu using CMake, I get an linker error.
include_what_you_use::CreateCompilerInstance cannot be found. There seems to be
no directive for CMake to actually build iwyu_driver.cc. After adding this file
to CMakeLists.txt everything works as expected.
Original issue reported on code.google.com by [email protected]
on 20 Apr 2011 at 1:56
Attachments:
From reading the documentation pages, I get the impression that iwyu currently
only supports pure C and C++ files. This ticket is to request the ability to
run iwyu on Objective-C and Objective-C++ files as well.
Real Objective-C code almost exclusively uses #import, so iwyu would need to
support #import as well as #include. The two are not entirely synonymous:
Unlike #include, which splices the named file into the source code every time,
#import remembers files it has encountered before, and will only splice the
file into the source code the first time. I'm not sure whether this detail
would be significant to iwyu, but I include it in case it would.
#import is technically a separate extension to C, available in pure C files as
well on Apple's platforms, so, ideally, support for #import should not be
restricted to Objective-C code.
In Objective-C headers, it may be appropriate to move an #import of another
class's header to the module file and replace it in the header with an @class
declaration. However, this cannot be done unconditionally: There are some
occasional cases where a header really does need to import another header, most
especially for superclasses. @class can be used when the only uses of the class
name(s) are in variable and property declarations.
Original issue reported on code.google.com by boredzo
on 3 Jul 2011 at 5:59
Hi,
iwyu no longer compiles against the head of Clang/LLVM, following this change:
http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110214/038992.html
It looks like it's no longer necessary to call setLLVMContext, as a default
llvm context is now constructed by CodeGenAction.
Paul
Original issue reported on code.google.com by [email protected]
on 18 Feb 2011 at 2:25
Attachments:
Given a header file like this one:
#include <SomeLargeClass.h>
struct X {
void f(const SomeLargeClass &c) {
// lots of code here
}
};
... it would be great if iwyu could say something like "moving definition of
'f' to .cpp file would allow removing include of <SomeLargeClass.h>".
It would be especially great if this warning could be produced only when the
user(s) of the given include are all functions large enough that they are not
likely to be inlined (and aren't required to be in the header due to being
templates or constexpr).
Original issue reported on code.google.com by [email protected]
on 7 Jul 2011 at 5:24
This assertion shows up a bunch when running on firefox (or just spidermonkey)
on linux x86-64 but I'm not quite sure how to distill a reduced testcase.
Invocation:
/home/ehren/llvm/llvm/Debug+Asserts/bin/include-what-you-use -o jsanalyze.o -c
-I./../../dist/system_wrappers_js -include
/home/ehren/llvm/mozilla-central/js/src/config/gcc_hidden.h
-DOSTYPE=\"Linux2.6.27.41-170.2.117.fc10\" -DOSARCH=Linux -DEXPORT_JS_API
-D__STDC_LIMIT_MACROS -DJS_HAS_CTYPES -DDLL_PREFIX=\"lib\" -DDLL_SUFFIX=\".so\"
-Ictypes/libffi/include -I. -I/home/ehren/llvm/mozilla-central/js/src -I.
-I./../../dist/include -I./../../dist/include/nsprpub
-I/home/ehren/llvm/mozilla-central/objdir/dist/include/nspr
-I/home/ehren/llvm/mozilla-central/js/src
-I/home/ehren/llvm/mozilla-central/js/src/assembler
-I/home/ehren/llvm/mozilla-central/js/src/yarr -fPIC -fno-rtti
-fno-exceptions -Wall -Wpointer-arith -Woverloaded-virtual -Wsynth
-Wno-ctor-dtor-privacy -Wno-non-virtual-dtor -Wcast-align -Wno-invalid-offsetof
-Wno-variadic-macros -Werror=return-type -pedantic -Wno-long-long
-fno-strict-aliasing -pthread -pipe -DDEBUG -D_DEBUG -DTRACING -g
-DUSE_SYSTEM_MALLOC=1 -DENABLE_ASSEMBLER=1 -DENABLE_JIT=1 -DMOZILLA_CLIENT
-include ./js-confdefs.h -MD -MF .deps/jsanalyze.pp
/home/ehren/llvm/mozilla-central/js/src/jsanalyze.cpp
From the backtrace it looks like this concerns include-what-you-use warnings
that would should up with IWYU_VERBOSE=7.
Eg the verbose output before the crash is:
Ignoring full use of js::analyze::Script
(/home/ehren/llvm/mozilla-central/js/src/jsanalyze.cpp:655:35): #including dfn
from "jsanalyze.h"
Noting fwd-decl use of js::analyze::Bytecode
(/home/ehren/llvm/mozilla-central/js/src/jsanalyze.cpp:659:37) is satisfied by
dfn in /home/ehren/llvm/mozilla-central/js/src/jsanalyze.h:56:8
Ignoring fwd-decl use of js::analyze::Bytecode
(/home/ehren/llvm/mozilla-central/js/src/jsanalyze.cpp:659:37): have definition
at /home/ehren/llvm/mozilla-central/js/src/jsanalyze.h:56:8
Ignoring full use of js::analyze::Script
(/home/ehren/llvm/mozilla-central/js/src/jsanalyze.cpp:659:47): #including dfn
from "jsanalyze.h"
Ignoring full use of js::analyze::Bytecode
(/home/ehren/llvm/mozilla-central/js/src/jsanalyze.cpp:659:28): #including dfn
from "jsanalyze.h"
Ignoring full use of js::analyze::Script
(/home/ehren/llvm/mozilla-central/js/src/jsanalyze.cpp:661:21): #including dfn
from "jsanalyze.h"
Ignoring full use of js::analyze::Bytecode
(/home/ehren/llvm/mozilla-central/js/src/jsanalyze.cpp:666:28): #including dfn
from "jsanalyze.h"
Ignoring full use of js::analyze::Script
(/home/ehren/llvm/mozilla-central/js/src/jsanalyze.cpp:671:16): #including dfn
from "jsanalyze.h"
include-what-you-use: SourceLocation.cpp:84: clang::FullSourceLoc
clang::FullSourceLoc::getSpellingLoc() const: Assertion `isValid()' failed.
Stack dump:
0. <eof> parser at end of file
When I apply the attached patch I get:
Invalid location: warning: is defined in <jsanalyze.h>, which isn't directly
#included.
and then a bunch of correct output (except for the angle brackets but that's
another issue):
/home/ehren/llvm/mozilla-central/js/src/jsanalyze.cpp:55:5: warning:
JS_FinishArenaPool is defined in <jsarena.h>, which isn't directly #included.
/home/ehren/llvm/mozilla-central/js/src/jsanalyze.cpp:60:12: warning:
JSArenaPool needs a declaration, but does not provide or directly #include one.
/home/ehren/llvm/mozilla-central/js/src/jsanalyze.cpp:63:5: warning:
JS_ARENA_ALLOCATE is defined in <jsarena.h>, which isn't directly #included.
etc
I guess if something like this patch is accepted I could also clean up the
warning in iwyu_output.cc:GetWarningMessage to say something like
warning: anonymous decl defined in "blah.h"
instead of just printing a space whenever the location is bad.
In any case, there might be deeper issues though...
eg from looking at the frame for GetWarningMsg:
#5 0x00000000004dbe20 in GetWarningMsg (use=@0x1f71e50) at iwyu_output.cc:1308
warning = {static npos = 18446744073709551615,
_M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>},
_M_p = 0x1f90658 "/home/ehren/llvm/mozilla-central/js/src/jsanalyze.cpp:653:49: warning: JSScript is defined in <jsscript.h>, which isn't directly #included.\n"}}
spelling_loc = {<clang::SourceLocation> = {ID = 22006}, SrcMgr = 0x1249150}
instantiation_loc = {<clang::SourceLocation> = {ID = 33095856}, SrcMgr = 0x7fffffffd4ff}
warning = {static npos = 18446744073709551615,
_M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x7fffffffd4b0 "\020\tรฏยฟยฝ\001"}}
it seems like the proper warning should be:
/home/ehren/llvm/mozilla-central/js/src/jsanalyze.cpp:653:49: warning: JSScript
is defined in <jsscript.h>, which isn't directly #included.
Not sure why we end up with an invalid spelling loc in this case. Also not sure
where __gnu_cxx::new_allocator<char>> comes into play. The source code line
that's causing trouble is jsanalyze.cpp:653 which is a JS_ASSERT that resolves
to RegularFunctionCall("message", __FILE__, __LINE__) so I wonder if it's
something screwy with the __FILE__ directives.
Perhaps a follow up issue is needed? I'm not sure if this would affect
correctness.
(note, same issue affects GetInstantiationLoc so I rolled both fixes into one)
Original issue reported on code.google.com by Ehren.M
on 15 May 2011 at 8:56
Attachments:
iwyu doesn't support response files (aka '@files'). Support for these were
added to clang in r108697
(http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20100719/032322.html
), but iwyu doesn't seem to have picked up this change.
Here's a simple test to demonstrate this behaviour:
---test.cpp---
#ifndef RSP_SAYS_HELLO
#error Didn't see the .rsp file
#endif
int main()
{
return 0;
}
---test.rsp---
-DRSP_SAYS_HELLO
C:\dev\test_rsp>include-what-you-use @test.rsp test.cpp
error: no such file or directory: '@test.rsp'
test.cpp(4) : error: #error Didn't see the .rsp file
#error Didn't see the .rsp file
^
(test.cpp has correct #includes/fwd-decls)
The same files compile without error via clang:
C:\dev\test_rsp>clang -fsyntax-only @test.rsp test.cpp
The attached patch resolves this. I've lifted the response file handling from
<clang>\tools\driver\driver.cpp and applied to iwyu.cc. Ideally there'd be some
shared code that we could use to avoid the copy-pasta; I'll look into raising a
patch against Clang to address this.
(BTW the patch below contains a slightly tweaked version of the code from
driver.cpp. The original code aggressively strips backslashes, regardless of
whether they're actually part of a recognised escape sequence -
backslash-backslash or backslash-space. I've made a change to make this
slightly more lenient, which I believe is closer to how GCC handles response
files. )
Original issue reported on code.google.com by [email protected]
on 20 Feb 2011 at 7:09
Attachments:
As far as I can tell, iwyu does not work well for C code, which means it can
also not be used on projects (like ICU) that expose C APIs (sadly necessary for
stable APIs from shared libraries) and/or contain .c implementation files.
Please accept pragmas inside /* C-style comments */, and please provide a way
to mark a file as C code so that --comments writes /* C-style comments */.
Original issue reported on code.google.com by markus.icu
on 5 May 2011 at 8:39
I downloaded and built llvm-2.9 and clang-2.9 from tarballs (I don't have svn
access, so I can't use the repo versions).
When trying to build include-what-you-use in
llvm-2.9/tools/clang/tools/include-what-you-use
I get:
wyu.cc: In function โint main(int, const char**)โ:
iwyu.cc:3090: error: โclass clang::CompilerInstanceโ has no member named
โsetLLVMContextโ
Looking at the CompilerInstance.h header, I agree - there's no setLLVMContext
method there.
I don't see that method in the svn repo version either:
http://llvm.org/svn/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstan
ce.h
Any suggestions?
Original issue reported on code.google.com by [email protected]
on 31 May 2011 at 1:08
Currently, then I build CMake's INSTALL target, it installs clang, clang++ all
all the other LLVM executables to the directory specified by
CMAKE_INSTALL_PREFIX. It doesn't do this for the include-what-you-use
executable however, so I have to remember to manually copy this across when
installing.
This small patch registers IWYU so that it's installed along with everything
else.
Is it ok to apply?
Original issue reported on code.google.com by [email protected]
on 22 May 2011 at 10:01
Attachments:
Given the following files:
a.cpp >>>>>
#include "b.h"
class A {
B *getB(int i) { return &(_b[i]); }
B *_b;
};
<<<<<
b.h >>>>>
class B {
int foo;
};
<<<<<
"$ include-what-you-use a.cpp" suggests:
a.cpp should add these lines:
class B;
a.cpp should remove these lines:
- #include "b.h" // lines 1-1
Doing so leads to a compilation error:
a.cpp:4:30: error: subscript of pointer to incomplete type 'B'
B *getB(int i) { return &(_b[i]); }
Original issue reported on code.google.com by [email protected]
on 1 May 2011 at 1:51
It would be possible to use IWYU in unmodified build process (with IWYU set as
compiler, of course) if it returned 0 on valid sources and wrote empty output
file (to satisfy build system).
Original issue reported on code.google.com by [email protected]
on 29 Mar 2011 at 1:00
The build procedure in README.txt does not work when the build dir differs from
the source dir.
$ svn info ~/LLVM/llvm/
URL: http://llvm.org/svn/llvm-project/llvm/trunk
Repository Root: http://llvm.org/svn/llvm-project
Repository UUID: 91177308-0d34-0410-b5e6-96231b3b80d8
Revision: 125001
$ svn info ~/LLVM/llvm/tools/clang/
URL: http://llvm.org/svn/llvm-project/cfe/trunk
Repository Root: http://llvm.org/svn/llvm-project
Repository UUID: 91177308-0d34-0410-b5e6-96231b3b80d8
Revision: 125001
Checked out include-what-you-use into ~/LLVM/llvm/tools/clang/tools
$ svn info ~/LLVM/llvm/tools/clang/tools/include-what-you-use-read-only
URL: http://include-what-you-use.googlecode.com/svn/trunk
Repository Root: http://include-what-you-use.googlecode.com/svn
Repository UUID: 812d1f90-f944-d88a-411a-122bdc93e1ea
Revision: 15
cd ~/LLVM/llvm/tools/clang/tools/
make
What is the expected output? What do you see instead?
$ make
../../../../Makefile.common:61: ../../../../Makefile.config: No such file or
directory
../../../../Makefile.common:69: /Makefile.rules: No such file or directory
make: *** No rule to make target `/Makefile.rules'. Stop.
The reason for the error is that Makefile.config and Makefile.rules exist in
the build directory (in this case, ~/LLVM/build-release) and not the source
directory (~/LLVM/llvm)
The following patch integrates include-what-you-use with clang:
~/LLVM/llvm/tools/clang/tools$ svn diff Makefile
Index: Makefile
===================================================================
--- Makefile (revision 125001)
+++ Makefile (working copy)
@@ -8,7 +8,7 @@
##===----------------------------------------------------------------------===##
CLANG_LEVEL := ..
-DIRS := driver libclang c-index-test
+DIRS := driver libclang c-index-test include-what-you-use-read-only
include $(CLANG_LEVEL)/../../Makefile.config
Original issue reported on code.google.com by [email protected]
on 7 Feb 2011 at 9:21
Compilation of iwyu_driver.cc failed with message:
llvm[4]: Compiling iwyu_include_picker.cc for Release+Asserts build
/home/kostya/src/svn/llvm/tools/clang/tools/include-what-you-use/iwyu_driver.cc:
In function 'clang::CompilerInstance* CreateCompilerInstance(int, const
char**)':
/home/kostya/src/svn/llvm/tools/clang/tools/include-what-you-use/iwyu_driver.cc:
161: error: no matching function for call to
'clang::driver::Driver::BuildCompilation(size_t, const char**)'
/home/kostya/src/svn/llvm/tools/clang/tools/include-what-you-use/../../include/c
lang/Driver/Driver.h:219: note: candidates are: clang::driver::Compilation*
clang::driver::Driver::BuildCompilation(llvm::ArrayRef<const char*>)
Original issue reported on code.google.com by [email protected]
on 26 Mar 2011 at 3:53
When source files are using 'PC' (\r\n) line endings, ProcessPragmasInFile
fails to operate correctly. In my test case I have this line:
#include <stddef.h> // IWYU pragma: keep
And IWYU gives this warning:
<blah>/Core/Types.h:3:47: warning: Unknown or malformed pragma (keep)
Stepping through in the debugger, pragma_text is "keep\r".
The attached patch resolves this issue for me, but I'm unable to run the
testsuite to see if there are any regressions.
Original issue reported on code.google.com by [email protected]
on 9 Mar 2011 at 10:58
Attachments:
What steps will reproduce the problem? Give the *exact* arguments passed
to include-what-you-use, and attach the input source file that gives the
problem (minimal test-cases are much appreciated!)
1. include-what-you-use Foo.cpp
2.
3.
What is the expected output? What do you see instead?
0. <eof> parser at end of file
1. source/Foo.cpp:4:3: instantiating function definition 'Foo'
Segmentation fault (core dumped)
What version of the product are you using? On what operating system?
iwyu: rev 255, llvm/clang: 132185
Please provide any additional information below.
The file compiles fine with clang++ -c Foo.cpp
Foo.cpp:
class Foo
{
public:
Foo(const char* s);
};
Original issue reported on code.google.com by [email protected]
on 27 May 2011 at 7:50
(running linux x86-64)
Assertion that pops up on several test cases and real code:
SemaDeclCXX.cpp:5958: clang::CXXConstructorDecl*
clang::Sema::DeclareImplicitDefaultConstructor(clang::CXXRecordDecl*):
Assertion `!ClassDecl->hasUserDeclaredConstructor() && "Should not build
implicit default constructor!"' failed.
back trace:
#0 0x0000003751e32f05 in raise () from /lib64/libc.so.6
#1 0x0000003751e34a73 in abort () from /lib64/libc.so.6
#2 0x0000003751e2bef9 in __assert_fail () from /lib64/libc.so.6
#3 0x000000000076cd93 in clang::Sema::DeclareImplicitDefaultConstructor
(this=0x12943b0, ClassDecl=0x1e6a310) at SemaDeclCXX.cpp:5957
#4 0x000000000045f531 in
include_what_you_use::BaseAstVisitor<include_what_you_use::IwyuAstConsumer>::Ins
tantiateImplicitMethods (this=0x1283ca0, decl=0x1e6a310)
at iwyu.cc:647
#5 0x000000000049eb43 in
include_what_you_use::BaseAstVisitor<include_what_you_use::IwyuAstConsumer>::Tra
verseCXXRecordDecl (this=0x1283ca0, decl=0x1e6a310)
at iwyu.cc:694
#6 0x000000000048e230 in
clang::RecursiveASTVisitor<include_what_you_use::IwyuAstConsumer>::TraverseDecl
(this=0x1283ca0, D=0x1e6a310)
at /home/ehren/llvm/llvm/tools/clang/tools/include-what-you-use/../../include/clang/AST/DeclNodes.inc:195
#7 0x000000000048e656 in
include_what_you_use::BaseAstVisitor<include_what_you_use::IwyuAstConsumer>::Tra
verseDecl (this=0x1283ca0, decl=0x1e6a310) at iwyu.cc:351
#8 0x000000000048e883 in
clang::RecursiveASTVisitor<include_what_you_use::IwyuAstConsumer>::TraverseDeclC
ontextHelper (this=0x1283ca0, DC=0x1e5bf60)
at /home/ehren/llvm/llvm/tools/clang/tools/include-what-you-use/../../include/clang/AST/RecursiveASTVisitor.h:1054
#9 0x000000000048ea6e in
clang::RecursiveASTVisitor<include_what_you_use::IwyuAstConsumer>::TraverseNames
paceDecl (this=0x1283ca0, D=0x1e5bf30)
at /home/ehren/llvm/llvm/tools/clang/tools/include-what-you-use/../../include/clang/AST/RecursiveASTVisitor.h:1148
#10 0x000000000048e020 in
clang::RecursiveASTVisitor<include_what_you_use::IwyuAstConsumer>::TraverseDecl
(this=0x1283ca0, D=0x1e5bf30)
at /home/ehren/llvm/llvm/tools/clang/tools/include-what-you-use/../../include/clang/AST/DeclNodes.inc:61
#11 0x000000000048e656 in
include_what_you_use::BaseAstVisitor<include_what_you_use::IwyuAstConsumer>::Tra
verseDecl (this=0x1283ca0, decl=0x1e5bf30) at iwyu.cc:351
#12 0x000000000048e883 in
clang::RecursiveASTVisitor<include_what_you_use::IwyuAstConsumer>::TraverseDeclC
ontextHelper (this=0x1283ca0, DC=0x1e5bef0)
at /home/ehren/llvm/llvm/tools/clang/tools/include-what-you-use/../../include/clang/AST/RecursiveASTVisitor.h:1054
#13 0x000000000048ea6e in
clang::RecursiveASTVisitor<include_what_you_use::IwyuAstConsumer>::TraverseNames
paceDecl (this=0x1283ca0, D=0x1e5bec0)
at /home/ehren/llvm/llvm/tools/clang/tools/include-what-you-use/../../include/clang/AST/RecursiveASTVisitor.h:1148
#14 0x000000000048e020 in
clang::RecursiveASTVisitor<include_what_you_use::IwyuAstConsumer>::TraverseDecl
(this=0x1283ca0, D=0x1e5bec0)
at /home/ehren/llvm/llvm/tools/clang/tools/include-what-you-use/../../include/clang/AST/DeclNodes.inc:61
#15 0x000000000048e656 in
include_what_you_use::BaseAstVisitor<include_what_you_use::IwyuAstConsumer>::Tra
verseDecl (this=0x1283ca0, decl=0x1e5bec0) at iwyu.cc:351
#16 0x000000000048e883 in
clang::RecursiveASTVisitor<include_what_you_use::IwyuAstConsumer>::TraverseDeclC
ontextHelper (this=0x1283ca0, DC=0x12609d8)
at /home/ehren/llvm/llvm/tools/clang/tools/include-what-you-use/../../include/clang/AST/RecursiveASTVisitor.h:1054
#17 0x000000000048f052 in
clang::RecursiveASTVisitor<include_what_you_use::IwyuAstConsumer>::TraverseTrans
lationUnitDecl (this=0x1283ca0, D=0x12609b0)
at /home/ehren/llvm/llvm/tools/clang/tools/include-what-you-use/../../include/clang/AST/RecursiveASTVisitor.h:1127
#18 0x000000000048e5e0 in
clang::RecursiveASTVisitor<include_what_you_use::IwyuAstConsumer>::TraverseDecl
(this=0x1283ca0, D=0x12609b0)
at /home/ehren/llvm/llvm/tools/clang/tools/include-what-you-use/../../include/clang/AST/DeclNodes.inc:421
#19 0x000000000048e656 in
include_what_you_use::BaseAstVisitor<include_what_you_use::IwyuAstConsumer>::Tra
verseDecl (this=0x1283ca0, decl=0x12609b0) at iwyu.cc:351
#20 0x000000000048e6a7 in
include_what_you_use::IwyuAstConsumer::HandleTranslationUnit (this=0x1283c90,
context=@0x125e090) at iwyu.cc:3238
#21 0x0000000000657b93 in clang::ParseAST (S=@0x12943b0, PrintStats=false) at
ParseAST.cpp:97
#22 0x0000000000518a5f in clang::ASTFrontendAction::ExecuteAction
(this=0x1246620) at FrontendAction.cpp:376
#23 0x0000000000518b6c in clang::FrontendAction::Execute (this=0x1246620) at
FrontendAction.cpp:296
#24 0x0000000000500768 in clang::CompilerInstance::ExecuteAction
(this=0x124d920, Act=@0x1246620) at CompilerInstance.cpp:600
#25 0x0000000000414512 in main (argc=57, argv=0x7fffffffda48) at iwyu.cc:3628
Test cases affected:
INFO:root:tests/implicit_ctor.cc: Using iwyu flags
['--check_also="tests/*-d1.h"']
>>> Running ../../../../Debug+Asserts/bin/include-what-you-use -Xiwyu
--verbose=3 -Xiwyu --check_also="tests/*-d1.h" -I . tests/implicit_ctor.cc
INFO:root:tests/iwyu_stricter_than_cpp.cc: Using iwyu flags
['--check_also="tests/*-*[^0-9].h"', '--check_also="tests/*-d2.h"']
>>> Running ../../../../Debug+Asserts/bin/include-what-you-use -Xiwyu
--verbose=3 -Xiwyu --check_also="tests/*-*[^0-9].h" -Xiwyu
--check_also="tests/*-d2.h" -I . tests/iwyu_stricter_than_cpp.cc
>>> Running ../../../../Debug+Asserts/bin/include-what-you-use -Xiwyu
--verbose=3 -I . tests/templated_constructor.cc
>>> Running ../../../../Debug+Asserts/bin/include-what-you-use -Xiwyu
--verbose=3 -I . tests/virtual_tpl_method.cc
wrt the patch, I wonder how hasUserDeclaredConstructor can be false but
hasDeclaredDefaultConstructor can be true (maybe some dummy default constructor
gets inserted at some point other than
Sema::DeclareImplicitDefaultConstructor?). In any case, just changing the guard
to match the assert seems to be safe.
Also, I haven't looked into it but there might be similar fixes possible for
the ifdefed 0 code just below this.
Original issue reported on code.google.com by Ehren.M
on 15 May 2011 at 6:34
Attachments:
Hello,
This is a follow up to Issue 11. This is what I'm currently seeing (with r26)
when running with a build targeting Win32:
C:\dev\test_iwyu>type test.h
#pragma once
struct Hello
{
enum { X = 0 };
};
C:\dev\test_iwyu>type test.cpp
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "test.h"
int main()
{
printf( "Sin(0): %f\n", sinf(1.0f) );
printf( "Hello::X: %d\n", Hello::X );
}
C:\dev\test_iwyu>include-what-you-use test.cpp
test.cpp should add these lines:
#include <c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include/math.h>
#include <c:\Program Files (x86)\Microsoft Visual Studio
10.0\VC\include/stdio.h>
test.cpp should remove these lines:
- #include <math.h> // lines 1-1
- #include <stdio.h> // lines 2-2
- #include <string.h> // lines 3-3
The full include-list for test.cpp:
#include <c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include/math.h>
#include <c:\Program Files (x86)\Microsoft Visual Studio
10.0\VC\include/stdio.h>
#include "test.h" // for Hello, Hello::::X
---
NB that the math.h/stdio.h includes are not being found in the system include
dirs, and are being turned into absolute filenames.
This is the output I'd expect:
test.cpp should add these lines:
test.cpp should remove these lines:
- #include <string.h> // lines 3-3
The full include-list for test.cpp:
#include <math.h> // for sinf
#include <stdio.h> // for printf
#include "test.h" // for Hello, Hello::::X
---
The attached patches fix this issue (producing the above output), and should
provide much more robust behaviour on different platforms (though StripPast and
StartsWith might need some work to ignore case on Win32).
I'd appreciate some feedback on the approach I've taken for the patch
(particularly with the point at which I call MakeSystemDirs - perhaps this
should be moved upstream or downstream?). Unfortunately it relies on exposing
some fields in Clang's HeaderSearch class, and I'm not sure if there will be
any problems getting this applied to Clang's source tree.
An alternative approach I considered was to add another callback on PPCallbacks
to inform about the search dirs as the preprocessor is initialised. That seemed
a bit more involved though, and would still require a change to Clang.
NB at the moment I'm throwing away a fair bit of useful info when I construct
the list of search paths. Clang keeps track of some other useful info in
DirectoryLookup, such as whether the dir is user supplied or not. The
getDirCharacteristic() call might contain useful info for deciding whether to
return c_include_multimap_ or cpp_include_multimap_.
Regards,
Paul
Original issue reported on code.google.com by [email protected]
on 17 Feb 2011 at 9:12
Attachments:
Hello,
I was able to compile llvm and clang r124350 as specified in the Makefile of
include-what-you-use r86.
However when trying to compile nclude-what-you-use I am getting compile errors:
llvm[4]: Compiling iwyu.cc for Debug+Asserts build
~/llvm-r124350/tools/clang/tools/include-what-you-use/iwyu_location_util.h:186:
error: expected unqualified-id before โ*โ token
~/llvm-r124350/tools/clang/tools/include-what-you-use/iwyu_location_util.h:186:
error: expected โ,โ or โ...โ before โ*โ token
~/llvm-r124350/tools/clang/tools/include-what-you-use/iwyu_location_util.h:186:
error: ISO C++ forbids declaration of โparameterโ with no type
It looks like it cannot find clang::NestedNameSpecifierLoc. Do I need to
configure an build llvm/clang with particular parameter? I build llvm/clang
using ./configure and make with no parameters as specified here:
http://clang.llvm.org/get_started.html#build
OS: CentOS release 5.2 (Final)
gcc/g++ version: (GCC) 4.1.2 20071124 (Red Hat 4.1.2-42)
Any help is appreciated.
Original issue reported on code.google.com by [email protected]
on 25 Mar 2011 at 11:59
When compiling with MSVC, I see these warnings:
3>C:\dev\llvm_svn\tools\clang\include\clang/AST/Expr.h(635): warning C4099:
'clang::ExplicitTemplateArgumentList' : type name first seen using 'class' now
seen using 'struct'
3>
c:\dev\llvm_svn\tools\clang\tools\include-what-you-use\iwyu_ast_util.h(38) :
see declaration of 'clang::ExplicitTemplateArgumentList'
(duplicated several times for each inclusion of iwyu_ast_util.h)
ExplicitTemplateArgumentList is defined as a struct within Clang, and IWYU
forward declares it as a class. MSVC takes grievance to this for some reason.
The attached (trivial) patch fixes this. Is it ok to apply?
Original issue reported on code.google.com by [email protected]
on 22 May 2011 at 10:12
Attachments:
When I reference new in my source, IWYU informs me:
blah.h should add these lines:
#include "/usr/include/c++/<version>/new" // for operator new
I believe on other platforms this is being handled by NormalizeSystemPath.
However on Win32 (possibly as a result of some of my other changes) this is
being picked up as a local include (Case 1 in ConvertToQuotedInclude).
I can see where this include is being generated (iwyu.cc:1920). One (gross) fix
would be to use "C:/usr/include/c++/<version>/new" for this on Win32. I'll hold
off on that for now and try to find something a little nicer...
Original issue reported on code.google.com by [email protected]
on 9 Mar 2011 at 11:09
The wiki could do with a page explaining why IWYU is a good idea,
what the benefits are over the alternatives,
and why forward declarations are preferred over #includes.
Original issue reported on code.google.com by [email protected]
on 17 Apr 2011 at 1:18
On OSX 10.6.6, I get the following error when running test badinc at r62. Could
you please confirm that it passes for you? If so, it is likely this is an
osx/linux environment difference.
======================================================================
FAIL: runTest (__main__.badinc)
----------------------------------------------------------------------
Traceback (most recent call last):
File "run_iwyu_tests.py", line 85, in <lambda>
{'runTest': lambda self, f=filename: self.RunOneTest(f)})
File "run_iwyu_tests.py", line 67, in RunOneTest
iwyu_flags, verbose=True)
File "/Volumes/work/chromium/src/third_party/llvm-build/tools/clang/tools/include-what-you-use/iwyu_test_util.py", line 396, in TestIwyuOnRelativeFile
test_case.assert_(not failures, ''.join(failures))
AssertionError:
tests/badinc.cc:717: actual diagnostic doesn't match expectation.
Expected: regular expression "I1_Class is...*badinc-i1.h"
Actual: I1_Class needs a declaration, but does not provide or directly #include
one.
tests/badinc.cc:720: expecting 1 diagnostics; actually had 0:
tests/badinc.cc:755: expecting 4 diagnostics; actually had 3:
I1_Class needs a declaration, but does not provide or directly #include one.
I1_TemplateClass is defined in "tests/badinc-i1.h", which isn't directly
#included.
std::vector is defined in <vector>, which isn't directly #included.
tests/badinc.cc:824: expecting 3 diagnostics; actually had 2:
I1_Class needs a declaration, but does not provide or directly #include one.
I1_TypedefOnly_Class is defined in "tests/badinc-i1.h", which isn't directly
#included.
tests/badinc.cc:829: expecting 4 diagnostics; actually had 3:
I1_Class needs a declaration, but does not provide or directly #include one.
I1_TypedefOnly_Class is defined in "tests/badinc-i1.h", which isn't directly
#included.
I1_TypedefOnly_Class<I1_Class>::i is defined in "tests/badinc-i1.h", which
isn't directly #included.
tests/badinc.cc:1013: expecting 1 diagnostics; actually had 0:
tests/badinc.cc:1071: actual diagnostic doesn't match expectation.
Expected: regular expression "size_t is...*<stddef.h>"
Actual: size_t is defined in <unistd.h>, which isn't directly #included.
tests/badinc.cc:1123: expecting 0 diagnostics; actually had 1:
errno is defined in <sys/errno.h>, which isn't directly #included.
tests/badinc.cc:1256: expecting 4 diagnostics; actually had 3:
I1_Class needs a declaration, but does not provide or directly #include one.
I1_TemplateMethodOnlyClass is defined in "tests/badinc-i1.h", which isn't
directly #included.
I2_Class needs a declaration, but does not provide or directly #include one.
tests/badinc.cc:1915: expecting 4 diagnostics; actually had 3:
I1_Class needs a declaration, but does not provide or directly #include one.
I1_Struct needs a declaration, but does not provide or directly #include one.
I1_TemplateMethodOnlyClass is defined in "tests/badinc-i1.h", which isn't
directly #included.
tests/badinc.h:136: expecting 0 diagnostics; actually had 1:
errno is defined in <sys/errno.h>, which isn't directly #included.
tests/badinc.h:298: expecting 4 diagnostics; actually had 3:
I2_Class is defined in "tests/badinc-i2.h", which isn't directly #included.
I2_Class needs a declaration, but does not provide or directly #include one.
std::vector is defined in <vector>, which isn't directly #included.
Unexpected summary diffs for tests/badinc.cc:
+++
@@ -2,6 +2,7 @@
#include <ctype.h>
#include <stddef.h>
#include <stdlib.h>
+#include <unistd.h>
#include <list>
#include <new>
#include "tests/badinc-i1.h"
@@ -31,13 +32,14 @@
#include "tests/badinc-inl.h"
#include <ctype.h> // for isascii
#include <setjmp.h>
-#include <stddef.h> // for offsetof, size_t
+#include <stddef.h> // for offsetof
#include <stdlib.h> // for rand
+#include <unistd.h> // for size_t
#include <algorithm> // for find
#include <fstream> // for fstream
#include <list> // for list
#include <new> // for operator new
-#include <string> // for allocator, basic_string, char_traits, operator+,
string
+#include <string> // for allocator, basic_string, operator+, string
#include <typeinfo> // for type_info
#include "tests/badinc-d1.h" // for D1CopyClassFn, D1Function, D1_Class, D1_CopyClass, D1_Enum, D1_Enum::D11, D1_I1_Typedef, D1_StructPtr, D1_Subclass, D1_TemplateClass, D1_TemplateStructWithDefaultParam, MACRO_CALLING_I4_FUNCTION
#include "tests/badinc-d4.h" // for D4_ClassForOperator, operator<<
---
Unexpected summary diffs for tests/badinc.h:
+++
@@ -1,5 +1,6 @@
tests/badinc.h should add these lines:
#include <stdio.h>
+#include <sys/errno.h>
#include <set>
#include <utility>
#include <vector>
@@ -8,14 +9,15 @@
tests/badinc.h should remove these lines:
- #include <ctype.h> // lines XX-XX
+- #include <errno.h> // lines XX-XX
- #include <math.h> // lines XX-XX
- #include "tests/badinc-d2.h" // lines XX-XX
- class H_ForwardDeclareClass; // lines XX-XX
- template <typename T> class I2_TypedefOnly_Class; // lines XX-XX
The full include-list for tests/badinc.h:
-#include <errno.h> // for errno
#include <stdio.h> // for NULL, printf
+#include <sys/errno.h> // for errno
#include <queue> // for queue
#include <set> // for set
#include <string> // for string
---
----------------------------------------------------------------------
Ran 18 tests in 2.849s
FAILED (failures=1)
Original issue reported on code.google.com by [email protected]
on 15 Mar 2011 at 6:09
I broke the cmake link for linkers that care about order. The attached patch
restores the correct order.
Original issue reported on code.google.com by [email protected]
on 8 Feb 2011 at 5:53
Attachments:
GetSpellingLoc and GetInstantiationLoc can cause asserts in
clang::FullSourceLoc if they are invoked with an invalid 'loc'. This can happen
when running IWYU with --verbose=3. In the cases I saw it happening they were
being called from GetWarningMsg(), but there may be other examples.
The attached patch resolves the issue. GetLineNumber already has some similar
checks.
Original issue reported on code.google.com by [email protected]
on 16 Jul 2011 at 1:56
Attachments:
The attached patch provides the following improvements to GetCanonicalName:
* .cxx and .cpp extensions are handled (I'm using the same list as used in
IsHeaderFile() - perhaps .inl should be considered too)
* Path separators are canonicalised on Win32. Our build system provides search
paths with forward slashes as separators, but paths with backslashes creep in
somewhere. So foo\bar\baz.h and foo/bar/baz.h should now be considered the same.
I've added a couple of tests for the first case to the testsuite, but the
README suggests that there's no framework for the 'more_tests' tests yet. When
this is available I'll add some extra tests for separator canonicalisation.
There are a few TODOs:
* CanonicalizeFilePath should probably collapse '../' sequences, i.e. a/b/../c
and a/c should be considered the same (this is handled nicely by
PathCanonicalize on Win32, perhaps there's a nice Unixy equivalent?)
* We should probably ignore case on Win32.
(BTW there is a 'canonicalize()' function in llvm/Support/FileSystem.h which
would do what we want, but it doesn't seem to be implemented :/ )
Original issue reported on code.google.com by [email protected]
on 23 Feb 2011 at 8:31
Attachments:
What steps will reproduce the problem? Give the *exact* arguments passed
python run_iwyu_tests.py
What is the expected output? What do you see instead?
Expected: OK
Output Instead:
[..]
ERROR:root:Test failed for tests/badinc.cc
---
tests/badinc.cc:580: expecting 2 diagnostics; actually had 1:
I1_Class needs a declaration, but does not provide or directly #include one.
---
[..]
F
======================================================================
FAIL: testIwyuWorks (__main__.IwyuTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "run_iwyu_tests.py", line 68, in testIwyuWorks
self.assert_(not failed_tests, 'Failed tests: %s' % ' '.join(failed_tests))
AssertionError: Failed tests: tests/badinc.cc
----------------------------------------------------------------------
Ran 1 test in 12.055s
FAILED (failures=1)
What version of the product are you using? On what operating system?
iwyu 0.1 with svn llvm and svn clang. Ubuntu 10.10 64bit.
Please provide any additional information below.
..
Original issue reported on code.google.com by [email protected]
on 5 Feb 2011 at 1:31
Hi this is a small patch to compile include-what-you-use with MSVC 2010.
There are still problems with the python script on Win32. I will address these
later.
Original issue reported on code.google.com by [email protected]
on 8 Feb 2011 at 1:17
Attachments:
/path/to/include-what-you-use animation_container.cc -I.
animation_container.h should add these lines:
#include "animation_container_element.h" // for AnimationContainerElement
animation_container.h should remove these lines:
- namespace ui { class AnimationContainerElement; } // lines 7-7
The full include-list for animation_container.h:
#include <set> // for set
#include "animation_container_element.h" // for AnimationContainerElement
---
animation_container.cc should add these lines:
animation_container.cc should remove these lines:
- #include "animation_container_element.h" // lines 3-3
The full include-list for animation_container.cc:
#include "animation_container.h"
---
What is the expected output? What do you see instead?
I expect that the forward declaration of AnimationContainerElement would be
considered legit and that iwyu would not state I should remove the forward
declaration.
What version of the product are you using? On what operating system?
Clang 3.0 (trunk 127569)
iwyu r96
Original issue reported on code.google.com by [email protected]
on 29 Mar 2011 at 12:13
Attachments:
Many headers contains non-inline implementation which leads to more include and
less forward declaration. If there is a way to automatically extract
non-inlineable implementation from *.hpp to *.cpp file, and re-analysis the
depedency, this should further reduce compile time.
Original issue reported on code.google.com by [email protected]
on 9 Jun 2011 at 12:49
I was running Release+Asserts and all tests failed with no output. It took a
bit of debugging to see that IWYU_PATH wasn't there and that tests require a
Debug+Asserts build. This patch should help future noobs.
Original issue reported on code.google.com by [email protected]
on 15 Mar 2011 at 12:13
Attachments:
The project home refers licensing to the source code files. In the source code
there is reference to LICENSE.TXT, but no such file exists in the tarball.
Original issue reported on code.google.com by [email protected]
on 8 Jul 2011 at 9:20
What steps will reproduce the problem? Give the *exact* arguments passed
to include-what-you-use, and attach the input source file that gives the
problem (minimal test-cases are much appreciated!)
1. Build llvm+clang+iwyu using cmake
What is the expected output? What do you see instead?
I'd hope for a successful build, but the link fails with some undefined symbols:
Linking CXX executable ../../../../bin/include-what-you-use
../../../../lib/libclangAST.a(InheritViz.cpp.o): In function
`clang::InheritanceHierarchyWriter::WriteNode(clang::QualType, bool)':
/local/brs/work/llvm-source/tools/clang/lib/AST/InheritViz.cpp:80: undefined
reference to `llvm::DOT::EscapeString(std::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&)'
../../../../lib/libclangAST.a(InheritViz.cpp.o): In function
`clang::CXXRecordDecl::viewInheritance(clang::ASTContext&) const':
/local/brs/work/llvm-source/tools/clang/lib/AST/InheritViz.cpp:160: undefined
reference to `llvm::DisplayGraph(llvm::sys::Path const&, bool,
llvm::GraphProgram::Name)'
../../../../lib/libclangAST.a(InheritViz.cpp.o): In function
`clang::InheritanceHierarchyWriter::WriteGraph(clang::QualType)':
/local/brs/work/llvm-source/tools/clang/lib/AST/InheritViz.cpp:46: undefined
reference to `llvm::DOT::EscapeString(std::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&)'
../../../../lib/libclangBasic.a(Targets.cpp.o): In function `(anonymous
namespace)::DarwinTargetInfo<(anonymous
namespace)::ARMTargetInfo>::isValidSectionSpecifier(llvm::StringRef) const':
/local/brs/work/llvm-source/tools/clang/lib/Basic/Targets.cpp:162: undefined
reference to `llvm::MCSectionMachO::ParseSectionSpecifier(llvm::StringRef,
llvm::StringRef&, llvm::StringRef&, unsigned int&, unsigned int&)'
../../../../lib/libclangBasic.a(Targets.cpp.o): In function `(anonymous
namespace)::DarwinTargetInfo<(anonymous
namespace)::X86_64TargetInfo>::isValidSectionSpecifier(llvm::StringRef) const':
/local/brs/work/llvm-source/tools/clang/lib/Basic/Targets.cpp:162: undefined
reference to `llvm::MCSectionMachO::ParseSectionSpecifier(llvm::StringRef,
llvm::StringRef&, llvm::StringRef&, unsigned int&, unsigned int&)'
../../../../lib/libclangBasic.a(Targets.cpp.o): In function `(anonymous
namespace)::DarwinTargetInfo<(anonymous
namespace)::X86_32TargetInfo>::isValidSectionSpecifier(llvm::StringRef) const':
/local/brs/work/llvm-source/tools/clang/lib/Basic/Targets.cpp:162: undefined
reference to `llvm::MCSectionMachO::ParseSectionSpecifier(llvm::StringRef,
llvm::StringRef&, llvm::StringRef&, unsigned int&, unsigned int&)'
../../../../lib/libclangBasic.a(Targets.cpp.o): In function `(anonymous
namespace)::DarwinTargetInfo<(anonymous
namespace)::PPC64TargetInfo>::isValidSectionSpecifier(llvm::StringRef) const':
/local/brs/work/llvm-source/tools/clang/lib/Basic/Targets.cpp:162: undefined
reference to `llvm::MCSectionMachO::ParseSectionSpecifier(llvm::StringRef,
llvm::StringRef&, llvm::StringRef&, unsigned int&, unsigned int&)'
../../../../lib/libclangBasic.a(Targets.cpp.o): In function `(anonymous
namespace)::DarwinTargetInfo<(anonymous
namespace)::PPC32TargetInfo>::isValidSectionSpecifier(llvm::StringRef) const':
/local/brs/work/llvm-source/tools/clang/lib/Basic/Targets.cpp:162: undefined
reference to `llvm::MCSectionMachO::ParseSectionSpecifier(llvm::StringRef,
llvm::StringRef&, llvm::StringRef&, unsigned int&, unsigned int&)'
collect2: ld returned 1 exit status
What version of the product are you using? On what operating system?
trunk, on GNU/Linux (32 bit).
Please provide any additional information below.
This patch from the cfe-dev mailing list fixes it:
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,15 +5,15 @@ if( MSVC )
endif()
set(LLVM_USED_LIBS
+ clangFrontend
+ clangSerialization
+ clangDriver
+ clangSema
clangAnalysis
clangAST
- clangBasic
- clangDriver
- clangFrontend
- clangLex
clangParse
- clangSema
- clangSerialization
+ clangLex
+ clangBasic
)
Original issue reported on code.google.com by [email protected]
on 8 Feb 2011 at 5:52
What steps will reproduce the problem? Give the *exact* arguments passed
to include-what-you-use, and attach the input source file that gives the
problem (minimal test-cases are much appreciated!)
1. Try to build on OS X
What is the expected output? What do you see instead?
Should work. Instead, I get several errors about typeid not working with
-fno-rtti in the system's tr1 headers.
If I run `make REQUIRES_RTTI=1`, things work fine (I ran it for both building
llvm and iwyu; not sure if it's required for both).
What version of the product are you using? On what operating system?
trunk as of now, os x 10.6
Please provide any additional information below.
Original issue reported on code.google.com by [email protected]
on 5 Feb 2011 at 3:29
Hello,
I've been playing with iwyu (r22 from the svn repository), running on Win7. I
have a trivial fix from my first evening's hacking.
StripPathPrefixAndGetAssociatedIncludeMap is incorrectly differentiating
between absolute and relative paths on Win32. With this input:
C:\dev\test_iwyu>type test.cpp
#include <math.h>
#include <stdio.h>
#include <string.h>
int main()
{
printf( "Hello: %f\n", sinf(0.0f) );
}
I see this output:
C:\dev\test_iwyu>include-what-you-use test.cpp
test.cpp should add these lines:
#include "c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include/math.h"
#include "c:\Program Files (x86)\Microsoft Visual Studio
10.0\VC\include/stdio.h"
test.cpp should remove these lines:
- #include <math.h> // lines 1-1
- #include <stdio.h> // lines 2-2
- #include <string.h> // lines 3-3
The full include-list for test.cpp:
#include "c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include/math.h"
#include "c:\Program Files (x86)\Microsoft Visual Studio
10.0\VC\include/stdio.h"
---
There's clearly a couple of issues here, but one that's easy to fix is iwyu
turning the angle-bracket/system includes into quoted/'user' includes. Other
issues aside, I'd expect to see this output:
C:\dev\test_iwyu>include-what-you-use test.cpp
test.cpp should add these lines:
#include <c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include/math.h>
#include <c:\Program Files (x86)\Microsoft Visual Studio
10.0\VC\include/stdio.h>
test.cpp should remove these lines:
- #include <math.h> // lines 1-1
- #include <stdio.h> // lines 2-2
- #include <string.h> // lines 3-3
The full include-list for test.cpp:
#include <c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include/math.h>
#include <c:\Program Files (x86)\Microsoft Visual Studio
10.0\VC\include/stdio.h>
---
The attached patch should fix this. I'm using llvm::sys::path::is_relative()
rather than checking for a leading "/". I'm on the lookout for any other issues
along these lines...
(The bigger issue of <math.h> becoming absolute, i.e. the '// TODO(csilvers):
get a full list of include dirs from the compiler.' is for another night :)
Regards,
Paul
Original issue reported on code.google.com by [email protected]
on 16 Feb 2011 at 11:48
Attachments:
When the compile line refers to a source file by its absolute name iwyu
suggests that the includes be changed to absolute:
jason$ cat Foo.h
#ifndef _FOO_H_
#define _FOO_H_
class Foo {
Foo();
};
#endif
jason$ cat Foo.cpp
#include "Foo.h"
Foo::Foo() {}
jason$ include-what-you-use /Users/jason/Desktop/iwyu/Foo.cpp
/Users/jason/Desktop/iwyu/Foo.cpp should add these lines:
#include </Users/jason/Desktop/iwyu/Foo.h> // for Foo
/Users/jason/Desktop/iwyu/Foo.cpp should remove these lines:
- #include "Foo.h" // lines 1-1
The full include-list for /Users/jason/Desktop/iwyu/Foo.cpp:
#include </Users/jason/Desktop/iwyu/Foo.h> // for Foo
---
However when referring to the source file by relative name the output is as
expected:
jason$ ~/Sources/llvm/build/bin/include-what-you-use Foo.cpp
(Foo.cpp has correct #includes/fwd-decls)
Original issue reported on code.google.com by [email protected]
on 7 Feb 2011 at 7:24
iwyu reorders #include files alphabetically. This does not work for projects
that have a different style, such as including public headers before internal
ones, and one particular public header before the other public ones. (For
example, in ICU.)
Please add an option to turn off reordering. In that case, iwyu should add new
#includes after the last existing one.
Original issue reported on code.google.com by markus.icu
on 5 May 2011 at 8:32
/path/to/include-what-you-use creditcard_field.cc
What is the expected output? What do you see instead?
No errors. Instead:
creditcard_field.h should add these lines:
#include "autofill_field.h" // for AutofillField
creditcard_field.h should remove these lines:
- class AutofillField; // lines 3-3
The full include-list for creditcard_field.h:
#include <vector> // for vector, etc
#include "autofill_field.h" // for AutofillField
AutofillField is used in the header as:
static void Parse(std::vector<AutofillField*>::const_iterator* iter);
If you take off the ::const_iterator part in the declaration and dfn, iwyu does
not produce the error stated above.
What version of the product are you using? On what operating system?
r96.
Original issue reported on code.google.com by [email protected]
on 29 Mar 2011 at 9:06
Attachments:
When reordering #includes, iwyu appears to use a case-sensitive ASCII
comparison. It would be nicer to be case-insensitive, and even better to also
sort punctuation before digits before letters.
Original issue reported on code.google.com by markus.icu
on 5 May 2011 at 8:34
What steps will reproduce the problem? Give the *exact* arguments
I seem to be coming up against an iwyu problem with Macros
Let say we have 1 cpp and 1 header in test folder
--> the cpp "Macro.cpp"
#define Vector_ bool
#define TYPE int
#include "Macro2.h"
#undef TYPE
#define TYPE double
#include "Macro2.h"
#undef TYPE
int main()
{
f(3);
f(3.1);
}
--> the header "Macro2.h"
void f(TYPE const t) {
}
What is the expected output? What do you see instead?
I should see "correct includes", instead iwyu want to remove #include "Macro2.h"
What version of the product are you using? On what operating system?
iwyu r250
Please provide any additional information below.
Original issue reported on code.google.com by [email protected]
on 22 Jun 2011 at 5:14
hummer:include-what-you-use thakis$ ack GetBestIncludeForSymbol .
iwyu_include_picker.h
82: // GetBestIncludeForSymbol, and probably will rarely need to be
Original issue reported on code.google.com by [email protected]
on 5 Feb 2011 at 3:37
That description uses scoped_ptr and the instantiation of its con- and
destructor to demonstrate that a forward declaration of "T" is sufficient for
scoped_ptr<T> to work.
But according to boost docs, T shall be a complete type when scoped_ptr<T> is
implicitly instantiated.
Original issue reported on code.google.com by [email protected]
on 5 Feb 2011 at 3:20
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.