This is a major change on how we represent nested name qualifications in
the AST.
* The nested name specifier itself and how it's stored is changed. The
prefixes for types are handled within the type hierarchy, which makes
canonicalization for them super cheap, no memory allocation required.
Also translating a type into nested name specifier form becomes a no-op.
An identifier is stored as a DependentNameType. The nested name
specifier gains a lightweight handle class, to be used instead of
passing around pointers, which is similar to what is implemented for
TemplateName. There is still one free bit available, and this handle can
be used within a PointerUnion and PointerIntPair, which should keep
bit-packing aficionados happy.
* The ElaboratedType node is removed, all type nodes in which it could
previously apply to can now store the elaborated keyword and name
qualifier, tail allocating when present.
* TagTypes can now point to the exact declaration found when producing
these, as opposed to the previous situation of there only existing one
TagType per entity. This increases the amount of type sugar retained,
and can have several applications, for example in tracking module
ownership, and other tools which care about source file origins, such as
IWYU. These TagTypes are lazily allocated, in order to limit the
increase in AST size.
This patch offers a great performance benefit.
It greatly improves compilation time for
[stdexec](https://github.com/NVIDIA/stdexec). For one datapoint, for
`test_on2.cpp` in that project, which is the slowest compiling test,
this patch improves `-c` compilation time by about 7.2%, with the
`-fsyntax-only` improvement being at ~12%.
This has great results on compile-time-tracker as well:

This patch also further enables other optimziations in the future, and
will reduce the performance impact of template specialization resugaring
when that lands.
It has some other miscelaneous drive-by fixes.
About the review: Yes the patch is huge, sorry about that. Part of the
reason is that I started by the nested name specifier part, before the
ElaboratedType part, but that had a huge performance downside, as
ElaboratedType is a big performance hog. I didn't have the steam to go
back and change the patch after the fact.
There is also a lot of internal API changes, and it made sense to remove
ElaboratedType in one go, versus removing it from one type at a time, as
that would present much more churn to the users. Also, the nested name
specifier having a different API avoids missing changes related to how
prefixes work now, which could make existing code compile but not work.
How to review: The important changes are all in
`clang/include/clang/AST` and `clang/lib/AST`, with also important
changes in `clang/lib/Sema/TreeTransform.h`.
The rest and bulk of the changes are mostly consequences of the changes
in API.
PS: TagType::getDecl is renamed to `getOriginalDecl` in this patch, just
for easier to rebasing. I plan to rename it back after this lands.
Fixes#136624
Fixes https://github.com/llvm/llvm-project/issues/43179
Fixes https://github.com/llvm/llvm-project/issues/68670
Fixes https://github.com/llvm/llvm-project/issues/92757
Useful when the check warns on template functions to know which type
it's complaining about. Otherwise, since the instantiation stack is not
printed, it's very hard to tell.
Co-authored-by: Carlos Gálvez <carlos.galvez@zenseact.com>
Summary:
Replacing by-value parameters with passing by-reference is not safe for
coroutines because the caller may be executed in parallel with the
callee, which increases the chances of resulting in dangling references
and hard-to-find crashes. See for the reference
[cppcoreguidelines-avoid-reference-coroutine-parameters](https://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/avoid-reference-coroutine-parameters.html).
Test Plan: check-clang-tools
Run misc-use-internal-linkage check over clang-tidy code.
Also fixed a couple of other clang-tidy warnings.
Apart from issues in header files, all '.cpp' in
`clang-tools-extra/clang-tidy` must be clang-tidy clear now.
These are identified by misc-include-cleaner. I've filtered out those
that break builds. Also, I'm staying away from llvm-config.h,
config.h, and Compiler.h, which likely cause platform- or
compiler-specific build failures.
This PR aims to fix `performance-move-const-arg` #126515
## Changes
Enhanced the `performance-move-arg` check in Clang-Tidy to detect cases
where `std::move` is used
in **ternary operator expressions which was not being matched therefore
being tagged as a false negative**
## Testing
- A new mock class has been where the changes have been tested & all
tests pass
I'd appreciate any feedback since this is my first time contributing to
LLVM.
Tolerate fix-it breaking compilation when functions is used as pointers.
`isReferencedOutsideOfCallExpr` will visit the whole translate unit for
each matched function decls. It will waste lots of cpu time in some big
cpp files.
But the benefits of this validation are limited. Lots of function usage
are out of current translation unit.
After removing this validation step, the check profiling changes from
5.7 to 1.1 in SemaExprCXX.cpp, which is similar to version 18.
This patch improves, but doens't fully resolve the layering violation,
which stems from relying on Sema. There's one function that needs to
convert enumerator to a string (`buildQualifier` in
`FixItHintUtils.cpp`), but `Qualifiers::TQ` doesn't offer such function.
Even more, the set of enumerators is not complete compared to
`DeclSpec::TQ`, so I'm afraid that this would be a functional change.
If a add_clang_library call doesn't specify building as static or shared
library they are implicitly added to the list static libraries that is
linked in to clang-cpp shared library here.
315ba77406/clang/cmake/modules/AddClang.cmake (L107)
Because the clang-tools-extra libraries targets were declared after
clang-cpp they by luck never got linked to clang-cpp.
This change is required for clang symbol visibility macros on windows to
work correctly for clang tools since we need to distinguish if a target
being built will be importing or exporting clang symbols from the
clang-cpp DLL.
... so that downstream checks can override behaviour to do additional
processing.
Refactor the rest of the logic to `handleConstRefFix` (which is also
`virtual`).
This is otherwise and NFC.
This is similar to https://github.com/llvm/llvm-project/pull/73921 but
for `performance-unnecessary-value-param`.
Clang-Tidy unnecessary-value-param value param will be triggered for
templated functions if at least one instantiontion with expensive to
copy type is present in translation unit.
It is relatively common mistake to write lambda functions with auto
arguments for expensive to copy types.
…and operators that have non-const overloads.
This allows `unnecessary-copy-initialization` to warn on more cases.
The common case is a class with a a set of const/non-sconst overloads
(e.g. std::vector::operator[]).
```
void F() {
std::vector<Expensive> v;
// ...
const Expensive e = v[i];
}
```
This uses a more systematic approach for determining whcich
`DeclRefExpr`s mutate the underlying object: Instead of using a few
matchers, we walk up the AST until we find a parent that we can prove
cannot change the underlying object.
This allows us to handle most address taking and dereference, bindings
to value and const& variables, and track constness of pointee (see
changes in DeclRefExprUtilsTest.cpp).
This allows supporting more patterns in
`performance-unnecessary-copy-initialization`.
Those two patterns are relatively common:
```
const auto e = (*vector_ptr)[i]
```
and
```
const auto e = vector_ptr->at(i);
```
In our codebase, we have around 25% additional findings from
`performance-unnecessary-copy-initialization` with this change. I did
not see any additional false positives.
Enums without enumerators (empty) are now excluded from analysis as it's
not possible to peroperly determinate new narrowed type, and such enums
can be used in diffrent way, like as strong-types.
Closes#71544
Enforce a stricter match with the swap function signature, eliminating false-positives.
Fixes: #64303
Reviewed By: carlosgalvezp
Differential Revision: https://reviews.llvm.org/D157185
The modules build trips over this frequently because there is no textual
include of the tablegen output, but the module includes it.
Differential revision: https://reviews.llvm.org/D157119
Finds enum type definitions that could use smaller integral type as a base.
Reviewed By: xgupta
Differential Revision: https://reviews.llvm.org/D144135
add_new_check.py does not work properly for checks that
generate fixes in base class. Adding some comments to those
checks in order to fix list.rst generation.
We now display a simple note if the reason is that the used class does not
support move semantics.
This fixes llvm#62550
Reviewed By: PiotrZSL
Differential Revision: https://reviews.llvm.org/D153220
Added new checks
- `performance-noexcept-destructor`
- `performance-noexcept-swap`
Also added cppcoreguidlines aliases for the 2 new checks as well as `performance-noexcept-move-constructor`
This fixes llvm#62154
Reviewed By: PiotrZSL
Differential Revision: https://reviews.llvm.org/D148697
This check flags uses of `std::endl` on streams and suggests using the newline character `'\n'` instead. `std::endl` performs two operations: it writes a newline character to the output stream and then flushes the stream buffer, which can be less efficient than writing a single newline character using `'\n'`.
This fixes llvm#35321
Reviewed By: PiotrZSL
Differential Revision: https://reviews.llvm.org/D148318
Previously a struct like this:
template <typename>
struct A { A(A&&) = default; };
Would trigger a false positive, since even though it is not marked as
noexcept it still is due to the `= default`.
Now we only give a warning if the defaulted move constructor is
actually declared as throwing and correctly resolve it if they are
defaulted.
This fixes llvm#56026, llvm#41414, llvm#38081
Reviewed By: PiotrZSL
Differential Revision: https://reviews.llvm.org/D146922
In the following code:
```cc
struct Obj {
Obj();
Obj(const Obj &);
Obj(Obj &&);
virtual ~Obj();
};
Obj ConstNrvo() {
const Obj obj;
return obj;
}
```
performance-no-automatic-move warns about the constness of `obj`. However, NRVO
is applied to `obj`, so the `const` should have no effect on performance.
This change modifies the matcher to exclude NRVO variables.
#clang-tidy
Reviewed By: courbet, PiotrZSL
Differential Revision: https://reviews.llvm.org/D147419
We forgot to apply the change to headers in the previous patch,
due to missing "-header-filter" in the run-clang-tidy invocation.
Differential Revision: https://reviews.llvm.org/D142307