[clang] [clang] CTAD alias: Fix missing template arg packs during the transformation (PR #92535)

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

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


[clang] [Sema] Fix an out-of-bounds crash when diagnosing bad conversion for a function with a parameter pack. (PR #92721)

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

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

None

>From 2aa2caf15282d28e9fda99d51776d842d3d57e95 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Sun, 19 May 2024 22:47:14 +0200
Subject: [PATCH] [Sema] Fix an out-of-bounds crash when diagnosing bad
 conversion for a function with a parameter pack.

---
 clang/docs/ReleaseNotes.rst   |  2 ++
 clang/lib/Sema/SemaOverload.cpp   | 10 --
 clang/test/Misc/diag-overload-cand-ranges.cpp |  8 
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index be4cded276321..de3d258ae578a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -573,6 +573,8 @@ Bug Fixes in This Version
 - Clang now correctly disallows VLA type compound literals, e.g. 
``(int[size]){}``,
   as the C standard mandates. (#GH89835)
 
+- Fix an out-of-bounds crash when diagnosing bad conversion for a function 
with a parameter pack. 
+
 Bug Fixes to Compiler Builtins
 ^^
 
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 2eb25237a0de6..73a175f724402 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -11298,8 +11298,14 @@ static void DiagnoseBadConversion(Sema , 
OverloadCandidate *Cand,
   Expr *FromExpr = Conv.Bad.FromExpr;
   QualType FromTy = Conv.Bad.getFromType();
   QualType ToTy = Conv.Bad.getToType();
-  SourceRange ToParamRange =
-  !isObjectArgument ? Fn->getParamDecl(I)->getSourceRange() : 
SourceRange();
+  SourceRange ToParamRange;
+  if (!isObjectArgument) {
+if (I < Fn->getNumParams())
+  ToParamRange = Fn->getParamDecl(I)->getSourceRange();
+else
+  // parameter pack case.
+  ToParamRange = Fn->parameters().back()->getSourceRange();
+  }
 
   if (FromTy == S.Context.OverloadTy) {
 assert(FromExpr && "overload set argument came from implicit argument?");
diff --git a/clang/test/Misc/diag-overload-cand-ranges.cpp 
b/clang/test/Misc/diag-overload-cand-ranges.cpp
index 080ca484d4b74..06d638d9b719c 100644
--- a/clang/test/Misc/diag-overload-cand-ranges.cpp
+++ b/clang/test/Misc/diag-overload-cand-ranges.cpp
@@ -70,3 +70,11 @@ template  class Type1 {};
 template  void Function1(int zz, Type1 , int ww) {}
 
 void Function() { Function1(33, Type1<-42>(), 66); }
+
+// CHECK:  error: no matching function for call to 'b'
+// CHECK:  :{[[@LINE+1]]:41-[[@LINE+1]]:45}: note: {{.*}} no known 
conversion from 'int' to 'ForwardClass' for 3rd argument
+template  void b(T, U...);
+class ForwardClass;
+void NoCrash() {
+  b(1, 1, 0);
+}

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][AST] Fix end location of DeclarationNameInfo on instantiated methods (PR #92654)

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

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

nit: add a note in `clang/docs/ReleaseNotes.rst` 

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


[clang] [clang] CTAD alias: Fix missing template arg packs during the transformation (PR #92535)

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

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

clang rejects some valid code (see testcases) because of an incorrect 
transformed deduction guides. This patch fixes it.

We miss the template argument packs during the transformation (`auto 
(type-parameter-0-0...) -> Foo<>`). In 
`TreeTransform::TransformTemplateArguments `, we have a logic of handling 
template argument packs which were originally added to support CTAD alias, it 
doesn't seem to be needed, we need to unpack them. 

>From 21ff4048fdee4f76d7d73ae9f2bfaf18614a4a3b Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 17 May 2024 14:12:04 +0200
Subject: [PATCH] [clang] CTAD alias: Fix missing template arg packs during the
 transformation.

---
 clang/lib/Sema/TreeTransform.h   |  8 
 clang/test/AST/ast-dump-ctad-alias.cpp   | 20 
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp |  5 +
 3 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index b10e5ba65eb1c..f9fec21bf5bb6 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4818,14 +4818,6 @@ bool TreeTransform::TransformTemplateArguments(
 TemplateArgumentLoc In = *First;
 
 if (In.getArgument().getKind() == TemplateArgument::Pack) {
-  // When building the deduction guides, we rewrite the argument packs
-  // instead of unpacking.
-  if (getSema().CodeSynthesisContexts.back().Kind ==
-  Sema::CodeSynthesisContext::BuildingDeductionGuides) {
-if (getDerived().TransformTemplateArgument(In, Out, Uneval))
-  return true;
-continue;
-  }
   // Unpack argument packs, which we translate them into separate
   // arguments.
   // FIXME: We could do much better if we could guarantee that the
diff --git a/clang/test/AST/ast-dump-ctad-alias.cpp 
b/clang/test/AST/ast-dump-ctad-alias.cpp
index 7fe6c05621eee..9382558393e4c 100644
--- a/clang/test/AST/ast-dump-ctad-alias.cpp
+++ b/clang/test/AST/ast-dump-ctad-alias.cpp
@@ -48,3 +48,23 @@ Out2::AInner t(1.0);
 // CHECK-NEXT: |   |-TemplateArgument type 'double'
 // CHECK-NEXT: |   | `-BuiltinType {{.*}} 'double'
 // CHECK-NEXT: |   `-ParmVarDecl {{.*}} 'double'
+
+template 
+struct Foo {
+  Foo(T1...);
+};
+
+template 
+using AFoo = Foo;
+AFoo a(1, 2);
+// CHECK:  |-CXXDeductionGuideDecl {{.*}} implicit  'auto (type-parameter-0-0...) -> Foo'
+// CHECK-NEXT: | | `-ParmVarDecl {{.*}} 'type-parameter-0-0...' pack
+// CHECK-NEXT: | `-CXXDeductionGuideDecl {{.*}} implicit used  'auto (int, int) -> Foo' implicit_instantiation
+
+template 
+using BFoo = Foo;
+BFoo b2(1.0, 2.0);
+// CHECK:  |-CXXDeductionGuideDecl {{.*}} implicit  'auto (type-parameter-0-0, type-parameter-0-0) -> Foo'
+// CHECK-NEXT: | | |-ParmVarDecl {{.*}} 'type-parameter-0-0'
+// CHECK-NEXT: | | `-ParmVarDecl {{.*}} 'type-parameter-0-0'
+// CHECK-NEXT: | `-CXXDeductionGuideDecl {{.*}} implicit used  'auto (double, double) -> Foo' implicit_instantiation
diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp 
b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
index 7c186dc379c7b..479b0e3606721 100644
--- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
+++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
@@ -173,6 +173,11 @@ template 
 using AFoo = Foo;
 
 auto b = AFoo{};
+AFoo a(1, 2);
+
+template 
+using BFoo = Foo;
+BFoo b2(1.0, 2.0);
 } // namespace test13
 
 namespace test14 {

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

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


@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+// Scalar types are bitwise clonable.
+static_assert(__is_bitwise_cloneable(int));
+static_assert(__is_bitwise_cloneable(int*));
+// array
+static_assert(__is_bitwise_cloneable(int[10]));
+
+// non-scalar types.
+static_assert(!__is_bitwise_cloneable(int&));
+
+
+struct Forward; // expected-note 2{{forward declaration of 'Forward'}}
+static_assert(!__is_bitwise_cloneable(Forward)); // expected-error 
{{incomplete type 'Forward' used in type trait expression}}
+
+struct Foo { int a; };
+static_assert(__is_bitwise_cloneable(Foo));
+
+struct DynamicClass { virtual int Foo(); };
+static_assert(__is_bitwise_cloneable(DynamicClass));
+
+struct Bar { int& b; }; // trivially copyable
+static_assert(__is_trivially_copyable(Bar));
+static_assert(__is_bitwise_cloneable(Bar));

hokein wrote:

Because of the reference member `int & b`.

Reference types are currently excluded in bitwise-cloneable types (references 
are just alias, and they cannot be reset once initialized).

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


[clang] [clang] CTAD alias: Emit a more descriptive diagnostic message when is_deducible constraint is evaluated to false. (PR #92389)

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

hokein wrote:

Thanks @mizvekov for the quick fix.

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


[clang] [clang] CTAD alias: Emit a more descriptive diagnostic message when is_deducible constraint is evaluated to false. (PR #92389)

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

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


[clang] [clang] CTAD alias: Emit a more descriptive diagnostic message when is_deducible constraint is evaluated to false. (PR #92389)

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


@@ -111,7 +111,7 @@ struct Foo {
 template 
 using Bar = Foo; // expected-note {{candidate template ignored: 
couldn't infer template argument 'X'}} \
// expected-note {{candidate template ignored: 
constraints not satisfied [with X = int]}} \
-   // expected-note {{because '__is_deducible}}
+   // expected-note {{can not deduce template 
arguments for 'Bar' from the type 'Foo'}}

hokein wrote:

ah, this was left when I adjusted the message. Done.

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


[clang] [clang] CTAD alias: Emit a more descriptive diagnostic message when is_deducible constraint is evaluated to false. (PR #92389)

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

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

>From ada7f47eae6ef66a51cdeb91ab5aca0e188e5704 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Thu, 16 May 2024 14:05:57 +0200
Subject: [PATCH] [clang] CTAD alias: Emit a more descriptive diagnostic
 message when is_deducible constraint is evaluated to false.

Fixes https://github.com/llvm/llvm-project/issues/92225
---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 ++
 clang/lib/Sema/SemaConcept.cpp   | 7 +++
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 7 +++
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e648b503ac034..93fd5c16989da 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3003,6 +3003,8 @@ def 
note_single_arg_concept_specialization_constraint_evaluated_to_false : Note<
   "%select{and|because}0 %1 does not satisfy %2">;
 def note_atomic_constraint_evaluated_to_false_elaborated : Note<
   "%select{and|because}0 '%1' (%2 %3 %4) evaluated to false">;
+def note_is_deducible_constraint_evaluated_to_false : Note<
+  "cannot deduce template arguments for %0 from %1">;
 def err_constrained_virtual_method : Error<
   "virtual function cannot have a requires clause">;
 def err_trailing_requires_clause_on_deduction_guide : Error<
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 7bfec4e11f7aa..202dd86c67f62 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -1162,6 +1162,13 @@ static void 
diagnoseWellFormedUnsatisfiedConstraintExpr(Sema ,
 break;
   }
 return;
+  } else if (auto *TTE = dyn_cast(SubstExpr);
+ TTE && TTE->getTrait() == clang::TypeTrait::BTT_IsDeducible) {
+assert(TTE->getNumArgs() == 2);
+S.Diag(SubstExpr->getSourceRange().getBegin(),
+   diag::note_is_deducible_constraint_evaluated_to_false)
+<< TTE->getArg(0)->getType() << TTE->getArg(1)->getType();
+return;
   }
 
   S.Diag(SubstExpr->getSourceRange().getBegin(),
diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp 
b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
index 7c186dc379c7b..21b2b8bff5002 100644
--- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
+++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
@@ -111,7 +111,7 @@ struct Foo {
 template 
 using Bar = Foo; // expected-note {{candidate template ignored: 
couldn't infer template argument 'X'}} \
// expected-note {{candidate template ignored: 
constraints not satisfied [with X = int]}} \
-   // expected-note {{because '__is_deducible}}
+   // expected-note {{cannot deduce template 
arguments for 'Bar' from 'Foo'}}
 
 
 Bar s = {{1}}; // expected-error {{no viable constructor or deduction guide }}
@@ -138,7 +138,7 @@ template struct Foo { T c; };
 template
 using AFoo = Foo; // expected-note {{candidate template ignored: could not 
match 'Foo' against 'int'}} \
 // expected-note {{candidate template ignored: constraints 
not satisfied [with Y = int]}} \
-// expected-note {{because '__is_deducible(AFoo, 
Foo)' evaluated to false}} \
+// expected-note {{cannot deduce template arguments for 
'AFoo' from 'Foo'}} \
 // expected-note {{candidate function template not viable: 
requires 0 arguments, but 1 was provided}}
 
 AFoo s = {1}; // expected-error {{no viable constructor or deduction guide for 
deduction of template arguments of 'AFoo'}}
@@ -196,10 +196,9 @@ template  struct Foo { Foo(T); };
 
 template using AFoo = Foo;
 template concept False = false;
-// FIXME: emit a more descriptive diagnostic for "__is_deducible" constraint 
failure.
 template
 using BFoo = AFoo; // expected-note {{candidate template ignored: 
constraints not satisfied [with V = int]}} \
-  // expected-note {{because '__is_deducible(BFoo, Foo)' evaluated to false}} \
+  // expected-note {{cannot deduce template arguments for 
'BFoo' from 'Foo'}} \
   // expected-note {{candidate template ignored: could not 
match 'Foo' against 'int *'}}
 int i = 0;
 AFoo a1(); // OK, deduce Foo

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD alias: Emit a more descriptive diagnostic message when is_deducible constraint is evaluated to false. (PR #92389)

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

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

Fixes https://github.com/llvm/llvm-project/issues/92225

>From 20294489121be7a68519280da8e144c2b9be398c Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Thu, 16 May 2024 14:05:57 +0200
Subject: [PATCH] [clang] CTAD alias: Emit a more descriptive diagnostic
 message when is_deducible constraint is evaluated to false.

Fixes https://github.com/llvm/llvm-project/issues/92225
---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 ++
 clang/lib/Sema/SemaConcept.cpp   | 7 +++
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 6 +++---
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e648b503ac034..04bf6ed2c52f5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3003,6 +3003,8 @@ def 
note_single_arg_concept_specialization_constraint_evaluated_to_false : Note<
   "%select{and|because}0 %1 does not satisfy %2">;
 def note_atomic_constraint_evaluated_to_false_elaborated : Note<
   "%select{and|because}0 '%1' (%2 %3 %4) evaluated to false">;
+def note_is_deducible_constraint_evaluated_to_false : Note<
+  "cannot deduce template arguments of %0 from %1">;
 def err_constrained_virtual_method : Error<
   "virtual function cannot have a requires clause">;
 def err_trailing_requires_clause_on_deduction_guide : Error<
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 7bfec4e11f7aa..202dd86c67f62 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -1162,6 +1162,13 @@ static void 
diagnoseWellFormedUnsatisfiedConstraintExpr(Sema ,
 break;
   }
 return;
+  } else if (auto *TTE = dyn_cast(SubstExpr);
+ TTE && TTE->getTrait() == clang::TypeTrait::BTT_IsDeducible) {
+assert(TTE->getNumArgs() == 2);
+S.Diag(SubstExpr->getSourceRange().getBegin(),
+   diag::note_is_deducible_constraint_evaluated_to_false)
+<< TTE->getArg(0)->getType() << TTE->getArg(1)->getType();
+return;
   }
 
   S.Diag(SubstExpr->getSourceRange().getBegin(),
diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp 
b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
index 7c186dc379c7b..f7367d01bc2eb 100644
--- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
+++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
@@ -111,7 +111,7 @@ struct Foo {
 template 
 using Bar = Foo; // expected-note {{candidate template ignored: 
couldn't infer template argument 'X'}} \
// expected-note {{candidate template ignored: 
constraints not satisfied [with X = int]}} \
-   // expected-note {{because '__is_deducible}}
+   // expected-note {{can not deduce template 
arguments for 'Bar' from the type 'Foo'}}
 
 
 Bar s = {{1}}; // expected-error {{no viable constructor or deduction guide }}
@@ -138,7 +138,7 @@ template struct Foo { T c; };
 template
 using AFoo = Foo; // expected-note {{candidate template ignored: could not 
match 'Foo' against 'int'}} \
 // expected-note {{candidate template ignored: constraints 
not satisfied [with Y = int]}} \
-// expected-note {{because '__is_deducible(AFoo, 
Foo)' evaluated to false}} \
+// expected-note {{cannot deduce template arguments for 
'AFoo' from 'Foo'}} \
 // expected-note {{candidate function template not viable: 
requires 0 arguments, but 1 was provided}}
 
 AFoo s = {1}; // expected-error {{no viable constructor or deduction guide for 
deduction of template arguments of 'AFoo'}}
@@ -199,7 +199,7 @@ template concept False = false;
 // FIXME: emit a more descriptive diagnostic for "__is_deducible" constraint 
failure.
 template
 using BFoo = AFoo; // expected-note {{candidate template ignored: 
constraints not satisfied [with V = int]}} \
-  // expected-note {{because '__is_deducible(BFoo, Foo)' evaluated to false}} \
+  // expected-note {{cannot deduce template arguments for 
'BFoo' from 'Foo'}} \
   // expected-note {{candidate template ignored: could not 
match 'Foo' against 'int *'}}
 int i = 0;
 AFoo a1(); // OK, deduce Foo

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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

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


[clang] [AST] RecursiveASTVisitor: Don't traverse the alias deduction guides in the default mode. (PR #91454)

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

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


[clang] [clang-tools-extra] [clang] Fix CXXNewExpr end source location for 'new struct S' (PR #92266)

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

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


[clang] [clang-tools-extra] [clang] Fix CXXNewExpr end source location for 'new struct S' (PR #92266)

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


@@ -583,3 +583,8 @@ void NonADLCall3() {
   f(x);
 }
 } // namespace test_adl_call_three
+

hokein wrote:

nit: wrap the code within `namespace GH35300 { ...}`.

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


[clang] [clang-tools-extra] [clang] Fix CXXNewExpr end source location for 'new struct S' (PR #92266)

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

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

thanks, still good.

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


[clang] [AST] RecursiveASTVisitor: Don't traverse the alias deduction guides in the default mode. (PR #91454)

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

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

>From e560fe2bf2d4bdc07a71682aa4d3a4bee8730b80 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Wed, 8 May 2024 12:11:10 +0200
Subject: [PATCH 1/2] [AST] RecursiveASTVisitor: Don't traverse the alias
 deduction guides in default mode.

---
 clang/include/clang/AST/RecursiveASTVisitor.h | 28 --
 .../DeductionGuide.cpp| 89 +++
 2 files changed, 110 insertions(+), 7 deletions(-)
 create mode 100644 
clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp

diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h 
b/clang/include/clang/AST/RecursiveASTVisitor.h
index f9b145b4e86a5..2517189c95300 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -736,13 +736,27 @@ bool RecursiveASTVisitor::TraverseDecl(Decl *D) {
 
   // As a syntax visitor, by default we want to ignore declarations for
   // implicit declarations (ones not typed explicitly by the user).
-  if (!getDerived().shouldVisitImplicitCode() && D->isImplicit()) {
-// For an implicit template type parameter, its type constraints are not
-// implicit and are not represented anywhere else. We still need to visit
-// them.
-if (auto *TTPD = dyn_cast(D))
-  return TraverseTemplateTypeParamDeclConstraints(TTPD);
-return true;
+  if (!getDerived().shouldVisitImplicitCode()) {
+if (D->isImplicit()) {
+  // For an implicit template type parameter, its type constraints are not
+  // implicit and are not represented anywhere else. We still need to visit
+  // them.
+  if (auto *TTPD = dyn_cast(D))
+return TraverseTemplateTypeParamDeclConstraints(TTPD);
+  return true;
+}
+
+// Deduction guides for alias templates are always synthesized, so they
+// should not be traversed unless shouldVisitImplicitCode() returns true.
+//
+// It's important to note that checking the implicit bit is not efficient
+// for the alias case. For deduction guides synthesized from explicit
+// user-defined deduction guides, we must maintain the explicit bit to
+// ensure correct overload resolution.
+if (auto *FTD = dyn_cast(D))
+  if (llvm::isa_and_present(
+  FTD->getDeclName().getCXXDeductionGuideTemplate()))
+return true;
   }
 
   switch (D->getKind()) {
diff --git 
a/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp 
b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp
new file mode 100644
index 0..abfdbaea4a615
--- /dev/null
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp
@@ -0,0 +1,89 @@
+//===- unittest/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "TestVisitor.h"
+#include 
+
+using namespace clang;
+
+namespace {
+
+class DeductionGuideVisitor
+: public ExpectedLocationVisitor {
+public:
+  DeductionGuideVisitor(bool ShouldVisitImplicitCode)
+  : ShouldVisitImplicitCode(ShouldVisitImplicitCode) {}
+  bool VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
+std::string Storage;
+llvm::raw_string_ostream Stream(Storage);
+D->print(Stream);
+Match(Stream.str(),D->getLocation());
+return true;
+  }
+
+  bool shouldVisitTemplateInstantiations() const {
+return false;
+  }
+
+  bool shouldVisitImplicitCode() const {
+return ShouldVisitImplicitCode;
+  }
+  bool ShouldVisitImplicitCode;
+};
+
+TEST(RecursiveASTVisitor, DeductionGuideNonImplicitMode) {
+  DeductionGuideVisitor Visitor(/*ShouldVisitImplicitCode*/ false);
+  // Verify that the synthezied deduction guide for alias is not visited in
+  // RAV's implicit mode.
+  Visitor.ExpectMatch("Foo(T) -> Foo", 11, 1);
+  Visitor.DisallowMatch("Bar(type-parameter-0-0) -> Foo", 14, 1);
+  EXPECT_TRUE(Visitor.runOver(
+R"cpp(
+template 
+concept False = true;
+
+template  
+struct Foo { 
+  Foo(T);
+};
+
+template requires False
+Foo(T) -> Foo;
+
+template 
+using Bar = Foo;
+Bar s(1); 
+   )cpp"
+  , DeductionGuideVisitor::Lang_CXX2a));
+}
+
+TEST(RecursiveASTVisitor, DeductionGuideImplicitMode) {
+  DeductionGuideVisitor Visitor(/*ShouldVisitImplicitCode*/ true);
+  Visitor.ExpectMatch("Foo(T) -> Foo", 11, 1);
+  Visitor.ExpectMatch("Bar(type-parameter-0-0) -> Foo", 14, 1);
+  EXPECT_TRUE(Visitor.runOver(
+R"cpp(
+template 
+concept False = true;
+
+template  
+struct Foo { 
+  Foo(T);
+};
+
+template requires False
+Foo(T) -> Foo;
+
+template 
+using Bar = Foo;
+Bar s(1); 
+   )cpp"
+  , DeductionGuideVisitor::Lang_CXX2a));
+}
+
+} // end anonymous namespace

>From 

[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

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


@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+// Scalar types are bitwise clonable.
+static_assert(__is_bitwise_cloneable(int));
+static_assert(__is_bitwise_cloneable(int*));
+// array
+static_assert(__is_bitwise_cloneable(int[10]));
+
+// non-scalar types.
+static_assert(!__is_bitwise_cloneable(int&));
+
+
+struct Forward; // expected-note 2{{forward declaration of 'Forward'}}
+static_assert(!__is_bitwise_cloneable(Forward)); // expected-error 
{{incomplete type 'Forward' used in type trait expression}}
+
+struct Foo { int a; };
+static_assert(__is_bitwise_cloneable(Foo));
+
+struct DynamicClass { virtual int Foo(); };
+static_assert(__is_bitwise_cloneable(DynamicClass));
+
+struct Bar { int& b; }; // trivially copyable
+static_assert(__is_trivially_copyable(Bar));
+static_assert(__is_bitwise_cloneable(Bar));

hokein wrote:

This is a tricky bit.

The question arises: should we consider all trivially copyable types to be 
bitwise cloneable? My inclination is to say yes. Since memcpy is `safe` on all 
trivially copyable types, it's probably a good idea to ensure that 
bitwise_clonable covers as many types as possible.

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

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


@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+// Scalar types are bitwise clonable.
+static_assert(__is_bitwise_cloneable(int));
+static_assert(__is_bitwise_cloneable(int*));
+// array
+static_assert(__is_bitwise_cloneable(int[10]));
+
+// non-scalar types.
+static_assert(!__is_bitwise_cloneable(int&));
+
+
+struct Forward; // expected-note 2{{forward declaration of 'Forward'}}
+static_assert(!__is_bitwise_cloneable(Forward)); // expected-error 
{{incomplete type 'Forward' used in type trait expression}}
+
+struct Foo { int a; };
+static_assert(__is_bitwise_cloneable(Foo));
+
+struct DynamicClass { virtual int Foo(); };
+static_assert(__is_bitwise_cloneable(DynamicClass));

hokein wrote:

Done.

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

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


@@ -2718,6 +2718,36 @@ bool QualType::isTriviallyCopyableType(const ASTContext 
) const {
  /*IsCopyConstructible=*/false);
 }
 
+bool QualType::isBitwiseCloneableType(const ASTContext & Context) const {
+  QualType CanonicalType = getCanonicalType();
+  if (CanonicalType->isIncompleteType() || CanonicalType->isDependentType())
+return false;
+  // Trivially copyable types are bitwise clonable, e.g. scalar types.
+  if (CanonicalType.isTriviallyCopyableType(Context))
+return true;
+
+  if (CanonicalType->isArrayType())
+return Context.getBaseElementType(CanonicalType)
+.isBitwiseCloneableType(Context);
+
+  if (const auto *RD = CanonicalType->getAsCXXRecordDecl()) {
+for (auto Base : RD->bases())
+  if (!Base.getType().isBitwiseCloneableType(Context))
+return false;
+for (auto VBase : RD->vbases())
+  if (!VBase.getType().isBitwiseCloneableType(Context))
+return false;
+
+for (auto *const Field : RD->fields()) {
+  QualType T = Context.getBaseElementType(Field->getType());

hokein wrote:

Switched to `isBitwiseCloneableType(Field->getType())`.

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

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


@@ -2718,6 +2718,36 @@ bool QualType::isTriviallyCopyableType(const ASTContext 
) const {
  /*IsCopyConstructible=*/false);
 }
 
+bool QualType::isBitwiseCloneableType(const ASTContext & Context) const {
+  QualType CanonicalType = getCanonicalType();
+  if (CanonicalType->isIncompleteType() || CanonicalType->isDependentType())
+return false;
+  // Trivially copyable types are bitwise clonable, e.g. scalar types.
+  if (CanonicalType.isTriviallyCopyableType(Context))
+return true;
+
+  if (CanonicalType->isArrayType())
+return Context.getBaseElementType(CanonicalType)
+.isBitwiseCloneableType(Context);
+
+  if (const auto *RD = CanonicalType->getAsCXXRecordDecl()) {
+for (auto Base : RD->bases())
+  if (!Base.getType().isBitwiseCloneableType(Context))

hokein wrote:

Good point, added a FIXME (we could use an extra bit in the class definition 
class to cache the result).

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

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

https://github.com/hokein commented:

thanks for the review.

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

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


@@ -3958,6 +3958,50 @@ Note that the `size` argument must be a compile time 
constant.
 
 Note that this intrinsic cannot yet be called in a ``constexpr`` context.
 
+``__is_bitwise_cloneable``
+-
+
+A type trait is used to check whether a type can be safely copied by memcpy.
+
+**Syntax**:
+
+.. code-block:: c++
+
+  bool __is_bitwise_cloneable(Type)
+
+** Example of Use**:
+
+.. code-block:: c++
+
+  // Return a cloned object of the given default instance.
+  Foo* Clone(const Foo* default_instance, char* buffer, unsigned size) {
+if constexpr __is_bitwise_cloneable(decltype(*default_instance)) {
+  // Fast path via memcopy, without calling class constructor.
+  memcpy(buffer, default_instance, size);
+  // Explicitly start the lifetime of the cloned object.
+  return __builtin_start_object_lifetime(reinterpret_cast(buffer));
+}
+// Fallback the operator new, which invoke the class constructor.
+return new(buffer) Foo(*default_instance);
+  }
+
+**Description**:
+
+It is common for library owners to perform memcpy/memmove on types that aren't
+trivally copyable for performance reason. However, according to the C++ 
standard,

hokein wrote:

Done.

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

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

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

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

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

>From 10d06e728d836f4aaad7dbf1a6b06b57e4092bb1 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Mon, 25 Mar 2024 15:10:51 +0100
Subject: [PATCH 1/3] [clang] Implement a bitwise_copyable builtin type trait.

This patch implements a `__is_bitwise_copyable` builtin in clang.

The bitwise copyable types act as the trivially copyable types, but
they support a wider range of types (e.g. classes with virtual methods) --
their underlying types can be safely copied by `memcopy` or `memmove`,
the clang compiler guarantees that both source and destination objects
have the same *object* representations after the copy operation, and the
lifetime of the destination object implicitly starts.

A particular use case of this builtin is to clone an object via memcopy
(without running the constructor):

```
Message* clone(const Message* src, char* buffer, int size) {
  if constexpr __is_bitwise_copyable(Message) {
// bitwise copy to buffer, and implicitly create objects at the buffer
__builtin_memcpy(buffer, src, size);
return std::launder(reinterpret_cast(buffer));
  }
  // Fallback the operator new, which calls the constructor to start the 
lifetime.
  return new(buffer) Message(src);
}
```

Note that the definition of bitwise copyable is not tied to the Rule Of
Five, so users of this builtin must guarantee that program semantic constraints
are satisfied, e.g. no double resource deallocations.

Context: https://discourse.llvm.org/t/extension-for-creating-objects-via-memcpy
---
 clang/include/clang/AST/Type.h| 12 +
 clang/include/clang/Basic/TokenKinds.def  |  1 +
 clang/lib/AST/Type.cpp| 23 
 clang/lib/Sema/SemaExprCXX.cpp|  4 +++
 .../SemaCXX/builtin-is-bitwise-copyable.cpp   | 26 +++
 5 files changed, 66 insertions(+)
 create mode 100644 clang/test/SemaCXX/builtin-is-bitwise-copyable.cpp

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index e6643469e0b33..ff60f1c4b3520 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1120,6 +1120,18 @@ class QualType {
   /// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
   bool isTriviallyCopyableType(const ASTContext ) const;
 
+  /// Return true if this is a bitwise copyable type.
+  ///
+  /// This is an extension in clang: bitwise copyable types act as trivially
+  /// copyable types, underlying bytes of bitwise copyable type can be safely
+  /// copied by memcpy or memmove. Clang guarantees that both source and
+  /// destination objects have the same **object** representations after the
+  /// copy, and the lifetime of the destination object implicitly starts.
+  ///
+  /// bitwise copyable types cover a wider range of types, e.g. classes with
+  /// virtual methods.
+  bool isBitwiseCopyableType(const ASTContext ) const;
+
   /// Return true if this is a trivially copyable type
   bool isTriviallyCopyConstructibleType(const ASTContext ) const;
 
diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index 56c4b17f769d7..ce2298543fac6 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -527,6 +527,7 @@ TYPE_TRAIT_2(__is_pointer_interconvertible_base_of, 
IsPointerInterconvertibleBas
 #include "clang/Basic/TransformTypeTraits.def"
 
 // Clang-only C++ Type Traits
+TYPE_TRAIT_1(__is_bitwise_copyable, IsBitwiseCopyable, KEYCXX)
 TYPE_TRAIT_1(__is_trivially_relocatable, IsTriviallyRelocatable, KEYCXX)
 TYPE_TRAIT_1(__is_trivially_equality_comparable, 
IsTriviallyEqualityComparable, KEYCXX)
 TYPE_TRAIT_1(__is_bounded_array, IsBoundedArray, KEYCXX)
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index e31741cd44240..5c0b89545a92b 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2731,6 +2731,29 @@ bool QualType::isTriviallyCopyableType(const ASTContext 
) const {
  /*IsCopyConstructible=*/false);
 }
 
+bool QualType::isBitwiseCopyableType(const ASTContext & Context) const {
+  QualType CanonicalType = getCanonicalType();
+  if (CanonicalType->isIncompleteType() || CanonicalType->isDependentType())
+return false;
+  // Trivially copyable types are bitwise copyable, e.g. scalar types.
+  if (CanonicalType.isTriviallyCopyableType(Context))
+return true;
+
+  if (CanonicalType->isArrayType())
+return Context.getBaseElementType(CanonicalType)
+.isBitwiseCopyableType(Context);
+
+  if (const auto *RD = CanonicalType->getAsCXXRecordDecl()) {
+for (auto *const Field : RD->fields()) {
+  QualType T = Context.getBaseElementType(Field->getType());
+  if (!T.isBitwiseCopyableType(Context))
+return false;
+}
+return true;
+  }
+  return false;
+}
+
 bool QualType::isTriviallyCopyConstructibleType(
 const 

[clang] [clang-tools-extra] [clang] Fix CXXNewExpr end source location for 'new struct S' (PR #92266)

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


@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -ast-dump %s  2>&1 | FileCheck %s

hokein wrote:

For ast-dump lit tests, we usually place them in `clang/test/AST/` dir with 
name `ast-dump*.cpp` (or we can add it to the existing `ast-dump-expr.cpp`).

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


[clang] [clang-tools-extra] [clang] Fix CXXNewExpr end source location for 'new struct S' (PR #92266)

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

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

thanks, this looks good to me, a small nit.

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


[clang] [clang-tools-extra] [clang] Fix CXXNewExpr end source location for 'new struct S' (PR #92266)

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

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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

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

>From 659cf5b5c1216ab9f6a8dbb63b4f93de41cd173d Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 19 Apr 2024 10:54:12 +0200
Subject: [PATCH 1/2] [clang] CTAD: implement the missing IsDeducible
 constraint for alias templates.

Fixes https://github.com/llvm/llvm-project/issues/85192
Fixes https://github.com/llvm/llvm-project/issues/84492

- rebase to main
- add release note for __is_deducible
- implement diagnostics for bad argument types for __is_deducible

Don't expose __is_deducible trait.

Refine the implementation of hiding __is_deducible type trait.

Apply approach 3.
---
 clang/include/clang/Basic/TokenKinds.def |  3 +
 clang/include/clang/Sema/Sema.h  |  9 ++
 clang/lib/Basic/TypeTraits.cpp   | 10 +++
 clang/lib/Sema/SemaExprCXX.cpp   | 10 ++-
 clang/lib/Sema/SemaTemplate.cpp  | 82 +--
 clang/lib/Sema/SemaTemplateDeduction.cpp | 86 
 clang/test/AST/ast-dump-ctad-alias.cpp   | 20 +++--
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 27 --
 clang/test/SemaTemplate/deduction-guide.cpp  | 16 ++--
 clang/www/cxx_status.html|  4 +-
 10 files changed, 238 insertions(+), 29 deletions(-)

diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index 56c4b17f769d7..b5a0e9df9f7ae 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -538,6 +538,9 @@ TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX)
 TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_constructs_from_temporary, 
ReferenceConstructsFromTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_converts_from_temporary, 
ReferenceConvertsFromTemporary, KEYCXX)
+// IsDeducible is only used internally by clang for CTAD implementation and
+// is not exposed to users.
+TYPE_TRAIT_2(/*EmptySpellingName*/, IsDeducible, KEYCXX)
 
 // Embarcadero Expression Traits
 EXPRESSION_TRAIT(__is_lvalue_expr, IsLValueExpr, KEYCXX)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6a414aa57f32b..66d5e2d4a4ade 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9492,6 +9492,15 @@ class Sema final : public SemaBase {
   ArrayRef TemplateArgs,
   sema::TemplateDeductionInfo );
 
+  /// Deduce the template arguments of the given template from \p FromType.
+  /// Used to implement the IsDeducible constraint for alias CTAD per C++
+  /// [over.match.class.deduct]p4.
+  ///
+  /// It only supports class or type alias templates.
+  TemplateDeductionResult
+  DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType,
+  sema::TemplateDeductionInfo );
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo ,
diff --git a/clang/lib/Basic/TypeTraits.cpp b/clang/lib/Basic/TypeTraits.cpp
index 4dbf678dc395b..8d6794223ccaf 100644
--- a/clang/lib/Basic/TypeTraits.cpp
+++ b/clang/lib/Basic/TypeTraits.cpp
@@ -13,6 +13,7 @@
 #include "clang/Basic/TypeTraits.h"
 #include "llvm/Support/ErrorHandling.h"
 #include 
+#include 
 using namespace clang;
 
 static constexpr const char *TypeTraitNames[] = {
@@ -81,6 +82,15 @@ const char *clang::getTraitName(UnaryExprOrTypeTrait T) {
 
 const char *clang::getTraitSpelling(TypeTrait T) {
   assert(T <= TT_Last && "invalid enum value!");
+  if (T == BTT_IsDeducible) {
+// The __is_deducible is an internal-only type trait. To hide it from
+// external users, we define it with an empty spelling name, preventing the
+// clang parser from recognizing its token kind.
+// However, other components such as the AST dump still require the real
+// type trait name. Therefore, we return the real name when needed.
+assert(std::strlen(TypeTraitSpellings[T]) == 0);
+return "__is_deducible";
+  }
   return TypeTraitSpellings[T];
 }
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 34e12078a8c92..e4601f7d6c47d 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6143,7 +6143,15 @@ static bool EvaluateBinaryTypeTrait(Sema , 
TypeTrait BTT, const TypeSourceI
 
 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
   }
-default: llvm_unreachable("not a BTT");
+  case BTT_IsDeducible: {
+const auto *TSTToBeDeduced = cast(LhsT);
+sema::TemplateDeductionInfo Info(KeyLoc);
+return Self.DeduceTemplateArgumentsFromType(
+   TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
+   Info) == TemplateDeductionResult::Success;
+  }
+  default:
+llvm_unreachable("not a BTT");
   }
   llvm_unreachable("Unknown type trait or not 

[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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

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

>From 659cf5b5c1216ab9f6a8dbb63b4f93de41cd173d Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 19 Apr 2024 10:54:12 +0200
Subject: [PATCH 1/2] [clang] CTAD: implement the missing IsDeducible
 constraint for alias templates.

Fixes https://github.com/llvm/llvm-project/issues/85192
Fixes https://github.com/llvm/llvm-project/issues/84492

- rebase to main
- add release note for __is_deducible
- implement diagnostics for bad argument types for __is_deducible

Don't expose __is_deducible trait.

Refine the implementation of hiding __is_deducible type trait.

Apply approach 3.
---
 clang/include/clang/Basic/TokenKinds.def |  3 +
 clang/include/clang/Sema/Sema.h  |  9 ++
 clang/lib/Basic/TypeTraits.cpp   | 10 +++
 clang/lib/Sema/SemaExprCXX.cpp   | 10 ++-
 clang/lib/Sema/SemaTemplate.cpp  | 82 +--
 clang/lib/Sema/SemaTemplateDeduction.cpp | 86 
 clang/test/AST/ast-dump-ctad-alias.cpp   | 20 +++--
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 27 --
 clang/test/SemaTemplate/deduction-guide.cpp  | 16 ++--
 clang/www/cxx_status.html|  4 +-
 10 files changed, 238 insertions(+), 29 deletions(-)

diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index 56c4b17f769d7..b5a0e9df9f7ae 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -538,6 +538,9 @@ TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX)
 TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_constructs_from_temporary, 
ReferenceConstructsFromTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_converts_from_temporary, 
ReferenceConvertsFromTemporary, KEYCXX)
+// IsDeducible is only used internally by clang for CTAD implementation and
+// is not exposed to users.
+TYPE_TRAIT_2(/*EmptySpellingName*/, IsDeducible, KEYCXX)
 
 // Embarcadero Expression Traits
 EXPRESSION_TRAIT(__is_lvalue_expr, IsLValueExpr, KEYCXX)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6a414aa57f32b..66d5e2d4a4ade 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9492,6 +9492,15 @@ class Sema final : public SemaBase {
   ArrayRef TemplateArgs,
   sema::TemplateDeductionInfo );
 
+  /// Deduce the template arguments of the given template from \p FromType.
+  /// Used to implement the IsDeducible constraint for alias CTAD per C++
+  /// [over.match.class.deduct]p4.
+  ///
+  /// It only supports class or type alias templates.
+  TemplateDeductionResult
+  DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType,
+  sema::TemplateDeductionInfo );
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo ,
diff --git a/clang/lib/Basic/TypeTraits.cpp b/clang/lib/Basic/TypeTraits.cpp
index 4dbf678dc395b..8d6794223ccaf 100644
--- a/clang/lib/Basic/TypeTraits.cpp
+++ b/clang/lib/Basic/TypeTraits.cpp
@@ -13,6 +13,7 @@
 #include "clang/Basic/TypeTraits.h"
 #include "llvm/Support/ErrorHandling.h"
 #include 
+#include 
 using namespace clang;
 
 static constexpr const char *TypeTraitNames[] = {
@@ -81,6 +82,15 @@ const char *clang::getTraitName(UnaryExprOrTypeTrait T) {
 
 const char *clang::getTraitSpelling(TypeTrait T) {
   assert(T <= TT_Last && "invalid enum value!");
+  if (T == BTT_IsDeducible) {
+// The __is_deducible is an internal-only type trait. To hide it from
+// external users, we define it with an empty spelling name, preventing the
+// clang parser from recognizing its token kind.
+// However, other components such as the AST dump still require the real
+// type trait name. Therefore, we return the real name when needed.
+assert(std::strlen(TypeTraitSpellings[T]) == 0);
+return "__is_deducible";
+  }
   return TypeTraitSpellings[T];
 }
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 34e12078a8c92..e4601f7d6c47d 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6143,7 +6143,15 @@ static bool EvaluateBinaryTypeTrait(Sema , 
TypeTrait BTT, const TypeSourceI
 
 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
   }
-default: llvm_unreachable("not a BTT");
+  case BTT_IsDeducible: {
+const auto *TSTToBeDeduced = cast(LhsT);
+sema::TemplateDeductionInfo Info(KeyLoc);
+return Self.DeduceTemplateArgumentsFromType(
+   TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
+   Info) == TemplateDeductionResult::Success;
+  }
+  default:
+llvm_unreachable("not a BTT");
   }
   llvm_unreachable("Unknown type trait or not 

[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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

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

>From 659cf5b5c1216ab9f6a8dbb63b4f93de41cd173d Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 19 Apr 2024 10:54:12 +0200
Subject: [PATCH 1/2] [clang] CTAD: implement the missing IsDeducible
 constraint for alias templates.

Fixes https://github.com/llvm/llvm-project/issues/85192
Fixes https://github.com/llvm/llvm-project/issues/84492

- rebase to main
- add release note for __is_deducible
- implement diagnostics for bad argument types for __is_deducible

Don't expose __is_deducible trait.

Refine the implementation of hiding __is_deducible type trait.

Apply approach 3.
---
 clang/include/clang/Basic/TokenKinds.def |  3 +
 clang/include/clang/Sema/Sema.h  |  9 ++
 clang/lib/Basic/TypeTraits.cpp   | 10 +++
 clang/lib/Sema/SemaExprCXX.cpp   | 10 ++-
 clang/lib/Sema/SemaTemplate.cpp  | 82 +--
 clang/lib/Sema/SemaTemplateDeduction.cpp | 86 
 clang/test/AST/ast-dump-ctad-alias.cpp   | 20 +++--
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 27 --
 clang/test/SemaTemplate/deduction-guide.cpp  | 16 ++--
 clang/www/cxx_status.html|  4 +-
 10 files changed, 238 insertions(+), 29 deletions(-)

diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index 56c4b17f769d7..b5a0e9df9f7ae 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -538,6 +538,9 @@ TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX)
 TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_constructs_from_temporary, 
ReferenceConstructsFromTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_converts_from_temporary, 
ReferenceConvertsFromTemporary, KEYCXX)
+// IsDeducible is only used internally by clang for CTAD implementation and
+// is not exposed to users.
+TYPE_TRAIT_2(/*EmptySpellingName*/, IsDeducible, KEYCXX)
 
 // Embarcadero Expression Traits
 EXPRESSION_TRAIT(__is_lvalue_expr, IsLValueExpr, KEYCXX)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6a414aa57f32b..66d5e2d4a4ade 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9492,6 +9492,15 @@ class Sema final : public SemaBase {
   ArrayRef TemplateArgs,
   sema::TemplateDeductionInfo );
 
+  /// Deduce the template arguments of the given template from \p FromType.
+  /// Used to implement the IsDeducible constraint for alias CTAD per C++
+  /// [over.match.class.deduct]p4.
+  ///
+  /// It only supports class or type alias templates.
+  TemplateDeductionResult
+  DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType,
+  sema::TemplateDeductionInfo );
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo ,
diff --git a/clang/lib/Basic/TypeTraits.cpp b/clang/lib/Basic/TypeTraits.cpp
index 4dbf678dc395b..8d6794223ccaf 100644
--- a/clang/lib/Basic/TypeTraits.cpp
+++ b/clang/lib/Basic/TypeTraits.cpp
@@ -13,6 +13,7 @@
 #include "clang/Basic/TypeTraits.h"
 #include "llvm/Support/ErrorHandling.h"
 #include 
+#include 
 using namespace clang;
 
 static constexpr const char *TypeTraitNames[] = {
@@ -81,6 +82,15 @@ const char *clang::getTraitName(UnaryExprOrTypeTrait T) {
 
 const char *clang::getTraitSpelling(TypeTrait T) {
   assert(T <= TT_Last && "invalid enum value!");
+  if (T == BTT_IsDeducible) {
+// The __is_deducible is an internal-only type trait. To hide it from
+// external users, we define it with an empty spelling name, preventing the
+// clang parser from recognizing its token kind.
+// However, other components such as the AST dump still require the real
+// type trait name. Therefore, we return the real name when needed.
+assert(std::strlen(TypeTraitSpellings[T]) == 0);
+return "__is_deducible";
+  }
   return TypeTraitSpellings[T];
 }
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 34e12078a8c92..e4601f7d6c47d 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6143,7 +6143,15 @@ static bool EvaluateBinaryTypeTrait(Sema , 
TypeTrait BTT, const TypeSourceI
 
 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
   }
-default: llvm_unreachable("not a BTT");
+  case BTT_IsDeducible: {
+const auto *TSTToBeDeduced = cast(LhsT);
+sema::TemplateDeductionInfo Info(KeyLoc);
+return Self.DeduceTemplateArgumentsFromType(
+   TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
+   Info) == TemplateDeductionResult::Success;
+  }
+  default:
+llvm_unreachable("not a BTT");
   }
   llvm_unreachable("Unknown type trait or not 

[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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

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

>From 659cf5b5c1216ab9f6a8dbb63b4f93de41cd173d Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 19 Apr 2024 10:54:12 +0200
Subject: [PATCH 1/2] [clang] CTAD: implement the missing IsDeducible
 constraint for alias templates.

Fixes https://github.com/llvm/llvm-project/issues/85192
Fixes https://github.com/llvm/llvm-project/issues/84492

- rebase to main
- add release note for __is_deducible
- implement diagnostics for bad argument types for __is_deducible

Don't expose __is_deducible trait.

Refine the implementation of hiding __is_deducible type trait.

Apply approach 3.
---
 clang/include/clang/Basic/TokenKinds.def |  3 +
 clang/include/clang/Sema/Sema.h  |  9 ++
 clang/lib/Basic/TypeTraits.cpp   | 10 +++
 clang/lib/Sema/SemaExprCXX.cpp   | 10 ++-
 clang/lib/Sema/SemaTemplate.cpp  | 82 +--
 clang/lib/Sema/SemaTemplateDeduction.cpp | 86 
 clang/test/AST/ast-dump-ctad-alias.cpp   | 20 +++--
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 27 --
 clang/test/SemaTemplate/deduction-guide.cpp  | 16 ++--
 clang/www/cxx_status.html|  4 +-
 10 files changed, 238 insertions(+), 29 deletions(-)

diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index 56c4b17f769d7..b5a0e9df9f7ae 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -538,6 +538,9 @@ TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX)
 TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_constructs_from_temporary, 
ReferenceConstructsFromTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_converts_from_temporary, 
ReferenceConvertsFromTemporary, KEYCXX)
+// IsDeducible is only used internally by clang for CTAD implementation and
+// is not exposed to users.
+TYPE_TRAIT_2(/*EmptySpellingName*/, IsDeducible, KEYCXX)
 
 // Embarcadero Expression Traits
 EXPRESSION_TRAIT(__is_lvalue_expr, IsLValueExpr, KEYCXX)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6a414aa57f32b..66d5e2d4a4ade 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9492,6 +9492,15 @@ class Sema final : public SemaBase {
   ArrayRef TemplateArgs,
   sema::TemplateDeductionInfo );
 
+  /// Deduce the template arguments of the given template from \p FromType.
+  /// Used to implement the IsDeducible constraint for alias CTAD per C++
+  /// [over.match.class.deduct]p4.
+  ///
+  /// It only supports class or type alias templates.
+  TemplateDeductionResult
+  DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType,
+  sema::TemplateDeductionInfo );
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo ,
diff --git a/clang/lib/Basic/TypeTraits.cpp b/clang/lib/Basic/TypeTraits.cpp
index 4dbf678dc395b..8d6794223ccaf 100644
--- a/clang/lib/Basic/TypeTraits.cpp
+++ b/clang/lib/Basic/TypeTraits.cpp
@@ -13,6 +13,7 @@
 #include "clang/Basic/TypeTraits.h"
 #include "llvm/Support/ErrorHandling.h"
 #include 
+#include 
 using namespace clang;
 
 static constexpr const char *TypeTraitNames[] = {
@@ -81,6 +82,15 @@ const char *clang::getTraitName(UnaryExprOrTypeTrait T) {
 
 const char *clang::getTraitSpelling(TypeTrait T) {
   assert(T <= TT_Last && "invalid enum value!");
+  if (T == BTT_IsDeducible) {
+// The __is_deducible is an internal-only type trait. To hide it from
+// external users, we define it with an empty spelling name, preventing the
+// clang parser from recognizing its token kind.
+// However, other components such as the AST dump still require the real
+// type trait name. Therefore, we return the real name when needed.
+assert(std::strlen(TypeTraitSpellings[T]) == 0);
+return "__is_deducible";
+  }
   return TypeTraitSpellings[T];
 }
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 34e12078a8c92..e4601f7d6c47d 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6143,7 +6143,15 @@ static bool EvaluateBinaryTypeTrait(Sema , 
TypeTrait BTT, const TypeSourceI
 
 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
   }
-default: llvm_unreachable("not a BTT");
+  case BTT_IsDeducible: {
+const auto *TSTToBeDeduced = cast(LhsT);
+sema::TemplateDeductionInfo Info(KeyLoc);
+return Self.DeduceTemplateArgumentsFromType(
+   TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
+   Info) == TemplateDeductionResult::Success;
+  }
+  default:
+llvm_unreachable("not a BTT");
   }
   llvm_unreachable("Unknown type trait or not 

[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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


@@ -2774,6 +2775,41 @@ Expr *transformRequireClause(Sema , 
FunctionTemplateDecl *FTD,
   return E.getAs();
 }
 
+// Build the associated constraints for the alias deduction guides.
+// C++ [over.match.class.deduct]p3.3:
+//   The associated constraints ([temp.constr.decl]) are the conjunction of the
+//   associated constraints of g and a constraint that is satisfied if and only
+//   if the arguments of A are deducible (see below) from the return type.
+Expr *
+buildAssociatedConstraints(Sema , TypeAliasTemplateDecl *AliasTemplate,
+   FunctionTemplateDecl *FTD,
+   llvm::ArrayRef TransformedArgs,
+   QualType ReturnType) {
+  auto  = SemaRef.Context;

hokein wrote:

Oops,  it looks like I forgot to push one commit.

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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

hokein wrote:

Thanks for the review.

> I'll approve that modulo nit but i think we want
> 
> * An issue to keep track of the duplication in 
> `FinishTemplateArgumentDeduction`

Filed #92224.

> * A follow up PR to improve diagnostics

Filed #92225, and assigned to myself. Will do it.

> Thanks!



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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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

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

>From 20947c1a34fae3593a98dba125e5d70d652c7190 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 19 Apr 2024 10:54:12 +0200
Subject: [PATCH 1/2] [clang] CTAD: implement the missing IsDeducible
 constraint for alias templates.

Fixes https://github.com/llvm/llvm-project/issues/85192
Fixes https://github.com/llvm/llvm-project/issues/84492

- rebase to main
- add release note for __is_deducible
- implement diagnostics for bad argument types for __is_deducible

Don't expose __is_deducible trait.

Refine the implementation of hiding __is_deducible type trait.

Apply approach 3.
---
 clang/include/clang/Basic/TokenKinds.def |  3 +
 clang/include/clang/Sema/Sema.h  |  9 ++
 clang/lib/Basic/TypeTraits.cpp   | 10 +++
 clang/lib/Sema/SemaExprCXX.cpp   | 10 ++-
 clang/lib/Sema/SemaTemplate.cpp  | 82 +--
 clang/lib/Sema/SemaTemplateDeduction.cpp | 86 
 clang/test/AST/ast-dump-ctad-alias.cpp   | 20 +++--
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 27 --
 clang/test/SemaTemplate/deduction-guide.cpp  | 16 ++--
 clang/www/cxx_status.html|  4 +-
 10 files changed, 238 insertions(+), 29 deletions(-)

diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index 56c4b17f769d7..b5a0e9df9f7ae 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -538,6 +538,9 @@ TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX)
 TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_constructs_from_temporary, 
ReferenceConstructsFromTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_converts_from_temporary, 
ReferenceConvertsFromTemporary, KEYCXX)
+// IsDeducible is only used internally by clang for CTAD implementation and
+// is not exposed to users.
+TYPE_TRAIT_2(/*EmptySpellingName*/, IsDeducible, KEYCXX)
 
 // Embarcadero Expression Traits
 EXPRESSION_TRAIT(__is_lvalue_expr, IsLValueExpr, KEYCXX)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 4efd3878e861b..8cee7ab2c7b4e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9597,6 +9597,15 @@ class Sema final : public SemaBase {
   ArrayRef TemplateArgs,
   sema::TemplateDeductionInfo );
 
+  /// Deduce the template arguments of the given template from \p FromType.
+  /// Used to implement the IsDeducible constraint for alias CTAD per C++
+  /// [over.match.class.deduct]p4.
+  ///
+  /// It only supports class or type alias templates.
+  TemplateDeductionResult
+  DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType,
+  sema::TemplateDeductionInfo );
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo ,
diff --git a/clang/lib/Basic/TypeTraits.cpp b/clang/lib/Basic/TypeTraits.cpp
index 4dbf678dc395b..8d6794223ccaf 100644
--- a/clang/lib/Basic/TypeTraits.cpp
+++ b/clang/lib/Basic/TypeTraits.cpp
@@ -13,6 +13,7 @@
 #include "clang/Basic/TypeTraits.h"
 #include "llvm/Support/ErrorHandling.h"
 #include 
+#include 
 using namespace clang;
 
 static constexpr const char *TypeTraitNames[] = {
@@ -81,6 +82,15 @@ const char *clang::getTraitName(UnaryExprOrTypeTrait T) {
 
 const char *clang::getTraitSpelling(TypeTrait T) {
   assert(T <= TT_Last && "invalid enum value!");
+  if (T == BTT_IsDeducible) {
+// The __is_deducible is an internal-only type trait. To hide it from
+// external users, we define it with an empty spelling name, preventing the
+// clang parser from recognizing its token kind.
+// However, other components such as the AST dump still require the real
+// type trait name. Therefore, we return the real name when needed.
+assert(std::strlen(TypeTraitSpellings[T]) == 0);
+return "__is_deducible";
+  }
   return TypeTraitSpellings[T];
 }
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index c181092113e1f..1cd912e3863d8 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6142,7 +6142,15 @@ static bool EvaluateBinaryTypeTrait(Sema , 
TypeTrait BTT, const TypeSourceI
 
 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
   }
-default: llvm_unreachable("not a BTT");
+  case BTT_IsDeducible: {
+const auto *TSTToBeDeduced = cast(LhsT);
+sema::TemplateDeductionInfo Info(KeyLoc);
+return Self.DeduceTemplateArgumentsFromType(
+   TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
+   Info) == TemplateDeductionResult::Success;
+  }
+  default:
+llvm_unreachable("not a BTT");
   }
   llvm_unreachable("Unknown type trait or not 

[clang] [clang-tools-extra] [Clang] Retain the angle loci for invented template parameters of constraints (PR #92104)

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

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

Thanks!

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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


@@ -2774,6 +2775,41 @@ Expr *transformRequireClause(Sema , 
FunctionTemplateDecl *FTD,
   return E.getAs();
 }
 
+// Build the associated constraints for the alias deduction guides.
+// C++ [over.match.class.deduct]p3.3:
+//   The associated constraints ([temp.constr.decl]) are the conjunction of the
+//   associated constraints of g and a constraint that is satisfied if and only
+//   if the arguments of A are deducible (see below) from the return type.
+Expr *
+buildAssociatedConstraints(Sema , TypeAliasTemplateDecl *AliasTemplate,
+   FunctionTemplateDecl *FTD,
+   llvm::ArrayRef TransformedArgs,
+   QualType ReturnType) {
+  auto  = SemaRef.Context;

hokein wrote:

Done.

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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


@@ -6116,6 +6116,17 @@ static bool EvaluateBinaryTypeTrait(Sema , 
TypeTrait BTT, const TypeSourceI
   tok::kw___is_pointer_interconvertible_base_of);
 
 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
+  }
+  case BTT_IsDeducible: {
+if (const auto *TSTToBeDeduced =
+LhsT->getAs()) {
+  sema::TemplateDeductionInfo Info(KeyLoc);
+  return Self.DeduceTemplateArgumentsFromType(
+ TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
+ Info) == TemplateDeductionResult::Success;
+}
+assert("Expect to see DeducedTemplateSpecializationType!");

hokein wrote:

Switched to `cast`.

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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


@@ -27,7 +27,8 @@ enum TypeTrait {
   ,
 #define TYPE_TRAIT_2(Spelling, Name, Key) BTT_##Name,
 #include "clang/Basic/TokenKinds.def"
-  BTT_Last = UTT_Last // BTT_Last == last BTT_XX in the enum.
+  BTT_Last = UTT_Last

hokein wrote:

Reverted the change.

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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


@@ -18,6 +18,7 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"

hokein wrote:

Done.

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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


@@ -190,13 +196,15 @@ template  struct Foo { Foo(T); };
 
 template using AFoo = Foo;
 template concept False = false;
-template using BFoo = AFoo;
+template
+using BFoo = AFoo; // expected-note {{candidate template ignored: 
constraints not satisfied [with V = int]}} \
+  // expected-note {{because '__is_deducible(BFoo, Foo)' evaluated to false}} \

hokein wrote:

I'd prefer to do it in a follow up (this patch is quite large already). Added a 
FIXME.

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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

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

>From 20947c1a34fae3593a98dba125e5d70d652c7190 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 19 Apr 2024 10:54:12 +0200
Subject: [PATCH] [clang] CTAD: implement the missing IsDeducible constraint
 for alias templates.

Fixes https://github.com/llvm/llvm-project/issues/85192
Fixes https://github.com/llvm/llvm-project/issues/84492

- rebase to main
- add release note for __is_deducible
- implement diagnostics for bad argument types for __is_deducible

Don't expose __is_deducible trait.

Refine the implementation of hiding __is_deducible type trait.

Apply approach 3.
---
 clang/include/clang/Basic/TokenKinds.def |  3 +
 clang/include/clang/Sema/Sema.h  |  9 ++
 clang/lib/Basic/TypeTraits.cpp   | 10 +++
 clang/lib/Sema/SemaExprCXX.cpp   | 10 ++-
 clang/lib/Sema/SemaTemplate.cpp  | 82 +--
 clang/lib/Sema/SemaTemplateDeduction.cpp | 86 
 clang/test/AST/ast-dump-ctad-alias.cpp   | 20 +++--
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 27 --
 clang/test/SemaTemplate/deduction-guide.cpp  | 16 ++--
 clang/www/cxx_status.html|  4 +-
 10 files changed, 238 insertions(+), 29 deletions(-)

diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index 56c4b17f769d7..b5a0e9df9f7ae 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -538,6 +538,9 @@ TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX)
 TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_constructs_from_temporary, 
ReferenceConstructsFromTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_converts_from_temporary, 
ReferenceConvertsFromTemporary, KEYCXX)
+// IsDeducible is only used internally by clang for CTAD implementation and
+// is not exposed to users.
+TYPE_TRAIT_2(/*EmptySpellingName*/, IsDeducible, KEYCXX)
 
 // Embarcadero Expression Traits
 EXPRESSION_TRAIT(__is_lvalue_expr, IsLValueExpr, KEYCXX)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 4efd3878e861b..8cee7ab2c7b4e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9597,6 +9597,15 @@ class Sema final : public SemaBase {
   ArrayRef TemplateArgs,
   sema::TemplateDeductionInfo );
 
+  /// Deduce the template arguments of the given template from \p FromType.
+  /// Used to implement the IsDeducible constraint for alias CTAD per C++
+  /// [over.match.class.deduct]p4.
+  ///
+  /// It only supports class or type alias templates.
+  TemplateDeductionResult
+  DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType,
+  sema::TemplateDeductionInfo );
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo ,
diff --git a/clang/lib/Basic/TypeTraits.cpp b/clang/lib/Basic/TypeTraits.cpp
index 4dbf678dc395b..8d6794223ccaf 100644
--- a/clang/lib/Basic/TypeTraits.cpp
+++ b/clang/lib/Basic/TypeTraits.cpp
@@ -13,6 +13,7 @@
 #include "clang/Basic/TypeTraits.h"
 #include "llvm/Support/ErrorHandling.h"
 #include 
+#include 
 using namespace clang;
 
 static constexpr const char *TypeTraitNames[] = {
@@ -81,6 +82,15 @@ const char *clang::getTraitName(UnaryExprOrTypeTrait T) {
 
 const char *clang::getTraitSpelling(TypeTrait T) {
   assert(T <= TT_Last && "invalid enum value!");
+  if (T == BTT_IsDeducible) {
+// The __is_deducible is an internal-only type trait. To hide it from
+// external users, we define it with an empty spelling name, preventing the
+// clang parser from recognizing its token kind.
+// However, other components such as the AST dump still require the real
+// type trait name. Therefore, we return the real name when needed.
+assert(std::strlen(TypeTraitSpellings[T]) == 0);
+return "__is_deducible";
+  }
   return TypeTraitSpellings[T];
 }
 
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index c181092113e1f..1cd912e3863d8 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6142,7 +6142,15 @@ static bool EvaluateBinaryTypeTrait(Sema , 
TypeTrait BTT, const TypeSourceI
 
 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
   }
-default: llvm_unreachable("not a BTT");
+  case BTT_IsDeducible: {
+const auto *TSTToBeDeduced = cast(LhsT);
+sema::TemplateDeductionInfo Info(KeyLoc);
+return Self.DeduceTemplateArgumentsFromType(
+   TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
+   Info) == TemplateDeductionResult::Success;
+  }
+  default:
+llvm_unreachable("not a BTT");
   }
   llvm_unreachable("Unknown type trait or not 

[clang] [clang] CTAD alias: fix the transformation for the require-clause expr (PR #90961)

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

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


[clang] [clang] CTAD alias: fix the transformation for the require-clause expr (PR #90961)

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

hokein wrote:

I'm merging it now (happy to address any post-comments).

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


[clang] [clang] CTAD alias: fix the transformation for the require-clause expr (PR #90961)

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

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

>From 0bdb18c0ffc37b38e81487b45e0e00e4480473aa Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 3 May 2024 11:04:21 +0200
Subject: [PATCH 1/2] [clang] CTAD alias: refine the transformation for the
 require-clause expr.

In the clang AST, constraint nodes are deliberately not instantiated unless they
are actively being evaluated. Consequently, occurrences of template parameters
in the require-clause expression have a subtle "depth" difference compared to
normal occurrences in place contexts, such as function parameters. When
transforming the require-clause, we must take this distinction into account.

The existing implementation overlooks this consideration. This patch is
to rewrite the implementation of the require-clause transformation to
address this issue.
---
 clang/lib/Sema/SemaTemplate.cpp  | 147 +--
 clang/test/AST/ast-dump-ctad-alias.cpp   |  40 +
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp |  68 +
 3 files changed, 242 insertions(+), 13 deletions(-)
 create mode 100644 clang/test/AST/ast-dump-ctad-alias.cpp

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 0e7bd8dd89573..88becbdba6449 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2758,31 +2758,151 @@ bool hasDeclaredDeductionGuides(DeclarationName Name, 
DeclContext *DC) {
   return false;
 }
 
+unsigned getTemplateParameterDepth(NamedDecl *TemplateParam) {
+  if (auto *TTP = dyn_cast(TemplateParam))
+return TTP->getDepth();
+  if (auto *TTP = dyn_cast(TemplateParam))
+return TTP->getDepth();
+  if (auto *NTTP = dyn_cast(TemplateParam))
+return NTTP->getDepth();
+  llvm_unreachable("Unhandled template parameter types");
+}
+
 NamedDecl *transformTemplateParameter(Sema , DeclContext *DC,
   NamedDecl *TemplateParam,
   MultiLevelTemplateArgumentList ,
-  unsigned NewIndex) {
+  unsigned NewIndex, unsigned NewDepth) {
   if (auto *TTP = dyn_cast(TemplateParam))
-return transformTemplateTypeParam(SemaRef, DC, TTP, Args, TTP->getDepth(),
+return transformTemplateTypeParam(SemaRef, DC, TTP, Args, NewDepth,
   NewIndex);
   if (auto *TTP = dyn_cast(TemplateParam))
 return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex,
-  TTP->getDepth());
+  NewDepth);
   if (auto *NTTP = dyn_cast(TemplateParam))
 return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex,
-  NTTP->getDepth());
+  NewDepth);
   llvm_unreachable("Unhandled template parameter types");
 }
 
-Expr *transformRequireClause(Sema , FunctionTemplateDecl *FTD,
- llvm::ArrayRef TransformedArgs) 
{
-  Expr *RC = FTD->getTemplateParameters()->getRequiresClause();
+// Transform the require-clause of F if any.
+// The return result is expected to be the require-clause for the synthesized
+// alias deduction guide.
+Expr *transformRequireClause(
+Sema , FunctionTemplateDecl *F,
+TypeAliasTemplateDecl *AliasTemplate,
+ArrayRef DeduceResults) {
+  Expr *RC = F->getTemplateParameters()->getRequiresClause();
   if (!RC)
 return nullptr;
+
+  auto  = SemaRef.Context;
+  LocalInstantiationScope Scope(SemaRef);
+
+  // In the clang AST, constraint nodes are deliberately not instantiated 
unless
+  // they are actively being evaluated. Consequently, occurrences of template
+  // parameters in the require-clause expression have a subtle "depth"
+  // difference compared to normal occurrences in places, such as function
+  // parameters. When transforming the require-clause, we must take this
+  // distinction into account:
+  //
+  //   1) In the transformed require-clause, occurrences of template parameters
+  //   must use the "uninstantiated" depth;
+  //   2) When substituting on the require-clause expr of the underlying
+  //   deduction guide, we must use the entire set of template argument lists;
+  //
+  // It's important to note that we're performing this transformation on an
+  // *instantiated* AliasTemplate.
+
+  // For 1), if the alias template is nested within a class template, we
+  // calcualte the 'uninstantiated' depth by adding the substitution level 
back.
+  unsigned AdjustDepth = 0;
+  if (auto *PrimaryTemplate = 
AliasTemplate->getInstantiatedFromMemberTemplate())
+AdjustDepth = PrimaryTemplate->getTemplateDepth();
+
+  // We rebuild all template parameters with the uninstantiated depth, and
+  // build template arguments refer to them.
+  SmallVector AdjustedAliasTemplateArgs;
+
+  for (auto *TP : *AliasTemplate->getTemplateParameters()) {
+// Rebuild any internal references to 

[clang] 2b38688 - Reland: [clang] Use getDefaultArgRange instead of getDefaultArg to retrieve

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

Author: Haojian Wu
Date: 2024-05-11T22:07:21+02:00
New Revision: 2b386888b78327db4906b12401e1a89438471548

URL: 
https://github.com/llvm/llvm-project/commit/2b386888b78327db4906b12401e1a89438471548
DIFF: 
https://github.com/llvm/llvm-project/commit/2b386888b78327db4906b12401e1a89438471548.diff

LOG: Reland: [clang] Use getDefaultArgRange instead of getDefaultArg to retrieve
source location in `ConvertConstructorToDeductionGuideTransform`.

The commit fec471649fffaa3ec44e17801e5c9605825e58bb was reverted by accident in 
7415524b45392651969374c067041daa82dc89e7.

Reland it with a testcase.

Added: 


Modified: 
clang/lib/Sema/SemaTemplate.cpp
clang/test/SemaTemplate/ctad.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 82badb2efb5cf..0e7bd8dd89573 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2679,7 +2679,7 @@ struct ConvertConstructorToDeductionGuideTransform {
   // placeholder to indicate there is a default argument.
   QualType ParamTy = NewDI->getType();
   NewDefArg = new (SemaRef.Context)
-  OpaqueValueExpr(OldParam->getDefaultArg()->getBeginLoc(),
+  OpaqueValueExpr(OldParam->getDefaultArgRange().getBegin(),
   ParamTy.getNonLValueExprType(SemaRef.Context),
   ParamTy->isLValueReferenceType()   ? VK_LValue
   : ParamTy->isRValueReferenceType() ? VK_XValue

diff  --git a/clang/test/SemaTemplate/ctad.cpp 
b/clang/test/SemaTemplate/ctad.cpp
index ec144d4f44ba8..e981ea8d5ecfb 100644
--- a/clang/test/SemaTemplate/ctad.cpp
+++ b/clang/test/SemaTemplate/ctad.cpp
@@ -54,3 +54,18 @@ template struct Y { Y(T); };
 template struct Y ;
 Y y(1);
 }
+
+namespace NoCrashOnGettingDefaultArgLoc {
+template 
+class A {
+  A(int = 1); // expected-note {{candidate template ignored: couldn't infer 
template argumen}}
+};
+class C : A {
+  using A::A;
+};
+template 
+class D : C { // expected-note {{candidate function template not viable: 
requires 1 argument}}
+  using C::C;
+};
+D abc; // expected-error {{no viable constructor or deduction guide}}
+}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] CTAD alias: fix the transformation for the require-clause expr (PR #90961)

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

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

>From 9cc438e2def2fa98af71ba79eb82e033f3d5905a Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 3 May 2024 11:04:21 +0200
Subject: [PATCH] [clang] CTAD alias: refine the transformation for the
 require-clause expr.

In the clang AST, constraint nodes are deliberately not instantiated unless they
are actively being evaluated. Consequently, occurrences of template parameters
in the require-clause expression have a subtle "depth" difference compared to
normal occurrences in place contexts, such as function parameters. When
transforming the require-clause, we must take this distinction into account.

The existing implementation overlooks this consideration. This patch is
to rewrite the implementation of the require-clause transformation to
address this issue.
---
 clang/lib/Sema/SemaTemplate.cpp  | 147 +--
 clang/test/AST/ast-dump-ctad-alias.cpp   |  40 +
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp |  68 +
 3 files changed, 242 insertions(+), 13 deletions(-)
 create mode 100644 clang/test/AST/ast-dump-ctad-alias.cpp

diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 480c0103ae335..1b0b8542164d6 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2758,31 +2758,151 @@ bool hasDeclaredDeductionGuides(DeclarationName Name, 
DeclContext *DC) {
   return false;
 }
 
+unsigned getTemplateParameterDepth(NamedDecl *TemplateParam) {
+  if (auto *TTP = dyn_cast(TemplateParam))
+return TTP->getDepth();
+  if (auto *TTP = dyn_cast(TemplateParam))
+return TTP->getDepth();
+  if (auto *NTTP = dyn_cast(TemplateParam))
+return NTTP->getDepth();
+  llvm_unreachable("Unhandled template parameter types");
+}
+
 NamedDecl *transformTemplateParameter(Sema , DeclContext *DC,
   NamedDecl *TemplateParam,
   MultiLevelTemplateArgumentList ,
-  unsigned NewIndex) {
+  unsigned NewIndex, unsigned NewDepth) {
   if (auto *TTP = dyn_cast(TemplateParam))
-return transformTemplateTypeParam(SemaRef, DC, TTP, Args, TTP->getDepth(),
+return transformTemplateTypeParam(SemaRef, DC, TTP, Args, NewDepth,
   NewIndex);
   if (auto *TTP = dyn_cast(TemplateParam))
 return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex,
-  TTP->getDepth());
+  NewDepth);
   if (auto *NTTP = dyn_cast(TemplateParam))
 return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex,
-  NTTP->getDepth());
+  NewDepth);
   llvm_unreachable("Unhandled template parameter types");
 }
 
-Expr *transformRequireClause(Sema , FunctionTemplateDecl *FTD,
- llvm::ArrayRef TransformedArgs) 
{
-  Expr *RC = FTD->getTemplateParameters()->getRequiresClause();
+// Transform the require-clause of F if any.
+// The return result is expected to be the require-clause for the synthesized
+// alias deduction guide.
+Expr *transformRequireClause(
+Sema , FunctionTemplateDecl *F,
+TypeAliasTemplateDecl *AliasTemplate,
+ArrayRef DeduceResults) {
+  Expr *RC = F->getTemplateParameters()->getRequiresClause();
   if (!RC)
 return nullptr;
+
+  auto  = SemaRef.Context;
+  LocalInstantiationScope Scope(SemaRef);
+
+  // In the clang AST, constraint nodes are deliberately not instantiated 
unless
+  // they are actively being evaluated. Consequently, occurrences of template
+  // parameters in the require-clause expression have a subtle "depth"
+  // difference compared to normal occurrences in places, such as function
+  // parameters. When transforming the require-clause, we must take this
+  // distinction into account:
+  //
+  //   1) In the transformed require-clause, occurrences of template parameters
+  //   must use the "uninstantiated" depth;
+  //   2) When substituting on the require-clause expr of the underlying
+  //   deduction guide, we must use the entire set of template argument lists;
+  //
+  // It's important to note that we're performing this transformation on an
+  // *instantiated* AliasTemplate.
+
+  // For 1), if the alias template is nested within a class template, we
+  // calcualte the 'uninstantiated' depth by adding the substitution level 
back.
+  unsigned AdjustDepth = 0;
+  if (auto *PrimaryTemplate = 
AliasTemplate->getInstantiatedFromMemberTemplate())
+AdjustDepth = PrimaryTemplate->getTemplateDepth();
+
+  // We rebuild all template parameters with the uninstantiated depth, and
+  // build template arguments refer to them.
+  SmallVector AdjustedAliasTemplateArgs;
+
+  for (auto *TP : *AliasTemplate->getTemplateParameters()) {
+// Rebuild any internal references to earlier 

[clang] [clang] CTAD alias: fix the transformation for the require-clause expr (PR #90961)

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

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


[clang] [llvm] [AST] Print the separator "," for template arguments in ConceptReference::print (PR #91750)

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

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


[clang] [llvm] [AST] Print the separator "," for template arguments in ConceptReference::print (PR #91750)

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


@@ -24,6 +24,7 @@ add_clang_unittest(ASTTests
   CommentLexer.cpp
   CommentParser.cpp
   CommentTextTest.cpp
+  ConceptPrinterTest.cpp

hokein wrote:

Done (we're not required to update gn build files, and there's a bot that can 
automate the porting).

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


[clang] [llvm] [AST] Print the separator "," for template arguments in ConceptReference::print (PR #91750)

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


@@ -106,9 +106,15 @@ void ConceptReference::print(llvm::raw_ostream ,
   ConceptName.printName(OS, Policy);
   if (hasExplicitTemplateArgs()) {
 OS << "<";
+bool First = true;
 // FIXME: Find corresponding parameter for argument
-for (auto  : ArgsAsWritten->arguments())
+for (auto  : ArgsAsWritten->arguments()) {
+  if (First)
+First = false;
+  else
+OS << ", ";

hokein wrote:

Thanks! I wasn't aware we have such a helpful utility.

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


[clang] [llvm] [AST] Print the separator "," for template arguments in ConceptReference::print (PR #91750)

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

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

>From e7b23e02e9b4c98d9e24dd1debcdefada7a16004 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 10 May 2024 16:31:20 +0200
Subject: [PATCH 1/2] [AST] Print the separator , for template arguments in
 ConceptReference::print

---
 clang/lib/AST/ASTConcept.cpp   |  8 ++-
 clang/unittests/AST/CMakeLists.txt |  1 +
 clang/unittests/AST/ConceptPrinterTest.cpp | 57 ++
 3 files changed, 65 insertions(+), 1 deletion(-)
 create mode 100644 clang/unittests/AST/ConceptPrinterTest.cpp

diff --git a/clang/lib/AST/ASTConcept.cpp b/clang/lib/AST/ASTConcept.cpp
index b3ec99448b3e1..6bef68fc87eea 100644
--- a/clang/lib/AST/ASTConcept.cpp
+++ b/clang/lib/AST/ASTConcept.cpp
@@ -106,9 +106,15 @@ void ConceptReference::print(llvm::raw_ostream ,
   ConceptName.printName(OS, Policy);
   if (hasExplicitTemplateArgs()) {
 OS << "<";
+bool First = true;
 // FIXME: Find corresponding parameter for argument
-for (auto  : ArgsAsWritten->arguments())
+for (auto  : ArgsAsWritten->arguments()) {
+  if (First)
+First = false;
+  else
+OS << ", ";
   ArgLoc.getArgument().print(Policy, OS, /*IncludeType*/ false);
+}
 OS << ">";
   }
 }
diff --git a/clang/unittests/AST/CMakeLists.txt 
b/clang/unittests/AST/CMakeLists.txt
index 54765e36db008..29d2b39cff8b1 100644
--- a/clang/unittests/AST/CMakeLists.txt
+++ b/clang/unittests/AST/CMakeLists.txt
@@ -24,6 +24,7 @@ add_clang_unittest(ASTTests
   CommentLexer.cpp
   CommentParser.cpp
   CommentTextTest.cpp
+  ConceptPrinterTest.cpp
   DataCollectionTest.cpp
   DeclPrinterTest.cpp
   DeclTest.cpp
diff --git a/clang/unittests/AST/ConceptPrinterTest.cpp 
b/clang/unittests/AST/ConceptPrinterTest.cpp
new file mode 100644
index 0..bd1f6bbfa5658
--- /dev/null
+++ b/clang/unittests/AST/ConceptPrinterTest.cpp
@@ -0,0 +1,57 @@
+//===- unittests/AST/ConceptPrinterTest.cpp --- Concept printer tests 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "ASTPrint.h"
+#include "clang/AST/ASTConcept.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ExprConcepts.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallString.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace ast_matchers;
+using namespace tooling;
+
+namespace {
+
+static void PrintConceptReference(raw_ostream , const ASTContext *Context,
+  const ConceptSpecializationExpr *T,
+  PrintingPolicyAdjuster PolicyAdjuster) {
+  assert(T && T->getConceptReference() &&
+ "Expected non-null concept reference");
+
+  PrintingPolicy Policy = Context->getPrintingPolicy();
+  if (PolicyAdjuster)
+PolicyAdjuster(Policy);
+  T->getConceptReference()->print(Out, Policy);
+}
+
+::testing::AssertionResult
+PrintedConceptMatches(StringRef Code, const std::vector ,
+  const StatementMatcher ,
+  StringRef ExpectedPrinted) {
+  return PrintedNodeMatches(
+  Code, Args, NodeMatch, ExpectedPrinted, "", PrintConceptReference);
+}
+const internal::VariadicDynCastAllOfMatcher
+conceptSpecializationExpr;
+} // unnamed namespace
+
+TEST(ConceptPrinter, ConceptReference) {
+  std::string Code = R"cpp(
+template  concept D = true;
+template
+requires D
+void g(T);
+  )cpp";
+  auto Matcher = conceptSpecializationExpr().bind("id");
+
+  ASSERT_TRUE(PrintedConceptMatches(Code, {"-std=c++20"}, Matcher, "D"));
+}

>From 251fd97fbf87d0c0fbe35f646058d3f9534c05a7 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 10 May 2024 17:40:55 +0200
Subject: [PATCH 2/2] address review comments.

---
 clang/lib/AST/ASTConcept.cpp | 8 +++-
 llvm/utils/gn/secondary/clang/unittests/AST/BUILD.gn | 1 +
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/clang/lib/AST/ASTConcept.cpp b/clang/lib/AST/ASTConcept.cpp
index 6bef68fc87eea..0387fc9f6aec2 100644
--- a/clang/lib/AST/ASTConcept.cpp
+++ b/clang/lib/AST/ASTConcept.cpp
@@ -15,6 +15,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/PrettyPrinter.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringExtras.h"
 
 using namespace clang;
 
@@ -106,13 +107,10 @@ void ConceptReference::print(llvm::raw_ostream ,
   ConceptName.printName(OS, Policy);
   if (hasExplicitTemplateArgs()) {
 OS << "<";
-bool First = true;
+llvm::ListSeparator Sep(", ");
 // FIXME: Find corresponding parameter for argument
 for (auto  : ArgsAsWritten->arguments()) {
-  if (First)
-First = false;
-  else
-

[clang] [AST] Print the separator "," for template arguments in ConceptReference::print (PR #91750)

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

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

None

>From e7b23e02e9b4c98d9e24dd1debcdefada7a16004 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 10 May 2024 16:31:20 +0200
Subject: [PATCH] [AST] Print the separator , for template arguments in
 ConceptReference::print

---
 clang/lib/AST/ASTConcept.cpp   |  8 ++-
 clang/unittests/AST/CMakeLists.txt |  1 +
 clang/unittests/AST/ConceptPrinterTest.cpp | 57 ++
 3 files changed, 65 insertions(+), 1 deletion(-)
 create mode 100644 clang/unittests/AST/ConceptPrinterTest.cpp

diff --git a/clang/lib/AST/ASTConcept.cpp b/clang/lib/AST/ASTConcept.cpp
index b3ec99448b3e1..6bef68fc87eea 100644
--- a/clang/lib/AST/ASTConcept.cpp
+++ b/clang/lib/AST/ASTConcept.cpp
@@ -106,9 +106,15 @@ void ConceptReference::print(llvm::raw_ostream ,
   ConceptName.printName(OS, Policy);
   if (hasExplicitTemplateArgs()) {
 OS << "<";
+bool First = true;
 // FIXME: Find corresponding parameter for argument
-for (auto  : ArgsAsWritten->arguments())
+for (auto  : ArgsAsWritten->arguments()) {
+  if (First)
+First = false;
+  else
+OS << ", ";
   ArgLoc.getArgument().print(Policy, OS, /*IncludeType*/ false);
+}
 OS << ">";
   }
 }
diff --git a/clang/unittests/AST/CMakeLists.txt 
b/clang/unittests/AST/CMakeLists.txt
index 54765e36db008..29d2b39cff8b1 100644
--- a/clang/unittests/AST/CMakeLists.txt
+++ b/clang/unittests/AST/CMakeLists.txt
@@ -24,6 +24,7 @@ add_clang_unittest(ASTTests
   CommentLexer.cpp
   CommentParser.cpp
   CommentTextTest.cpp
+  ConceptPrinterTest.cpp
   DataCollectionTest.cpp
   DeclPrinterTest.cpp
   DeclTest.cpp
diff --git a/clang/unittests/AST/ConceptPrinterTest.cpp 
b/clang/unittests/AST/ConceptPrinterTest.cpp
new file mode 100644
index 0..bd1f6bbfa5658
--- /dev/null
+++ b/clang/unittests/AST/ConceptPrinterTest.cpp
@@ -0,0 +1,57 @@
+//===- unittests/AST/ConceptPrinterTest.cpp --- Concept printer tests 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "ASTPrint.h"
+#include "clang/AST/ASTConcept.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ExprConcepts.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallString.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace ast_matchers;
+using namespace tooling;
+
+namespace {
+
+static void PrintConceptReference(raw_ostream , const ASTContext *Context,
+  const ConceptSpecializationExpr *T,
+  PrintingPolicyAdjuster PolicyAdjuster) {
+  assert(T && T->getConceptReference() &&
+ "Expected non-null concept reference");
+
+  PrintingPolicy Policy = Context->getPrintingPolicy();
+  if (PolicyAdjuster)
+PolicyAdjuster(Policy);
+  T->getConceptReference()->print(Out, Policy);
+}
+
+::testing::AssertionResult
+PrintedConceptMatches(StringRef Code, const std::vector ,
+  const StatementMatcher ,
+  StringRef ExpectedPrinted) {
+  return PrintedNodeMatches(
+  Code, Args, NodeMatch, ExpectedPrinted, "", PrintConceptReference);
+}
+const internal::VariadicDynCastAllOfMatcher
+conceptSpecializationExpr;
+} // unnamed namespace
+
+TEST(ConceptPrinter, ConceptReference) {
+  std::string Code = R"cpp(
+template  concept D = true;
+template
+requires D
+void g(T);
+  )cpp";
+  auto Matcher = conceptSpecializationExpr().bind("id");
+
+  ASSERT_TRUE(PrintedConceptMatches(Code, {"-std=c++20"}, Matcher, "D"));
+}

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Revise the transformation of CTAD parameters of nested class templates (PR #91628)

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


@@ -2583,11 +2580,27 @@ struct ConvertConstructorToDeductionGuideTransform {
 
 //-- The types of the function parameters are those of the constructor.
 for (auto *OldParam : TL.getParams()) {
-  ParmVarDecl *NewParam =
-  transformFunctionTypeParam(OldParam, Args, MaterializedTypedefs);
-  if (NestedPattern && NewParam)
+  ParmVarDecl *NewParam = OldParam;
+  // Given
+  //   template  struct C {
+  // template  struct D {
+  //   template  D(U, V);
+  // };
+  //   };
+  // First, transform all the references to template parameters that are
+  // defined outside of the surrounding class template. That is T in the
+  // above example.
+  if (NestedPattern) {
 NewParam = transformFunctionTypeParam(NewParam, OuterInstantiationArgs,
   MaterializedTypedefs);
+if (!NewParam)
+  return QualType();
+  }
+  // Then, transform all the references to template parameters that are
+  // defined at the class template and the constructor. In this example,
+  // they're U and V, respectively.
+  NewParam =
+  transformFunctionTypeParam(NewParam, Args, MaterializedTypedefs);

hokein wrote:

We have the same pattern on Line 2438-2452 in this file, where we perform a 
substitution of `OuterInstantiationArgs` on a new transformed parameter decl, I 
think we should probably fix it as well.

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


[clang] [Clang][Sema] Revise the transformation of CTAD parameters of nested class templates (PR #91628)

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


@@ -84,3 +84,17 @@ nested_init_list::concept_fail nil_invalid{1, ""};
 // expected-note@#INIT_LIST_INNER_INVALID {{candidate template ignored: 
substitution failure [with F = const char *]: constraints not satisfied for 
class template 'concept_fail' [with F = const char *]}}
 // expected-note@#INIT_LIST_INNER_INVALID {{candidate function template not 
viable: requires 1 argument, but 2 were provided}}
 // expected-note@#INIT_LIST_INNER_INVALID {{candidate function template not 
viable: requires 0 arguments, but 2 were provided}}
+
+namespace PR88142 {

hokein wrote:

nit: PR => GH

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


[clang] [Clang][Sema] Revise the transformation of CTAD parameters of nested class templates (PR #91628)

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

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


[clang] [Clang][Sema] Revise the transformation of CTAD parameters of nested class templates (PR #91628)

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

https://github.com/hokein commented:

The fix looks good to me, and thanks for the comprehensive explanation in the 
description.

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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

https://github.com/hokein commented:

Replied some review comments. I haven't updated the code yet (plan to do it 
after #90961)

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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


@@ -3307,6 +3341,58 @@ 
Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial,
   return ::DeduceTemplateArguments(*this, Partial, TemplateArgs, Info);
 }
 
+TemplateDeductionResult
+Sema::DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType,

hokein wrote:

This function is public (the documentation and comments are in `Sema.h` header).

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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


@@ -190,13 +196,15 @@ template  struct Foo { Foo(T); };
 
 template using AFoo = Foo;
 template concept False = false;
-template using BFoo = AFoo;
+template
+using BFoo = AFoo; // expected-note {{candidate template ignored: 
constraints not satisfied [with V = int]}} \
+  // expected-note {{because '__is_deducible(BFoo, Foo)' evaluated to false}} \

hokein wrote:

Do you think this is a blocker for landing this PR?  The current state is 
acceptable to me, although not ideal. I plan to send out a follow-up patch to 
address it.

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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


@@ -27,7 +27,8 @@ enum TypeTrait {
   ,
 #define TYPE_TRAIT_2(Spelling, Name, Key) BTT_##Name,
 #include "clang/Basic/TokenKinds.def"
-  BTT_Last = UTT_Last // BTT_Last == last BTT_XX in the enum.
+  BTT_Last = UTT_Last

hokein wrote:

oops, this is not intended. This was left when I reverted some changes.

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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


@@ -3239,6 +3239,40 @@ static TemplateDeductionResult 
FinishTemplateArgumentDeduction(
 
   return TemplateDeductionResult::Success;
 }
+/// Complete template argument deduction for DeduceTemplateArgumentsFromType.
+/// FIXME: this is mostly duplicated with the above two versions. Deduplicate
+/// the three implementations.

hokein wrote:

It is in my TODO list, but its priority is currently low, so I don't anticipate 
addressing it in the near future. This seems like a good candidate for a 
"GoodFirst" issue, so I'm thinking we can file an issue in case someone wants 
to contribute.

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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

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


[clang] [AST] RecursiveASTVisitor: Don't traverse the alias deduction guides in the default mode. (PR #91454)

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

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

By default (`shouldVisitImplicitCode()` returns `false`), RAV should not 
traverse AST nodes that are not spelled in the source code. Deduction guides 
for alias templates are always synthesized, so they should not be traversed.

This is usually done by checking the implicit bit of the Decl. However, this 
doesn't work deduction guides that are synthesized from explicit user-defined 
deduction guides, as we must maintain the explicit bit to ensure correct 
overload resolution.

>From e560fe2bf2d4bdc07a71682aa4d3a4bee8730b80 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Wed, 8 May 2024 12:11:10 +0200
Subject: [PATCH] [AST] RecursiveASTVisitor: Don't traverse the alias deduction
 guides in default mode.

---
 clang/include/clang/AST/RecursiveASTVisitor.h | 28 --
 .../DeductionGuide.cpp| 89 +++
 2 files changed, 110 insertions(+), 7 deletions(-)
 create mode 100644 
clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp

diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h 
b/clang/include/clang/AST/RecursiveASTVisitor.h
index f9b145b4e86a5..2517189c95300 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -736,13 +736,27 @@ bool RecursiveASTVisitor::TraverseDecl(Decl *D) {
 
   // As a syntax visitor, by default we want to ignore declarations for
   // implicit declarations (ones not typed explicitly by the user).
-  if (!getDerived().shouldVisitImplicitCode() && D->isImplicit()) {
-// For an implicit template type parameter, its type constraints are not
-// implicit and are not represented anywhere else. We still need to visit
-// them.
-if (auto *TTPD = dyn_cast(D))
-  return TraverseTemplateTypeParamDeclConstraints(TTPD);
-return true;
+  if (!getDerived().shouldVisitImplicitCode()) {
+if (D->isImplicit()) {
+  // For an implicit template type parameter, its type constraints are not
+  // implicit and are not represented anywhere else. We still need to visit
+  // them.
+  if (auto *TTPD = dyn_cast(D))
+return TraverseTemplateTypeParamDeclConstraints(TTPD);
+  return true;
+}
+
+// Deduction guides for alias templates are always synthesized, so they
+// should not be traversed unless shouldVisitImplicitCode() returns true.
+//
+// It's important to note that checking the implicit bit is not efficient
+// for the alias case. For deduction guides synthesized from explicit
+// user-defined deduction guides, we must maintain the explicit bit to
+// ensure correct overload resolution.
+if (auto *FTD = dyn_cast(D))
+  if (llvm::isa_and_present(
+  FTD->getDeclName().getCXXDeductionGuideTemplate()))
+return true;
   }
 
   switch (D->getKind()) {
diff --git 
a/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp 
b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp
new file mode 100644
index 0..abfdbaea4a615
--- /dev/null
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp
@@ -0,0 +1,89 @@
+//===- unittest/Tooling/RecursiveASTVisitorTests/DeductionGuide.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "TestVisitor.h"
+#include 
+
+using namespace clang;
+
+namespace {
+
+class DeductionGuideVisitor
+: public ExpectedLocationVisitor {
+public:
+  DeductionGuideVisitor(bool ShouldVisitImplicitCode)
+  : ShouldVisitImplicitCode(ShouldVisitImplicitCode) {}
+  bool VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
+std::string Storage;
+llvm::raw_string_ostream Stream(Storage);
+D->print(Stream);
+Match(Stream.str(),D->getLocation());
+return true;
+  }
+
+  bool shouldVisitTemplateInstantiations() const {
+return false;
+  }
+
+  bool shouldVisitImplicitCode() const {
+return ShouldVisitImplicitCode;
+  }
+  bool ShouldVisitImplicitCode;
+};
+
+TEST(RecursiveASTVisitor, DeductionGuideNonImplicitMode) {
+  DeductionGuideVisitor Visitor(/*ShouldVisitImplicitCode*/ false);
+  // Verify that the synthezied deduction guide for alias is not visited in
+  // RAV's implicit mode.
+  Visitor.ExpectMatch("Foo(T) -> Foo", 11, 1);
+  Visitor.DisallowMatch("Bar(type-parameter-0-0) -> Foo", 14, 1);
+  EXPECT_TRUE(Visitor.runOver(
+R"cpp(
+template 
+concept False = true;
+
+template  
+struct Foo { 
+  Foo(T);
+};
+
+template requires False
+Foo(T) -> Foo;
+
+template 
+using Bar = Foo;
+Bar s(1); 
+   )cpp"
+  , DeductionGuideVisitor::Lang_CXX2a));
+}
+
+TEST(RecursiveASTVisitor, DeductionGuideImplicitMode) {
+  

[clang] [Coro] Relax a debug-info test (PR #91401)

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

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


https://github.com/llvm/llvm-project/pull/91401
___
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: implement the missing IsDeducible constraint for alias templates (PR #89358)

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

hokein wrote:

> > I agree with you -- having a well-described diagnostic message is better 
> > and clearer. I'm happy to improve it once we settle on the final 
> > implementation approach (the current diagnostic because 
> > '__is_deducible(AFoo, Foo)' evaluated to false seems okay to me. GCC also 
> > emits similar diagnostics).
> 
> Well, if we agree on that, the only thing to do for approach 3 is to deal 
> with "anonymous" traits in ast dump and similar, which seems to be a fairly 
> bounded effort!

I was worried about the potential need to handle these issues in various 
places. However, thinking more about it today, I think we can address them 
locally in the `getTraitSpelling`, which seems like a more favorable approach.

I've now updated the patch to implement approach 3. Please take a look. Note 
that I haven't addressed the diagnostic improvement part yet; I plan to handle 
that in a separate follow-up patch.



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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

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

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

>From bf6acda6c7cb9a08b82b149c0df38d90e395f9e1 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 19 Apr 2024 10:54:12 +0200
Subject: [PATCH 1/4] [clang] CTAD: implement the missing IsDeducible
 constraint for alias templates.

Fixes https://github.com/llvm/llvm-project/issues/85192
Fixes https://github.com/llvm/llvm-project/issues/84492
---
 clang/include/clang/Basic/TokenKinds.def  |  1 +
 clang/include/clang/Sema/Sema.h   |  9 ++
 clang/lib/Parse/ParseExprCXX.cpp  | 16 ++--
 clang/lib/Sema/SemaExprCXX.cpp| 11 +++
 clang/lib/Sema/SemaTemplate.cpp   | 70 ---
 clang/lib/Sema/SemaTemplateDeduction.cpp  | 87 +++
 clang/test/SemaCXX/cxx20-ctad-type-alias.cpp  | 26 --
 .../test/SemaCXX/type-traits-is-deducible.cpp | 47 ++
 clang/www/cxx_status.html |  8 +-
 9 files changed, 243 insertions(+), 32 deletions(-)
 create mode 100644 clang/test/SemaCXX/type-traits-is-deducible.cpp

diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index a27fbed358a60..74102f4053968 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -537,6 +537,7 @@ TYPE_TRAIT_1(__is_referenceable, IsReferenceable, KEYCXX)
 TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX)
 TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
 TYPE_TRAIT_2(__reference_constructs_from_temporary, 
ReferenceConstructsFromTemporary, KEYCXX)
+TYPE_TRAIT_2(__is_deducible, IsDeducible, KEYCXX)
 
 // Embarcadero Expression Traits
 EXPRESSION_TRAIT(__is_lvalue_expr, IsLValueExpr, KEYCXX)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index a80ac6dbc7613..6f9a31bbbaf60 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9597,6 +9597,15 @@ class Sema final : public SemaBase {
   ArrayRef TemplateArgs,
   sema::TemplateDeductionInfo );
 
+  /// Deduce the template arguments of the given template from \p FromType.
+  /// Used to implement the IsDeducible constraint for alias CTAD per C++
+  /// [over.match.class.deduct]p4.
+  ///
+  /// It only supports class or type alias templates.
+  TemplateDeductionResult
+  DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType,
+  sema::TemplateDeductionInfo );
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo ,
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 0d2ad980696fc..af4e205eeff80 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -3906,14 +3906,18 @@ ExprResult Parser::ParseTypeTrait() {
   BalancedDelimiterTracker Parens(*this, tok::l_paren);
   if (Parens.expectAndConsume())
 return ExprError();
-
+  TypeTrait TTKind = TypeTraitFromTokKind(Kind);
   SmallVector Args;
   do {
 // Parse the next type.
-TypeResult Ty = ParseTypeName(/*SourceRange=*/nullptr,
-  getLangOpts().CPlusPlus
-  ? DeclaratorContext::TemplateTypeArg
-  : DeclaratorContext::TypeName);
+TypeResult Ty = ParseTypeName(
+/*SourceRange=*/nullptr,
+getLangOpts().CPlusPlus
+// For __is_deducible type trait, the first argument is a template
+// specification type without template argument lists.
+? (TTKind == BTT_IsDeducible ? DeclaratorContext::TemplateArg
+ : DeclaratorContext::TemplateTypeArg)
+: DeclaratorContext::TypeName);
 if (Ty.isInvalid()) {
   Parens.skipToEnd();
   return ExprError();
@@ -3937,7 +3941,7 @@ ExprResult Parser::ParseTypeTrait() {
 
   SourceLocation EndLoc = Parens.getCloseLocation();
 
-  return Actions.ActOnTypeTrait(TypeTraitFromTokKind(Kind), Loc, Args, EndLoc);
+  return Actions.ActOnTypeTrait(TTKind, Loc, Args, EndLoc);
 }
 
 /// ParseArrayTypeTrait - Parse the built-in array type-trait
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index c1cb03e4ec7ae..222e8babdfaaa 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6116,6 +6116,17 @@ static bool EvaluateBinaryTypeTrait(Sema , 
TypeTrait BTT, const TypeSourceI
   tok::kw___is_pointer_interconvertible_base_of);
 
 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
+  }
+  case BTT_IsDeducible: {
+if (const auto *TSTToBeDeduced =
+LhsT->getAs()) {
+  sema::TemplateDeductionInfo Info(KeyLoc);
+  return Self.DeduceTemplateArgumentsFromType(
+ 

[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-tools-extra] [clang] Don't preserve the typo expr in the recovery expr for invalid VarDecls (PR #90948)

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

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


[clang] [clang-tools-extra] [clang] Don't preserve the typo expr in the recovery expr for invalid VarDecls (PR #90948)

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

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


[clang] [clang-tools-extra] [clang] Don't preserve the typo expr in the recovery expr for invalid VarDecls (PR #90948)

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


@@ -13530,9 +13530,12 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr 
*Init, bool DirectInit) {
   }
 
   if (VDecl->isInvalidDecl()) {
-CorrectDelayedTyposInExpr(Init, VDecl);
+ExprResult Res = CorrectDelayedTyposInExpr(Init, VDecl);
+std::vector SubExprs;

hokein wrote:

Switched to `SmallVector`.

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


[clang] [clang-tools-extra] [clang] Don't preserve the typo expr in the recovery expr for invalid VarDecls (PR #90948)

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

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

>From 2f29011bae5bf1b285c2ab1700c887d74eaec4b0 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 3 May 2024 10:06:39 +0200
Subject: [PATCH 1/2] [clang] Don't preserve the typo expr in the recovery expr
 for invalid VarDecls.

With the commit d5308949cf884d8e4b971d51a8b4f73584c4adec, we now
preserve the initializer for invalid decls with the recovery-expr.

However there is a chance that the original init expr is a typo-expr, we
should not preserve it in the final AST, as typo-expr is an internal AST
nodes. We should use the one after the typo correction.

This is spotted by a clangd hover crash on the testcase.
---
 clang-tools-extra/clangd/unittests/HoverTests.cpp | 13 +
 clang/lib/Sema/SemaDecl.cpp   |  7 +--
 clang/test/AST/ast-dump-recovery.cpp  |  5 +
 3 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp 
b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 5ead74748f550c..28df24f34827c0 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -965,6 +965,19 @@ class Foo final {})cpp";
  // Bindings are in theory public members of an anonymous struct.
  HI.AccessSpecifier = "public";
}},
+  {// Don't crash on invalid decl with invalid init expr.
+   R"cpp(
+  Unknown [[^abc]] = invalid;
+  // error-ok
+  )cpp",
+   [](HoverInfo ) {
+ HI.Name = "abc";
+ HI.Kind = index::SymbolKind::Variable;
+ HI.NamespaceScope = "";
+ HI.Definition = "int abc = ()";
+ HI.Type = "int";
+ HI.AccessSpecifier = "public";
+   }},
   {// Extra info for function call.
R"cpp(
   void fun(int arg_a, int _b) {};
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 19968452f0d566..169df60b56bb4b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -13530,9 +13530,12 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr 
*Init, bool DirectInit) {
   }
 
   if (VDecl->isInvalidDecl()) {
-CorrectDelayedTyposInExpr(Init, VDecl);
+ExprResult Res = CorrectDelayedTyposInExpr(Init, VDecl);
+std::vector SubExprs;
+if (Res.isUsable())
+  SubExprs.push_back(Res.get());
 ExprResult Recovery =
-CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), {Init});
+CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), SubExprs);
 if (Expr *E = Recovery.get())
   VDecl->setInit(E);
 return;
diff --git a/clang/test/AST/ast-dump-recovery.cpp 
b/clang/test/AST/ast-dump-recovery.cpp
index 77527743fe8577..a88dff471d9f04 100644
--- a/clang/test/AST/ast-dump-recovery.cpp
+++ b/clang/test/AST/ast-dump-recovery.cpp
@@ -419,6 +419,11 @@ void InitializerOfInvalidDecl() {
   // CHECK:  VarDecl {{.*}} invalid InvalidDecl
   // CHECK-NEXT: `-RecoveryExpr {{.*}} '' contains-errors
   // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'ValidDecl'
+
+  Unknown InvalidDeclWithInvalidInit = Invalid;
+  // CHECK:  VarDecl {{.*}} invalid InvalidDeclWithInvalidInit
+  // CHECK-NEXT: `-RecoveryExpr {{.*}} '' contains-errors
+  // CHECK-NOT:`-TypoExpr
 }
 
 void RecoverToAnInvalidDecl() {

>From 06c30958b7bb2c664440e47bd2257e068f72c2b1 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Mon, 6 May 2024 20:16:05 +0200
Subject: [PATCH 2/2] address review comments.

---
 clang/lib/Sema/SemaDecl.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 169df60b56bb4b..590f37837eb2df 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -13531,7 +13531,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr 
*Init, bool DirectInit) {
 
   if (VDecl->isInvalidDecl()) {
 ExprResult Res = CorrectDelayedTyposInExpr(Init, VDecl);
-std::vector SubExprs;
+SmallVector SubExprs;
 if (Res.isUsable())
   SubExprs.push_back(Res.get());
 ExprResult Recovery =

___
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 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-tools-extra] [clang] Don't preserve the typo expr in the recovery expr for invalid VarDecls (PR #90948)

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

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

With the commit d5308949cf884d8e4b971d51a8b4f73584c4adec, we now preserve the 
initializer for invalid decls with the recovery-expr.

However there is a chance that the original init expr is a typo-expr, we should 
not preserve it in the final AST, as typo-expr is an internal AST nodes. We 
should use the one after the typo correction.

This is spotted by a clangd hover crash on the testcase.

>From 2f29011bae5bf1b285c2ab1700c887d74eaec4b0 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 3 May 2024 10:06:39 +0200
Subject: [PATCH] [clang] Don't preserve the typo expr in the recovery expr for
 invalid VarDecls.

With the commit d5308949cf884d8e4b971d51a8b4f73584c4adec, we now
preserve the initializer for invalid decls with the recovery-expr.

However there is a chance that the original init expr is a typo-expr, we
should not preserve it in the final AST, as typo-expr is an internal AST
nodes. We should use the one after the typo correction.

This is spotted by a clangd hover crash on the testcase.
---
 clang-tools-extra/clangd/unittests/HoverTests.cpp | 13 +
 clang/lib/Sema/SemaDecl.cpp   |  7 +--
 clang/test/AST/ast-dump-recovery.cpp  |  5 +
 3 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp 
b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 5ead74748f550c..28df24f34827c0 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -965,6 +965,19 @@ class Foo final {})cpp";
  // Bindings are in theory public members of an anonymous struct.
  HI.AccessSpecifier = "public";
}},
+  {// Don't crash on invalid decl with invalid init expr.
+   R"cpp(
+  Unknown [[^abc]] = invalid;
+  // error-ok
+  )cpp",
+   [](HoverInfo ) {
+ HI.Name = "abc";
+ HI.Kind = index::SymbolKind::Variable;
+ HI.NamespaceScope = "";
+ HI.Definition = "int abc = ()";
+ HI.Type = "int";
+ HI.AccessSpecifier = "public";
+   }},
   {// Extra info for function call.
R"cpp(
   void fun(int arg_a, int _b) {};
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 19968452f0d566..169df60b56bb4b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -13530,9 +13530,12 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr 
*Init, bool DirectInit) {
   }
 
   if (VDecl->isInvalidDecl()) {
-CorrectDelayedTyposInExpr(Init, VDecl);
+ExprResult Res = CorrectDelayedTyposInExpr(Init, VDecl);
+std::vector SubExprs;
+if (Res.isUsable())
+  SubExprs.push_back(Res.get());
 ExprResult Recovery =
-CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), {Init});
+CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), SubExprs);
 if (Expr *E = Recovery.get())
   VDecl->setInit(E);
 return;
diff --git a/clang/test/AST/ast-dump-recovery.cpp 
b/clang/test/AST/ast-dump-recovery.cpp
index 77527743fe8577..a88dff471d9f04 100644
--- a/clang/test/AST/ast-dump-recovery.cpp
+++ b/clang/test/AST/ast-dump-recovery.cpp
@@ -419,6 +419,11 @@ void InitializerOfInvalidDecl() {
   // CHECK:  VarDecl {{.*}} invalid InvalidDecl
   // CHECK-NEXT: `-RecoveryExpr {{.*}} '' contains-errors
   // CHECK-NEXT:   `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'ValidDecl'
+
+  Unknown InvalidDeclWithInvalidInit = Invalid;
+  // CHECK:  VarDecl {{.*}} invalid InvalidDeclWithInvalidInit
+  // CHECK-NEXT: `-RecoveryExpr {{.*}} '' contains-errors
+  // CHECK-NOT:`-TypoExpr
 }
 
 void RecoverToAnInvalidDecl() {

___
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 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 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);

[clang] [AST] Dump explicit template arguments for UnreslovedLookupExpr. (PR #90466)

2024-04-29 Thread Haojian Wu via cfe-commits

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


[clang] [AST] Dump explicit template arguments for UnreslovedLookupExpr. (PR #90466)

2024-04-29 Thread Haojian Wu via cfe-commits

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


[clang] [AST] Dump explicit template arguments for UnreslovedLookupExpr. (PR #90466)

2024-04-29 Thread Haojian Wu via cfe-commits


@@ -107,3 +107,17 @@ auto FooFunc(C auto V) -> C decltype(auto) {
 }
 
 }
+
+namespace dump_unreslove_lookup_arguments {

hokein wrote:

ah, good catch. I moved to a generic place, ast-dump-templates.cpp.

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


[clang] [AST] Dump explicit template arguments for UnreslovedLookupExpr. (PR #90466)

2024-04-29 Thread Haojian Wu via cfe-commits

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

>From b584fab7f2283535d4a04bc55efec6ff508870de Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Mon, 29 Apr 2024 15:04:01 +0200
Subject: [PATCH 1/2] [AST] Dump explicit template arguments for
 UnreslovedLookupExpr.

Having them dump is useful for ad-hoc debugging.
---
 clang/include/clang/AST/ASTNodeTraverser.h|  6 ++
 clang/test/AST/ast-dump-concepts.cpp  | 14 +++
 ...dump-template-json-win32-mangler-crash.cpp | 88 +++
 3 files changed, 108 insertions(+)

diff --git a/clang/include/clang/AST/ASTNodeTraverser.h 
b/clang/include/clang/AST/ASTNodeTraverser.h
index 216dc9eef08b62..cf7493ac37852b 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -844,6 +844,12 @@ class ASTNodeTraverser
 }
   }
 
+  void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr* E) {
+if (E->hasExplicitTemplateArgs())
+  for (auto Arg : E->template_arguments())
+Visit(Arg.getArgument());
+  }
+
   void VisitRequiresExpr(const RequiresExpr *E) {
 for (auto *D : E->getLocalParameters())
   Visit(D);
diff --git a/clang/test/AST/ast-dump-concepts.cpp 
b/clang/test/AST/ast-dump-concepts.cpp
index 5bb174e3548ed2..01064b76f6d462 100644
--- a/clang/test/AST/ast-dump-concepts.cpp
+++ b/clang/test/AST/ast-dump-concepts.cpp
@@ -107,3 +107,17 @@ auto FooFunc(C auto V) -> C decltype(auto) {
 }
 
 }
+
+namespace dump_unreslove_lookup_arguments {
+template 
+constexpr bool C = true;
+
+template 
+requires(C)
+// CHECK:  ParenExpr {{.*}} '' lvalue
+// CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} '' lvalue (no 
ADL) = 'C'
+// CHECK-NEXT:   `-TemplateArgument type 'T'
+// CHECK-NEXT: `-TemplateTypeParmType {{.*}} 'T'
+// CHECK-NEXT:   `-TemplateTypeParm {{.*}} 'T'
+struct Foo {};
+}
diff --git a/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp 
b/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp
index cf740516db6f4b..5ac55d269dce48 100644
--- a/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp
+++ b/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp
@@ -1846,6 +1846,42 @@ int main()
 // CHECK-NEXT:  "kind": "VarTemplateDecl",
 // CHECK-NEXT:  "name": "is_const_v"
 // CHECK-NEXT: }
+// CHECK-NEXT:],
+// CHECK-NEXT:"inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT:  "kind": "TemplateArgument",
+// CHECK-NEXT:  "type": {
+// CHECK-NEXT:   "qualType": "const _Ty"
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "inner": [
+// CHECK-NEXT:   {
+// CHECK-NEXT:"id": "0x{{.*}}",
+// CHECK-NEXT:"kind": "QualType",
+// CHECK-NEXT:"type": {
+// CHECK-NEXT: "qualType": "const _Ty"
+// CHECK-NEXT:},
+// CHECK-NEXT:"qualifiers": "const",
+// CHECK-NEXT:"inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT:  "id": "0x{{.*}}",
+// CHECK-NEXT:  "kind": "TemplateTypeParmType",
+// CHECK-NEXT:  "type": {
+// CHECK-NEXT:   "qualType": "_Ty"
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "isDependent": true,
+// CHECK-NEXT:  "isInstantiationDependent": true,
+// CHECK-NEXT:  "depth": 0,
+// CHECK-NEXT:  "index": 0,
+// CHECK-NEXT:  "decl": {
+// CHECK-NEXT:   "id": "0x{{.*}}",
+// CHECK-NEXT:   "kind": "TemplateTypeParmDecl",
+// CHECK-NEXT:   "name": "_Ty"
+// CHECK-NEXT:  }
+// CHECK-NEXT: }
+// CHECK-NEXT:]
+// CHECK-NEXT:   }
+// CHECK-NEXT:  ]
+// CHECK-NEXT: }
 // CHECK-NEXT:]
 // CHECK-NEXT:   }
 // CHECK-NEXT:  ]
@@ -1900,6 +1936,32 @@ int main()
 // CHECK-NEXT:  "kind": "VarTemplateDecl",
 // CHECK-NEXT:  "name": "is_reference_v"
 // CHECK-NEXT: }
+// CHECK-NEXT:],
+// CHECK-NEXT:"inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT:  "kind": "TemplateArgument",
+// CHECK-NEXT:  "type": {
+// CHECK-NEXT:   "qualType": "_Ty"
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "inner": [
+// CHECK-NEXT:   {
+// CHECK-NEXT:"id": "0x{{.*}}",
+// CHECK-NEXT:"kind": "TemplateTypeParmType",
+// CHECK-NEXT:"type": {
+// CHECK-NEXT: "qualType": "_Ty"
+// CHECK-NEXT:},
+// CHECK-NEXT:"isDependent": true,
+// CHECK-NEXT:"isInstantiationDependent": true,
+// CHECK-NEXT:"depth": 0,
+// CHECK-NEXT:"index": 0,
+// 

[clang] [AST] Dump explicit template arguments for UnreslovedLookupExpr. (PR #90466)

2024-04-29 Thread Haojian Wu via cfe-commits

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

>From b584fab7f2283535d4a04bc55efec6ff508870de Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Mon, 29 Apr 2024 15:04:01 +0200
Subject: [PATCH 1/2] [AST] Dump explicit template arguments for
 UnreslovedLookupExpr.

Having them dump is useful for ad-hoc debugging.
---
 clang/include/clang/AST/ASTNodeTraverser.h|  6 ++
 clang/test/AST/ast-dump-concepts.cpp  | 14 +++
 ...dump-template-json-win32-mangler-crash.cpp | 88 +++
 3 files changed, 108 insertions(+)

diff --git a/clang/include/clang/AST/ASTNodeTraverser.h 
b/clang/include/clang/AST/ASTNodeTraverser.h
index 216dc9eef08b62..cf7493ac37852b 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -844,6 +844,12 @@ class ASTNodeTraverser
 }
   }
 
+  void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr* E) {
+if (E->hasExplicitTemplateArgs())
+  for (auto Arg : E->template_arguments())
+Visit(Arg.getArgument());
+  }
+
   void VisitRequiresExpr(const RequiresExpr *E) {
 for (auto *D : E->getLocalParameters())
   Visit(D);
diff --git a/clang/test/AST/ast-dump-concepts.cpp 
b/clang/test/AST/ast-dump-concepts.cpp
index 5bb174e3548ed2..01064b76f6d462 100644
--- a/clang/test/AST/ast-dump-concepts.cpp
+++ b/clang/test/AST/ast-dump-concepts.cpp
@@ -107,3 +107,17 @@ auto FooFunc(C auto V) -> C decltype(auto) {
 }
 
 }
+
+namespace dump_unreslove_lookup_arguments {
+template 
+constexpr bool C = true;
+
+template 
+requires(C)
+// CHECK:  ParenExpr {{.*}} '' lvalue
+// CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} '' lvalue (no 
ADL) = 'C'
+// CHECK-NEXT:   `-TemplateArgument type 'T'
+// CHECK-NEXT: `-TemplateTypeParmType {{.*}} 'T'
+// CHECK-NEXT:   `-TemplateTypeParm {{.*}} 'T'
+struct Foo {};
+}
diff --git a/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp 
b/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp
index cf740516db6f4b..5ac55d269dce48 100644
--- a/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp
+++ b/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp
@@ -1846,6 +1846,42 @@ int main()
 // CHECK-NEXT:  "kind": "VarTemplateDecl",
 // CHECK-NEXT:  "name": "is_const_v"
 // CHECK-NEXT: }
+// CHECK-NEXT:],
+// CHECK-NEXT:"inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT:  "kind": "TemplateArgument",
+// CHECK-NEXT:  "type": {
+// CHECK-NEXT:   "qualType": "const _Ty"
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "inner": [
+// CHECK-NEXT:   {
+// CHECK-NEXT:"id": "0x{{.*}}",
+// CHECK-NEXT:"kind": "QualType",
+// CHECK-NEXT:"type": {
+// CHECK-NEXT: "qualType": "const _Ty"
+// CHECK-NEXT:},
+// CHECK-NEXT:"qualifiers": "const",
+// CHECK-NEXT:"inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT:  "id": "0x{{.*}}",
+// CHECK-NEXT:  "kind": "TemplateTypeParmType",
+// CHECK-NEXT:  "type": {
+// CHECK-NEXT:   "qualType": "_Ty"
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "isDependent": true,
+// CHECK-NEXT:  "isInstantiationDependent": true,
+// CHECK-NEXT:  "depth": 0,
+// CHECK-NEXT:  "index": 0,
+// CHECK-NEXT:  "decl": {
+// CHECK-NEXT:   "id": "0x{{.*}}",
+// CHECK-NEXT:   "kind": "TemplateTypeParmDecl",
+// CHECK-NEXT:   "name": "_Ty"
+// CHECK-NEXT:  }
+// CHECK-NEXT: }
+// CHECK-NEXT:]
+// CHECK-NEXT:   }
+// CHECK-NEXT:  ]
+// CHECK-NEXT: }
 // CHECK-NEXT:]
 // CHECK-NEXT:   }
 // CHECK-NEXT:  ]
@@ -1900,6 +1936,32 @@ int main()
 // CHECK-NEXT:  "kind": "VarTemplateDecl",
 // CHECK-NEXT:  "name": "is_reference_v"
 // CHECK-NEXT: }
+// CHECK-NEXT:],
+// CHECK-NEXT:"inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT:  "kind": "TemplateArgument",
+// CHECK-NEXT:  "type": {
+// CHECK-NEXT:   "qualType": "_Ty"
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "inner": [
+// CHECK-NEXT:   {
+// CHECK-NEXT:"id": "0x{{.*}}",
+// CHECK-NEXT:"kind": "TemplateTypeParmType",
+// CHECK-NEXT:"type": {
+// CHECK-NEXT: "qualType": "_Ty"
+// CHECK-NEXT:},
+// CHECK-NEXT:"isDependent": true,
+// CHECK-NEXT:"isInstantiationDependent": true,
+// CHECK-NEXT:"depth": 0,
+// CHECK-NEXT:"index": 0,
+// 

[clang] [AST] Dump explicit template arguments for UnreslovedLookupExpr. (PR #90466)

2024-04-29 Thread Haojian Wu via cfe-commits

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

Having them dump is useful for ad-hoc debugging (context: 
https://github.com/llvm/llvm-project/issues/90046)

>From b584fab7f2283535d4a04bc55efec6ff508870de Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Mon, 29 Apr 2024 15:04:01 +0200
Subject: [PATCH] [AST] Dump explicit template arguments for
 UnreslovedLookupExpr.

Having them dump is useful for ad-hoc debugging.
---
 clang/include/clang/AST/ASTNodeTraverser.h|  6 ++
 clang/test/AST/ast-dump-concepts.cpp  | 14 +++
 ...dump-template-json-win32-mangler-crash.cpp | 88 +++
 3 files changed, 108 insertions(+)

diff --git a/clang/include/clang/AST/ASTNodeTraverser.h 
b/clang/include/clang/AST/ASTNodeTraverser.h
index 216dc9eef08b62..cf7493ac37852b 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -844,6 +844,12 @@ class ASTNodeTraverser
 }
   }
 
+  void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr* E) {
+if (E->hasExplicitTemplateArgs())
+  for (auto Arg : E->template_arguments())
+Visit(Arg.getArgument());
+  }
+
   void VisitRequiresExpr(const RequiresExpr *E) {
 for (auto *D : E->getLocalParameters())
   Visit(D);
diff --git a/clang/test/AST/ast-dump-concepts.cpp 
b/clang/test/AST/ast-dump-concepts.cpp
index 5bb174e3548ed2..01064b76f6d462 100644
--- a/clang/test/AST/ast-dump-concepts.cpp
+++ b/clang/test/AST/ast-dump-concepts.cpp
@@ -107,3 +107,17 @@ auto FooFunc(C auto V) -> C decltype(auto) {
 }
 
 }
+
+namespace dump_unreslove_lookup_arguments {
+template 
+constexpr bool C = true;
+
+template 
+requires(C)
+// CHECK:  ParenExpr {{.*}} '' lvalue
+// CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} '' lvalue (no 
ADL) = 'C'
+// CHECK-NEXT:   `-TemplateArgument type 'T'
+// CHECK-NEXT: `-TemplateTypeParmType {{.*}} 'T'
+// CHECK-NEXT:   `-TemplateTypeParm {{.*}} 'T'
+struct Foo {};
+}
diff --git a/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp 
b/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp
index cf740516db6f4b..5ac55d269dce48 100644
--- a/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp
+++ b/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp
@@ -1846,6 +1846,42 @@ int main()
 // CHECK-NEXT:  "kind": "VarTemplateDecl",
 // CHECK-NEXT:  "name": "is_const_v"
 // CHECK-NEXT: }
+// CHECK-NEXT:],
+// CHECK-NEXT:"inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT:  "kind": "TemplateArgument",
+// CHECK-NEXT:  "type": {
+// CHECK-NEXT:   "qualType": "const _Ty"
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "inner": [
+// CHECK-NEXT:   {
+// CHECK-NEXT:"id": "0x{{.*}}",
+// CHECK-NEXT:"kind": "QualType",
+// CHECK-NEXT:"type": {
+// CHECK-NEXT: "qualType": "const _Ty"
+// CHECK-NEXT:},
+// CHECK-NEXT:"qualifiers": "const",
+// CHECK-NEXT:"inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT:  "id": "0x{{.*}}",
+// CHECK-NEXT:  "kind": "TemplateTypeParmType",
+// CHECK-NEXT:  "type": {
+// CHECK-NEXT:   "qualType": "_Ty"
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "isDependent": true,
+// CHECK-NEXT:  "isInstantiationDependent": true,
+// CHECK-NEXT:  "depth": 0,
+// CHECK-NEXT:  "index": 0,
+// CHECK-NEXT:  "decl": {
+// CHECK-NEXT:   "id": "0x{{.*}}",
+// CHECK-NEXT:   "kind": "TemplateTypeParmDecl",
+// CHECK-NEXT:   "name": "_Ty"
+// CHECK-NEXT:  }
+// CHECK-NEXT: }
+// CHECK-NEXT:]
+// CHECK-NEXT:   }
+// CHECK-NEXT:  ]
+// CHECK-NEXT: }
 // CHECK-NEXT:]
 // CHECK-NEXT:   }
 // CHECK-NEXT:  ]
@@ -1900,6 +1936,32 @@ int main()
 // CHECK-NEXT:  "kind": "VarTemplateDecl",
 // CHECK-NEXT:  "name": "is_reference_v"
 // CHECK-NEXT: }
+// CHECK-NEXT:],
+// CHECK-NEXT:"inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT:  "kind": "TemplateArgument",
+// CHECK-NEXT:  "type": {
+// CHECK-NEXT:   "qualType": "_Ty"
+// CHECK-NEXT:  },
+// CHECK-NEXT:  "inner": [
+// CHECK-NEXT:   {
+// CHECK-NEXT:"id": "0x{{.*}}",
+// CHECK-NEXT:"kind": "TemplateTypeParmType",
+// CHECK-NEXT:"type": {
+// CHECK-NEXT: "qualType": "_Ty"
+// CHECK-NEXT:},
+// CHECK-NEXT:"isDependent": true,
+// CHECK-NEXT:"isInstantiationDependent": 

[clang] [clang] Add __builtin_start_object_lifetime builtin. (PR #82776)

2024-04-29 Thread Haojian Wu via cfe-commits

hokein wrote:

Friendly ping.

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


[clang] [clang] Add __builtin_start_object_lifetime builtin. (PR #82776)

2024-04-29 Thread Haojian Wu via cfe-commits

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

>From 3ab1a074592f85715c061007c56c69c24794a556 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 23 Feb 2024 10:03:16 +0100
Subject: [PATCH 1/2] [clang] Add __builtin_start_object_lifetime builtin.

This patch implements a clang built `__builtin_start_object_lifetime`,
it has the same semantics as C++23's `std::start_lifetime_as`, but
without the implicit-lifetime type restriction, it can be used for
implementing `std::start_lifetime_as` in the future.

Due to the current clang lowering, the builtin reuses the existing 
`__builtin_launder` implementation:
- it is a no-op for the most part;
- with `-fstrict-vtable-pointers` flag, we update the vtpr assumption correctly
  (mark the load/store vptr with appropriate invariant group intrinsics)
  to prevent incorrect vptr load folding;
- for now, the builtin is non-constant, cannot be executed in constant 
evaluation;

CAVEAT:
- this builtin may cause TBAA miscomplies without the `-fno-strict-alias`
  flag. These TBAA miscompiles are known issues and may need more LLVM
  IR support for the fix, fixing them is orthogonal to the implementaton of the
  builtin.

Context: 
https://discourse.llvm.org/t/extension-for-creating-objects-via-memcpy/76961
---
 clang/include/clang/Basic/Builtins.td |  6 +++
 clang/lib/CodeGen/CGBuiltin.cpp   |  1 +
 clang/lib/Sema/SemaChecking.cpp   |  2 +
 clang/test/CodeGen/builtins.c | 10 
 .../builtin-start-object-life-time.cpp| 49 +++
 clang/test/SemaCXX/builtins.cpp   | 33 -
 6 files changed, 100 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGenCXX/builtin-start-object-life-time.cpp

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index de721a87b3341d..399fabe53d9fa0 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -926,6 +926,12 @@ def Launder : Builtin {
   let Prototype = "void*(void*)";
 }
 
+def StartObjectLifeTime : Builtin {
+  let Spellings = ["__builtin_start_object_lifetime"];
+  let Attributes = [NoThrow, CustomTypeChecking];
+  let Prototype = "void*(void*)";
+}
+
 def IsConstantEvaluated : LangBuiltin<"CXX_LANG"> {
   let Spellings = ["__builtin_is_constant_evaluated"];
   let Attributes = [NoThrow, Constexpr];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 7e5f2edfc732cc..e81f39149bfbc9 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4521,6 +4521,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
 
 return RValue::get(nullptr);
   }
+  case Builtin::BI__builtin_start_object_lifetime:
   case Builtin::BI__builtin_launder: {
 const Expr *Arg = E->getArg(0);
 QualType ArgTy = Arg->getType()->getPointeeType();
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 51757f4cf727d6..f16a9a53857154 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -38,6 +38,7 @@
 #include "clang/AST/TypeLoc.h"
 #include "clang/AST/UnresolvedSet.h"
 #include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/Builtins.h"
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/IdentifierTable.h"
@@ -2641,6 +2642,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
 TheCall->setType(Context.IntTy);
 break;
   }
+  case Builtin::BI__builtin_start_object_lifetime:
   case Builtin::BI__builtin_launder:
 return BuiltinLaunder(*this, TheCall);
   case Builtin::BI__sync_fetch_and_add:
diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c
index 407e0857d22311..00c81c23d0ed02 100644
--- a/clang/test/CodeGen/builtins.c
+++ b/clang/test/CodeGen/builtins.c
@@ -143,6 +143,7 @@ int main(void) {
   P(signbit, (1.0));
 
   R(launder, ());
+  R(start_object_lifetime, ());
 
   return 0;
 }
@@ -511,6 +512,15 @@ void test_builtin_launder(int *p) {
   int *d = __builtin_launder(p);
 }
 
+/// It should be a NOP in C since there are no vtables.
+// CHECK-LABEL: define{{.*}} void @test_builtin_start_object_lifetime
+void test_builtin_start_object_lifetime(int *p) {
+  // CHECK: [[TMP:%.*]] = load ptr,
+  // CHECK-NOT: @llvm.launder
+  // CHECK: store ptr [[TMP]],
+  int *d = __builtin_start_object_lifetime(p);
+}
+
 // __warn_memset_zero_len should be NOP, see 
https://sourceware.org/bugzilla/show_bug.cgi?id=25399
 // CHECK-LABEL: define{{.*}} void @test___warn_memset_zero_len
 void test___warn_memset_zero_len(void) {
diff --git a/clang/test/CodeGenCXX/builtin-start-object-life-time.cpp 
b/clang/test/CodeGenCXX/builtin-start-object-life-time.cpp
new file mode 100644
index 00..58012f52cc0ef5
--- /dev/null
+++ b/clang/test/CodeGenCXX/builtin-start-object-life-time.cpp
@@ -0,0 

[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

2024-04-29 Thread Haojian Wu via cfe-commits

hokein wrote:

> @hokein Independently of the direction taken I'd like to see a better 
> diagnostic than "atomic constraint using an undocumented/cryptic trait that 
> is not in the code is not satisfied". 
> So when we try to print atomic constraints, we should do something more user 
> friendly for is_deducible. (`note_atomic_constraint_evaluated_to_false` in 
> `diagnoseWellFormedUnsatisfiedConstraintExpr` AFAICT). It might be a bit 
> ad-hoc, but I think it's worth doing

I agree with you -- having a well-described diagnostic message is better and 
clearer. I'm happy to improve it once we settle on the final implementation 
approach (the current diagnostic `because '__is_deducible(AFoo, Foo)' 
evaluated to false` seems okay to me. GCC also emits similar diagnostics).

By the way, other parts of this patch are ready for review.

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


[clang] [clang] Implement a bitwise_copyable builtin type trait. (PR #86512)

2024-04-29 Thread Haojian Wu via cfe-commits

hokein wrote:

Friendly ping, it is ready for the second round of review. 

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

2024-04-26 Thread Haojian Wu via cfe-commits

hokein wrote:

It appears that the consensus is to avoid exposing the internal 
`__is_deducible` type trait to end-users, as there are no compelling use cases 
and it's not expected to be used in libc++. This also aligns with the approach 
taken by GCC.

Regarding implementation, the current tablegen-based mechanism doesn't offer an 
optimal solution for defining internal-only builtins. Several options:

1) Making manual changes in the `TypeTrait` structure code, as proposed by 
@AaronBallman. While feasible, this approach may be somewhat hacky and would 
require modifications in multiple places (please see the current 
implementation, which involves four locations).
2) Following the standard defining-builtin approach but emitting a diagnostic 
warning when Clang parses `__is_deducible`. This option seems to strike the 
right balance, as it provides a compromise between adherence to clang's 
standard implementation and user guidance. Additionally, it would allow for 
dedicated lit tests for this type trait.
3) Following the standard approach but omitting the type trait name in the 
`TYPE_TRAIT_2` macro, as suggested by @cor3ntin. However, this approach will 
affect components that need to print the type-trait name (e.g., AST dump, 
diagnostics).

Opinions and thoughts would be appreciated, @AaronBallman, @cor3ntin, 
@erichkeane 


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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

2024-04-24 Thread Haojian Wu via cfe-commits

hokein wrote:

> > Ah, I see. I haven't tried that, but one downside I can see is that it will 
> > make diagnostics for CTAD worse, we need to spell the type trait name in 
> > error messages when the __is_deducible trait fails.
> 
> I think we should have a custom diag for that anyway "is not deducible from" 
> is better than " `__is_deducible<>` is false"

I think this is one of the symptoms, missing the trait name in the AST dump is 
another symptom.

And I'm not aware of an easy way to customize a diagnostic within clang's 
template-constraint check mechanism. One implementation I can think of is to 
manual call the `DeduceTemplateArgumentsFromType` in the function overload 
resolution for the alias CTAD, and then emit a custom diagnostic, but it feels 
awkward.


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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

2024-04-24 Thread Haojian Wu via cfe-commits

hokein wrote:

> > OK, I have hidden the `__is_deducible` trait as suggested. Please take 
> > another look.
> 
> Sorry, I think my suggestion was not clear enough. did you try to put 
> `TYPE_TRAIT_2(/**/, IsDeducible, KEYCXX)` in `TokenKinds.def` (and then other 
> headers should _NOT_ be modified)

Ah, I see. I haven't tried that, but one downside I can see is that it will 
make diagnostics for CTAD worse, we need to spell the type trait name in error 
messages when the `__is_deducible` trait fails.

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


[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

2024-04-24 Thread Haojian Wu via cfe-commits

hokein wrote:

OK, I have hidden the `__is_deducible` trait as suggested. Please take another 
look.

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


  1   2   3   4   5   6   7   8   9   10   >