summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaojian Wu <hokein.wu@gmail.com>2024-05-03 11:04:21 +0200
committerHaojian Wu <hokein.wu@gmail.com>2024-05-03 11:10:43 +0200
commit621899224aa7d59ab70675f6ff32b298b06a515a (patch)
tree07cc241740ea4e9ccf73261609917a6df8bf6d6e
parent40365147f7aabeaaefd7e9bf6f2b96d6f7135992 (diff)
[clang] CTAD: fix the aggregate deduction guide for alias templates.upstream/users/hokein/fix-ctad-aggregate-base
For alias templates, the way we construct their aggregate deduction guides is not following the standard way. We should do the same thing as we do for implicit deduction guides.
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp62
-rw-r--r--clang/test/SemaCXX/cxx20-ctad-type-alias.cpp14
-rw-r--r--clang/test/SemaTemplate/deduction-guide.cpp7
3 files changed, 23 insertions, 60 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index b43c65874b04..7f49acc36769 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3053,66 +3053,8 @@ FunctionTemplateDecl *DeclareAggregateDeductionGuideForTypeAlias(
RHSTemplate, ParamTypes, Loc);
if (!RHSDeductionGuide)
return nullptr;
-
- LocalInstantiationScope Scope(SemaRef);
- Sema::InstantiatingTemplate BuildingDeductionGuides(
- SemaRef, AliasTemplate->getLocation(), RHSDeductionGuide,
- Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
- if (BuildingDeductionGuides.isInvalid())
- return nullptr;
-
- // Build a new template parameter list for the synthesized aggregate deduction
- // guide by transforming the one from RHSDeductionGuide.
- SmallVector<NamedDecl *> TransformedTemplateParams;
- // Template args that refer to the rebuilt template parameters.
- // All template arguments must be initialized in advance.
- SmallVector<TemplateArgument> TransformedTemplateArgs(
- RHSDeductionGuide->getTemplateParameters()->size());
- for (auto *TP : *RHSDeductionGuide->getTemplateParameters()) {
- // Rebuild any internal references to earlier parameters and reindex as
- // we go.
- MultiLevelTemplateArgumentList Args;
- Args.setKind(TemplateSubstitutionKind::Rewrite);
- Args.addOuterTemplateArguments(TransformedTemplateArgs);
- NamedDecl *NewParam = transformTemplateParameter(
- SemaRef, AliasTemplate->getDeclContext(), TP, Args,
- /*NewIndex=*/TransformedTemplateParams.size());
-
- TransformedTemplateArgs[TransformedTemplateParams.size()] =
- SemaRef.Context.getCanonicalTemplateArgument(
- SemaRef.Context.getInjectedTemplateArg(NewParam));
- TransformedTemplateParams.push_back(NewParam);
- }
- // FIXME: implement the is_deducible constraint per C++
- // [over.match.class.deduct]p3.3.
- Expr *TransformedRequiresClause = transformRequireClause(
- SemaRef, RHSDeductionGuide, TransformedTemplateArgs);
- auto *TransformedTemplateParameterList = TemplateParameterList::Create(
- SemaRef.Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(),
- AliasTemplate->getTemplateParameters()->getLAngleLoc(),
- TransformedTemplateParams,
- AliasTemplate->getTemplateParameters()->getRAngleLoc(),
- TransformedRequiresClause);
- auto *TransformedTemplateArgList = TemplateArgumentList::CreateCopy(
- SemaRef.Context, TransformedTemplateArgs);
-
- if (auto *TransformedDeductionGuide = SemaRef.InstantiateFunctionDeclaration(
- RHSDeductionGuide, TransformedTemplateArgList,
- AliasTemplate->getLocation(),
- Sema::CodeSynthesisContext::BuildingDeductionGuides)) {
- auto *GD =
- llvm::dyn_cast<clang::CXXDeductionGuideDecl>(TransformedDeductionGuide);
- FunctionTemplateDecl *Result = buildDeductionGuide(
- SemaRef, AliasTemplate, TransformedTemplateParameterList,
- GD->getCorrespondingConstructor(), GD->getExplicitSpecifier(),
- GD->getTypeSourceInfo(), AliasTemplate->getBeginLoc(),
- AliasTemplate->getLocation(), AliasTemplate->getEndLoc(),
- GD->isImplicit());
- cast<CXXDeductionGuideDecl>(Result->getTemplatedDecl())
- ->setDeductionCandidateKind(DeductionCandidate::Aggregate);
- return Result;
- }
- return nullptr;
+ return BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate,
+ RHSDeductionGuide, Loc);
}
} // namespace
diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
index 508a3a5da76a..e8b4383f53c5 100644
--- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
+++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp
@@ -307,3 +307,17 @@ using AFoo = Foo<int, Derived<U>>;
AFoo a(Derived<int>{});
} // namespace test22
+
+namespace test23 {
+// We have an aggregate deduction guide "G(T) -> G<T>".
+template<typename T>
+struct G { T t1; };
+
+template<typename X = int>
+using AG = G<int>;
+
+AG ag(1.0);
+// Verify that the aggregate deduction guide "AG(int) -> AG<int>" is built and
+// choosen.
+static_assert(__is_same(decltype(ag.t1), int));
+} // namespace test23
diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp
index ff5e39216762..c8636a673221 100644
--- a/clang/test/SemaTemplate/deduction-guide.cpp
+++ b/clang/test/SemaTemplate/deduction-guide.cpp
@@ -261,6 +261,13 @@ AG ag = {1};
// CHECK: | `-BuiltinType {{.*}} 'int'
// CHECK: `-ParmVarDecl {{.*}} 'int'
+template <typename X = int>
+using BG = G<int>;
+BG bg(1.0);
+// CHECK-LABEL: Dumping <deduction guide for BG>
+// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for BG>
+// CHECK: |-CXXDeductionGuideDecl {{.*}} 'auto (int) -> G<int>' aggregate
+
template <typename D>
requires (sizeof(D) == 4)
struct Foo {