diff options
author | Haojian Wu <hokein.wu@gmail.com> | 2024-05-03 11:04:21 +0200 |
---|---|---|
committer | Haojian Wu <hokein.wu@gmail.com> | 2024-05-03 11:10:43 +0200 |
commit | 621899224aa7d59ab70675f6ff32b298b06a515a (patch) | |
tree | 07cc241740ea4e9ccf73261609917a6df8bf6d6e | |
parent | 40365147f7aabeaaefd7e9bf6f2b96d6f7135992 (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.cpp | 62 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 14 | ||||
-rw-r--r-- | clang/test/SemaTemplate/deduction-guide.cpp | 7 |
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 { |