xref: /freebsd-src/contrib/llvm-project/clang/lib/Sema/SemaTemplateDeductionGuide.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1*0fca6ea1SDimitry Andric //===- SemaTemplateDeductionGude.cpp - Template Argument Deduction---------===//
2*0fca6ea1SDimitry Andric //
3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0fca6ea1SDimitry Andric //
7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
8*0fca6ea1SDimitry Andric //
9*0fca6ea1SDimitry Andric // This file implements deduction guides for C++ class template argument
10*0fca6ea1SDimitry Andric // deduction.
11*0fca6ea1SDimitry Andric //
12*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
13*0fca6ea1SDimitry Andric 
14*0fca6ea1SDimitry Andric #include "TreeTransform.h"
15*0fca6ea1SDimitry Andric #include "TypeLocBuilder.h"
16*0fca6ea1SDimitry Andric #include "clang/AST/ASTConsumer.h"
17*0fca6ea1SDimitry Andric #include "clang/AST/ASTContext.h"
18*0fca6ea1SDimitry Andric #include "clang/AST/Decl.h"
19*0fca6ea1SDimitry Andric #include "clang/AST/DeclBase.h"
20*0fca6ea1SDimitry Andric #include "clang/AST/DeclCXX.h"
21*0fca6ea1SDimitry Andric #include "clang/AST/DeclFriend.h"
22*0fca6ea1SDimitry Andric #include "clang/AST/DeclTemplate.h"
23*0fca6ea1SDimitry Andric #include "clang/AST/DeclarationName.h"
24*0fca6ea1SDimitry Andric #include "clang/AST/Expr.h"
25*0fca6ea1SDimitry Andric #include "clang/AST/ExprCXX.h"
26*0fca6ea1SDimitry Andric #include "clang/AST/OperationKinds.h"
27*0fca6ea1SDimitry Andric #include "clang/AST/RecursiveASTVisitor.h"
28*0fca6ea1SDimitry Andric #include "clang/AST/TemplateBase.h"
29*0fca6ea1SDimitry Andric #include "clang/AST/TemplateName.h"
30*0fca6ea1SDimitry Andric #include "clang/AST/Type.h"
31*0fca6ea1SDimitry Andric #include "clang/AST/TypeLoc.h"
32*0fca6ea1SDimitry Andric #include "clang/Basic/LLVM.h"
33*0fca6ea1SDimitry Andric #include "clang/Basic/SourceLocation.h"
34*0fca6ea1SDimitry Andric #include "clang/Basic/Specifiers.h"
35*0fca6ea1SDimitry Andric #include "clang/Basic/TypeTraits.h"
36*0fca6ea1SDimitry Andric #include "clang/Sema/DeclSpec.h"
37*0fca6ea1SDimitry Andric #include "clang/Sema/Initialization.h"
38*0fca6ea1SDimitry Andric #include "clang/Sema/Lookup.h"
39*0fca6ea1SDimitry Andric #include "clang/Sema/Overload.h"
40*0fca6ea1SDimitry Andric #include "clang/Sema/Ownership.h"
41*0fca6ea1SDimitry Andric #include "clang/Sema/Scope.h"
42*0fca6ea1SDimitry Andric #include "clang/Sema/Template.h"
43*0fca6ea1SDimitry Andric #include "clang/Sema/TemplateDeduction.h"
44*0fca6ea1SDimitry Andric #include "llvm/ADT/ArrayRef.h"
45*0fca6ea1SDimitry Andric #include "llvm/ADT/DenseSet.h"
46*0fca6ea1SDimitry Andric #include "llvm/ADT/STLExtras.h"
47*0fca6ea1SDimitry Andric #include "llvm/ADT/SmallVector.h"
48*0fca6ea1SDimitry Andric #include "llvm/Support/Casting.h"
49*0fca6ea1SDimitry Andric #include "llvm/Support/ErrorHandling.h"
50*0fca6ea1SDimitry Andric #include <cassert>
51*0fca6ea1SDimitry Andric #include <optional>
52*0fca6ea1SDimitry Andric #include <utility>
53*0fca6ea1SDimitry Andric 
54*0fca6ea1SDimitry Andric using namespace clang;
55*0fca6ea1SDimitry Andric using namespace sema;
56*0fca6ea1SDimitry Andric 
57*0fca6ea1SDimitry Andric namespace {
58*0fca6ea1SDimitry Andric /// Tree transform to "extract" a transformed type from a class template's
59*0fca6ea1SDimitry Andric /// constructor to a deduction guide.
60*0fca6ea1SDimitry Andric class ExtractTypeForDeductionGuide
61*0fca6ea1SDimitry Andric     : public TreeTransform<ExtractTypeForDeductionGuide> {
62*0fca6ea1SDimitry Andric   llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs;
63*0fca6ea1SDimitry Andric   ClassTemplateDecl *NestedPattern;
64*0fca6ea1SDimitry Andric   const MultiLevelTemplateArgumentList *OuterInstantiationArgs;
65*0fca6ea1SDimitry Andric   std::optional<TemplateDeclInstantiator> TypedefNameInstantiator;
66*0fca6ea1SDimitry Andric 
67*0fca6ea1SDimitry Andric public:
68*0fca6ea1SDimitry Andric   typedef TreeTransform<ExtractTypeForDeductionGuide> Base;
69*0fca6ea1SDimitry Andric   ExtractTypeForDeductionGuide(
70*0fca6ea1SDimitry Andric       Sema &SemaRef,
71*0fca6ea1SDimitry Andric       llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs,
72*0fca6ea1SDimitry Andric       ClassTemplateDecl *NestedPattern,
73*0fca6ea1SDimitry Andric       const MultiLevelTemplateArgumentList *OuterInstantiationArgs)
74*0fca6ea1SDimitry Andric       : Base(SemaRef), MaterializedTypedefs(MaterializedTypedefs),
75*0fca6ea1SDimitry Andric         NestedPattern(NestedPattern),
76*0fca6ea1SDimitry Andric         OuterInstantiationArgs(OuterInstantiationArgs) {
77*0fca6ea1SDimitry Andric     if (OuterInstantiationArgs)
78*0fca6ea1SDimitry Andric       TypedefNameInstantiator.emplace(
79*0fca6ea1SDimitry Andric           SemaRef, SemaRef.getASTContext().getTranslationUnitDecl(),
80*0fca6ea1SDimitry Andric           *OuterInstantiationArgs);
81*0fca6ea1SDimitry Andric   }
82*0fca6ea1SDimitry Andric 
83*0fca6ea1SDimitry Andric   TypeSourceInfo *transform(TypeSourceInfo *TSI) { return TransformType(TSI); }
84*0fca6ea1SDimitry Andric 
85*0fca6ea1SDimitry Andric   /// Returns true if it's safe to substitute \p Typedef with
86*0fca6ea1SDimitry Andric   /// \p OuterInstantiationArgs.
87*0fca6ea1SDimitry Andric   bool mightReferToOuterTemplateParameters(TypedefNameDecl *Typedef) {
88*0fca6ea1SDimitry Andric     if (!NestedPattern)
89*0fca6ea1SDimitry Andric       return false;
90*0fca6ea1SDimitry Andric 
91*0fca6ea1SDimitry Andric     static auto WalkUp = [](DeclContext *DC, DeclContext *TargetDC) {
92*0fca6ea1SDimitry Andric       if (DC->Equals(TargetDC))
93*0fca6ea1SDimitry Andric         return true;
94*0fca6ea1SDimitry Andric       while (DC->isRecord()) {
95*0fca6ea1SDimitry Andric         if (DC->Equals(TargetDC))
96*0fca6ea1SDimitry Andric           return true;
97*0fca6ea1SDimitry Andric         DC = DC->getParent();
98*0fca6ea1SDimitry Andric       }
99*0fca6ea1SDimitry Andric       return false;
100*0fca6ea1SDimitry Andric     };
101*0fca6ea1SDimitry Andric 
102*0fca6ea1SDimitry Andric     if (WalkUp(Typedef->getDeclContext(), NestedPattern->getTemplatedDecl()))
103*0fca6ea1SDimitry Andric       return true;
104*0fca6ea1SDimitry Andric     if (WalkUp(NestedPattern->getTemplatedDecl(), Typedef->getDeclContext()))
105*0fca6ea1SDimitry Andric       return true;
106*0fca6ea1SDimitry Andric     return false;
107*0fca6ea1SDimitry Andric   }
108*0fca6ea1SDimitry Andric 
109*0fca6ea1SDimitry Andric   QualType
110*0fca6ea1SDimitry Andric   RebuildTemplateSpecializationType(TemplateName Template,
111*0fca6ea1SDimitry Andric                                     SourceLocation TemplateNameLoc,
112*0fca6ea1SDimitry Andric                                     TemplateArgumentListInfo &TemplateArgs) {
113*0fca6ea1SDimitry Andric     if (!OuterInstantiationArgs ||
114*0fca6ea1SDimitry Andric         !isa_and_present<TypeAliasTemplateDecl>(Template.getAsTemplateDecl()))
115*0fca6ea1SDimitry Andric       return Base::RebuildTemplateSpecializationType(Template, TemplateNameLoc,
116*0fca6ea1SDimitry Andric                                                      TemplateArgs);
117*0fca6ea1SDimitry Andric 
118*0fca6ea1SDimitry Andric     auto *TATD = cast<TypeAliasTemplateDecl>(Template.getAsTemplateDecl());
119*0fca6ea1SDimitry Andric     auto *Pattern = TATD;
120*0fca6ea1SDimitry Andric     while (Pattern->getInstantiatedFromMemberTemplate())
121*0fca6ea1SDimitry Andric       Pattern = Pattern->getInstantiatedFromMemberTemplate();
122*0fca6ea1SDimitry Andric     if (!mightReferToOuterTemplateParameters(Pattern->getTemplatedDecl()))
123*0fca6ea1SDimitry Andric       return Base::RebuildTemplateSpecializationType(Template, TemplateNameLoc,
124*0fca6ea1SDimitry Andric                                                      TemplateArgs);
125*0fca6ea1SDimitry Andric 
126*0fca6ea1SDimitry Andric     Decl *NewD =
127*0fca6ea1SDimitry Andric         TypedefNameInstantiator->InstantiateTypeAliasTemplateDecl(TATD);
128*0fca6ea1SDimitry Andric     if (!NewD)
129*0fca6ea1SDimitry Andric       return QualType();
130*0fca6ea1SDimitry Andric 
131*0fca6ea1SDimitry Andric     auto *NewTATD = cast<TypeAliasTemplateDecl>(NewD);
132*0fca6ea1SDimitry Andric     MaterializedTypedefs.push_back(NewTATD->getTemplatedDecl());
133*0fca6ea1SDimitry Andric 
134*0fca6ea1SDimitry Andric     return Base::RebuildTemplateSpecializationType(
135*0fca6ea1SDimitry Andric         TemplateName(NewTATD), TemplateNameLoc, TemplateArgs);
136*0fca6ea1SDimitry Andric   }
137*0fca6ea1SDimitry Andric 
138*0fca6ea1SDimitry Andric   QualType TransformTypedefType(TypeLocBuilder &TLB, TypedefTypeLoc TL) {
139*0fca6ea1SDimitry Andric     ASTContext &Context = SemaRef.getASTContext();
140*0fca6ea1SDimitry Andric     TypedefNameDecl *OrigDecl = TL.getTypedefNameDecl();
141*0fca6ea1SDimitry Andric     TypedefNameDecl *Decl = OrigDecl;
142*0fca6ea1SDimitry Andric     // Transform the underlying type of the typedef and clone the Decl only if
143*0fca6ea1SDimitry Andric     // the typedef has a dependent context.
144*0fca6ea1SDimitry Andric     bool InDependentContext = OrigDecl->getDeclContext()->isDependentContext();
145*0fca6ea1SDimitry Andric 
146*0fca6ea1SDimitry Andric     // A typedef/alias Decl within the NestedPattern may reference the outer
147*0fca6ea1SDimitry Andric     // template parameters. They're substituted with corresponding instantiation
148*0fca6ea1SDimitry Andric     // arguments here and in RebuildTemplateSpecializationType() above.
149*0fca6ea1SDimitry Andric     // Otherwise, we would have a CTAD guide with "dangling" template
150*0fca6ea1SDimitry Andric     // parameters.
151*0fca6ea1SDimitry Andric     // For example,
152*0fca6ea1SDimitry Andric     //   template <class T> struct Outer {
153*0fca6ea1SDimitry Andric     //     using Alias = S<T>;
154*0fca6ea1SDimitry Andric     //     template <class U> struct Inner {
155*0fca6ea1SDimitry Andric     //       Inner(Alias);
156*0fca6ea1SDimitry Andric     //     };
157*0fca6ea1SDimitry Andric     //   };
158*0fca6ea1SDimitry Andric     if (OuterInstantiationArgs && InDependentContext &&
159*0fca6ea1SDimitry Andric         TL.getTypePtr()->isInstantiationDependentType()) {
160*0fca6ea1SDimitry Andric       Decl = cast_if_present<TypedefNameDecl>(
161*0fca6ea1SDimitry Andric           TypedefNameInstantiator->InstantiateTypedefNameDecl(
162*0fca6ea1SDimitry Andric               OrigDecl, /*IsTypeAlias=*/isa<TypeAliasDecl>(OrigDecl)));
163*0fca6ea1SDimitry Andric       if (!Decl)
164*0fca6ea1SDimitry Andric         return QualType();
165*0fca6ea1SDimitry Andric       MaterializedTypedefs.push_back(Decl);
166*0fca6ea1SDimitry Andric     } else if (InDependentContext) {
167*0fca6ea1SDimitry Andric       TypeLocBuilder InnerTLB;
168*0fca6ea1SDimitry Andric       QualType Transformed =
169*0fca6ea1SDimitry Andric           TransformType(InnerTLB, OrigDecl->getTypeSourceInfo()->getTypeLoc());
170*0fca6ea1SDimitry Andric       TypeSourceInfo *TSI = InnerTLB.getTypeSourceInfo(Context, Transformed);
171*0fca6ea1SDimitry Andric       if (isa<TypeAliasDecl>(OrigDecl))
172*0fca6ea1SDimitry Andric         Decl = TypeAliasDecl::Create(
173*0fca6ea1SDimitry Andric             Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
174*0fca6ea1SDimitry Andric             OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
175*0fca6ea1SDimitry Andric       else {
176*0fca6ea1SDimitry Andric         assert(isa<TypedefDecl>(OrigDecl) && "Not a Type alias or typedef");
177*0fca6ea1SDimitry Andric         Decl = TypedefDecl::Create(
178*0fca6ea1SDimitry Andric             Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
179*0fca6ea1SDimitry Andric             OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
180*0fca6ea1SDimitry Andric       }
181*0fca6ea1SDimitry Andric       MaterializedTypedefs.push_back(Decl);
182*0fca6ea1SDimitry Andric     }
183*0fca6ea1SDimitry Andric 
184*0fca6ea1SDimitry Andric     QualType TDTy = Context.getTypedefType(Decl);
185*0fca6ea1SDimitry Andric     TypedefTypeLoc TypedefTL = TLB.push<TypedefTypeLoc>(TDTy);
186*0fca6ea1SDimitry Andric     TypedefTL.setNameLoc(TL.getNameLoc());
187*0fca6ea1SDimitry Andric 
188*0fca6ea1SDimitry Andric     return TDTy;
189*0fca6ea1SDimitry Andric   }
190*0fca6ea1SDimitry Andric };
191*0fca6ea1SDimitry Andric 
192*0fca6ea1SDimitry Andric // Build a deduction guide using the provided information.
193*0fca6ea1SDimitry Andric //
194*0fca6ea1SDimitry Andric // A deduction guide can be either a template or a non-template function
195*0fca6ea1SDimitry Andric // declaration. If \p TemplateParams is null, a non-template function
196*0fca6ea1SDimitry Andric // declaration will be created.
197*0fca6ea1SDimitry Andric NamedDecl *buildDeductionGuide(
198*0fca6ea1SDimitry Andric     Sema &SemaRef, TemplateDecl *OriginalTemplate,
199*0fca6ea1SDimitry Andric     TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor,
200*0fca6ea1SDimitry Andric     ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart,
201*0fca6ea1SDimitry Andric     SourceLocation Loc, SourceLocation LocEnd, bool IsImplicit,
202*0fca6ea1SDimitry Andric     llvm::ArrayRef<TypedefNameDecl *> MaterializedTypedefs = {}) {
203*0fca6ea1SDimitry Andric   DeclContext *DC = OriginalTemplate->getDeclContext();
204*0fca6ea1SDimitry Andric   auto DeductionGuideName =
205*0fca6ea1SDimitry Andric       SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(
206*0fca6ea1SDimitry Andric           OriginalTemplate);
207*0fca6ea1SDimitry Andric 
208*0fca6ea1SDimitry Andric   DeclarationNameInfo Name(DeductionGuideName, Loc);
209*0fca6ea1SDimitry Andric   ArrayRef<ParmVarDecl *> Params =
210*0fca6ea1SDimitry Andric       TInfo->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams();
211*0fca6ea1SDimitry Andric 
212*0fca6ea1SDimitry Andric   // Build the implicit deduction guide template.
213*0fca6ea1SDimitry Andric   auto *Guide =
214*0fca6ea1SDimitry Andric       CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, ES, Name,
215*0fca6ea1SDimitry Andric                                     TInfo->getType(), TInfo, LocEnd, Ctor);
216*0fca6ea1SDimitry Andric   Guide->setImplicit(IsImplicit);
217*0fca6ea1SDimitry Andric   Guide->setParams(Params);
218*0fca6ea1SDimitry Andric 
219*0fca6ea1SDimitry Andric   for (auto *Param : Params)
220*0fca6ea1SDimitry Andric     Param->setDeclContext(Guide);
221*0fca6ea1SDimitry Andric   for (auto *TD : MaterializedTypedefs)
222*0fca6ea1SDimitry Andric     TD->setDeclContext(Guide);
223*0fca6ea1SDimitry Andric   if (isa<CXXRecordDecl>(DC))
224*0fca6ea1SDimitry Andric     Guide->setAccess(AS_public);
225*0fca6ea1SDimitry Andric 
226*0fca6ea1SDimitry Andric   if (!TemplateParams) {
227*0fca6ea1SDimitry Andric     DC->addDecl(Guide);
228*0fca6ea1SDimitry Andric     return Guide;
229*0fca6ea1SDimitry Andric   }
230*0fca6ea1SDimitry Andric 
231*0fca6ea1SDimitry Andric   auto *GuideTemplate = FunctionTemplateDecl::Create(
232*0fca6ea1SDimitry Andric       SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide);
233*0fca6ea1SDimitry Andric   GuideTemplate->setImplicit(IsImplicit);
234*0fca6ea1SDimitry Andric   Guide->setDescribedFunctionTemplate(GuideTemplate);
235*0fca6ea1SDimitry Andric 
236*0fca6ea1SDimitry Andric   if (isa<CXXRecordDecl>(DC))
237*0fca6ea1SDimitry Andric     GuideTemplate->setAccess(AS_public);
238*0fca6ea1SDimitry Andric 
239*0fca6ea1SDimitry Andric   DC->addDecl(GuideTemplate);
240*0fca6ea1SDimitry Andric   return GuideTemplate;
241*0fca6ea1SDimitry Andric }
242*0fca6ea1SDimitry Andric 
243*0fca6ea1SDimitry Andric // Transform a given template type parameter `TTP`.
244*0fca6ea1SDimitry Andric TemplateTypeParmDecl *
245*0fca6ea1SDimitry Andric transformTemplateTypeParam(Sema &SemaRef, DeclContext *DC,
246*0fca6ea1SDimitry Andric                            TemplateTypeParmDecl *TTP,
247*0fca6ea1SDimitry Andric                            MultiLevelTemplateArgumentList &Args,
248*0fca6ea1SDimitry Andric                            unsigned NewDepth, unsigned NewIndex) {
249*0fca6ea1SDimitry Andric   // TemplateTypeParmDecl's index cannot be changed after creation, so
250*0fca6ea1SDimitry Andric   // substitute it directly.
251*0fca6ea1SDimitry Andric   auto *NewTTP = TemplateTypeParmDecl::Create(
252*0fca6ea1SDimitry Andric       SemaRef.Context, DC, TTP->getBeginLoc(), TTP->getLocation(), NewDepth,
253*0fca6ea1SDimitry Andric       NewIndex, TTP->getIdentifier(), TTP->wasDeclaredWithTypename(),
254*0fca6ea1SDimitry Andric       TTP->isParameterPack(), TTP->hasTypeConstraint(),
255*0fca6ea1SDimitry Andric       TTP->isExpandedParameterPack()
256*0fca6ea1SDimitry Andric           ? std::optional<unsigned>(TTP->getNumExpansionParameters())
257*0fca6ea1SDimitry Andric           : std::nullopt);
258*0fca6ea1SDimitry Andric   if (const auto *TC = TTP->getTypeConstraint())
259*0fca6ea1SDimitry Andric     SemaRef.SubstTypeConstraint(NewTTP, TC, Args,
260*0fca6ea1SDimitry Andric                                 /*EvaluateConstraint=*/true);
261*0fca6ea1SDimitry Andric   if (TTP->hasDefaultArgument()) {
262*0fca6ea1SDimitry Andric     TemplateArgumentLoc InstantiatedDefaultArg;
263*0fca6ea1SDimitry Andric     if (!SemaRef.SubstTemplateArgument(
264*0fca6ea1SDimitry Andric             TTP->getDefaultArgument(), Args, InstantiatedDefaultArg,
265*0fca6ea1SDimitry Andric             TTP->getDefaultArgumentLoc(), TTP->getDeclName()))
266*0fca6ea1SDimitry Andric       NewTTP->setDefaultArgument(SemaRef.Context, InstantiatedDefaultArg);
267*0fca6ea1SDimitry Andric   }
268*0fca6ea1SDimitry Andric   SemaRef.CurrentInstantiationScope->InstantiatedLocal(TTP, NewTTP);
269*0fca6ea1SDimitry Andric   return NewTTP;
270*0fca6ea1SDimitry Andric }
271*0fca6ea1SDimitry Andric // Similar to above, but for non-type template or template template parameters.
272*0fca6ea1SDimitry Andric template <typename NonTypeTemplateOrTemplateTemplateParmDecl>
273*0fca6ea1SDimitry Andric NonTypeTemplateOrTemplateTemplateParmDecl *
274*0fca6ea1SDimitry Andric transformTemplateParam(Sema &SemaRef, DeclContext *DC,
275*0fca6ea1SDimitry Andric                        NonTypeTemplateOrTemplateTemplateParmDecl *OldParam,
276*0fca6ea1SDimitry Andric                        MultiLevelTemplateArgumentList &Args, unsigned NewIndex,
277*0fca6ea1SDimitry Andric                        unsigned NewDepth) {
278*0fca6ea1SDimitry Andric   // Ask the template instantiator to do the heavy lifting for us, then adjust
279*0fca6ea1SDimitry Andric   // the index of the parameter once it's done.
280*0fca6ea1SDimitry Andric   auto *NewParam = cast<NonTypeTemplateOrTemplateTemplateParmDecl>(
281*0fca6ea1SDimitry Andric       SemaRef.SubstDecl(OldParam, DC, Args));
282*0fca6ea1SDimitry Andric   NewParam->setPosition(NewIndex);
283*0fca6ea1SDimitry Andric   NewParam->setDepth(NewDepth);
284*0fca6ea1SDimitry Andric   return NewParam;
285*0fca6ea1SDimitry Andric }
286*0fca6ea1SDimitry Andric 
287*0fca6ea1SDimitry Andric /// Transform to convert portions of a constructor declaration into the
288*0fca6ea1SDimitry Andric /// corresponding deduction guide, per C++1z [over.match.class.deduct]p1.
289*0fca6ea1SDimitry Andric struct ConvertConstructorToDeductionGuideTransform {
290*0fca6ea1SDimitry Andric   ConvertConstructorToDeductionGuideTransform(Sema &S,
291*0fca6ea1SDimitry Andric                                               ClassTemplateDecl *Template)
292*0fca6ea1SDimitry Andric       : SemaRef(S), Template(Template) {
293*0fca6ea1SDimitry Andric     // If the template is nested, then we need to use the original
294*0fca6ea1SDimitry Andric     // pattern to iterate over the constructors.
295*0fca6ea1SDimitry Andric     ClassTemplateDecl *Pattern = Template;
296*0fca6ea1SDimitry Andric     while (Pattern->getInstantiatedFromMemberTemplate()) {
297*0fca6ea1SDimitry Andric       if (Pattern->isMemberSpecialization())
298*0fca6ea1SDimitry Andric         break;
299*0fca6ea1SDimitry Andric       Pattern = Pattern->getInstantiatedFromMemberTemplate();
300*0fca6ea1SDimitry Andric       NestedPattern = Pattern;
301*0fca6ea1SDimitry Andric     }
302*0fca6ea1SDimitry Andric 
303*0fca6ea1SDimitry Andric     if (NestedPattern)
304*0fca6ea1SDimitry Andric       OuterInstantiationArgs = SemaRef.getTemplateInstantiationArgs(Template);
305*0fca6ea1SDimitry Andric   }
306*0fca6ea1SDimitry Andric 
307*0fca6ea1SDimitry Andric   Sema &SemaRef;
308*0fca6ea1SDimitry Andric   ClassTemplateDecl *Template;
309*0fca6ea1SDimitry Andric   ClassTemplateDecl *NestedPattern = nullptr;
310*0fca6ea1SDimitry Andric 
311*0fca6ea1SDimitry Andric   DeclContext *DC = Template->getDeclContext();
312*0fca6ea1SDimitry Andric   CXXRecordDecl *Primary = Template->getTemplatedDecl();
313*0fca6ea1SDimitry Andric   DeclarationName DeductionGuideName =
314*0fca6ea1SDimitry Andric       SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(Template);
315*0fca6ea1SDimitry Andric 
316*0fca6ea1SDimitry Andric   QualType DeducedType = SemaRef.Context.getTypeDeclType(Primary);
317*0fca6ea1SDimitry Andric 
318*0fca6ea1SDimitry Andric   // Index adjustment to apply to convert depth-1 template parameters into
319*0fca6ea1SDimitry Andric   // depth-0 template parameters.
320*0fca6ea1SDimitry Andric   unsigned Depth1IndexAdjustment = Template->getTemplateParameters()->size();
321*0fca6ea1SDimitry Andric 
322*0fca6ea1SDimitry Andric   // Instantiation arguments for the outermost depth-1 templates
323*0fca6ea1SDimitry Andric   // when the template is nested
324*0fca6ea1SDimitry Andric   MultiLevelTemplateArgumentList OuterInstantiationArgs;
325*0fca6ea1SDimitry Andric 
326*0fca6ea1SDimitry Andric   /// Transform a constructor declaration into a deduction guide.
327*0fca6ea1SDimitry Andric   NamedDecl *transformConstructor(FunctionTemplateDecl *FTD,
328*0fca6ea1SDimitry Andric                                   CXXConstructorDecl *CD) {
329*0fca6ea1SDimitry Andric     SmallVector<TemplateArgument, 16> SubstArgs;
330*0fca6ea1SDimitry Andric 
331*0fca6ea1SDimitry Andric     LocalInstantiationScope Scope(SemaRef);
332*0fca6ea1SDimitry Andric 
333*0fca6ea1SDimitry Andric     // C++ [over.match.class.deduct]p1:
334*0fca6ea1SDimitry Andric     // -- For each constructor of the class template designated by the
335*0fca6ea1SDimitry Andric     //    template-name, a function template with the following properties:
336*0fca6ea1SDimitry Andric 
337*0fca6ea1SDimitry Andric     //    -- The template parameters are the template parameters of the class
338*0fca6ea1SDimitry Andric     //       template followed by the template parameters (including default
339*0fca6ea1SDimitry Andric     //       template arguments) of the constructor, if any.
340*0fca6ea1SDimitry Andric     TemplateParameterList *TemplateParams =
341*0fca6ea1SDimitry Andric         SemaRef.GetTemplateParameterList(Template);
342*0fca6ea1SDimitry Andric     if (FTD) {
343*0fca6ea1SDimitry Andric       TemplateParameterList *InnerParams = FTD->getTemplateParameters();
344*0fca6ea1SDimitry Andric       SmallVector<NamedDecl *, 16> AllParams;
345*0fca6ea1SDimitry Andric       SmallVector<TemplateArgument, 16> Depth1Args;
346*0fca6ea1SDimitry Andric       AllParams.reserve(TemplateParams->size() + InnerParams->size());
347*0fca6ea1SDimitry Andric       AllParams.insert(AllParams.begin(), TemplateParams->begin(),
348*0fca6ea1SDimitry Andric                        TemplateParams->end());
349*0fca6ea1SDimitry Andric       SubstArgs.reserve(InnerParams->size());
350*0fca6ea1SDimitry Andric       Depth1Args.reserve(InnerParams->size());
351*0fca6ea1SDimitry Andric 
352*0fca6ea1SDimitry Andric       // Later template parameters could refer to earlier ones, so build up
353*0fca6ea1SDimitry Andric       // a list of substituted template arguments as we go.
354*0fca6ea1SDimitry Andric       for (NamedDecl *Param : *InnerParams) {
355*0fca6ea1SDimitry Andric         MultiLevelTemplateArgumentList Args;
356*0fca6ea1SDimitry Andric         Args.setKind(TemplateSubstitutionKind::Rewrite);
357*0fca6ea1SDimitry Andric         Args.addOuterTemplateArguments(Depth1Args);
358*0fca6ea1SDimitry Andric         Args.addOuterRetainedLevel();
359*0fca6ea1SDimitry Andric         if (NestedPattern)
360*0fca6ea1SDimitry Andric           Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
361*0fca6ea1SDimitry Andric         NamedDecl *NewParam = transformTemplateParameter(Param, Args);
362*0fca6ea1SDimitry Andric         if (!NewParam)
363*0fca6ea1SDimitry Andric           return nullptr;
364*0fca6ea1SDimitry Andric         // Constraints require that we substitute depth-1 arguments
365*0fca6ea1SDimitry Andric         // to match depths when substituted for evaluation later
366*0fca6ea1SDimitry Andric         Depth1Args.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam));
367*0fca6ea1SDimitry Andric 
368*0fca6ea1SDimitry Andric         if (NestedPattern) {
369*0fca6ea1SDimitry Andric           TemplateDeclInstantiator Instantiator(SemaRef, DC,
370*0fca6ea1SDimitry Andric                                                 OuterInstantiationArgs);
371*0fca6ea1SDimitry Andric           Instantiator.setEvaluateConstraints(false);
372*0fca6ea1SDimitry Andric           SemaRef.runWithSufficientStackSpace(NewParam->getLocation(), [&] {
373*0fca6ea1SDimitry Andric             NewParam = cast<NamedDecl>(Instantiator.Visit(NewParam));
374*0fca6ea1SDimitry Andric           });
375*0fca6ea1SDimitry Andric         }
376*0fca6ea1SDimitry Andric 
377*0fca6ea1SDimitry Andric         assert(NewParam->getTemplateDepth() == 0 &&
378*0fca6ea1SDimitry Andric                "Unexpected template parameter depth");
379*0fca6ea1SDimitry Andric 
380*0fca6ea1SDimitry Andric         AllParams.push_back(NewParam);
381*0fca6ea1SDimitry Andric         SubstArgs.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam));
382*0fca6ea1SDimitry Andric       }
383*0fca6ea1SDimitry Andric 
384*0fca6ea1SDimitry Andric       // Substitute new template parameters into requires-clause if present.
385*0fca6ea1SDimitry Andric       Expr *RequiresClause = nullptr;
386*0fca6ea1SDimitry Andric       if (Expr *InnerRC = InnerParams->getRequiresClause()) {
387*0fca6ea1SDimitry Andric         MultiLevelTemplateArgumentList Args;
388*0fca6ea1SDimitry Andric         Args.setKind(TemplateSubstitutionKind::Rewrite);
389*0fca6ea1SDimitry Andric         Args.addOuterTemplateArguments(Depth1Args);
390*0fca6ea1SDimitry Andric         Args.addOuterRetainedLevel();
391*0fca6ea1SDimitry Andric         if (NestedPattern)
392*0fca6ea1SDimitry Andric           Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
393*0fca6ea1SDimitry Andric         ExprResult E = SemaRef.SubstExpr(InnerRC, Args);
394*0fca6ea1SDimitry Andric         if (E.isInvalid())
395*0fca6ea1SDimitry Andric           return nullptr;
396*0fca6ea1SDimitry Andric         RequiresClause = E.getAs<Expr>();
397*0fca6ea1SDimitry Andric       }
398*0fca6ea1SDimitry Andric 
399*0fca6ea1SDimitry Andric       TemplateParams = TemplateParameterList::Create(
400*0fca6ea1SDimitry Andric           SemaRef.Context, InnerParams->getTemplateLoc(),
401*0fca6ea1SDimitry Andric           InnerParams->getLAngleLoc(), AllParams, InnerParams->getRAngleLoc(),
402*0fca6ea1SDimitry Andric           RequiresClause);
403*0fca6ea1SDimitry Andric     }
404*0fca6ea1SDimitry Andric 
405*0fca6ea1SDimitry Andric     // If we built a new template-parameter-list, track that we need to
406*0fca6ea1SDimitry Andric     // substitute references to the old parameters into references to the
407*0fca6ea1SDimitry Andric     // new ones.
408*0fca6ea1SDimitry Andric     MultiLevelTemplateArgumentList Args;
409*0fca6ea1SDimitry Andric     Args.setKind(TemplateSubstitutionKind::Rewrite);
410*0fca6ea1SDimitry Andric     if (FTD) {
411*0fca6ea1SDimitry Andric       Args.addOuterTemplateArguments(SubstArgs);
412*0fca6ea1SDimitry Andric       Args.addOuterRetainedLevel();
413*0fca6ea1SDimitry Andric     }
414*0fca6ea1SDimitry Andric 
415*0fca6ea1SDimitry Andric     FunctionProtoTypeLoc FPTL = CD->getTypeSourceInfo()
416*0fca6ea1SDimitry Andric                                     ->getTypeLoc()
417*0fca6ea1SDimitry Andric                                     .getAsAdjusted<FunctionProtoTypeLoc>();
418*0fca6ea1SDimitry Andric     assert(FPTL && "no prototype for constructor declaration");
419*0fca6ea1SDimitry Andric 
420*0fca6ea1SDimitry Andric     // Transform the type of the function, adjusting the return type and
421*0fca6ea1SDimitry Andric     // replacing references to the old parameters with references to the
422*0fca6ea1SDimitry Andric     // new ones.
423*0fca6ea1SDimitry Andric     TypeLocBuilder TLB;
424*0fca6ea1SDimitry Andric     SmallVector<ParmVarDecl *, 8> Params;
425*0fca6ea1SDimitry Andric     SmallVector<TypedefNameDecl *, 4> MaterializedTypedefs;
426*0fca6ea1SDimitry Andric     QualType NewType = transformFunctionProtoType(TLB, FPTL, Params, Args,
427*0fca6ea1SDimitry Andric                                                   MaterializedTypedefs);
428*0fca6ea1SDimitry Andric     if (NewType.isNull())
429*0fca6ea1SDimitry Andric       return nullptr;
430*0fca6ea1SDimitry Andric     TypeSourceInfo *NewTInfo = TLB.getTypeSourceInfo(SemaRef.Context, NewType);
431*0fca6ea1SDimitry Andric 
432*0fca6ea1SDimitry Andric     return buildDeductionGuide(
433*0fca6ea1SDimitry Andric         SemaRef, Template, TemplateParams, CD, CD->getExplicitSpecifier(),
434*0fca6ea1SDimitry Andric         NewTInfo, CD->getBeginLoc(), CD->getLocation(), CD->getEndLoc(),
435*0fca6ea1SDimitry Andric         /*IsImplicit=*/true, MaterializedTypedefs);
436*0fca6ea1SDimitry Andric   }
437*0fca6ea1SDimitry Andric 
438*0fca6ea1SDimitry Andric   /// Build a deduction guide with the specified parameter types.
439*0fca6ea1SDimitry Andric   NamedDecl *buildSimpleDeductionGuide(MutableArrayRef<QualType> ParamTypes) {
440*0fca6ea1SDimitry Andric     SourceLocation Loc = Template->getLocation();
441*0fca6ea1SDimitry Andric 
442*0fca6ea1SDimitry Andric     // Build the requested type.
443*0fca6ea1SDimitry Andric     FunctionProtoType::ExtProtoInfo EPI;
444*0fca6ea1SDimitry Andric     EPI.HasTrailingReturn = true;
445*0fca6ea1SDimitry Andric     QualType Result = SemaRef.BuildFunctionType(DeducedType, ParamTypes, Loc,
446*0fca6ea1SDimitry Andric                                                 DeductionGuideName, EPI);
447*0fca6ea1SDimitry Andric     TypeSourceInfo *TSI = SemaRef.Context.getTrivialTypeSourceInfo(Result, Loc);
448*0fca6ea1SDimitry Andric     if (NestedPattern)
449*0fca6ea1SDimitry Andric       TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,
450*0fca6ea1SDimitry Andric                               DeductionGuideName);
451*0fca6ea1SDimitry Andric 
452*0fca6ea1SDimitry Andric     if (!TSI)
453*0fca6ea1SDimitry Andric       return nullptr;
454*0fca6ea1SDimitry Andric 
455*0fca6ea1SDimitry Andric     FunctionProtoTypeLoc FPTL =
456*0fca6ea1SDimitry Andric         TSI->getTypeLoc().castAs<FunctionProtoTypeLoc>();
457*0fca6ea1SDimitry Andric 
458*0fca6ea1SDimitry Andric     // Build the parameters, needed during deduction / substitution.
459*0fca6ea1SDimitry Andric     SmallVector<ParmVarDecl *, 4> Params;
460*0fca6ea1SDimitry Andric     for (auto T : ParamTypes) {
461*0fca6ea1SDimitry Andric       auto *TSI = SemaRef.Context.getTrivialTypeSourceInfo(T, Loc);
462*0fca6ea1SDimitry Andric       if (NestedPattern)
463*0fca6ea1SDimitry Andric         TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,
464*0fca6ea1SDimitry Andric                                 DeclarationName());
465*0fca6ea1SDimitry Andric       if (!TSI)
466*0fca6ea1SDimitry Andric         return nullptr;
467*0fca6ea1SDimitry Andric 
468*0fca6ea1SDimitry Andric       ParmVarDecl *NewParam =
469*0fca6ea1SDimitry Andric           ParmVarDecl::Create(SemaRef.Context, DC, Loc, Loc, nullptr,
470*0fca6ea1SDimitry Andric                               TSI->getType(), TSI, SC_None, nullptr);
471*0fca6ea1SDimitry Andric       NewParam->setScopeInfo(0, Params.size());
472*0fca6ea1SDimitry Andric       FPTL.setParam(Params.size(), NewParam);
473*0fca6ea1SDimitry Andric       Params.push_back(NewParam);
474*0fca6ea1SDimitry Andric     }
475*0fca6ea1SDimitry Andric 
476*0fca6ea1SDimitry Andric     return buildDeductionGuide(
477*0fca6ea1SDimitry Andric         SemaRef, Template, SemaRef.GetTemplateParameterList(Template), nullptr,
478*0fca6ea1SDimitry Andric         ExplicitSpecifier(), TSI, Loc, Loc, Loc, /*IsImplicit=*/true);
479*0fca6ea1SDimitry Andric   }
480*0fca6ea1SDimitry Andric 
481*0fca6ea1SDimitry Andric private:
482*0fca6ea1SDimitry Andric   /// Transform a constructor template parameter into a deduction guide template
483*0fca6ea1SDimitry Andric   /// parameter, rebuilding any internal references to earlier parameters and
484*0fca6ea1SDimitry Andric   /// renumbering as we go.
485*0fca6ea1SDimitry Andric   NamedDecl *transformTemplateParameter(NamedDecl *TemplateParam,
486*0fca6ea1SDimitry Andric                                         MultiLevelTemplateArgumentList &Args) {
487*0fca6ea1SDimitry Andric     if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
488*0fca6ea1SDimitry Andric       return transformTemplateTypeParam(
489*0fca6ea1SDimitry Andric           SemaRef, DC, TTP, Args, TTP->getDepth() - 1,
490*0fca6ea1SDimitry Andric           Depth1IndexAdjustment + TTP->getIndex());
491*0fca6ea1SDimitry Andric     if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
492*0fca6ea1SDimitry Andric       return transformTemplateParam(SemaRef, DC, TTP, Args,
493*0fca6ea1SDimitry Andric                                     Depth1IndexAdjustment + TTP->getIndex(),
494*0fca6ea1SDimitry Andric                                     TTP->getDepth() - 1);
495*0fca6ea1SDimitry Andric     auto *NTTP = cast<NonTypeTemplateParmDecl>(TemplateParam);
496*0fca6ea1SDimitry Andric     return transformTemplateParam(SemaRef, DC, NTTP, Args,
497*0fca6ea1SDimitry Andric                                   Depth1IndexAdjustment + NTTP->getIndex(),
498*0fca6ea1SDimitry Andric                                   NTTP->getDepth() - 1);
499*0fca6ea1SDimitry Andric   }
500*0fca6ea1SDimitry Andric 
501*0fca6ea1SDimitry Andric   QualType transformFunctionProtoType(
502*0fca6ea1SDimitry Andric       TypeLocBuilder &TLB, FunctionProtoTypeLoc TL,
503*0fca6ea1SDimitry Andric       SmallVectorImpl<ParmVarDecl *> &Params,
504*0fca6ea1SDimitry Andric       MultiLevelTemplateArgumentList &Args,
505*0fca6ea1SDimitry Andric       SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs) {
506*0fca6ea1SDimitry Andric     SmallVector<QualType, 4> ParamTypes;
507*0fca6ea1SDimitry Andric     const FunctionProtoType *T = TL.getTypePtr();
508*0fca6ea1SDimitry Andric 
509*0fca6ea1SDimitry Andric     //    -- The types of the function parameters are those of the constructor.
510*0fca6ea1SDimitry Andric     for (auto *OldParam : TL.getParams()) {
511*0fca6ea1SDimitry Andric       ParmVarDecl *NewParam = OldParam;
512*0fca6ea1SDimitry Andric       // Given
513*0fca6ea1SDimitry Andric       //   template <class T> struct C {
514*0fca6ea1SDimitry Andric       //     template <class U> struct D {
515*0fca6ea1SDimitry Andric       //       template <class V> D(U, V);
516*0fca6ea1SDimitry Andric       //     };
517*0fca6ea1SDimitry Andric       //   };
518*0fca6ea1SDimitry Andric       // First, transform all the references to template parameters that are
519*0fca6ea1SDimitry Andric       // defined outside of the surrounding class template. That is T in the
520*0fca6ea1SDimitry Andric       // above example.
521*0fca6ea1SDimitry Andric       if (NestedPattern) {
522*0fca6ea1SDimitry Andric         NewParam = transformFunctionTypeParam(
523*0fca6ea1SDimitry Andric             NewParam, OuterInstantiationArgs, MaterializedTypedefs,
524*0fca6ea1SDimitry Andric             /*TransformingOuterPatterns=*/true);
525*0fca6ea1SDimitry Andric         if (!NewParam)
526*0fca6ea1SDimitry Andric           return QualType();
527*0fca6ea1SDimitry Andric       }
528*0fca6ea1SDimitry Andric       // Then, transform all the references to template parameters that are
529*0fca6ea1SDimitry Andric       // defined at the class template and the constructor. In this example,
530*0fca6ea1SDimitry Andric       // they're U and V, respectively.
531*0fca6ea1SDimitry Andric       NewParam =
532*0fca6ea1SDimitry Andric           transformFunctionTypeParam(NewParam, Args, MaterializedTypedefs,
533*0fca6ea1SDimitry Andric                                      /*TransformingOuterPatterns=*/false);
534*0fca6ea1SDimitry Andric       if (!NewParam)
535*0fca6ea1SDimitry Andric         return QualType();
536*0fca6ea1SDimitry Andric       ParamTypes.push_back(NewParam->getType());
537*0fca6ea1SDimitry Andric       Params.push_back(NewParam);
538*0fca6ea1SDimitry Andric     }
539*0fca6ea1SDimitry Andric 
540*0fca6ea1SDimitry Andric     //    -- The return type is the class template specialization designated by
541*0fca6ea1SDimitry Andric     //       the template-name and template arguments corresponding to the
542*0fca6ea1SDimitry Andric     //       template parameters obtained from the class template.
543*0fca6ea1SDimitry Andric     //
544*0fca6ea1SDimitry Andric     // We use the injected-class-name type of the primary template instead.
545*0fca6ea1SDimitry Andric     // This has the convenient property that it is different from any type that
546*0fca6ea1SDimitry Andric     // the user can write in a deduction-guide (because they cannot enter the
547*0fca6ea1SDimitry Andric     // context of the template), so implicit deduction guides can never collide
548*0fca6ea1SDimitry Andric     // with explicit ones.
549*0fca6ea1SDimitry Andric     QualType ReturnType = DeducedType;
550*0fca6ea1SDimitry Andric     TLB.pushTypeSpec(ReturnType).setNameLoc(Primary->getLocation());
551*0fca6ea1SDimitry Andric 
552*0fca6ea1SDimitry Andric     // Resolving a wording defect, we also inherit the variadicness of the
553*0fca6ea1SDimitry Andric     // constructor.
554*0fca6ea1SDimitry Andric     FunctionProtoType::ExtProtoInfo EPI;
555*0fca6ea1SDimitry Andric     EPI.Variadic = T->isVariadic();
556*0fca6ea1SDimitry Andric     EPI.HasTrailingReturn = true;
557*0fca6ea1SDimitry Andric 
558*0fca6ea1SDimitry Andric     QualType Result = SemaRef.BuildFunctionType(
559*0fca6ea1SDimitry Andric         ReturnType, ParamTypes, TL.getBeginLoc(), DeductionGuideName, EPI);
560*0fca6ea1SDimitry Andric     if (Result.isNull())
561*0fca6ea1SDimitry Andric       return QualType();
562*0fca6ea1SDimitry Andric 
563*0fca6ea1SDimitry Andric     FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
564*0fca6ea1SDimitry Andric     NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
565*0fca6ea1SDimitry Andric     NewTL.setLParenLoc(TL.getLParenLoc());
566*0fca6ea1SDimitry Andric     NewTL.setRParenLoc(TL.getRParenLoc());
567*0fca6ea1SDimitry Andric     NewTL.setExceptionSpecRange(SourceRange());
568*0fca6ea1SDimitry Andric     NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
569*0fca6ea1SDimitry Andric     for (unsigned I = 0, E = NewTL.getNumParams(); I != E; ++I)
570*0fca6ea1SDimitry Andric       NewTL.setParam(I, Params[I]);
571*0fca6ea1SDimitry Andric 
572*0fca6ea1SDimitry Andric     return Result;
573*0fca6ea1SDimitry Andric   }
574*0fca6ea1SDimitry Andric 
575*0fca6ea1SDimitry Andric   ParmVarDecl *transformFunctionTypeParam(
576*0fca6ea1SDimitry Andric       ParmVarDecl *OldParam, MultiLevelTemplateArgumentList &Args,
577*0fca6ea1SDimitry Andric       llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs,
578*0fca6ea1SDimitry Andric       bool TransformingOuterPatterns) {
579*0fca6ea1SDimitry Andric     TypeSourceInfo *OldDI = OldParam->getTypeSourceInfo();
580*0fca6ea1SDimitry Andric     TypeSourceInfo *NewDI;
581*0fca6ea1SDimitry Andric     if (auto PackTL = OldDI->getTypeLoc().getAs<PackExpansionTypeLoc>()) {
582*0fca6ea1SDimitry Andric       // Expand out the one and only element in each inner pack.
583*0fca6ea1SDimitry Andric       Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, 0);
584*0fca6ea1SDimitry Andric       NewDI =
585*0fca6ea1SDimitry Andric           SemaRef.SubstType(PackTL.getPatternLoc(), Args,
586*0fca6ea1SDimitry Andric                             OldParam->getLocation(), OldParam->getDeclName());
587*0fca6ea1SDimitry Andric       if (!NewDI)
588*0fca6ea1SDimitry Andric         return nullptr;
589*0fca6ea1SDimitry Andric       NewDI =
590*0fca6ea1SDimitry Andric           SemaRef.CheckPackExpansion(NewDI, PackTL.getEllipsisLoc(),
591*0fca6ea1SDimitry Andric                                      PackTL.getTypePtr()->getNumExpansions());
592*0fca6ea1SDimitry Andric     } else
593*0fca6ea1SDimitry Andric       NewDI = SemaRef.SubstType(OldDI, Args, OldParam->getLocation(),
594*0fca6ea1SDimitry Andric                                 OldParam->getDeclName());
595*0fca6ea1SDimitry Andric     if (!NewDI)
596*0fca6ea1SDimitry Andric       return nullptr;
597*0fca6ea1SDimitry Andric 
598*0fca6ea1SDimitry Andric     // Extract the type. This (for instance) replaces references to typedef
599*0fca6ea1SDimitry Andric     // members of the current instantiations with the definitions of those
600*0fca6ea1SDimitry Andric     // typedefs, avoiding triggering instantiation of the deduced type during
601*0fca6ea1SDimitry Andric     // deduction.
602*0fca6ea1SDimitry Andric     NewDI = ExtractTypeForDeductionGuide(
603*0fca6ea1SDimitry Andric                 SemaRef, MaterializedTypedefs, NestedPattern,
604*0fca6ea1SDimitry Andric                 TransformingOuterPatterns ? &Args : nullptr)
605*0fca6ea1SDimitry Andric                 .transform(NewDI);
606*0fca6ea1SDimitry Andric 
607*0fca6ea1SDimitry Andric     // Resolving a wording defect, we also inherit default arguments from the
608*0fca6ea1SDimitry Andric     // constructor.
609*0fca6ea1SDimitry Andric     ExprResult NewDefArg;
610*0fca6ea1SDimitry Andric     if (OldParam->hasDefaultArg()) {
611*0fca6ea1SDimitry Andric       // We don't care what the value is (we won't use it); just create a
612*0fca6ea1SDimitry Andric       // placeholder to indicate there is a default argument.
613*0fca6ea1SDimitry Andric       QualType ParamTy = NewDI->getType();
614*0fca6ea1SDimitry Andric       NewDefArg = new (SemaRef.Context)
615*0fca6ea1SDimitry Andric           OpaqueValueExpr(OldParam->getDefaultArgRange().getBegin(),
616*0fca6ea1SDimitry Andric                           ParamTy.getNonLValueExprType(SemaRef.Context),
617*0fca6ea1SDimitry Andric                           ParamTy->isLValueReferenceType()   ? VK_LValue
618*0fca6ea1SDimitry Andric                           : ParamTy->isRValueReferenceType() ? VK_XValue
619*0fca6ea1SDimitry Andric                                                              : VK_PRValue);
620*0fca6ea1SDimitry Andric     }
621*0fca6ea1SDimitry Andric     // Handle arrays and functions decay.
622*0fca6ea1SDimitry Andric     auto NewType = NewDI->getType();
623*0fca6ea1SDimitry Andric     if (NewType->isArrayType() || NewType->isFunctionType())
624*0fca6ea1SDimitry Andric       NewType = SemaRef.Context.getDecayedType(NewType);
625*0fca6ea1SDimitry Andric 
626*0fca6ea1SDimitry Andric     ParmVarDecl *NewParam = ParmVarDecl::Create(
627*0fca6ea1SDimitry Andric         SemaRef.Context, DC, OldParam->getInnerLocStart(),
628*0fca6ea1SDimitry Andric         OldParam->getLocation(), OldParam->getIdentifier(), NewType, NewDI,
629*0fca6ea1SDimitry Andric         OldParam->getStorageClass(), NewDefArg.get());
630*0fca6ea1SDimitry Andric     NewParam->setScopeInfo(OldParam->getFunctionScopeDepth(),
631*0fca6ea1SDimitry Andric                            OldParam->getFunctionScopeIndex());
632*0fca6ea1SDimitry Andric     SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam);
633*0fca6ea1SDimitry Andric     return NewParam;
634*0fca6ea1SDimitry Andric   }
635*0fca6ea1SDimitry Andric };
636*0fca6ea1SDimitry Andric 
637*0fca6ea1SDimitry Andric unsigned getTemplateParameterDepth(NamedDecl *TemplateParam) {
638*0fca6ea1SDimitry Andric   if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
639*0fca6ea1SDimitry Andric     return TTP->getDepth();
640*0fca6ea1SDimitry Andric   if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
641*0fca6ea1SDimitry Andric     return TTP->getDepth();
642*0fca6ea1SDimitry Andric   if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
643*0fca6ea1SDimitry Andric     return NTTP->getDepth();
644*0fca6ea1SDimitry Andric   llvm_unreachable("Unhandled template parameter types");
645*0fca6ea1SDimitry Andric }
646*0fca6ea1SDimitry Andric 
647*0fca6ea1SDimitry Andric unsigned getTemplateParameterIndex(NamedDecl *TemplateParam) {
648*0fca6ea1SDimitry Andric   if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
649*0fca6ea1SDimitry Andric     return TTP->getIndex();
650*0fca6ea1SDimitry Andric   if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
651*0fca6ea1SDimitry Andric     return TTP->getIndex();
652*0fca6ea1SDimitry Andric   if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
653*0fca6ea1SDimitry Andric     return NTTP->getIndex();
654*0fca6ea1SDimitry Andric   llvm_unreachable("Unhandled template parameter types");
655*0fca6ea1SDimitry Andric }
656*0fca6ea1SDimitry Andric 
657*0fca6ea1SDimitry Andric // Find all template parameters that appear in the given DeducedArgs.
658*0fca6ea1SDimitry Andric // Return the indices of the template parameters in the TemplateParams.
659*0fca6ea1SDimitry Andric SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
660*0fca6ea1SDimitry Andric     const TemplateParameterList *TemplateParamsList,
661*0fca6ea1SDimitry Andric     ArrayRef<TemplateArgument> DeducedArgs) {
662*0fca6ea1SDimitry Andric   struct TemplateParamsReferencedFinder
663*0fca6ea1SDimitry Andric       : public RecursiveASTVisitor<TemplateParamsReferencedFinder> {
664*0fca6ea1SDimitry Andric     const TemplateParameterList *TemplateParamList;
665*0fca6ea1SDimitry Andric     llvm::BitVector ReferencedTemplateParams;
666*0fca6ea1SDimitry Andric 
667*0fca6ea1SDimitry Andric     TemplateParamsReferencedFinder(
668*0fca6ea1SDimitry Andric         const TemplateParameterList *TemplateParamList)
669*0fca6ea1SDimitry Andric         : TemplateParamList(TemplateParamList),
670*0fca6ea1SDimitry Andric           ReferencedTemplateParams(TemplateParamList->size()) {}
671*0fca6ea1SDimitry Andric 
672*0fca6ea1SDimitry Andric     bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) {
673*0fca6ea1SDimitry Andric       // We use the index and depth to retrieve the corresponding template
674*0fca6ea1SDimitry Andric       // parameter from the parameter list, which is more robost.
675*0fca6ea1SDimitry Andric       Mark(TTP->getDepth(), TTP->getIndex());
676*0fca6ea1SDimitry Andric       return true;
677*0fca6ea1SDimitry Andric     }
678*0fca6ea1SDimitry Andric 
679*0fca6ea1SDimitry Andric     bool VisitDeclRefExpr(DeclRefExpr *DRE) {
680*0fca6ea1SDimitry Andric       MarkAppeared(DRE->getFoundDecl());
681*0fca6ea1SDimitry Andric       return true;
682*0fca6ea1SDimitry Andric     }
683*0fca6ea1SDimitry Andric 
684*0fca6ea1SDimitry Andric     bool TraverseTemplateName(TemplateName Template) {
685*0fca6ea1SDimitry Andric       if (auto *TD = Template.getAsTemplateDecl())
686*0fca6ea1SDimitry Andric         MarkAppeared(TD);
687*0fca6ea1SDimitry Andric       return RecursiveASTVisitor::TraverseTemplateName(Template);
688*0fca6ea1SDimitry Andric     }
689*0fca6ea1SDimitry Andric 
690*0fca6ea1SDimitry Andric     void MarkAppeared(NamedDecl *ND) {
691*0fca6ea1SDimitry Andric       if (llvm::isa<NonTypeTemplateParmDecl, TemplateTypeParmDecl,
692*0fca6ea1SDimitry Andric                     TemplateTemplateParmDecl>(ND))
693*0fca6ea1SDimitry Andric         Mark(getTemplateParameterDepth(ND), getTemplateParameterIndex(ND));
694*0fca6ea1SDimitry Andric     }
695*0fca6ea1SDimitry Andric     void Mark(unsigned Depth, unsigned Index) {
696*0fca6ea1SDimitry Andric       if (Index < TemplateParamList->size() &&
697*0fca6ea1SDimitry Andric           TemplateParamList->getParam(Index)->getTemplateDepth() == Depth)
698*0fca6ea1SDimitry Andric         ReferencedTemplateParams.set(Index);
699*0fca6ea1SDimitry Andric     }
700*0fca6ea1SDimitry Andric   };
701*0fca6ea1SDimitry Andric   TemplateParamsReferencedFinder Finder(TemplateParamsList);
702*0fca6ea1SDimitry Andric   Finder.TraverseTemplateArguments(DeducedArgs);
703*0fca6ea1SDimitry Andric 
704*0fca6ea1SDimitry Andric   SmallVector<unsigned> Results;
705*0fca6ea1SDimitry Andric   for (unsigned Index = 0; Index < TemplateParamsList->size(); ++Index) {
706*0fca6ea1SDimitry Andric     if (Finder.ReferencedTemplateParams[Index])
707*0fca6ea1SDimitry Andric       Results.push_back(Index);
708*0fca6ea1SDimitry Andric   }
709*0fca6ea1SDimitry Andric   return Results;
710*0fca6ea1SDimitry Andric }
711*0fca6ea1SDimitry Andric 
712*0fca6ea1SDimitry Andric bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) {
713*0fca6ea1SDimitry Andric   // Check whether we've already declared deduction guides for this template.
714*0fca6ea1SDimitry Andric   // FIXME: Consider storing a flag on the template to indicate this.
715*0fca6ea1SDimitry Andric   assert(Name.getNameKind() ==
716*0fca6ea1SDimitry Andric              DeclarationName::NameKind::CXXDeductionGuideName &&
717*0fca6ea1SDimitry Andric          "name must be a deduction guide name");
718*0fca6ea1SDimitry Andric   auto Existing = DC->lookup(Name);
719*0fca6ea1SDimitry Andric   for (auto *D : Existing)
720*0fca6ea1SDimitry Andric     if (D->isImplicit())
721*0fca6ea1SDimitry Andric       return true;
722*0fca6ea1SDimitry Andric   return false;
723*0fca6ea1SDimitry Andric }
724*0fca6ea1SDimitry Andric 
725*0fca6ea1SDimitry Andric NamedDecl *transformTemplateParameter(Sema &SemaRef, DeclContext *DC,
726*0fca6ea1SDimitry Andric                                       NamedDecl *TemplateParam,
727*0fca6ea1SDimitry Andric                                       MultiLevelTemplateArgumentList &Args,
728*0fca6ea1SDimitry Andric                                       unsigned NewIndex, unsigned NewDepth) {
729*0fca6ea1SDimitry Andric   if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
730*0fca6ea1SDimitry Andric     return transformTemplateTypeParam(SemaRef, DC, TTP, Args, NewDepth,
731*0fca6ea1SDimitry Andric                                       NewIndex);
732*0fca6ea1SDimitry Andric   if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
733*0fca6ea1SDimitry Andric     return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex, NewDepth);
734*0fca6ea1SDimitry Andric   if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
735*0fca6ea1SDimitry Andric     return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex, NewDepth);
736*0fca6ea1SDimitry Andric   llvm_unreachable("Unhandled template parameter types");
737*0fca6ea1SDimitry Andric }
738*0fca6ea1SDimitry Andric 
739*0fca6ea1SDimitry Andric // Build the associated constraints for the alias deduction guides.
740*0fca6ea1SDimitry Andric // C++ [over.match.class.deduct]p3.3:
741*0fca6ea1SDimitry Andric //   The associated constraints ([temp.constr.decl]) are the conjunction of the
742*0fca6ea1SDimitry Andric //   associated constraints of g and a constraint that is satisfied if and only
743*0fca6ea1SDimitry Andric //   if the arguments of A are deducible (see below) from the return type.
744*0fca6ea1SDimitry Andric //
745*0fca6ea1SDimitry Andric // The return result is expected to be the require-clause for the synthesized
746*0fca6ea1SDimitry Andric // alias deduction guide.
747*0fca6ea1SDimitry Andric Expr *
748*0fca6ea1SDimitry Andric buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F,
749*0fca6ea1SDimitry Andric                            TypeAliasTemplateDecl *AliasTemplate,
750*0fca6ea1SDimitry Andric                            ArrayRef<DeducedTemplateArgument> DeduceResults,
751*0fca6ea1SDimitry Andric                            unsigned FirstUndeducedParamIdx, Expr *IsDeducible) {
752*0fca6ea1SDimitry Andric   Expr *RC = F->getTemplateParameters()->getRequiresClause();
753*0fca6ea1SDimitry Andric   if (!RC)
754*0fca6ea1SDimitry Andric     return IsDeducible;
755*0fca6ea1SDimitry Andric 
756*0fca6ea1SDimitry Andric   ASTContext &Context = SemaRef.Context;
757*0fca6ea1SDimitry Andric   LocalInstantiationScope Scope(SemaRef);
758*0fca6ea1SDimitry Andric 
759*0fca6ea1SDimitry Andric   // In the clang AST, constraint nodes are deliberately not instantiated unless
760*0fca6ea1SDimitry Andric   // they are actively being evaluated. Consequently, occurrences of template
761*0fca6ea1SDimitry Andric   // parameters in the require-clause expression have a subtle "depth"
762*0fca6ea1SDimitry Andric   // difference compared to normal occurrences in places, such as function
763*0fca6ea1SDimitry Andric   // parameters. When transforming the require-clause, we must take this
764*0fca6ea1SDimitry Andric   // distinction into account:
765*0fca6ea1SDimitry Andric   //
766*0fca6ea1SDimitry Andric   //   1) In the transformed require-clause, occurrences of template parameters
767*0fca6ea1SDimitry Andric   //   must use the "uninstantiated" depth;
768*0fca6ea1SDimitry Andric   //   2) When substituting on the require-clause expr of the underlying
769*0fca6ea1SDimitry Andric   //   deduction guide, we must use the entire set of template argument lists;
770*0fca6ea1SDimitry Andric   //
771*0fca6ea1SDimitry Andric   // It's important to note that we're performing this transformation on an
772*0fca6ea1SDimitry Andric   // *instantiated* AliasTemplate.
773*0fca6ea1SDimitry Andric 
774*0fca6ea1SDimitry Andric   // For 1), if the alias template is nested within a class template, we
775*0fca6ea1SDimitry Andric   // calcualte the 'uninstantiated' depth by adding the substitution level back.
776*0fca6ea1SDimitry Andric   unsigned AdjustDepth = 0;
777*0fca6ea1SDimitry Andric   if (auto *PrimaryTemplate =
778*0fca6ea1SDimitry Andric           AliasTemplate->getInstantiatedFromMemberTemplate())
779*0fca6ea1SDimitry Andric     AdjustDepth = PrimaryTemplate->getTemplateDepth();
780*0fca6ea1SDimitry Andric 
781*0fca6ea1SDimitry Andric   // We rebuild all template parameters with the uninstantiated depth, and
782*0fca6ea1SDimitry Andric   // build template arguments refer to them.
783*0fca6ea1SDimitry Andric   SmallVector<TemplateArgument> AdjustedAliasTemplateArgs;
784*0fca6ea1SDimitry Andric 
785*0fca6ea1SDimitry Andric   for (auto *TP : *AliasTemplate->getTemplateParameters()) {
786*0fca6ea1SDimitry Andric     // Rebuild any internal references to earlier parameters and reindex
787*0fca6ea1SDimitry Andric     // as we go.
788*0fca6ea1SDimitry Andric     MultiLevelTemplateArgumentList Args;
789*0fca6ea1SDimitry Andric     Args.setKind(TemplateSubstitutionKind::Rewrite);
790*0fca6ea1SDimitry Andric     Args.addOuterTemplateArguments(AdjustedAliasTemplateArgs);
791*0fca6ea1SDimitry Andric     NamedDecl *NewParam = transformTemplateParameter(
792*0fca6ea1SDimitry Andric         SemaRef, AliasTemplate->getDeclContext(), TP, Args,
793*0fca6ea1SDimitry Andric         /*NewIndex=*/AdjustedAliasTemplateArgs.size(),
794*0fca6ea1SDimitry Andric         getTemplateParameterDepth(TP) + AdjustDepth);
795*0fca6ea1SDimitry Andric 
796*0fca6ea1SDimitry Andric     TemplateArgument NewTemplateArgument =
797*0fca6ea1SDimitry Andric         Context.getInjectedTemplateArg(NewParam);
798*0fca6ea1SDimitry Andric     AdjustedAliasTemplateArgs.push_back(NewTemplateArgument);
799*0fca6ea1SDimitry Andric   }
800*0fca6ea1SDimitry Andric   // Template arguments used to transform the template arguments in
801*0fca6ea1SDimitry Andric   // DeducedResults.
802*0fca6ea1SDimitry Andric   SmallVector<TemplateArgument> TemplateArgsForBuildingRC(
803*0fca6ea1SDimitry Andric       F->getTemplateParameters()->size());
804*0fca6ea1SDimitry Andric   // Transform the transformed template args
805*0fca6ea1SDimitry Andric   MultiLevelTemplateArgumentList Args;
806*0fca6ea1SDimitry Andric   Args.setKind(TemplateSubstitutionKind::Rewrite);
807*0fca6ea1SDimitry Andric   Args.addOuterTemplateArguments(AdjustedAliasTemplateArgs);
808*0fca6ea1SDimitry Andric 
809*0fca6ea1SDimitry Andric   for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
810*0fca6ea1SDimitry Andric     const auto &D = DeduceResults[Index];
811*0fca6ea1SDimitry Andric     if (D.isNull()) { // non-deduced template parameters of f
812*0fca6ea1SDimitry Andric       NamedDecl *TP = F->getTemplateParameters()->getParam(Index);
813*0fca6ea1SDimitry Andric       MultiLevelTemplateArgumentList Args;
814*0fca6ea1SDimitry Andric       Args.setKind(TemplateSubstitutionKind::Rewrite);
815*0fca6ea1SDimitry Andric       Args.addOuterTemplateArguments(TemplateArgsForBuildingRC);
816*0fca6ea1SDimitry Andric       // Rebuild the template parameter with updated depth and index.
817*0fca6ea1SDimitry Andric       NamedDecl *NewParam = transformTemplateParameter(
818*0fca6ea1SDimitry Andric           SemaRef, F->getDeclContext(), TP, Args,
819*0fca6ea1SDimitry Andric           /*NewIndex=*/FirstUndeducedParamIdx,
820*0fca6ea1SDimitry Andric           getTemplateParameterDepth(TP) + AdjustDepth);
821*0fca6ea1SDimitry Andric       FirstUndeducedParamIdx += 1;
822*0fca6ea1SDimitry Andric       assert(TemplateArgsForBuildingRC[Index].isNull());
823*0fca6ea1SDimitry Andric       TemplateArgsForBuildingRC[Index] =
824*0fca6ea1SDimitry Andric           Context.getInjectedTemplateArg(NewParam);
825*0fca6ea1SDimitry Andric       continue;
826*0fca6ea1SDimitry Andric     }
827*0fca6ea1SDimitry Andric     TemplateArgumentLoc Input =
828*0fca6ea1SDimitry Andric         SemaRef.getTrivialTemplateArgumentLoc(D, QualType(), SourceLocation{});
829*0fca6ea1SDimitry Andric     TemplateArgumentLoc Output;
830*0fca6ea1SDimitry Andric     if (!SemaRef.SubstTemplateArgument(Input, Args, Output)) {
831*0fca6ea1SDimitry Andric       assert(TemplateArgsForBuildingRC[Index].isNull() &&
832*0fca6ea1SDimitry Andric              "InstantiatedArgs must be null before setting");
833*0fca6ea1SDimitry Andric       TemplateArgsForBuildingRC[Index] = Output.getArgument();
834*0fca6ea1SDimitry Andric     }
835*0fca6ea1SDimitry Andric   }
836*0fca6ea1SDimitry Andric 
837*0fca6ea1SDimitry Andric   // A list of template arguments for transforming the require-clause of F.
838*0fca6ea1SDimitry Andric   // It must contain the entire set of template argument lists.
839*0fca6ea1SDimitry Andric   MultiLevelTemplateArgumentList ArgsForBuildingRC;
840*0fca6ea1SDimitry Andric   ArgsForBuildingRC.setKind(clang::TemplateSubstitutionKind::Rewrite);
841*0fca6ea1SDimitry Andric   ArgsForBuildingRC.addOuterTemplateArguments(TemplateArgsForBuildingRC);
842*0fca6ea1SDimitry Andric   // For 2), if the underlying deduction guide F is nested in a class template,
843*0fca6ea1SDimitry Andric   // we need the entire template argument list, as the constraint AST in the
844*0fca6ea1SDimitry Andric   // require-clause of F remains completely uninstantiated.
845*0fca6ea1SDimitry Andric   //
846*0fca6ea1SDimitry Andric   // For example:
847*0fca6ea1SDimitry Andric   //   template <typename T> // depth 0
848*0fca6ea1SDimitry Andric   //   struct Outer {
849*0fca6ea1SDimitry Andric   //      template <typename U>
850*0fca6ea1SDimitry Andric   //      struct Foo { Foo(U); };
851*0fca6ea1SDimitry Andric   //
852*0fca6ea1SDimitry Andric   //      template <typename U> // depth 1
853*0fca6ea1SDimitry Andric   //      requires C<U>
854*0fca6ea1SDimitry Andric   //      Foo(U) -> Foo<int>;
855*0fca6ea1SDimitry Andric   //   };
856*0fca6ea1SDimitry Andric   //   template <typename U>
857*0fca6ea1SDimitry Andric   //   using AFoo = Outer<int>::Foo<U>;
858*0fca6ea1SDimitry Andric   //
859*0fca6ea1SDimitry Andric   // In this scenario, the deduction guide for `Foo` inside `Outer<int>`:
860*0fca6ea1SDimitry Andric   //   - The occurrence of U in the require-expression is [depth:1, index:0]
861*0fca6ea1SDimitry Andric   //   - The occurrence of U in the function parameter is [depth:0, index:0]
862*0fca6ea1SDimitry Andric   //   - The template parameter of U is [depth:0, index:0]
863*0fca6ea1SDimitry Andric   //
864*0fca6ea1SDimitry Andric   // We add the outer template arguments which is [int] to the multi-level arg
865*0fca6ea1SDimitry Andric   // list to ensure that the occurrence U in `C<U>` will be replaced with int
866*0fca6ea1SDimitry Andric   // during the substitution.
867*0fca6ea1SDimitry Andric   //
868*0fca6ea1SDimitry Andric   // NOTE: The underlying deduction guide F is instantiated -- either from an
869*0fca6ea1SDimitry Andric   // explicitly-written deduction guide member, or from a constructor.
870*0fca6ea1SDimitry Andric   // getInstantiatedFromMemberTemplate() can only handle the former case, so we
871*0fca6ea1SDimitry Andric   // check the DeclContext kind.
872*0fca6ea1SDimitry Andric   if (F->getLexicalDeclContext()->getDeclKind() ==
873*0fca6ea1SDimitry Andric       clang::Decl::ClassTemplateSpecialization) {
874*0fca6ea1SDimitry Andric     auto OuterLevelArgs = SemaRef.getTemplateInstantiationArgs(
875*0fca6ea1SDimitry Andric         F, F->getLexicalDeclContext(),
876*0fca6ea1SDimitry Andric         /*Final=*/false, /*Innermost=*/std::nullopt,
877*0fca6ea1SDimitry Andric         /*RelativeToPrimary=*/true,
878*0fca6ea1SDimitry Andric         /*Pattern=*/nullptr,
879*0fca6ea1SDimitry Andric         /*ForConstraintInstantiation=*/true);
880*0fca6ea1SDimitry Andric     for (auto It : OuterLevelArgs)
881*0fca6ea1SDimitry Andric       ArgsForBuildingRC.addOuterTemplateArguments(It.Args);
882*0fca6ea1SDimitry Andric   }
883*0fca6ea1SDimitry Andric 
884*0fca6ea1SDimitry Andric   ExprResult E = SemaRef.SubstExpr(RC, ArgsForBuildingRC);
885*0fca6ea1SDimitry Andric   if (E.isInvalid())
886*0fca6ea1SDimitry Andric     return nullptr;
887*0fca6ea1SDimitry Andric 
888*0fca6ea1SDimitry Andric   auto Conjunction =
889*0fca6ea1SDimitry Andric       SemaRef.BuildBinOp(SemaRef.getCurScope(), SourceLocation{},
890*0fca6ea1SDimitry Andric                          BinaryOperatorKind::BO_LAnd, E.get(), IsDeducible);
891*0fca6ea1SDimitry Andric   if (Conjunction.isInvalid())
892*0fca6ea1SDimitry Andric     return nullptr;
893*0fca6ea1SDimitry Andric   return Conjunction.getAs<Expr>();
894*0fca6ea1SDimitry Andric }
895*0fca6ea1SDimitry Andric // Build the is_deducible constraint for the alias deduction guides.
896*0fca6ea1SDimitry Andric // [over.match.class.deduct]p3.3:
897*0fca6ea1SDimitry Andric //    ... and a constraint that is satisfied if and only if the arguments
898*0fca6ea1SDimitry Andric //    of A are deducible (see below) from the return type.
899*0fca6ea1SDimitry Andric Expr *buildIsDeducibleConstraint(Sema &SemaRef,
900*0fca6ea1SDimitry Andric                                  TypeAliasTemplateDecl *AliasTemplate,
901*0fca6ea1SDimitry Andric                                  QualType ReturnType,
902*0fca6ea1SDimitry Andric                                  SmallVector<NamedDecl *> TemplateParams) {
903*0fca6ea1SDimitry Andric   ASTContext &Context = SemaRef.Context;
904*0fca6ea1SDimitry Andric   // Constraint AST nodes must use uninstantiated depth.
905*0fca6ea1SDimitry Andric   if (auto *PrimaryTemplate =
906*0fca6ea1SDimitry Andric           AliasTemplate->getInstantiatedFromMemberTemplate();
907*0fca6ea1SDimitry Andric       PrimaryTemplate && TemplateParams.size() > 0) {
908*0fca6ea1SDimitry Andric     LocalInstantiationScope Scope(SemaRef);
909*0fca6ea1SDimitry Andric 
910*0fca6ea1SDimitry Andric     // Adjust the depth for TemplateParams.
911*0fca6ea1SDimitry Andric     unsigned AdjustDepth = PrimaryTemplate->getTemplateDepth();
912*0fca6ea1SDimitry Andric     SmallVector<TemplateArgument> TransformedTemplateArgs;
913*0fca6ea1SDimitry Andric     for (auto *TP : TemplateParams) {
914*0fca6ea1SDimitry Andric       // Rebuild any internal references to earlier parameters and reindex
915*0fca6ea1SDimitry Andric       // as we go.
916*0fca6ea1SDimitry Andric       MultiLevelTemplateArgumentList Args;
917*0fca6ea1SDimitry Andric       Args.setKind(TemplateSubstitutionKind::Rewrite);
918*0fca6ea1SDimitry Andric       Args.addOuterTemplateArguments(TransformedTemplateArgs);
919*0fca6ea1SDimitry Andric       NamedDecl *NewParam = transformTemplateParameter(
920*0fca6ea1SDimitry Andric           SemaRef, AliasTemplate->getDeclContext(), TP, Args,
921*0fca6ea1SDimitry Andric           /*NewIndex=*/TransformedTemplateArgs.size(),
922*0fca6ea1SDimitry Andric           getTemplateParameterDepth(TP) + AdjustDepth);
923*0fca6ea1SDimitry Andric 
924*0fca6ea1SDimitry Andric       TemplateArgument NewTemplateArgument =
925*0fca6ea1SDimitry Andric           Context.getInjectedTemplateArg(NewParam);
926*0fca6ea1SDimitry Andric       TransformedTemplateArgs.push_back(NewTemplateArgument);
927*0fca6ea1SDimitry Andric     }
928*0fca6ea1SDimitry Andric     // Transformed the ReturnType to restore the uninstantiated depth.
929*0fca6ea1SDimitry Andric     MultiLevelTemplateArgumentList Args;
930*0fca6ea1SDimitry Andric     Args.setKind(TemplateSubstitutionKind::Rewrite);
931*0fca6ea1SDimitry Andric     Args.addOuterTemplateArguments(TransformedTemplateArgs);
932*0fca6ea1SDimitry Andric     ReturnType = SemaRef.SubstType(
933*0fca6ea1SDimitry Andric         ReturnType, Args, AliasTemplate->getLocation(),
934*0fca6ea1SDimitry Andric         Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate));
935*0fca6ea1SDimitry Andric   };
936*0fca6ea1SDimitry Andric 
937*0fca6ea1SDimitry Andric   SmallVector<TypeSourceInfo *> IsDeducibleTypeTraitArgs = {
938*0fca6ea1SDimitry Andric       Context.getTrivialTypeSourceInfo(
939*0fca6ea1SDimitry Andric           Context.getDeducedTemplateSpecializationType(
940*0fca6ea1SDimitry Andric               TemplateName(AliasTemplate), /*DeducedType=*/QualType(),
941*0fca6ea1SDimitry Andric               /*IsDependent=*/true)), // template specialization type whose
942*0fca6ea1SDimitry Andric                                       // arguments will be deduced.
943*0fca6ea1SDimitry Andric       Context.getTrivialTypeSourceInfo(
944*0fca6ea1SDimitry Andric           ReturnType), // type from which template arguments are deduced.
945*0fca6ea1SDimitry Andric   };
946*0fca6ea1SDimitry Andric   return TypeTraitExpr::Create(
947*0fca6ea1SDimitry Andric       Context, Context.getLogicalOperationType(), AliasTemplate->getLocation(),
948*0fca6ea1SDimitry Andric       TypeTrait::BTT_IsDeducible, IsDeducibleTypeTraitArgs,
949*0fca6ea1SDimitry Andric       AliasTemplate->getLocation(), /*Value*/ false);
950*0fca6ea1SDimitry Andric }
951*0fca6ea1SDimitry Andric 
952*0fca6ea1SDimitry Andric std::pair<TemplateDecl *, llvm::ArrayRef<TemplateArgument>>
953*0fca6ea1SDimitry Andric getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) {
954*0fca6ea1SDimitry Andric   // Unwrap the sugared ElaboratedType.
955*0fca6ea1SDimitry Andric   auto RhsType = AliasTemplate->getTemplatedDecl()
956*0fca6ea1SDimitry Andric                      ->getUnderlyingType()
957*0fca6ea1SDimitry Andric                      .getSingleStepDesugaredType(SemaRef.Context);
958*0fca6ea1SDimitry Andric   TemplateDecl *Template = nullptr;
959*0fca6ea1SDimitry Andric   llvm::ArrayRef<TemplateArgument> AliasRhsTemplateArgs;
960*0fca6ea1SDimitry Andric   if (const auto *TST = RhsType->getAs<TemplateSpecializationType>()) {
961*0fca6ea1SDimitry Andric     // Cases where the RHS of the alias is dependent. e.g.
962*0fca6ea1SDimitry Andric     //   template<typename T>
963*0fca6ea1SDimitry Andric     //   using AliasFoo1 = Foo<T>; // a class/type alias template specialization
964*0fca6ea1SDimitry Andric     Template = TST->getTemplateName().getAsTemplateDecl();
965*0fca6ea1SDimitry Andric     AliasRhsTemplateArgs = TST->template_arguments();
966*0fca6ea1SDimitry Andric   } else if (const auto *RT = RhsType->getAs<RecordType>()) {
967*0fca6ea1SDimitry Andric     // Cases where template arguments in the RHS of the alias are not
968*0fca6ea1SDimitry Andric     // dependent. e.g.
969*0fca6ea1SDimitry Andric     //   using AliasFoo = Foo<bool>;
970*0fca6ea1SDimitry Andric     if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(
971*0fca6ea1SDimitry Andric             RT->getAsCXXRecordDecl())) {
972*0fca6ea1SDimitry Andric       Template = CTSD->getSpecializedTemplate();
973*0fca6ea1SDimitry Andric       AliasRhsTemplateArgs = CTSD->getTemplateArgs().asArray();
974*0fca6ea1SDimitry Andric     }
975*0fca6ea1SDimitry Andric   } else {
976*0fca6ea1SDimitry Andric     assert(false && "unhandled RHS type of the alias");
977*0fca6ea1SDimitry Andric   }
978*0fca6ea1SDimitry Andric   return {Template, AliasRhsTemplateArgs};
979*0fca6ea1SDimitry Andric }
980*0fca6ea1SDimitry Andric 
981*0fca6ea1SDimitry Andric // Build deduction guides for a type alias template from the given underlying
982*0fca6ea1SDimitry Andric // deduction guide F.
983*0fca6ea1SDimitry Andric FunctionTemplateDecl *
984*0fca6ea1SDimitry Andric BuildDeductionGuideForTypeAlias(Sema &SemaRef,
985*0fca6ea1SDimitry Andric                                 TypeAliasTemplateDecl *AliasTemplate,
986*0fca6ea1SDimitry Andric                                 FunctionTemplateDecl *F, SourceLocation Loc) {
987*0fca6ea1SDimitry Andric   LocalInstantiationScope Scope(SemaRef);
988*0fca6ea1SDimitry Andric   Sema::InstantiatingTemplate BuildingDeductionGuides(
989*0fca6ea1SDimitry Andric       SemaRef, AliasTemplate->getLocation(), F,
990*0fca6ea1SDimitry Andric       Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
991*0fca6ea1SDimitry Andric   if (BuildingDeductionGuides.isInvalid())
992*0fca6ea1SDimitry Andric     return nullptr;
993*0fca6ea1SDimitry Andric 
994*0fca6ea1SDimitry Andric   auto &Context = SemaRef.Context;
995*0fca6ea1SDimitry Andric   auto [Template, AliasRhsTemplateArgs] =
996*0fca6ea1SDimitry Andric       getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
997*0fca6ea1SDimitry Andric 
998*0fca6ea1SDimitry Andric   auto RType = F->getTemplatedDecl()->getReturnType();
999*0fca6ea1SDimitry Andric   // The (trailing) return type of the deduction guide.
1000*0fca6ea1SDimitry Andric   const TemplateSpecializationType *FReturnType =
1001*0fca6ea1SDimitry Andric       RType->getAs<TemplateSpecializationType>();
1002*0fca6ea1SDimitry Andric   if (const auto *InjectedCNT = RType->getAs<InjectedClassNameType>())
1003*0fca6ea1SDimitry Andric     // implicitly-generated deduction guide.
1004*0fca6ea1SDimitry Andric     FReturnType = InjectedCNT->getInjectedTST();
1005*0fca6ea1SDimitry Andric   else if (const auto *ET = RType->getAs<ElaboratedType>())
1006*0fca6ea1SDimitry Andric     // explicit deduction guide.
1007*0fca6ea1SDimitry Andric     FReturnType = ET->getNamedType()->getAs<TemplateSpecializationType>();
1008*0fca6ea1SDimitry Andric   assert(FReturnType && "expected to see a return type");
1009*0fca6ea1SDimitry Andric   // Deduce template arguments of the deduction guide f from the RHS of
1010*0fca6ea1SDimitry Andric   // the alias.
1011*0fca6ea1SDimitry Andric   //
1012*0fca6ea1SDimitry Andric   // C++ [over.match.class.deduct]p3: ...For each function or function
1013*0fca6ea1SDimitry Andric   // template f in the guides of the template named by the
1014*0fca6ea1SDimitry Andric   // simple-template-id of the defining-type-id, the template arguments
1015*0fca6ea1SDimitry Andric   // of the return type of f are deduced from the defining-type-id of A
1016*0fca6ea1SDimitry Andric   // according to the process in [temp.deduct.type] with the exception
1017*0fca6ea1SDimitry Andric   // that deduction does not fail if not all template arguments are
1018*0fca6ea1SDimitry Andric   // deduced.
1019*0fca6ea1SDimitry Andric   //
1020*0fca6ea1SDimitry Andric   //
1021*0fca6ea1SDimitry Andric   //  template<typename X, typename Y>
1022*0fca6ea1SDimitry Andric   //  f(X, Y) -> f<Y, X>;
1023*0fca6ea1SDimitry Andric   //
1024*0fca6ea1SDimitry Andric   //  template<typename U>
1025*0fca6ea1SDimitry Andric   //  using alias = f<int, U>;
1026*0fca6ea1SDimitry Andric   //
1027*0fca6ea1SDimitry Andric   // The RHS of alias is f<int, U>, we deduced the template arguments of
1028*0fca6ea1SDimitry Andric   // the return type of the deduction guide from it: Y->int, X->U
1029*0fca6ea1SDimitry Andric   sema::TemplateDeductionInfo TDeduceInfo(Loc);
1030*0fca6ea1SDimitry Andric   // Must initialize n elements, this is required by DeduceTemplateArguments.
1031*0fca6ea1SDimitry Andric   SmallVector<DeducedTemplateArgument> DeduceResults(
1032*0fca6ea1SDimitry Andric       F->getTemplateParameters()->size());
1033*0fca6ea1SDimitry Andric 
1034*0fca6ea1SDimitry Andric   // FIXME: DeduceTemplateArguments stops immediately at the first
1035*0fca6ea1SDimitry Andric   // non-deducible template argument. However, this doesn't seem to casue
1036*0fca6ea1SDimitry Andric   // issues for practice cases, we probably need to extend it to continue
1037*0fca6ea1SDimitry Andric   // performing deduction for rest of arguments to align with the C++
1038*0fca6ea1SDimitry Andric   // standard.
1039*0fca6ea1SDimitry Andric   SemaRef.DeduceTemplateArguments(
1040*0fca6ea1SDimitry Andric       F->getTemplateParameters(), FReturnType->template_arguments(),
1041*0fca6ea1SDimitry Andric       AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
1042*0fca6ea1SDimitry Andric       /*NumberOfArgumentsMustMatch=*/false);
1043*0fca6ea1SDimitry Andric 
1044*0fca6ea1SDimitry Andric   SmallVector<TemplateArgument> DeducedArgs;
1045*0fca6ea1SDimitry Andric   SmallVector<unsigned> NonDeducedTemplateParamsInFIndex;
1046*0fca6ea1SDimitry Andric   // !!NOTE: DeduceResults respects the sequence of template parameters of
1047*0fca6ea1SDimitry Andric   // the deduction guide f.
1048*0fca6ea1SDimitry Andric   for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
1049*0fca6ea1SDimitry Andric     if (const auto &D = DeduceResults[Index]; !D.isNull()) // Deduced
1050*0fca6ea1SDimitry Andric       DeducedArgs.push_back(D);
1051*0fca6ea1SDimitry Andric     else
1052*0fca6ea1SDimitry Andric       NonDeducedTemplateParamsInFIndex.push_back(Index);
1053*0fca6ea1SDimitry Andric   }
1054*0fca6ea1SDimitry Andric   auto DeducedAliasTemplateParams =
1055*0fca6ea1SDimitry Andric       TemplateParamsReferencedInTemplateArgumentList(
1056*0fca6ea1SDimitry Andric           AliasTemplate->getTemplateParameters(), DeducedArgs);
1057*0fca6ea1SDimitry Andric   // All template arguments null by default.
1058*0fca6ea1SDimitry Andric   SmallVector<TemplateArgument> TemplateArgsForBuildingFPrime(
1059*0fca6ea1SDimitry Andric       F->getTemplateParameters()->size());
1060*0fca6ea1SDimitry Andric 
1061*0fca6ea1SDimitry Andric   // Create a template parameter list for the synthesized deduction guide f'.
1062*0fca6ea1SDimitry Andric   //
1063*0fca6ea1SDimitry Andric   // C++ [over.match.class.deduct]p3.2:
1064*0fca6ea1SDimitry Andric   //   If f is a function template, f' is a function template whose template
1065*0fca6ea1SDimitry Andric   //   parameter list consists of all the template parameters of A
1066*0fca6ea1SDimitry Andric   //   (including their default template arguments) that appear in the above
1067*0fca6ea1SDimitry Andric   //   deductions or (recursively) in their default template arguments
1068*0fca6ea1SDimitry Andric   SmallVector<NamedDecl *> FPrimeTemplateParams;
1069*0fca6ea1SDimitry Andric   // Store template arguments that refer to the newly-created template
1070*0fca6ea1SDimitry Andric   // parameters, used for building `TemplateArgsForBuildingFPrime`.
1071*0fca6ea1SDimitry Andric   SmallVector<TemplateArgument, 16> TransformedDeducedAliasArgs(
1072*0fca6ea1SDimitry Andric       AliasTemplate->getTemplateParameters()->size());
1073*0fca6ea1SDimitry Andric 
1074*0fca6ea1SDimitry Andric   for (unsigned AliasTemplateParamIdx : DeducedAliasTemplateParams) {
1075*0fca6ea1SDimitry Andric     auto *TP =
1076*0fca6ea1SDimitry Andric         AliasTemplate->getTemplateParameters()->getParam(AliasTemplateParamIdx);
1077*0fca6ea1SDimitry Andric     // Rebuild any internal references to earlier parameters and reindex as
1078*0fca6ea1SDimitry Andric     // we go.
1079*0fca6ea1SDimitry Andric     MultiLevelTemplateArgumentList Args;
1080*0fca6ea1SDimitry Andric     Args.setKind(TemplateSubstitutionKind::Rewrite);
1081*0fca6ea1SDimitry Andric     Args.addOuterTemplateArguments(TransformedDeducedAliasArgs);
1082*0fca6ea1SDimitry Andric     NamedDecl *NewParam = transformTemplateParameter(
1083*0fca6ea1SDimitry Andric         SemaRef, AliasTemplate->getDeclContext(), TP, Args,
1084*0fca6ea1SDimitry Andric         /*NewIndex=*/FPrimeTemplateParams.size(),
1085*0fca6ea1SDimitry Andric         getTemplateParameterDepth(TP));
1086*0fca6ea1SDimitry Andric     FPrimeTemplateParams.push_back(NewParam);
1087*0fca6ea1SDimitry Andric 
1088*0fca6ea1SDimitry Andric     TemplateArgument NewTemplateArgument =
1089*0fca6ea1SDimitry Andric         Context.getInjectedTemplateArg(NewParam);
1090*0fca6ea1SDimitry Andric     TransformedDeducedAliasArgs[AliasTemplateParamIdx] = NewTemplateArgument;
1091*0fca6ea1SDimitry Andric   }
1092*0fca6ea1SDimitry Andric   unsigned FirstUndeducedParamIdx = FPrimeTemplateParams.size();
1093*0fca6ea1SDimitry Andric   //   ...followed by the template parameters of f that were not deduced
1094*0fca6ea1SDimitry Andric   //   (including their default template arguments)
1095*0fca6ea1SDimitry Andric   for (unsigned FTemplateParamIdx : NonDeducedTemplateParamsInFIndex) {
1096*0fca6ea1SDimitry Andric     auto *TP = F->getTemplateParameters()->getParam(FTemplateParamIdx);
1097*0fca6ea1SDimitry Andric     MultiLevelTemplateArgumentList Args;
1098*0fca6ea1SDimitry Andric     Args.setKind(TemplateSubstitutionKind::Rewrite);
1099*0fca6ea1SDimitry Andric     // We take a shortcut here, it is ok to reuse the
1100*0fca6ea1SDimitry Andric     // TemplateArgsForBuildingFPrime.
1101*0fca6ea1SDimitry Andric     Args.addOuterTemplateArguments(TemplateArgsForBuildingFPrime);
1102*0fca6ea1SDimitry Andric     NamedDecl *NewParam = transformTemplateParameter(
1103*0fca6ea1SDimitry Andric         SemaRef, F->getDeclContext(), TP, Args, FPrimeTemplateParams.size(),
1104*0fca6ea1SDimitry Andric         getTemplateParameterDepth(TP));
1105*0fca6ea1SDimitry Andric     FPrimeTemplateParams.push_back(NewParam);
1106*0fca6ea1SDimitry Andric 
1107*0fca6ea1SDimitry Andric     assert(TemplateArgsForBuildingFPrime[FTemplateParamIdx].isNull() &&
1108*0fca6ea1SDimitry Andric            "The argument must be null before setting");
1109*0fca6ea1SDimitry Andric     TemplateArgsForBuildingFPrime[FTemplateParamIdx] =
1110*0fca6ea1SDimitry Andric         Context.getInjectedTemplateArg(NewParam);
1111*0fca6ea1SDimitry Andric   }
1112*0fca6ea1SDimitry Andric 
1113*0fca6ea1SDimitry Andric   // To form a deduction guide f' from f, we leverage clang's instantiation
1114*0fca6ea1SDimitry Andric   // mechanism, we construct a template argument list where the template
1115*0fca6ea1SDimitry Andric   // arguments refer to the newly-created template parameters of f', and
1116*0fca6ea1SDimitry Andric   // then apply instantiation on this template argument list to instantiate
1117*0fca6ea1SDimitry Andric   // f, this ensures all template parameter occurrences are updated
1118*0fca6ea1SDimitry Andric   // correctly.
1119*0fca6ea1SDimitry Andric   //
1120*0fca6ea1SDimitry Andric   // The template argument list is formed from the `DeducedArgs`, two parts:
1121*0fca6ea1SDimitry Andric   //  1) appeared template parameters of alias: transfrom the deduced
1122*0fca6ea1SDimitry Andric   //  template argument;
1123*0fca6ea1SDimitry Andric   //  2) non-deduced template parameters of f: rebuild a
1124*0fca6ea1SDimitry Andric   //  template argument;
1125*0fca6ea1SDimitry Andric   //
1126*0fca6ea1SDimitry Andric   // 2) has been built already (when rebuilding the new template
1127*0fca6ea1SDimitry Andric   // parameters), we now perform 1).
1128*0fca6ea1SDimitry Andric   MultiLevelTemplateArgumentList Args;
1129*0fca6ea1SDimitry Andric   Args.setKind(TemplateSubstitutionKind::Rewrite);
1130*0fca6ea1SDimitry Andric   Args.addOuterTemplateArguments(TransformedDeducedAliasArgs);
1131*0fca6ea1SDimitry Andric   for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
1132*0fca6ea1SDimitry Andric     const auto &D = DeduceResults[Index];
1133*0fca6ea1SDimitry Andric     if (D.isNull()) {
1134*0fca6ea1SDimitry Andric       // 2): Non-deduced template parameter has been built already.
1135*0fca6ea1SDimitry Andric       assert(!TemplateArgsForBuildingFPrime[Index].isNull() &&
1136*0fca6ea1SDimitry Andric              "template arguments for non-deduced template parameters should "
1137*0fca6ea1SDimitry Andric              "be been set!");
1138*0fca6ea1SDimitry Andric       continue;
1139*0fca6ea1SDimitry Andric     }
1140*0fca6ea1SDimitry Andric     TemplateArgumentLoc Input =
1141*0fca6ea1SDimitry Andric         SemaRef.getTrivialTemplateArgumentLoc(D, QualType(), SourceLocation{});
1142*0fca6ea1SDimitry Andric     TemplateArgumentLoc Output;
1143*0fca6ea1SDimitry Andric     if (!SemaRef.SubstTemplateArgument(Input, Args, Output)) {
1144*0fca6ea1SDimitry Andric       assert(TemplateArgsForBuildingFPrime[Index].isNull() &&
1145*0fca6ea1SDimitry Andric              "InstantiatedArgs must be null before setting");
1146*0fca6ea1SDimitry Andric       TemplateArgsForBuildingFPrime[Index] = Output.getArgument();
1147*0fca6ea1SDimitry Andric     }
1148*0fca6ea1SDimitry Andric   }
1149*0fca6ea1SDimitry Andric 
1150*0fca6ea1SDimitry Andric   auto *TemplateArgListForBuildingFPrime =
1151*0fca6ea1SDimitry Andric       TemplateArgumentList::CreateCopy(Context, TemplateArgsForBuildingFPrime);
1152*0fca6ea1SDimitry Andric   // Form the f' by substituting the template arguments into f.
1153*0fca6ea1SDimitry Andric   if (auto *FPrime = SemaRef.InstantiateFunctionDeclaration(
1154*0fca6ea1SDimitry Andric           F, TemplateArgListForBuildingFPrime, AliasTemplate->getLocation(),
1155*0fca6ea1SDimitry Andric           Sema::CodeSynthesisContext::BuildingDeductionGuides)) {
1156*0fca6ea1SDimitry Andric     auto *GG = cast<CXXDeductionGuideDecl>(FPrime);
1157*0fca6ea1SDimitry Andric 
1158*0fca6ea1SDimitry Andric     Expr *IsDeducible = buildIsDeducibleConstraint(
1159*0fca6ea1SDimitry Andric         SemaRef, AliasTemplate, FPrime->getReturnType(), FPrimeTemplateParams);
1160*0fca6ea1SDimitry Andric     Expr *RequiresClause =
1161*0fca6ea1SDimitry Andric         buildAssociatedConstraints(SemaRef, F, AliasTemplate, DeduceResults,
1162*0fca6ea1SDimitry Andric                                    FirstUndeducedParamIdx, IsDeducible);
1163*0fca6ea1SDimitry Andric 
1164*0fca6ea1SDimitry Andric     auto *FPrimeTemplateParamList = TemplateParameterList::Create(
1165*0fca6ea1SDimitry Andric         Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(),
1166*0fca6ea1SDimitry Andric         AliasTemplate->getTemplateParameters()->getLAngleLoc(),
1167*0fca6ea1SDimitry Andric         FPrimeTemplateParams,
1168*0fca6ea1SDimitry Andric         AliasTemplate->getTemplateParameters()->getRAngleLoc(),
1169*0fca6ea1SDimitry Andric         /*RequiresClause=*/RequiresClause);
1170*0fca6ea1SDimitry Andric     auto *Result = cast<FunctionTemplateDecl>(buildDeductionGuide(
1171*0fca6ea1SDimitry Andric         SemaRef, AliasTemplate, FPrimeTemplateParamList,
1172*0fca6ea1SDimitry Andric         GG->getCorrespondingConstructor(), GG->getExplicitSpecifier(),
1173*0fca6ea1SDimitry Andric         GG->getTypeSourceInfo(), AliasTemplate->getBeginLoc(),
1174*0fca6ea1SDimitry Andric         AliasTemplate->getLocation(), AliasTemplate->getEndLoc(),
1175*0fca6ea1SDimitry Andric         F->isImplicit()));
1176*0fca6ea1SDimitry Andric     cast<CXXDeductionGuideDecl>(Result->getTemplatedDecl())
1177*0fca6ea1SDimitry Andric         ->setDeductionCandidateKind(GG->getDeductionCandidateKind());
1178*0fca6ea1SDimitry Andric     return Result;
1179*0fca6ea1SDimitry Andric   }
1180*0fca6ea1SDimitry Andric   return nullptr;
1181*0fca6ea1SDimitry Andric }
1182*0fca6ea1SDimitry Andric 
1183*0fca6ea1SDimitry Andric void DeclareImplicitDeductionGuidesForTypeAlias(
1184*0fca6ea1SDimitry Andric     Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate, SourceLocation Loc) {
1185*0fca6ea1SDimitry Andric   if (AliasTemplate->isInvalidDecl())
1186*0fca6ea1SDimitry Andric     return;
1187*0fca6ea1SDimitry Andric   auto &Context = SemaRef.Context;
1188*0fca6ea1SDimitry Andric   // FIXME: if there is an explicit deduction guide after the first use of the
1189*0fca6ea1SDimitry Andric   // type alias usage, we will not cover this explicit deduction guide. fix this
1190*0fca6ea1SDimitry Andric   // case.
1191*0fca6ea1SDimitry Andric   if (hasDeclaredDeductionGuides(
1192*0fca6ea1SDimitry Andric           Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate),
1193*0fca6ea1SDimitry Andric           AliasTemplate->getDeclContext()))
1194*0fca6ea1SDimitry Andric     return;
1195*0fca6ea1SDimitry Andric   auto [Template, AliasRhsTemplateArgs] =
1196*0fca6ea1SDimitry Andric       getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
1197*0fca6ea1SDimitry Andric   if (!Template)
1198*0fca6ea1SDimitry Andric     return;
1199*0fca6ea1SDimitry Andric   DeclarationNameInfo NameInfo(
1200*0fca6ea1SDimitry Andric       Context.DeclarationNames.getCXXDeductionGuideName(Template), Loc);
1201*0fca6ea1SDimitry Andric   LookupResult Guides(SemaRef, NameInfo, clang::Sema::LookupOrdinaryName);
1202*0fca6ea1SDimitry Andric   SemaRef.LookupQualifiedName(Guides, Template->getDeclContext());
1203*0fca6ea1SDimitry Andric   Guides.suppressDiagnostics();
1204*0fca6ea1SDimitry Andric 
1205*0fca6ea1SDimitry Andric   for (auto *G : Guides) {
1206*0fca6ea1SDimitry Andric     if (auto *DG = dyn_cast<CXXDeductionGuideDecl>(G)) {
1207*0fca6ea1SDimitry Andric       // The deduction guide is a non-template function decl, we just clone it.
1208*0fca6ea1SDimitry Andric       auto *FunctionType =
1209*0fca6ea1SDimitry Andric           SemaRef.Context.getTrivialTypeSourceInfo(DG->getType());
1210*0fca6ea1SDimitry Andric       FunctionProtoTypeLoc FPTL =
1211*0fca6ea1SDimitry Andric           FunctionType->getTypeLoc().castAs<FunctionProtoTypeLoc>();
1212*0fca6ea1SDimitry Andric 
1213*0fca6ea1SDimitry Andric       // Clone the parameters.
1214*0fca6ea1SDimitry Andric       for (unsigned I = 0, N = DG->getNumParams(); I != N; ++I) {
1215*0fca6ea1SDimitry Andric         const auto *P = DG->getParamDecl(I);
1216*0fca6ea1SDimitry Andric         auto *TSI = SemaRef.Context.getTrivialTypeSourceInfo(P->getType());
1217*0fca6ea1SDimitry Andric         ParmVarDecl *NewParam = ParmVarDecl::Create(
1218*0fca6ea1SDimitry Andric             SemaRef.Context, G->getDeclContext(),
1219*0fca6ea1SDimitry Andric             DG->getParamDecl(I)->getBeginLoc(), P->getLocation(), nullptr,
1220*0fca6ea1SDimitry Andric             TSI->getType(), TSI, SC_None, nullptr);
1221*0fca6ea1SDimitry Andric         NewParam->setScopeInfo(0, I);
1222*0fca6ea1SDimitry Andric         FPTL.setParam(I, NewParam);
1223*0fca6ea1SDimitry Andric       }
1224*0fca6ea1SDimitry Andric       auto *Transformed = cast<FunctionDecl>(buildDeductionGuide(
1225*0fca6ea1SDimitry Andric           SemaRef, AliasTemplate, /*TemplateParams=*/nullptr,
1226*0fca6ea1SDimitry Andric           /*Constructor=*/nullptr, DG->getExplicitSpecifier(), FunctionType,
1227*0fca6ea1SDimitry Andric           AliasTemplate->getBeginLoc(), AliasTemplate->getLocation(),
1228*0fca6ea1SDimitry Andric           AliasTemplate->getEndLoc(), DG->isImplicit()));
1229*0fca6ea1SDimitry Andric 
1230*0fca6ea1SDimitry Andric       // FIXME: Here the synthesized deduction guide is not a templated
1231*0fca6ea1SDimitry Andric       // function. Per [dcl.decl]p4, the requires-clause shall be present only
1232*0fca6ea1SDimitry Andric       // if the declarator declares a templated function, a bug in standard?
1233*0fca6ea1SDimitry Andric       auto *Constraint = buildIsDeducibleConstraint(
1234*0fca6ea1SDimitry Andric           SemaRef, AliasTemplate, Transformed->getReturnType(), {});
1235*0fca6ea1SDimitry Andric       if (auto *RC = DG->getTrailingRequiresClause()) {
1236*0fca6ea1SDimitry Andric         auto Conjunction =
1237*0fca6ea1SDimitry Andric             SemaRef.BuildBinOp(SemaRef.getCurScope(), SourceLocation{},
1238*0fca6ea1SDimitry Andric                                BinaryOperatorKind::BO_LAnd, RC, Constraint);
1239*0fca6ea1SDimitry Andric         if (!Conjunction.isInvalid())
1240*0fca6ea1SDimitry Andric           Constraint = Conjunction.getAs<Expr>();
1241*0fca6ea1SDimitry Andric       }
1242*0fca6ea1SDimitry Andric       Transformed->setTrailingRequiresClause(Constraint);
1243*0fca6ea1SDimitry Andric     }
1244*0fca6ea1SDimitry Andric     FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(G);
1245*0fca6ea1SDimitry Andric     if (!F)
1246*0fca6ea1SDimitry Andric       continue;
1247*0fca6ea1SDimitry Andric     // The **aggregate** deduction guides are handled in a different code path
1248*0fca6ea1SDimitry Andric     // (DeclareAggregateDeductionGuideFromInitList), which involves the tricky
1249*0fca6ea1SDimitry Andric     // cache.
1250*0fca6ea1SDimitry Andric     if (cast<CXXDeductionGuideDecl>(F->getTemplatedDecl())
1251*0fca6ea1SDimitry Andric             ->getDeductionCandidateKind() == DeductionCandidate::Aggregate)
1252*0fca6ea1SDimitry Andric       continue;
1253*0fca6ea1SDimitry Andric 
1254*0fca6ea1SDimitry Andric     BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate, F, Loc);
1255*0fca6ea1SDimitry Andric   }
1256*0fca6ea1SDimitry Andric }
1257*0fca6ea1SDimitry Andric 
1258*0fca6ea1SDimitry Andric // Build an aggregate deduction guide for a type alias template.
1259*0fca6ea1SDimitry Andric FunctionTemplateDecl *DeclareAggregateDeductionGuideForTypeAlias(
1260*0fca6ea1SDimitry Andric     Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate,
1261*0fca6ea1SDimitry Andric     MutableArrayRef<QualType> ParamTypes, SourceLocation Loc) {
1262*0fca6ea1SDimitry Andric   TemplateDecl *RHSTemplate =
1263*0fca6ea1SDimitry Andric       getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate).first;
1264*0fca6ea1SDimitry Andric   if (!RHSTemplate)
1265*0fca6ea1SDimitry Andric     return nullptr;
1266*0fca6ea1SDimitry Andric   auto *RHSDeductionGuide = SemaRef.DeclareAggregateDeductionGuideFromInitList(
1267*0fca6ea1SDimitry Andric       RHSTemplate, ParamTypes, Loc);
1268*0fca6ea1SDimitry Andric   if (!RHSDeductionGuide)
1269*0fca6ea1SDimitry Andric     return nullptr;
1270*0fca6ea1SDimitry Andric   return BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate,
1271*0fca6ea1SDimitry Andric                                          RHSDeductionGuide, Loc);
1272*0fca6ea1SDimitry Andric }
1273*0fca6ea1SDimitry Andric 
1274*0fca6ea1SDimitry Andric } // namespace
1275*0fca6ea1SDimitry Andric 
1276*0fca6ea1SDimitry Andric FunctionTemplateDecl *Sema::DeclareAggregateDeductionGuideFromInitList(
1277*0fca6ea1SDimitry Andric     TemplateDecl *Template, MutableArrayRef<QualType> ParamTypes,
1278*0fca6ea1SDimitry Andric     SourceLocation Loc) {
1279*0fca6ea1SDimitry Andric   llvm::FoldingSetNodeID ID;
1280*0fca6ea1SDimitry Andric   ID.AddPointer(Template);
1281*0fca6ea1SDimitry Andric   for (auto &T : ParamTypes)
1282*0fca6ea1SDimitry Andric     T.getCanonicalType().Profile(ID);
1283*0fca6ea1SDimitry Andric   unsigned Hash = ID.ComputeHash();
1284*0fca6ea1SDimitry Andric 
1285*0fca6ea1SDimitry Andric   auto Found = AggregateDeductionCandidates.find(Hash);
1286*0fca6ea1SDimitry Andric   if (Found != AggregateDeductionCandidates.end()) {
1287*0fca6ea1SDimitry Andric     CXXDeductionGuideDecl *GD = Found->getSecond();
1288*0fca6ea1SDimitry Andric     return GD->getDescribedFunctionTemplate();
1289*0fca6ea1SDimitry Andric   }
1290*0fca6ea1SDimitry Andric 
1291*0fca6ea1SDimitry Andric   if (auto *AliasTemplate = llvm::dyn_cast<TypeAliasTemplateDecl>(Template)) {
1292*0fca6ea1SDimitry Andric     if (auto *FTD = DeclareAggregateDeductionGuideForTypeAlias(
1293*0fca6ea1SDimitry Andric             *this, AliasTemplate, ParamTypes, Loc)) {
1294*0fca6ea1SDimitry Andric       auto *GD = cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl());
1295*0fca6ea1SDimitry Andric       GD->setDeductionCandidateKind(DeductionCandidate::Aggregate);
1296*0fca6ea1SDimitry Andric       AggregateDeductionCandidates[Hash] = GD;
1297*0fca6ea1SDimitry Andric       return FTD;
1298*0fca6ea1SDimitry Andric     }
1299*0fca6ea1SDimitry Andric   }
1300*0fca6ea1SDimitry Andric 
1301*0fca6ea1SDimitry Andric   if (CXXRecordDecl *DefRecord =
1302*0fca6ea1SDimitry Andric           cast<CXXRecordDecl>(Template->getTemplatedDecl())->getDefinition()) {
1303*0fca6ea1SDimitry Andric     if (TemplateDecl *DescribedTemplate =
1304*0fca6ea1SDimitry Andric             DefRecord->getDescribedClassTemplate())
1305*0fca6ea1SDimitry Andric       Template = DescribedTemplate;
1306*0fca6ea1SDimitry Andric   }
1307*0fca6ea1SDimitry Andric 
1308*0fca6ea1SDimitry Andric   DeclContext *DC = Template->getDeclContext();
1309*0fca6ea1SDimitry Andric   if (DC->isDependentContext())
1310*0fca6ea1SDimitry Andric     return nullptr;
1311*0fca6ea1SDimitry Andric 
1312*0fca6ea1SDimitry Andric   ConvertConstructorToDeductionGuideTransform Transform(
1313*0fca6ea1SDimitry Andric       *this, cast<ClassTemplateDecl>(Template));
1314*0fca6ea1SDimitry Andric   if (!isCompleteType(Loc, Transform.DeducedType))
1315*0fca6ea1SDimitry Andric     return nullptr;
1316*0fca6ea1SDimitry Andric 
1317*0fca6ea1SDimitry Andric   // In case we were expanding a pack when we attempted to declare deduction
1318*0fca6ea1SDimitry Andric   // guides, turn off pack expansion for everything we're about to do.
1319*0fca6ea1SDimitry Andric   ArgumentPackSubstitutionIndexRAII SubstIndex(*this,
1320*0fca6ea1SDimitry Andric                                                /*NewSubstitutionIndex=*/-1);
1321*0fca6ea1SDimitry Andric   // Create a template instantiation record to track the "instantiation" of
1322*0fca6ea1SDimitry Andric   // constructors into deduction guides.
1323*0fca6ea1SDimitry Andric   InstantiatingTemplate BuildingDeductionGuides(
1324*0fca6ea1SDimitry Andric       *this, Loc, Template,
1325*0fca6ea1SDimitry Andric       Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
1326*0fca6ea1SDimitry Andric   if (BuildingDeductionGuides.isInvalid())
1327*0fca6ea1SDimitry Andric     return nullptr;
1328*0fca6ea1SDimitry Andric 
1329*0fca6ea1SDimitry Andric   ClassTemplateDecl *Pattern =
1330*0fca6ea1SDimitry Andric       Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
1331*0fca6ea1SDimitry Andric   ContextRAII SavedContext(*this, Pattern->getTemplatedDecl());
1332*0fca6ea1SDimitry Andric 
1333*0fca6ea1SDimitry Andric   auto *FTD = cast<FunctionTemplateDecl>(
1334*0fca6ea1SDimitry Andric       Transform.buildSimpleDeductionGuide(ParamTypes));
1335*0fca6ea1SDimitry Andric   SavedContext.pop();
1336*0fca6ea1SDimitry Andric   auto *GD = cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl());
1337*0fca6ea1SDimitry Andric   GD->setDeductionCandidateKind(DeductionCandidate::Aggregate);
1338*0fca6ea1SDimitry Andric   AggregateDeductionCandidates[Hash] = GD;
1339*0fca6ea1SDimitry Andric   return FTD;
1340*0fca6ea1SDimitry Andric }
1341*0fca6ea1SDimitry Andric 
1342*0fca6ea1SDimitry Andric void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
1343*0fca6ea1SDimitry Andric                                           SourceLocation Loc) {
1344*0fca6ea1SDimitry Andric   if (auto *AliasTemplate = llvm::dyn_cast<TypeAliasTemplateDecl>(Template)) {
1345*0fca6ea1SDimitry Andric     DeclareImplicitDeductionGuidesForTypeAlias(*this, AliasTemplate, Loc);
1346*0fca6ea1SDimitry Andric     return;
1347*0fca6ea1SDimitry Andric   }
1348*0fca6ea1SDimitry Andric   if (CXXRecordDecl *DefRecord =
1349*0fca6ea1SDimitry Andric           cast<CXXRecordDecl>(Template->getTemplatedDecl())->getDefinition()) {
1350*0fca6ea1SDimitry Andric     if (TemplateDecl *DescribedTemplate =
1351*0fca6ea1SDimitry Andric             DefRecord->getDescribedClassTemplate())
1352*0fca6ea1SDimitry Andric       Template = DescribedTemplate;
1353*0fca6ea1SDimitry Andric   }
1354*0fca6ea1SDimitry Andric 
1355*0fca6ea1SDimitry Andric   DeclContext *DC = Template->getDeclContext();
1356*0fca6ea1SDimitry Andric   if (DC->isDependentContext())
1357*0fca6ea1SDimitry Andric     return;
1358*0fca6ea1SDimitry Andric 
1359*0fca6ea1SDimitry Andric   ConvertConstructorToDeductionGuideTransform Transform(
1360*0fca6ea1SDimitry Andric       *this, cast<ClassTemplateDecl>(Template));
1361*0fca6ea1SDimitry Andric   if (!isCompleteType(Loc, Transform.DeducedType))
1362*0fca6ea1SDimitry Andric     return;
1363*0fca6ea1SDimitry Andric 
1364*0fca6ea1SDimitry Andric   if (hasDeclaredDeductionGuides(Transform.DeductionGuideName, DC))
1365*0fca6ea1SDimitry Andric     return;
1366*0fca6ea1SDimitry Andric 
1367*0fca6ea1SDimitry Andric   // In case we were expanding a pack when we attempted to declare deduction
1368*0fca6ea1SDimitry Andric   // guides, turn off pack expansion for everything we're about to do.
1369*0fca6ea1SDimitry Andric   ArgumentPackSubstitutionIndexRAII SubstIndex(*this, -1);
1370*0fca6ea1SDimitry Andric   // Create a template instantiation record to track the "instantiation" of
1371*0fca6ea1SDimitry Andric   // constructors into deduction guides.
1372*0fca6ea1SDimitry Andric   InstantiatingTemplate BuildingDeductionGuides(
1373*0fca6ea1SDimitry Andric       *this, Loc, Template,
1374*0fca6ea1SDimitry Andric       Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{});
1375*0fca6ea1SDimitry Andric   if (BuildingDeductionGuides.isInvalid())
1376*0fca6ea1SDimitry Andric     return;
1377*0fca6ea1SDimitry Andric 
1378*0fca6ea1SDimitry Andric   // Convert declared constructors into deduction guide templates.
1379*0fca6ea1SDimitry Andric   // FIXME: Skip constructors for which deduction must necessarily fail (those
1380*0fca6ea1SDimitry Andric   // for which some class template parameter without a default argument never
1381*0fca6ea1SDimitry Andric   // appears in a deduced context).
1382*0fca6ea1SDimitry Andric   ClassTemplateDecl *Pattern =
1383*0fca6ea1SDimitry Andric       Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
1384*0fca6ea1SDimitry Andric   ContextRAII SavedContext(*this, Pattern->getTemplatedDecl());
1385*0fca6ea1SDimitry Andric   llvm::SmallPtrSet<NamedDecl *, 8> ProcessedCtors;
1386*0fca6ea1SDimitry Andric   bool AddedAny = false;
1387*0fca6ea1SDimitry Andric   for (NamedDecl *D : LookupConstructors(Pattern->getTemplatedDecl())) {
1388*0fca6ea1SDimitry Andric     D = D->getUnderlyingDecl();
1389*0fca6ea1SDimitry Andric     if (D->isInvalidDecl() || D->isImplicit())
1390*0fca6ea1SDimitry Andric       continue;
1391*0fca6ea1SDimitry Andric 
1392*0fca6ea1SDimitry Andric     D = cast<NamedDecl>(D->getCanonicalDecl());
1393*0fca6ea1SDimitry Andric 
1394*0fca6ea1SDimitry Andric     // Within C++20 modules, we may have multiple same constructors in
1395*0fca6ea1SDimitry Andric     // multiple same RecordDecls. And it doesn't make sense to create
1396*0fca6ea1SDimitry Andric     // duplicated deduction guides for the duplicated constructors.
1397*0fca6ea1SDimitry Andric     if (ProcessedCtors.count(D))
1398*0fca6ea1SDimitry Andric       continue;
1399*0fca6ea1SDimitry Andric 
1400*0fca6ea1SDimitry Andric     auto *FTD = dyn_cast<FunctionTemplateDecl>(D);
1401*0fca6ea1SDimitry Andric     auto *CD =
1402*0fca6ea1SDimitry Andric         dyn_cast_or_null<CXXConstructorDecl>(FTD ? FTD->getTemplatedDecl() : D);
1403*0fca6ea1SDimitry Andric     // Class-scope explicit specializations (MS extension) do not result in
1404*0fca6ea1SDimitry Andric     // deduction guides.
1405*0fca6ea1SDimitry Andric     if (!CD || (!FTD && CD->isFunctionTemplateSpecialization()))
1406*0fca6ea1SDimitry Andric       continue;
1407*0fca6ea1SDimitry Andric 
1408*0fca6ea1SDimitry Andric     // Cannot make a deduction guide when unparsed arguments are present.
1409*0fca6ea1SDimitry Andric     if (llvm::any_of(CD->parameters(), [](ParmVarDecl *P) {
1410*0fca6ea1SDimitry Andric           return !P || P->hasUnparsedDefaultArg();
1411*0fca6ea1SDimitry Andric         }))
1412*0fca6ea1SDimitry Andric       continue;
1413*0fca6ea1SDimitry Andric 
1414*0fca6ea1SDimitry Andric     ProcessedCtors.insert(D);
1415*0fca6ea1SDimitry Andric     Transform.transformConstructor(FTD, CD);
1416*0fca6ea1SDimitry Andric     AddedAny = true;
1417*0fca6ea1SDimitry Andric   }
1418*0fca6ea1SDimitry Andric 
1419*0fca6ea1SDimitry Andric   // C++17 [over.match.class.deduct]
1420*0fca6ea1SDimitry Andric   //    --  If C is not defined or does not declare any constructors, an
1421*0fca6ea1SDimitry Andric   //    additional function template derived as above from a hypothetical
1422*0fca6ea1SDimitry Andric   //    constructor C().
1423*0fca6ea1SDimitry Andric   if (!AddedAny)
1424*0fca6ea1SDimitry Andric     Transform.buildSimpleDeductionGuide(std::nullopt);
1425*0fca6ea1SDimitry Andric 
1426*0fca6ea1SDimitry Andric   //    -- An additional function template derived as above from a hypothetical
1427*0fca6ea1SDimitry Andric   //    constructor C(C), called the copy deduction candidate.
1428*0fca6ea1SDimitry Andric   cast<CXXDeductionGuideDecl>(
1429*0fca6ea1SDimitry Andric       cast<FunctionTemplateDecl>(
1430*0fca6ea1SDimitry Andric           Transform.buildSimpleDeductionGuide(Transform.DeducedType))
1431*0fca6ea1SDimitry Andric           ->getTemplatedDecl())
1432*0fca6ea1SDimitry Andric       ->setDeductionCandidateKind(DeductionCandidate::Copy);
1433*0fca6ea1SDimitry Andric 
1434*0fca6ea1SDimitry Andric   SavedContext.pop();
1435*0fca6ea1SDimitry Andric }
1436