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
We copy arguments from different template parameter lists depending on
the deducibility of the template parameters. In particular, we may lose
the default template argument from the original alias declaration, and
this patch helps preserve that.
Fixes https://github.com/llvm/llvm-project/issues/133132
The previous approach broke code generation for the MS ABI due to an
unintended code path during constraint substitution. This time we
address the issue by inspecting the evaluation contexts and thereby
avoiding that code path.
This reapplies 96eced624 (#102857).
032ad59 taught the instantiator to expand template argument packs for
rewrite. However we might already be in a pack expansion when we
synthesizing the CTAD guide, so we reset the ArgPackSubstIndex to ensure
it doesn't get confused.
No release note because this is a regression in Clang 21.
Fixes https://github.com/llvm/llvm-project/issues/141425
---------
Co-authored-by: Erich Keane <ekeane@nvidia.com>
It's possible that some deduced template arguments come from default
arguments, not just from the return type. So we need to recursively
visit the default arguments of the parameter if it's referenced, thereby
the template parameter referenced by the defualt arguments could come
along to the synthesized deduction guide.
Fixes https://github.com/llvm/llvm-project/issues/134471
This introduces a new class 'UnsignedOrNone', which models a lite
version of `std::optional<unsigned>`, but has the same size as
'unsigned'.
This replaces most uses of `std::optional<unsigned>`, and similar
schemes utilizing 'int' and '-1' as sentinel.
Besides the smaller size advantage, this is simpler to serialize, as its
internal representation is a single unsigned int as well.
Thanks to the example provided by MagentaTreehouse, I realized the
assertion I added in b8d1f3d6 didn't cover all valid cases like, when
inheriting from a class template specialization, the source of a
synthesized template parameter might be an implicit specialization,
whose inner function template is thus living at depth 0, for which we
don’t want it to overflow too.
I've decided to remove that assertion because I don't think it's
particularly useful: we're checking whether Depth = 0 parameters come
from function templates whose parents contribute no template parameters
to the depth, which is redundant given what the template depth already
means.
This also incorporates a drive-by fix for
https://github.com/llvm/llvm-project/pull/132061#discussion_r2008756718,
which I somehow missed.
It turns out that TemplateParamsReferencedInTemplateArgumentList() and
MarkUsedTemplateParameters() have the similar goal, so let's drop the
hand-written ASTVisitor.
There were some cases where we computed incorrect template parameter
depths for synthesized CTAD, invalid as they might be, we still
shouldn't crash anyway.
Technically the only scenario in which the inner function template's
depth is 0 is when it lives within an explicit template specialization,
where the template parameter list is empty.
Fixes https://github.com/llvm/llvm-project/issues/128691
Fixes#125821
The assertion was too strict, as Clang can reach this code path when
recursively generating deduction guides for alias templates. See the
detailed explanation
[here](https://github.com/llvm/llvm-project/issues/125821#issuecomment-2639130893).
No release notes needed, as there is no behavior change in release
builds.
Fixes#103016
This is the last missing piece for the C++20 CTAD alias feature. No
release note being added in this PR yet, I will send out a follow-up
patch to mark this feature done.
(Since the release 20 branch is cut, I think we should target on
clang21).
For deduction guides generated from alias template CTAD, store the
deduction guide they were originated from. The source kind is also
maintained for future expansion in CTAD from inherited constructors.
This tracking is required to determine whether an alias template already
has a deduction guide corresponding to some deduction guide on the
original template, in order to support deduction guides for the alias
from deduction guides declared after the initial usage.
We missed a case of type constraints referencing deduced template
parameters when constructing a deduction guide for the type alias. This
patch fixes the issue by swapping the order of constructing 'template
arguments not appearing in the type alias parameters' and 'template
arguments that are not yet deduced'.
Fixes https://github.com/llvm/llvm-project/issues/122134
This patch partially implements CWG2369 for non-lambda-constrained
functions.
Lambdas are left intact at this point because we need extra work to
correctly instantiate captures before the function instantiation.
As a premise of CWG2369, this patch also implements CWG2770 to ensure
the function parameters are instantiated on demand.
Closes https://github.com/llvm/llvm-project/issues/54440
This patch reapplies #111173, fixing a bug when instantiating dependent
expressions that name a member template that is later explicitly
specialized for a class specialization that is implicitly instantiated.
The bug is addressed by adding the `hasMemberSpecialization` function,
which return `true` if _any_ redeclaration is a member specialization.
This is then used when determining the instantiation pattern for a
specialization of a template, and when collecting template arguments for
a specialization of a template.
TypedefNameDecl referenced by a synthesized CTAD guide for type aliases
was not transformed previously, resulting in a substitution failure in
BuildDeductionGuideForTypeAlias() when substituting into the
right-hand-side deduction guide.
This patch fixes it in the way we have been doing since
https://reviews.llvm.org/D80743. We transform all the function
parameters, parenting referenced TypedefNameDecls with the
CXXDeductionGuideDecl. Then we instantiate these declarations in
FindInstantiatedDecl() as we build up the eventual deduction guide,
using the mechanism introduced in D80743
Fixes#111508
Reapplies #106585, fixing an issue where non-dependent names of member
templates appearing prior to that member template being explicitly
specialized for an implicitly instantiated class template specialization
would incorrectly use the definition of the explicitly specialized
member template.
Currently, clang rejects the following explicit specialization of `f`
due to the constraints not being equivalent:
```
template<typename T>
struct A
{
template<bool B>
void f() requires B;
};
template<>
template<bool B>
void A<int>::f() requires B { }
```
This happens because, in most cases, we do not set the flag indicating
whether a `RedeclarableTemplate` is an explicit specialization of a
member of an implicitly instantiated class template specialization until
_after_ we compare constraints for equivalence. This patch addresses the
issue (and a number of other issues) by:
- storing the flag indicating whether a declaration is a member
specialization on a per declaration basis, and
- significantly refactoring `Sema::getTemplateInstantiationArgs` so we
collect the right set of template argument in all cases.
Many of our declaration matching & constraint evaluation woes can be
traced back to bugs in `Sema::getTemplateInstantiationArgs`. This
change/refactor should fix a lot of them. It also paves the way for
fixing #101330 and #105462 per my suggestion in #102267 (which I have
implemented on top of this patch but will merge in a subsequent PR).
We ended up having two transformTemplateParameter() after CTAD for type
aliases was landed. This patch cleans them up and allows them to share
one implementation.
As a bonus, this also uses getDepthAndIndex() in preference to
getTemplateParameter{Depth,Index}().
This seems to be low-hanging fruit: We could remove all calls to
`Context.getCanonicalTemplateArgument()` and gain a better
diagnostic/AST.
The non-canonical template arguments shouldn't make a difference when
synthesizing a CTAD guide, so this is intended to be an NFC.
Closes https://github.com/llvm/llvm-project/issues/79798
Split out the deduction guide related code from SemaTemplate.cpp to a
dedicated file.
These code has grown significantly, and moving it to a separate file
will improve code organization.