824 Commits

Author SHA1 Message Date
Matheus Izvekov
a24523ac8d
[clang] Implement instantiation context note for checking template parameters (#126088)
Instead of manually adding a note pointing to the relevant template
parameter to every relevant error, which is very easy to miss, this
patch adds a new instantiation context note, so that this can work using
RAII magic.

This fixes a bunch of places where these notes were missing, and is more
future-proof.

Some diagnostics are reworked to make better use of this note:
- Errors about missing template arguments now refer to the parameter
which is missing an argument.
- Template Template parameter mismatches now refer to template
parameters as parameters instead of arguments.

It's likely this will add the note to some diagnostics where the
parameter is not super relevant, but this can be reworked with time and
the decrease in maintenance burden makes up for it.

This bypasses the templight dumper for the new context entry, as the
tests are very hard to update.

This depends on #125453, which is needed to avoid losing the context
note for errors occuring during template argument deduction.
2025-03-06 14:58:42 -03:00
erichkeane
df1e102e2a [OpenACC] implement AST/Sema for 'routine' construct with argument
The 'routine' construct has two forms, one which takes the name of a
function that it applies to, and another where it implicitly figures it
out based on the next declaration. This patch implements the former with
the required restrictions on the name and the function-static-variables
as specified.

What has not been implemented is any clauses for this, any of the A.3.4
warnings, or the other form.
2025-03-06 06:42:17 -08:00
Matheus Izvekov
0948fc85aa
[clang] print correct context for diagnostics suppressed by deduction (#125453)
This patch makes it so the correct instantiation context is printed for
diagnostics suppessed by template argument deduction.

The context is saved along with the suppressed diagnostic, and when the
declaration they were attached to becomes used, we print the correct
context, instead of whatever context was at this point.
2025-02-20 08:50:03 -03:00
Jason Rice
f7c71f1622
[Clang][P1061] Consolidate ResolvedUnpexandedPackExpr into FunctionParmPackExpr (#125394)
This merges the functionality of ResolvedUnexpandedPackExpr into
FunctionParmPackExpr. I also added a test to show that
https://github.com/llvm/llvm-project/issues/125103 should be fixed with
this. I put the removal of ResolvedUnexpandedPackExpr in its own commit.
Let me know what you think.

Fixes #125103
2025-02-18 09:42:24 +01:00
Younan Zhang
c08b80eb52
[Clang] Remove the PackExpansion restrictions for rewrite substitution (#126206)
When substituting for rewrite purposes, as in rebuilding constraints for
a synthesized deduction guide, it assumed that packs were in
PackExpansion* form, such that the instantiator could extract a pattern.
    
For type aliases CTAD, while rebuilding their associated constraints,
this might not be the case because we'll call
`TransformTemplateArgument()` for the alias template arguments, where
there might be cases e.g. a non-pack expansion type into a pack
expansion, so the assumption wouldn't hold.
    
This patch fixes that by making it treat the non-pack expansions as
direct patterns when rewriting.

Fixes #124715
2025-02-14 15:25:52 +08:00
Matheus Izvekov
346077aaa6
Reland: [clang] Track function template instantiation from definition (#125266) 2025-02-05 14:12:12 -03:00
Matheus Izvekov
c94d930a21
[clang] NFC: rename MatchedPackOnParmToNonPackOnArg to StrictPackMatch (#125418)
This rename follows the proposed wording in P3310R5, which introduces
the term 'strict pack match' to refer to the same thing.
2025-02-05 13:16:33 -03:00
Kazu Hirata
c517edbd0c
[Sema] Migrate away from PointerUnion::dyn_cast (NFC) (#125811)
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 Specialized to be nonnull. Note that if Specialized
were
null, dereferencing Tmpl would trigger a segfault.
2025-02-05 07:16:36 -08:00
Kazu Hirata
63c59dda43
[Sema] Migrate away from PointerUnion::dyn_cast (NFC) (#125630)
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 *Found to be nonnull.  Note that if *Found were
null, cast<VarDecl>(TransformedDecl) would trigger an assertion error.
2025-02-04 09:09:01 -08:00
Martin Storsjö
5c24847e7d Revert "[clang] Track function template instantiation from definition (#112241)"
This reverts commit 07a0e2be86f33beb6d519a3d466b95c2257e93cb.

This change broke compiling Qt; see
https://github.com/llvm/llvm-project/pull/112241 for details.
2025-01-30 12:05:56 +02:00
Jason Rice
abc8812df0
[Clang][P1061] Add stuctured binding packs (#121417)
This is an implementation of P1061 Structure Bindings Introduce a Pack
without the ability to use packs outside of templates. There is a couple
of ways the AST could have been sliced so let me know what you think.
The only part of this change that I am unsure of is the
serialization/deserialization stuff. I followed the implementation of
other Exprs, but I do not really know how it is tested. Thank you for
your time considering this.

---------

Co-authored-by: Yanzuo Liu <zwuis@outlook.com>
2025-01-29 21:43:52 +01:00
Matheus Izvekov
07a0e2be86
[clang] Track function template instantiation from definition (#112241)
This fixes instantiation of definition for friend function templates,
when the declaration found and the one containing the definition have
different template contexts.

In these cases, the the function declaration corresponding to the
definition is not available; it may not even be instantiated at all.

So this patch adds a bit which tracks which function template
declaration was instantiated from the member template. It's used to find
which primary template serves as a context for the purpose of
obtainining the template arguments needed to instantiate the definition.

Fixes #55509

Relanding patch, with no changes, after it was reverted due to revert of
commit this patch depended on.
2025-01-29 17:23:36 -03:00
Matheus Izvekov
e29c085812
[clang] disallow narrowing when matching template template parameters (#124313)
This fixes the core issue described in P3579, following the design
intent of P0522 to not introduce any new cases where a template template
parameter match is allowed for a template which is not valid for all
possible uses.

With this patch, narrowing conversions are disallowed for TTP matching.

This reuses the existing machinery for diagnosing narrowing in a
converted constant expression.
Since P0522 is a DR and we apply it all the way back to C++98, this
brings that machinery to use in older standards, in this very narrow
scope of TTP matching.

This still doesn't solve the ambiguity when partial ordering NTTPs of
different integral types, this is blocked by a different bug which will
be fixed in a subsequent patch (but the test cases are added).
2025-01-28 15:51:17 -03:00
Younan Zhang
27c9173075
[Clang] Remove unnecessary Decl transform & profiles for SizeOfPackExpr (#124533)
We used to always transform the pattern declaration for SizeOfPackExpr
to ensure the constraint expression's profile produced the desired
result. However, this approach failed to handle pack expansions when the
pack referred to function parameters. In such cases, the function
parameters were formerly expanded to 1 to avoid building Subst* nodes
(see e6974daa7). That workaround caused us to transform a pack without a
proper ArgumentPackSubstitutionIndex, leading to crashes when
transforming the pattern.

It turns out that profiling the pattern for partially substituted
SizeOfPackExprs is unnecessary because their transformed forms are also
profiled within the partial arguments.

Fixes https://github.com/llvm/llvm-project/issues/124161
2025-01-27 23:04:57 +08:00
Matheus Izvekov
28ad8978ee
Reland: [clang] unified CWG2398 and P0522 changes; finishes implementation of P3310 (#124137)
This patch relands the following PRs:
* #111711
* #107350
* #111457

All of these patches were reverted due to an issue reported in
https://github.com/llvm/llvm-project/pull/111711#issuecomment-2406491485,
due to interdependencies.

---
[clang] Finish implementation of P0522

This finishes the clang implementation of P0522, getting rid
of the fallback to the old, pre-P0522 rules.

Before this patch, when partial ordering template template parameters,
we would perform, in order:
* If the old rules would match, we would accept it. Otherwise, don't
  generate diagnostics yet.
* If the new rules would match, just accept it. Otherwise, don't
  generate any diagnostics yet again.
* Apply the old rules again, this time with diagnostics.

This situation was far from ideal, as we would sometimes:
* Accept some things we shouldn't.
* Reject some things we shouldn't.
* Only diagnose rejection in terms of the old rules.

With this patch, we apply the P0522 rules throughout.

This needed to extend template argument deduction in order
to accept the historial rule for TTP matching pack parameter to non-pack
arguments.
This change also makes us accept some combinations of historical and P0522
allowances we wouldn't before.

It also fixes a bunch of bugs that were documented in the test suite,
which I am not sure there are issues already created for them.

This causes a lot of changes to the way these failures are diagnosed,
with related test suite churn.

The problem here is that the old rules were very simple and
non-recursive, making it easy to provide customized diagnostics,
and to keep them consistent with each other.

The new rules are a lot more complex and rely on template argument
deduction, substitutions, and they are recursive.

The approach taken here is to mostly rely on existing diagnostics,
and create a new instantiation context that keeps track of this context.

So for example when a substitution failure occurs, we use the error
produced there unmodified, and just attach notes to it explaining
that it occurred in the context of partial ordering this template
argument against that template parameter.

This diverges from the old diagnostics, which would lead with an
error pointing to the template argument, explain the problem
in subsequent notes, and produce a final note pointing to the parameter.

---
[clang] CWG2398: improve overload resolution backwards compat

With this change, we discriminate if the primary template and which partial
specializations would have participated in overload resolution prior to
P0522 changes.

We collect those in an initial set. If this set is not empty, or the
primary template would have matched, we proceed with this set as the
candidates for overload resolution.

Otherwise, we build a new overload set with everything else, and proceed
as usual.

---
[clang] Implement TTP 'reversed' pack matching for deduced function template calls.

Clang previously missed implementing P0522 pack matching
for deduced function template calls.
2025-01-23 20:37:33 -03:00
Kazu Hirata
f5736aee11
[Sema] Migrate away from PointerUnion::dyn_cast (NFC) (#123284)
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 Stored to be nonnull.
2025-01-17 08:46:52 -08:00
Younan Zhang
3972ed5708
Revert "[Clang] Implement CWG2369 "Ordering between constraints and substitution"" (#122130)
Unfortunately that breaks some code on Windows when lambdas come into
play, as reported in
https://github.com/llvm/llvm-project/pull/102857#issuecomment-2577861178

This reverts commit 96eced624e0f120155256033fdcb8342e7e58d6e.
2025-01-08 18:27:25 +01:00
Younan Zhang
96eced624e
[Clang] Implement CWG2369 "Ordering between constraints and substitution" (#102857)
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
2025-01-05 10:50:52 +08:00
Kazu Hirata
1e3e199ed9
[Sema] Migrate away from PointerUnion::{is,get} (NFC) (#117498)
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.
2024-11-27 09:13:28 -08:00
Kazu Hirata
46d750be2e
[Sema] Remove unused includes (NFC) (#116461)
Identified with misc-include-cleaner.
2024-11-16 07:37:33 -08:00
Sirraide
dde802b153
[Clang] [NFC] Refactor AST visitors in Sema and the static analyser to use DynamicRecursiveASTVisitor (#115144)
This pr refactors all recursive AST visitors in `Sema`, `Analyze`, and
`StaticAnalysis` to inherit from DRAV instead. This is over half of the
visitors that inherit from RAV directly.

See also #115132, #110040, #93462

LLVM Compile-Time Tracker link for this branch:
https://llvm-compile-time-tracker.com/compare.php?from=5adb5c05a2e9f31385fbba8b0436cbc07d91a44d&to=b58e589a86c06ba28d4d90613864d10be29aa5ba&stat=instructions%3Au
2024-11-15 08:04:08 +01:00
Younan Zhang
de2fad3251
[Clang] Fix dependent expression handling for assumptions (#115646)
The function definition instantiation assumes any declarations used
inside are already transformed before transforming the body, so we need
to preserve the transformed expression of CXXAssumeAttr even if it is
not a constant expression. Moreover, the full expression of the
assumption should also entail a potential lambda capture transformation,
hence the call to ActOnFinishFullExpr() after TransformExpr().

Fixes #114787
2024-11-12 09:45:33 +08:00
Younan Zhang
37b4df434d
[Clang] Remove the wrong assumption when rebuilding SizeOfPackExprs for constraint normalization (#115120)
In 463a4f150, we assumed that all the template argument packs are of
size 1 when normalizing a constraint expression because I mistakenly
thought those packs were obtained from their injected template
parameters. This was wrong because we might be checking constraints when
instantiating a friend declaration within a class template
specialization, where the parent class template is specialized with
non-dependent template arguments.

In that sense, we shouldn't assume any pack size nor expand anything in
such a scenario. Moreover, there are no intermediate (substituted but
unexpanded) AST nodes for template template parameters, so we have to
special-case their transformations by looking into the instantiation
scope instead of extracting anything from template arguments.

Fixes #115098
2024-11-08 14:04:57 +08:00
Younan Zhang
adb0d8ddce
[Clang] Distinguish expanding-pack-in-place cases for SubstTemplateTypeParmTypes (#114220)
In 50e5411e4, we preserved the pack substitution index within
SubstTemplateTypeParmType nodes and performed in-place expansions of
packs such that type constraints on a lambda that serve as a pattern of
a fold expression could be evaluated if the type constraints contain any
packs that are expanded by the fold expression.

However, we made an incorrect assumption of the condition under which
in-place expansion should occur. For example, a SizeOfPackExpr case
relies on SubstTemplateTypeParmType nodes being transformed to
SubstTemplateTypeParmPackTypes rather than expanding them immediately in
place.

This fixes that by adding a flag to SubstTemplateTypeParmType to
discriminate such in-place expansion situations.

Fixes https://github.com/llvm/llvm-project/issues/113518
2024-11-07 15:37:14 +08:00
Krystian Stasiowski
44ab3805b5
Revert "Reapply "[Clang][Sema] Refactor collection of multi-level template argument lists (#106585, #111173)" (#111852)" (#115159)
This reverts commit 2bb3d3a3f32ffaef3d9b6a27db7f1941f0cb1136.
2024-11-06 09:25:29 -05:00
Krystian Stasiowski
2904f809cd
Revert "[Clang][Sema] Use the correct injected template arguments for partial specializations when collecting multi-level template argument lists (#112381)" (#115157)
This reverts commit 9381c6fd04cc16a7606633f57c96c11e58181ddb.
2024-11-06 08:43:37 -05:00
Krystian Stasiowski
79f4d8f014
Revert "Reapply "[Clang][Sema] Always use latest redeclaration of primary template" (#114569)" (#115156)
This reverts commit b24650e814e55d90acfc40acf045456c98f32b9c.
2024-11-06 08:38:59 -05:00
Krystian Stasiowski
b24650e814
Reapply "[Clang][Sema] Always use latest redeclaration of primary template" (#114569)
This patch reapplies #114258, fixing an infinite recursion bug in
`ASTImporter` that occurs when importing the primary template of a class
template specialization when the latest redeclaration of that template
is a friend declaration in the primary template.
2024-11-01 16:15:33 -04:00
Felipe de Azevedo Piovezan
4afa978756
Revert "[Clang][Sema] Always use latest redeclaration of primary template" (#114304)
Clang importer doesn't seem to work well with this change, see
discussion in the original PR.

Reverts llvm/llvm-project#114258
2024-10-30 14:04:26 -07:00
Krystian Stasiowski
90786adade
[Clang][Sema] Always use latest redeclaration of primary template (#114258)
This patch fixes a couple of regressions introduced in #111852.

Consider:

```
template<typename T>
struct A
{
    template<bool U>
    static constexpr bool f() requires U
    {
        return true;
    }
};

template<>
template<bool U>
constexpr bool A<short>::f() requires U
{
    return A<long>::f<U>();
}

template<>
template<bool U>
constexpr bool A<long>::f() requires U
{
    return true;
}

static_assert(A<short>::f<true>()); // crash here
```

This crashes because when collecting template arguments from the _first_
declaration of `A<long>::f<true>` for constraint checking, we don't add
the template arguments from the enclosing class template specialization
because there exists another redeclaration that is a member
specialization.

This also fixes the following example, which happens for a similar
reason:
```
// input.cppm

export module input;

export template<int N>
constexpr int f();

template<int N>
struct A {
  template<int J>
  friend constexpr int f();
};

template struct A<0>;

template<int N>
constexpr int f() {
  return N;
}
```

```
// input.cpp

import input;

static_assert(f<1>() == 1); // error: static assertion failed
```
2024-10-30 14:50:40 -04:00
Krystian Stasiowski
7d1e283bd3
[Clang][Sema] Ignore previous partial specializations of member templates explicitly specialized for an implicitly instantiated class template specialization (#113464)
Consider the following:
```
template<typename T>
struct A {
  template<typename U>
  struct B {
    static constexpr int x = 0; // #1
  };

  template<typename U>
  struct B<U*> {
    static constexpr int x = 1; // #2
  };
};

template<>
template<typename U>
struct A<long>::B {
  static constexpr int x = 2; // #3
};

static_assert(A<short>::B<int>::y == 0); // uses #1
static_assert(A<short>::B<int*>::y == 1); // uses #2

static_assert(A<long>::B<int>::y == 2); // uses #3
static_assert(A<long>::B<int*>::y == 2); // uses #3
```

According to [temp.spec.partial.member] p2:
> If the primary member template is explicitly specialized for a given
(implicit) specialization of the enclosing class template, the partial
specializations of the member template are ignored for this
specialization of the enclosing class template.
If a partial specialization of the member template is explicitly
specialized for a given (implicit) specialization of the enclosing class
template, the primary member template and its other partial
specializations are still considered for this specialization of the
enclosing class template.

The example above fails to compile because we currently don't implement
[temp.spec.partial.member] p2. This patch implements the wording, fixing #51051.
2024-10-30 11:24:10 -04:00
Krystian Stasiowski
639a7ac648
[Clang][AST] Store injected template arguments in TemplateParameterList (#113579)
Currently, we store injected template arguments in
`RedeclarableTemplateDecl::CommonBase`. This approach has a couple
problems:
1. We can only access the injected template arguments of
`RedeclarableTemplateDecl` derived types, but other `Decl` kinds still
make use of the injected arguments (e.g.
`ClassTemplatePartialSpecializationDecl`,
`VarTemplatePartialSpecializationDecl`, and `TemplateTemplateParmDecl`).
2. Accessing the injected template arguments requires the common data
structure to be allocated. This may occur before we determine whether a
previous declaration exists (e.g. when comparing constraints), so if the
template _is_ a redeclaration, we end up discarding the common data
structure.

This patch moves the storage and access of injected template arguments
from `RedeclarableTemplateDecl` to `TemplateParameterList`.
2024-10-29 13:36:55 -04:00
Jay Foad
4dd55c567a
[clang] Use {} instead of std::nullopt to initialize empty ArrayRef (#109399)
Follow up to #109133.
2024-10-24 10:23:40 +01:00
Vlad Serebrennikov
8536c2e9a2
[clang][NFC] Move concepts::createSubstDiagAt from AST to Sema (#113294)
This fixes layering violation introduced in
2fd01d75a863184766ee0c82b5c0fc8be172448a. The declaration is moved to
`SemaTemplateInstantiate` section of `Sema.h`, after the file where it's
implemented.
2024-10-22 22:18:25 +04:00
Boaz Brickner
09cc75e2cc
[clang] Deduplicate the logic that only warns once when stack is almost full (#112552)
Zero diff in behavior.
2024-10-18 10:11:14 +02:00
Krystian Stasiowski
9381c6fd04
[Clang][Sema] Use the correct injected template arguments for partial specializations when collecting multi-level template argument lists (#112381)
After #111852 refactored multi-level template argument list collection,
the following results in a crash:
```
template<typename T, bool B>
struct A;

template<bool B>
struct A<int, B>
{
    void f() requires B;
};

template<bool B>
void A<int, B>::f() requires B { } // crash here
```

This happens because when collecting template arguments for constraint
normalization from a partial specialization, we incorrectly use the
template argument list of the partial specialization. We should be using
the template argument list of the _template-head_ (as defined in
[temp.arg.general] p2). Fixes #112222.
2024-10-16 10:40:03 -04:00
Krystian Stasiowski
2bb3d3a3f3
Reapply "[Clang][Sema] Refactor collection of multi-level template argument lists (#106585, #111173)" (#111852)
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.
2024-10-11 14:08:06 -04:00
Sirraide
48bda00b28
[Clang] [Sema] Don't crash on unexpanded pack in invalid block literal (#110762)
Consider #109148:
```c++
template <typename ...Ts>
void f() {
    [] {
        (^Ts);
    };
}
```

When we encounter `^Ts`, we try to parse a block and subsequently call
`DiagnoseUnexpandedParameterPack()` (in `ActOnBlockArguments()`), which
sees `Ts` and sets `ContainsUnexpandedParameterPack` to `true` in the
`LambdaScopeInfo` of the enclosing lambda. However, the entire block is
subsequently discarded entirely because it isn’t even syntactically
well-formed. As a result, `ContainsUnexpandedParameterPack` is `true`
despite the lambda’s body no longer containing any unexpanded packs,
which causes an assertion the next time
`DiagnoseUnexpandedParameterPack()` is called.

This pr moves handling of unexpanded parameter packs into
`CapturingScopeInfo` instead so that the same logic is used for both
blocks and lambdas. This fixes this issue since the
`ContainsUnexpandedParameterPack` flag is now part of the block (and
before that, its `CapturingScopeInfo`) and no longer affects the
surrounding lambda directly when the block is parsed. Moreover, this
change makes blocks actually usable with pack expansion.

This fixes #109148.
2024-10-11 20:03:43 +02:00
Mikhail Goncharov
efcfa6e711 Revert "Reland: [clang] Finish implementation of P0522 (#111711)"
See discussion in https://github.com/llvm/llvm-project/pull/111711

This reverts commit 6213aa5e58a7d32bdc82dd40322fb1bab83c4783.
2024-10-11 14:47:38 +02:00
Mikhail Goncharov
bdd46cc6b7 Revert "[clang] CWG2398: improve overload resolution backwards compat (#107350)"
See discussion in https://github.com/llvm/llvm-project/pull/111711

This reverts commit 224519b08945637a85e9798c78286643288f7b77.
2024-10-11 14:47:21 +02:00
Eric Astor
73e74e496e
[clang][frontend] Support applying the annotate attribute to statements (#111841)
By allowing AnnotateAttr to be applied to statements, users can place arbitrary information in the AST for later use.

For example, this can be used for HW-targeted language extensions that involve specialized loop annotations.
2024-10-10 12:21:34 -04:00
Matheus Izvekov
224519b089
[clang] CWG2398: improve overload resolution backwards compat (#107350)
With this change, we discriminate if the primary template and which
partial specializations would have participated in overload resolution
prior to P0522 changes.

We collect those in an initial set. If this set is not empty, or the
primary template would have matched, we proceed with this set as the
candidates for overload resolution.

Otherwise, we build a new overload set with everything else, and proceed
as usual.
2024-10-10 04:50:53 -03:00
Matheus Izvekov
6213aa5e58
Reland: [clang] Finish implementation of P0522 (#111711)
This finishes the clang implementation of P0522, getting rid of the
fallback to the old, pre-P0522 rules.

Before this patch, when partial ordering template template parameters,
we would perform, in order:
* If the old rules would match, we would accept it. Otherwise, don't
generate diagnostics yet.
* If the new rules would match, just accept it. Otherwise, don't
generate any diagnostics yet again.
* Apply the old rules again, this time with diagnostics.

This situation was far from ideal, as we would sometimes:
* Accept some things we shouldn't.
* Reject some things we shouldn't.
* Only diagnose rejection in terms of the old rules.

With this patch, we apply the P0522 rules throughout.

This needed to extend template argument deduction in order to accept the
historial rule for TTP matching pack parameter to non-pack arguments.
This change also makes us accept some combinations of historical and
P0522 allowances we wouldn't before.

It also fixes a bunch of bugs that were documented in the test suite,
which I am not sure there are issues already created for them.

This causes a lot of changes to the way these failures are diagnosed,
with related test suite churn.

The problem here is that the old rules were very simple and
non-recursive, making it easy to provide customized diagnostics, and to
keep them consistent with each other.

The new rules are a lot more complex and rely on template argument
deduction, substitutions, and they are recursive.

The approach taken here is to mostly rely on existing diagnostics, and
create a new instantiation context that keeps track of this context.

So for example when a substitution failure occurs, we use the error
produced there unmodified, and just attach notes to it explaining that
it occurred in the context of partial ordering this template argument
against that template parameter.

This diverges from the old diagnostics, which would lead with an error
pointing to the template argument, explain the problem in subsequent
notes, and produce a final note pointing to the parameter.
2024-10-10 04:39:46 -03:00
Krystian Stasiowski
1dff3309fd
Revert "Reapply "[Clang][Sema] Refactor collection of multi-level template argument lists (#106585)" (#111173)" (#111766)
This reverts commit 4da8ac34f76e707ab94380b94f616457cfd2cb83.
2024-10-09 17:49:32 -04:00
Krystian Stasiowski
91dd4ec20e
Revert "[clang] Track function template instantiation from definition (#110387)" (#111764)
This reverts commit 4336f00f2156970cc0af2816331387a0a4039317.
2024-10-09 17:43:55 -04:00
Hans Wennborg
ada6372e52 Revert "[clang] Finish implementation of P0522 (#96023)"
This caused Clang to reject valid code, see discussion on the PR
https://github.com/llvm/llvm-project/pull/96023#issuecomment-2393228464
and https://github.com/llvm/llvm-project/issues/111363

This reverts commit 6afe56732a172d3f2cbd0330b1fcb34bbfd002a9 and
follow-up commit 9abb97f9663a27fe5b8e346ed557b3435aa9ec2f.
2024-10-09 08:41:42 +02:00
Matheus Izvekov
4336f00f21
[clang] Track function template instantiation from definition (#110387)
This fixes instantiation of definition for friend function templates,
when the declaration found and the one containing the definition
have different template contexts.

In these cases, the the function declaration corresponding to the
definition is not available; it may not even be instantiated at all.

So this patch adds a bit which tracks which function template
declaration was instantiated from the member template.
It's used to find which primary template serves as a context
for the purpose of obtaining the template arguments needed
to instantiate the definition.

Fixes #55509
2024-10-09 01:55:21 -03:00
Krystian Stasiowski
4da8ac34f7
Reapply "[Clang][Sema] Refactor collection of multi-level template argument lists (#106585)" (#111173)
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.
2024-10-08 10:14:09 -04:00
Matheus Izvekov
017b504b46
[clang] Don't lose track of explicit specializations of member function templates (#111267)
When instantiating a class template, we would lose track of function
template explicit specializations, marking them with the wrong
specialization kind.

This would lead to improperly using the explcit specialization arguments
to instantiate the function body.

This also better matches MSVC on the behaviour of explicitly vs
implicitly instantiating these.

Fixes #111266
2024-10-07 16:46:27 -03:00
Matheus Izvekov
6afe56732a
[clang] Finish implementation of P0522 (#96023)
This finishes the clang implementation of P0522, getting rid of the
fallback to the old, pre-P0522 rules.

Before this patch, when partial ordering template template parameters,
we would perform, in order:
* If the old rules would match, we would accept it. Otherwise, don't
generate diagnostics yet.
* If the new rules would match, just accept it. Otherwise, don't
generate any diagnostics yet again.
* Apply the old rules again, this time with diagnostics.

This situation was far from ideal, as we would sometimes:
* Accept some things we shouldn't.
* Reject some things we shouldn't.
* Only diagnose rejection in terms of the old rules.

With this patch, we apply the P0522 rules throughout.

This needed to extend template argument deduction in order to accept the
historial rule for TTP matching pack parameter to non-pack arguments.
This change also makes us accept some combinations of historical and
P0522 allowances we wouldn't before.

It also fixes a bunch of bugs that were documented in the test suite,
which I am not sure there are issues already created for them.

This causes a lot of changes to the way these failures are diagnosed,
with related test suite churn.

The problem here is that the old rules were very simple and
non-recursive, making it easy to provide customized diagnostics, and to
keep them consistent with each other.

The new rules are a lot more complex and rely on template argument
deduction, substitutions, and they are recursive.

The approach taken here is to mostly rely on existing diagnostics, and
create a new instantiation context that keeps track of things.

So for example when a substitution failure occurs, we use the error
produced there unmodified, and just attach notes to it explaining that
it occurred in the context of partial ordering this template argument
against that template parameter.

This diverges from the old diagnostics, which would lead with an error
pointing to the template argument, explain the problem in subsequent
notes, and produce a final note pointing to the parameter.
2024-10-01 20:50:26 -03:00