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