Commit Graph

135 Commits

Author SHA1 Message Date
Kim Gräsman 81ee985377 Ignore uses of declarations from inside of functions
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
2023-01-22 20:35:42 +01:00
Kim Gräsman 80410de523 Renumber the full-use trimming steps
... to make room for a new one at the very top, now denoted 'TBD'.

We only do this separately to keep the diff less noisy.
2023-01-22 20:35:42 +01:00
Kim Gräsman bd305afe7d Support 'IWYU pragma: export' for forward declarations
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.
2023-01-22 20:32:32 +01:00
Kim Gräsman c3f92ad08f Remove outdated TODO
<iterator> is now required, not due to a bug, but because it provides
std::inserter.

Remove TODO and update why-comment.
2023-01-07 21:26:41 +01:00
Kim Gräsman d7e4a20e8f Clean out IWYU pragma comments in IWYU itself
None of these pragmas are necessary at this point.
2023-01-07 21:26:41 +01:00
Kim Gräsman 849c2a2f55 Format all lines with trailing whitespace
This is the result of:

    git grep -n "\s$" | grep-format

No functional change.
2023-01-07 12:27:16 +01:00
Kim Gräsman b65c4b63a7 Format all lines with leading =
This is the unadorned output of:

    git grep -En "^\s*=" -- ':!tests/*' | grep-format

There are some examples with comments between the variable name and the
'=' that clang-format left unchanged.

No functional change.
2023-01-07 12:27:16 +01:00
Kim Gräsman 890a3150d7 Format all return statements on their own line
This is the unadorned result of:

    git grep -En "\w.*return .*;" -- ':!tests/*' | grep-format

Having return statements on their own line makes it easier to set
breakpoints in most debuggers.

No functional change.
2023-01-07 12:27:16 +01:00
Kim Gräsman 616927dec4 Avoid dynamic mapping to self for reverse macro dependency
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.
2022-12-04 16:18:13 +01:00
Kim Gräsman 6d5414fcf3 Add consistent logging for dynamic mappings
* Do all this logging on level 8, whether logging is on for file or not
* Always say "Add dynamic mappings..."
* Don't log quoted from->to, that's already logged in AddMapping
* State the reason dynamic mapping is added
* Include file paths where available

This should make it easier to troubleshoot strange effects from dynamic
mappings triggered by IWYU itself.
2022-12-04 16:18:13 +01:00
Bolshakov b20224b9fc Fix opaque decl of enum with bool underlying type
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.
2022-11-25 20:24:25 +01:00
Kim Gräsman 7ca0a75b85 [clang compat] Harden handling of 'final' specifier
Clang 9f57b65a272817752aa00e2fb94154e6eed1d0ec sometimes prints the 'final'
keyword twice for a declaration (tracking bug:
https://github.com/llvm/llvm-project/issues/56517).

This triggered several bugs in MungedForwardDeclareLineForTemplates:

* Only removed first 'final'
* Removed one character too many (sizeof(char[]) includes the trailing NUL)

Instead, replace all occurrences of 'final' and do it first so the stripping of
superclasses and body also get rid of trailing spaces. This should now work even
if the upstream bug is fixed.
2022-07-16 15:43:31 +02:00
Bolshakov fb41044b9f Suggest enumeration opaque declarations
Opaque (i.e., in fact, forward) declarations are allowed for scoped
enumerations and unscoped ones with underlying type explicitly
specified.
2022-06-13 07:47:21 +02:00
Bolshakov 799a8ef1b5 Replace RecordDecl by TagDecl
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.
2022-06-13 07:47:21 +02:00
Bolshakov 496d200ce0 Avoid double reporting of all class members
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.
2022-05-28 22:54:19 +02:00
Daniel Hannon 3f456f66c2 add --comment_style option with tests 2022-05-28 11:03:47 +02:00
Jan Kokemüller 8bc14b8f04 Do not warn on unnamed struct fields 2022-05-18 20:21:09 +02:00
Salman Javed 75226c1ce8 Add `--update_comments` option
Fixes #75 and fixes #494.
Add `--update_comments` option to make IWYU always print the 'why'
#include comments, regardless of whether any include lines need to be
added or removed. With this change, IWYU will update the "// for xyz"
comments as the code changes, preventing the comments from becoming
stale.
2021-10-01 06:31:27 +02:00
Kim Grasman c311760516 Improve detection of builtin functions
The technique used before relied on linear search of all builtins by
name. This did not work with qualified C++ names of C library names such
as std::pow and std::round.

Use ASTContext to get to BuiltinInfo, and in turn use that to check more
specific traits of the builtin by ID instead of name.

Add distinct tests for C and C++ to cover both <math.h> and <cmath>.

Fixes issue #776.
2021-06-05 11:13:26 +02:00
Alexey Storozhev 4f87d580cb Replace direct member access with a getter 2021-05-22 14:20:09 +02:00
Alexey Storozhev 7115b0e30a Get a FileEntry for <new> imports
This change is driven by the idea of switching to FileEntry/FileID-based
way of calculating IWYU violations.

Currently IWYU calculates the difference between presented and desired
imports by comparing the list of strings (OneIncludeOrForwardDeclareLine::line),
but it would probably be easier and more reliable to operate with
FileEntries and FileIDs to determine the unused imports and their
locations.

In order to switch from a string-based solution all the
"stringly"-represented imports should be replaced with a corresponding
FileEntry or a FileID.

This change uses the preprocessor to lookup the FileEntry for `<new>`
in the corner case that reports the "placement new" symbol usage.
2021-05-22 14:19:14 +02:00
Florian Schmaus 60b2ea7050 Do not provide arguments when calling Decl.isReplaceableGlobalAllocationFunction()
LLVM added a second boolean argument to
isReplaceableGlobalAllocationFunction() with 3dd5a298bfff ("[clang]
Annotating C++'s `operator new` with more attributes"). However both
parameters define a default argument. Hence there is no need to
explicitly state the argument, if it is already the default argument,
which is nullptr is isReplaceableGlobalAllocationFunction() case. This
also increases readability.
2020-11-08 19:41:04 +01:00
John Bytheway b4838853e5 Remove trailing whitespace from source files 2020-05-24 14:14:59 +02:00
Kim Grasman 6ce8df6aa4 Don't second-guess template specializations
Before this patch, IWYU would skip past template specializations and go
for the base template when trying to find the definition for a class
template.

This led to misbehavior as reported in issue #735 so that:

    // template.hpp
    template<typename>
    struct T;

    template<> struct T<int> { int x; };

    // source.cpp
    #include "template.hpp"

    int f(T<int>& t) { return t.x; }

would require a forward declaration of the base template in source.cpp.

Remove this step on the basis that we _are_ in fact using the
specialization, and the file containing the specialization will probably
have some declaration (or even definition) of the base template.
2020-05-23 10:54:37 +02:00
Kim Grasman a85cea1b30 Improve handling of placement new
Instead of 'IsDefaultNewOrDelete' which uses heuristics and string
parsing, use FunctionDecl::isReplaceableGlobalAllocationFunction from
the Clang API. It returns true for any replaceable allocation function,
which happens to coincide nicely with all allocation functions except
placement new.

Fixes #777 and improves behavior for the modern allocation functions:

- Sized deallocation in C++14
- Aligned allocation in C++17

This small improvement fixes a number of TODOs in the new placement_new
testcase, and makes it possible to add a testcase for implicit aligned
allocation in operator_new, as aligned allocation no longer requires
<new>.

Patch based on work and lots of good input from Adar Dembo.
2020-05-02 11:42:24 +02:00
Andrea Bocci 53487d2097 Add explicit conversion from llvm::StringRef to std::string
llvm/llvm-project@777180a makes the llvm::StringRef conversion operator
to std::string explicit.
These changes add a call to the str() method to perform the conversion.

Signed-off-by: Andrea Bocci <andrea.bocci@cern.ch>
2020-03-03 21:44:35 +01:00
Kim Grasman f4ef6528d9 Expose use flags directly from OneUse
This makes it clearer which flags are used where.
2019-12-26 16:41:12 +01:00
Miklos Vajna 6d7574e6c5 iwyu_output: add using decl for dyn_cast
Seems that's the style used elsewhere. Fixes this build error against
latest llvm-project.git:

/home/vmiklos/git/include-what-you-use/iwyu_output.cc: In function ‘bool include_what_you_use::internal::DeclCanBeForwardDeclared(const clang::Decl*, std::__cxx11::string*)’:
/home/vmiklos/git/include-what-you-use/iwyu_output.cc:727:35: error: ‘dyn_cast’ was not declared in this scope
   } else if (const auto* record = dyn_cast<RecordDecl>(decl)) {
                                   ^~~~~~~~
/home/vmiklos/git/include-what-you-use/iwyu_output.cc:727:35: note: suggested alternatives:
In file included from /home/vmiklos/git/llvm/instdir/include/clang/Basic/LLVM.h:21:0,
                 from /home/vmiklos/git/llvm/instdir/include/clang/AST/APValue.h:17,
                 from /home/vmiklos/git/llvm/instdir/include/clang/AST/Decl.h:16,
                 from /home/vmiklos/git/include-what-you-use/iwyu_output.h:27,
                 from /home/vmiklos/git/include-what-you-use/iwyu_output.cc:10:
/home/vmiklos/git/llvm/instdir/include/llvm/Support/Casting.h:342:61: note:   ‘llvm::dyn_cast’
 LLVM_NODISCARD inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) {
                                                             ^~~~~~~~
/home/vmiklos/git/llvm/instdir/include/llvm/Support/Casting.h:332:5: note:   ‘llvm::dyn_cast’
     dyn_cast(const Y &Val) {
     ^~~~~~~~
/home/vmiklos/git/include-what-you-use/iwyu_output.cc:727:54: error: expected primary-expression before ‘>’ token
   } else if (const auto* record = dyn_cast<RecordDecl>(decl)) {
                                                      ^
2019-11-23 16:17:20 +01:00
Kim Grasman 393a5fa358 Better reporting when disqualifying forward-decls
Introduce an overload to DeclCanBeForwardDeclared which puts a reason in
an output parameter, so logging can say in more detail why a declaration
was not qualified for forward declaration.

Keep the old overload as a plain forward, not all call sites want or
need the reason string.
2019-11-09 16:23:08 +01:00
Kim Grasman 613efed42e Disable forward-declares for decls in inline namespaces
Technically users can forward-declare inline namespaces, e.g.

  namespace std {
  inline namespace __1 {

  template <class T>
  struct hash;

  }
  }

but that would be both confusing and problematic:

1) The symbol is referred to as std::hash, but declared here with a name
   nobody should ever see.
2) When a new ABI version is added for std::hash, a new internal
   namespace -- e.g. __2 -- will be added, and std::hash and
   std::__1::hash no longer refer to the same symbol.

As inline namespaces are intended primarily as a versioning feature for
library authors, avoid trying to second-guess them and just require a
full use for any decl inside an inline namespace.

This fixes issue #713.
2019-11-09 16:23:08 +01:00
Kim Grasman 8353f98e6a Remove HasAnonymousNamespace
There's already a Decl::isInAnonymousNamespace in the Clang API.

No functional change.
2019-11-09 16:23:08 +01:00
Uladzislau Paulovich 981001cfee Fix final class forward-declaration bug 2019-09-30 21:55:51 +02:00
Kim Grasman 919f21b5ff Remove ineffectual variable endpos
A (misspelled) comment said something about adjusting for trailing
spaces, but at that point the string had already been shortened several
times. I suspect this is just a left-over.

All tests pass with this removed, so let's revisit it with test coverage
if any bugs fall out.
2019-09-29 14:54:09 +02:00
John Bytheway 2bd1ddee4a Fix symbol mappings to relative includes
If a symbol was ultimately mapped to a header which was (or should be)
included via a ""-style relative include then that would not be handled
correctly.

Update the symbol mappings to be handled in the same way as the include
mappings so that this should no longer be an issue.
2019-09-01 16:41:53 +02:00
John Bytheway 1513718871 Fix combination of pragma export and "" includes
Fix some corner cases that can arise due to interaction between pragma
export and includes that are relative to the including header (i.e.
includes that can only be done using "", not <>).

Because headers are mostly handled as quoted includes for the purposes
of mapping, this can go wrong with relative includes because they are
not always relative to the same place, and at some places in the code we
don't even know what they're relative to.

Fix this by tracking full paths in parallel or instead of quoted
includes in certain places.
2019-09-01 16:41:53 +02:00
John Bytheway fe8e57b441 Introduce MappedInclude wrapper struct
Currently this is just a simple wrapper around a quoted include.  This
provides some type safety, but no behavioural change is intended.

This lays the groundwork for adding more data to the MappedInclude
object in order to fix some bugs.
2019-09-01 16:41:53 +02:00
Levente Győző Lénárt bc381437ce Find a decl before the use with --no_fwd_decls
If we find a fwd-decl use with --no_fwd_decls, we see if there is already an
include that provides the decl, and if there is, we keep that include otherwise
we keep the local decl.
2019-07-31 16:18:09 +02:00
Kim Grasman a7d99d15b3 Make --no_fwd_decls respect local forward decls
Before this, the --no_fwd_decls mode would force-remove existing forward
decls:

    class Foo;
    void Bar(const Foo*);

Add an additional rule that we avoid promoting uses of forward-
declarations in the same file to full uses, to retain forward-decls like
the above.

This makes the behavior of --no_fwd_decls simpler and more consistent:
optimize for fewer redeclarations instead of fewer includes. Whenever
there's a choice between a forward-decl and an include, choose the
include.

Add test coverage for more variants of included forward decls.
2019-03-19 20:11:33 +01:00
John Bytheway e00e5f1f09 Stop ignoring uses for builtins with mappings
IWYU used to ignore all uses of builtins.

This makes sense normally.  However, when a symbol has an explicit
mapping defined, we should not ignore uses of it.

In particular, for example, one might require a particular header to be
included when certain builtins are used, and this change allows that by
defining a mapping for that builtin.

Also, under some situations some standard library functions (e.g.
std::round) get treated as builtins.  With this change IWYU respects
mappings for such builtins, and by defining them suitably it will no
longer remove #include <cmath>.
2019-03-08 08:54:37 +01:00
John Bytheway 33b7ce7500 Refactor check for builtin function
Create a new function to test whether a decl is a builtin function.
2019-03-08 08:54:37 +01:00
John Bytheway ca65ee68c2 Support headers using symbols mapped to themselves
Currently if IWYU decides that the best header for a symbol is the same
one that uses the symbol, it can cause that header to add a #include of
itself.

This in particular can happen with mappings.

Detect this case and cause the use to be ignored.

Furthermore, when choosing from multiple public mapping headers, prefer
to use oneself where possible (since that minimizes #includes).
2019-03-04 07:36:01 +01:00
Miklos Vajna 353a6da9b7 Add new --cxx17ns option
This opts in for the more concise syntax introduced in C++17: namespace
a::b { ... }.

Usage of this is especially useful in codebases where existing forward
declarations in nested namespaces already use this form: so the IWYU
suggestion for new forward declarations can be consistent with the
existing ones.

fix_includes.py already handled this, but add a test to maintain this
behavior, too.
2019-02-06 19:55:19 +01:00
John Bytheway 9945e543d8 Support nested wrapper headers
The existing code coped poorly with the case where header A includes B
includes C includes D where D is a private header and B and C are both
public headers for a symbol in D.  In this case B would be forced to
include D directly when it ought only to be including C.

Fix this by an additional condition on the special case intended to
handle these sorts of situations.

For further detail, see discussion at
https://github.com/include-what-you-use/include-what-you-use/pull/615

Also test.
2019-01-05 21:49:10 +01:00
J.Ru 27da44e009 Introduce an extra use flag UF_ExplicitInstantiation
To signal that the use refers to an explicit instantiation, for which the
"canonical" decl is not suitable.

Also, since it is meant to be used in a specific context, the ReportDeclUse
prototype has been adapted to take optional extra flags as an additional
input.
2018-12-07 09:12:01 +01:00
J.Ru e31cd2adda Handle builtins properly during template traversal
Don't assume that the decl for a template specialization must always be
a record. If, for example, such template is built in, the decl will derive
from TemplateDecl instead.

Also, explictly look for BuiltinTemplateDecl during post processing to
correctly identify them as builtins. If this is not done, a following
check would ignore them anyway but in that case they will be reported as
"backwards includes".

Function builtins handled now using getBuiltinID/isBuiltinFunc from clang
to identify all the predefined symbols that have no include and should be
ignored. Before, only the symbols prefixed with __builtin_ were identified.

Fixes #150
2018-08-11 16:39:58 +02:00
Scott Ramsby 4a0cb6a526 Add option to change header ordering to place quoted local project headers first 2018-06-11 21:28:48 +02:00
Scott Ramsby 8ceeb7c529 Refactor header sorting logic to be more clear 2018-05-26 02:09:43 +02:00
Christoph Weiss f1ec249c42 fix dangling reference and unused argument 2018-03-15 21:25:56 +01:00
Kim Grasman 2406addcc7 Count free function definitions as uses
Now that we can provide context for uses with use flags, we can tweak
IWYU behavior when a function is being defined.

This allows us to treat a function definition as a use of all
previously-seen declarations.

Fixes #179, #491 and #441.
2018-03-09 20:37:52 +01:00
Kim Grasman aa2bc1f9e0 Replace in_cxx_method_body with an extensible use-flag
This makes it possible to pass more context information about a use
from the detection phase to later IWYU analysis phases.
2018-03-09 20:37:52 +01:00