The full type use reporting in the three covered cases is ensured
with excessive `CanIgnoreType` calls which check not only the type
to be reported but also the type before dereferencing (which occurs
to be in the resugaring map). This approach should be refactored
in subsequent commits.
Using type deduction, a function can define a local type and return it:
auto func() {
struct X {};
return X();
}
Before this change, IWYU would register X as a use for callers of func.
In certain situations (union inside lambda inside macro) this would lead
to a forward-declare use trying to format a forward-declaration of the
type local to the function in PrintForwardDeclare. This led to a crash
since the lambda was unnamed, but there's really no point trying to
forward-declare a type that is private to a function.
Generalize this so we ignore all uses of symbols declared inside a
function. In order to get in contact with that symbol, we must already
have access to the function, so the containing header must already be
included.
Fixes issue: 795
Covers both begin_export/end_export blocks and single-line export
pragmas.
Like with 'IWYU pragma: keep' marks the forward decl as automatically
desired to avoid removing manually exported but unused decls.
Add a simple testcase and update documentation.
Previously, ReportDeclUse was called for TypedefDecl when TypedefType
is passed to ReportTypeUse. This change short-circuits that path. But
an underlying type should still be reported if the typedef doesn't
"provide" it. Hence, corresponding logic is moved into ReportTypeUse.
So ReportDeclUse reports typedef declarations and ReportTypeUse reports
typedef underlying types now.
Report fwd-decls only for explicitly written types
There is no point in reporting forward-declaration of a type when just
its pointer is used and the type is not explicitly written
in the source. Explicitly written pointer types are handled, e.g.,
in VisitTemplateSpecializationType and VisitTagType.
Add test cases for redundant fwd-decl absence
In very particular circumstances (see test case), VisitFunctionDecl
would see a function definition that was an implicit constructor of a
builtin (va_list_tag).
Rather than crashing for implicit code, just say it's not in a header.
This feels a little questionable, because depending on how IsInHeader is
used, it might be misleading that it returns false for builtins/implicit
code. But I think it makes sense for now.
Fixes issue #1162.
Non-sugared template specialization type template arguments are already
analyzed due to 'TraverseType' call inside
'InstantiatedTemplateVisitor::TraverseSubstTemplateTypeParmTypeHelper'
and subsequent 'TraverseTemplateSpecializationTypeHelper' call.
Components of sugared template specialization types are added into
resugar_map, otherwise their template arguments would not be reported.
Test case has been extended.
Full template specialization type use requires full information about
its template-argument-dependent fields and nested typedefs. But earlier,
it wasn't reported in many cases when template specialization type isn't
written explicitly in non-fwd-decl context.
Commit 04f1c92537 added a mechanism that
dynamically adds a mapping from the includee to the includer in this
case:
// a.h
#if CONTROL_FLAG
void foo();
#else
void bar();
#endif
// b.h
#define CONTROL_FLAG
#include "a.h"
However, there was no check that includee and includer were different,
so regular #include guards would cause self-mappings, which would
eventually lead to cycles in mappings and assertion failures, e.g.:
Cycle in include-mapping:
<z.hpp> ->
<z.hpp>
,,,/iwyu_include_picker.cc:845: Assertion failed: Cycle in include-mapping
Aborted
Avoid this by checking if the file defining the macro is the same as the
file using it; in that case we don't need a mapping.
Only attempt to report decl uses of template names that have an
underlying template decl. This ignores uses of dependent templates and
potentially other such variations.
Even if that causes us to miss reporting for some valid constructs, it
allows further analysis of files that would otherwise crash IWYU.
Fixes issue #1140
Boolean type is internally represented in clang as '_Bool' builtin type.
In order to display it correctly taking into account language options,
actual printing policy should be used.
this was a proposed issue in #1095 where one could
make a block of keeps as opposed to marking every
keep with a pragma: keep instruction.
added test to verify and updated documentation
where appropriate.
This is useful to generically remap files from one directory to another.
The following mapping would for instance map all files under the "foo/"
directory to "third_party/foo/", for instance, mapping "foo/bar.h" to
"third_party/foo/bar.h".
[ { include: ['@"(foo/.*)"', private, '"third_party/\1"', public ] } ]
This is useful for large project where different third_party libraries
are compiled together. In Chromium for instance, include paths would
look like:
-Ithird_party -Ithird_party/v8/include
This allows code in V8 to include its own headers directly. Other
third_parties would include them via "third_party/v8/include/...".
Because files are accessible from two different paths, IWYU can't know
which should be used. Using a mapping file, adding or removing the
"third_party/v8/include" prefix where needed, resolves this problem.
This change provides better location info when using macros such as:
BOOST_CHECK_THROW(..., Exc);
The use of type Exc would be attributed to the file defining the macro
before this patch, but is now correctly attributed to the expansion
location.
Co-authored-by: Kim Gräsman <kim.grasman@gmail.com>
A function may just transmit passed-by-reference parameter somewhere.
Requirement to explicitly write forward declaration in the same file
(.cpp-file) to avoid '#include' suggestion is impractical when that type
is already fwd-declared in the corresponding header.
'Autocast' may still make sense for header-defined functions, due to
unlimited number of possible callers, so analysis of those fuctions
is kept.
Both function declaration site handling and call site handling
are changed.
Some standard libraries have a [[nodiscard]] attribute on std::find,
which leads to a warning about unused return value, which in turns masks
any real results from the test.
Avoid std::ignore since this test is older than C++11.
It is needed in order to be able to add definition to passing-by-ref
function and test on it "autocast" rules, not type info requirement
due to parameter variable definition.
New 'DirectStruct*'s and 'TplDirectStruct*'s are added because
requirement to '#include' their header is tested only by that
'#include', no inline diagnostics are emitted.
Clang recently moved to gnu++17 by default, where dynamic exception
specifications are no longer supported. Upstream change:
3e99b8d947
Since badinc.cc is all pre-C++11 code, pin the language standard for
it to gnu++98, which has a number of interesting benefits:
* makes it less rewarding to add new tests here
* any standard library changes have significantly lower impact
* it's about 30% faster
No functional change.
There is no need in reporting enum opaque declaration or full use if
enumeration type name or enumerator name isn't explicitly written,
because it should already be present elsewhere in the translation unit,
probably through included headers.
IWYU doesn't produce any outputs, so -save-temps does not have any useful
effect.
Before this patch, passing -save-temps did, however, generate multiple
compilation jobs which caused a fatal error:
error: unable to handle compilation, expected exactly one compiler job
Filter the arguments out, similar to what Clang tools do by default.
Fixes issue #1060.
Desugar performs the same desugaring as RemoveElaboration, and more.
This patch is a straight:
git grep -l "RemoveElaboration" | xargs sed -i -e 's/RemoveElaboration/Desugar/'
followed by a test cleanup in badinc.cc, where Desugar sees through more sugar
than RemoveElaboration, and actually produces better results.
This covers the common C pattern of declaring a typedef for a struct before the
struct itself, e.g.
typedef struct foo foo_t;
struct foo {
int value;
foo_t *next;
};
Fixes issue #1065.
Previously, it doesn't really check the need of including a file
with a type referred to by typedef from specialized template
'Container<Class>', because that file was reported due to declaration
of 'Pair' typedef. Now, it shows an error: Class1 full usage through
nested typedef or alias doesn't trigger full type requirement.
Some standard libraries require that any std::less<> specializations have a
const operator(). That seems hygienic anyway, so add a const qualifier.
Fixes the precomputed_tpl_args test on FreeBSD (and probably Mac).
The reason is that
1) enumerators led to much noise in explanatory comments
(the idea is similar to cedf9d6984323a0a68847d), and
2) without this change, EnumClass::Item is reported separately
as fwd-decl use of EnumClass along with the full use
of EnumClass::Item.
Unnamed enums are an exception.
This is preparation for adding suggestions for enumeration opaque
(forward) declarations. Enums should be treated almost similar
to classes and structs, so clang::RecordDecl should be replaced
by clang::TagDecl, which is a superclass for RecordDecl and EnumDecl,
in many places.
We used to ignore all analysis of AST nodes inside a `typedef`, but that
caused us to miss author-intent analysis of nested typedefs.
Remove the special casing for member-of-typedef now that reporting as a
whole is less granular (we now report only the parent type instead of
all nested components).
Add test cases to demonstrate that nested typedefs observe
the author-intent rules.
In addition to C++ methods, silence reports of all declarations inside a
class (data members, types, etc.) if the parent type has already been
reported.