================ @@ -1216,10 +1324,225 @@ void DeclareImplicitDeductionGuidesForTypeAlias( ->getDeductionCandidateKind() == DeductionCandidate::Aggregate) continue; - BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate, F, Loc); + BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate, F, Loc, + FromInheritedCtor); } } +void DeclareImplicitDeductionGuidesFromInheritedConstructors( + Sema &SemaRef, TemplateDecl *Template, ClassTemplateDecl *Pattern, + TypeSourceInfo *BaseTSI, unsigned BaseIdx) { + auto &Context = SemaRef.Context; + DeclContext *DC = Template->getDeclContext(); + const auto *BaseTST = BaseTSI->getType()->getAs<TemplateSpecializationType>(); + if (!BaseTST) + return; + SourceLocation BaseLoc = BaseTSI->getTypeLoc().getBeginLoc(); + + TemplateDecl *BaseTD = BaseTST->getTemplateName().getAsTemplateDecl(); + if (!BaseTD) + return; + + // Substitute any parameters with default arguments not present in the base, + // since partial specializations cannot have default parameters + TemplateParameterList *TemplateTPL = Pattern->getTemplateParameters(); + auto BaseDeducedTemplateParams = + TemplateParamsReferencedInTemplateArgumentList( + TemplateTPL, BaseTST->template_arguments()); + SmallVector<NamedDecl *, 8> PartialSpecParams; + SmallVector<TemplateArgument, 8> SubstArgs; + PartialSpecParams.reserve(TemplateTPL->size()); + SubstArgs.reserve(TemplateTPL->size()); + LocalInstantiationScope Scope(SemaRef); + for (unsigned I = 0, N = TemplateTPL->size(); I < N; ++I) { + NamedDecl *Param = TemplateTPL->getParam(I); + if (!BaseDeducedTemplateParams.contains(I)) { + if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param); + TTP && TTP->hasDefaultArgument()) { + SubstArgs.push_back(TTP->getDefaultArgument().getArgument()); + continue; + } + + if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param); + NTTP && NTTP->hasDefaultArgument()) { + SubstArgs.push_back(NTTP->getDefaultArgument().getArgument()); + continue; + } + + if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param); + TTP && TTP->hasDefaultArgument()) { + SubstArgs.push_back(TTP->getDefaultArgument().getArgument()); + continue; + } + + // We have a template parameter that is not present in the base + // and does not have a default argument. We create the deduction + // guide anyway to display a diagnostic. + } + + MultiLevelTemplateArgumentList Args; + Args.setKind(TemplateSubstitutionKind::Rewrite); + Args.addOuterTemplateArguments(SubstArgs); + Args.addOuterRetainedLevels(Template->getTemplateDepth()); + + NamedDecl *NewParam = transformTemplateParameter( + SemaRef, DC, Param, Args, PartialSpecParams.size(), + Template->getTemplateDepth()); + if (!NewParam) + return; + + PartialSpecParams.push_back(NewParam); + SubstArgs.push_back(Context.getInjectedTemplateArg(NewParam)); + } + + Expr *RequiresClause = nullptr; + MultiLevelTemplateArgumentList Args; + Args.setKind(TemplateSubstitutionKind::Rewrite); + Args.addOuterTemplateArguments(SubstArgs); + Args.addOuterRetainedLevels(Template->getTemplateDepth()); + if (Expr *TemplateRC = TemplateTPL->getRequiresClause()) { + ExprResult E = SemaRef.SubstExpr(TemplateRC, Args); + if (E.isInvalid()) + return; + RequiresClause = E.getAs<Expr>(); + } + auto *PartialSpecTPL = TemplateParameterList::Create( + Context, TemplateTPL->getTemplateLoc(), TemplateTPL->getLAngleLoc(), + PartialSpecParams, TemplateTPL->getRAngleLoc(), RequiresClause); + + // [over.match.class.deduct]p1.10 + // Let A be an alias template whose template parameter list is that of + // [Template] and whose defining-type-id is [BaseTSI] ... + auto *TransformedBase = + SemaRef.SubstType(BaseTSI, Args, BaseLoc, DeclarationName(), true); + auto *BaseAD = TypeAliasDecl::Create( + Context, DC, SourceLocation(), BaseLoc, + TransformedBase->getType().getBaseTypeIdentifier(), TransformedBase); + std::string AliasDeclName = + (Twine("__ctad_alias_") + BaseTD->getName() + "_to_" + + Template->getName() + "_" + Twine(BaseIdx)) + .str(); + IdentifierInfo *AliasIdentifier = &Context.Idents.get(AliasDeclName); + auto *BaseATD = TypeAliasTemplateDecl::Create( + Context, DC, BaseLoc, DeclarationName(AliasIdentifier), PartialSpecTPL, + BaseAD); + BaseAD->setDescribedAliasTemplate(BaseATD); + BaseAD->setImplicit(); + BaseATD->setImplicit(); + + DC->addDecl(BaseATD); + + // ... given a class template `template <typename> class CC;` + // whose primary template is not defined ... + auto *TParam = TemplateTypeParmDecl::Create( + Context, DC, SourceLocation(), SourceLocation(), + Template->getTemplateDepth(), 0, nullptr, false, false); + TParam->setImplicit(); + auto *MapperTPL = TemplateParameterList::Create( + Context, SourceLocation(), SourceLocation(), + ArrayRef<NamedDecl *>(TParam), SourceLocation(), nullptr); + + std::string MapperDeclName = + (Twine("__ctad_mapper_") + BaseTD->getName() + "_to_" + ---------------- antangelo wrote:
Done https://github.com/llvm/llvm-project/pull/98788 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits