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.
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.
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.
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.
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
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.
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.
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.
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>
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.
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.
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.
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%).
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.
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.
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>
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>
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.
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>
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.
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.
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.
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.
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/'
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.
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.
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.