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
The core AST nodes (Decl, Stmt, Type, TypeLoc) all have a kind denoting
their specific derived type, and a corresponding function to get a
printable string for the kind.
Implement a polymorphic GetKindName that calls the right function
depending on type, and also adds a suffix to mirror the clang class
name.
Make all uses of the get...Name functions call these wrappers instead.
No visible change intended.
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.
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.
'Elaborated type specifier' is the formal term for 'struct X', 'class Y' or
'union Z'. Use it to avoid potential confusion around what 'elaboration node'
means.
Clean up a comment that claimed 'MostElaboratedAncestor' used
'IsElaborationNode', where it actually doesn't.
No functional change.
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.
When a consteval function is called, its call-expression is wrapped in a
ConstantExpr in the Clang AST. There's an upstream bug [1] where Clang
doesn't account for that when searching the AST for a cast-expression's
potential user-defined conversion function, leading to an assertion
failure or a crash.
Reimplement GetConversionFunction so it works in this case. This can
safely be reverted when the upstream bug is fixed.
[1] https://github.com/llvm/llvm-project/issues/53044
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.
ASTNode was consistently instantiated using GlobalSourceManager(). The
passed-in source manager was only used in ASTNode::GetLocation().
Use GlobalSourceManager() there directly instead to keep the constructor
interface simpler.
No functional change.
In walking the AST there were various places where types were only
expanded if !CanIgnoreType. But the criteria were wrong
The CanIgnoreType is suitable for determining whether a type was
reportable, but not whether it was expansion-worthy.
Add a new parameter to CanIgnoreType to distinguish the two use cases,
and pass it in a couple of cases.
Also, tweak the resugar map construction code. Now it is capable of
handling template aliases as well as template classes and functions.
Add a new test that now passes with these changes.
This also resolves a couple of TODOs in an existing test, so update that
accordingly.
The previous code to catch aliases of template parameters would not
catch the case where the template parameter was elaborated. Walk past
the relevant ASTNodes to catch such cases.
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.
When an alias template was used, IWYU would resolve it to the underlying
aliased type rather than the template for the purposes of determining
what header was required. This led to incorrect header removals in some
cases.
Fix that by splitting the TypeToDeclAsWritten into two functions:
TypeToDeclAsWritten and TypeToDeclForContent. The former is used for
determining uses of the Decl itself, the latter is used for determining
uses of the arguments passed to the template.
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.
Teach IsFowardDecl() to not confuse an explicit template instantiation
with a forward declaration.
Also make sure to report explicit instantiations (declaration or
definition) as full uses during visitation.
Fixes#558
It fixes case in `tests/cxx/badinc.cc` when for
new I1_TemplateClass<I2_Class, I1_Struct>[kI1ConstInt]
we erroneously don't need full declaration for `I1_Struct`.
Clang r283406 improved handling array creation which caused us to see
not template type but array type. The fix is to take element type in
this case.
Another attempted approach is
GetTypeOf(constructor_expr->getConstructor()->getParent());
But it doesn't work because in this case we receive not template type
but instantiated `RecordType` that has no template arguments. For example,
with mentioned code we get type like
RecordType 0x7fb7ccc251f0 'class I1_TemplateClass<class EmptyClass, struct Fail_Struct>'
`-ClassTemplateSpecialization 0x7fb7ccc250f0 'I1_TemplateClass'
instead of desired
TemplateSpecializationType 0x7fb7ccc253f0 'I1_TemplateClass<class EmptyClass, struct Fail_Struct>' sugar I1_TemplateClass
|-TemplateArgument type 'class EmptyClass'
|-TemplateArgument type 'struct Fail_Struct'
`-RecordType 0x7fb7ccc251f0 'class I1_TemplateClass<class EmptyClass, struct Fail_Struct>'
`-ClassTemplateSpecialization 0x7fb7ccc250f0 'I1_TemplateClass'
Bugs #334, #335 and #338 were all caused by the new macro location
rule that considers a forward-decl in the macro definition file a
hint that uses of the declared type inside a macro are attributed
to the macro's expansion location.
Several different kinds of declarations were mis-characterized as
forward decls.
This patch improves IsForwardDecl to better detect this, and
simplifies the heuristic rule so that any forward-declaration
outside of a macro in the same file as the macro definition will
count as a use-attribution hint.
Fragments such as this:
friend class Container<T>::Iterator;
would not be recognized as needing a forward-declaration, so IWYU
would suggest removing forward-decls of Iterator.
This patch changes this and expands the test suite for nested classes
to cover containing class templates and friend declarations.
Fixes issue #331.
NULL/0 -> nullptr
C standard library include -> C++ counterparts
Occasional use of auto
Explicit strcmp return value check
Remove unused usings
Closing comments for anonymous namespaces
- Remove DEVTOOLS_MAINTENANCE_ from header guards, that was a
now-unnecessary Googleism
- Fix header guard to match filename in all production code
- Fix header guard to match path in all tests
Clang r256359 removed `getOptionalExplicitTemplateArgs` on various Expr
subclasses. Use
`void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const`
instead.
`const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const` doesn't look
like appropriate replacement because it checks only `HasTemplateKWAndArgsInfo`
and we'll need to do `hasExplicitTemplateArgs()` checks ourselves.
On Windows builds of Clang/IWYU -fdelayed-template-parsing
is enabled by default. This means parsing of (function) templates
is delayed until instantiation time. If a template is never
instantiated, it is never parsed.
This is terrible behavior for IWYU, where we must traverse code
in templates looking for uses, whether they're ever instantiated
or not. So we run a separate pass that force-parses all late-
parsed FunctionDecl, building their AST before IWYU analysis.
Fixes a number of prefix_header tests that were previously failing
on Windows.
Changes of particular note:
* Resolved merge conflicts in:
third_party/llvm/libcxx/src/exception.cpp
third_party/llvm/llvm/tools/clang/lib/Driver/Tools.cpp
third_party/llvm/llvm/tools/clang/tools/driver/cc1_main.cpp
* Manual edits to
third_party/llvm/llvm/tools/clang/lib/Tooling/Tooling.cpp
due to diagnostic classes renaming
* Fixed up Cymbal, Grok and IWYU code for various class renamings
R=chandlerc,csilvers,chrsmith
Revision created by MOE tool push_codebase.
MOE_MIGRATION=3337
This fixes an issue I ran across where I couldn't inhibit the forward declaration
of a symbol defined in an anonymous namespace.
R=csilvers
DELTA=59 (53 added, 0 deleted, 6 changed)
Revision created by MOE tool push_codebase.
MOE_MIGRATION=3326
I don't know how to word some of the comments -- in particular, I don't
know reasons besides not ever being instantiated for the definition
to be unknown at this point.
One big change here: GetDefinitionForClass always returns a RecordDecl.
R=csilvers,chandlerc
DELTA=43 (0 added, 24 deleted, 19 changed)
Revision created by MOE tool push_codebase.
MOE_MIGRATION=3312
arguments using the 'precomputed cache'. In such situations,
it totally ignored the currently active resugar_map, replacing
it with one of its own. That worked fine for types outside of
templates, but not fine for types inside (such as a 'hash_map<T>'
inside a templated class).
I "fixed" this. "Fixed" is in quotes because this turned up a
whole slew of other problems I don't even attempt to resolve
here (though I spent a few hours trying). One is that it's
possible to have a type like hash_map that has some arguments
that are dependent and some that aren't; in theory, for these
types, we can correctly attribute the use to the template
author or template instantiator depending on which type it
is. But I can't figure out how to get clang to do any
meaningful analysis of incomplete (dependent) types, so I've
punted on that for now.
The second thing wrong is I jumped through all sorts of hoops
to handle default template arguments correctly, so if a class
has a hash_map<T> and you instantiate T with string, you're
also made responsible for hash<string>. This *should* work,
but clang is giving hash<string> a type I don't expect
(RecordType, not TemplateSpecializationType), and I don't know
how to deal with that -- I don't know how to extract the
'string' part of this RecordType. Ugh. I punt on this now,
as well.
Even in this incomplete form, it's enough to resolve a P1 bug,
so I figure it's worth putting in.
R=dsturtevant
DELTA=141 (97 added, 7 deleted, 37 changed)
Revision created by MOE tool push_codebase.
MOE_MIGRATION=3147
statements for cast, isa, and dyn_cast. I don't know what's
changed (maybe upstream took out a using statement somewhere
that we were depending on?), but it was our bad in the first
place, so I'm happy to fix it.
Because we try not to use using statements in .h files, I just
prefixed ::llvm:: there when appropriate.
R=wan
DELTA=13 (8 added, 0 deleted, 5 changed)
Revision created by MOE tool push_codebase.
MOE_MIGRATION=2674
to iwyu). Fixes a crashing bug when they occur, due to a
failed assert elsewhere in the code that we only
forward-declare classes.
R=dsturtevant
DELTA=33 (32 added, 0 deleted, 1 changed)
Revision created by MOE tool push_codebase.
MOE_MIGRATION=2414