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

2024-08-31 Thread Matheus Izvekov via cfe-commits


@@ -3237,6 +3237,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.
+static TemplateDeductionResult FinishTemplateArgumentDeduction(
+Sema &S, TemplateDecl *TD,
+SmallVectorImpl &Deduced,
+TemplateDeductionInfo &Info) {
+  // Unevaluated SFINAE context.
+  EnterExpressionEvaluationContext Unevaluated(
+  S, Sema::ExpressionEvaluationContext::Unevaluated);
+  Sema::SFINAETrap Trap(S);
+
+  Sema::ContextRAII SavedContext(S, getAsDeclContextOrEnclosing(TD));
+
+  // C++ [temp.deduct.type]p2:
+  //   [...] or if any template argument remains neither deduced nor
+  //   explicitly specified, template argument deduction fails.
+  SmallVector SugaredBuilder, CanonicalBuilder;
+  if (auto Result = ConvertDeducedTemplateArguments(
+  S, TD, /*IsPartialOrdering=*/false, Deduced, Info, SugaredBuilder,
+  CanonicalBuilder);
+  Result != TemplateDeductionResult::Success)
+return Result;
+

mizvekov wrote:

This is missing a consistency check, ie [temp.deduct.type]p1.

Otherwise we would incorrectly accept a match where there would be a 
non-deduced mismatch.

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-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] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

2024-05-15 Thread via cfe-commits

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


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 &Info);
 
+  /// 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 &Info);
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo &Info,
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 &Self, 
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("Unknow

[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 &Info);
 
+  /// 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 &Info);
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo &Info,
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 &Self, 
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("Unknow

[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 &Info);
 
+  /// 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 &Info);
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo &Info,
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 &Self, 
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("Unknow

[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 &Info);
 
+  /// 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 &Info);
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo &Info,
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 &Self, 
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("Unknow

[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 &SemaRef, 
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 &SemaRef, TypeAliasTemplateDecl *AliasTemplate,
+   FunctionTemplateDecl *FTD,
+   llvm::ArrayRef TransformedArgs,
+   QualType ReturnType) {
+  auto &Context = 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 &Info);
 
+  /// 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 &Info);
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo &Info,
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 &Self, 
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("Unknow

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

2024-05-13 Thread via cfe-commits

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

I'll approve that modulo nit but i think we want

- An issue to keep track of the duplication in `FinishTemplateArgumentDeduction`
- A follow up PR to improve diagnostics


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-13 Thread via cfe-commits


@@ -2774,6 +2775,41 @@ Expr *transformRequireClause(Sema &SemaRef, 
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 &SemaRef, TypeAliasTemplateDecl *AliasTemplate,
+   FunctionTemplateDecl *FTD,
+   llvm::ArrayRef TransformedArgs,
+   QualType ReturnType) {
+  auto &Context = SemaRef.Context;

cor3ntin wrote:

I'm not seeing a change here?

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 via cfe-commits

https://github.com/cor3ntin 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-13 Thread Haojian Wu via cfe-commits


@@ -2774,6 +2775,41 @@ Expr *transformRequireClause(Sema &SemaRef, 
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 &SemaRef, TypeAliasTemplateDecl *AliasTemplate,
+   FunctionTemplateDecl *FTD,
+   llvm::ArrayRef TransformedArgs,
+   QualType ReturnType) {
+  auto &Context = 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 &Self, 
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 &Info);
 
+  /// 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 &Info);
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo &Info,
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 &Self, 
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 ty

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

2024-05-08 Thread 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}} \

cor3ntin wrote:

I certainly think it's not a good user-facing diagnostic, and i don't think the 
fix would be difficult
but doing it separately seems reasonable. WDYT @AaronBallman? 

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 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] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

2024-05-08 Thread 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

cor3ntin wrote:

Why remove the comment?

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 via cfe-commits


@@ -2774,6 +2775,41 @@ Expr *transformRequireClause(Sema &SemaRef, 
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 &SemaRef, TypeAliasTemplateDecl *AliasTemplate,
+   FunctionTemplateDecl *FTD,
+   llvm::ArrayRef TransformedArgs,
+   QualType ReturnType) {
+  auto &Context = SemaRef.Context;

cor3ntin wrote:

```suggestion
  (const?) ASTContext &Context = SemaRef.Context;
```

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 via cfe-commits


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

cor3ntin wrote:

We have a lot of `DeduceTemplateArguments` function so I think we want to add a 
comment here describing what that function does / when it is used.

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 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}} \

cor3ntin wrote:

I think we want to add code in this PR to improve the diagnostic

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 via cfe-commits


@@ -6116,6 +6116,17 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, 
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!");

cor3ntin wrote:

that is always true (you probably mean `false && ""`).
But I would remove the `if`, use 
`cast(LhsT)` that will assert for you)

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 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.

cor3ntin wrote:

Is that something you would be willing to do in a 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-08 Thread 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"

cor3ntin wrote:

Probably not a needed 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-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 &Info);
 
+  /// 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 &Info);
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo &Info,
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 &Self, 
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: implement the missing IsDeducible constraint for alias templates (PR #89358)

2024-04-29 Thread via cfe-commits

cor3ntin 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!

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-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] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)

2024-04-26 Thread via cfe-commits

cor3ntin 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

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-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 via cfe-commits

cor3ntin 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"


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 via cfe-commits

cor3ntin 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) 

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


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

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


@@ -868,13 +868,7 @@ C++20 implementation status
 
   Class template argument deduction for alias templates
   https://wg21.link/p1814r0";>P1814R0
-  
-
-  Clang 19 (Partial)
-  The associated constraints (over.match.class.deduct#3.3) for the
-  synthesized deduction guides are not yet implemented.
-
-  
+  Clang 19 (Partial)

hokein wrote:

Added it back.

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 via cfe-commits

github-actions[bot] wrote:




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



You can test this locally with the following command:


``bash
git-clang-format --diff 83bc7b57714dc2f6b33c188f2b95a0025468ba51 
502066518604dde5c7596f377a61d25562d2a5ab -- 
clang/include/clang/Basic/TypeTraits.h clang/include/clang/Sema/Sema.h 
clang/lib/Basic/TypeTraits.cpp clang/lib/Sema/SemaExprCXX.cpp 
clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateDeduction.cpp 
clang/test/SemaCXX/cxx20-ctad-type-alias.cpp 
clang/test/SemaTemplate/deduction-guide.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/Basic/TypeTraits.cpp b/clang/lib/Basic/TypeTraits.cpp
index 1728ea3abb..43d892d3b9 100644
--- a/clang/lib/Basic/TypeTraits.cpp
+++ b/clang/lib/Basic/TypeTraits.cpp
@@ -19,9 +19,9 @@ static constexpr const char *TypeTraitNames[] = {
 #define TYPE_TRAIT_1(Spelling, Name, Key) #Name,
 #include "clang/Basic/TokenKinds.def"
 #define TYPE_TRAIT_2(Spelling, Name, Key) #Name,
-  // IsDeducible is only used internally by clang for CTAD implementation and
-  // is not exposed to users.
-  TYPE_TRAIT_2(/**/, IsDeducible, KEYCXX)
+// IsDeducible is only used internally by clang for CTAD implementation and
+// is not exposed to users.
+TYPE_TRAIT_2(/**/, IsDeducible, KEYCXX)
 #include "clang/Basic/TokenKinds.def"
 #define TYPE_TRAIT_N(Spelling, Name, Key) #Name,
 #include "clang/Basic/TokenKinds.def"
@@ -31,9 +31,10 @@ static constexpr const char *TypeTraitSpellings[] = {
 #define TYPE_TRAIT_1(Spelling, Name, Key) #Spelling,
 #include "clang/Basic/TokenKinds.def"
 #define TYPE_TRAIT_2(Spelling, Name, Key) #Spelling,
-  // __is_deducible is only used internally by clang for CTAD implementation 
and
-  // is not exposed to users.
-  TYPE_TRAIT_2(__is_deducible, /**/, KEYCXX)
+// __is_deducible is only used internally by clang for CTAD implementation
+// and
+// is not exposed to users.
+TYPE_TRAIT_2(__is_deducible, /**/, KEYCXX)
 #include "clang/Basic/TokenKinds.def"
 #define TYPE_TRAIT_N(Spelling, Name, Key) #Spelling,
 #include "clang/Basic/TokenKinds.def"
@@ -65,9 +66,9 @@ static constexpr const unsigned TypeTraitArities[] = {
 #define TYPE_TRAIT_1(Spelling, Name, Key) 1,
 #include "clang/Basic/TokenKinds.def"
 #define TYPE_TRAIT_2(Spelling, Name, Key) 2,
-  // IsDeducible is only used internally by clang for CTAD implementation and
-  // is not exposed to users.
-  TYPE_TRAIT_2(/**/, IsDeducible, KEYCXX)
+// IsDeducible is only used internally by clang for CTAD implementation and
+// is not exposed to users.
+TYPE_TRAIT_2(/**/, IsDeducible, KEYCXX)
 #include "clang/Basic/TokenKinds.def"
 #define TYPE_TRAIT_N(Spelling, Name, Key) 0,
 #include "clang/Basic/TokenKinds.def"

``




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

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

>From 2385c46a2ae67e0890a7232fdec16b0b92da060b Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 19 Apr 2024 10:54:12 +0200
Subject: [PATCH 1/3] [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 a27fbed358a60c2..74102f405396816 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 64607b91acbfc95..3b67cc948e84d0b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9598,6 +9598,15 @@ class Sema final : public SemaBase {
   ArrayRef TemplateArgs,
   sema::TemplateDeductionInfo &Info);
 
+  /// 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 &Info);
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo &Info,
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 0d2ad980696fcc2..af4e205eeff8032 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 779a41620033dc6..a197a2eabde9130 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6116,6 +6116,17 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, 
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.DeduceTemplateArg

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

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

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

>From 2385c46a2ae67e0890a7232fdec16b0b92da060b Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 19 Apr 2024 10:54:12 +0200
Subject: [PATCH 1/3] [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 a27fbed358a60c2..74102f405396816 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 64607b91acbfc95..3b67cc948e84d0b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9598,6 +9598,15 @@ class Sema final : public SemaBase {
   ArrayRef TemplateArgs,
   sema::TemplateDeductionInfo &Info);
 
+  /// 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 &Info);
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo &Info,
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 0d2ad980696fcc2..af4e205eeff8032 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 779a41620033dc6..a197a2eabde9130 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6116,6 +6116,17 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, 
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.DeduceTemplateArg

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

2024-04-23 Thread via cfe-commits

cor3ntin wrote:

> > > This approach is doable technically, but it feels hacky and fragile. What 
> > > if we emit an error (or warning) diagnostic and reject the code when we 
> > > parse the __is_deducible type trait?
> > 
> > 
> > Why do you think it is fragile? I think a comment around `BTT_IsDeducible` 
> > would take care of that
> 
> This is not a single-place change, we have to duplicate the `BTT_IsDeducible` 
> manual change for at least 4 places:
> 
> * 
> https://github.com/llvm/llvm-project/blob/main/clang/include/clang/Basic/TypeTraits.h#L28
> * 
> https://github.com/llvm/llvm-project/blob/main/clang/lib/Basic/TypeTraits.cpp#L21
> * 
> https://github.com/llvm/llvm-project/blob/main/clang/lib/Basic/TypeTraits.cpp#L30
> * 
> https://github.com/llvm/llvm-project/blob/main/clang/lib/Basic/TypeTraits.cpp#L61

Something like that seem to be fine

```cpp
// IsDeducible is only used internally by clang and is not exposed to source 
code
TYPE_TRAIT_2(/**/, IsDeducible, KEYCXX)
```

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-23 Thread via cfe-commits


@@ -868,13 +868,7 @@ C++20 implementation status
 
   Class template argument deduction for alias templates
   https://wg21.link/p1814r0";>P1814R0
-  
-
-  Clang 19 (Partial)
-  The associated constraints (over.match.class.deduct#3.3) for the
-  synthesized deduction guides are not yet implemented.
-
-  
+  Clang 19 (Partial)

cor3ntin wrote:

Can you add back a details saying that the feature macro has not been updated?
However, i suspect that we do want to finalize the feature for Clang 19.

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-23 Thread via cfe-commits

cor3ntin wrote:

> This approach is doable technically, but it feels hacky and fragile. What if 
> we emit an error (or warning) diagnostic and reject the code when we parse 
> the __is_deducible type trait?

Why do you think it is fragile? I think a comment around `BTT_IsDeducible` 
would take care of that

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-23 Thread Haojian Wu via cfe-commits


@@ -868,13 +868,7 @@ C++20 implementation status
 
   Class template argument deduction for alias templates
   https://wg21.link/p1814r0";>P1814R0
-  
-
-  Clang 19 (Partial)
-  The associated constraints (over.match.class.deduct#3.3) for the
-  synthesized deduction guides are not yet implemented.
-
-  
+  Clang 19 (Partial)

hokein wrote:

With this patch, this feature is completed. However, I suspect that there maybe 
issues, and it needs some time to be productized. Therefore, I hesitate to say 
that it is "ready" (although I'm not sure what the common practice is).

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-23 Thread Haojian Wu via cfe-commits

hokein wrote:

> > > Regarding the __is_deducible type trait, GCC also provides one, but it 
> > > was hidden from users and only used for internal CTAD implementation. I'm 
> > > not sure if we should follow the same strategy in clang, ideas?
> > 
> > 
> > I have mixed feeling. What do you think @AaronBallman ?
> 
> Personally, I do not like exposing type traits that aren't for use with the 
> STL. 

This is a valid argument. This type trait is supposed to be clang-internal only 
and should not be used in other places. The main benefit of exposing it is for 
testing purposes, and I personally found it to be really useful for debugging.

> One idea would be to remove the type trait from TokenKinds.def and instead 
> manually add `BTT_IsDeducible` to:
> 
> https://github.com/llvm/llvm-project/blob/c61f0a8e94004b05d9ec115d3bff8cff331b4491/clang/include/clang/Basic/TypeTraits.h#L21
> 
> along with a comment explaining that this is for internal use only rather 
> than be exposed to users. (You'd have to see if there are other places using 
> `TYPE_TRAIT_2` that might need adjustment as well.) Then we can remove the 
> release note, error checking can become assertions, etc.

This approach is doable technically, but it feels hacky and fragile. What if we 
emit an error (or warning) diagnostic and reject the code when we parse the 
`__is_deducible` type trait?

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-22 Thread Aaron Ballman via cfe-commits


@@ -868,13 +868,7 @@ C++20 implementation status
 
   Class template argument deduction for alias templates
   https://wg21.link/p1814r0";>P1814R0
-  
-
-  Clang 19 (Partial)
-  The associated constraints (over.match.class.deduct#3.3) for the
-  synthesized deduction guides are not yet implemented.
-
-  
+  Clang 19 (Partial)

AaronBallman wrote:

Why is this still partial?

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-22 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> > Regarding the __is_deducible type trait, GCC also provides one, but it was 
> > hidden from users and only used for internal CTAD implementation. I'm not 
> > sure if we should follow the same strategy in clang, ideas?
> 
> I have mixed feeling. What do you think @AaronBallman ?

Personally, I do not like exposing type traits that aren't for use with the 
STL. One idea would be to remove the type trait from TokenKinds.def and instead 
manually add `BTT_IsDeducible` to: 
https://github.com/llvm/llvm-project/blob/c61f0a8e94004b05d9ec115d3bff8cff331b4491/clang/include/clang/Basic/TypeTraits.h#L21
 along with a comment explaining that this is for internal use only rather than 
be exposed to users. (You'd have to see if there are other places using 
`TYPE_TRAIT_2` that might need adjustment as well.) Then we can remove the 
release note, error checking can become assertions, etc.

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-22 Thread via cfe-commits

cor3ntin wrote:

> Regarding the __is_deducible type trait, GCC also provides one, but it was 
> hidden from users and only used for internal CTAD implementation. I'm not 
> sure if we should follow the same strategy in clang, ideas?

I have mixed feeling. What do you think @AaronBallman ?

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-22 Thread Haojian Wu via cfe-commits

hokein wrote:

> Needs a release note, and I think we actually DO have to do those diagnostics 
> here.

Added a release note for the new builtin.


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-22 Thread Haojian Wu via cfe-commits


@@ -6100,6 +6100,17 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, 
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;
+}
+// FIXME: emit a diagnostic.

hokein wrote:

implemented a new diagnostic for bad argument types for the builtin.

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-22 Thread Haojian Wu via cfe-commits


@@ -3207,6 +3241,59 @@ 
Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial,
   return ::DeduceTemplateArguments(*this, Partial, TemplateArgs, Info);
 }
 
+TemplateDeductionResult
+Sema::DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType,
+  sema::TemplateDeductionInfo &Info) {
+  if (TD->isInvalidDecl())
+return TemplateDeductionResult::Invalid;
+
+  QualType PType;
+  if (const auto *CTD = dyn_cast(TD)) {
+// Use the InjectedClassNameType.
+PType = Context.getTypeDeclType(CTD->getTemplatedDecl());
+  } else if (const auto *AliasTemplate = dyn_cast(TD)) {
+PType = AliasTemplate->getTemplatedDecl()
+->getUnderlyingType()
+.getCanonicalType();
+  } else {
+// FIXME: emit a diagnostic, we only only support alias and class 
templates.

hokein wrote:

It turns out we will never hit other cases in this code path (we will reject 
the var/function templates when parsing the type trait expr). I changed it to 
`assert`.

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-22 Thread Haojian Wu via cfe-commits

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

>From 9583811bfa66ff058f5e33012cd77501ce3e5e23 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
---
 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 a27fbed358a60c..74102f40539681 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 ffc58c681cdcd5..a4470ef0aab280 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9591,6 +9591,15 @@ class Sema final : public SemaBase {
   ArrayRef TemplateArgs,
   sema::TemplateDeductionInfo &Info);
 
+  /// 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 &Info);
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo &Info,
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 0d2ad980696fcc..af4e205eeff803 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 7582cbd75fec05..0833a985b48b88 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6100,6 +6100,17 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, 
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.DeduceTemplateArgumentsFr

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

2024-04-19 Thread Erich Keane via cfe-commits

https://github.com/erichkeane 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-04-19 Thread Erich Keane via cfe-commits


@@ -3207,6 +3241,59 @@ 
Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial,
   return ::DeduceTemplateArguments(*this, Partial, TemplateArgs, Info);
 }
 
+TemplateDeductionResult
+Sema::DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType,
+  sema::TemplateDeductionInfo &Info) {
+  if (TD->isInvalidDecl())
+return TemplateDeductionResult::Invalid;
+
+  QualType PType;
+  if (const auto *CTD = dyn_cast(TD)) {
+// Use the InjectedClassNameType.
+PType = Context.getTypeDeclType(CTD->getTemplatedDecl());
+  } else if (const auto *AliasTemplate = dyn_cast(TD)) {
+PType = AliasTemplate->getTemplatedDecl()
+->getUnderlyingType()
+.getCanonicalType();
+  } else {
+// FIXME: emit a diagnostic, we only only support alias and class 
templates.

erichkeane wrote:

Same here.

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-19 Thread Erich Keane via cfe-commits


@@ -6100,6 +6100,17 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, 
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;
+}
+// FIXME: emit a diagnostic.

erichkeane wrote:

I dont think we can leave this as 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-04-19 Thread Erich Keane via cfe-commits

https://github.com/erichkeane commented:

Needs a release note, and I think we actually DO have to do those diagnostics 
here.  

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-19 Thread Haojian Wu via cfe-commits

hokein wrote:

Regarding the __is_deducible type trait, GCC also provides one, but it was 
hidden from users and only used for internal CTAD implementation. I'm not sure 
if we should follow the same strategy in clang, ideas? 

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-19 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Haojian Wu (hokein)


Changes

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

This patch implements the "IsDeducible" constraint where the template arguments 
of the alias template can be deduced from the returned type of the synthesized 
deduction guide, per C++ [over.match.class.deduct]p4. In the implementation, we 
perform the deduction directly, which is more efficient than the way specified 
in the standard.

In this patch, we add a `__is_deducible` builtin type trait, it is useful for 
ad-hoc debugging, and testing.

Also update relevant CTAD tests which were incorrectly compiled due to the 
missing constraint.




---
Full diff: https://github.com/llvm/llvm-project/pull/89358.diff


9 Files Affected:

- (modified) clang/include/clang/Basic/TokenKinds.def (+1) 
- (modified) clang/include/clang/Sema/Sema.h (+9) 
- (modified) clang/lib/Parse/ParseExprCXX.cpp (+10-6) 
- (modified) clang/lib/Sema/SemaExprCXX.cpp (+11) 
- (modified) clang/lib/Sema/SemaTemplate.cpp (+60-23) 
- (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+87) 
- (modified) clang/test/SemaCXX/cxx20-ctad-type-alias.cpp (+17-9) 
- (added) clang/test/SemaCXX/type-traits-is-deducible.cpp (+47) 
- (modified) clang/www/cxx_status.html (+1-7) 


``diff
diff --git a/clang/include/clang/Basic/TokenKinds.def 
b/clang/include/clang/Basic/TokenKinds.def
index a27fbed358a60c..74102f40539681 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 1e89dfc58d92b1..0d8477cf49aaf0 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9591,6 +9591,15 @@ class Sema final : public SemaBase {
   ArrayRef TemplateArgs,
   sema::TemplateDeductionInfo &Info);
 
+  /// 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 &Info);
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo &Info,
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 0d2ad980696fcc..af4e205eeff803 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 7582cbd75fec05..0833a985b48b88 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6100,6 +6100,17 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, 
TypeTrait BTT, const TypeSourceI
   tok::kw___is_pointer_interc

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

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

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

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

This patch implements the "IsDeducible" constraint where the template arguments 
of the alias template can be deduced from the returned type of the synthesized 
deduction guide, per C++ [over.match.class.deduct]p4. In the implementation, we 
perform the deduction directly, which is more efficient than the way specified 
in the standard.

In this patch, we add a `__is_deducible` builtin type trait, it is useful for 
ad-hoc debugging, and testing.

Also update relevant CTAD tests which were incorrectly compiled due to the 
missing constraint.




>From 19a50f5cfb67d23f979cf94c5518f41af921468e 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
---
 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   | 83 +-
 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(+), 45 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 a27fbed358a60c..74102f40539681 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 1e89dfc58d92b1..0d8477cf49aaf0 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9591,6 +9591,15 @@ class Sema final : public SemaBase {
   ArrayRef TemplateArgs,
   sema::TemplateDeductionInfo &Info);
 
+  /// 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 &Info);
+
   TemplateDeductionResult DeduceTemplateArguments(
   TemplateParameterList *TemplateParams, ArrayRef Ps,
   ArrayRef As, sema::TemplateDeductionInfo &Info,
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 0d2ad980696fcc..af4e205eeff803 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 t