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

source code of clang/lib/Sema/SemaTemplateDeductionGuide.cpp