Commit Graph

1277 Commits

Author SHA1 Message Date
Kim Gräsman 44444960dc Remove unnecessary namespace qualifiers
Add using-declaration for clang::TemplateDecl, and remove explicit
namespace qualifiers for use of RecordDecl and CXXRecordDecl, which are
already pulled in with using-declarations.

No functional change intended.
2022-12-04 16:09:05 +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 9f68769aa1 [ci] Update CI builder to ubuntu-22.04 2022-11-13 13:02:04 +01:00
Kim Gräsman 9bcfd0b1a1 [clang compat] [cmake] Use LLVM major ver for resource headers
The clang-resource-headers CMake target is not exported from the
packaged LLVM/Clang CMake modules, so we synthesize it by explicitly
copying resource/built-in headers from the package install root to the
build dir.

Clang 16 changed the structure not to use major.minor.patch but rather
just the major version (in line with LLVM versioning at large).

Adjust so we pick up the headers from the right place, and put them
where Clang libraries will be looking.
2022-11-13 13:02:04 +01:00
Kim Gräsman a6a3e0830a Bump version to 0.20 on master 2022-11-02 21:01:48 +01:00
Kim Gräsman 7325bf5901 Update README for IWYU 0.19 2022-11-02 19:48:02 +01:00
Daniel Hannon cf1624a4e2 Add begin_keep and end_keep pragmas, test and docs
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.
2022-11-02 19:33:10 +01:00
Kim Gräsman 109fdb4cdd Revert "See through C++20 consteval for conversion functions"
A proper fix is now available in LLVM as of
https://github.com/llvm/llvm-project/commit/403d7d8d7093d6637a006f8b3f7538

This reverts commit 7d7fd80da7.
2022-11-01 19:18:17 +01:00
Daniel Hannon f20eadd206 [clang compat] Use TemplateSpecializationType ArrayRef APIS
clang 1acffe81ee9117691812b9bf8747c03354177d15 changed the API for
clang::TemplateSpecializationType to no longer have getArgs() or getNumArgs()
This change replaces them with template_args() and retains the previous logic
2022-10-30 20:29:59 +01:00
Kim Gräsman 6d416d5f90 Extract helper function to only add regex anchors if necessary
This avoid double-anchoring, for example if users put their own anchors
in mappings. It also reduces clutter in the RegexMatch/RegexReplace
functions now that both need to do the same anchoring.
2022-10-09 21:28:37 +02:00
Kim Gräsman fb4093be77 Remove superfluous comment
RegexMatch already has a doc comment in the header.
2022-10-09 21:28:37 +02:00
Jean-Philippe Gravel 6fb66575fb Add support for group/backreferences regex replacement in mapping files.
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.
2022-10-09 20:40:18 +02:00
jspam b74819dc5f
Use more exact location for caught exceptions
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>
2022-10-09 16:35:19 +02:00
Bolshakov aa9a2d2a55 Test "autocast" rules on header-defined functions 2022-10-08 16:17:50 +02:00
Bolshakov bbbae2d858 Clarify comment 2022-10-08 16:17:50 +02:00
Bolshakov 862812049a Avoid 'autocast' reporting for function definition
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.
2022-10-08 16:17:50 +02:00
Kim Gräsman 8b3da1112e Better support CRLF line endings in custom lexer
Running the tests/cxx/comment_pragmas.cc test on Windows fails saying
that <some_system_header_file> is not diagnosed correctly.

Turns out to be because our custom lexer for GNU @headername comment
directives did not respect Windows line endings, and failed properly
identify the @headername.

Match on both CR and LF when attempting to find end of line.
2022-10-08 12:37:55 +02:00
Et7f3 24985e2ecf
fix: Don't force pull MacOs libcxx's header
As a fix for issue #247 we added a block of hard-coded paths to the
include search path, which would find libc++ from the MacOS SDK.

While the MacOS SDK is usually present where IWYU is run, on developer
machines, there may be any number of other sysroots providing libc++
that users would prefer to use.

The Nix tool is one such player, where builds are isolated and all
dependencies are gathered in a single root for reproducibility.

Recent experiments with Clang on different Mac systems show that:

* if the MacOS SDK is present, IWYU picks it up automatically via the
  Clang driver
* if the MacOS SDK is not present, no include paths are conjured out of
  thin air
* Clang installed from Homebrew llvm package automatically finds the
  libc++ also provided as part of that package

It seems only IWYU forcefully adds magic paths, and it causes
problems for folks who want to do the right thing and build the sysroot
themselves. So remove these hard-coded paths.

If there is no installation of libc++ discoverable to Clang's probing,
or an alternative libc++ is desired, users can disable probing and
specify relevant paths directly on command-line:

  # for Homebrew version of llvm-14
  include-what-you-use -nostdinc++ \
      -isystem /opt/homebrew/opt/llvm\@14/include/c++/v1 \
      sourcefile.cc

  # for Apple Command Line Tools version of libc++
  include-what-you-use -nostdinc++ \
      -isystem /Library/Developer/CommandLineTools/usr/include/c++/v1 \
      sourcefile.cc

The mechanics of this technique is described in more detail for Clang:
https://libcxx.llvm.org//UsingLibcxx.html#using-a-custom-built-libc.

Co-authored-by: Kim Gräsman <kim.grasman@gmail.com>
2022-10-08 11:59:14 +02:00
Kim Gräsman c1d8dd310a Explicitly ignore std::find result in iterator test
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.
2022-10-03 16:45:37 +02:00
Andrey Ali Khan Bolshakov 96f940149d
Test 'autocast' call site handling more precisely
Check that only the last parameters require full type info for autocast.
2022-10-03 16:44:56 +02:00
Bolshakov ff1b866acf Test 'autocast' to value and reference separately
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.
2022-10-03 14:53:56 +02:00
Bolshakov 2b6cc114d0 Reformat autocast test files
This prepares for adding some new well-formatted code.

No functional change.
2022-10-03 14:53:56 +02:00
Bolshakov 1d053edce2 Move autocast testing from badinc
More cases are covered by iwyu_stricter_than_cpp.
2022-09-12 18:58:19 +02:00
Kim Gräsman 164b8fe759 [clang compat] Add explicit -std=gnu++98 to badinc.cc
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.
2022-09-11 21:53:28 +02:00
Kim Gräsman c685e46c4e Don't attempt to canonicalize '<stdin>'
This little beauty would cause an assertion failure in GetCanonicalName:

  printf "#include <stdio.h>" | include-what-you-use -c -x c -

Special-case '<stdin>' like we do with '<built-in>'.

Fixes issue #1105.
2022-09-10 10:49:16 +02:00
Bolshakov 3db4d4ae02 Test absence of redundant enum reporting 2022-09-04 13:20:54 +02:00
Bolshakov 8751dac97b Avoid redundant enum type reporting
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.
2022-09-04 13:20:54 +02:00
Kim Gräsman f81ef2388e Move ^$ anchoring into RegexMatch
Only LLVM regexes need explicit anchoring; std::regex_match already has
full match semantics.

This saves us thousands of temporaries when using std::regex-based
dialects and actually improves processing time of

  $ time include-what-you-use -Xiwyu --regex=ecmascript -Xiwyu --mapping_file=qt5_11.imp tests/981/t.cc
  ...
  real    0m5,517s
  user    0m5,504s
  sys     0m0,013s

if only very slightly (~10%).
2022-09-03 15:04:27 +02:00
Kim Gräsman 2f561c1035 Remove unused capture group
When building regexes from @-prefixed mappings, we wrapped the
expression in ^(...)$ to force llvm::Regex::match to match only the
whole string.

The parentheses were probably added in there by accident, we have no use
for a capture group in this scenario, and the anchors are fine without
grouping.
2022-09-03 15:04:27 +02:00
Kim Gräsman 5b5dd13746 Add new testcase for --regex=ecmascript
The default for --regex is llvm, so it's covered by any existing tests
with mappings.
2022-09-03 15:04:27 +02:00
Kim Gräsman cf53880822 Add --regex option
As reported in issue #981, using std::regex in IWYU has caused a
tremendous performance regression for large mapping files containing
regex mappings.

  $ cat t.cc
  #include <string>

  # with llvm::Regex
  $ time include-what-you-use -Xiwyu --mapping_file=qt5_11.imp t.cc
  ...
  real 0m0,529s
  user 0m0,509s
  sys  0m0,020s

  # with std::regex
  $ time include-what-you-use -Xiwyu --mapping_file=qt5_11.imp t.cc
  ...
  real 0m29,870s
  user 0m29,717s
  sys  0m0,012s

qt5_11.imp contains 2300+ regex mappings, and <string> has a bunch of
includes, so this is a good testbed for regular expression engines, but
over 50x slower is not the result we were hoping for.

The reason we switched to std::regex was to get support for negative
lookaround (llvm::Regex does not have it), but exotic regexes in
mappings are pretty rare, and this is a significant performance hit.

Introduce a --regex option to select regex dialect, with documented
tradeoffs. Put the default back to LLVM's fast implementation.

This fixes issue #981.
2022-09-03 15:04:27 +02:00
Kim Gräsman 0a714265c0 Add regex module
Move regular expression matching into a function in its own module.

No functional change.
2022-09-03 15:04:27 +02:00
Alejandro Colomar 6f2b277e6d Add mappings for itimerspec
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
2022-09-03 12:37:20 +02:00
Alejandro Colomar 16df68dbb7 Add mappings for <bits/struct_stat.h>
struct stat members are implemented through macros and other
stuff, which is defined in that headers, so map the header to the
same headers that struct stat is mapped.

Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
2022-09-03 12:37:20 +02:00
Alejandro Colomar 3bb4e2dc8d Add mappings for getopt(3) and opt{arg,err,ind,opt}
Glibc also provides them in <getopt.h>, but let's recommend the
portable POSIX header only.

Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
2022-09-03 12:37:20 +02:00
Alejandro Colomar 57044c7e43 Add mappings for <bits/types/siginfo_t.h>
siginfo_t members are implemented through macros and other stuff,
which is defined in that header, so map the header to the same
headers that siginfo_t is mapped.

Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
2022-09-03 12:37:20 +02:00
Alejandro Colomar 58f925f063 Add mappings for <bits/mman-shared.h>
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
2022-09-03 12:37:20 +02:00
Kim Gräsman eee6d6a199 Drop -save-temps command-line args
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.
2022-09-01 20:03:59 +02:00
Boleyn Su 6f772242cf Add mapping of bits/utility.h for gcc.stl.headers 2022-09-01 19:50:08 +02:00
Alejandro Colomar 75623bce3b Fix mapping for <bits/syscall.h>
SYS_xxx macros, which are implemented in glibc in
<bits/syscall.h>, are intended to be included from
<sys/syscall.h>.  See syscall(2), amd also see the following:

$ grepc -k 'SYS_[a-z]\w+' /usr/include | head
/usr/include/x86_64-linux-gnu/bits/syscall.h:35:# define SYS_accept __NR_accept
/usr/include/x86_64-linux-gnu/bits/syscall.h:39:# define SYS_accept4 __NR_accept4
/usr/include/x86_64-linux-gnu/bits/syscall.h:43:# define SYS_access __NR_access
/usr/include/x86_64-linux-gnu/bits/syscall.h:47:# define SYS_acct __NR_acct
/usr/include/x86_64-linux-gnu/bits/syscall.h:51:# define SYS_acl_get __NR_acl_get
/usr/include/x86_64-linux-gnu/bits/syscall.h:55:# define SYS_acl_set __NR_acl_set
/usr/include/x86_64-linux-gnu/bits/syscall.h:59:# define SYS_add_key __NR_add_key
/usr/include/x86_64-linux-gnu/bits/syscall.h:63:# define SYS_adjtimex __NR_adjtimex
/usr/include/x86_64-linux-gnu/bits/syscall.h:67:# define SYS_afs_syscall __NR_afs_syscall
/usr/include/x86_64-linux-gnu/bits/syscall.h:71:# define SYS_alarm __NR_alarm
$ grep -rn bits/syscall.h /usr/include
/usr/include/x86_64-linux-gnu/bits/syscall.h:5:# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."
/usr/include/x86_64-linux-gnu/sys/syscall.h:27:   programs expect the traditional form SYS_*.  <bits/syscall.h>
/usr/include/x86_64-linux-gnu/sys/syscall.h:29:#include <bits/syscall.h>

I removed duplicate mappings, and also removed the mapping for
<syscall.h>, which is an undocumented feature of glibc.  Portable
programs should stick to <sys/syscall.h> (and unportable ones
too, since there's no gain apart from those 4 bytes).

Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
2022-09-01 19:44:29 +02:00
Kim Gräsman 4ad1d428ff Refactor CanForwardDeclareType for better sugar tolerance
These changes have no effect on the current test suite, but there are
obvious weaknesses when sugared types are taken into account.

The way CanForwardDeclareType asks if the parent is-a particular AST
node type is generally unsound in the presence of sugar, such as
ElaboratedType, which may show up above any Type in the tree.

An example:

  class C {};
  typedef C FooBar;

produces:

  `-TypedefDecl 0x559e505c6e30
    `-ElaboratedType 0x559e505c6df0 'C' sugar
      `-RecordType 0x559e505c6cc0 'C'
        `-CXXRecord 0x559e505c6c30 'C'

If we were to call CanForwardDeclare for the type C, it would not
classify as part of a TypedefDecl, because its parent is-a
ElaboratedType.

Therefore, delay any parent type checking until we've rewinded the
current AST node using MostElaboratedAncestor (there's a case to be made
that we should add a more general MostSugaredAncestor to walk _up_ the
tree until a desugared node is reached, much the same way as Desugar
will walk _down_ the tree. But that's good idea for a separate project.)

This was inspired by Clang 15f3cd6bfc670ba6106184a903eb04be059e5977,
which wraps the majority of Type nodes in an additional ElaboratedType
node.
2022-08-31 22:30:12 +02:00
Kim Gräsman ce63c68ed2 [clang compat] Back up through sugar before parent type check
This is kind-of the inverse of desugaring -- walk up the ancestor chain until
we're at the most elaborated (should really be "sugared") ancestor. Then we can
make assumptions about parent types again.

Clang 15f3cd6bfc670ba6106184a903eb04be059e5977 made this necessary, because many
more type nodes are now wrapped in ElaboratedType, which breaks naive parent
type checking.
2022-08-31 22:24:54 +02:00
Kim Gräsman 18a331be38 [clang compat] Canonicalize template args before identity comparison
Clang 15f3cd6bfc670ba6106184a903eb04be059e5977 made this necessary, because many
more type nodes are now wrapped in ElaboratedType, which makes it more risky to
compare non-canonical types for identity.
2022-08-31 22:24:54 +02:00
Kim Gräsman ed7860fa6f [clang compat] Desugar types before author-intent analysis
We already did desugaring (or, historically, RemoveElaboration) before
insertion or lookup in responsibility maps -- e.g.
GetCallerResponsibleTypesForAutocast and
GetCallerResponsibleTypesForFnReturn -- in most cases.

Clang after 15f3cd6bfc670ba6106184a903eb04be059e5977 wraps many more
type nodes in ElaboratedType, so we need to be even more diligent about
this.
2022-08-31 22:24:54 +02:00
Kim Gräsman af050f9d44 Only desugar type once in IsClassType
Now that we're using Desugar, which handles null pointers, we can desugar once
and reuse the result for both type checks.
2022-08-31 22:16:16 +02:00
Kim Gräsman 45e8234da9 Remove double desugar and clarify comment
The mechanical replacements caused some strange end result for functions with
both RemoveSubstTemplateTypeParm and RemoveElaboration. Clarify.
2022-08-31 22:16:16 +02:00
Kim Gräsman 7fd6c9f798 Replace all uses of RemoveSubstTemplateTypeParm with Desugar
No visible functional change, but we now desugar more aggressively.

This patch is the result of:

  git grep -l "RemoveSubstTemplateTypeParm" | xargs sed -i -e 's/RemoveSubstTemplateTypeParam/Desugar/'
2022-08-31 22:16:16 +02:00
Kim Gräsman 77e9128cba Replace all uses of RemoveElaboration with Desugar
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.
2022-08-31 22:16:16 +02:00
Kim Gräsman 73845f5cf9 Add new Desugar utility function
Desugar is a primitive for removing sugar from a Type node until a non-sugar
Type is reached. Type::getAs<> has similar semantics, but it requires a known
end-state; Desugar keeps going until there's no more sugar left.

Clang already has a plethora of functionality for this, most notably
Type::getUnqualifiedType. But IWYU can't use it, because we don't consider
TypedefType and UsingType sugar -- they're critical to correct
analysis. Similarly we have a lot of special-casing around
TemplateSpecializationType (which is conditionally sugar in Clang).

So, Desugar has desugaring semantics, but stops at TypedefType, UsingType and
TemplateSpecializationType if they are seen before we run out of sugar.

This is designed to be used instead of Type::getAs<> when the target type isn't
known and we just want to shave off sugar.

The sugar types most commonly seen are ElaboratedType and
SubstTemplateTypeParmType, but there are likely others that will be handled
automagically here.
2022-08-31 22:16:16 +02:00
Kim Gräsman f0eb46972a Check for SubstTemplateTypeParmType before desugaring
RemovePointersAndReferencesAsWritten should be allowed to return a
desugared type, so typecheck for SubstTemplateTypeParmType on the type
before pointers/refs (and any sugar) have been removed.
2022-08-31 22:16:16 +02:00