This patch extends the canonicalization printing policy to cover
expressions
and template names, and wires that up to the template argument printer,
covering expressions, and to the expression within a dependent decltype.
This is helpful for debugging, or if these expressions somehow end up
in diagnostics, as without this patch they can print as completely
unrelated
expressions, which can be quite confusing.
This is because expressions are not uniqued, unlike types, and
when a template specialization containing an expression is the first to
be
canonicalized, the expression ends up appearing in the canonical type of
subsequent equivalent specializations.
Fixes https://github.com/llvm/llvm-project/issues/92292
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.
Note that PointerUnion::dyn_cast has been soft deprecated in
PointerUnion.h:
// FIXME: Replace the uses of is(), get() and dyn_cast() with
// isa<T>, cast<T> and the llvm::dyn_cast<T>
Literal migration would result in dyn_cast_if_present (see the
definition of PointerUnion::dyn_cast), but this patch uses dyn_cast
because we expect InVectors.front() and P to be nonnull.
Note that PointerUnion::dyn_cast has been soft deprecated in
PointerUnion.h:
// FIXME: Replace the uses of is(), get() and dyn_cast() with
// isa<T>, cast<T> and the llvm::dyn_cast<T>
This patch migrates uses of PointerUnion::dyn_cast to
dyn_cast_if_present (see the definition of PointerUnion::dyn_cast).
Note that we cannot use dyn_cast in any of the migrations in this
patch; placing
assert(!X.isNull());
just before any of dyn_cast_if_present in this patch triggers some
failure in check-clang.
Note that PointerUnion::{is,get} have been soft deprecated in
PointerUnion.h:
// FIXME: Replace the uses of is(), get() and dyn_cast() with
// isa<T>, cast<T> and the llvm::dyn_cast<T>
I'm not touching PointerUnion::dyn_cast for now because it's a bit
complicated; we could blindly migrate it to dyn_cast_if_present, but
we should probably use dyn_cast when the operand is known to be
non-null.
This extends default argument deduction to cover class templates as
well, applying only to partial ordering, adding to the provisional
wording introduced in https://github.com/llvm/llvm-project/pull/89807.
This solves some ambuguity introduced in P0522 regarding how template
template parameters are partially ordered, and should reduce the
negative impact of enabling `-frelaxed-template-template-args` by
default.
Given the following example:
```C++
template <class T1, class T2 = float> struct A;
template <class T3> struct B;
template <template <class T4> class TT1, class T5> struct B<TT1<T5>>; // #1
template <class T6, class T7> struct B<A<T6, T7>>; // #2
template struct B<A<int>>;
```
Prior to P0522, `#2` was picked. Afterwards, this became ambiguous. This
patch restores the pre-P0522 behavior, `#2` is picked again.
This reverts the functional elements of commit
3e78fa860235431323aaf08c8fa922d75a7cfffa and redoes it, by fixing the
true root cause of #61317.
A TemplateName can be non-canonical; profiling it based on the canonical
name would result in inconsistent preservation of as-written information
in the AST.
The true problem in #61317 is that we would not consider the methods
with requirements expression which contain DTSTs as the same in relation
to merging of declarations when importing modules.
The expressions would never match because they contained DTSTs pointing
to different redeclarations of the same class template, but since
canonicalization for them was broken, their canonical types would not
match either.
---
No changelog entry because #61317 was already claimed as fixed in
previous release.
These will work as AST Text node dumpers, as usual, instead of AST
printers.
Note that for now, the TemplateName dumper is using the TemplateArgument
dumper through an implicit conversion.
This can be fixed in a later pass.
This patch improves the preservation of qualifiers and loss of type
sugar in TemplateNames.
This problem is analogous to https://reviews.llvm.org/D112374 and this
patch takes a very similar approach to that patch, except the impact
here is much lesser.
When a TemplateName was written bare, without qualifications, we
wouldn't produce a QualifiedTemplate which could be used to disambiguate
it from a Canonical TemplateName. This had effects in the TemplateName
printer, which had workarounds to deal with this, and wouldn't print the
TemplateName as-written in most situations.
There are also some related fixes to help preserve this type sugar along
the way into diagnostics, so that this patch can be properly tested.
- Fix dropping the template keyword.
- Fix type deduction to preserve sugar in TST TemplateNames.
TemplateName::getAsTemplateDecl() returns the underlying TemplateDecl
for a UsingTemplate kind template name. We should respect that in the
Profile method otherwise we might desugar the template name unexpectedly
(e.g. for template argument deduction with deduciton guides).
Differential Revision: https://reviews.llvm.org/D146202
Close https://github.com/llvm/llvm-project/issues/61317
The root cause of the problem is that we profile TemplateName by the
non-canonical decls so that the compiler thought they are two different
types. But this is not true. We fixed the issue after we profile the
template name by using the same name.
Implements the changes required to perform substitution with
non-canonical template arguments, and to 'finalize' them
by not placing 'Subst' nodes.
A finalized substitution means we won't resugar them later,
because these templates themselves were eagerly substituted
with the intended arguments at the point of use. We may still
resugar other templates used within those, though.
This patch does not actually implement any uses of this
functionality, those will be added in subsequent patches,
so expect no changes to existing tests.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Differential Revision: https://reviews.llvm.org/D134604
Implements the changes required to perform substitution with
non-canonical template arguments, and to 'finalize' them
by not placing 'Subst' nodes.
A finalized substitution means we won't resugar them later,
because these templates themselves were eagerly substituted
with the intended arguments at the point of use. We may still
resugar other templates used within those, though.
This patch does not actually implement any uses of this
functionality, those will be added in subsequent patches,
so expect no changes to existing tests.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Differential Revision: https://reviews.llvm.org/D134604
This is a change to how we represent type subsitution in the AST.
Instead of only storing the replaced type, we track the templated
entity we are substituting, plus an index.
We modify MLTAL to track the templated entity at each level.
Otherwise, it's much more expensive to go from the template parameter back
to the templated entity, and not possible to do in some cases, as when
we instantiate outer templates, parameters might still reference the
original entity.
This also allows us to very cheaply lookup the templated entity we saw in
the naming context and find the corresponding argument it was replaced
from, such as for implementing template specialization resugaring.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Differential Revision: https://reviews.llvm.org/D131858
The diagnostics engine is very smart about being passed a NamedDecl to
print as part of a diagnostic; it gets the "right" form of the name,
quotes it properly, etc. However, the result of using an unnamed tag
declaration was to print '' instead of anything useful.
This patch causes us to print the same information we'd have gotten if
we had printed the type of the declaration rather than the name of it,
as that's the most relevant information we can display.
Differential Revision: https://reviews.llvm.org/D134813
If the underlying template name of a qualified template name is a using
decl, TemplateName::getAsUsingDecl() will return it.
This will make the UsingTemplateName consumer life easier.
Differential Revision: https://reviews.llvm.org/D124437
This is the template version of https://reviews.llvm.org/D114251.
This patch introduces a new template name kind (UsingTemplateName). The
UsingTemplateName stores the found using-shadow decl (and underlying
template can be retrieved from the using-shadow decl). With the new
template name, we can be able to find the using decl that a template
typeloc (e.g. TemplateSpecializationTypeLoc) found its underlying template,
which is useful for tooling use cases (include cleaner etc).
This patch merely focuses on adding the node to the AST.
Next steps:
- support using-decl in qualified template name;
- update the clangd and other tools to use this new node;
- add ast matchers for matching different kinds of template names;
Differential Revision: https://reviews.llvm.org/D123127
It breaks arm build, there is no free bit for the extra
UsingShadowDecl in TemplateName::StorageType.
Reverting it to build the buildbot back until we comeup with a fix.
This reverts commit 5a5be4044f0bceb71bb6a81f6955704691b389ed.
This is the template version of https://reviews.llvm.org/D114251.
This patch introduces a new template name kind (UsingTemplateName). The
UsingTemplateName stores the found using-shadow decl (and underlying
template can be retrieved from the using-shadow decl). With the new
template name, we can be able to find the using decl that a template
typeloc (e.g. TemplateSpecializationTypeLoc) found its underlying template,
which is useful for tooling use cases (include cleaner etc).
This patch merely focuses on adding the node to the AST.
Next steps:
- support using-decl in qualified template name;
- update the clangd and other tools to use this new node;
- add ast matchers for matching different kinds of template names;
Differential Revision: https://reviews.llvm.org/D123127
Underscore-uglified identifiers are used in standard library implementations to
guard against collisions with macros, and they hurt readability considerably.
(Consider `push_back(Tp_ &&__value)` vs `push_back(Tp value)`.
When we're describing an interface, the exact names of parameters are not
critical so we can drop these prefixes.
This patch adds a new PrintingPolicy flag that can applies this stripping
when recursively printing pieces of AST.
We set it in code completion/signature help, and in clangd's hover display.
All three features also do a bit of manual poking at names, so fix up those too.
Fixes https://github.com/clangd/clangd/issues/736
Differential Revision: https://reviews.llvm.org/D116387
I discovered this quirk when working on some DWARF - AST printing prints
type template parameters fully qualified, but printed template template
parameters the way they were written syntactically, or wholely
unqualified - instead, we should print them consistently with the way we
print type template parameters: fully qualified.
The one place this got weird was for partial specializations like in
ast-print-temp-class.cpp - hence the need for checking for
TemplateNameDependenceScope::DependentInstantiation template template
parameters. (not 100% sure that's the right solution to that, though -
open to ideas)
Differential Revision: https://reviews.llvm.org/D108794
PartialDiagnostic misses some functions compared to DiagnosticBuilder.
This patch refactors DiagnosticBuilder and PartialDiagnostic, extracts
the common functionality so that the streaming << operators are
shared.
Differential Revision: https://reviews.llvm.org/D84362
This reverts commit 8e780a1653e6f87755a447e921b8f929d8b70996.
DiagnosticBuilder is a value type, created on the stack everywhere. IMO
we should not be adding a vtable to it, and making very operator<< use a
virtual interface. There are other feasible designs for implementing
this. The original review, D84362, was approved by @tra, who is
responsible for Clang's CUDA support, but it wasn't reviewed by @rsmith
or anyone responsible for clang's diagnostic library.
This recommits 829d14ee0a6aa79c89f7f3d9fcd9d27d3efd2b91.
The patch was reverted due to a regression in some CUDA app
which was thought to be caused by this patch. However, investigation
showed that the regression was due to some other issues, therefore
recommit this patch.
PartialDiagnostic misses some functions compared to DiagnosticBuilder.
This patch refactors DiagnosticBuilder and PartialDiagnostic, extracts
the common functionality so that the streaming << operators are
shared.
Differential Revision: https://reviews.llvm.org/D84362
New code added in ec3060c72de6 looked like
+ case TemplateName::NameKind::OverloadedTemplate:
+ assert(false && "overloaded templates shouldn't survive to here.");
+ default:
If compiling without asserts we then got a warning about unannotated
fallthrough from the case into the default.
Change the assert into an llvm_unreachable to silence the warning.
Summary:
This changes introduces an enum to represent dependencies as a bitmask
and extract common patterns from code that computes dependency bits into
helper functions.
Reviewers: rsmith, martong, shafik, ilya-biryukov, hokein
Subscribers: hokein, sammccall, Mordante, riccibruno, merge_guards_bot, rnkovacs, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71920
template name is not visible to unqualified lookup.
In order to support this without a severe degradation in our ability to
diagnose typos in template names, this change significantly restructures
the way we handle template-id-shaped syntax for which lookup of the
template name finds nothing.
Instead of eagerly diagnosing an undeclared template name, we now form a
placeholder template-name representing a name that is known to not find
any templates. When the parser sees such a name, it attempts to
disambiguate whether we have a less-than comparison or a template-id.
Any diagnostics or typo-correction for the name are delayed until its
point of use.
The upshot should be a small improvement of our diagostic quality
overall: we now take more syntactic context into account when trying to
resolve an undeclared identifier on the left hand side of a '<'. In
fact, this works well enough that the backwards-compatible portion (for
an undeclared identifier rather than a lookup that finds functions but
no function templates) is enabled in all language modes.
llvm-svn: 360308
Because diagnostics and their notes are not connected at the API level,
if the error message for an overload is emitted, then the overload
candidates are completed - if a diagnostic is emitted during that work,
the notes related to overload candidates would be attached to the latter
diagnostic, not the original error. Sort of worse, if the latter
diagnostic was disabled, the notes are disabled.
Reviewers: rsmith
Differential Revision: https://reviews.llvm.org/D61357
llvm-svn: 359854
to reflect the new license.
We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.
Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.
llvm-svn: 351636
Specifically, we would not properly parse these types within template arguments
(for non-type template parameters), and in tentative parses. Fixing both of
these essentially requires that we parse deduced template specialization types
as types in all contexts, even in template argument lists -- in particular,
tentative parsing may look ahead and annotate a deduced template specialization
type before we figure out that we're actually supposed to treat the tokens as a
template-name. We deal with this by simply permitting deduced template
specialization types when parsing template arguments, and converting them to
template template arguments.
llvm-svn: 326299