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.
Since the implementation of DR458 (d1446017), we have had an algorithm
that template parameters would take precedence over its parent scopes at
the name lookup. However, we failed to handle the following case where
the member function declaration is not yet deferral parsed (This is
where the patch of DR458 applies):
```cpp
namespace NS {
int CC;
template <typename> struct C;
}
template <typename CC>
struct NS::C {
void foo(CC);
};
```
When parsing the parameter of the function declaration `void foo(CC)`,
we used to perform a name lookup following such a Scope chain:
```
FunctionScope foo (failed)
RecordScope C (failed)
NamespaceScope NS (found `int CC`)
(If failed)
TemplateParameterScope of C
```
This doesn't seem right because according to `[temp.local]`, a template
parameter scope should be searched before its parent scope to which the
parameter appertains. This patch corrects the search scopes by setting a
lookup Entity for template parameter Scopes so that we can bail out in
CppNameLookup() when reaching the RecordScope. Afterward, the search
chain would be like:
```
FunctionScope foo (failed)
RecordScope C (failed)
TemplateParameterScope of C (found CC)
(If failed)
NamespaceScope NS
```
Fixes https://github.com/llvm/llvm-project/issues/64082
We need to rebuild the template parameters of out-of-line
definitions/specializations of member templates in the context of the
current instantiation for the purposes of declaration matching. We
already do this for function templates and class templates, but not
variable templates, partial specializations of variable template, and
partial specializations of class templates. This patch fixes the latter
cases.
fixes https://github.com/llvm/llvm-project/issues/98258
The cause is that the assertion "Nothing should reference a value below
the actual template depth" is incorrect since we can have a generic
lambda inside requires-clause of friend function template, and the
generic lambda can reference to values with greater template depth.
---------
Co-authored-by: cor3ntin <corentinjabot@gmail.com>
Because there may be multiple constrained function of the same type, we
need to perform overload resolution to find the best viable function to
specialize.
Fixes#46029
Forked from https://github.com/llvm/llvm-project/pull/102510 by
[mizvekov](https://github.com/mizvekov). Changes are captured as a fixup
commit.
There are some external projects that can't rely on our own sugar
propagation for templated entities, because they need to resugar types
which only exist within their framework, and so are entirely invisible
to our internal tooling.
This new flag is meant to prevent our transforms from removing any
Subst*
nodes.
For this, this is wired only to template type alias subsititutions.
Note that our AST does represent enough information to correctly
resugar template type alias, so any users of this are limited in their
capacity to reconstruct the parameter substitutions fully.
---------
Co-authored-by: Matheus Izvekov <mizvekov@gmail.com>
A class member named by an expression in a member function that may instantiate to a static _or_ non-static member is represented by a `UnresolvedLookupExpr` in order to defer the implicit transformation to a class member access expression until instantiation. Since `ASTContext::getDecltypeType` only creates a `DecltypeType` that has a `DependentDecltypeType` as its canonical type when the operand is instantiation dependent, and since we do not transform types unless they are instantiation dependent, we need to mark the `UnresolvedLookupExpr` as instantiation dependent in order to correctly build a `DecltypeType` using the expression as its operand with a `DependentDecltypeType` canonical type. Fixes#99873.
The selection of the most constrained candidate for member function
explicit specializations introduced in #88963 does not check whether the
selected candidate is more constrained than all other candidates, which
can result in ambiguities being undiagnosed. This patch addresses the
issue.
This makes use of the changes introduced in D134604, in order to
instantiate alias templates witn a final sugared substitution.
This comes at no additional relevant cost.
Since we don't track / unique them in specializations, we wouldn't be
able to resugar them later anyway.
Differential Revision: https://reviews.llvm.org/D136565
This is mostly a cleanups patch, with some hard to observe sugar
preservation improvements.
Except for the function template deduction changes which improve some
pre-existing diagnostics a little bit.
This reverts commit ce4aada6e2135e29839f672a6599db628b53295d and a
follow-up patch 8ef26f1289bf069ccc0d6383f2f4c0116a1206c1.
This new warning can not be fully suppressed by the
`-Wno-missing-dependent-template-keyword` flag, this gives developer no
time to do the cleanup in a large codebase, see https://github.com/llvm/llvm-project/pull/98547#issuecomment-2228250884
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.
Reapplies #92957, fixing an instance where the `template` keyword was
missing prior to a dependent name in `llvm/ADT/ArrayRef.h`. An
_alias-declaration_ is used to work around a bug affecting GCC releases
before 11.1 (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94799) which
rejects the use of the `template` keyword prior to the
_nested-name-specifier_ in the class member access.
As described in https://github.com/llvm/llvm-project/issues/90209#issuecomment-2135972202,
Clang may not preserve enough information during template argument
deduction. This can result in a merely canonical `TemplateTypeParmType`
with a null `Decl`, leading to an incomplete template parameter list for
the synthesized deduction guide.
This patch addresses the issue by using the index and depth information
to retrieve the corresponding template parameter, rather than relying on
`TTP->getDecl()`.
Fixes#90209
This patch addresses an issue where non-template explicit deduction
guides were not considered when synthesized the deduction guides for
alias templates.
Fixes#94927.
Similar to the approach of handling nested class templates when building
a CTAD guide, we substitute the template parameters of a type alias
declaration with the instantiating template arguments in order to ensure
the guide eventually doesn't reference any outer template parameters.
For example,
```cpp
template <class T> struct Outer {
using Alias = S<T>;
template <class U> struct Inner {
Inner(Alias);
};
};
```
we used to retain the reference to T accidentally because the
TreeTransform does nothing on type alias Decls by default.
Fixes https://github.com/llvm/llvm-project/issues/94614
CWG1835 was one of the many core issues resolved by P1787R6: "Declarations and where to
find them" (http://wg21.link/p1787r6). Its resolution changes how
member-qualified names (as defined by [basic.lookup.qual.general] p2) are looked
up. This patch implementation that resolution.
Previously, an _identifier_ following `.` or `->` would be first looked
up in the type of the object expression (i.e. qualified lookup), and
then in the context of the _postfix-expression_ (i.e. unqualified
lookup) if nothing was found; the result of the second lookup was
required to name a class template. Notably, this second lookup would
occur even when the object expression was dependent, and its result
would be used to determine whether a `<` token is the start of a
_template-argument_list_.
The new wording in [basic.lookup.qual.general] p2 states:
> A member-qualified name is the (unique) component name, if any, of
> - an _unqualified-id_ or
> - a _nested-name-specifier_ of the form _`type-name ::`_ or
_`namespace-name ::`_
>
> in the id-expression of a class member access expression. A
***qualified name*** is
> - a member-qualified name or
> - the terminal name of
> - a _qualified-id_,
> - a _using-declarator_,
> - a _typename-specifier_,
> - a _qualified-namespace-specifier_, or
> - a _nested-name-specifier_, _elaborated-type-specifier_, or
_class-or-decltype_ that has a _nested-name-specifier_.
>
> The _lookup context_ of a member-qualified name is the type of its
associated object expression (considered dependent if the object
expression is type-dependent). The lookup context of any other qualified
name is the type, template, or namespace nominated by the preceding
_nested-name-specifier_.
And [basic.lookup.qual.general] p3 now states:
> _Qualified name lookup_ in a class, namespace, or enumeration performs
a search of the scope associated with it except as specified below.
Unless otherwise specified, a qualified name undergoes qualified name
lookup in its lookup context from the point where it appears unless the
lookup context either is dependent and is not the current instantiation
or is not a class or class template. If nothing is found by qualified
lookup for a member-qualified name that is the terminal name of a
_nested-name-specifier_ and is not dependent, it undergoes unqualified
lookup.
In non-standardese terms, these two paragraphs essentially state the
following:
- A name that immediately follows `.` or `->` in a class member access
expression is a member-qualified name
- A member-qualified name will be first looked up in the type of the
object expression `T` unless `T` is a dependent type that is _not_ the
current instantiation, e.g.
```
template<typename T>
struct A
{
void f(T* t)
{
this->x; // type of the object expression is 'A<T>'. although 'A<T>' is dependent, it is the
// current instantiation so we look up 'x' in the template definition context.
t->y; // type of the object expression is 'T' ('->' is transformed to '.' per [expr.ref]).
// 'T' is dependent and is *not* the current instantiation, so we lookup 'y' in the
// template instantiation context.
}
};
```
- If the first lookup finds nothing and:
- the member-qualified name is the first component of a
_nested-name-specifier_ (which could be an _identifier_ or a
_simple-template-id_), and either:
- the type of the object expression is the current instantiation and it
has no dependent base classes, or
- the type of the object expression is not dependent
then we lookup the name again, this time via unqualified lookup.
Although the second (unqualified) lookup is stated not to occur when the
member-qualified name is dependent, a dependent name will _not_ be
dependent once the template is instantiated, so the second lookup must
"occur" during instantiation if qualified lookup does not find anything.
This means that we must perform the second (unqualified) lookup during
parsing even when the type of the object expression is dependent, but
those results are _not_ used to determine whether a `<` token is the
start of a _template-argument_list_; they are stored so we can replicate
the second lookup during instantiation.
In even simpler terms (paraphrasing the meeting minutes from the review of P1787; see https://wiki.edg.com/bin/view/Wg21summer2020/P1787%28Lookup%29Review2020-06-15Through2020-06-18):
- Unqualified lookup always happens for the first name in a
_nested-name-specifier_ that follows `.` or `->`
- The result of that lookup is only used to determine whether `<` is the
start of a _template-argument-list_ if the first (qualified) lookup
found nothing and the lookup context:
- is not dependent, or
- is the current instantiation and has no dependent base classes.
An example:
```
struct A
{
void f();
};
template<typename T>
using B = A;
template<typename T>
struct C : A
{
template<typename U>
void g();
void h(T* t)
{
this->g<int>(); // ok, '<' is the start of a template-argument-list ('g' was found via qualified lookup in the current instantiation)
this->B<void>::f(); // ok, '<' is the start of a template-argument-list (current instantiation has no dependent bases, 'B' was found via unqualified lookup)
t->g<int>(); // error: '<' means less than (unqualified lookup does not occur for a member-qualified name that isn't the first component of a nested-name-specifier)
t->B<void>::f(); // error: '<' means less than (unqualified lookup does not occur if the name is dependent)
t->template B<void>::f(); // ok: '<' is the start of a template-argument-list ('template' keyword used)
}
};
```
Some additional notes:
- Per [basic.lookup.qual.general] p1, lookup for a
member-qualified name only considers namespaces, types, and templates
whose specializations are types if it's an _identifier_ followed by
`::`; lookup for the component name of a _simple-template-id_ followed
by `::` is _not_ subject to this rule.
- The wording which specifies when the second unqualified lookup occurs
appears to be paradoxical. We are supposed to do it only for the first
component name of a _nested-name-specifier_ that follows `.` or `->`
when qualified lookup finds nothing. However, when that name is followed
by `<` (potentially starting a _simple-template-id_) we don't _know_
whether it will be the start of a _nested-name-specifier_ until we do
the lookup -- but we aren't supposed to do the lookup until we know it's
part of a _nested-name-specifier_! ***However***, since we only do the
second lookup when the first lookup finds nothing (and the name isn't
dependent), ***and*** since neither lookup is type-only, the only valid
option is for the name to be the _template-name_ in a
_simple-template-id_ that is followed by `::` (it can't be an
_unqualified-id_ naming a member because we already determined that the
lookup context doesn't have a member with that name). Thus, we can lock
into the _nested-name-specifier_ interpretation and do the second lookup
without having to know whether the _simple-template-id_ will be followed
by `::` yet.
In the https://github.com/llvm/llvm-project/pull/90961 fix, we miss a
case where the undeduced template parameters of the underlying deduction
guide are not transformed, which leaves incorrect depth/index
information, and causes crashes when evaluating constraints.
This patch fix this missing case.
Fixes#92596Fixes#92212
This patch moves documentation of `Sema` functions from `.cpp` files to `Sema.h` when there was no documentation in the latter, or it can be trivially subsumed. More complicated cases when there's less trivial divergence between documentation attached to declaration and the one attached to implementation are left for a later PR that would require review.
It appears that doxygen can find the documentation for a function defined out-of-line even if it's attached to an implementation, and not declaration. But other tools, e.g. clangd, are not as powerful. So this patch significantly improves autocompletion experience for (at least) clangd-based IDEs.
This patch addresses static analyzer concerns where `TSI` could be
dereferenced after being assigned a null value from `SubstType` in
`ConvertConstructorToDeductionGuideTransform()`.
The fixes now check null value of `TSI` after the call to `SubstType`
and return `nullptr` to prevent potential null pointer dereferences when
calling getTypeLoc() or getType() and ensure safe execution.
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.
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.
When performing template argument deduction, we extend the provisional
wording introduced in https://github.com/llvm/llvm-project/pull/89807 so
it also covers deduction of class templates.
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 has the beneficial side effect of making the following code valid:
```C++
template<class T, class U> struct A {};
A<int, float> v;
template<template<class> class TT> void f(TT<int>);
// OK: TT picks 'float' as the default argument for the second parameter.
void g() { f(v); }
```
---
Since this changes provisional implementation of CWG2398 which has not
been released yet, and already contains a changelog entry, we don't
provide a changelog entry here.
This is an enabler for https://github.com/llvm/llvm-project/pull/92855
This allows an NTTP default argument to be set as an arbitrary
TemplateArgument, not just an expression.
This allows template parameter packs to have default arguments in the
AST, even though the language proper doesn't support the syntax for it.
This allows NTTP default arguments to be other kinds of arguments, like
packs, integral constants, and such.
This is an enabler for a future patch.
This allows an type-parameter default argument to be set as an arbitrary
TemplateArgument, not just a type.
This allows template parameter packs to have default arguments in the
AST, even though the language proper doesn't support the syntax for it.
This will be used in a later patch which synthesizes template parameter
lists with arbitrary default arguments taken from template
specializations.
There are a few places we used SubsType, because we only had a type, now
we use SubstTemplateArgument.
SubstTemplateArgument was missing arguments for setting Instantiation
location and entity names.
Adding those is needed so we don't regress in diagnostics.
Clang incorrectly accepts the following when using C++14 or later:
```
struct A {
template<typename T>
void f() const;
template<>
constexpr void f<int>();
};
```
Non-static member functions declared `constexpr` are only implicitly
`const` in C++11. This patch makes clang reject the explicit
specialization of `f` in language modes after C++11.
According to [expr.prim.id.general] p2:
> If an _id-expression_ `E` denotes a non-static non-type member of some
class `C` at a point where the current class is `X` and
> - `E` is potentially evaluated or `C` is `X` or a base class of `X`,
and
> - `E` is not the _id-expression_ of a class member access expression,
and
> - if `E` is a _qualified-id_, `E` is not the un-parenthesized operand
of the unary `&` operator,
>
> the _id-expression_ is transformed into a class member access
expression using `(*this)` as the object expression.
Consider the following:
```
struct A
{
void f0();
template<typename T>
void f1();
};
template<typename T>
struct B : T
{
auto g0() -> decltype(T::f0()); // ok
auto g1() -> decltype(T::template f1<int>()); // error: call to non-static member function without an object argument
};
template struct B<A>;
```
Clang incorrectly rejects the call to `f1` in the _trailing-return-type_
of `g1`. Furthermore, the following snippet results in a crash during
codegen:
```
struct A
{
void f();
};
template<typename T>
struct B : T
{
template<typename U>
static void g();
template<>
void g<int>()
{
return T::f(); // crash here
}
};
template struct B<A>;
```
This happens because we unconditionally build a
`CXXDependentScopeMemberExpr` (with an implicit object expression) for
`T::f` when parsing the template definition, even though we don't know
whether `g` is an implicit object member function yet.
This patch fixes these issues by instead building
`DependentScopeDeclRefExpr`s for such expressions, and only transforming
them into implicit class member access expressions during instantiation.
Since we implemented the MS "unqualified lookup into dependent bases"
extension by building an implicit class member access (and relying on
the first component name of the _nested-name-specifier_ to be looked up
in the context of the object expression during instantiation), we
instead pre-append a fake _nested-name-specifier_ that refers to the
injected-class-name of the enclosing class. This patch also refactors
`Sema::BuildQualifiedDeclarationNameExpr` and
`Sema::BuildQualifiedTemplateIdExpr`, streamlining their implementation
and removing any redundant checks.
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.
When performing template argument deduction, a template template
parameter
containing no packs should be more specialized than one that does.
Given the following example:
```C++
template<class T2> struct A;
template<template<class ...T3s> class TT1, class T4> struct A<TT1<T4>>; // #1
template<template<class T5 > class TT2, class T6> struct A<TT2<T6>>; // #2
template<class T1> struct B;
template struct A<B<char>>;
```
Prior to P0522, candidate `#2` would be more specialized.
After P0522, neither is more specialized, so this becomes ambiguous.
With this change, `#2` becomes more specialized again,
maintaining compatibility with pre-P0522 implementations.
The problem is that in P0522, candidates are at least as specialized
when matching packs to fixed-size lists both ways, whereas before,
a fixed-size list is more specialized.
This patch keeps the original behavior when checking template arguments
outside deduction, but restores this aspect of pre-P0522 matching
during deduction.
---
Since this changes provisional implementation of CWG2398 which has
not been released yet, and already contains a changelog entry,
we don't provide a changelog entry here.
Fixes https://github.com/llvm/llvm-project/issues/85192
Fixes https://github.com/llvm/llvm-project/issues/84492
This patch implements the "IsDeducible" constraint where the template
arguments of the alias template can be deduced from the returned type of
the synthesized deduction guide, per C++ [over.match.class.deduct]p4. In
the implementation, we perform the deduction directly, which is more
efficient than the way specified in the standard.
Also update relevant CTAD tests which were incorrectly compiled due to
the missing constraint.
When partial ordering alias templates against template template
parameters, allow pack expansions when the alias has a fixed-size
parameter list.
These expansions were generally disallowed by proposed resolution for
CWG1430.
By previously diagnosing these when checking template template
parameters, we would be too strict in trying to prevent any potential
invalid use.
This flows against the more general idea that template template
parameters are weakly typed, that we would rather allow an argument that
might be possibly misused, and only diagnose the actual misuses during
instantiation.
Since this interaction between P0522R0 and CWG1430 is also a
backwards-compat breaking change, we implement provisional wording to
allow these.
Fixes https://github.com/llvm/llvm-project/issues/62529
In the clang AST, constraint nodes are deliberately not instantiated
unless they are actively being evaluated. Consequently, occurrences of
template parameters in the require-clause expression have a subtle
"depth" difference compared to normal occurrences in places, such as
function parameters. When transforming the require-clause, we must take
this distinction into account.
The existing implementation overlooks this consideration. This patch is
to rewrite the implementation of the require-clause transformation to
address this issue.
Fixes#90177
source location in `ConvertConstructorToDeductionGuideTransform`.
The commit fec471649fffaa3ec44e17801e5c9605825e58bb was reverted by accident in 7415524b45392651969374c067041daa82dc89e7.
Reland it with a testcase.
I'm planning to remove StringRef::equals in favor of
StringRef::operator==.
- StringRef::operator==/!= outnumber StringRef::equals by a factor of
24 under clang/ in terms of their usage.
- The elimination of StringRef::equals brings StringRef closer to
std::string_view, which has operator== but not equals.
- S == "foo" is more readable than S.equals("foo"), especially for
!Long.Expression.equals("str") vs Long.Expression != "str".
This fixes a regression introduced by bee78b88f.
When we form a deduction guide for a constructor, basically, we do the
following work:
- Collect template parameters from the constructor's surrounding class
template, if present.
- Collect template parameters from the constructor.
- Splice these template parameters together into a new template
parameter list.
- Turn all the references (e.g. the function parameter list) to the
invented parameter list by applying a `TreeTransform` to the function
type.
In the previous fix, we handled cases of nested class templates by
substituting the "outer" template parameters (i.e. those not declared at
the surrounding class template or the constructor) with the
instantiating template arguments. The approach per se makes sense, but
there was a flaw in the following case:
```cpp
template <typename U, typename... Us> struct X {
template <typename V> struct Y {
template <typename T> Y(T) {}
};
template <typename T> Y(T) -> Y<T>;
};
X<int>::Y y(42);
```
While we're transforming the parameters for `Y(T)`, we first attempt to
transform all references to `V` and `T`; then, we handle the references
to outer parameters `U` and `Us` using the template arguments from
`X<int>` by transforming the same `ParamDecl`. However, the first step
results in the reference `T` being `<template-param-0-1>` because the
invented `T` is the last of the parameter list of the deduction guide,
and what we're substituting with is a corresponding parameter pack
(which is `Us`, though empty). Hence we're messing up the substitution.
I think we can resolve it by reversing the substitution order, which
means handling outer template parameters first and then the inner
parameters.
There's no release note because this is a regression in 18, and I hope
we can catch up with the last release.
Fixes https://github.com/llvm/llvm-project/issues/88142