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