xref: /freebsd-src/contrib/llvm-project/clang/lib/Sema/SemaTemplateDeductionGuide.cpp (revision d686ce931cab72612a9e1ada9fe99d65e11a32a3)
10fca6ea1SDimitry Andric //===- SemaTemplateDeductionGude.cpp - Template Argument Deduction---------===//
20fca6ea1SDimitry Andric //
30fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60fca6ea1SDimitry Andric //
70fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
80fca6ea1SDimitry Andric //
90fca6ea1SDimitry Andric // This file implements deduction guides for C++ class template argument
100fca6ea1SDimitry Andric // deduction.
110fca6ea1SDimitry Andric //
120fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
130fca6ea1SDimitry Andric 
140fca6ea1SDimitry Andric #include "TreeTransform.h"
150fca6ea1SDimitry Andric #include "TypeLocBuilder.h"
160fca6ea1SDimitry Andric #include "clang/AST/ASTConsumer.h"
170fca6ea1SDimitry Andric #include "clang/AST/ASTContext.h"
180fca6ea1SDimitry Andric #include "clang/AST/Decl.h"
190fca6ea1SDimitry Andric #include "clang/AST/DeclBase.h"
200fca6ea1SDimitry Andric #include "clang/AST/DeclCXX.h"
210fca6ea1SDimitry Andric #include "clang/AST/DeclFriend.h"
220fca6ea1SDimitry Andric #include "clang/AST/DeclTemplate.h"
230fca6ea1SDimitry Andric #include "clang/AST/DeclarationName.h"
240fca6ea1SDimitry Andric #include "clang/AST/Expr.h"
250fca6ea1SDimitry Andric #include "clang/AST/ExprCXX.h"
260fca6ea1SDimitry Andric #include "clang/AST/OperationKinds.h"
270fca6ea1SDimitry Andric #include "clang/AST/RecursiveASTVisitor.h"
280fca6ea1SDimitry Andric #include "clang/AST/TemplateBase.h"
290fca6ea1SDimitry Andric #include "clang/AST/TemplateName.h"
300fca6ea1SDimitry Andric #include "clang/AST/Type.h"
310fca6ea1SDimitry Andric #include "clang/AST/TypeLoc.h"
320fca6ea1SDimitry Andric #include "clang/Basic/LLVM.h"
330fca6ea1SDimitry Andric #include "clang/Basic/SourceLocation.h"
340fca6ea1SDimitry Andric #include "clang/Basic/Specifiers.h"
350fca6ea1SDimitry Andric #include "clang/Basic/TypeTraits.h"
360fca6ea1SDimitry Andric #include "clang/Sema/DeclSpec.h"
370fca6ea1SDimitry Andric #include "clang/Sema/Initialization.h"
380fca6ea1SDimitry Andric #include "clang/Sema/Lookup.h"
390fca6ea1SDimitry Andric #include "clang/Sema/Overload.h"
400fca6ea1SDimitry Andric #include "clang/Sema/Ownership.h"
410fca6ea1SDimitry Andric #include "clang/Sema/Scope.h"
420fca6ea1SDimitry Andric #include "clang/Sema/Template.h"
430fca6ea1SDimitry Andric #include "clang/Sema/TemplateDeduction.h"
440fca6ea1SDimitry Andric #include "llvm/ADT/ArrayRef.h"
450fca6ea1SDimitry Andric #include "llvm/ADT/DenseSet.h"
460fca6ea1SDimitry Andric #include "llvm/ADT/STLExtras.h"
470fca6ea1SDimitry Andric #include "llvm/ADT/SmallVector.h"
480fca6ea1SDimitry Andric #include "llvm/Support/Casting.h"
490fca6ea1SDimitry Andric #include "llvm/Support/ErrorHandling.h"
500fca6ea1SDimitry Andric #include <cassert>
510fca6ea1SDimitry Andric #include <optional>
520fca6ea1SDimitry Andric #include <utility>
530fca6ea1SDimitry Andric 
540fca6ea1SDimitry Andric using namespace clang;
550fca6ea1SDimitry Andric using namespace sema;
560fca6ea1SDimitry Andric 
570fca6ea1SDimitry Andric namespace {
580fca6ea1SDimitry Andric /// Tree transform to "extract" a transformed type from a class template's
590fca6ea1SDimitry Andric /// constructor to a deduction guide.
600fca6ea1SDimitry Andric class ExtractTypeForDeductionGuide
610fca6ea1SDimitry Andric     : public TreeTransform<ExtractTypeForDeductionGuide> {
620fca6ea1SDimitry Andric   llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs;
630fca6ea1SDimitry Andric   ClassTemplateDecl *NestedPattern;
640fca6ea1SDimitry Andric   const MultiLevelTemplateArgumentList *OuterInstantiationArgs;
650fca6ea1SDimitry Andric   std::optional<TemplateDeclInstantiator> TypedefNameInstantiator;
660fca6ea1SDimitry Andric 
670fca6ea1SDimitry Andric public:
680fca6ea1SDimitry Andric   typedef TreeTransform<ExtractTypeForDeductionGuide> Base;
690fca6ea1SDimitry Andric   ExtractTypeForDeductionGuide(
700fca6ea1SDimitry Andric       Sema &SemaRef,
710fca6ea1SDimitry Andric       llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs,
72*d686ce93SDimitry Andric       ClassTemplateDecl *NestedPattern = nullptr,
73*d686ce93SDimitry Andric       const MultiLevelTemplateArgumentList *OuterInstantiationArgs = nullptr)
740fca6ea1SDimitry Andric       : Base(SemaRef), MaterializedTypedefs(MaterializedTypedefs),
750fca6ea1SDimitry Andric         NestedPattern(NestedPattern),
760fca6ea1SDimitry Andric         OuterInstantiationArgs(OuterInstantiationArgs) {
770fca6ea1SDimitry Andric     if (OuterInstantiationArgs)
780fca6ea1SDimitry Andric       TypedefNameInstantiator.emplace(
790fca6ea1SDimitry Andric           SemaRef, SemaRef.getASTContext().getTranslationUnitDecl(),
800fca6ea1SDimitry Andric           *OuterInstantiationArgs);
810fca6ea1SDimitry Andric   }
820fca6ea1SDimitry Andric 
830fca6ea1SDimitry Andric   TypeSourceInfo *transform(TypeSourceInfo *TSI) { return TransformType(TSI); }
840fca6ea1SDimitry Andric 
850fca6ea1SDimitry Andric   /// Returns true if it's safe to substitute \p Typedef with
860fca6ea1SDimitry Andric   /// \p OuterInstantiationArgs.
870fca6ea1SDimitry Andric   bool mightReferToOuterTemplateParameters(TypedefNameDecl *Typedef) {
880fca6ea1SDimitry Andric     if (!NestedPattern)
890fca6ea1SDimitry Andric       return false;
900fca6ea1SDimitry Andric 
910fca6ea1SDimitry Andric     static auto WalkUp = [](DeclContext *DC, DeclContext *TargetDC) {
920fca6ea1SDimitry Andric       if (DC->Equals(TargetDC))
930fca6ea1SDimitry Andric         return true;
940fca6ea1SDimitry Andric       while (DC->isRecord()) {
950fca6ea1SDimitry Andric         if (DC->Equals(TargetDC))
960fca6ea1SDimitry Andric           return true;
970fca6ea1SDimitry Andric         DC = DC->getParent();
980fca6ea1SDimitry Andric       }
990fca6ea1SDimitry Andric       return false;
1000fca6ea1SDimitry Andric     };
1010fca6ea1SDimitry Andric 
1020fca6ea1SDimitry Andric     if (WalkUp(Typedef->getDeclContext(), NestedPattern->getTemplatedDecl()))
1030fca6ea1SDimitry Andric       return true;
1040fca6ea1SDimitry Andric     if (WalkUp(NestedPattern->getTemplatedDecl(), Typedef->getDeclContext()))
1050fca6ea1SDimitry Andric       return true;
1060fca6ea1SDimitry Andric     return false;
1070fca6ea1SDimitry Andric   }
1080fca6ea1SDimitry Andric 
1090fca6ea1SDimitry Andric   QualType
1100fca6ea1SDimitry Andric   RebuildTemplateSpecializationType(TemplateName Template,
1110fca6ea1SDimitry Andric                                     SourceLocation TemplateNameLoc,
1120fca6ea1SDimitry Andric                                     TemplateArgumentListInfo &TemplateArgs) {
1130fca6ea1SDimitry Andric     if (!OuterInstantiationArgs ||
1140fca6ea1SDimitry Andric         !isa_and_present<TypeAliasTemplateDecl>(Template.getAsTemplateDecl()))
1150fca6ea1SDimitry Andric       return Base::RebuildTemplateSpecializationType(Template, TemplateNameLoc,
1160fca6ea1SDimitry Andric                                                      TemplateArgs);
1170fca6ea1SDimitry Andric 
1180fca6ea1SDimitry Andric     auto *TATD = cast<TypeAliasTemplateDecl>(Template.getAsTemplateDecl());
1190fca6ea1SDimitry Andric     auto *Pattern = TATD;
1200fca6ea1SDimitry Andric     while (Pattern->getInstantiatedFromMemberTemplate())
1210fca6ea1SDimitry Andric       Pattern = Pattern->getInstantiatedFromMemberTemplate();
1220fca6ea1SDimitry Andric     if (!mightReferToOuterTemplateParameters(Pattern->getTemplatedDecl()))
1230fca6ea1SDimitry Andric       return Base::RebuildTemplateSpecializationType(Template, TemplateNameLoc,
1240fca6ea1SDimitry Andric                                                      TemplateArgs);
1250fca6ea1SDimitry Andric 
1260fca6ea1SDimitry Andric     Decl *NewD =
1270fca6ea1SDimitry Andric         TypedefNameInstantiator->InstantiateTypeAliasTemplateDecl(TATD);
1280fca6ea1SDimitry Andric     if (!NewD)
1290fca6ea1SDimitry Andric       return QualType();
1300fca6ea1SDimitry Andric 
1310fca6ea1SDimitry Andric     auto *NewTATD = cast<TypeAliasTemplateDecl>(NewD);
1320fca6ea1SDimitry Andric     MaterializedTypedefs.push_back(NewTATD->getTemplatedDecl());
1330fca6ea1SDimitry Andric 
1340fca6ea1SDimitry Andric     return Base::RebuildTemplateSpecializationType(
1350fca6ea1SDimitry Andric         TemplateName(NewTATD), TemplateNameLoc, TemplateArgs);
1360fca6ea1SDimitry Andric   }
1370fca6ea1SDimitry Andric 
1380fca6ea1SDimitry Andric   QualType TransformTypedefType(TypeLocBuilder &TLB, TypedefTypeLoc TL) {
1390fca6ea1SDimitry Andric     ASTContext &Context = SemaRef.getASTContext();
1400fca6ea1SDimitry Andric     TypedefNameDecl *OrigDecl = TL.getTypedefNameDecl();
1410fca6ea1SDimitry Andric     TypedefNameDecl *Decl = OrigDecl;
1420fca6ea1SDimitry Andric     // Transform the underlying type of the typedef and clone the Decl only if
1430fca6ea1SDimitry Andric     // the typedef has a dependent context.
1440fca6ea1SDimitry Andric     bool InDependentContext = OrigDecl->getDeclContext()->isDependentContext();
1450fca6ea1SDimitry Andric 
1460fca6ea1SDimitry Andric     // A typedef/alias Decl within the NestedPattern may reference the outer
1470fca6ea1SDimitry Andric     // template parameters. They're substituted with corresponding instantiation
1480fca6ea1SDimitry Andric     // arguments here and in RebuildTemplateSpecializationType() above.
1490fca6ea1SDimitry Andric     // Otherwise, we would have a CTAD guide with "dangling" template
1500fca6ea1SDimitry Andric     // parameters.
1510fca6ea1SDimitry Andric     // For example,
1520fca6ea1SDimitry Andric     //   template <class T> struct Outer {
1530fca6ea1SDimitry Andric     //     using Alias = S<T>;
1540fca6ea1SDimitry Andric     //     template <class U> struct Inner {
1550fca6ea1SDimitry Andric     //       Inner(Alias);
1560fca6ea1SDimitry Andric     //     };
1570fca6ea1SDimitry Andric     //   };
1580fca6ea1SDimitry Andric     if (OuterInstantiationArgs && InDependentContext &&
1590fca6ea1SDimitry Andric         TL.getTypePtr()->isInstantiationDependentType()) {
1600fca6ea1SDimitry Andric       Decl = cast_if_present<TypedefNameDecl>(
1610fca6ea1SDimitry Andric           TypedefNameInstantiator->InstantiateTypedefNameDecl(
1620fca6ea1SDimitry Andric               OrigDecl, /*IsTypeAlias=*/isa<TypeAliasDecl>(OrigDecl)));
1630fca6ea1SDimitry Andric       if (!Decl)
1640fca6ea1SDimitry Andric         return QualType();
1650fca6ea1SDimitry Andric       MaterializedTypedefs.push_back(Decl);
1660fca6ea1SDimitry Andric     } else if (InDependentContext) {
1670fca6ea1SDimitry Andric       TypeLocBuilder InnerTLB;
1680fca6ea1SDimitry Andric       QualType Transformed =
1690fca6ea1SDimitry Andric           TransformType(InnerTLB, OrigDecl->getTypeSourceInfo()->getTypeLoc());
1700fca6ea1SDimitry Andric       TypeSourceInfo *TSI = InnerTLB.getTypeSourceInfo(Context, Transformed);
1710fca6ea1SDimitry Andric       if (isa<TypeAliasDecl>(OrigDecl))
1720fca6ea1SDimitry Andric         Decl = TypeAliasDecl::Create(
1730fca6ea1SDimitry Andric             Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
1740fca6ea1SDimitry Andric             OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
1750fca6ea1SDimitry Andric       else {
1760fca6ea1SDimitry Andric         assert(isa<TypedefDecl>(OrigDecl) && "Not a Type alias or typedef");
1770fca6ea1SDimitry Andric         Decl = TypedefDecl::Create(
1780fca6ea1SDimitry Andric             Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
1790fca6ea1SDimitry Andric             OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
1800fca6ea1SDimitry Andric       }
1810fca6ea1SDimitry Andric       MaterializedTypedefs.push_back(Decl);
1820fca6ea1SDimitry Andric     }
1830fca6ea1SDimitry Andric 
1840fca6ea1SDimitry Andric     QualType TDTy = Context.getTypedefType(Decl);
1850fca6ea1SDimitry Andric     TypedefTypeLoc TypedefTL = TLB.push<TypedefTypeLoc>(TDTy);
1860fca6ea1SDimitry Andric     TypedefTL.setNameLoc(TL.getNameLoc());
1870fca6ea1SDimitry Andric 
1880fca6ea1SDimitry Andric     return TDTy;
1890fca6ea1SDimitry Andric   }
1900fca6ea1SDimitry Andric };
1910fca6ea1SDimitry Andric 
1920fca6ea1SDimitry Andric // Build a deduction guide using the provided information.
1930fca6ea1SDimitry Andric //
1940fca6ea1SDimitry Andric // A deduction guide can be either a template or a non-template function
1950fca6ea1SDimitry Andric // declaration. If \p TemplateParams is null, a non-template function
1960fca6ea1SDimitry Andric // declaration will be created.
1970fca6ea1SDimitry Andric NamedDecl *buildDeductionGuide(
1980fca6ea1SDimitry Andric     Sema &SemaRef, TemplateDecl *OriginalTemplate,
1990fca6ea1SDimitry Andric     TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor,
2000fca6ea1SDimitry Andric     ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart,
2010fca6ea1SDimitry Andric     SourceLocation Loc, SourceLocation LocEnd, bool IsImplicit,
2020fca6ea1SDimitry Andric     llvm::ArrayRef<TypedefNameDecl *> MaterializedTypedefs = {}) {
2030fca6ea1SDimitry Andric   DeclContext *DC = OriginalTemplate->getDeclContext();
2040fca6ea1SDimitry Andric   auto DeductionGuideName =
2050fca6ea1SDimitry Andric       SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(
2060fca6ea1SDimitry Andric           OriginalTemplate);
2070fca6ea1SDimitry Andric 
2080fca6ea1SDimitry Andric   DeclarationNameInfo Name(DeductionGuideName, Loc);
2090fca6ea1SDimitry Andric   ArrayRef<ParmVarDecl *> Params =
2100fca6ea1SDimitry Andric       TInfo->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams();
2110fca6ea1SDimitry Andric 
2120fca6ea1SDimitry Andric   // Build the implicit deduction guide template.
2130fca6ea1SDimitry Andric   auto *Guide =
2140fca6ea1SDimitry Andric       CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, ES, Name,
2150fca6ea1SDimitry Andric                                     TInfo->getType(), TInfo, LocEnd, Ctor);
2160fca6ea1SDimitry Andric   Guide->setImplicit(IsImplicit);
2170fca6ea1SDimitry Andric   Guide->setParams(Params);
2180fca6ea1SDimitry Andric 
2190fca6ea1SDimitry Andric   for (auto *Param : Params)
2200fca6ea1SDimitry Andric     Param->setDeclContext(Guide);
2210fca6ea1SDimitry Andric   for (auto *TD : MaterializedTypedefs)
2220fca6ea1SDimitry Andric     TD->setDeclContext(Guide);
2230fca6ea1SDimitry Andric   if (isa<CXXRecordDecl>(DC))
2240fca6ea1SDimitry Andric     Guide->setAccess(AS_public);
2250fca6ea1SDimitry Andric 
2260fca6ea1SDimitry Andric   if (!TemplateParams) {
2270fca6ea1SDimitry Andric     DC->addDecl(Guide);
2280fca6ea1SDimitry Andric     return Guide;
2290fca6ea1SDimitry Andric   }
2300fca6ea1SDimitry Andric 
2310fca6ea1SDimitry Andric   auto *GuideTemplate = FunctionTemplateDecl::Create(
2320fca6ea1SDimitry Andric       SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide);
2330fca6ea1SDimitry Andric   GuideTemplate->setImplicit(IsImplicit);
2340fca6ea1SDimitry Andric   Guide->setDescribedFunctionTemplate(GuideTemplate);
2350fca6ea1SDimitry Andric 
2360fca6ea1SDimitry Andric   if (isa<CXXRecordDecl>(DC))
2370fca6ea1SDimitry Andric     GuideTemplate->setAccess(AS_public);
2380fca6ea1SDimitry Andric 
2390fca6ea1SDimitry Andric   DC->addDecl(GuideTemplate);
2400fca6ea1SDimitry Andric   return GuideTemplate;
2410fca6ea1SDimitry Andric }
2420fca6ea1SDimitry Andric 
2430fca6ea1SDimitry Andric // Transform a given template type parameter `TTP`.
2440fca6ea1SDimitry Andric TemplateTypeParmDecl *
2450fca6ea1SDimitry Andric transformTemplateTypeParam(Sema &SemaRef, DeclContext *DC,
2460fca6ea1SDimitry Andric                            TemplateTypeParmDecl *TTP,
2470fca6ea1SDimitry Andric                            MultiLevelTemplateArgumentList &Args,
2480fca6ea1SDimitry Andric                            unsigned NewDepth, unsigned NewIndex) {
2490fca6ea1SDimitry Andric   // TemplateTypeParmDecl's index cannot be changed after creation, so
2500fca6ea1SDimitry Andric   // substitute it directly.
2510fca6ea1SDimitry Andric   auto *NewTTP = TemplateTypeParmDecl::Create(
2520fca6ea1SDimitry Andric       SemaRef.Context, DC, TTP->getBeginLoc(), TTP->getLocation(), NewDepth,
2530fca6ea1SDimitry Andric       NewIndex, TTP->getIdentifier(), TTP->wasDeclaredWithTypename(),
2540fca6ea1SDimitry Andric       TTP->isParameterPack(), TTP->hasTypeConstraint(),
2550fca6ea1SDimitry Andric       TTP->isExpandedParameterPack()
2560fca6ea1SDimitry Andric           ? std::optional<unsigned>(TTP->getNumExpansionParameters())
2570fca6ea1SDimitry Andric           : std::nullopt);
2580fca6ea1SDimitry Andric   if (const auto *TC = TTP->getTypeConstraint())
2590fca6ea1SDimitry Andric     SemaRef.SubstTypeConstraint(NewTTP, TC, Args,
2600fca6ea1SDimitry Andric                                 /*EvaluateConstraint=*/true);
2610fca6ea1SDimitry Andric   if (TTP->hasDefaultArgument()) {
2620fca6ea1SDimitry Andric     TemplateArgumentLoc InstantiatedDefaultArg;
2630fca6ea1SDimitry Andric     if (!SemaRef.SubstTemplateArgument(
2640fca6ea1SDimitry Andric             TTP->getDefaultArgument(), Args, InstantiatedDefaultArg,
2650fca6ea1SDimitry Andric             TTP->getDefaultArgumentLoc(), TTP->getDeclName()))
2660fca6ea1SDimitry Andric       NewTTP->setDefaultArgument(SemaRef.Context, InstantiatedDefaultArg);
2670fca6ea1SDimitry Andric   }
2680fca6ea1SDimitry Andric   SemaRef.CurrentInstantiationScope->InstantiatedLocal(TTP, NewTTP);
2690fca6ea1SDimitry Andric   return NewTTP;
2700fca6ea1SDimitry Andric }
2710fca6ea1SDimitry Andric // Similar to above, but for non-type template or template template parameters.
2720fca6ea1SDimitry Andric template <typename NonTypeTemplateOrTemplateTemplateParmDecl>
2730fca6ea1SDimitry Andric NonTypeTemplateOrTemplateTemplateParmDecl *
2740fca6ea1SDimitry Andric transformTemplateParam(Sema &SemaRef, DeclContext *DC,
2750fca6ea1SDimitry Andric                        NonTypeTemplateOrTemplateTemplateParmDecl *OldParam,
2760fca6ea1SDimitry Andric                        MultiLevelTemplateArgumentList &Args, unsigned NewIndex,
2770fca6ea1SDimitry Andric                        unsigned NewDepth) {
2780fca6ea1SDimitry Andric   // Ask the template instantiator to do the heavy lifting for us, then adjust
2790fca6ea1SDimitry Andric   // the index of the parameter once it's done.
2800fca6ea1SDimitry Andric   auto *NewParam = cast<NonTypeTemplateOrTemplateTemplateParmDecl>(
2810fca6ea1SDimitry Andric       SemaRef.SubstDecl(OldParam, DC, Args));
2820fca6ea1SDimitry Andric   NewParam->setPosition(NewIndex);
2830fca6ea1SDimitry Andric   NewParam->setDepth(NewDepth);
2840fca6ea1SDimitry Andric   return NewParam;
2850fca6ea1SDimitry Andric }
2860fca6ea1SDimitry Andric 
2870fca6ea1SDimitry Andric /// Transform to convert portions of a constructor declaration into the
2880fca6ea1SDimitry Andric /// corresponding deduction guide, per C++1z [over.match.class.deduct]p1.
2890fca6ea1SDimitry Andric struct ConvertConstructorToDeductionGuideTransform {
2900fca6ea1SDimitry Andric   ConvertConstructorToDeductionGuideTransform(Sema &S,
2910fca6ea1SDimitry Andric                                               ClassTemplateDecl *Template)
2920fca6ea1SDimitry Andric       : SemaRef(S), Template(Template) {
2930fca6ea1SDimitry Andric     // If the template is nested, then we need to use the original
2940fca6ea1SDimitry Andric     // pattern to iterate over the constructors.
2950fca6ea1SDimitry Andric     ClassTemplateDecl *Pattern = Template;
2960fca6ea1SDimitry Andric     while (Pattern->getInstantiatedFromMemberTemplate()) {
2970fca6ea1SDimitry Andric       if (Pattern->isMemberSpecialization())
2980fca6ea1SDimitry Andric         break;
2990fca6ea1SDimitry Andric       Pattern = Pattern->getInstantiatedFromMemberTemplate();
3000fca6ea1SDimitry Andric       NestedPattern = Pattern;
3010fca6ea1SDimitry Andric     }
3020fca6ea1SDimitry Andric 
3030fca6ea1SDimitry Andric     if (NestedPattern)
3040fca6ea1SDimitry Andric       OuterInstantiationArgs = SemaRef.getTemplateInstantiationArgs(Template);
3050fca6ea1SDimitry Andric   }
3060fca6ea1SDimitry Andric 
3070fca6ea1SDimitry Andric   Sema &SemaRef;
3080fca6ea1SDimitry Andric   ClassTemplateDecl *Template;
3090fca6ea1SDimitry Andric   ClassTemplateDecl *NestedPattern = nullptr;
3100fca6ea1SDimitry Andric 
3110fca6ea1SDimitry Andric   DeclContext *DC = Template->getDeclContext();
3120fca6ea1SDimitry Andric   CXXRecordDecl *Primary = Template->getTemplatedDecl();
3130fca6ea1SDimitry Andric   DeclarationName DeductionGuideName =
3140fca6ea1SDimitry Andric       SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(Template);
3150fca6ea1SDimitry Andric 
3160fca6ea1SDimitry Andric   QualType DeducedType = SemaRef.Context.getTypeDeclType(Primary);
3170fca6ea1SDimitry Andric 
3180fca6ea1SDimitry Andric   // Index adjustment to apply to convert depth-1 template parameters into
3190fca6ea1SDimitry Andric   // depth-0 template parameters.
3200fca6ea1SDimitry Andric   unsigned Depth1IndexAdjustment = Template->getTemplateParameters()->size();
3210fca6ea1SDimitry Andric 
3220fca6ea1SDimitry Andric   // Instantiation arguments for the outermost depth-1 templates
3230fca6ea1SDimitry Andric   // when the template is nested
3240fca6ea1SDimitry Andric   MultiLevelTemplateArgumentList OuterInstantiationArgs;
3250fca6ea1SDimitry Andric 
3260fca6ea1SDimitry Andric   /// Transform a constructor declaration into a deduction guide.
3270fca6ea1SDimitry Andric   NamedDecl *transformConstructor(FunctionTemplateDecl *FTD,
3280fca6ea1SDimitry Andric                                   CXXConstructorDecl *CD) {
3290fca6ea1SDimitry Andric     SmallVector<TemplateArgument, 16> SubstArgs;
3300fca6ea1SDimitry Andric 
3310fca6ea1SDimitry Andric     LocalInstantiationScope Scope(SemaRef);
3320fca6ea1SDimitry Andric 
3330fca6ea1SDimitry Andric     // C++ [over.match.class.deduct]p1:
3340fca6ea1SDimitry Andric     // -- For each constructor of the class template designated by the
3350fca6ea1SDimitry Andric     //    template-name, a function template with the following properties:
3360fca6ea1SDimitry Andric 
3370fca6ea1SDimitry Andric     //    -- The template parameters are the template parameters of the class
3380fca6ea1SDimitry Andric     //       template followed by the template parameters (including default
3390fca6ea1SDimitry Andric     //       template arguments) of the constructor, if any.
3400fca6ea1SDimitry Andric     TemplateParameterList *TemplateParams =
3410fca6ea1SDimitry Andric         SemaRef.GetTemplateParameterList(Template);
3420fca6ea1SDimitry Andric     if (FTD) {
3430fca6ea1SDimitry Andric       TemplateParameterList *InnerParams = FTD->getTemplateParameters();
3440fca6ea1SDimitry Andric       SmallVector<NamedDecl *, 16> AllParams;
3450fca6ea1SDimitry Andric       SmallVector<TemplateArgument, 16> Depth1Args;
3460fca6ea1SDimitry Andric       AllParams.reserve(TemplateParams->size() + InnerParams->size());
3470fca6ea1SDimitry Andric       AllParams.insert(AllParams.begin(), TemplateParams->begin(),
3480fca6ea1SDimitry Andric                        TemplateParams->end());
3490fca6ea1SDimitry Andric       SubstArgs.reserve(InnerParams->size());
3500fca6ea1SDimitry Andric       Depth1Args.reserve(InnerParams->size());
3510fca6ea1SDimitry Andric 
3520fca6ea1SDimitry Andric       // Later template parameters could refer to earlier ones, so build up
3530fca6ea1SDimitry Andric       // a list of substituted template arguments as we go.
3540fca6ea1SDimitry Andric       for (NamedDecl *Param : *InnerParams) {
3550fca6ea1SDimitry Andric         MultiLevelTemplateArgumentList Args;
3560fca6ea1SDimitry Andric         Args.setKind(TemplateSubstitutionKind::Rewrite);
3570fca6ea1SDimitry Andric         Args.addOuterTemplateArguments(Depth1Args);
3580fca6ea1SDimitry Andric         Args.addOuterRetainedLevel();
3590fca6ea1SDimitry Andric         if (NestedPattern)
3600fca6ea1SDimitry Andric           Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
3610fca6ea1SDimitry Andric         NamedDecl *NewParam = transformTemplateParameter(Param, Args);
3620fca6ea1SDimitry Andric         if (!NewParam)
3630fca6ea1SDimitry Andric           return nullptr;
3640fca6ea1SDimitry Andric         // Constraints require that we substitute depth-1 arguments
3650fca6ea1SDimitry Andric         // to match depths when substituted for evaluation later
3660fca6ea1SDimitry Andric         Depth1Args.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam));
3670fca6ea1SDimitry Andric 
3680fca6ea1SDimitry Andric         if (NestedPattern) {
3690fca6ea1SDimitry Andric           TemplateDeclInstantiator Instantiator(SemaRef, DC,
3700fca6ea1SDimitry Andric                                                 OuterInstantiationArgs);
3710fca6ea1SDimitry Andric           Instantiator.setEvaluateConstraints(false);
3720fca6ea1SDimitry Andric           SemaRef.runWithSufficientStackSpace(NewParam->getLocation(), [&] {
3730fca6ea1SDimitry Andric             NewParam = cast<NamedDecl>(Instantiator.Visit(NewParam));
3740fca6ea1SDimitry Andric           });
3750fca6ea1SDimitry Andric         }
3760fca6ea1SDimitry Andric 
3770fca6ea1SDimitry Andric         assert(NewParam->getTemplateDepth() == 0 &&
3780fca6ea1SDimitry Andric                "Unexpected template parameter depth");
3790fca6ea1SDimitry Andric 
3800fca6ea1SDimitry Andric         AllParams.push_back(NewParam);
3810fca6ea1SDimitry Andric         SubstArgs.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam));
3820fca6ea1SDimitry Andric       }
3830fca6ea1SDimitry Andric 
3840fca6ea1SDimitry Andric       // Substitute new template parameters into requires-clause if present.
3850fca6ea1SDimitry Andric       Expr *RequiresClause = nullptr;
3860fca6ea1SDimitry Andric       if (Expr *InnerRC = InnerParams->getRequiresClause()) {
3870fca6ea1SDimitry Andric         MultiLevelTemplateArgumentList Args;
3880fca6ea1SDimitry Andric         Args.setKind(TemplateSubstitutionKind::Rewrite);
3890fca6ea1SDimitry Andric         Args.addOuterTemplateArguments(Depth1Args);
3900fca6ea1SDimitry Andric         Args.addOuterRetainedLevel();
3910fca6ea1SDimitry Andric         if (NestedPattern)
3920fca6ea1SDimitry Andric           Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
3930fca6ea1SDimitry Andric         ExprResult E = SemaRef.SubstExpr(InnerRC, Args);
3940fca6ea1SDimitry Andric         if (E.isInvalid())
3950fca6ea1SDimitry Andric           return nullptr;
3960fca6ea1SDimitry Andric         RequiresClause = E.getAs<Expr>();
3970fca6ea1SDimitry Andric       }
3980fca6ea1SDimitry Andric 
3990fca6ea1SDimitry Andric       TemplateParams = TemplateParameterList::Create(
4000fca6ea1SDimitry Andric           SemaRef.Context, InnerParams->getTemplateLoc(),
4010fca6ea1SDimitry Andric           InnerParams->getLAngleLoc(), AllParams, InnerParams->getRAngleLoc(),
4020fca6ea1SDimitry Andric           RequiresClause);
4030fca6ea1SDimitry Andric     }
4040fca6ea1SDimitry Andric 
4050fca6ea1SDimitry Andric     // If we built a new template-parameter-list, track that we need to
4060fca6ea1SDimitry Andric     // substitute references to the old parameters into references to the
4070fca6ea1SDimitry Andric     // new ones.
4080fca6ea1SDimitry Andric     MultiLevelTemplateArgumentList Args;
4090fca6ea1SDimitry Andric     Args.setKind(TemplateSubstitutionKind::Rewrite);
4100fca6ea1SDimitry Andric     if (FTD) {
4110fca6ea1SDimitry Andric       Args.addOuterTemplateArguments(SubstArgs);
4120fca6ea1SDimitry Andric       Args.addOuterRetainedLevel();
4130fca6ea1SDimitry Andric     }
4140fca6ea1SDimitry Andric 
4150fca6ea1SDimitry Andric     FunctionProtoTypeLoc FPTL = CD->getTypeSourceInfo()
4160fca6ea1SDimitry Andric                                     ->getTypeLoc()
4170fca6ea1SDimitry Andric                                     .getAsAdjusted<FunctionProtoTypeLoc>();
4180fca6ea1SDimitry Andric     assert(FPTL && "no prototype for constructor declaration");
4190fca6ea1SDimitry Andric 
4200fca6ea1SDimitry Andric     // Transform the type of the function, adjusting the return type and
4210fca6ea1SDimitry Andric     // replacing references to the old parameters with references to the
4220fca6ea1SDimitry Andric     // new ones.
4230fca6ea1SDimitry Andric     TypeLocBuilder TLB;
4240fca6ea1SDimitry Andric     SmallVector<ParmVarDecl *, 8> Params;
4250fca6ea1SDimitry Andric     SmallVector<TypedefNameDecl *, 4> MaterializedTypedefs;
4260fca6ea1SDimitry Andric     QualType NewType = transformFunctionProtoType(TLB, FPTL, Params, Args,
4270fca6ea1SDimitry Andric                                                   MaterializedTypedefs);
4280fca6ea1SDimitry Andric     if (NewType.isNull())
4290fca6ea1SDimitry Andric       return nullptr;
4300fca6ea1SDimitry Andric     TypeSourceInfo *NewTInfo = TLB.getTypeSourceInfo(SemaRef.Context, NewType);
4310fca6ea1SDimitry Andric 
4320fca6ea1SDimitry Andric     return buildDeductionGuide(
4330fca6ea1SDimitry Andric         SemaRef, Template, TemplateParams, CD, CD->getExplicitSpecifier(),
4340fca6ea1SDimitry Andric         NewTInfo, CD->getBeginLoc(), CD->getLocation(), CD->getEndLoc(),
4350fca6ea1SDimitry Andric         /*IsImplicit=*/true, MaterializedTypedefs);
4360fca6ea1SDimitry Andric   }
4370fca6ea1SDimitry Andric 
4380fca6ea1SDimitry Andric   /// Build a deduction guide with the specified parameter types.
4390fca6ea1SDimitry Andric   NamedDecl *buildSimpleDeductionGuide(MutableArrayRef<QualType> ParamTypes) {
4400fca6ea1SDimitry Andric     SourceLocation Loc = Template->getLocation();
4410fca6ea1SDimitry Andric 
4420fca6ea1SDimitry Andric     // Build the requested type.
4430fca6ea1SDimitry Andric     FunctionProtoType::ExtProtoInfo EPI;
4440fca6ea1SDimitry Andric     EPI.HasTrailingReturn = true;
4450fca6ea1SDimitry Andric     QualType Result = SemaRef.BuildFunctionType(DeducedType, ParamTypes, Loc,
4460fca6ea1SDimitry Andric                                                 DeductionGuideName, EPI);
4470fca6ea1SDimitry Andric     TypeSourceInfo *TSI = SemaRef.Context.getTrivialTypeSourceInfo(Result, Loc);
4480fca6ea1SDimitry Andric     if (NestedPattern)
4490fca6ea1SDimitry Andric       TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,
4500fca6ea1SDimitry Andric                               DeductionGuideName);
4510fca6ea1SDimitry Andric 
4520fca6ea1SDimitry Andric     if (!TSI)
4530fca6ea1SDimitry Andric       return nullptr;
4540fca6ea1SDimitry Andric 
4550fca6ea1SDimitry Andric     FunctionProtoTypeLoc FPTL =
4560fca6ea1SDimitry Andric         TSI->getTypeLoc().castAs<FunctionProtoTypeLoc>();
4570fca6ea1SDimitry Andric 
4580fca6ea1SDimitry Andric     // Build the parameters, needed during deduction / substitution.
4590fca6ea1SDimitry Andric     SmallVector<ParmVarDecl *, 4> Params;
4600fca6ea1SDimitry Andric     for (auto T : ParamTypes) {
4610fca6ea1SDimitry Andric       auto *TSI = SemaRef.Context.getTrivialTypeSourceInfo(T, Loc);
4620fca6ea1SDimitry Andric       if (NestedPattern)
4630fca6ea1SDimitry Andric         TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,
4640fca6ea1SDimitry Andric                                 DeclarationName());
4650fca6ea1SDimitry Andric       if (!TSI)
4660fca6ea1SDimitry Andric         return nullptr;
4670fca6ea1SDimitry Andric 
4680fca6ea1SDimitry Andric       ParmVarDecl *NewParam =
4690fca6ea1SDimitry Andric           ParmVarDecl::Create(SemaRef.Context, DC, Loc, Loc, nullptr,
4700fca6ea1SDimitry Andric                               TSI->getType(), TSI, SC_None, nullptr);
4710fca6ea1SDimitry Andric       NewParam->setScopeInfo(0, Params.size());
4720fca6ea1SDimitry Andric       FPTL.setParam(Params.size(), NewParam);
4730fca6ea1SDimitry Andric       Params.push_back(NewParam);
4740fca6ea1SDimitry Andric     }
4750fca6ea1SDimitry Andric 
4760fca6ea1SDimitry Andric     return buildDeductionGuide(
4770fca6ea1SDimitry Andric         SemaRef, Template, SemaRef.GetTemplateParameterList(Template), nullptr,
4780fca6ea1SDimitry Andric         ExplicitSpecifier(), TSI, Loc, Loc, Loc, /*IsImplicit=*/true);
4790fca6ea1SDimitry Andric   }
4800fca6ea1SDimitry Andric 
4810fca6ea1SDimitry Andric private:
4820fca6ea1SDimitry Andric   /// Transform a constructor template parameter into a deduction guide template
4830fca6ea1SDimitry Andric   /// parameter, rebuilding any internal references to earlier parameters and
4840fca6ea1SDimitry Andric   /// renumbering as we go.
4850fca6ea1SDimitry Andric   NamedDecl *transformTemplateParameter(NamedDecl *TemplateParam,
4860fca6ea1SDimitry Andric                                         MultiLevelTemplateArgumentList &Args) {
4870fca6ea1SDimitry Andric     if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
4880fca6ea1SDimitry Andric       return transformTemplateTypeParam(
4890fca6ea1SDimitry Andric           SemaRef, DC, TTP, Args, TTP->getDepth() - 1,
4900fca6ea1SDimitry Andric           Depth1IndexAdjustment + TTP->getIndex());
4910fca6ea1SDimitry Andric     if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
4920fca6ea1SDimitry Andric       return transformTemplateParam(SemaRef, DC, TTP, Args,
4930fca6ea1SDimitry Andric                                     Depth1IndexAdjustment + TTP->getIndex(),
4940fca6ea1SDimitry Andric                                     TTP->getDepth() - 1);
4950fca6ea1SDimitry Andric     auto *NTTP = cast<NonTypeTemplateParmDecl>(TemplateParam);
4960fca6ea1SDimitry Andric     return transformTemplateParam(SemaRef, DC, NTTP, Args,
4970fca6ea1SDimitry Andric                                   Depth1IndexAdjustment + NTTP->getIndex(),
4980fca6ea1SDimitry Andric                                   NTTP->getDepth() - 1);
4990fca6ea1SDimitry Andric   }
5000fca6ea1SDimitry Andric 
5010fca6ea1SDimitry Andric   QualType transformFunctionProtoType(
5020fca6ea1SDimitry Andric       TypeLocBuilder &TLB, FunctionProtoTypeLoc TL,
5030fca6ea1SDimitry Andric       SmallVectorImpl<ParmVarDecl *> &Params,
5040fca6ea1SDimitry Andric       MultiLevelTemplateArgumentList &Args,
5050fca6ea1SDimitry Andric       SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs) {
5060fca6ea1SDimitry Andric     SmallVector<QualType, 4> ParamTypes;
5070fca6ea1SDimitry Andric     const FunctionProtoType *T = TL.getTypePtr();
5080fca6ea1SDimitry Andric 
5090fca6ea1SDimitry Andric     //    -- The types of the function parameters are those of the constructor.
5100fca6ea1SDimitry Andric     for (auto *OldParam : TL.getParams()) {
5110fca6ea1SDimitry Andric       ParmVarDecl *NewParam = OldParam;
5120fca6ea1SDimitry Andric       // Given
5130fca6ea1SDimitry Andric       //   template <class T> struct C {
5140fca6ea1SDimitry Andric       //     template <class U> struct D {
5150fca6ea1SDimitry Andric       //       template <class V> D(U, V);
5160fca6ea1SDimitry Andric       //     };
5170fca6ea1SDimitry Andric       //   };
5180fca6ea1SDimitry Andric       // First, transform all the references to template parameters that are
5190fca6ea1SDimitry Andric       // defined outside of the surrounding class template. That is T in the
5200fca6ea1SDimitry Andric       // above example.
5210fca6ea1SDimitry Andric       if (NestedPattern) {
5220fca6ea1SDimitry Andric         NewParam = transformFunctionTypeParam(
5230fca6ea1SDimitry Andric             NewParam, OuterInstantiationArgs, MaterializedTypedefs,
5240fca6ea1SDimitry Andric             /*TransformingOuterPatterns=*/true);
5250fca6ea1SDimitry Andric         if (!NewParam)
5260fca6ea1SDimitry Andric           return QualType();
5270fca6ea1SDimitry Andric       }
5280fca6ea1SDimitry Andric       // Then, transform all the references to template parameters that are
5290fca6ea1SDimitry Andric       // defined at the class template and the constructor. In this example,
5300fca6ea1SDimitry Andric       // they're U and V, respectively.
5310fca6ea1SDimitry Andric       NewParam =
5320fca6ea1SDimitry Andric           transformFunctionTypeParam(NewParam, Args, MaterializedTypedefs,
5330fca6ea1SDimitry Andric                                      /*TransformingOuterPatterns=*/false);
5340fca6ea1SDimitry Andric       if (!NewParam)
5350fca6ea1SDimitry Andric         return QualType();
5360fca6ea1SDimitry Andric       ParamTypes.push_back(NewParam->getType());
5370fca6ea1SDimitry Andric       Params.push_back(NewParam);
5380fca6ea1SDimitry Andric     }
5390fca6ea1SDimitry Andric 
5400fca6ea1SDimitry Andric     //    -- The return type is the class template specialization designated by
5410fca6ea1SDimitry Andric     //       the template-name and template arguments corresponding to the
5420fca6ea1SDimitry Andric     //       template parameters obtained from the class template.
5430fca6ea1SDimitry Andric     //
5440fca6ea1SDimitry Andric     // We use the injected-class-name type of the primary template instead.
5450fca6ea1SDimitry Andric     // This has the convenient property that it is different from any type that
5460fca6ea1SDimitry Andric     // the user can write in a deduction-guide (because they cannot enter the
5470fca6ea1SDimitry Andric     // context of the template), so implicit deduction guides can never collide
5480fca6ea1SDimitry Andric     // with explicit ones.
5490fca6ea1SDimitry Andric     QualType ReturnType = DeducedType;
5500fca6ea1SDimitry Andric     TLB.pushTypeSpec(ReturnType).setNameLoc(Primary->getLocation());
5510fca6ea1SDimitry Andric 
5520fca6ea1SDimitry Andric     // Resolving a wording defect, we also inherit the variadicness of the
5530fca6ea1SDimitry Andric     // constructor.
5540fca6ea1SDimitry Andric     FunctionProtoType::ExtProtoInfo EPI;
5550fca6ea1SDimitry Andric     EPI.Variadic = T->isVariadic();
5560fca6ea1SDimitry Andric     EPI.HasTrailingReturn = true;
5570fca6ea1SDimitry Andric 
5580fca6ea1SDimitry Andric     QualType Result = SemaRef.BuildFunctionType(
5590fca6ea1SDimitry Andric         ReturnType, ParamTypes, TL.getBeginLoc(), DeductionGuideName, EPI);
5600fca6ea1SDimitry Andric     if (Result.isNull())
5610fca6ea1SDimitry Andric       return QualType();
5620fca6ea1SDimitry Andric 
5630fca6ea1SDimitry Andric     FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
5640fca6ea1SDimitry Andric     NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
5650fca6ea1SDimitry Andric     NewTL.setLParenLoc(TL.getLParenLoc());
5660fca6ea1SDimitry Andric     NewTL.setRParenLoc(TL.getRParenLoc());
5670fca6ea1SDimitry Andric     NewTL.setExceptionSpecRange(SourceRange());
5680fca6ea1SDimitry Andric     NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
5690fca6ea1SDimitry Andric     for (unsigned I = 0, E = NewTL.getNumParams(); I != E; ++I)
5700fca6ea1SDimitry Andric       NewTL.setParam(I, Params[I]);
5710fca6ea1SDimitry Andric 
5720fca6ea1SDimitry Andric     return Result;
5730fca6ea1SDimitry Andric   }
5740fca6ea1SDimitry Andric 
5750fca6ea1SDimitry Andric   ParmVarDecl *transformFunctionTypeParam(
5760fca6ea1SDimitry Andric       ParmVarDecl *OldParam, MultiLevelTemplateArgumentList &Args,
5770fca6ea1SDimitry Andric       llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs,
5780fca6ea1SDimitry Andric       bool TransformingOuterPatterns) {
5790fca6ea1SDimitry Andric     TypeSourceInfo *OldDI = OldParam->getTypeSourceInfo();
5800fca6ea1SDimitry Andric     TypeSourceInfo *NewDI;
5810fca6ea1SDimitry Andric     if (auto PackTL = OldDI->getTypeLoc().getAs<PackExpansionTypeLoc>()) {
5820fca6ea1SDimitry Andric       // Expand out the one and only element in each inner pack.
5830fca6ea1SDimitry Andric       Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, 0);
5840fca6ea1SDimitry Andric       NewDI =
5850fca6ea1SDimitry Andric           SemaRef.SubstType(PackTL.getPatternLoc(), Args,
5860fca6ea1SDimitry Andric                             OldParam->getLocation(), OldParam->getDeclName());
5870fca6ea1SDimitry Andric       if (!NewDI)
5880fca6ea1SDimitry Andric         return nullptr;
5890fca6ea1SDimitry Andric       NewDI =
5900fca6ea1SDimitry Andric           SemaRef.CheckPackExpansion(NewDI, PackTL.getEllipsisLoc(),
5910fca6ea1SDimitry Andric                                      PackTL.getTypePtr()->getNumExpansions());
5920fca6ea1SDimitry Andric     } else
5930fca6ea1SDimitry Andric       NewDI = SemaRef.SubstType(OldDI, Args, OldParam->getLocation(),
5940fca6ea1SDimitry Andric                                 OldParam->getDeclName());
5950fca6ea1SDimitry Andric     if (!NewDI)
5960fca6ea1SDimitry Andric       return nullptr;
5970fca6ea1SDimitry Andric 
5980fca6ea1SDimitry Andric     // Extract the type. This (for instance) replaces references to typedef
5990fca6ea1SDimitry Andric     // members of the current instantiations with the definitions of those
6000fca6ea1SDimitry Andric     // typedefs, avoiding triggering instantiation of the deduced type during
6010fca6ea1SDimitry Andric     // deduction.
6020fca6ea1SDimitry Andric     NewDI = ExtractTypeForDeductionGuide(
6030fca6ea1SDimitry Andric                 SemaRef, MaterializedTypedefs, NestedPattern,
6040fca6ea1SDimitry Andric                 TransformingOuterPatterns ? &Args : nullptr)
6050fca6ea1SDimitry Andric                 .transform(NewDI);
6060fca6ea1SDimitry Andric 
6070fca6ea1SDimitry Andric     // Resolving a wording defect, we also inherit default arguments from the
6080fca6ea1SDimitry Andric     // constructor.
6090fca6ea1SDimitry Andric     ExprResult NewDefArg;
6100fca6ea1SDimitry Andric     if (OldParam->hasDefaultArg()) {
6110fca6ea1SDimitry Andric       // We don't care what the value is (we won't use it); just create a
6120fca6ea1SDimitry Andric       // placeholder to indicate there is a default argument.
6130fca6ea1SDimitry Andric       QualType ParamTy = NewDI->getType();
6140fca6ea1SDimitry Andric       NewDefArg = new (SemaRef.Context)
6150fca6ea1SDimitry Andric           OpaqueValueExpr(OldParam->getDefaultArgRange().getBegin(),
6160fca6ea1SDimitry Andric                           ParamTy.getNonLValueExprType(SemaRef.Context),
6170fca6ea1SDimitry Andric                           ParamTy->isLValueReferenceType()   ? VK_LValue
6180fca6ea1SDimitry Andric                           : ParamTy->isRValueReferenceType() ? VK_XValue
6190fca6ea1SDimitry Andric                                                              : VK_PRValue);
6200fca6ea1SDimitry Andric     }
6210fca6ea1SDimitry Andric     // Handle arrays and functions decay.
6220fca6ea1SDimitry Andric     auto NewType = NewDI->getType();
6230fca6ea1SDimitry Andric     if (NewType->isArrayType() || NewType->isFunctionType())
6240fca6ea1SDimitry Andric       NewType = SemaRef.Context.getDecayedType(NewType);
6250fca6ea1SDimitry Andric 
6260fca6ea1SDimitry Andric     ParmVarDecl *NewParam = ParmVarDecl::Create(
6270fca6ea1SDimitry Andric         SemaRef.Context, DC, OldParam->getInnerLocStart(),
6280fca6ea1SDimitry Andric         OldParam->getLocation(), OldParam->getIdentifier(), NewType, NewDI,
6290fca6ea1SDimitry Andric         OldParam->getStorageClass(), NewDefArg.get());
6300fca6ea1SDimitry Andric     NewParam->setScopeInfo(OldParam->getFunctionScopeDepth(),
6310fca6ea1SDimitry Andric                            OldParam->getFunctionScopeIndex());
6320fca6ea1SDimitry Andric     SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam);
6330fca6ea1SDimitry Andric     return NewParam;
6340fca6ea1SDimitry Andric   }
6350fca6ea1SDimitry Andric };
6360fca6ea1SDimitry Andric 
6370fca6ea1SDimitry Andric unsigned getTemplateParameterDepth(NamedDecl *TemplateParam) {
6380fca6ea1SDimitry Andric   if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
6390fca6ea1SDimitry Andric     return TTP->getDepth();
6400fca6ea1SDimitry Andric   if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
6410fca6ea1SDimitry Andric     return TTP->getDepth();
6420fca6ea1SDimitry Andric   if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
6430fca6ea1SDimitry Andric     return NTTP->getDepth();
6440fca6ea1SDimitry Andric   llvm_unreachable("Unhandled template parameter types");
6450fca6ea1SDimitry Andric }
6460fca6ea1SDimitry Andric 
6470fca6ea1SDimitry Andric unsigned getTemplateParameterIndex(NamedDecl *TemplateParam) {
6480fca6ea1SDimitry Andric   if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
6490fca6ea1SDimitry Andric     return TTP->getIndex();
6500fca6ea1SDimitry Andric   if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
6510fca6ea1SDimitry Andric     return TTP->getIndex();
6520fca6ea1SDimitry Andric   if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
6530fca6ea1SDimitry Andric     return NTTP->getIndex();
6540fca6ea1SDimitry Andric   llvm_unreachable("Unhandled template parameter types");
6550fca6ea1SDimitry Andric }
6560fca6ea1SDimitry Andric 
6570fca6ea1SDimitry Andric // Find all template parameters that appear in the given DeducedArgs.
6580fca6ea1SDimitry Andric // Return the indices of the template parameters in the TemplateParams.
6590fca6ea1SDimitry Andric SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
6600fca6ea1SDimitry Andric     const TemplateParameterList *TemplateParamsList,
6610fca6ea1SDimitry Andric     ArrayRef<TemplateArgument> DeducedArgs) {
6620fca6ea1SDimitry Andric   struct TemplateParamsReferencedFinder
6630fca6ea1SDimitry Andric       : public RecursiveASTVisitor<TemplateParamsReferencedFinder> {
6640fca6ea1SDimitry Andric     const TemplateParameterList *TemplateParamList;
6650fca6ea1SDimitry Andric     llvm::BitVector ReferencedTemplateParams;
6660fca6ea1SDimitry Andric 
6670fca6ea1SDimitry Andric     TemplateParamsReferencedFinder(
6680fca6ea1SDimitry Andric         const TemplateParameterList *TemplateParamList)
6690fca6ea1SDimitry Andric         : TemplateParamList(TemplateParamList),
6700fca6ea1SDimitry Andric           ReferencedTemplateParams(TemplateParamList->size()) {}
6710fca6ea1SDimitry Andric 
6720fca6ea1SDimitry Andric     bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) {
6730fca6ea1SDimitry Andric       // We use the index and depth to retrieve the corresponding template
6740fca6ea1SDimitry Andric       // parameter from the parameter list, which is more robost.
6750fca6ea1SDimitry Andric       Mark(TTP->getDepth(), TTP->getIndex());
6760fca6ea1SDimitry Andric       return true;
6770fca6ea1SDimitry Andric     }
6780fca6ea1SDimitry Andric 
6790fca6ea1SDimitry Andric     bool VisitDeclRefExpr(DeclRefExpr *DRE) {
6800fca6ea1SDimitry Andric       MarkAppeared(DRE->getFoundDecl());
6810fca6ea1SDimitry Andric       return true;
6820fca6ea1SDimitry Andric     }
6830fca6ea1SDimitry Andric 
6840fca6ea1SDimitry Andric     bool TraverseTemplateName(TemplateName Template) {
6850fca6ea1SDimitry Andric       if (auto *TD = Template.getAsTemplateDecl())
6860fca6ea1SDimitry Andric         MarkAppeared(TD);
6870fca6ea1SDimitry Andric       return RecursiveASTVisitor::TraverseTemplateName(Template);
6880fca6ea1SDimitry Andric     }
6890fca6ea1SDimitry Andric 
6900fca6ea1SDimitry Andric     void MarkAppeared(NamedDecl *ND) {
6910fca6ea1SDimitry Andric       if (llvm::isa<NonTypeTemplateParmDecl, TemplateTypeParmDecl,
6920fca6ea1SDimitry Andric                     TemplateTemplateParmDecl>(ND))
6930fca6ea1SDimitry Andric         Mark(getTemplateParameterDepth(ND), getTemplateParameterIndex(ND));
6940fca6ea1SDimitry Andric     }
6950fca6ea1SDimitry Andric     void Mark(unsigned Depth, unsigned Index) {
6960fca6ea1SDimitry Andric       if (Index < TemplateParamList->size() &&
6970fca6ea1SDimitry Andric           TemplateParamList->getParam(Index)->getTemplateDepth() == Depth)
6980fca6ea1SDimitry Andric         ReferencedTemplateParams.set(Index);
6990fca6ea1SDimitry Andric     }
7000fca6ea1SDimitry Andric   };
7010fca6ea1SDimitry Andric   TemplateParamsReferencedFinder Finder(TemplateParamsList);
7020fca6ea1SDimitry Andric   Finder.TraverseTemplateArguments(DeducedArgs);
7030fca6ea1SDimitry Andric 
7040fca6ea1SDimitry Andric   SmallVector<unsigned> Results;
7050fca6ea1SDimitry Andric   for (unsigned Index = 0; Index < TemplateParamsList->size(); ++Index) {
7060fca6ea1SDimitry Andric     if (Finder.ReferencedTemplateParams[Index])
7070fca6ea1SDimitry Andric       Results.push_back(Index);
7080fca6ea1SDimitry Andric   }
7090fca6ea1SDimitry Andric   return Results;
7100fca6ea1SDimitry Andric }
7110fca6ea1SDimitry Andric 
7120fca6ea1SDimitry Andric bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) {
7130fca6ea1SDimitry Andric   // Check whether we've already declared deduction guides for this template.
7140fca6ea1SDimitry Andric   // FIXME: Consider storing a flag on the template to indicate this.
7150fca6ea1SDimitry Andric   assert(Name.getNameKind() ==
7160fca6ea1SDimitry Andric              DeclarationName::NameKind::CXXDeductionGuideName &&
7170fca6ea1SDimitry Andric          "name must be a deduction guide name");
7180fca6ea1SDimitry Andric   auto Existing = DC->lookup(Name);
7190fca6ea1SDimitry Andric   for (auto *D : Existing)
7200fca6ea1SDimitry Andric     if (D->isImplicit())
7210fca6ea1SDimitry Andric       return true;
7220fca6ea1SDimitry Andric   return false;
7230fca6ea1SDimitry Andric }
7240fca6ea1SDimitry Andric 
7250fca6ea1SDimitry Andric NamedDecl *transformTemplateParameter(Sema &SemaRef, DeclContext *DC,
7260fca6ea1SDimitry Andric                                       NamedDecl *TemplateParam,
7270fca6ea1SDimitry Andric                                       MultiLevelTemplateArgumentList &Args,
7280fca6ea1SDimitry Andric                                       unsigned NewIndex, unsigned NewDepth) {
7290fca6ea1SDimitry Andric   if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
7300fca6ea1SDimitry Andric     return transformTemplateTypeParam(SemaRef, DC, TTP, Args, NewDepth,
7310fca6ea1SDimitry Andric                                       NewIndex);
7320fca6ea1SDimitry Andric   if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
7330fca6ea1SDimitry Andric     return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex, NewDepth);
7340fca6ea1SDimitry Andric   if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
7350fca6ea1SDimitry Andric     return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex, NewDepth);
7360fca6ea1SDimitry Andric   llvm_unreachable("Unhandled template parameter types");
7370fca6ea1SDimitry Andric }
7380fca6ea1SDimitry Andric 
7390fca6ea1SDimitry Andric // Build the associated constraints for the alias deduction guides.
7400fca6ea1SDimitry Andric // C++ [over.match.class.deduct]p3.3:
7410fca6ea1SDimitry Andric //   The associated constraints ([temp.constr.decl]) are the conjunction of the
7420fca6ea1SDimitry Andric //   associated constraints of g and a constraint that is satisfied if and only
7430fca6ea1SDimitry Andric //   if the arguments of A are deducible (see below) from the return type.
7440fca6ea1SDimitry Andric //
7450fca6ea1SDimitry Andric // The return result is expected to be the require-clause for the synthesized
7460fca6ea1SDimitry Andric // alias deduction guide.
7470fca6ea1SDimitry Andric Expr *
7480fca6ea1SDimitry Andric buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F,
7490fca6ea1SDimitry Andric                            TypeAliasTemplateDecl *AliasTemplate,
7500fca6ea1SDimitry Andric                            ArrayRef<DeducedTemplateArgument> DeduceResults,
7510fca6ea1SDimitry Andric                            unsigned FirstUndeducedParamIdx, Expr *IsDeducible) {
7520fca6ea1SDimitry Andric   Expr *RC = F->getTemplateParameters()->getRequiresClause();
7530fca6ea1SDimitry Andric   if (!RC)
7540fca6ea1SDimitry Andric     return IsDeducible;
7550fca6ea1SDimitry Andric 
7560fca6ea1SDimitry Andric   ASTContext &Context = SemaRef.Context;
7570fca6ea1SDimitry Andric   LocalInstantiationScope Scope(SemaRef);
7580fca6ea1SDimitry Andric 
7590fca6ea1SDimitry Andric   // In the clang AST, constraint nodes are deliberately not instantiated unless
7600fca6ea1SDimitry Andric   // they are actively being evaluated. Consequently, occurrences of template
7610fca6ea1SDimitry Andric   // parameters in the require-clause expression have a subtle "depth"
7620fca6ea1SDimitry Andric   // difference compared to normal occurrences in places, such as function
7630fca6ea1SDimitry Andric   // parameters. When transforming the require-clause, we must take this
7640fca6ea1SDimitry Andric   // distinction into account:
7650fca6ea1SDimitry Andric   //
7660fca6ea1SDimitry Andric   //   1) In the transformed require-clause, occurrences of template parameters
7670fca6ea1SDimitry Andric   //   must use the "uninstantiated" depth;
7680fca6ea1SDimitry Andric   //   2) When substituting on the require-clause expr of the underlying
7690fca6ea1SDimitry Andric   //   deduction guide, we must use the entire set of template argument lists;
7700fca6ea1SDimitry Andric   //
7710fca6ea1SDimitry Andric   // It's important to note that we're performing this transformation on an
7720fca6ea1SDimitry Andric   // *instantiated* AliasTemplate.
7730fca6ea1SDimitry Andric 
7740fca6ea1SDimitry Andric   // For 1), if the alias template is nested within a class template, we
7750fca6ea1SDimitry Andric   // calcualte the 'uninstantiated' depth by adding the substitution level back.
7760fca6ea1SDimitry Andric   unsigned AdjustDepth = 0;
7770fca6ea1SDimitry Andric   if (auto *PrimaryTemplate =
7780fca6ea1SDimitry Andric           AliasTemplate->getInstantiatedFromMemberTemplate())
7790fca6ea1SDimitry Andric     AdjustDepth = PrimaryTemplate->getTemplateDepth();
7800fca6ea1SDimitry Andric 
7810fca6ea1SDimitry Andric   // We rebuild all template parameters with the uninstantiated depth, and
7820fca6ea1SDimitry Andric   // build template arguments refer to them.
7830fca6ea1SDimitry Andric   SmallVector<TemplateArgument> AdjustedAliasTemplateArgs;
7840fca6ea1SDimitry Andric 
7850fca6ea1SDimitry Andric   for (auto *TP : *AliasTemplate->getTemplateParameters()) {
7860fca6ea1SDimitry Andric     // Rebuild any internal references to earlier parameters and reindex
7870fca6ea1SDimitry Andric     // as we go.
7880fca6ea1SDimitry Andric     MultiLevelTemplateArgumentList Args;
7890fca6ea1SDimitry Andric     Args.setKind(TemplateSubstitutionKind::Rewrite);
7900fca6ea1SDimitry Andric     Args.addOuterTemplateArguments(AdjustedAliasTemplateArgs);
7910fca6ea1SDimitry Andric     NamedDecl *NewParam = transformTemplateParameter(
7920fca6ea1SDimitry Andric         SemaRef, AliasTemplate->getDeclContext(), TP, Args,
7930fca6ea1SDimitry Andric         /*NewIndex=*/AdjustedAliasTemplateArgs.size(),
7940fca6ea1SDimitry Andric         getTemplateParameterDepth(TP) + AdjustDepth);
7950fca6ea1SDimitry Andric 
7960fca6ea1SDimitry Andric     TemplateArgument NewTemplateArgument =
7970fca6ea1SDimitry Andric         Context.getInjectedTemplateArg(NewParam);
7980fca6ea1SDimitry Andric     AdjustedAliasTemplateArgs.push_back(NewTemplateArgument);
7990fca6ea1SDimitry Andric   }
8000fca6ea1SDimitry Andric   // Template arguments used to transform the template arguments in
8010fca6ea1SDimitry Andric   // DeducedResults.
8020fca6ea1SDimitry Andric   SmallVector<TemplateArgument> TemplateArgsForBuildingRC(
8030fca6ea1SDimitry Andric       F->getTemplateParameters()->size());
8040fca6ea1SDimitry Andric   // Transform the transformed template args
8050fca6ea1SDimitry Andric   MultiLevelTemplateArgumentList Args;
8060fca6ea1SDimitry Andric   Args.setKind(TemplateSubstitutionKind::Rewrite);
8070fca6ea1SDimitry Andric   Args.addOuterTemplateArguments(AdjustedAliasTemplateArgs);
8080fca6ea1SDimitry Andric 
8090fca6ea1SDimitry Andric   for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
8100fca6ea1SDimitry Andric     const auto &D = DeduceResults[Index];
8110fca6ea1SDimitry Andric     if (D.isNull()) { // non-deduced template parameters of f
8120fca6ea1SDimitry Andric       NamedDecl *TP = F->getTemplateParameters()->getParam(Index);
8130fca6ea1SDimitry Andric       MultiLevelTemplateArgumentList Args;
8140fca6ea1SDimitry Andric       Args.setKind(TemplateSubstitutionKind::Rewrite);
8150fca6ea1SDimitry Andric       Args.addOuterTemplateArguments(TemplateArgsForBuildingRC);
8160fca6ea1SDimitry Andric       // Rebuild the template parameter with updated depth and index.
8170fca6ea1SDimitry Andric       NamedDecl *NewParam = transformTemplateParameter(
8180fca6ea1SDimitry Andric           SemaRef, F->getDeclContext(), TP, Args,
8190fca6ea1SDimitry Andric           /*NewIndex=*/FirstUndeducedParamIdx,
8200fca6ea1SDimitry Andric           getTemplateParameterDepth(TP) + AdjustDepth);
8210fca6ea1SDimitry Andric       FirstUndeducedParamIdx += 1;
8220fca6ea1SDimitry Andric       assert(TemplateArgsForBuildingRC[Index].isNull());
8230fca6ea1SDimitry Andric       TemplateArgsForBuildingRC[Index] =
8240fca6ea1SDimitry Andric           Context.getInjectedTemplateArg(NewParam);
8250fca6ea1SDimitry Andric       continue;
8260fca6ea1SDimitry Andric     }
8270fca6ea1SDimitry Andric     TemplateArgumentLoc Input =
8280fca6ea1SDimitry Andric         SemaRef.getTrivialTemplateArgumentLoc(D, QualType(), SourceLocation{});
8290fca6ea1SDimitry Andric     TemplateArgumentLoc Output;
8300fca6ea1SDimitry Andric     if (!SemaRef.SubstTemplateArgument(Input, Args, Output)) {
8310fca6ea1SDimitry Andric       assert(TemplateArgsForBuildingRC[Index].isNull() &&
8320fca6ea1SDimitry Andric              "InstantiatedArgs must be null before setting");
8330fca6ea1SDimitry Andric       TemplateArgsForBuildingRC[Index] = Output.getArgument();
8340fca6ea1SDimitry Andric     }
8350fca6ea1SDimitry Andric   }
8360fca6ea1SDimitry Andric 
8370fca6ea1SDimitry Andric   // A list of template arguments for transforming the require-clause of F.
8380fca6ea1SDimitry Andric   // It must contain the entire set of template argument lists.
8390fca6ea1SDimitry Andric   MultiLevelTemplateArgumentList ArgsForBuildingRC;
8400fca6ea1SDimitry Andric   ArgsForBuildingRC.setKind(clang::TemplateSubstitutionKind::Rewrite);
8410fca6ea1SDimitry Andric   ArgsForBuildingRC.addOuterTemplateArguments(TemplateArgsForBuildingRC);
8420fca6ea1SDimitry Andric   // For 2), if the underlying deduction guide F is nested in a class template,
8430fca6ea1SDimitry Andric   // we need the entire template argument list, as the constraint AST in the
8440fca6ea1SDimitry Andric   // require-clause of F remains completely uninstantiated.
8450fca6ea1SDimitry Andric   //
8460fca6ea1SDimitry Andric   // For example:
8470fca6ea1SDimitry Andric   //   template <typename T> // depth 0
8480fca6ea1SDimitry Andric   //   struct Outer {
8490fca6ea1SDimitry Andric   //      template <typename U>
8500fca6ea1SDimitry Andric   //      struct Foo { Foo(U); };
8510fca6ea1SDimitry Andric   //
8520fca6ea1SDimitry Andric   //      template <typename U> // depth 1
8530fca6ea1SDimitry Andric   //      requires C<U>
8540fca6ea1SDimitry Andric   //      Foo(U) -> Foo<int>;
8550fca6ea1SDimitry Andric   //   };
8560fca6ea1SDimitry Andric   //   template <typename U>
8570fca6ea1SDimitry Andric   //   using AFoo = Outer<int>::Foo<U>;
8580fca6ea1SDimitry Andric   //
8590fca6ea1SDimitry Andric   // In this scenario, the deduction guide for `Foo` inside `Outer<int>`:
8600fca6ea1SDimitry Andric   //   - The occurrence of U in the require-expression is [depth:1, index:0]
8610fca6ea1SDimitry Andric   //   - The occurrence of U in the function parameter is [depth:0, index:0]
8620fca6ea1SDimitry Andric   //   - The template parameter of U is [depth:0, index:0]
8630fca6ea1SDimitry Andric   //
8640fca6ea1SDimitry Andric   // We add the outer template arguments which is [int] to the multi-level arg
8650fca6ea1SDimitry Andric   // list to ensure that the occurrence U in `C<U>` will be replaced with int
8660fca6ea1SDimitry Andric   // during the substitution.
8670fca6ea1SDimitry Andric   //
8680fca6ea1SDimitry Andric   // NOTE: The underlying deduction guide F is instantiated -- either from an
8690fca6ea1SDimitry Andric   // explicitly-written deduction guide member, or from a constructor.
8700fca6ea1SDimitry Andric   // getInstantiatedFromMemberTemplate() can only handle the former case, so we
8710fca6ea1SDimitry Andric   // check the DeclContext kind.
8720fca6ea1SDimitry Andric   if (F->getLexicalDeclContext()->getDeclKind() ==
8730fca6ea1SDimitry Andric       clang::Decl::ClassTemplateSpecialization) {
8740fca6ea1SDimitry Andric     auto OuterLevelArgs = SemaRef.getTemplateInstantiationArgs(
8750fca6ea1SDimitry Andric         F, F->getLexicalDeclContext(),
8760fca6ea1SDimitry Andric         /*Final=*/false, /*Innermost=*/std::nullopt,
8770fca6ea1SDimitry Andric         /*RelativeToPrimary=*/true,
8780fca6ea1SDimitry Andric         /*Pattern=*/nullptr,
8790fca6ea1SDimitry Andric         /*ForConstraintInstantiation=*/true);
8800fca6ea1SDimitry Andric     for (auto It : OuterLevelArgs)
8810fca6ea1SDimitry Andric       ArgsForBuildingRC.addOuterTemplateArguments(It.Args);
8820fca6ea1SDimitry Andric   }
8830fca6ea1SDimitry Andric 
8840fca6ea1SDimitry Andric   ExprResult E = SemaRef.SubstExpr(RC, ArgsForBuildingRC);
8850fca6ea1SDimitry Andric   if (E.isInvalid())
8860fca6ea1SDimitry Andric     return nullptr;
8870fca6ea1SDimitry Andric 
8880fca6ea1SDimitry Andric   auto Conjunction =
8890fca6ea1SDimitry Andric       SemaRef.BuildBinOp(SemaRef.getCurScope(), SourceLocation{},
8900fca6ea1SDimitry Andric                          BinaryOperatorKind::BO_LAnd, E.get(), IsDeducible);
8910fca6ea1SDimitry Andric   if (Conjunction.isInvalid())
8920fca6ea1SDimitry Andric     return nullptr;
8930fca6ea1SDimitry Andric   return Conjunction.getAs<Expr>();
8940fca6ea1SDimitry Andric }
8950fca6ea1SDimitry Andric // Build the is_deducible constraint for the alias deduction guides.
8960fca6ea1SDimitry Andric // [over.match.class.deduct]p3.3:
8970fca6ea1SDimitry Andric //    ... and a constraint that is satisfied if and only if the arguments
8980fca6ea1SDimitry Andric //    of A are deducible (see below) from the return type.
8990fca6ea1SDimitry Andric Expr *buildIsDeducibleConstraint(Sema &SemaRef,
9000fca6ea1SDimitry Andric                                  TypeAliasTemplateDecl *AliasTemplate,
9010fca6ea1SDimitry Andric                                  QualType ReturnType,
9020fca6ea1SDimitry Andric                                  SmallVector<NamedDecl *> TemplateParams) {
9030fca6ea1SDimitry Andric   ASTContext &Context = SemaRef.Context;
9040fca6ea1SDimitry Andric   // Constraint AST nodes must use uninstantiated depth.
9050fca6ea1SDimitry Andric   if (auto *PrimaryTemplate =
9060fca6ea1SDimitry Andric           AliasTemplate->getInstantiatedFromMemberTemplate();
9070fca6ea1SDimitry Andric       PrimaryTemplate && TemplateParams.size() > 0) {
9080fca6ea1SDimitry Andric     LocalInstantiationScope Scope(SemaRef);
9090fca6ea1SDimitry Andric 
9100fca6ea1SDimitry Andric     // Adjust the depth for TemplateParams.
9110fca6ea1SDimitry Andric     unsigned AdjustDepth = PrimaryTemplate->getTemplateDepth();
9120fca6ea1SDimitry Andric     SmallVector<TemplateArgument> TransformedTemplateArgs;
9130fca6ea1SDimitry Andric     for (auto *TP : TemplateParams) {
9140fca6ea1SDimitry Andric       // Rebuild any internal references to earlier parameters and reindex
9150fca6ea1SDimitry Andric       // as we go.
9160fca6ea1SDimitry Andric       MultiLevelTemplateArgumentList Args;
9170fca6ea1SDimitry Andric       Args.setKind(TemplateSubstitutionKind::Rewrite);
9180fca6ea1SDimitry Andric       Args.addOuterTemplateArguments(TransformedTemplateArgs);
9190fca6ea1SDimitry Andric       NamedDecl *NewParam = transformTemplateParameter(
9200fca6ea1SDimitry Andric           SemaRef, AliasTemplate->getDeclContext(), TP, Args,
9210fca6ea1SDimitry Andric           /*NewIndex=*/TransformedTemplateArgs.size(),
9220fca6ea1SDimitry Andric           getTemplateParameterDepth(TP) + AdjustDepth);
9230fca6ea1SDimitry Andric 
9240fca6ea1SDimitry Andric       TemplateArgument NewTemplateArgument =
9250fca6ea1SDimitry Andric           Context.getInjectedTemplateArg(NewParam);
9260fca6ea1SDimitry Andric       TransformedTemplateArgs.push_back(NewTemplateArgument);
9270fca6ea1SDimitry Andric     }
9280fca6ea1SDimitry Andric     // Transformed the ReturnType to restore the uninstantiated depth.
9290fca6ea1SDimitry Andric     MultiLevelTemplateArgumentList Args;
9300fca6ea1SDimitry Andric     Args.setKind(TemplateSubstitutionKind::Rewrite);
9310fca6ea1SDimitry Andric     Args.addOuterTemplateArguments(TransformedTemplateArgs);
9320fca6ea1SDimitry Andric     ReturnType = SemaRef.SubstType(
9330fca6ea1SDimitry Andric         ReturnType, Args, AliasTemplate->getLocation(),
9340fca6ea1SDimitry Andric         Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate));
9350fca6ea1SDimitry Andric   };
9360fca6ea1SDimitry Andric 
9370fca6ea1SDimitry Andric   SmallVector<TypeSourceInfo *> IsDeducibleTypeTraitArgs = {
9380fca6ea1SDimitry Andric       Context.getTrivialTypeSourceInfo(
9390fca6ea1SDimitry Andric           Context.getDeducedTemplateSpecializationType(
9400fca6ea1SDimitry Andric               TemplateName(AliasTemplate), /*DeducedType=*/QualType(),
9410fca6ea1SDimitry Andric               /*IsDependent=*/true)), // template specialization type whose
9420fca6ea1SDimitry Andric                                       // arguments will be deduced.
9430fca6ea1SDimitry Andric       Context.getTrivialTypeSourceInfo(
9440fca6ea1SDimitry Andric           ReturnType), // type from which template arguments are deduced.
9450fca6ea1SDimitry Andric   };
9460fca6ea1SDimitry Andric   return TypeTraitExpr::Create(
9470fca6ea1SDimitry Andric       Context, Context.getLogicalOperationType(), AliasTemplate->getLocation(),
9480fca6ea1SDimitry Andric       TypeTrait::BTT_IsDeducible, IsDeducibleTypeTraitArgs,
9490fca6ea1SDimitry Andric       AliasTemplate->getLocation(), /*Value*/ false);
9500fca6ea1SDimitry Andric }
9510fca6ea1SDimitry Andric 
9520fca6ea1SDimitry Andric std::pair<TemplateDecl *, llvm::ArrayRef<TemplateArgument>>
9530fca6ea1SDimitry Andric getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) {
9540fca6ea1SDimitry Andric   // Unwrap the sugared ElaboratedType.
9550fca6ea1SDimitry Andric   auto RhsType = AliasTemplate->getTemplatedDecl()
9560fca6ea1SDimitry Andric                      ->getUnderlyingType()
9570fca6ea1SDimitry Andric                      .getSingleStepDesugaredType(SemaRef.Context);
9580fca6ea1SDimitry Andric   TemplateDecl *Template = nullptr;
9590fca6ea1SDimitry Andric   llvm::ArrayRef<TemplateArgument> AliasRhsTemplateArgs;
9600fca6ea1SDimitry Andric   if (const auto *TST = RhsType->getAs<TemplateSpecializationType>()) {
9610fca6ea1SDimitry Andric     // Cases where the RHS of the alias is dependent. e.g.
9620fca6ea1SDimitry Andric     //   template<typename T>
9630fca6ea1SDimitry Andric     //   using AliasFoo1 = Foo<T>; // a class/type alias template specialization
9640fca6ea1SDimitry Andric     Template = TST->getTemplateName().getAsTemplateDecl();
9650fca6ea1SDimitry Andric     AliasRhsTemplateArgs = TST->template_arguments();
9660fca6ea1SDimitry Andric   } else if (const auto *RT = RhsType->getAs<RecordType>()) {
9670fca6ea1SDimitry Andric     // Cases where template arguments in the RHS of the alias are not
9680fca6ea1SDimitry Andric     // dependent. e.g.
9690fca6ea1SDimitry Andric     //   using AliasFoo = Foo<bool>;
9700fca6ea1SDimitry Andric     if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(
9710fca6ea1SDimitry Andric             RT->getAsCXXRecordDecl())) {
9720fca6ea1SDimitry Andric       Template = CTSD->getSpecializedTemplate();
9730fca6ea1SDimitry Andric       AliasRhsTemplateArgs = CTSD->getTemplateArgs().asArray();
9740fca6ea1SDimitry Andric     }
9750fca6ea1SDimitry Andric   } else {
9760fca6ea1SDimitry Andric     assert(false && "unhandled RHS type of the alias");
9770fca6ea1SDimitry Andric   }
9780fca6ea1SDimitry Andric   return {Template, AliasRhsTemplateArgs};
9790fca6ea1SDimitry Andric }
9800fca6ea1SDimitry Andric 
9810fca6ea1SDimitry Andric // Build deduction guides for a type alias template from the given underlying
9820fca6ea1SDimitry Andric // deduction guide F.
9830fca6ea1SDimitry Andric FunctionTemplateDecl *
9840fca6ea1SDimitry Andric BuildDeductionGuideForTypeAlias(Sema &SemaRef,
9850fca6ea1SDimitry Andric                                 TypeAliasTemplateDecl *AliasTemplate,
9860fca6ea1SDimitry Andric                                 FunctionTemplateDecl *F, SourceLocation Loc) {
9870fca6ea1SDimitry Andric   LocalInstantiationScope Scope(SemaRef);
9880fca6ea1SDimitry Andric   Sema::InstantiatingTemplate BuildingDeductionGuides(
9890fca6ea1SDimitry Andric       SemaRef, AliasTemplate->getLocation(), F,
9900fca6ea1SDimitry Andric       Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
9910fca6ea1SDimitry Andric   if (BuildingDeductionGuides.isInvalid())
9920fca6ea1SDimitry Andric     return nullptr;
9930fca6ea1SDimitry Andric 
9940fca6ea1SDimitry Andric   auto &Context = SemaRef.Context;
9950fca6ea1SDimitry Andric   auto [Template, AliasRhsTemplateArgs] =
9960fca6ea1SDimitry Andric       getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
9970fca6ea1SDimitry Andric 
9980fca6ea1SDimitry Andric   auto RType = F->getTemplatedDecl()->getReturnType();
9990fca6ea1SDimitry Andric   // The (trailing) return type of the deduction guide.
10000fca6ea1SDimitry Andric   const TemplateSpecializationType *FReturnType =
10010fca6ea1SDimitry Andric       RType->getAs<TemplateSpecializationType>();
10020fca6ea1SDimitry Andric   if (const auto *InjectedCNT = RType->getAs<InjectedClassNameType>())
10030fca6ea1SDimitry Andric     // implicitly-generated deduction guide.
10040fca6ea1SDimitry Andric     FReturnType = InjectedCNT->getInjectedTST();
10050fca6ea1SDimitry Andric   else if (const auto *ET = RType->getAs<ElaboratedType>())
10060fca6ea1SDimitry Andric     // explicit deduction guide.
10070fca6ea1SDimitry Andric     FReturnType = ET->getNamedType()->getAs<TemplateSpecializationType>();
10080fca6ea1SDimitry Andric   assert(FReturnType && "expected to see a return type");
10090fca6ea1SDimitry Andric   // Deduce template arguments of the deduction guide f from the RHS of
10100fca6ea1SDimitry Andric   // the alias.
10110fca6ea1SDimitry Andric   //
10120fca6ea1SDimitry Andric   // C++ [over.match.class.deduct]p3: ...For each function or function
10130fca6ea1SDimitry Andric   // template f in the guides of the template named by the
10140fca6ea1SDimitry Andric   // simple-template-id of the defining-type-id, the template arguments
10150fca6ea1SDimitry Andric   // of the return type of f are deduced from the defining-type-id of A
10160fca6ea1SDimitry Andric   // according to the process in [temp.deduct.type] with the exception
10170fca6ea1SDimitry Andric   // that deduction does not fail if not all template arguments are
10180fca6ea1SDimitry Andric   // deduced.
10190fca6ea1SDimitry Andric   //
10200fca6ea1SDimitry Andric   //
10210fca6ea1SDimitry Andric   //  template<typename X, typename Y>
10220fca6ea1SDimitry Andric   //  f(X, Y) -> f<Y, X>;
10230fca6ea1SDimitry Andric   //
10240fca6ea1SDimitry Andric   //  template<typename U>
10250fca6ea1SDimitry Andric   //  using alias = f<int, U>;
10260fca6ea1SDimitry Andric   //
10270fca6ea1SDimitry Andric   // The RHS of alias is f<int, U>, we deduced the template arguments of
10280fca6ea1SDimitry Andric   // the return type of the deduction guide from it: Y->int, X->U
10290fca6ea1SDimitry Andric   sema::TemplateDeductionInfo TDeduceInfo(Loc);
10300fca6ea1SDimitry Andric   // Must initialize n elements, this is required by DeduceTemplateArguments.
10310fca6ea1SDimitry Andric   SmallVector<DeducedTemplateArgument> DeduceResults(
10320fca6ea1SDimitry Andric       F->getTemplateParameters()->size());
10330fca6ea1SDimitry Andric 
10340fca6ea1SDimitry Andric   // FIXME: DeduceTemplateArguments stops immediately at the first
10350fca6ea1SDimitry Andric   // non-deducible template argument. However, this doesn't seem to casue
10360fca6ea1SDimitry Andric   // issues for practice cases, we probably need to extend it to continue
10370fca6ea1SDimitry Andric   // performing deduction for rest of arguments to align with the C++
10380fca6ea1SDimitry Andric   // standard.
10390fca6ea1SDimitry Andric   SemaRef.DeduceTemplateArguments(
10400fca6ea1SDimitry Andric       F->getTemplateParameters(), FReturnType->template_arguments(),
10410fca6ea1SDimitry Andric       AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
10420fca6ea1SDimitry Andric       /*NumberOfArgumentsMustMatch=*/false);
10430fca6ea1SDimitry Andric 
10440fca6ea1SDimitry Andric   SmallVector<TemplateArgument> DeducedArgs;
10450fca6ea1SDimitry Andric   SmallVector<unsigned> NonDeducedTemplateParamsInFIndex;
10460fca6ea1SDimitry Andric   // !!NOTE: DeduceResults respects the sequence of template parameters of
10470fca6ea1SDimitry Andric   // the deduction guide f.
10480fca6ea1SDimitry Andric   for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
10490fca6ea1SDimitry Andric     if (const auto &D = DeduceResults[Index]; !D.isNull()) // Deduced
10500fca6ea1SDimitry Andric       DeducedArgs.push_back(D);
10510fca6ea1SDimitry Andric     else
10520fca6ea1SDimitry Andric       NonDeducedTemplateParamsInFIndex.push_back(Index);
10530fca6ea1SDimitry Andric   }
10540fca6ea1SDimitry Andric   auto DeducedAliasTemplateParams =
10550fca6ea1SDimitry Andric       TemplateParamsReferencedInTemplateArgumentList(
10560fca6ea1SDimitry Andric           AliasTemplate->getTemplateParameters(), DeducedArgs);
10570fca6ea1SDimitry Andric   // All template arguments null by default.
10580fca6ea1SDimitry Andric   SmallVector<TemplateArgument> TemplateArgsForBuildingFPrime(
10590fca6ea1SDimitry Andric       F->getTemplateParameters()->size());
10600fca6ea1SDimitry Andric 
10610fca6ea1SDimitry Andric   // Create a template parameter list for the synthesized deduction guide f'.
10620fca6ea1SDimitry Andric   //
10630fca6ea1SDimitry Andric   // C++ [over.match.class.deduct]p3.2:
10640fca6ea1SDimitry Andric   //   If f is a function template, f' is a function template whose template
10650fca6ea1SDimitry Andric   //   parameter list consists of all the template parameters of A
10660fca6ea1SDimitry Andric   //   (including their default template arguments) that appear in the above
10670fca6ea1SDimitry Andric   //   deductions or (recursively) in their default template arguments
10680fca6ea1SDimitry Andric   SmallVector<NamedDecl *> FPrimeTemplateParams;
10690fca6ea1SDimitry Andric   // Store template arguments that refer to the newly-created template
10700fca6ea1SDimitry Andric   // parameters, used for building `TemplateArgsForBuildingFPrime`.
10710fca6ea1SDimitry Andric   SmallVector<TemplateArgument, 16> TransformedDeducedAliasArgs(
10720fca6ea1SDimitry Andric       AliasTemplate->getTemplateParameters()->size());
10730fca6ea1SDimitry Andric 
10740fca6ea1SDimitry Andric   for (unsigned AliasTemplateParamIdx : DeducedAliasTemplateParams) {
10750fca6ea1SDimitry Andric     auto *TP =
10760fca6ea1SDimitry Andric         AliasTemplate->getTemplateParameters()->getParam(AliasTemplateParamIdx);
10770fca6ea1SDimitry Andric     // Rebuild any internal references to earlier parameters and reindex as
10780fca6ea1SDimitry Andric     // we go.
10790fca6ea1SDimitry Andric     MultiLevelTemplateArgumentList Args;
10800fca6ea1SDimitry Andric     Args.setKind(TemplateSubstitutionKind::Rewrite);
10810fca6ea1SDimitry Andric     Args.addOuterTemplateArguments(TransformedDeducedAliasArgs);
10820fca6ea1SDimitry Andric     NamedDecl *NewParam = transformTemplateParameter(
10830fca6ea1SDimitry Andric         SemaRef, AliasTemplate->getDeclContext(), TP, Args,
10840fca6ea1SDimitry Andric         /*NewIndex=*/FPrimeTemplateParams.size(),
10850fca6ea1SDimitry Andric         getTemplateParameterDepth(TP));
10860fca6ea1SDimitry Andric     FPrimeTemplateParams.push_back(NewParam);
10870fca6ea1SDimitry Andric 
10880fca6ea1SDimitry Andric     TemplateArgument NewTemplateArgument =
10890fca6ea1SDimitry Andric         Context.getInjectedTemplateArg(NewParam);
10900fca6ea1SDimitry Andric     TransformedDeducedAliasArgs[AliasTemplateParamIdx] = NewTemplateArgument;
10910fca6ea1SDimitry Andric   }
10920fca6ea1SDimitry Andric   unsigned FirstUndeducedParamIdx = FPrimeTemplateParams.size();
10930fca6ea1SDimitry Andric   //   ...followed by the template parameters of f that were not deduced
10940fca6ea1SDimitry Andric   //   (including their default template arguments)
10950fca6ea1SDimitry Andric   for (unsigned FTemplateParamIdx : NonDeducedTemplateParamsInFIndex) {
10960fca6ea1SDimitry Andric     auto *TP = F->getTemplateParameters()->getParam(FTemplateParamIdx);
10970fca6ea1SDimitry Andric     MultiLevelTemplateArgumentList Args;
10980fca6ea1SDimitry Andric     Args.setKind(TemplateSubstitutionKind::Rewrite);
10990fca6ea1SDimitry Andric     // We take a shortcut here, it is ok to reuse the
11000fca6ea1SDimitry Andric     // TemplateArgsForBuildingFPrime.
11010fca6ea1SDimitry Andric     Args.addOuterTemplateArguments(TemplateArgsForBuildingFPrime);
11020fca6ea1SDimitry Andric     NamedDecl *NewParam = transformTemplateParameter(
11030fca6ea1SDimitry Andric         SemaRef, F->getDeclContext(), TP, Args, FPrimeTemplateParams.size(),
11040fca6ea1SDimitry Andric         getTemplateParameterDepth(TP));
11050fca6ea1SDimitry Andric     FPrimeTemplateParams.push_back(NewParam);
11060fca6ea1SDimitry Andric 
11070fca6ea1SDimitry Andric     assert(TemplateArgsForBuildingFPrime[FTemplateParamIdx].isNull() &&
11080fca6ea1SDimitry Andric            "The argument must be null before setting");
11090fca6ea1SDimitry Andric     TemplateArgsForBuildingFPrime[FTemplateParamIdx] =
11100fca6ea1SDimitry Andric         Context.getInjectedTemplateArg(NewParam);
11110fca6ea1SDimitry Andric   }
11120fca6ea1SDimitry Andric 
11130fca6ea1SDimitry Andric   // To form a deduction guide f' from f, we leverage clang's instantiation
11140fca6ea1SDimitry Andric   // mechanism, we construct a template argument list where the template
11150fca6ea1SDimitry Andric   // arguments refer to the newly-created template parameters of f', and
11160fca6ea1SDimitry Andric   // then apply instantiation on this template argument list to instantiate
11170fca6ea1SDimitry Andric   // f, this ensures all template parameter occurrences are updated
11180fca6ea1SDimitry Andric   // correctly.
11190fca6ea1SDimitry Andric   //
11200fca6ea1SDimitry Andric   // The template argument list is formed from the `DeducedArgs`, two parts:
11210fca6ea1SDimitry Andric   //  1) appeared template parameters of alias: transfrom the deduced
11220fca6ea1SDimitry Andric   //  template argument;
11230fca6ea1SDimitry Andric   //  2) non-deduced template parameters of f: rebuild a
11240fca6ea1SDimitry Andric   //  template argument;
11250fca6ea1SDimitry Andric   //
11260fca6ea1SDimitry Andric   // 2) has been built already (when rebuilding the new template
11270fca6ea1SDimitry Andric   // parameters), we now perform 1).
11280fca6ea1SDimitry Andric   MultiLevelTemplateArgumentList Args;
11290fca6ea1SDimitry Andric   Args.setKind(TemplateSubstitutionKind::Rewrite);
11300fca6ea1SDimitry Andric   Args.addOuterTemplateArguments(TransformedDeducedAliasArgs);
11310fca6ea1SDimitry Andric   for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
11320fca6ea1SDimitry Andric     const auto &D = DeduceResults[Index];
11330fca6ea1SDimitry Andric     if (D.isNull()) {
11340fca6ea1SDimitry Andric       // 2): Non-deduced template parameter has been built already.
11350fca6ea1SDimitry Andric       assert(!TemplateArgsForBuildingFPrime[Index].isNull() &&
11360fca6ea1SDimitry Andric              "template arguments for non-deduced template parameters should "
11370fca6ea1SDimitry Andric              "be been set!");
11380fca6ea1SDimitry Andric       continue;
11390fca6ea1SDimitry Andric     }
11400fca6ea1SDimitry Andric     TemplateArgumentLoc Input =
11410fca6ea1SDimitry Andric         SemaRef.getTrivialTemplateArgumentLoc(D, QualType(), SourceLocation{});
11420fca6ea1SDimitry Andric     TemplateArgumentLoc Output;
11430fca6ea1SDimitry Andric     if (!SemaRef.SubstTemplateArgument(Input, Args, Output)) {
11440fca6ea1SDimitry Andric       assert(TemplateArgsForBuildingFPrime[Index].isNull() &&
11450fca6ea1SDimitry Andric              "InstantiatedArgs must be null before setting");
11460fca6ea1SDimitry Andric       TemplateArgsForBuildingFPrime[Index] = Output.getArgument();
11470fca6ea1SDimitry Andric     }
11480fca6ea1SDimitry Andric   }
11490fca6ea1SDimitry Andric 
11500fca6ea1SDimitry Andric   auto *TemplateArgListForBuildingFPrime =
11510fca6ea1SDimitry Andric       TemplateArgumentList::CreateCopy(Context, TemplateArgsForBuildingFPrime);
11520fca6ea1SDimitry Andric   // Form the f' by substituting the template arguments into f.
11530fca6ea1SDimitry Andric   if (auto *FPrime = SemaRef.InstantiateFunctionDeclaration(
11540fca6ea1SDimitry Andric           F, TemplateArgListForBuildingFPrime, AliasTemplate->getLocation(),
11550fca6ea1SDimitry Andric           Sema::CodeSynthesisContext::BuildingDeductionGuides)) {
11560fca6ea1SDimitry Andric     auto *GG = cast<CXXDeductionGuideDecl>(FPrime);
11570fca6ea1SDimitry Andric 
11580fca6ea1SDimitry Andric     Expr *IsDeducible = buildIsDeducibleConstraint(
11590fca6ea1SDimitry Andric         SemaRef, AliasTemplate, FPrime->getReturnType(), FPrimeTemplateParams);
11600fca6ea1SDimitry Andric     Expr *RequiresClause =
11610fca6ea1SDimitry Andric         buildAssociatedConstraints(SemaRef, F, AliasTemplate, DeduceResults,
11620fca6ea1SDimitry Andric                                    FirstUndeducedParamIdx, IsDeducible);
11630fca6ea1SDimitry Andric 
11640fca6ea1SDimitry Andric     auto *FPrimeTemplateParamList = TemplateParameterList::Create(
11650fca6ea1SDimitry Andric         Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(),
11660fca6ea1SDimitry Andric         AliasTemplate->getTemplateParameters()->getLAngleLoc(),
11670fca6ea1SDimitry Andric         FPrimeTemplateParams,
11680fca6ea1SDimitry Andric         AliasTemplate->getTemplateParameters()->getRAngleLoc(),
11690fca6ea1SDimitry Andric         /*RequiresClause=*/RequiresClause);
11700fca6ea1SDimitry Andric     auto *Result = cast<FunctionTemplateDecl>(buildDeductionGuide(
11710fca6ea1SDimitry Andric         SemaRef, AliasTemplate, FPrimeTemplateParamList,
11720fca6ea1SDimitry Andric         GG->getCorrespondingConstructor(), GG->getExplicitSpecifier(),
11730fca6ea1SDimitry Andric         GG->getTypeSourceInfo(), AliasTemplate->getBeginLoc(),
11740fca6ea1SDimitry Andric         AliasTemplate->getLocation(), AliasTemplate->getEndLoc(),
11750fca6ea1SDimitry Andric         F->isImplicit()));
11760fca6ea1SDimitry Andric     cast<CXXDeductionGuideDecl>(Result->getTemplatedDecl())
11770fca6ea1SDimitry Andric         ->setDeductionCandidateKind(GG->getDeductionCandidateKind());
11780fca6ea1SDimitry Andric     return Result;
11790fca6ea1SDimitry Andric   }
11800fca6ea1SDimitry Andric   return nullptr;
11810fca6ea1SDimitry Andric }
11820fca6ea1SDimitry Andric 
11830fca6ea1SDimitry Andric void DeclareImplicitDeductionGuidesForTypeAlias(
11840fca6ea1SDimitry Andric     Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate, SourceLocation Loc) {
11850fca6ea1SDimitry Andric   if (AliasTemplate->isInvalidDecl())
11860fca6ea1SDimitry Andric     return;
11870fca6ea1SDimitry Andric   auto &Context = SemaRef.Context;
11880fca6ea1SDimitry Andric   // FIXME: if there is an explicit deduction guide after the first use of the
11890fca6ea1SDimitry Andric   // type alias usage, we will not cover this explicit deduction guide. fix this
11900fca6ea1SDimitry Andric   // case.
11910fca6ea1SDimitry Andric   if (hasDeclaredDeductionGuides(
11920fca6ea1SDimitry Andric           Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate),
11930fca6ea1SDimitry Andric           AliasTemplate->getDeclContext()))
11940fca6ea1SDimitry Andric     return;
11950fca6ea1SDimitry Andric   auto [Template, AliasRhsTemplateArgs] =
11960fca6ea1SDimitry Andric       getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
11970fca6ea1SDimitry Andric   if (!Template)
11980fca6ea1SDimitry Andric     return;
11990fca6ea1SDimitry Andric   DeclarationNameInfo NameInfo(
12000fca6ea1SDimitry Andric       Context.DeclarationNames.getCXXDeductionGuideName(Template), Loc);
12010fca6ea1SDimitry Andric   LookupResult Guides(SemaRef, NameInfo, clang::Sema::LookupOrdinaryName);
12020fca6ea1SDimitry Andric   SemaRef.LookupQualifiedName(Guides, Template->getDeclContext());
12030fca6ea1SDimitry Andric   Guides.suppressDiagnostics();
12040fca6ea1SDimitry Andric 
12050fca6ea1SDimitry Andric   for (auto *G : Guides) {
12060fca6ea1SDimitry Andric     if (auto *DG = dyn_cast<CXXDeductionGuideDecl>(G)) {
12070fca6ea1SDimitry Andric       // The deduction guide is a non-template function decl, we just clone it.
12080fca6ea1SDimitry Andric       auto *FunctionType =
12090fca6ea1SDimitry Andric           SemaRef.Context.getTrivialTypeSourceInfo(DG->getType());
12100fca6ea1SDimitry Andric       FunctionProtoTypeLoc FPTL =
12110fca6ea1SDimitry Andric           FunctionType->getTypeLoc().castAs<FunctionProtoTypeLoc>();
12120fca6ea1SDimitry Andric 
12130fca6ea1SDimitry Andric       // Clone the parameters.
12140fca6ea1SDimitry Andric       for (unsigned I = 0, N = DG->getNumParams(); I != N; ++I) {
12150fca6ea1SDimitry Andric         const auto *P = DG->getParamDecl(I);
12160fca6ea1SDimitry Andric         auto *TSI = SemaRef.Context.getTrivialTypeSourceInfo(P->getType());
12170fca6ea1SDimitry Andric         ParmVarDecl *NewParam = ParmVarDecl::Create(
12180fca6ea1SDimitry Andric             SemaRef.Context, G->getDeclContext(),
12190fca6ea1SDimitry Andric             DG->getParamDecl(I)->getBeginLoc(), P->getLocation(), nullptr,
12200fca6ea1SDimitry Andric             TSI->getType(), TSI, SC_None, nullptr);
12210fca6ea1SDimitry Andric         NewParam->setScopeInfo(0, I);
12220fca6ea1SDimitry Andric         FPTL.setParam(I, NewParam);
12230fca6ea1SDimitry Andric       }
12240fca6ea1SDimitry Andric       auto *Transformed = cast<FunctionDecl>(buildDeductionGuide(
12250fca6ea1SDimitry Andric           SemaRef, AliasTemplate, /*TemplateParams=*/nullptr,
12260fca6ea1SDimitry Andric           /*Constructor=*/nullptr, DG->getExplicitSpecifier(), FunctionType,
12270fca6ea1SDimitry Andric           AliasTemplate->getBeginLoc(), AliasTemplate->getLocation(),
12280fca6ea1SDimitry Andric           AliasTemplate->getEndLoc(), DG->isImplicit()));
12290fca6ea1SDimitry Andric 
12300fca6ea1SDimitry Andric       // FIXME: Here the synthesized deduction guide is not a templated
12310fca6ea1SDimitry Andric       // function. Per [dcl.decl]p4, the requires-clause shall be present only
12320fca6ea1SDimitry Andric       // if the declarator declares a templated function, a bug in standard?
12330fca6ea1SDimitry Andric       auto *Constraint = buildIsDeducibleConstraint(
12340fca6ea1SDimitry Andric           SemaRef, AliasTemplate, Transformed->getReturnType(), {});
12350fca6ea1SDimitry Andric       if (auto *RC = DG->getTrailingRequiresClause()) {
12360fca6ea1SDimitry Andric         auto Conjunction =
12370fca6ea1SDimitry Andric             SemaRef.BuildBinOp(SemaRef.getCurScope(), SourceLocation{},
12380fca6ea1SDimitry Andric                                BinaryOperatorKind::BO_LAnd, RC, Constraint);
12390fca6ea1SDimitry Andric         if (!Conjunction.isInvalid())
12400fca6ea1SDimitry Andric           Constraint = Conjunction.getAs<Expr>();
12410fca6ea1SDimitry Andric       }
12420fca6ea1SDimitry Andric       Transformed->setTrailingRequiresClause(Constraint);
12430fca6ea1SDimitry Andric     }
12440fca6ea1SDimitry Andric     FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(G);
12450fca6ea1SDimitry Andric     if (!F)
12460fca6ea1SDimitry Andric       continue;
12470fca6ea1SDimitry Andric     // The **aggregate** deduction guides are handled in a different code path
12480fca6ea1SDimitry Andric     // (DeclareAggregateDeductionGuideFromInitList), which involves the tricky
12490fca6ea1SDimitry Andric     // cache.
12500fca6ea1SDimitry Andric     if (cast<CXXDeductionGuideDecl>(F->getTemplatedDecl())
12510fca6ea1SDimitry Andric             ->getDeductionCandidateKind() == DeductionCandidate::Aggregate)
12520fca6ea1SDimitry Andric       continue;
12530fca6ea1SDimitry Andric 
12540fca6ea1SDimitry Andric     BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate, F, Loc);
12550fca6ea1SDimitry Andric   }
12560fca6ea1SDimitry Andric }
12570fca6ea1SDimitry Andric 
12580fca6ea1SDimitry Andric // Build an aggregate deduction guide for a type alias template.
12590fca6ea1SDimitry Andric FunctionTemplateDecl *DeclareAggregateDeductionGuideForTypeAlias(
12600fca6ea1SDimitry Andric     Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate,
12610fca6ea1SDimitry Andric     MutableArrayRef<QualType> ParamTypes, SourceLocation Loc) {
12620fca6ea1SDimitry Andric   TemplateDecl *RHSTemplate =
12630fca6ea1SDimitry Andric       getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate).first;
12640fca6ea1SDimitry Andric   if (!RHSTemplate)
12650fca6ea1SDimitry Andric     return nullptr;
1266*d686ce93SDimitry Andric 
1267*d686ce93SDimitry Andric   llvm::SmallVector<TypedefNameDecl *> TypedefDecls;
1268*d686ce93SDimitry Andric   llvm::SmallVector<QualType> NewParamTypes;
1269*d686ce93SDimitry Andric   ExtractTypeForDeductionGuide TypeAliasTransformer(SemaRef, TypedefDecls);
1270*d686ce93SDimitry Andric   for (QualType P : ParamTypes) {
1271*d686ce93SDimitry Andric     QualType Type = TypeAliasTransformer.TransformType(P);
1272*d686ce93SDimitry Andric     if (Type.isNull())
1273*d686ce93SDimitry Andric       return nullptr;
1274*d686ce93SDimitry Andric     NewParamTypes.push_back(Type);
1275*d686ce93SDimitry Andric   }
1276*d686ce93SDimitry Andric 
12770fca6ea1SDimitry Andric   auto *RHSDeductionGuide = SemaRef.DeclareAggregateDeductionGuideFromInitList(
1278*d686ce93SDimitry Andric       RHSTemplate, NewParamTypes, Loc);
12790fca6ea1SDimitry Andric   if (!RHSDeductionGuide)
12800fca6ea1SDimitry Andric     return nullptr;
1281*d686ce93SDimitry Andric 
1282*d686ce93SDimitry Andric   for (TypedefNameDecl *TD : TypedefDecls)
1283*d686ce93SDimitry Andric     TD->setDeclContext(RHSDeductionGuide->getTemplatedDecl());
1284*d686ce93SDimitry Andric 
12850fca6ea1SDimitry Andric   return BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate,
12860fca6ea1SDimitry Andric                                          RHSDeductionGuide, Loc);
12870fca6ea1SDimitry Andric }
12880fca6ea1SDimitry Andric 
12890fca6ea1SDimitry Andric } // namespace
12900fca6ea1SDimitry Andric 
12910fca6ea1SDimitry Andric FunctionTemplateDecl *Sema::DeclareAggregateDeductionGuideFromInitList(
12920fca6ea1SDimitry Andric     TemplateDecl *Template, MutableArrayRef<QualType> ParamTypes,
12930fca6ea1SDimitry Andric     SourceLocation Loc) {
12940fca6ea1SDimitry Andric   llvm::FoldingSetNodeID ID;
12950fca6ea1SDimitry Andric   ID.AddPointer(Template);
12960fca6ea1SDimitry Andric   for (auto &T : ParamTypes)
12970fca6ea1SDimitry Andric     T.getCanonicalType().Profile(ID);
12980fca6ea1SDimitry Andric   unsigned Hash = ID.ComputeHash();
12990fca6ea1SDimitry Andric 
13000fca6ea1SDimitry Andric   auto Found = AggregateDeductionCandidates.find(Hash);
13010fca6ea1SDimitry Andric   if (Found != AggregateDeductionCandidates.end()) {
13020fca6ea1SDimitry Andric     CXXDeductionGuideDecl *GD = Found->getSecond();
13030fca6ea1SDimitry Andric     return GD->getDescribedFunctionTemplate();
13040fca6ea1SDimitry Andric   }
13050fca6ea1SDimitry Andric 
13060fca6ea1SDimitry Andric   if (auto *AliasTemplate = llvm::dyn_cast<TypeAliasTemplateDecl>(Template)) {
13070fca6ea1SDimitry Andric     if (auto *FTD = DeclareAggregateDeductionGuideForTypeAlias(
13080fca6ea1SDimitry Andric             *this, AliasTemplate, ParamTypes, Loc)) {
13090fca6ea1SDimitry Andric       auto *GD = cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl());
13100fca6ea1SDimitry Andric       GD->setDeductionCandidateKind(DeductionCandidate::Aggregate);
13110fca6ea1SDimitry Andric       AggregateDeductionCandidates[Hash] = GD;
13120fca6ea1SDimitry Andric       return FTD;
13130fca6ea1SDimitry Andric     }
13140fca6ea1SDimitry Andric   }
13150fca6ea1SDimitry Andric 
13160fca6ea1SDimitry Andric   if (CXXRecordDecl *DefRecord =
13170fca6ea1SDimitry Andric           cast<CXXRecordDecl>(Template->getTemplatedDecl())->getDefinition()) {
13180fca6ea1SDimitry Andric     if (TemplateDecl *DescribedTemplate =
13190fca6ea1SDimitry Andric             DefRecord->getDescribedClassTemplate())
13200fca6ea1SDimitry Andric       Template = DescribedTemplate;
13210fca6ea1SDimitry Andric   }
13220fca6ea1SDimitry Andric 
13230fca6ea1SDimitry Andric   DeclContext *DC = Template->getDeclContext();
13240fca6ea1SDimitry Andric   if (DC->isDependentContext())
13250fca6ea1SDimitry Andric     return nullptr;
13260fca6ea1SDimitry Andric 
13270fca6ea1SDimitry Andric   ConvertConstructorToDeductionGuideTransform Transform(
13280fca6ea1SDimitry Andric       *this, cast<ClassTemplateDecl>(Template));
13290fca6ea1SDimitry Andric   if (!isCompleteType(Loc, Transform.DeducedType))
13300fca6ea1SDimitry Andric     return nullptr;
13310fca6ea1SDimitry Andric 
13320fca6ea1SDimitry Andric   // In case we were expanding a pack when we attempted to declare deduction
13330fca6ea1SDimitry Andric   // guides, turn off pack expansion for everything we're about to do.
13340fca6ea1SDimitry Andric   ArgumentPackSubstitutionIndexRAII SubstIndex(*this,
13350fca6ea1SDimitry Andric                                                /*NewSubstitutionIndex=*/-1);
13360fca6ea1SDimitry Andric   // Create a template instantiation record to track the "instantiation" of
13370fca6ea1SDimitry Andric   // constructors into deduction guides.
13380fca6ea1SDimitry Andric   InstantiatingTemplate BuildingDeductionGuides(
13390fca6ea1SDimitry Andric       *this, Loc, Template,
13400fca6ea1SDimitry Andric       Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
13410fca6ea1SDimitry Andric   if (BuildingDeductionGuides.isInvalid())
13420fca6ea1SDimitry Andric     return nullptr;
13430fca6ea1SDimitry Andric 
13440fca6ea1SDimitry Andric   ClassTemplateDecl *Pattern =
13450fca6ea1SDimitry Andric       Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
13460fca6ea1SDimitry Andric   ContextRAII SavedContext(*this, Pattern->getTemplatedDecl());
13470fca6ea1SDimitry Andric 
13480fca6ea1SDimitry Andric   auto *FTD = cast<FunctionTemplateDecl>(
13490fca6ea1SDimitry Andric       Transform.buildSimpleDeductionGuide(ParamTypes));
13500fca6ea1SDimitry Andric   SavedContext.pop();
13510fca6ea1SDimitry Andric   auto *GD = cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl());
13520fca6ea1SDimitry Andric   GD->setDeductionCandidateKind(DeductionCandidate::Aggregate);
13530fca6ea1SDimitry Andric   AggregateDeductionCandidates[Hash] = GD;
13540fca6ea1SDimitry Andric   return FTD;
13550fca6ea1SDimitry Andric }
13560fca6ea1SDimitry Andric 
13570fca6ea1SDimitry Andric void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
13580fca6ea1SDimitry Andric                                           SourceLocation Loc) {
13590fca6ea1SDimitry Andric   if (auto *AliasTemplate = llvm::dyn_cast<TypeAliasTemplateDecl>(Template)) {
13600fca6ea1SDimitry Andric     DeclareImplicitDeductionGuidesForTypeAlias(*this, AliasTemplate, Loc);
13610fca6ea1SDimitry Andric     return;
13620fca6ea1SDimitry Andric   }
13630fca6ea1SDimitry Andric   if (CXXRecordDecl *DefRecord =
13640fca6ea1SDimitry Andric           cast<CXXRecordDecl>(Template->getTemplatedDecl())->getDefinition()) {
13650fca6ea1SDimitry Andric     if (TemplateDecl *DescribedTemplate =
13660fca6ea1SDimitry Andric             DefRecord->getDescribedClassTemplate())
13670fca6ea1SDimitry Andric       Template = DescribedTemplate;
13680fca6ea1SDimitry Andric   }
13690fca6ea1SDimitry Andric 
13700fca6ea1SDimitry Andric   DeclContext *DC = Template->getDeclContext();
13710fca6ea1SDimitry Andric   if (DC->isDependentContext())
13720fca6ea1SDimitry Andric     return;
13730fca6ea1SDimitry Andric 
13740fca6ea1SDimitry Andric   ConvertConstructorToDeductionGuideTransform Transform(
13750fca6ea1SDimitry Andric       *this, cast<ClassTemplateDecl>(Template));
13760fca6ea1SDimitry Andric   if (!isCompleteType(Loc, Transform.DeducedType))
13770fca6ea1SDimitry Andric     return;
13780fca6ea1SDimitry Andric 
13790fca6ea1SDimitry Andric   if (hasDeclaredDeductionGuides(Transform.DeductionGuideName, DC))
13800fca6ea1SDimitry Andric     return;
13810fca6ea1SDimitry Andric 
13820fca6ea1SDimitry Andric   // In case we were expanding a pack when we attempted to declare deduction
13830fca6ea1SDimitry Andric   // guides, turn off pack expansion for everything we're about to do.
13840fca6ea1SDimitry Andric   ArgumentPackSubstitutionIndexRAII SubstIndex(*this, -1);
13850fca6ea1SDimitry Andric   // Create a template instantiation record to track the "instantiation" of
13860fca6ea1SDimitry Andric   // constructors into deduction guides.
13870fca6ea1SDimitry Andric   InstantiatingTemplate BuildingDeductionGuides(
13880fca6ea1SDimitry Andric       *this, Loc, Template,
13890fca6ea1SDimitry Andric       Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
13900fca6ea1SDimitry Andric   if (BuildingDeductionGuides.isInvalid())
13910fca6ea1SDimitry Andric     return;
13920fca6ea1SDimitry Andric 
13930fca6ea1SDimitry Andric   // Convert declared constructors into deduction guide templates.
13940fca6ea1SDimitry Andric   // FIXME: Skip constructors for which deduction must necessarily fail (those
13950fca6ea1SDimitry Andric   // for which some class template parameter without a default argument never
13960fca6ea1SDimitry Andric   // appears in a deduced context).
13970fca6ea1SDimitry Andric   ClassTemplateDecl *Pattern =
13980fca6ea1SDimitry Andric       Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
13990fca6ea1SDimitry Andric   ContextRAII SavedContext(*this, Pattern->getTemplatedDecl());
14000fca6ea1SDimitry Andric   llvm::SmallPtrSet<NamedDecl *, 8> ProcessedCtors;
14010fca6ea1SDimitry Andric   bool AddedAny = false;
14020fca6ea1SDimitry Andric   for (NamedDecl *D : LookupConstructors(Pattern->getTemplatedDecl())) {
14030fca6ea1SDimitry Andric     D = D->getUnderlyingDecl();
14040fca6ea1SDimitry Andric     if (D->isInvalidDecl() || D->isImplicit())
14050fca6ea1SDimitry Andric       continue;
14060fca6ea1SDimitry Andric 
14070fca6ea1SDimitry Andric     D = cast<NamedDecl>(D->getCanonicalDecl());
14080fca6ea1SDimitry Andric 
14090fca6ea1SDimitry Andric     // Within C++20 modules, we may have multiple same constructors in
14100fca6ea1SDimitry Andric     // multiple same RecordDecls. And it doesn't make sense to create
14110fca6ea1SDimitry Andric     // duplicated deduction guides for the duplicated constructors.
14120fca6ea1SDimitry Andric     if (ProcessedCtors.count(D))
14130fca6ea1SDimitry Andric       continue;
14140fca6ea1SDimitry Andric 
14150fca6ea1SDimitry Andric     auto *FTD = dyn_cast<FunctionTemplateDecl>(D);
14160fca6ea1SDimitry Andric     auto *CD =
14170fca6ea1SDimitry Andric         dyn_cast_or_null<CXXConstructorDecl>(FTD ? FTD->getTemplatedDecl() : D);
14180fca6ea1SDimitry Andric     // Class-scope explicit specializations (MS extension) do not result in
14190fca6ea1SDimitry Andric     // deduction guides.
14200fca6ea1SDimitry Andric     if (!CD || (!FTD && CD->isFunctionTemplateSpecialization()))
14210fca6ea1SDimitry Andric       continue;
14220fca6ea1SDimitry Andric 
14230fca6ea1SDimitry Andric     // Cannot make a deduction guide when unparsed arguments are present.
14240fca6ea1SDimitry Andric     if (llvm::any_of(CD->parameters(), [](ParmVarDecl *P) {
14250fca6ea1SDimitry Andric           return !P || P->hasUnparsedDefaultArg();
14260fca6ea1SDimitry Andric         }))
14270fca6ea1SDimitry Andric       continue;
14280fca6ea1SDimitry Andric 
14290fca6ea1SDimitry Andric     ProcessedCtors.insert(D);
14300fca6ea1SDimitry Andric     Transform.transformConstructor(FTD, CD);
14310fca6ea1SDimitry Andric     AddedAny = true;
14320fca6ea1SDimitry Andric   }
14330fca6ea1SDimitry Andric 
14340fca6ea1SDimitry Andric   // C++17 [over.match.class.deduct]
14350fca6ea1SDimitry Andric   //    --  If C is not defined or does not declare any constructors, an
14360fca6ea1SDimitry Andric   //    additional function template derived as above from a hypothetical
14370fca6ea1SDimitry Andric   //    constructor C().
14380fca6ea1SDimitry Andric   if (!AddedAny)
14390fca6ea1SDimitry Andric     Transform.buildSimpleDeductionGuide(std::nullopt);
14400fca6ea1SDimitry Andric 
14410fca6ea1SDimitry Andric   //    -- An additional function template derived as above from a hypothetical
14420fca6ea1SDimitry Andric   //    constructor C(C), called the copy deduction candidate.
14430fca6ea1SDimitry Andric   cast<CXXDeductionGuideDecl>(
14440fca6ea1SDimitry Andric       cast<FunctionTemplateDecl>(
14450fca6ea1SDimitry Andric           Transform.buildSimpleDeductionGuide(Transform.DeducedType))
14460fca6ea1SDimitry Andric           ->getTemplatedDecl())
14470fca6ea1SDimitry Andric       ->setDeductionCandidateKind(DeductionCandidate::Copy);
14480fca6ea1SDimitry Andric 
14490fca6ea1SDimitry Andric   SavedContext.pop();
14500fca6ea1SDimitry Andric }
1451