================ @@ -2612,44 +2671,309 @@ struct ConvertConstructorToDeductionGuideTransform { SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam); return NewParam; } +}; - FunctionTemplateDecl *buildDeductionGuide( - TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor, - ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart, - SourceLocation Loc, SourceLocation LocEnd, - llvm::ArrayRef<TypedefNameDecl *> MaterializedTypedefs = {}) { - DeclarationNameInfo Name(DeductionGuideName, Loc); - ArrayRef<ParmVarDecl *> Params = - TInfo->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(); +// Find all template parameters of the AliasTemplate that appear in the +// given DeducedArgs. +SmallVector<unsigned> +FindAppearedTemplateParamsInAlias(ArrayRef<TemplateArgument> DeducedArgs, + TypeAliasTemplateDecl *AliasTemplate) { + struct FindAppearedTemplateParams + : public RecursiveASTVisitor<FindAppearedTemplateParams> { + llvm::DenseSet<NamedDecl *> TemplateParamsInAlias; + llvm::DenseSet<const NamedDecl *> AppearedTemplateParams; + + FindAppearedTemplateParams(ArrayRef<NamedDecl *> TemplateParamsInAlias) + : TemplateParamsInAlias(TemplateParamsInAlias.begin(), + TemplateParamsInAlias.end()) {} + + bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) { + TTP->getIndex(); + MarkAppeared(TTP->getDecl()); + return true; + } + bool VisitDeclRefExpr(DeclRefExpr *DRE) { + MarkAppeared(DRE->getFoundDecl()); + return true; + } - // Build the implicit deduction guide template. - auto *Guide = - CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, ES, Name, - TInfo->getType(), TInfo, LocEnd, Ctor); - Guide->setImplicit(); - Guide->setParams(Params); + void MarkAppeared(NamedDecl *ND) { + if (TemplateParamsInAlias.contains(ND)) + AppearedTemplateParams.insert(ND); + } + }; + ArrayRef<NamedDecl *> TemplateParamsInAlias = + AliasTemplate->getTemplateParameters()->asArray(); + FindAppearedTemplateParams MarkAppeared(TemplateParamsInAlias); + MarkAppeared.TraverseTemplateArguments(DeducedArgs); - for (auto *Param : Params) - Param->setDeclContext(Guide); - for (auto *TD : MaterializedTypedefs) - TD->setDeclContext(Guide); + SmallVector<unsigned> Results; + for (unsigned Index = 0; Index < TemplateParamsInAlias.size(); ++Index) { + if (MarkAppeared.AppearedTemplateParams.contains( + TemplateParamsInAlias[Index])) + Results.push_back(Index); + } + return Results; +} - auto *GuideTemplate = FunctionTemplateDecl::Create( - SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide); - GuideTemplate->setImplicit(); - Guide->setDescribedFunctionTemplate(GuideTemplate); +bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext* DC) { + // Check whether we've already declared deduction guides for this template. + // FIXME: Consider storing a flag on the template to indicate this. + auto Existing = DC->lookup(Name); + for (auto *D : Existing) + if (D->isImplicit()) + return true; + return false; +} - if (isa<CXXRecordDecl>(DC)) { - Guide->setAccess(AS_public); - GuideTemplate->setAccess(AS_public); +// Build deduction guides for a type alias template. +void DeclareImplicitDeductionGuidesForTypeAlias( + Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate, SourceLocation Loc) { + auto &Context = SemaRef.Context; + // FIXME: if there is an explicit deduction guide after the first use of the + // type alias usage, we will not cover this explicit deduction guide. fix this + // case. + if (hasDeclaredDeductionGuides( + Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate), + AliasTemplate->getDeclContext())) + return; + // Unrap the sugar ElaboratedType. + auto RhsType = AliasTemplate->getTemplatedDecl() + ->getUnderlyingType() + .getSingleStepDesugaredType(Context); + TemplateDecl *Template = nullptr; + llvm::ArrayRef<TemplateArgument> AliasRhsTemplateArgs; + if (const auto *TST = RhsType->getAs<TemplateSpecializationType>()) { + // TemplateName in TEST can be a TypeAliasTemplateDecl if ---------------- cor3ntin wrote:
```suggestion // TemplateName in TST can be a TypeAliasTemplateDecl if ``` https://github.com/llvm/llvm-project/pull/77890 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits