[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-07 Thread Matheus Izvekov via cfe-commits


@@ -261,6 +261,13 @@ AG ag = {1};
 // CHECK:   | `-BuiltinType {{.*}} 'int'
 // CHECK:   `-ParmVarDecl {{.*}} 'int'
 
+template 
+using BG = G;
+BG bg(1.0);
+// CHECK-LABEL: Dumping 
+// CHECK:  FunctionTemplateDecl {{.*}} implicit 
+// CHECK: |-CXXDeductionGuideDecl {{.*}} 'auto (int) -> G' aggregate

mizvekov wrote:

But that it is a child of something is trivial, because all declarations are 
children of something, except a translation unit declaration.

But the fact that this line test that this thing is neither the first nor the 
last child of that thing, means that it is quite likely to break with unrelated 
test churn.

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-07 Thread Haojian Wu via cfe-commits

https://github.com/hokein closed https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-07 Thread Haojian Wu via cfe-commits


@@ -261,6 +261,13 @@ AG ag = {1};
 // CHECK:   | `-BuiltinType {{.*}} 'int'
 // CHECK:   `-ParmVarDecl {{.*}} 'int'
 
+template 
+using BG = G;
+BG bg(1.0);
+// CHECK-LABEL: Dumping 
+// CHECK:  FunctionTemplateDecl {{.*}} implicit 
+// CHECK: |-CXXDeductionGuideDecl {{.*}} 'auto (int) -> G' aggregate

hokein wrote:

> The line is a CHECK, not a CHECK-NEXT, so it could appear any number of lines 
> afterwards.

Yeah, ideally it should be `CHECK-NEXT`, but we can't use it because of the 
ambiguity in the content of the above line (there are two other deduction 
guides emitting the same content), so I end up using the `CHECK: |-...`, it at 
least demonstrates that it is a child of something.

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-07 Thread Matheus Izvekov via cfe-commits


@@ -261,6 +261,13 @@ AG ag = {1};
 // CHECK:   | `-BuiltinType {{.*}} 'int'
 // CHECK:   `-ParmVarDecl {{.*}} 'int'
 
+template 
+using BG = G;
+BG bg(1.0);
+// CHECK-LABEL: Dumping 
+// CHECK:  FunctionTemplateDecl {{.*}} implicit 
+// CHECK: |-CXXDeductionGuideDecl {{.*}} 'auto (int) -> G' aggregate

mizvekov wrote:

The line is a CHECK, not a CHECK-NEXT, so it could appear any number of lines 
afterwards.
So this means it could be a child of something else that appears after it.

The CHECK matcher matches any number of characters before the first character 
specified,
So it would match something like `| | |-CXXDeductionGuideDecl {{.*}} 'auto 
(int) -> G' aggregate`
Ie, it could be deeply nested into something else.

Instead, I think it just demonstrates:
* It is a child of something.
* It's neither the first nor the last child of that thing.

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-07 Thread Haojian Wu via cfe-commits


@@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema , 
TypeAliasTemplateDecl *AliasTemplate) {
   return {Template, AliasRhsTemplateArgs};
 }
 
-// Build deduction guides for a type alias template.
+// Build deduction guides for a type alias template from the given underlying
+// deduction guide F.
+FunctionTemplateDecl *
+BuildDeductionGuideForTypeAlias(Sema ,
+TypeAliasTemplateDecl *AliasTemplate,
+FunctionTemplateDecl *F, SourceLocation Loc) {
+  LocalInstantiationScope Scope(SemaRef);
+  Sema::InstantiatingTemplate BuildingDeductionGuides(
+  SemaRef, AliasTemplate->getLocation(), F,
+  Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
+  if (BuildingDeductionGuides.isInvalid())
+return nullptr;
+
+  auto  = SemaRef.Context;
+  auto [Template, AliasRhsTemplateArgs] =
+  getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
+
+  auto RType = F->getTemplatedDecl()->getReturnType();
+  // The (trailing) return type of the deduction guide.
+  const TemplateSpecializationType *FReturnType =
+  RType->getAs();
+  if (const auto *InjectedCNT = RType->getAs())
+// implicitly-generated deduction guide.
+FReturnType = InjectedCNT->getInjectedTST();
+  else if (const auto *ET = RType->getAs())
+// explicit deduction guide.
+FReturnType = ET->getNamedType()->getAs();
+  assert(FReturnType && "expected to see a return type");
+  // Deduce template arguments of the deduction guide f from the RHS of
+  // the alias.
+  //
+  // C++ [over.match.class.deduct]p3: ...For each function or function
+  // template f in the guides of the template named by the
+  // simple-template-id of the defining-type-id, the template arguments
+  // of the return type of f are deduced from the defining-type-id of A
+  // according to the process in [temp.deduct.type] with the exception
+  // that deduction does not fail if not all template arguments are
+  // deduced.
+  //
+  //
+  //  template
+  //  f(X, Y) -> f;
+  //
+  //  template
+  //  using alias = f;
+  //
+  // The RHS of alias is f, we deduced the template arguments of
+  // the return type of the deduction guide from it: Y->int, X->U
+  sema::TemplateDeductionInfo TDeduceInfo(Loc);
+  // Must initialize n elements, this is required by DeduceTemplateArguments.
+  SmallVector DeduceResults(
+  F->getTemplateParameters()->size());
+
+  // FIXME: DeduceTemplateArguments stops immediately at the first
+  // non-deducible template argument. However, this doesn't seem to casue
+  // issues for practice cases, we probably need to extend it to continue
+  // performing deduction for rest of arguments to align with the C++
+  // standard.
+  SemaRef.DeduceTemplateArguments(
+  F->getTemplateParameters(), FReturnType->template_arguments(),
+  AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
+  /*NumberOfArgumentsMustMatch=*/false);
+
+  SmallVector DeducedArgs;
+  SmallVector NonDeducedTemplateParamsInFIndex;
+  // !!NOTE: DeduceResults respects the sequence of template parameters of
+  // the deduction guide f.
+  for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
+if (const auto  = DeduceResults[Index]; !D.isNull()) // Deduced
+  DeducedArgs.push_back(D);
+else
+  NonDeducedTemplateParamsInFIndex.push_back(Index);
+  }
+  auto DeducedAliasTemplateParams =
+  TemplateParamsReferencedInTemplateArgumentList(
+  AliasTemplate->getTemplateParameters()->asArray(), DeducedArgs);
+  // All template arguments null by default.
+  SmallVector TemplateArgsForBuildingFPrime(
+  F->getTemplateParameters()->size());
+
+  // Create a template parameter list for the synthesized deduction guide f'.
+  //
+  // C++ [over.match.class.deduct]p3.2:
+  //   If f is a function template, f' is a function template whose template
+  //   parameter list consists of all the template parameters of A
+  //   (including their default template arguments) that appear in the above
+  //   deductions or (recursively) in their default template arguments
+  SmallVector FPrimeTemplateParams;
+  // Store template arguments that refer to the newly-created template
+  // parameters, used for building `TemplateArgsForBuildingFPrime`.
+  SmallVector TransformedDeducedAliasArgs(
+  AliasTemplate->getTemplateParameters()->size());
+
+  for (unsigned AliasTemplateParamIdx : DeducedAliasTemplateParams) {
+auto *TP =
+
AliasTemplate->getTemplateParameters()->getParam(AliasTemplateParamIdx);
+// Rebuild any internal references to earlier parameters and reindex as
+// we go.
+MultiLevelTemplateArgumentList Args;
+Args.setKind(TemplateSubstitutionKind::Rewrite);
+Args.addOuterTemplateArguments(TransformedDeducedAliasArgs);
+NamedDecl *NewParam = transformTemplateParameter(
+SemaRef, AliasTemplate->getDeclContext(), TP, Args,
+/*NewIndex=*/FPrimeTemplateParams.size());
+

[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-07 Thread Haojian Wu via cfe-commits


@@ -261,6 +261,13 @@ AG ag = {1};
 // CHECK:   | `-BuiltinType {{.*}} 'int'
 // CHECK:   `-ParmVarDecl {{.*}} 'int'
 
+template 
+using BG = G;
+BG bg(1.0);
+// CHECK-LABEL: Dumping 
+// CHECK:  FunctionTemplateDecl {{.*}} implicit 
+// CHECK: |-CXXDeductionGuideDecl {{.*}} 'auto (int) -> G' aggregate

hokein wrote:

While the test is not matching the AST structure, I think it is better and 
clearer to keep it, as it explicitly demonstrates the child relationship with 
the above line (`FunctionTemplateDecl`).

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-07 Thread Haojian Wu via cfe-commits

https://github.com/hokein updated 
https://github.com/llvm/llvm-project/pull/90894

>From 40365147f7aabeaaefd7e9bf6f2b96d6f7135992 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 3 May 2024 10:53:54 +0200
Subject: [PATCH 1/3] Refactor: Extract the core deduction-guide construction
 implementation from DeclareImplicitDeductionGuidesForTypeAlias

We move the core implementation to a dedicate function, so that it can
be reused in other places.
---
 clang/lib/Sema/SemaTemplate.cpp | 390 +---
 1 file changed, 203 insertions(+), 187 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 989f3995ca59913..b43c65874b04e5b 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema , 
TypeAliasTemplateDecl *AliasTemplate) {
   return {Template, AliasRhsTemplateArgs};
 }
 
-// Build deduction guides for a type alias template.
+// Build deduction guides for a type alias template from the given underlying
+// deduction guide F.
+FunctionTemplateDecl *
+BuildDeductionGuideForTypeAlias(Sema ,
+TypeAliasTemplateDecl *AliasTemplate,
+FunctionTemplateDecl *F, SourceLocation Loc) {
+  LocalInstantiationScope Scope(SemaRef);
+  Sema::InstantiatingTemplate BuildingDeductionGuides(
+  SemaRef, AliasTemplate->getLocation(), F,
+  Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
+  if (BuildingDeductionGuides.isInvalid())
+return nullptr;
+
+  auto  = SemaRef.Context;
+  auto [Template, AliasRhsTemplateArgs] =
+  getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
+
+  auto RType = F->getTemplatedDecl()->getReturnType();
+  // The (trailing) return type of the deduction guide.
+  const TemplateSpecializationType *FReturnType =
+  RType->getAs();
+  if (const auto *InjectedCNT = RType->getAs())
+// implicitly-generated deduction guide.
+FReturnType = InjectedCNT->getInjectedTST();
+  else if (const auto *ET = RType->getAs())
+// explicit deduction guide.
+FReturnType = ET->getNamedType()->getAs();
+  assert(FReturnType && "expected to see a return type");
+  // Deduce template arguments of the deduction guide f from the RHS of
+  // the alias.
+  //
+  // C++ [over.match.class.deduct]p3: ...For each function or function
+  // template f in the guides of the template named by the
+  // simple-template-id of the defining-type-id, the template arguments
+  // of the return type of f are deduced from the defining-type-id of A
+  // according to the process in [temp.deduct.type] with the exception
+  // that deduction does not fail if not all template arguments are
+  // deduced.
+  //
+  //
+  //  template
+  //  f(X, Y) -> f;
+  //
+  //  template
+  //  using alias = f;
+  //
+  // The RHS of alias is f, we deduced the template arguments of
+  // the return type of the deduction guide from it: Y->int, X->U
+  sema::TemplateDeductionInfo TDeduceInfo(Loc);
+  // Must initialize n elements, this is required by DeduceTemplateArguments.
+  SmallVector DeduceResults(
+  F->getTemplateParameters()->size());
+
+  // FIXME: DeduceTemplateArguments stops immediately at the first
+  // non-deducible template argument. However, this doesn't seem to casue
+  // issues for practice cases, we probably need to extend it to continue
+  // performing deduction for rest of arguments to align with the C++
+  // standard.
+  SemaRef.DeduceTemplateArguments(
+  F->getTemplateParameters(), FReturnType->template_arguments(),
+  AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
+  /*NumberOfArgumentsMustMatch=*/false);
+
+  SmallVector DeducedArgs;
+  SmallVector NonDeducedTemplateParamsInFIndex;
+  // !!NOTE: DeduceResults respects the sequence of template parameters of
+  // the deduction guide f.
+  for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
+if (const auto  = DeduceResults[Index]; !D.isNull()) // Deduced
+  DeducedArgs.push_back(D);
+else
+  NonDeducedTemplateParamsInFIndex.push_back(Index);
+  }
+  auto DeducedAliasTemplateParams =
+  TemplateParamsReferencedInTemplateArgumentList(
+  AliasTemplate->getTemplateParameters()->asArray(), DeducedArgs);
+  // All template arguments null by default.
+  SmallVector TemplateArgsForBuildingFPrime(
+  F->getTemplateParameters()->size());
+
+  // Create a template parameter list for the synthesized deduction guide f'.
+  //
+  // C++ [over.match.class.deduct]p3.2:
+  //   If f is a function template, f' is a function template whose template
+  //   parameter list consists of all the template parameters of A
+  //   (including their default template arguments) that appear in the above
+  //   deductions or (recursively) in their default template arguments
+  SmallVector FPrimeTemplateParams;
+  // Store template arguments that refer to the newly-created template
+  // parameters, 

[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-03 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-03 Thread Krystian Stasiowski via cfe-commits


@@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema , 
TypeAliasTemplateDecl *AliasTemplate) {
   return {Template, AliasRhsTemplateArgs};
 }
 
-// Build deduction guides for a type alias template.
+// Build deduction guides for a type alias template from the given underlying
+// deduction guide F.
+FunctionTemplateDecl *
+BuildDeductionGuideForTypeAlias(Sema ,
+TypeAliasTemplateDecl *AliasTemplate,
+FunctionTemplateDecl *F, SourceLocation Loc) {
+  LocalInstantiationScope Scope(SemaRef);
+  Sema::InstantiatingTemplate BuildingDeductionGuides(
+  SemaRef, AliasTemplate->getLocation(), F,
+  Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
+  if (BuildingDeductionGuides.isInvalid())
+return nullptr;
+
+  auto  = SemaRef.Context;
+  auto [Template, AliasRhsTemplateArgs] =
+  getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
+
+  auto RType = F->getTemplatedDecl()->getReturnType();
+  // The (trailing) return type of the deduction guide.
+  const TemplateSpecializationType *FReturnType =
+  RType->getAs();
+  if (const auto *InjectedCNT = RType->getAs())
+// implicitly-generated deduction guide.
+FReturnType = InjectedCNT->getInjectedTST();
+  else if (const auto *ET = RType->getAs())
+// explicit deduction guide.
+FReturnType = ET->getNamedType()->getAs();
+  assert(FReturnType && "expected to see a return type");
+  // Deduce template arguments of the deduction guide f from the RHS of
+  // the alias.
+  //
+  // C++ [over.match.class.deduct]p3: ...For each function or function
+  // template f in the guides of the template named by the
+  // simple-template-id of the defining-type-id, the template arguments
+  // of the return type of f are deduced from the defining-type-id of A
+  // according to the process in [temp.deduct.type] with the exception
+  // that deduction does not fail if not all template arguments are
+  // deduced.
+  //
+  //
+  //  template
+  //  f(X, Y) -> f;
+  //
+  //  template
+  //  using alias = f;
+  //
+  // The RHS of alias is f, we deduced the template arguments of
+  // the return type of the deduction guide from it: Y->int, X->U
+  sema::TemplateDeductionInfo TDeduceInfo(Loc);
+  // Must initialize n elements, this is required by DeduceTemplateArguments.
+  SmallVector DeduceResults(
+  F->getTemplateParameters()->size());
+
+  // FIXME: DeduceTemplateArguments stops immediately at the first
+  // non-deducible template argument. However, this doesn't seem to casue
+  // issues for practice cases, we probably need to extend it to continue
+  // performing deduction for rest of arguments to align with the C++
+  // standard.
+  SemaRef.DeduceTemplateArguments(
+  F->getTemplateParameters(), FReturnType->template_arguments(),
+  AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
+  /*NumberOfArgumentsMustMatch=*/false);
+
+  SmallVector DeducedArgs;
+  SmallVector NonDeducedTemplateParamsInFIndex;
+  // !!NOTE: DeduceResults respects the sequence of template parameters of
+  // the deduction guide f.
+  for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
+if (const auto  = DeduceResults[Index]; !D.isNull()) // Deduced
+  DeducedArgs.push_back(D);
+else
+  NonDeducedTemplateParamsInFIndex.push_back(Index);
+  }
+  auto DeducedAliasTemplateParams =
+  TemplateParamsReferencedInTemplateArgumentList(
+  AliasTemplate->getTemplateParameters()->asArray(), DeducedArgs);
+  // All template arguments null by default.
+  SmallVector TemplateArgsForBuildingFPrime(
+  F->getTemplateParameters()->size());
+
+  // Create a template parameter list for the synthesized deduction guide f'.
+  //
+  // C++ [over.match.class.deduct]p3.2:
+  //   If f is a function template, f' is a function template whose template
+  //   parameter list consists of all the template parameters of A
+  //   (including their default template arguments) that appear in the above
+  //   deductions or (recursively) in their default template arguments
+  SmallVector FPrimeTemplateParams;
+  // Store template arguments that refer to the newly-created template
+  // parameters, used for building `TemplateArgsForBuildingFPrime`.
+  SmallVector TransformedDeducedAliasArgs(
+  AliasTemplate->getTemplateParameters()->size());
+
+  for (unsigned AliasTemplateParamIdx : DeducedAliasTemplateParams) {
+auto *TP =
+
AliasTemplate->getTemplateParameters()->getParam(AliasTemplateParamIdx);
+// Rebuild any internal references to earlier parameters and reindex as
+// we go.
+MultiLevelTemplateArgumentList Args;
+Args.setKind(TemplateSubstitutionKind::Rewrite);
+Args.addOuterTemplateArguments(TransformedDeducedAliasArgs);
+NamedDecl *NewParam = transformTemplateParameter(
+SemaRef, AliasTemplate->getDeclContext(), TP, Args,
+/*NewIndex=*/FPrimeTemplateParams.size());
+

[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-03 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian edited 
https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-03 Thread Matheus Izvekov via cfe-commits

https://github.com/mizvekov approved this pull request.

This looks like a straightforward fix to me as well

LGTM

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-03 Thread Matheus Izvekov via cfe-commits


@@ -261,6 +261,13 @@ AG ag = {1};
 // CHECK:   | `-BuiltinType {{.*}} 'int'
 // CHECK:   `-ParmVarDecl {{.*}} 'int'
 
+template 
+using BG = G;
+BG bg(1.0);
+// CHECK-LABEL: Dumping 
+// CHECK:  FunctionTemplateDecl {{.*}} implicit 
+// CHECK: |-CXXDeductionGuideDecl {{.*}} 'auto (int) -> G' aggregate

mizvekov wrote:

Nit: Since this isn't matching the structure of the AST anyway, it would 
probably be a good idea to avoid the possibility of unrelated test churn.

```suggestion
// CHECK: CXXDeductionGuideDecl {{.*}} 'auto (int) -> G' aggregate
```

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-03 Thread Matheus Izvekov via cfe-commits

https://github.com/mizvekov edited 
https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-03 Thread Haojian Wu via cfe-commits


@@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema , 
TypeAliasTemplateDecl *AliasTemplate) {
   return {Template, AliasRhsTemplateArgs};
 }
 
-// Build deduction guides for a type alias template.
+// Build deduction guides for a type alias template from the given underlying
+// deduction guide F.
+FunctionTemplateDecl *
+BuildDeductionGuideForTypeAlias(Sema ,

hokein wrote:

> to clarify, in the actual fix you removed a whole bunch of code?
https://github.com/llvm/llvm-project/commit/621899224aa7d59ab70675f6ff32b298b06a515a

Yes, that's correct. The removed code is an incorrect implementation which will 
generate wrong deduction guides.

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-03 Thread Erich Keane via cfe-commits

https://github.com/erichkeane approved this pull request.

I think I'm ok with this, please give others a day or two to sign off as well.

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-03 Thread via cfe-commits


@@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema , 
TypeAliasTemplateDecl *AliasTemplate) {
   return {Template, AliasRhsTemplateArgs};
 }
 
-// Build deduction guides for a type alias template.
+// Build deduction guides for a type alias template from the given underlying
+// deduction guide F.
+FunctionTemplateDecl *
+BuildDeductionGuideForTypeAlias(Sema ,

cor3ntin wrote:

to clarify, in the actual fix you removed a whole bunch of code?
https://github.com/llvm/llvm-project/pull/90894/commits/621899224aa7d59ab70675f6ff32b298b06a515a

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-03 Thread Haojian Wu via cfe-commits


@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++2a -verify -ast-dump -ast-dump-decl-types 
-ast-dump-filter "deduction guide" %s | FileCheck %s --strict-whitespace
+// RUN: %clang_cc1 -std=c++2a -verify -ast-dump -ast-dump-decl-types 
-Wno-c++11-narrowing -ast-dump-filter "deduction guide" %s | FileCheck %s 
--strict-whitespace

hokein wrote:

Oh, yeah, this was to suppress the narrowing double=>int conversion warning on 
`BG bg = {1.0};`. I have changed the way to init the `bg` to get rid of this 
warning.

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-03 Thread Haojian Wu via cfe-commits


@@ -261,6 +261,13 @@ AG ag = {1};
 // CHECK:   | `-BuiltinType {{.*}} 'int'
 // CHECK:   `-ParmVarDecl {{.*}} 'int'
 
+template 
+using BG = G;
+BG bg = {1.0};
+// CHECK-LABEL: Dumping 
+// CHECK: FunctionTemplateDecl

hokein wrote:

It is not possible to use the `CHECK-NEXT` here, as there are 3 deduction 
guides for BG, and each deduction guide has the same print content (which is 
`FunctionTemplateDecl 0x556b96b9da60 
llvm-project/clang/test/SemaTemplate/deduction-guide.cpp:264:1, line:265:17> 
col:1 implicit `)

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-03 Thread Haojian Wu via cfe-commits


@@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema , 
TypeAliasTemplateDecl *AliasTemplate) {
   return {Template, AliasRhsTemplateArgs};
 }
 
-// Build deduction guides for a type alias template.
+// Build deduction guides for a type alias template from the given underlying
+// deduction guide F.
+FunctionTemplateDecl *
+BuildDeductionGuideForTypeAlias(Sema ,

hokein wrote:

I have restructured commits in this PR. It contains two commits: one for the 
NFC refactoring change, the other one is for the actual fix. I hope it would 
make the review easier.

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-03 Thread Haojian Wu via cfe-commits


@@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema , 
TypeAliasTemplateDecl *AliasTemplate) {
   return {Template, AliasRhsTemplateArgs};
 }
 
-// Build deduction guides for a type alias template.
+// Build deduction guides for a type alias template from the given underlying
+// deduction guide F.
+FunctionTemplateDecl *
+BuildDeductionGuideForTypeAlias(Sema ,
+TypeAliasTemplateDecl *AliasTemplate,
+FunctionTemplateDecl *F, SourceLocation Loc) {
+  LocalInstantiationScope Scope(SemaRef);
+  Sema::InstantiatingTemplate BuildingDeductionGuides(
+  SemaRef, AliasTemplate->getLocation(), F,
+  Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
+  if (BuildingDeductionGuides.isInvalid())
+return nullptr;
+
+  auto  = SemaRef.Context;
+  auto [Template, AliasRhsTemplateArgs] =
+  getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
+
+  auto RType = F->getTemplatedDecl()->getReturnType();
+  // The (trailing) return type of the deduction guide.
+  const TemplateSpecializationType *FReturnType =
+  RType->getAs();
+  if (const auto *InjectedCNT = RType->getAs())
+// implicitly-generated deduction guide.
+FReturnType = InjectedCNT->getInjectedTST();
+  else if (const auto *ET = RType->getAs())
+// explicit deduction guide.
+FReturnType = ET->getNamedType()->getAs();
+  assert(FReturnType && "expected to see a return type");
+  // Deduce template arguments of the deduction guide f from the RHS of
+  // the alias.
+  //
+  // C++ [over.match.class.deduct]p3: ...For each function or function
+  // template f in the guides of the template named by the
+  // simple-template-id of the defining-type-id, the template arguments
+  // of the return type of f are deduced from the defining-type-id of A
+  // according to the process in [temp.deduct.type] with the exception
+  // that deduction does not fail if not all template arguments are
+  // deduced.
+  //
+  //
+  //  template
+  //  f(X, Y) -> f;
+  //
+  //  template
+  //  using alias = f;
+  //
+  // The RHS of alias is f, we deduced the template arguments of
+  // the return type of the deduction guide from it: Y->int, X->U
+  sema::TemplateDeductionInfo TDeduceInfo(Loc);
+  // Must initialize n elements, this is required by DeduceTemplateArguments.
+  SmallVector DeduceResults(
+  F->getTemplateParameters()->size());
+
+  // FIXME: DeduceTemplateArguments stops immediately at the first
+  // non-deducible template argument. However, this doesn't seem to casue
+  // issues for practice cases, we probably need to extend it to continue
+  // performing deduction for rest of arguments to align with the C++
+  // standard.
+  SemaRef.DeduceTemplateArguments(
+  F->getTemplateParameters(), FReturnType->template_arguments(),
+  AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
+  /*NumberOfArgumentsMustMatch=*/false);
+
+  SmallVector DeducedArgs;
+  SmallVector NonDeducedTemplateParamsInFIndex;
+  // !!NOTE: DeduceResults respects the sequence of template parameters of
+  // the deduction guide f.
+  for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
+if (const auto  = DeduceResults[Index]; !D.isNull()) // Deduced
+  DeducedArgs.push_back(D);
+else
+  NonDeducedTemplateParamsInFIndex.push_back(Index);
+  }
+  auto DeducedAliasTemplateParams =
+  TemplateParamsReferencedInTemplateArgumentList(
+  AliasTemplate->getTemplateParameters()->asArray(), DeducedArgs);
+  // All template arguments null by default.
+  SmallVector TemplateArgsForBuildingFPrime(
+  F->getTemplateParameters()->size());
+
+  // Create a template parameter list for the synthesized deduction guide f'.
+  //
+  // C++ [over.match.class.deduct]p3.2:
+  //   If f is a function template, f' is a function template whose template
+  //   parameter list consists of all the template parameters of A
+  //   (including their default template arguments) that appear in the above
+  //   deductions or (recursively) in their default template arguments
+  SmallVector FPrimeTemplateParams;
+  // Store template arguments that refer to the newly-created template
+  // parameters, used for building `TemplateArgsForBuildingFPrime`.
+  SmallVector TransformedDeducedAliasArgs(
+  AliasTemplate->getTemplateParameters()->size());
+
+  for (unsigned AliasTemplateParamIdx : DeducedAliasTemplateParams) {
+auto *TP =
+
AliasTemplate->getTemplateParameters()->getParam(AliasTemplateParamIdx);
+// Rebuild any internal references to earlier parameters and reindex as
+// we go.
+MultiLevelTemplateArgumentList Args;
+Args.setKind(TemplateSubstitutionKind::Rewrite);
+Args.addOuterTemplateArguments(TransformedDeducedAliasArgs);
+NamedDecl *NewParam = transformTemplateParameter(
+SemaRef, AliasTemplate->getDeclContext(), TP, Args,
+/*NewIndex*/ FPrimeTemplateParams.size());


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-03 Thread Haojian Wu via cfe-commits

https://github.com/hokein updated 
https://github.com/llvm/llvm-project/pull/90894

>From 40365147f7aabeaaefd7e9bf6f2b96d6f7135992 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 3 May 2024 10:53:54 +0200
Subject: [PATCH 1/2] Refactor: Extract the core deduction-guide construction
 implementation from DeclareImplicitDeductionGuidesForTypeAlias

We move the core implementation to a dedicate function, so that it can
be reused in other places.
---
 clang/lib/Sema/SemaTemplate.cpp | 390 +---
 1 file changed, 203 insertions(+), 187 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 989f3995ca5991..b43c65874b04e5 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema , 
TypeAliasTemplateDecl *AliasTemplate) {
   return {Template, AliasRhsTemplateArgs};
 }
 
-// Build deduction guides for a type alias template.
+// Build deduction guides for a type alias template from the given underlying
+// deduction guide F.
+FunctionTemplateDecl *
+BuildDeductionGuideForTypeAlias(Sema ,
+TypeAliasTemplateDecl *AliasTemplate,
+FunctionTemplateDecl *F, SourceLocation Loc) {
+  LocalInstantiationScope Scope(SemaRef);
+  Sema::InstantiatingTemplate BuildingDeductionGuides(
+  SemaRef, AliasTemplate->getLocation(), F,
+  Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
+  if (BuildingDeductionGuides.isInvalid())
+return nullptr;
+
+  auto  = SemaRef.Context;
+  auto [Template, AliasRhsTemplateArgs] =
+  getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
+
+  auto RType = F->getTemplatedDecl()->getReturnType();
+  // The (trailing) return type of the deduction guide.
+  const TemplateSpecializationType *FReturnType =
+  RType->getAs();
+  if (const auto *InjectedCNT = RType->getAs())
+// implicitly-generated deduction guide.
+FReturnType = InjectedCNT->getInjectedTST();
+  else if (const auto *ET = RType->getAs())
+// explicit deduction guide.
+FReturnType = ET->getNamedType()->getAs();
+  assert(FReturnType && "expected to see a return type");
+  // Deduce template arguments of the deduction guide f from the RHS of
+  // the alias.
+  //
+  // C++ [over.match.class.deduct]p3: ...For each function or function
+  // template f in the guides of the template named by the
+  // simple-template-id of the defining-type-id, the template arguments
+  // of the return type of f are deduced from the defining-type-id of A
+  // according to the process in [temp.deduct.type] with the exception
+  // that deduction does not fail if not all template arguments are
+  // deduced.
+  //
+  //
+  //  template
+  //  f(X, Y) -> f;
+  //
+  //  template
+  //  using alias = f;
+  //
+  // The RHS of alias is f, we deduced the template arguments of
+  // the return type of the deduction guide from it: Y->int, X->U
+  sema::TemplateDeductionInfo TDeduceInfo(Loc);
+  // Must initialize n elements, this is required by DeduceTemplateArguments.
+  SmallVector DeduceResults(
+  F->getTemplateParameters()->size());
+
+  // FIXME: DeduceTemplateArguments stops immediately at the first
+  // non-deducible template argument. However, this doesn't seem to casue
+  // issues for practice cases, we probably need to extend it to continue
+  // performing deduction for rest of arguments to align with the C++
+  // standard.
+  SemaRef.DeduceTemplateArguments(
+  F->getTemplateParameters(), FReturnType->template_arguments(),
+  AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
+  /*NumberOfArgumentsMustMatch=*/false);
+
+  SmallVector DeducedArgs;
+  SmallVector NonDeducedTemplateParamsInFIndex;
+  // !!NOTE: DeduceResults respects the sequence of template parameters of
+  // the deduction guide f.
+  for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
+if (const auto  = DeduceResults[Index]; !D.isNull()) // Deduced
+  DeducedArgs.push_back(D);
+else
+  NonDeducedTemplateParamsInFIndex.push_back(Index);
+  }
+  auto DeducedAliasTemplateParams =
+  TemplateParamsReferencedInTemplateArgumentList(
+  AliasTemplate->getTemplateParameters()->asArray(), DeducedArgs);
+  // All template arguments null by default.
+  SmallVector TemplateArgsForBuildingFPrime(
+  F->getTemplateParameters()->size());
+
+  // Create a template parameter list for the synthesized deduction guide f'.
+  //
+  // C++ [over.match.class.deduct]p3.2:
+  //   If f is a function template, f' is a function template whose template
+  //   parameter list consists of all the template parameters of A
+  //   (including their default template arguments) that appear in the above
+  //   deductions or (recursively) in their default template arguments
+  SmallVector FPrimeTemplateParams;
+  // Store template arguments that refer to the newly-created template
+  // parameters, 

[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-02 Thread Shafik Yaghmour via cfe-commits


@@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema , 
TypeAliasTemplateDecl *AliasTemplate) {
   return {Template, AliasRhsTemplateArgs};
 }
 
-// Build deduction guides for a type alias template.
+// Build deduction guides for a type alias template from the given underlying
+// deduction guide F.
+FunctionTemplateDecl *
+BuildDeductionGuideForTypeAlias(Sema ,
+TypeAliasTemplateDecl *AliasTemplate,
+FunctionTemplateDecl *F, SourceLocation Loc) {
+  LocalInstantiationScope Scope(SemaRef);
+  Sema::InstantiatingTemplate BuildingDeductionGuides(
+  SemaRef, AliasTemplate->getLocation(), F,
+  Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
+  if (BuildingDeductionGuides.isInvalid())
+return nullptr;
+
+  auto  = SemaRef.Context;
+  auto [Template, AliasRhsTemplateArgs] =
+  getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
+
+  auto RType = F->getTemplatedDecl()->getReturnType();
+  // The (trailing) return type of the deduction guide.
+  const TemplateSpecializationType *FReturnType =
+  RType->getAs();
+  if (const auto *InjectedCNT = RType->getAs())
+// implicitly-generated deduction guide.
+FReturnType = InjectedCNT->getInjectedTST();
+  else if (const auto *ET = RType->getAs())
+// explicit deduction guide.
+FReturnType = ET->getNamedType()->getAs();
+  assert(FReturnType && "expected to see a return type");
+  // Deduce template arguments of the deduction guide f from the RHS of
+  // the alias.
+  //
+  // C++ [over.match.class.deduct]p3: ...For each function or function
+  // template f in the guides of the template named by the
+  // simple-template-id of the defining-type-id, the template arguments
+  // of the return type of f are deduced from the defining-type-id of A
+  // according to the process in [temp.deduct.type] with the exception
+  // that deduction does not fail if not all template arguments are
+  // deduced.
+  //
+  //
+  //  template
+  //  f(X, Y) -> f;
+  //
+  //  template
+  //  using alias = f;
+  //
+  // The RHS of alias is f, we deduced the template arguments of
+  // the return type of the deduction guide from it: Y->int, X->U
+  sema::TemplateDeductionInfo TDeduceInfo(Loc);
+  // Must initialize n elements, this is required by DeduceTemplateArguments.
+  SmallVector DeduceResults(
+  F->getTemplateParameters()->size());
+
+  // FIXME: DeduceTemplateArguments stops immediately at the first
+  // non-deducible template argument. However, this doesn't seem to casue
+  // issues for practice cases, we probably need to extend it to continue
+  // performing deduction for rest of arguments to align with the C++
+  // standard.
+  SemaRef.DeduceTemplateArguments(
+  F->getTemplateParameters(), FReturnType->template_arguments(),
+  AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
+  /*NumberOfArgumentsMustMatch=*/false);
+
+  SmallVector DeducedArgs;
+  SmallVector NonDeducedTemplateParamsInFIndex;
+  // !!NOTE: DeduceResults respects the sequence of template parameters of
+  // the deduction guide f.
+  for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
+if (const auto  = DeduceResults[Index]; !D.isNull()) // Deduced
+  DeducedArgs.push_back(D);
+else
+  NonDeducedTemplateParamsInFIndex.push_back(Index);
+  }
+  auto DeducedAliasTemplateParams =
+  TemplateParamsReferencedInTemplateArgumentList(
+  AliasTemplate->getTemplateParameters()->asArray(), DeducedArgs);
+  // All template arguments null by default.
+  SmallVector TemplateArgsForBuildingFPrime(
+  F->getTemplateParameters()->size());
+
+  // Create a template parameter list for the synthesized deduction guide f'.
+  //
+  // C++ [over.match.class.deduct]p3.2:
+  //   If f is a function template, f' is a function template whose template
+  //   parameter list consists of all the template parameters of A
+  //   (including their default template arguments) that appear in the above
+  //   deductions or (recursively) in their default template arguments
+  SmallVector FPrimeTemplateParams;
+  // Store template arguments that refer to the newly-created template
+  // parameters, used for building `TemplateArgsForBuildingFPrime`.
+  SmallVector TransformedDeducedAliasArgs(
+  AliasTemplate->getTemplateParameters()->size());
+
+  for (unsigned AliasTemplateParamIdx : DeducedAliasTemplateParams) {
+auto *TP =
+
AliasTemplate->getTemplateParameters()->getParam(AliasTemplateParamIdx);
+// Rebuild any internal references to earlier parameters and reindex as
+// we go.
+MultiLevelTemplateArgumentList Args;
+Args.setKind(TemplateSubstitutionKind::Rewrite);
+Args.addOuterTemplateArguments(TransformedDeducedAliasArgs);
+NamedDecl *NewParam = transformTemplateParameter(
+SemaRef, AliasTemplate->getDeclContext(), TP, Args,
+/*NewIndex*/ FPrimeTemplateParams.size());


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-02 Thread Shafik Yaghmour via cfe-commits


@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++2a -verify -ast-dump -ast-dump-decl-types 
-ast-dump-filter "deduction guide" %s | FileCheck %s --strict-whitespace
+// RUN: %clang_cc1 -std=c++2a -verify -ast-dump -ast-dump-decl-types 
-Wno-c++11-narrowing -ast-dump-filter "deduction guide" %s | FileCheck %s 
--strict-whitespace

shafik wrote:

Is there a way to verify this fix w/o using a narrowing conversion?

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-02 Thread Haojian Wu via cfe-commits


@@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema , 
TypeAliasTemplateDecl *AliasTemplate) {
   return {Template, AliasRhsTemplateArgs};
 }
 
-// Build deduction guides for a type alias template.
+// Build deduction guides for a type alias template from the given underlying
+// deduction guide F.
+FunctionTemplateDecl *
+BuildDeductionGuideForTypeAlias(Sema ,

hokein wrote:

We just move the implementation from 
`DeclareImplicitDeductionGuidesForTypeAlias ` to a dedicated function, so that 
we can reuse it in the `DeclareAggregateDeductionGuideForTypeAlias`.

The functional change of this commit is in 
`DeclareAggregateDeductionGuideForTypeAlias`, the previous implementation is 
incorrect, and we should use the one in 
`DeclareImplicitDeductionGuidesForTypeAlias`.

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-02 Thread Krystian Stasiowski via cfe-commits


@@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema , 
TypeAliasTemplateDecl *AliasTemplate) {
   return {Template, AliasRhsTemplateArgs};
 }
 
-// Build deduction guides for a type alias template.
+// Build deduction guides for a type alias template from the given underlying
+// deduction guide F.
+FunctionTemplateDecl *
+BuildDeductionGuideForTypeAlias(Sema ,

sdkrystian wrote:

(if possible, please put the non-functional changes into their own commit for 
review purposes)

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-02 Thread via cfe-commits

cor3ntin wrote:

> Also needs release note.

that's a clang 19 feature fix afaict, so nope

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-02 Thread Erich Keane via cfe-commits

erichkeane wrote:

Also needs release note.

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-02 Thread Erich Keane via cfe-commits


@@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema , 
TypeAliasTemplateDecl *AliasTemplate) {
   return {Template, AliasRhsTemplateArgs};
 }
 
-// Build deduction guides for a type alias template.
+// Build deduction guides for a type alias template from the given underlying
+// deduction guide F.
+FunctionTemplateDecl *
+BuildDeductionGuideForTypeAlias(Sema ,

erichkeane wrote:

Best I can tell this is mostly a Copy/paste from the other two locations?  Can 
you point out for me what are the meaningful different changes?

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-02 Thread Erich Keane via cfe-commits


@@ -261,6 +261,13 @@ AG ag = {1};
 // CHECK:   | `-BuiltinType {{.*}} 'int'
 // CHECK:   `-ParmVarDecl {{.*}} 'int'
 
+template 
+using BG = G;
+BG bg = {1.0};
+// CHECK-LABEL: Dumping 
+// CHECK: FunctionTemplateDecl

erichkeane wrote:

Could these be `CHECK-NEXT` ? 

https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-02 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 2d4acb086541577ac6ab3a140b9ceb9659ce7094 
67b790e8a0e3f86155c2569373ced29ddd61c16b -- clang/lib/Sema/SemaTemplate.cpp 
clang/test/SemaCXX/cxx20-ctad-type-alias.cpp 
clang/test/SemaTemplate/deduction-guide.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index c3dbb0d58e..0d8459e499 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2979,7 +2979,7 @@ BuildDeductionGuideForTypeAlias(Sema ,
 auto *GG = cast(FPrime);
 
 Expr *RequiresClause =
-  transformRequireClause(SemaRef, F, TemplateArgsForBuildingFPrime);
+transformRequireClause(SemaRef, F, TemplateArgsForBuildingFPrime);
 
 // FIXME: implement the is_deducible constraint per C++
 // [over.match.class.deduct]p3.3:

``




https://github.com/llvm/llvm-project/pull/90894
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-02 Thread Haojian Wu via cfe-commits

https://github.com/hokein updated 
https://github.com/llvm/llvm-project/pull/90894

>From 67b790e8a0e3f86155c2569373ced29ddd61c16b Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Thu, 2 May 2024 21:06:15 +0200
Subject: [PATCH 1/2] [clang] CTAD: fix the aggregate deduction guide for alias
 templates.

For alias templates, the way we construct their aggregate deduction guides is
not following the standard way. We should do the same thing as we do for
implicit deduction guides.

This patch is mostly a refactoring change that pull the construct logic
out from `DeclareImplicitDeductionGuidesForTypeAlias` and reuse it for
building aggregate deduction guides.
---
 clang/lib/Sema/SemaTemplate.cpp  | 451 +--
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp |  14 +
 clang/test/SemaTemplate/deduction-guide.cpp  |   9 +-
 3 files changed, 227 insertions(+), 247 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 989f3995ca5991..c3dbb0d58e5bb5 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema , 
TypeAliasTemplateDecl *AliasTemplate) {
   return {Template, AliasRhsTemplateArgs};
 }
 
-// Build deduction guides for a type alias template.
+// Build deduction guides for a type alias template from the given underlying
+// deduction guide F.
+FunctionTemplateDecl *
+BuildDeductionGuideForTypeAlias(Sema ,
+TypeAliasTemplateDecl *AliasTemplate,
+FunctionTemplateDecl *F, SourceLocation Loc) {
+  LocalInstantiationScope Scope(SemaRef);
+  Sema::InstantiatingTemplate BuildingDeductionGuides(
+  SemaRef, AliasTemplate->getLocation(), F,
+  Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
+  if (BuildingDeductionGuides.isInvalid())
+return nullptr;
+
+  auto  = SemaRef.Context;
+  auto [Template, AliasRhsTemplateArgs] =
+  getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
+
+  auto RType = F->getTemplatedDecl()->getReturnType();
+  // The (trailing) return type of the deduction guide.
+  const TemplateSpecializationType *FReturnType =
+  RType->getAs();
+  if (const auto *InjectedCNT = RType->getAs())
+// implicitly-generated deduction guide.
+FReturnType = InjectedCNT->getInjectedTST();
+  else if (const auto *ET = RType->getAs())
+// explicit deduction guide.
+FReturnType = ET->getNamedType()->getAs();
+  assert(FReturnType && "expected to see a return type");
+  // Deduce template arguments of the deduction guide f from the RHS of
+  // the alias.
+  //
+  // C++ [over.match.class.deduct]p3: ...For each function or function
+  // template f in the guides of the template named by the
+  // simple-template-id of the defining-type-id, the template arguments
+  // of the return type of f are deduced from the defining-type-id of A
+  // according to the process in [temp.deduct.type] with the exception
+  // that deduction does not fail if not all template arguments are
+  // deduced.
+  //
+  //
+  //  template
+  //  f(X, Y) -> f;
+  //
+  //  template
+  //  using alias = f;
+  //
+  // The RHS of alias is f, we deduced the template arguments of
+  // the return type of the deduction guide from it: Y->int, X->U
+  sema::TemplateDeductionInfo TDeduceInfo(Loc);
+  // Must initialize n elements, this is required by DeduceTemplateArguments.
+  SmallVector DeduceResults(
+  F->getTemplateParameters()->size());
+
+  // FIXME: DeduceTemplateArguments stops immediately at the first
+  // non-deducible template argument. However, this doesn't seem to casue
+  // issues for practice cases, we probably need to extend it to continue
+  // performing deduction for rest of arguments to align with the C++
+  // standard.
+  SemaRef.DeduceTemplateArguments(
+  F->getTemplateParameters(), FReturnType->template_arguments(),
+  AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
+  /*NumberOfArgumentsMustMatch=*/false);
+
+  SmallVector DeducedArgs;
+  SmallVector NonDeducedTemplateParamsInFIndex;
+  // !!NOTE: DeduceResults respects the sequence of template parameters of
+  // the deduction guide f.
+  for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
+if (const auto  = DeduceResults[Index]; !D.isNull()) // Deduced
+  DeducedArgs.push_back(D);
+else
+  NonDeducedTemplateParamsInFIndex.push_back(Index);
+  }
+  auto DeducedAliasTemplateParams =
+  TemplateParamsReferencedInTemplateArgumentList(
+  AliasTemplate->getTemplateParameters()->asArray(), DeducedArgs);
+  // All template arguments null by default.
+  SmallVector TemplateArgsForBuildingFPrime(
+  F->getTemplateParameters()->size());
+
+  // Create a template parameter list for the synthesized deduction guide f'.
+  //
+  // C++ [over.match.class.deduct]p3.2:
+  //   If f is a function template, f' is a function template whose template
+  //   parameter list 

[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-02 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Haojian Wu (hokein)


Changes

For alias templates, our current way of constructing their aggregate deduction 
guides deviates from the standard approach. We should align it with how we 
handle implicit deduction guides.

This patch has a refactoring change which pulls the construction logic out from 
`DeclareImplicitDeductionGuidesForTypeAlia` and reusing it for building 
aggregate deduction guides.

---

Patch is 24.95 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/90894.diff


3 Files Affected:

- (modified) clang/lib/Sema/SemaTemplate.cpp (+205-246) 
- (modified) clang/test/SemaCXX/cxx20-ctad-type-alias.cpp (+14) 
- (modified) clang/test/SemaTemplate/deduction-guide.cpp (+8-1) 


``diff
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 989f3995ca5991..c3dbb0d58e5bb5 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema , 
TypeAliasTemplateDecl *AliasTemplate) {
   return {Template, AliasRhsTemplateArgs};
 }
 
-// Build deduction guides for a type alias template.
+// Build deduction guides for a type alias template from the given underlying
+// deduction guide F.
+FunctionTemplateDecl *
+BuildDeductionGuideForTypeAlias(Sema ,
+TypeAliasTemplateDecl *AliasTemplate,
+FunctionTemplateDecl *F, SourceLocation Loc) {
+  LocalInstantiationScope Scope(SemaRef);
+  Sema::InstantiatingTemplate BuildingDeductionGuides(
+  SemaRef, AliasTemplate->getLocation(), F,
+  Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
+  if (BuildingDeductionGuides.isInvalid())
+return nullptr;
+
+  auto  = SemaRef.Context;
+  auto [Template, AliasRhsTemplateArgs] =
+  getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
+
+  auto RType = F->getTemplatedDecl()->getReturnType();
+  // The (trailing) return type of the deduction guide.
+  const TemplateSpecializationType *FReturnType =
+  RType->getAs();
+  if (const auto *InjectedCNT = RType->getAs())
+// implicitly-generated deduction guide.
+FReturnType = InjectedCNT->getInjectedTST();
+  else if (const auto *ET = RType->getAs())
+// explicit deduction guide.
+FReturnType = ET->getNamedType()->getAs();
+  assert(FReturnType && "expected to see a return type");
+  // Deduce template arguments of the deduction guide f from the RHS of
+  // the alias.
+  //
+  // C++ [over.match.class.deduct]p3: ...For each function or function
+  // template f in the guides of the template named by the
+  // simple-template-id of the defining-type-id, the template arguments
+  // of the return type of f are deduced from the defining-type-id of A
+  // according to the process in [temp.deduct.type] with the exception
+  // that deduction does not fail if not all template arguments are
+  // deduced.
+  //
+  //
+  //  template
+  //  f(X, Y) -> f;
+  //
+  //  template
+  //  using alias = f;
+  //
+  // The RHS of alias is f, we deduced the template arguments of
+  // the return type of the deduction guide from it: Y->int, X->U
+  sema::TemplateDeductionInfo TDeduceInfo(Loc);
+  // Must initialize n elements, this is required by DeduceTemplateArguments.
+  SmallVector DeduceResults(
+  F->getTemplateParameters()->size());
+
+  // FIXME: DeduceTemplateArguments stops immediately at the first
+  // non-deducible template argument. However, this doesn't seem to casue
+  // issues for practice cases, we probably need to extend it to continue
+  // performing deduction for rest of arguments to align with the C++
+  // standard.
+  SemaRef.DeduceTemplateArguments(
+  F->getTemplateParameters(), FReturnType->template_arguments(),
+  AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
+  /*NumberOfArgumentsMustMatch=*/false);
+
+  SmallVector DeducedArgs;
+  SmallVector NonDeducedTemplateParamsInFIndex;
+  // !!NOTE: DeduceResults respects the sequence of template parameters of
+  // the deduction guide f.
+  for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
+if (const auto  = DeduceResults[Index]; !D.isNull()) // Deduced
+  DeducedArgs.push_back(D);
+else
+  NonDeducedTemplateParamsInFIndex.push_back(Index);
+  }
+  auto DeducedAliasTemplateParams =
+  TemplateParamsReferencedInTemplateArgumentList(
+  AliasTemplate->getTemplateParameters()->asArray(), DeducedArgs);
+  // All template arguments null by default.
+  SmallVector TemplateArgsForBuildingFPrime(
+  F->getTemplateParameters()->size());
+
+  // Create a template parameter list for the synthesized deduction guide f'.
+  //
+  // C++ [over.match.class.deduct]p3.2:
+  //   If f is a function template, f' is a function template whose template
+  //   parameter list consists of all the template parameters of A
+  //   (including their default template arguments) 

[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)

2024-05-02 Thread Haojian Wu via cfe-commits

https://github.com/hokein created 
https://github.com/llvm/llvm-project/pull/90894

For alias templates, our current way of constructing their aggregate deduction 
guides deviates from the standard approach. We should align it with how we 
handle implicit deduction guides.

This patch has a refactoring change which pulls the construction logic out from 
`DeclareImplicitDeductionGuidesForTypeAlia` and reusing it for building 
aggregate deduction guides.

>From 67b790e8a0e3f86155c2569373ced29ddd61c16b Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Thu, 2 May 2024 21:06:15 +0200
Subject: [PATCH] [clang] CTAD: fix the aggregate deduction guide for alias
 templates.

For alias templates, the way we construct their aggregate deduction guides is
not following the standard way. We should do the same thing as we do for
implicit deduction guides.

This patch is mostly a refactoring change that pull the construct logic
out from `DeclareImplicitDeductionGuidesForTypeAlias` and reuse it for
building aggregate deduction guides.
---
 clang/lib/Sema/SemaTemplate.cpp  | 451 +--
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp |  14 +
 clang/test/SemaTemplate/deduction-guide.cpp  |   9 +-
 3 files changed, 227 insertions(+), 247 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 989f3995ca5991..c3dbb0d58e5bb5 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema , 
TypeAliasTemplateDecl *AliasTemplate) {
   return {Template, AliasRhsTemplateArgs};
 }
 
-// Build deduction guides for a type alias template.
+// Build deduction guides for a type alias template from the given underlying
+// deduction guide F.
+FunctionTemplateDecl *
+BuildDeductionGuideForTypeAlias(Sema ,
+TypeAliasTemplateDecl *AliasTemplate,
+FunctionTemplateDecl *F, SourceLocation Loc) {
+  LocalInstantiationScope Scope(SemaRef);
+  Sema::InstantiatingTemplate BuildingDeductionGuides(
+  SemaRef, AliasTemplate->getLocation(), F,
+  Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
+  if (BuildingDeductionGuides.isInvalid())
+return nullptr;
+
+  auto  = SemaRef.Context;
+  auto [Template, AliasRhsTemplateArgs] =
+  getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
+
+  auto RType = F->getTemplatedDecl()->getReturnType();
+  // The (trailing) return type of the deduction guide.
+  const TemplateSpecializationType *FReturnType =
+  RType->getAs();
+  if (const auto *InjectedCNT = RType->getAs())
+// implicitly-generated deduction guide.
+FReturnType = InjectedCNT->getInjectedTST();
+  else if (const auto *ET = RType->getAs())
+// explicit deduction guide.
+FReturnType = ET->getNamedType()->getAs();
+  assert(FReturnType && "expected to see a return type");
+  // Deduce template arguments of the deduction guide f from the RHS of
+  // the alias.
+  //
+  // C++ [over.match.class.deduct]p3: ...For each function or function
+  // template f in the guides of the template named by the
+  // simple-template-id of the defining-type-id, the template arguments
+  // of the return type of f are deduced from the defining-type-id of A
+  // according to the process in [temp.deduct.type] with the exception
+  // that deduction does not fail if not all template arguments are
+  // deduced.
+  //
+  //
+  //  template
+  //  f(X, Y) -> f;
+  //
+  //  template
+  //  using alias = f;
+  //
+  // The RHS of alias is f, we deduced the template arguments of
+  // the return type of the deduction guide from it: Y->int, X->U
+  sema::TemplateDeductionInfo TDeduceInfo(Loc);
+  // Must initialize n elements, this is required by DeduceTemplateArguments.
+  SmallVector DeduceResults(
+  F->getTemplateParameters()->size());
+
+  // FIXME: DeduceTemplateArguments stops immediately at the first
+  // non-deducible template argument. However, this doesn't seem to casue
+  // issues for practice cases, we probably need to extend it to continue
+  // performing deduction for rest of arguments to align with the C++
+  // standard.
+  SemaRef.DeduceTemplateArguments(
+  F->getTemplateParameters(), FReturnType->template_arguments(),
+  AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
+  /*NumberOfArgumentsMustMatch=*/false);
+
+  SmallVector DeducedArgs;
+  SmallVector NonDeducedTemplateParamsInFIndex;
+  // !!NOTE: DeduceResults respects the sequence of template parameters of
+  // the deduction guide f.
+  for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
+if (const auto  = DeduceResults[Index]; !D.isNull()) // Deduced
+  DeducedArgs.push_back(D);
+else
+  NonDeducedTemplateParamsInFIndex.push_back(Index);
+  }
+  auto DeducedAliasTemplateParams =
+  TemplateParamsReferencedInTemplateArgumentList(
+  AliasTemplate->getTemplateParameters()->asArray(), DeducedArgs);