clang 22.0.0git
SemaTemplateDeductionGuide.cpp
Go to the documentation of this file.
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"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclBase.h"
20#include "clang/AST/DeclCXX.h"
24#include "clang/AST/Expr.h"
25#include "clang/AST/ExprCXX.h"
29#include "clang/AST/Type.h"
30#include "clang/AST/TypeLoc.h"
31#include "clang/Basic/LLVM.h"
35#include "clang/Sema/DeclSpec.h"
37#include "clang/Sema/Lookup.h"
38#include "clang/Sema/Overload.h"
40#include "clang/Sema/Scope.h"
42#include "clang/Sema/Template.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:
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 SemaRef, SemaRef.getASTContext().getTranslationUnitDecl(),
79 *OuterInstantiationArgs);
80 }
81
82 TypeSourceInfo *transform(TypeSourceInfo *TSI) { return TransformType(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(TargetDC))
92 return true;
93 while (DC->isRecord()) {
94 if (DC->Equals(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
110 SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {
111 if (!OuterInstantiationArgs ||
112 !isa_and_present<TypeAliasTemplateDecl>(Template.getAsTemplateDecl()))
114 Keyword, Template, TemplateNameLoc, TemplateArgs);
115
116 auto *TATD = cast<TypeAliasTemplateDecl>(Template.getAsTemplateDecl());
117 auto *Pattern = TATD;
118 while (Pattern->getInstantiatedFromMemberTemplate())
119 Pattern = Pattern->getInstantiatedFromMemberTemplate();
120 if (!mightReferToOuterTemplateParameters(Pattern->getTemplatedDecl()))
122 Keyword, Template, TemplateNameLoc, TemplateArgs);
123
124 Decl *NewD =
125 TypedefNameInstantiator->InstantiateTypeAliasTemplateDecl(TATD);
126 if (!NewD)
127 return QualType();
128
129 auto *NewTATD = cast<TypeAliasTemplateDecl>(NewD);
130 MaterializedTypedefs.push_back(NewTATD->getTemplatedDecl());
131
133 Keyword, TemplateName(NewTATD), TemplateNameLoc, TemplateArgs);
134 }
135
136 QualType TransformTypedefType(TypeLocBuilder &TLB, TypedefTypeLoc TL) {
137 ASTContext &Context = SemaRef.getASTContext();
138 TypedefNameDecl *OrigDecl = TL.getDecl();
139 TypedefNameDecl *Decl = OrigDecl;
140 const TypedefType *T = TL.getTypePtr();
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 &&
159 Decl = cast_if_present<TypedefNameDecl>(
160 TypedefNameInstantiator->InstantiateTypedefNameDecl(
161 OrigDecl, /*IsTypeAlias=*/isa<TypeAliasDecl>(OrigDecl)));
162 if (!Decl)
163 return QualType();
164 MaterializedTypedefs.push_back(Decl);
165 } else if (InDependentContext) {
166 TypeLocBuilder InnerTLB;
167 QualType Transformed =
168 TransformType(InnerTLB, OrigDecl->getTypeSourceInfo()->getTypeLoc());
169 TypeSourceInfo *TSI = InnerTLB.getTypeSourceInfo(Context, Transformed);
170 if (isa<TypeAliasDecl>(OrigDecl))
172 Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
173 OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
174 else {
175 assert(isa<TypedefDecl>(OrigDecl) && "Not a Type alias or typedef");
177 Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
178 OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
179 }
180 MaterializedTypedefs.push_back(Decl);
181 }
182
183 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
184 if (QualifierLoc) {
185 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
186 if (!QualifierLoc)
187 return QualType();
188 }
189
190 QualType TDTy = Context.getTypedefType(
191 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), Decl);
192 TLB.push<TypedefTypeLoc>(TDTy).set(TL.getElaboratedKeywordLoc(),
193 QualifierLoc, TL.getNameLoc());
194 return TDTy;
195 }
196};
197
198// Build a deduction guide using the provided information.
199//
200// A deduction guide can be either a template or a non-template function
201// declaration. If \p TemplateParams is null, a non-template function
202// declaration will be created.
203NamedDecl *
204buildDeductionGuide(Sema &SemaRef, TemplateDecl *OriginalTemplate,
205 TemplateParameterList *TemplateParams,
207 TypeSourceInfo *TInfo, SourceLocation LocStart,
208 SourceLocation Loc, SourceLocation LocEnd, bool IsImplicit,
209 llvm::ArrayRef<TypedefNameDecl *> MaterializedTypedefs = {},
210 const AssociatedConstraint &FunctionTrailingRC = {}) {
211 DeclContext *DC = OriginalTemplate->getDeclContext();
212 auto DeductionGuideName =
214 OriginalTemplate);
215
216 DeclarationNameInfo Name(DeductionGuideName, Loc);
218 TInfo->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams();
219
220 // Build the implicit deduction guide template.
221 auto *Guide = CXXDeductionGuideDecl::Create(
222 SemaRef.Context, DC, LocStart, ES, Name, TInfo->getType(), TInfo, LocEnd,
223 Ctor, DeductionCandidate::Normal, FunctionTrailingRC);
224 Guide->setImplicit(IsImplicit);
225 Guide->setParams(Params);
226
227 for (auto *Param : Params)
228 Param->setDeclContext(Guide);
229 for (auto *TD : MaterializedTypedefs)
230 TD->setDeclContext(Guide);
231 if (isa<CXXRecordDecl>(DC))
232 Guide->setAccess(AS_public);
233
234 if (!TemplateParams) {
235 DC->addDecl(Guide);
236 return Guide;
237 }
238
239 auto *GuideTemplate = FunctionTemplateDecl::Create(
240 SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide);
241 GuideTemplate->setImplicit(IsImplicit);
242 Guide->setDescribedFunctionTemplate(GuideTemplate);
243
244 if (isa<CXXRecordDecl>(DC))
245 GuideTemplate->setAccess(AS_public);
246
247 DC->addDecl(GuideTemplate);
248 return GuideTemplate;
249}
250
251// Transform a given template type parameter `TTP`.
252TemplateTypeParmDecl *transformTemplateTypeParam(
253 Sema &SemaRef, DeclContext *DC, TemplateTypeParmDecl *TTP,
254 MultiLevelTemplateArgumentList &Args, unsigned NewDepth, unsigned NewIndex,
255 bool EvaluateConstraint) {
256 // TemplateTypeParmDecl's index cannot be changed after creation, so
257 // substitute it directly.
258 auto *NewTTP = TemplateTypeParmDecl::Create(
259 SemaRef.Context, DC, TTP->getBeginLoc(), TTP->getLocation(), NewDepth,
260 NewIndex, TTP->getIdentifier(), TTP->wasDeclaredWithTypename(),
261 TTP->isParameterPack(), TTP->hasTypeConstraint(),
263 if (const auto *TC = TTP->getTypeConstraint())
264 SemaRef.SubstTypeConstraint(NewTTP, TC, Args,
265 /*EvaluateConstraint=*/EvaluateConstraint);
266 if (TTP->hasDefaultArgument()) {
267 TemplateArgumentLoc InstantiatedDefaultArg;
268 if (!SemaRef.SubstTemplateArgument(
269 TTP->getDefaultArgument(), Args, InstantiatedDefaultArg,
270 TTP->getDefaultArgumentLoc(), TTP->getDeclName()))
271 NewTTP->setDefaultArgument(SemaRef.Context, InstantiatedDefaultArg);
272 }
273 SemaRef.CurrentInstantiationScope->InstantiatedLocal(TTP, NewTTP);
274 return NewTTP;
275}
276// Similar to above, but for non-type template or template template parameters.
277template <typename NonTypeTemplateOrTemplateTemplateParmDecl>
278NonTypeTemplateOrTemplateTemplateParmDecl *
279transformTemplateParam(Sema &SemaRef, DeclContext *DC,
280 NonTypeTemplateOrTemplateTemplateParmDecl *OldParam,
281 MultiLevelTemplateArgumentList &Args, unsigned NewIndex,
282 unsigned NewDepth) {
283 // Ask the template instantiator to do the heavy lifting for us, then adjust
284 // the index of the parameter once it's done.
285 auto *NewParam = cast<NonTypeTemplateOrTemplateTemplateParmDecl>(
286 SemaRef.SubstDecl(OldParam, DC, Args));
287 NewParam->setPosition(NewIndex);
288 NewParam->setDepth(NewDepth);
289 return NewParam;
290}
291
292NamedDecl *transformTemplateParameter(Sema &SemaRef, DeclContext *DC,
295 unsigned NewIndex, unsigned NewDepth,
296 bool EvaluateConstraint = true) {
297 if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
298 return transformTemplateTypeParam(
299 SemaRef, DC, TTP, Args, NewDepth, NewIndex,
300 /*EvaluateConstraint=*/EvaluateConstraint);
301 if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
302 return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex, NewDepth);
303 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
304 return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex, NewDepth);
305 llvm_unreachable("Unhandled template parameter types");
306}
307
308/// Transform to convert portions of a constructor declaration into the
309/// corresponding deduction guide, per C++1z [over.match.class.deduct]p1.
310struct ConvertConstructorToDeductionGuideTransform {
311 ConvertConstructorToDeductionGuideTransform(Sema &S,
312 ClassTemplateDecl *Template)
313 : SemaRef(S), Template(Template) {
314 // If the template is nested, then we need to use the original
315 // pattern to iterate over the constructors.
316 ClassTemplateDecl *Pattern = Template;
317 while (Pattern->getInstantiatedFromMemberTemplate()) {
318 if (Pattern->isMemberSpecialization())
319 break;
320 Pattern = Pattern->getInstantiatedFromMemberTemplate();
321 NestedPattern = Pattern;
322 }
323
324 if (NestedPattern)
325 OuterInstantiationArgs = SemaRef.getTemplateInstantiationArgs(Template);
326 }
327
328 Sema &SemaRef;
330 ClassTemplateDecl *NestedPattern = nullptr;
331
332 DeclContext *DC = Template->getDeclContext();
333 CXXRecordDecl *Primary = Template->getTemplatedDecl();
334 DeclarationName DeductionGuideName =
336
338
339 // Index adjustment to apply to convert depth-1 template parameters into
340 // depth-0 template parameters.
341 unsigned Depth1IndexAdjustment = Template->getTemplateParameters()->size();
342
343 // Instantiation arguments for the outermost depth-1 templates
344 // when the template is nested
345 MultiLevelTemplateArgumentList OuterInstantiationArgs;
346
347 /// Transform a constructor declaration into a deduction guide.
348 NamedDecl *transformConstructor(FunctionTemplateDecl *FTD,
349 CXXConstructorDecl *CD) {
351
353
354 // C++ [over.match.class.deduct]p1:
355 // -- For each constructor of the class template designated by the
356 // template-name, a function template with the following properties:
357
358 // -- The template parameters are the template parameters of the class
359 // template followed by the template parameters (including default
360 // template arguments) of the constructor, if any.
361 TemplateParameterList *TemplateParams =
362 SemaRef.GetTemplateParameterList(Template);
364 AssociatedConstraint OuterRC(TemplateParams->getRequiresClause());
365 if (FTD) {
366 TemplateParameterList *InnerParams = FTD->getTemplateParameters();
368 AllParams.reserve(TemplateParams->size() + InnerParams->size());
369 AllParams.insert(AllParams.begin(), TemplateParams->begin(),
370 TemplateParams->end());
371 SubstArgs.reserve(InnerParams->size());
372 Depth1Args.reserve(InnerParams->size());
373
374 // Later template parameters could refer to earlier ones, so build up
375 // a list of substituted template arguments as we go.
376 for (NamedDecl *Param : *InnerParams) {
378 Args.setKind(TemplateSubstitutionKind::Rewrite);
379 Args.addOuterTemplateArguments(Depth1Args);
381 if (NestedPattern)
382 Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
383 auto [Depth, Index] = getDepthAndIndex(Param);
384 // Depth can be 0 if FTD belongs to a non-template class/a class
385 // template specialization with an empty template parameter list. In
386 // that case, we don't want the NewDepth to overflow, and it should
387 // remain 0.
388 NamedDecl *NewParam = transformTemplateParameter(
389 SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment,
390 Depth ? Depth - 1 : 0);
391 if (!NewParam)
392 return nullptr;
393 // Constraints require that we substitute depth-1 arguments
394 // to match depths when substituted for evaluation later
395 Depth1Args.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam));
396
397 if (NestedPattern) {
398 auto [Depth, Index] = getDepthAndIndex(NewParam);
399 NewParam = transformTemplateParameter(
400 SemaRef, DC, NewParam, OuterInstantiationArgs, Index,
401 Depth - OuterInstantiationArgs.getNumSubstitutedLevels(),
402 /*EvaluateConstraint=*/false);
403 }
404
405 assert(getDepthAndIndex(NewParam).first == 0 &&
406 "Unexpected template parameter depth");
407
408 AllParams.push_back(NewParam);
409 SubstArgs.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam));
410 }
411
412 // Substitute new template parameters into requires-clause if present.
413 Expr *RequiresClause = nullptr;
414 if (Expr *InnerRC = InnerParams->getRequiresClause()) {
416 Args.setKind(TemplateSubstitutionKind::Rewrite);
417 Args.addOuterTemplateArguments(Depth1Args);
419 if (NestedPattern)
420 Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
421 ExprResult E =
422 SemaRef.SubstConstraintExprWithoutSatisfaction(InnerRC, Args);
423 if (!E.isUsable())
424 return nullptr;
425 RequiresClause = E.get();
426 }
427
428 TemplateParams = TemplateParameterList::Create(
429 SemaRef.Context, InnerParams->getTemplateLoc(),
430 InnerParams->getLAngleLoc(), AllParams, InnerParams->getRAngleLoc(),
431 RequiresClause);
432 }
433
434 // If we built a new template-parameter-list, track that we need to
435 // substitute references to the old parameters into references to the
436 // new ones.
438 Args.setKind(TemplateSubstitutionKind::Rewrite);
439 if (FTD) {
440 Args.addOuterTemplateArguments(SubstArgs);
442 }
443
445 ->getTypeLoc()
447 assert(FPTL && "no prototype for constructor declaration");
448
449 // Transform the type of the function, adjusting the return type and
450 // replacing references to the old parameters with references to the
451 // new ones.
452 TypeLocBuilder TLB;
454 SmallVector<TypedefNameDecl *, 4> MaterializedTypedefs;
455 QualType NewType = transformFunctionProtoType(TLB, FPTL, Params, Args,
456 MaterializedTypedefs);
457 if (NewType.isNull())
458 return nullptr;
459 TypeSourceInfo *NewTInfo = TLB.getTypeSourceInfo(SemaRef.Context, NewType);
460
461 // At this point, the function parameters are already 'instantiated' in the
462 // current scope. Substitute into the constructor's trailing
463 // requires-clause, if any.
464 AssociatedConstraint FunctionTrailingRC;
465 if (const AssociatedConstraint &RC = CD->getTrailingRequiresClause()) {
467 Args.setKind(TemplateSubstitutionKind::Rewrite);
468 Args.addOuterTemplateArguments(Depth1Args);
470 if (NestedPattern)
471 Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
473 const_cast<Expr *>(RC.ConstraintExpr), Args);
474 if (!E.isUsable())
475 return nullptr;
476 FunctionTrailingRC = AssociatedConstraint(E.get(), RC.ArgPackSubstIndex);
477 }
478
479 // C++ [over.match.class.deduct]p1:
480 // If C is defined, for each constructor of C, a function template with
481 // the following properties:
482 // [...]
483 // - The associated constraints are the conjunction of the associated
484 // constraints of C and the associated constraints of the constructor, if
485 // any.
486 if (OuterRC) {
487 // The outer template parameters are not transformed, so their
488 // associated constraints don't need substitution.
489 // FIXME: Should simply add another field for the OuterRC, instead of
490 // combining them like this.
491 if (!FunctionTrailingRC)
492 FunctionTrailingRC = OuterRC;
493 else
494 FunctionTrailingRC = AssociatedConstraint(
496 SemaRef.Context,
497 /*lhs=*/const_cast<Expr *>(OuterRC.ConstraintExpr),
498 /*rhs=*/const_cast<Expr *>(FunctionTrailingRC.ConstraintExpr),
499 BO_LAnd, SemaRef.Context.BoolTy, VK_PRValue, OK_Ordinary,
500 TemplateParams->getTemplateLoc(), FPOptionsOverride()),
501 FunctionTrailingRC.ArgPackSubstIndex);
502 }
503
504 return buildDeductionGuide(
505 SemaRef, Template, TemplateParams, CD, CD->getExplicitSpecifier(),
506 NewTInfo, CD->getBeginLoc(), CD->getLocation(), CD->getEndLoc(),
507 /*IsImplicit=*/true, MaterializedTypedefs, FunctionTrailingRC);
508 }
509
510 /// Build a deduction guide with the specified parameter types.
511 NamedDecl *buildSimpleDeductionGuide(MutableArrayRef<QualType> ParamTypes) {
512 SourceLocation Loc = Template->getLocation();
513
514 // Build the requested type.
516 EPI.HasTrailingReturn = true;
517 QualType Result = SemaRef.BuildFunctionType(DeducedType, ParamTypes, Loc,
518 DeductionGuideName, EPI);
519 TypeSourceInfo *TSI = SemaRef.Context.getTrivialTypeSourceInfo(Result, Loc);
520 if (NestedPattern)
521 TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,
522 DeductionGuideName);
523
524 if (!TSI)
525 return nullptr;
526
529
530 // Build the parameters, needed during deduction / substitution.
532 for (auto T : ParamTypes) {
533 auto *TSI = SemaRef.Context.getTrivialTypeSourceInfo(T, Loc);
534 if (NestedPattern)
535 TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,
537 if (!TSI)
538 return nullptr;
539
540 ParmVarDecl *NewParam =
541 ParmVarDecl::Create(SemaRef.Context, DC, Loc, Loc, nullptr,
542 TSI->getType(), TSI, SC_None, nullptr);
543 NewParam->setScopeInfo(0, Params.size());
544 FPTL.setParam(Params.size(), NewParam);
545 Params.push_back(NewParam);
546 }
547
548 return buildDeductionGuide(
549 SemaRef, Template, SemaRef.GetTemplateParameterList(Template), nullptr,
550 ExplicitSpecifier(), TSI, Loc, Loc, Loc, /*IsImplicit=*/true);
551 }
552
553private:
554 QualType transformFunctionProtoType(
558 SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs) {
559 SmallVector<QualType, 4> ParamTypes;
560 const FunctionProtoType *T = TL.getTypePtr();
561
562 // -- The types of the function parameters are those of the constructor.
563 for (auto *OldParam : TL.getParams()) {
564 ParmVarDecl *NewParam = OldParam;
565 // Given
566 // template <class T> struct C {
567 // template <class U> struct D {
568 // template <class V> D(U, V);
569 // };
570 // };
571 // First, transform all the references to template parameters that are
572 // defined outside of the surrounding class template. That is T in the
573 // above example.
574 if (NestedPattern) {
575 NewParam = transformFunctionTypeParam(
576 NewParam, OuterInstantiationArgs, MaterializedTypedefs,
577 /*TransformingOuterPatterns=*/true);
578 if (!NewParam)
579 return QualType();
580 }
581 // Then, transform all the references to template parameters that are
582 // defined at the class template and the constructor. In this example,
583 // they're U and V, respectively.
584 NewParam =
585 transformFunctionTypeParam(NewParam, Args, MaterializedTypedefs,
586 /*TransformingOuterPatterns=*/false);
587 if (!NewParam)
588 return QualType();
589 ParamTypes.push_back(NewParam->getType());
590 Params.push_back(NewParam);
591 }
592
593 // -- The return type is the class template specialization designated by
594 // the template-name and template arguments corresponding to the
595 // template parameters obtained from the class template.
596 //
597 // We use the injected-class-name type of the primary template instead.
598 // This has the convenient property that it is different from any type that
599 // the user can write in a deduction-guide (because they cannot enter the
600 // context of the template), so implicit deduction guides can never collide
601 // with explicit ones.
602 QualType ReturnType = DeducedType;
603 auto TTL = TLB.push<TagTypeLoc>(ReturnType);
605 TTL.setQualifierLoc(NestedNameSpecifierLoc());
606 TTL.setNameLoc(Primary->getLocation());
607
608 // Resolving a wording defect, we also inherit the variadicness of the
609 // constructor.
611 EPI.Variadic = T->isVariadic();
612 EPI.HasTrailingReturn = true;
613
614 QualType Result = SemaRef.BuildFunctionType(
615 ReturnType, ParamTypes, TL.getBeginLoc(), DeductionGuideName, EPI);
616 if (Result.isNull())
617 return QualType();
618
621 NewTL.setLParenLoc(TL.getLParenLoc());
622 NewTL.setRParenLoc(TL.getRParenLoc());
625 for (unsigned I = 0, E = NewTL.getNumParams(); I != E; ++I)
626 NewTL.setParam(I, Params[I]);
627
628 return Result;
629 }
630
631 ParmVarDecl *transformFunctionTypeParam(
633 llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs,
634 bool TransformingOuterPatterns) {
635 TypeSourceInfo *OldDI = OldParam->getTypeSourceInfo();
636 TypeSourceInfo *NewDI;
637 if (auto PackTL = OldDI->getTypeLoc().getAs<PackExpansionTypeLoc>()) {
638 // Expand out the one and only element in each inner pack.
639 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, 0u);
640 NewDI =
641 SemaRef.SubstType(PackTL.getPatternLoc(), Args,
642 OldParam->getLocation(), OldParam->getDeclName());
643 if (!NewDI)
644 return nullptr;
645 NewDI =
646 SemaRef.CheckPackExpansion(NewDI, PackTL.getEllipsisLoc(),
647 PackTL.getTypePtr()->getNumExpansions());
648 } else
649 NewDI = SemaRef.SubstType(OldDI, Args, OldParam->getLocation(),
650 OldParam->getDeclName());
651 if (!NewDI)
652 return nullptr;
653
654 // Extract the type. This (for instance) replaces references to typedef
655 // members of the current instantiations with the definitions of those
656 // typedefs, avoiding triggering instantiation of the deduced type during
657 // deduction.
658 NewDI = ExtractTypeForDeductionGuide(
659 SemaRef, MaterializedTypedefs, NestedPattern,
660 TransformingOuterPatterns ? &Args : nullptr)
661 .transform(NewDI);
662
663 // Resolving a wording defect, we also inherit default arguments from the
664 // constructor.
665 ExprResult NewDefArg;
666 if (OldParam->hasDefaultArg()) {
667 // We don't care what the value is (we won't use it); just create a
668 // placeholder to indicate there is a default argument.
669 QualType ParamTy = NewDI->getType();
670 NewDefArg = new (SemaRef.Context)
672 ParamTy.getNonLValueExprType(SemaRef.Context),
674 : ParamTy->isRValueReferenceType() ? VK_XValue
675 : VK_PRValue);
676 }
677 // Handle arrays and functions decay.
678 auto NewType = NewDI->getType();
679 if (NewType->isArrayType() || NewType->isFunctionType())
680 NewType = SemaRef.Context.getDecayedType(NewType);
681
683 SemaRef.Context, DC, OldParam->getInnerLocStart(),
684 OldParam->getLocation(), OldParam->getIdentifier(), NewType, NewDI,
685 OldParam->getStorageClass(), NewDefArg.get());
686 NewParam->setScopeInfo(OldParam->getFunctionScopeDepth(),
687 OldParam->getFunctionScopeIndex());
688 SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam);
689 return NewParam;
690 }
691};
692
693// Find all template parameters that appear in the given DeducedArgs.
694// Return the indices of the template parameters in the TemplateParams.
695SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
696 Sema &SemaRef, const TemplateParameterList *TemplateParamsList,
697 ArrayRef<TemplateArgument> DeducedArgs) {
698
699 llvm::SmallBitVector ReferencedTemplateParams(TemplateParamsList->size());
701 DeducedArgs, TemplateParamsList->getDepth(), ReferencedTemplateParams);
702
703 auto MarkDefaultArgs = [&](auto *Param) {
704 if (!Param->hasDefaultArgument())
705 return;
707 Param->getDefaultArgument().getArgument(),
708 TemplateParamsList->getDepth(), ReferencedTemplateParams);
709 };
710
711 for (unsigned Index = 0; Index < TemplateParamsList->size(); ++Index) {
712 if (!ReferencedTemplateParams[Index])
713 continue;
714 auto *Param = TemplateParamsList->getParam(Index);
715 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param))
716 MarkDefaultArgs(TTPD);
717 else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param))
718 MarkDefaultArgs(NTTPD);
719 else
720 MarkDefaultArgs(cast<TemplateTemplateParmDecl>(Param));
721 }
722
723 SmallVector<unsigned> Results;
724 for (unsigned Index = 0; Index < TemplateParamsList->size(); ++Index) {
725 if (ReferencedTemplateParams[Index])
726 Results.push_back(Index);
727 }
728 return Results;
729}
730
731bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) {
732 // Check whether we've already declared deduction guides for this template.
733 // FIXME: Consider storing a flag on the template to indicate this.
734 assert(Name.getNameKind() ==
735 DeclarationName::NameKind::CXXDeductionGuideName &&
736 "name must be a deduction guide name");
737 auto Existing = DC->lookup(Name);
738 for (auto *D : Existing)
739 if (D->isImplicit())
740 return true;
741 return false;
742}
743
744// Returns all source deduction guides associated with the declared
745// deduction guides that have the specified deduction guide name.
746llvm::DenseSet<const NamedDecl *> getSourceDeductionGuides(DeclarationName Name,
747 DeclContext *DC) {
748 assert(Name.getNameKind() ==
749 DeclarationName::NameKind::CXXDeductionGuideName &&
750 "name must be a deduction guide name");
751 llvm::DenseSet<const NamedDecl *> Result;
752 for (auto *D : DC->lookup(Name)) {
753 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
754 D = FTD->getTemplatedDecl();
755
756 if (const auto *GD = dyn_cast<CXXDeductionGuideDecl>(D)) {
757 assert(GD->getSourceDeductionGuide() &&
758 "deduction guide for alias template must have a source deduction "
759 "guide");
760 Result.insert(GD->getSourceDeductionGuide());
761 }
762 }
763 return Result;
764}
765
766// Build the associated constraints for the alias deduction guides.
767// C++ [over.match.class.deduct]p3.3:
768// The associated constraints ([temp.constr.decl]) are the conjunction of the
769// associated constraints of g and a constraint that is satisfied if and only
770// if the arguments of A are deducible (see below) from the return type.
771//
772// The return result is expected to be the require-clause for the synthesized
773// alias deduction guide.
774Expr *
775buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F,
778 unsigned FirstUndeducedParamIdx, Expr *IsDeducible) {
780 if (!RC)
781 return IsDeducible;
782
783 ASTContext &Context = SemaRef.Context;
785
786 // In the clang AST, constraint nodes are deliberately not instantiated unless
787 // they are actively being evaluated. Consequently, occurrences of template
788 // parameters in the require-clause expression have a subtle "depth"
789 // difference compared to normal occurrences in places, such as function
790 // parameters. When transforming the require-clause, we must take this
791 // distinction into account:
792 //
793 // 1) In the transformed require-clause, occurrences of template parameters
794 // must use the "uninstantiated" depth;
795 // 2) When substituting on the require-clause expr of the underlying
796 // deduction guide, we must use the entire set of template argument lists;
797 //
798 // It's important to note that we're performing this transformation on an
799 // *instantiated* AliasTemplate.
800
801 // For 1), if the alias template is nested within a class template, we
802 // calcualte the 'uninstantiated' depth by adding the substitution level back.
803 unsigned AdjustDepth = 0;
804 if (auto *PrimaryTemplate =
805 AliasTemplate->getInstantiatedFromMemberTemplate())
806 AdjustDepth = PrimaryTemplate->getTemplateDepth();
807
808 // We rebuild all template parameters with the uninstantiated depth, and
809 // build template arguments refer to them.
810 SmallVector<TemplateArgument> AdjustedAliasTemplateArgs;
811
812 for (auto *TP : *AliasTemplate->getTemplateParameters()) {
813 // Rebuild any internal references to earlier parameters and reindex
814 // as we go.
816 Args.setKind(TemplateSubstitutionKind::Rewrite);
817 Args.addOuterTemplateArguments(AdjustedAliasTemplateArgs);
818 NamedDecl *NewParam = transformTemplateParameter(
819 SemaRef, AliasTemplate->getDeclContext(), TP, Args,
820 /*NewIndex=*/AdjustedAliasTemplateArgs.size(),
821 getDepthAndIndex(TP).first + AdjustDepth);
822
823 TemplateArgument NewTemplateArgument =
824 Context.getInjectedTemplateArg(NewParam);
825 AdjustedAliasTemplateArgs.push_back(NewTemplateArgument);
826 }
827 // Template arguments used to transform the template arguments in
828 // DeducedResults.
829 SmallVector<TemplateArgument> TemplateArgsForBuildingRC(
831 // Transform the transformed template args
833 Args.setKind(TemplateSubstitutionKind::Rewrite);
834 Args.addOuterTemplateArguments(AdjustedAliasTemplateArgs);
835
836 for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
837 const auto &D = DeduceResults[Index];
838 if (D.isNull()) { // non-deduced template parameters of f
839 NamedDecl *TP = F->getTemplateParameters()->getParam(Index);
841 Args.setKind(TemplateSubstitutionKind::Rewrite);
842 Args.addOuterTemplateArguments(TemplateArgsForBuildingRC);
843 // Rebuild the template parameter with updated depth and index.
844 NamedDecl *NewParam =
845 transformTemplateParameter(SemaRef, F->getDeclContext(), TP, Args,
846 /*NewIndex=*/FirstUndeducedParamIdx,
847 getDepthAndIndex(TP).first + AdjustDepth);
848 FirstUndeducedParamIdx += 1;
849 assert(TemplateArgsForBuildingRC[Index].isNull());
850 TemplateArgsForBuildingRC[Index] =
851 Context.getInjectedTemplateArg(NewParam);
852 continue;
853 }
854 TemplateArgumentLoc Input =
856 TemplateArgumentLoc Output;
857 if (!SemaRef.SubstTemplateArgument(Input, Args, Output)) {
858 assert(TemplateArgsForBuildingRC[Index].isNull() &&
859 "InstantiatedArgs must be null before setting");
860 TemplateArgsForBuildingRC[Index] = Output.getArgument();
861 }
862 }
863
864 // A list of template arguments for transforming the require-clause of F.
865 // It must contain the entire set of template argument lists.
866 MultiLevelTemplateArgumentList ArgsForBuildingRC;
868 ArgsForBuildingRC.addOuterTemplateArguments(TemplateArgsForBuildingRC);
869 // For 2), if the underlying deduction guide F is nested in a class template,
870 // we need the entire template argument list, as the constraint AST in the
871 // require-clause of F remains completely uninstantiated.
872 //
873 // For example:
874 // template <typename T> // depth 0
875 // struct Outer {
876 // template <typename U>
877 // struct Foo { Foo(U); };
878 //
879 // template <typename U> // depth 1
880 // requires C<U>
881 // Foo(U) -> Foo<int>;
882 // };
883 // template <typename U>
884 // using AFoo = Outer<int>::Foo<U>;
885 //
886 // In this scenario, the deduction guide for `Foo` inside `Outer<int>`:
887 // - The occurrence of U in the require-expression is [depth:1, index:0]
888 // - The occurrence of U in the function parameter is [depth:0, index:0]
889 // - The template parameter of U is [depth:0, index:0]
890 //
891 // We add the outer template arguments which is [int] to the multi-level arg
892 // list to ensure that the occurrence U in `C<U>` will be replaced with int
893 // during the substitution.
894 //
895 // NOTE: The underlying deduction guide F is instantiated -- either from an
896 // explicitly-written deduction guide member, or from a constructor.
897 // getInstantiatedFromMemberTemplate() can only handle the former case, so we
898 // check the DeclContext kind.
900 clang::Decl::ClassTemplateSpecialization) {
901 auto OuterLevelArgs = SemaRef.getTemplateInstantiationArgs(
902 F, F->getLexicalDeclContext(),
903 /*Final=*/false, /*Innermost=*/std::nullopt,
904 /*RelativeToPrimary=*/true,
905 /*Pattern=*/nullptr,
906 /*ForConstraintInstantiation=*/true);
907 for (auto It : OuterLevelArgs)
908 ArgsForBuildingRC.addOuterTemplateArguments(It.Args);
909 }
910
911 ExprResult E = SemaRef.SubstExpr(RC, ArgsForBuildingRC);
912 if (E.isInvalid())
913 return nullptr;
914
915 auto Conjunction =
916 SemaRef.BuildBinOp(SemaRef.getCurScope(), SourceLocation{},
917 BinaryOperatorKind::BO_LAnd, E.get(), IsDeducible);
918 if (Conjunction.isInvalid())
919 return nullptr;
920 return Conjunction.getAs<Expr>();
921}
922// Build the is_deducible constraint for the alias deduction guides.
923// [over.match.class.deduct]p3.3:
924// ... and a constraint that is satisfied if and only if the arguments
925// of A are deducible (see below) from the return type.
926Expr *buildIsDeducibleConstraint(Sema &SemaRef,
928 QualType ReturnType,
929 SmallVector<NamedDecl *> TemplateParams) {
930 ASTContext &Context = SemaRef.Context;
931 // Constraint AST nodes must use uninstantiated depth.
932 if (auto *PrimaryTemplate =
933 AliasTemplate->getInstantiatedFromMemberTemplate();
934 PrimaryTemplate && TemplateParams.size() > 0) {
936
937 // Adjust the depth for TemplateParams.
938 unsigned AdjustDepth = PrimaryTemplate->getTemplateDepth();
939 SmallVector<TemplateArgument> TransformedTemplateArgs;
940 for (auto *TP : TemplateParams) {
941 // Rebuild any internal references to earlier parameters and reindex
942 // as we go.
944 Args.setKind(TemplateSubstitutionKind::Rewrite);
945 Args.addOuterTemplateArguments(TransformedTemplateArgs);
946 NamedDecl *NewParam = transformTemplateParameter(
947 SemaRef, AliasTemplate->getDeclContext(), TP, Args,
948 /*NewIndex=*/TransformedTemplateArgs.size(),
949 getDepthAndIndex(TP).first + AdjustDepth);
950
951 TemplateArgument NewTemplateArgument =
952 Context.getInjectedTemplateArg(NewParam);
953 TransformedTemplateArgs.push_back(NewTemplateArgument);
954 }
955 // Transformed the ReturnType to restore the uninstantiated depth.
957 Args.setKind(TemplateSubstitutionKind::Rewrite);
958 Args.addOuterTemplateArguments(TransformedTemplateArgs);
959 ReturnType = SemaRef.SubstType(
960 ReturnType, Args, AliasTemplate->getLocation(),
962 }
963
964 SmallVector<TypeSourceInfo *> IsDeducibleTypeTraitArgs = {
967 ElaboratedTypeKeyword::None, TemplateName(AliasTemplate),
968 /*DeducedType=*/QualType(),
969 /*IsDependent=*/true),
970 AliasTemplate->getLocation()), // template specialization type whose
971 // arguments will be deduced.
973 ReturnType, AliasTemplate->getLocation()), // type from which template
974 // arguments are deduced.
975 };
977 Context, Context.getLogicalOperationType(), AliasTemplate->getLocation(),
978 TypeTrait::BTT_IsDeducible, IsDeducibleTypeTraitArgs,
979 AliasTemplate->getLocation(), /*Value*/ false);
980}
981
982std::pair<TemplateDecl *, llvm::ArrayRef<TemplateArgument>>
983getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) {
984 auto RhsType = AliasTemplate->getTemplatedDecl()->getUnderlyingType();
985 TemplateDecl *Template = nullptr;
986 llvm::ArrayRef<TemplateArgument> AliasRhsTemplateArgs;
987 if (const auto *TST = RhsType->getAs<TemplateSpecializationType>()) {
988 // Cases where the RHS of the alias is dependent. e.g.
989 // template<typename T>
990 // using AliasFoo1 = Foo<T>; // a class/type alias template specialization
991 Template = TST->getTemplateName().getAsTemplateDecl();
992 AliasRhsTemplateArgs =
993 TST->getAsNonAliasTemplateSpecializationType()->template_arguments();
994 } else if (const auto *RT = RhsType->getAs<RecordType>()) {
995 // Cases where template arguments in the RHS of the alias are not
996 // dependent. e.g.
997 // using AliasFoo = Foo<bool>;
998 if (const auto *CTSD =
999 dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl())) {
1000 Template = CTSD->getSpecializedTemplate();
1001 AliasRhsTemplateArgs = CTSD->getTemplateArgs().asArray();
1002 }
1003 }
1004 return {Template, AliasRhsTemplateArgs};
1005}
1006
1007bool IsNonDeducedArgument(const TemplateArgument &TA) {
1008 // The following cases indicate the template argument is non-deducible:
1009 // 1. The result is null. E.g. When it comes from a default template
1010 // argument that doesn't appear in the alias declaration.
1011 // 2. The template parameter is a pack and that cannot be deduced from
1012 // the arguments within the alias declaration.
1013 // Non-deducible template parameters will persist in the transformed
1014 // deduction guide.
1015 return TA.isNull() ||
1017 llvm::any_of(TA.pack_elements(), IsNonDeducedArgument));
1018}
1019
1020// Build deduction guides for a type alias template from the given underlying
1021// deduction guide F.
1023BuildDeductionGuideForTypeAlias(Sema &SemaRef,
1027 Sema::InstantiatingTemplate BuildingDeductionGuides(
1028 SemaRef, AliasTemplate->getLocation(), F,
1030 if (BuildingDeductionGuides.isInvalid())
1031 return nullptr;
1032
1033 auto &Context = SemaRef.Context;
1034 auto [Template, AliasRhsTemplateArgs] =
1035 getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
1036
1037 // We need both types desugared, before we continue to perform type deduction.
1038 // The intent is to get the template argument list 'matched', e.g. in the
1039 // following case:
1040 //
1041 //
1042 // template <class T>
1043 // struct A {};
1044 // template <class T>
1045 // using Foo = A<A<T>>;
1046 // template <class U = int>
1047 // using Bar = Foo<U>;
1048 //
1049 // In terms of Bar, we want U (which has the default argument) to appear in
1050 // the synthesized deduction guide, but U would remain undeduced if we deduced
1051 // A<A<T>> using Foo<U> directly.
1052 //
1053 // Instead, we need to canonicalize both against A, i.e. A<A<T>> and A<A<U>>,
1054 // such that T can be deduced as U.
1055 auto RType = F->getTemplatedDecl()->getReturnType();
1056 // The (trailing) return type of the deduction guide.
1057 const TemplateSpecializationType *FReturnType =
1059 if (const auto *ICNT = RType->getAsCanonical<InjectedClassNameType>())
1060 // implicitly-generated deduction guide.
1061 FReturnType = cast<TemplateSpecializationType>(
1062 ICNT->getOriginalDecl()->getCanonicalTemplateSpecializationType(
1063 SemaRef.Context));
1064 assert(FReturnType && "expected to see a return type");
1065 // Deduce template arguments of the deduction guide f from the RHS of
1066 // the alias.
1067 //
1068 // C++ [over.match.class.deduct]p3: ...For each function or function
1069 // template f in the guides of the template named by the
1070 // simple-template-id of the defining-type-id, the template arguments
1071 // of the return type of f are deduced from the defining-type-id of A
1072 // according to the process in [temp.deduct.type] with the exception
1073 // that deduction does not fail if not all template arguments are
1074 // deduced.
1075 //
1076 //
1077 // template<typename X, typename Y>
1078 // f(X, Y) -> f<Y, X>;
1079 //
1080 // template<typename U>
1081 // using alias = f<int, U>;
1082 //
1083 // The RHS of alias is f<int, U>, we deduced the template arguments of
1084 // the return type of the deduction guide from it: Y->int, X->U
1085 sema::TemplateDeductionInfo TDeduceInfo(Loc);
1086 // Must initialize n elements, this is required by DeduceTemplateArguments.
1088 F->getTemplateParameters()->size());
1089
1090 // FIXME: DeduceTemplateArguments stops immediately at the first
1091 // non-deducible template argument. However, this doesn't seem to cause
1092 // issues for practice cases, we probably need to extend it to continue
1093 // performing deduction for rest of arguments to align with the C++
1094 // standard.
1096 F->getTemplateParameters(), FReturnType->template_arguments(),
1097 AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
1098 /*NumberOfArgumentsMustMatch=*/false);
1099
1101 SmallVector<unsigned> NonDeducedTemplateParamsInFIndex;
1102 // !!NOTE: DeduceResults respects the sequence of template parameters of
1103 // the deduction guide f.
1104 for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
1105 const auto &D = DeduceResults[Index];
1106 if (!IsNonDeducedArgument(D))
1107 DeducedArgs.push_back(D);
1108 else
1109 NonDeducedTemplateParamsInFIndex.push_back(Index);
1110 }
1111 auto DeducedAliasTemplateParams =
1112 TemplateParamsReferencedInTemplateArgumentList(
1113 SemaRef, AliasTemplate->getTemplateParameters(), DeducedArgs);
1114 // All template arguments null by default.
1115 SmallVector<TemplateArgument> TemplateArgsForBuildingFPrime(
1116 F->getTemplateParameters()->size());
1117
1118 // Create a template parameter list for the synthesized deduction guide f'.
1119 //
1120 // C++ [over.match.class.deduct]p3.2:
1121 // If f is a function template, f' is a function template whose template
1122 // parameter list consists of all the template parameters of A
1123 // (including their default template arguments) that appear in the above
1124 // deductions or (recursively) in their default template arguments
1125 SmallVector<NamedDecl *> FPrimeTemplateParams;
1126 // Store template arguments that refer to the newly-created template
1127 // parameters, used for building `TemplateArgsForBuildingFPrime`.
1128 SmallVector<TemplateArgument, 16> TransformedDeducedAliasArgs(
1129 AliasTemplate->getTemplateParameters()->size());
1130 // We might be already within a pack expansion, but rewriting template
1131 // parameters is independent of that. (We may or may not expand new packs
1132 // when rewriting. So clear the state)
1133 Sema::ArgPackSubstIndexRAII PackSubstReset(SemaRef, std::nullopt);
1134
1135 for (unsigned AliasTemplateParamIdx : DeducedAliasTemplateParams) {
1136 auto *TP =
1137 AliasTemplate->getTemplateParameters()->getParam(AliasTemplateParamIdx);
1138 // Rebuild any internal references to earlier parameters and reindex as
1139 // we go.
1141 Args.setKind(TemplateSubstitutionKind::Rewrite);
1142 Args.addOuterTemplateArguments(TransformedDeducedAliasArgs);
1143 NamedDecl *NewParam = transformTemplateParameter(
1144 SemaRef, AliasTemplate->getDeclContext(), TP, Args,
1145 /*NewIndex=*/FPrimeTemplateParams.size(), getDepthAndIndex(TP).first);
1146 FPrimeTemplateParams.push_back(NewParam);
1147
1148 TemplateArgument NewTemplateArgument =
1149 Context.getInjectedTemplateArg(NewParam);
1150 TransformedDeducedAliasArgs[AliasTemplateParamIdx] = NewTemplateArgument;
1151 }
1152 unsigned FirstUndeducedParamIdx = FPrimeTemplateParams.size();
1153
1154 // To form a deduction guide f' from f, we leverage clang's instantiation
1155 // mechanism, we construct a template argument list where the template
1156 // arguments refer to the newly-created template parameters of f', and
1157 // then apply instantiation on this template argument list to instantiate
1158 // f, this ensures all template parameter occurrences are updated
1159 // correctly.
1160 //
1161 // The template argument list is formed, in order, from
1162 // 1) For the template parameters of the alias, the corresponding deduced
1163 // template arguments
1164 // 2) For the non-deduced template parameters of f. the
1165 // (rebuilt) template arguments corresponding.
1166 //
1167 // Note: the non-deduced template arguments of `f` might refer to arguments
1168 // deduced in 1), as in a type constraint.
1170 Args.setKind(TemplateSubstitutionKind::Rewrite);
1171 Args.addOuterTemplateArguments(TransformedDeducedAliasArgs);
1172 for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
1173 const auto &D = DeduceResults[Index];
1174 if (IsNonDeducedArgument(D)) {
1175 // 2): Non-deduced template parameters would be substituted later.
1176 continue;
1177 }
1178 TemplateArgumentLoc Input =
1180 TemplateArgumentLoc Output;
1181 if (!SemaRef.SubstTemplateArgument(Input, Args, Output)) {
1182 assert(TemplateArgsForBuildingFPrime[Index].isNull() &&
1183 "InstantiatedArgs must be null before setting");
1184 TemplateArgsForBuildingFPrime[Index] = Output.getArgument();
1185 }
1186 }
1187
1188 // Case 2)
1189 // ...followed by the template parameters of f that were not deduced
1190 // (including their default template arguments)
1191 for (unsigned FTemplateParamIdx : NonDeducedTemplateParamsInFIndex) {
1192 auto *TP = F->getTemplateParameters()->getParam(FTemplateParamIdx);
1194 Args.setKind(TemplateSubstitutionKind::Rewrite);
1195 // We take a shortcut here, it is ok to reuse the
1196 // TemplateArgsForBuildingFPrime.
1197 Args.addOuterTemplateArguments(TemplateArgsForBuildingFPrime);
1198 NamedDecl *NewParam = transformTemplateParameter(
1199 SemaRef, F->getDeclContext(), TP, Args, FPrimeTemplateParams.size(),
1200 getDepthAndIndex(TP).first);
1201 FPrimeTemplateParams.push_back(NewParam);
1202
1203 assert(TemplateArgsForBuildingFPrime[FTemplateParamIdx].isNull() &&
1204 "The argument must be null before setting");
1205 TemplateArgsForBuildingFPrime[FTemplateParamIdx] =
1206 Context.getInjectedTemplateArg(NewParam);
1207 }
1208
1209 auto *TemplateArgListForBuildingFPrime =
1210 TemplateArgumentList::CreateCopy(Context, TemplateArgsForBuildingFPrime);
1211 // Form the f' by substituting the template arguments into f.
1212 if (auto *FPrime = SemaRef.InstantiateFunctionDeclaration(
1213 F, TemplateArgListForBuildingFPrime, AliasTemplate->getLocation(),
1215 auto *GG = cast<CXXDeductionGuideDecl>(FPrime);
1216
1217 Expr *IsDeducible = buildIsDeducibleConstraint(
1218 SemaRef, AliasTemplate, FPrime->getReturnType(), FPrimeTemplateParams);
1219 Expr *RequiresClause =
1220 buildAssociatedConstraints(SemaRef, F, AliasTemplate, DeduceResults,
1221 FirstUndeducedParamIdx, IsDeducible);
1222
1223 auto *FPrimeTemplateParamList = TemplateParameterList::Create(
1224 Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(),
1225 AliasTemplate->getTemplateParameters()->getLAngleLoc(),
1226 FPrimeTemplateParams,
1227 AliasTemplate->getTemplateParameters()->getRAngleLoc(),
1228 /*RequiresClause=*/RequiresClause);
1229 auto *Result = cast<FunctionTemplateDecl>(buildDeductionGuide(
1230 SemaRef, AliasTemplate, FPrimeTemplateParamList,
1231 GG->getCorrespondingConstructor(), GG->getExplicitSpecifier(),
1232 GG->getTypeSourceInfo(), AliasTemplate->getBeginLoc(),
1233 AliasTemplate->getLocation(), AliasTemplate->getEndLoc(),
1234 F->isImplicit()));
1235 auto *DGuide = cast<CXXDeductionGuideDecl>(Result->getTemplatedDecl());
1236 DGuide->setDeductionCandidateKind(GG->getDeductionCandidateKind());
1237 DGuide->setSourceDeductionGuide(
1238 cast<CXXDeductionGuideDecl>(F->getTemplatedDecl()));
1239 DGuide->setSourceDeductionGuideKind(
1240 CXXDeductionGuideDecl::SourceDeductionGuideKind::Alias);
1241 return Result;
1242 }
1243 return nullptr;
1244}
1245
1246void DeclareImplicitDeductionGuidesForTypeAlias(
1248 if (AliasTemplate->isInvalidDecl())
1249 return;
1250 auto &Context = SemaRef.Context;
1251 auto [Template, AliasRhsTemplateArgs] =
1252 getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
1253 if (!Template)
1254 return;
1255 auto SourceDeductionGuides = getSourceDeductionGuides(
1257 AliasTemplate->getDeclContext());
1258
1259 DeclarationNameInfo NameInfo(
1261 LookupResult Guides(SemaRef, NameInfo, clang::Sema::LookupOrdinaryName);
1262 SemaRef.LookupQualifiedName(Guides, Template->getDeclContext());
1263 Guides.suppressDiagnostics();
1264
1265 for (auto *G : Guides) {
1266 if (auto *DG = dyn_cast<CXXDeductionGuideDecl>(G)) {
1267 if (SourceDeductionGuides.contains(DG))
1268 continue;
1269 // The deduction guide is a non-template function decl, we just clone it.
1270 auto *FunctionType =
1271 SemaRef.Context.getTrivialTypeSourceInfo(DG->getType());
1273 FunctionType->getTypeLoc().castAs<FunctionProtoTypeLoc>();
1274
1275 // Clone the parameters.
1276 for (unsigned I = 0, N = DG->getNumParams(); I != N; ++I) {
1277 const auto *P = DG->getParamDecl(I);
1278 auto *TSI = SemaRef.Context.getTrivialTypeSourceInfo(P->getType());
1279 ParmVarDecl *NewParam = ParmVarDecl::Create(
1280 SemaRef.Context, G->getDeclContext(),
1281 DG->getParamDecl(I)->getBeginLoc(), P->getLocation(), nullptr,
1282 TSI->getType(), TSI, SC_None, nullptr);
1283 NewParam->setScopeInfo(0, I);
1284 FPTL.setParam(I, NewParam);
1285 }
1286 auto *Transformed = cast<CXXDeductionGuideDecl>(buildDeductionGuide(
1287 SemaRef, AliasTemplate, /*TemplateParams=*/nullptr,
1288 /*Constructor=*/nullptr, DG->getExplicitSpecifier(), FunctionType,
1289 AliasTemplate->getBeginLoc(), AliasTemplate->getLocation(),
1290 AliasTemplate->getEndLoc(), DG->isImplicit()));
1291 Transformed->setSourceDeductionGuide(DG);
1292 Transformed->setSourceDeductionGuideKind(
1293 CXXDeductionGuideDecl::SourceDeductionGuideKind::Alias);
1294
1295 // FIXME: Here the synthesized deduction guide is not a templated
1296 // function. Per [dcl.decl]p4, the requires-clause shall be present only
1297 // if the declarator declares a templated function, a bug in standard?
1298 AssociatedConstraint Constraint(buildIsDeducibleConstraint(
1299 SemaRef, AliasTemplate, Transformed->getReturnType(), {}));
1300 if (const AssociatedConstraint &RC = DG->getTrailingRequiresClause()) {
1301 auto Conjunction = SemaRef.BuildBinOp(
1302 SemaRef.getCurScope(), SourceLocation{},
1303 BinaryOperatorKind::BO_LAnd, const_cast<Expr *>(RC.ConstraintExpr),
1304 const_cast<Expr *>(Constraint.ConstraintExpr));
1305 if (!Conjunction.isInvalid()) {
1306 Constraint.ConstraintExpr = Conjunction.getAs<Expr>();
1307 Constraint.ArgPackSubstIndex = RC.ArgPackSubstIndex;
1308 }
1309 }
1310 Transformed->setTrailingRequiresClause(Constraint);
1311 continue;
1312 }
1313 FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(G);
1314 if (!F || SourceDeductionGuides.contains(F->getTemplatedDecl()))
1315 continue;
1316 // The **aggregate** deduction guides are handled in a different code path
1317 // (DeclareAggregateDeductionGuideFromInitList), which involves the tricky
1318 // cache.
1319 if (cast<CXXDeductionGuideDecl>(F->getTemplatedDecl())
1320 ->getDeductionCandidateKind() == DeductionCandidate::Aggregate)
1321 continue;
1322
1323 BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate, F, Loc);
1324 }
1325}
1326
1327// Build an aggregate deduction guide for a type alias template.
1328FunctionTemplateDecl *DeclareAggregateDeductionGuideForTypeAlias(
1331 TemplateDecl *RHSTemplate =
1332 getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate).first;
1333 if (!RHSTemplate)
1334 return nullptr;
1335
1337 llvm::SmallVector<QualType> NewParamTypes;
1338 ExtractTypeForDeductionGuide TypeAliasTransformer(SemaRef, TypedefDecls);
1339 for (QualType P : ParamTypes) {
1340 QualType Type = TypeAliasTransformer.TransformType(P);
1341 if (Type.isNull())
1342 return nullptr;
1343 NewParamTypes.push_back(Type);
1344 }
1345
1346 auto *RHSDeductionGuide = SemaRef.DeclareAggregateDeductionGuideFromInitList(
1347 RHSTemplate, NewParamTypes, Loc);
1348 if (!RHSDeductionGuide)
1349 return nullptr;
1350
1351 for (TypedefNameDecl *TD : TypedefDecls)
1352 TD->setDeclContext(RHSDeductionGuide->getTemplatedDecl());
1353
1354 return BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate,
1355 RHSDeductionGuide, Loc);
1356}
1357
1358} // namespace
1359
1363 llvm::FoldingSetNodeID ID;
1364 ID.AddPointer(Template);
1365 for (auto &T : ParamTypes)
1366 T.getCanonicalType().Profile(ID);
1367 unsigned Hash = ID.ComputeHash();
1368
1369 auto Found = AggregateDeductionCandidates.find(Hash);
1370 if (Found != AggregateDeductionCandidates.end()) {
1371 CXXDeductionGuideDecl *GD = Found->getSecond();
1372 return GD->getDescribedFunctionTemplate();
1373 }
1374
1375 if (auto *AliasTemplate = llvm::dyn_cast<TypeAliasTemplateDecl>(Template)) {
1376 if (auto *FTD = DeclareAggregateDeductionGuideForTypeAlias(
1377 *this, AliasTemplate, ParamTypes, Loc)) {
1378 auto *GD = cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl());
1379 GD->setDeductionCandidateKind(DeductionCandidate::Aggregate);
1381 return FTD;
1382 }
1383 }
1384
1385 if (CXXRecordDecl *DefRecord =
1386 cast<CXXRecordDecl>(Template->getTemplatedDecl())->getDefinition()) {
1387 if (TemplateDecl *DescribedTemplate =
1388 DefRecord->getDescribedClassTemplate())
1389 Template = DescribedTemplate;
1390 }
1391
1392 DeclContext *DC = Template->getDeclContext();
1393 if (DC->isDependentContext())
1394 return nullptr;
1395
1396 ConvertConstructorToDeductionGuideTransform Transform(
1397 *this, cast<ClassTemplateDecl>(Template));
1398 if (!isCompleteType(Loc, Transform.DeducedType))
1399 return nullptr;
1400
1401 // In case we were expanding a pack when we attempted to declare deduction
1402 // guides, turn off pack expansion for everything we're about to do.
1403 ArgPackSubstIndexRAII SubstIndex(*this, std::nullopt);
1404 // Create a template instantiation record to track the "instantiation" of
1405 // constructors into deduction guides.
1406 InstantiatingTemplate BuildingDeductionGuides(
1407 *this, Loc, Template,
1409 if (BuildingDeductionGuides.isInvalid())
1410 return nullptr;
1411
1412 ClassTemplateDecl *Pattern =
1413 Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
1414 ContextRAII SavedContext(*this, Pattern->getTemplatedDecl());
1415
1416 auto *FTD = cast<FunctionTemplateDecl>(
1417 Transform.buildSimpleDeductionGuide(ParamTypes));
1418 SavedContext.pop();
1419 auto *GD = cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl());
1420 GD->setDeductionCandidateKind(DeductionCandidate::Aggregate);
1422 return FTD;
1423}
1424
1427 if (auto *AliasTemplate = llvm::dyn_cast<TypeAliasTemplateDecl>(Template)) {
1428 DeclareImplicitDeductionGuidesForTypeAlias(*this, AliasTemplate, Loc);
1429 return;
1430 }
1431 if (CXXRecordDecl *DefRecord =
1432 cast<CXXRecordDecl>(Template->getTemplatedDecl())->getDefinition()) {
1433 if (TemplateDecl *DescribedTemplate =
1434 DefRecord->getDescribedClassTemplate())
1435 Template = DescribedTemplate;
1436 }
1437
1438 DeclContext *DC = Template->getDeclContext();
1439 if (DC->isDependentContext())
1440 return;
1441
1442 ConvertConstructorToDeductionGuideTransform Transform(
1443 *this, cast<ClassTemplateDecl>(Template));
1444 if (!isCompleteType(Loc, Transform.DeducedType))
1445 return;
1446
1447 if (hasDeclaredDeductionGuides(Transform.DeductionGuideName, DC))
1448 return;
1449
1450 // In case we were expanding a pack when we attempted to declare deduction
1451 // guides, turn off pack expansion for everything we're about to do.
1452 ArgPackSubstIndexRAII SubstIndex(*this, std::nullopt);
1453 // Create a template instantiation record to track the "instantiation" of
1454 // constructors into deduction guides.
1455 InstantiatingTemplate BuildingDeductionGuides(
1456 *this, Loc, Template,
1458 if (BuildingDeductionGuides.isInvalid())
1459 return;
1460
1461 // Convert declared constructors into deduction guide templates.
1462 // FIXME: Skip constructors for which deduction must necessarily fail (those
1463 // for which some class template parameter without a default argument never
1464 // appears in a deduced context).
1465 ClassTemplateDecl *Pattern =
1466 Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
1467 ContextRAII SavedContext(*this, Pattern->getTemplatedDecl());
1468 llvm::SmallPtrSet<NamedDecl *, 8> ProcessedCtors;
1469 bool AddedAny = false;
1470 for (NamedDecl *D : LookupConstructors(Pattern->getTemplatedDecl())) {
1471 D = D->getUnderlyingDecl();
1472 if (D->isInvalidDecl() || D->isImplicit())
1473 continue;
1474
1475 D = cast<NamedDecl>(D->getCanonicalDecl());
1476
1477 // Within C++20 modules, we may have multiple same constructors in
1478 // multiple same RecordDecls. And it doesn't make sense to create
1479 // duplicated deduction guides for the duplicated constructors.
1480 if (ProcessedCtors.count(D))
1481 continue;
1482
1483 auto *FTD = dyn_cast<FunctionTemplateDecl>(D);
1484 auto *CD =
1485 dyn_cast_or_null<CXXConstructorDecl>(FTD ? FTD->getTemplatedDecl() : D);
1486 // Class-scope explicit specializations (MS extension) do not result in
1487 // deduction guides.
1488 if (!CD || (!FTD && CD->isFunctionTemplateSpecialization()))
1489 continue;
1490
1491 // Cannot make a deduction guide when unparsed arguments are present.
1492 if (llvm::any_of(CD->parameters(), [](ParmVarDecl *P) {
1493 return !P || P->hasUnparsedDefaultArg();
1494 }))
1495 continue;
1496
1497 ProcessedCtors.insert(D);
1498 Transform.transformConstructor(FTD, CD);
1499 AddedAny = true;
1500 }
1501
1502 // C++17 [over.match.class.deduct]
1503 // -- If C is not defined or does not declare any constructors, an
1504 // additional function template derived as above from a hypothetical
1505 // constructor C().
1506 if (!AddedAny)
1507 Transform.buildSimpleDeductionGuide({});
1508
1509 // -- An additional function template derived as above from a hypothetical
1510 // constructor C(C), called the copy deduction candidate.
1511 cast<CXXDeductionGuideDecl>(
1512 cast<FunctionTemplateDecl>(
1513 Transform.buildSimpleDeductionGuide(Transform.DeducedType))
1514 ->getTemplatedDecl())
1515 ->setDeductionCandidateKind(DeductionCandidate::Copy);
1516
1517 SavedContext.pop();
1518}
Defines the clang::ASTContext interface.
StringRef P
const Decl * D
Expr * E
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
SourceLocation Loc
Definition: SemaObjC.cpp:754
Defines the clang::SourceLocation class and associated facilities.
Defines various enumerations that describe declaration and type specifiers.
Defines the clang::TypeLoc interface and its subclasses.
Defines enumerations for the type traits support.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1201
DeclarationNameTable DeclarationNames
Definition: ASTContext.h:744
CanQualType getLogicalOperationType() const
The result type of logical operations, '<', '>', '!=', etc.
Definition: ASTContext.h:2269
QualType getDecayedType(QualType T) const
Return the uniqued reference to the decayed version of the given type.
CanQualType BoolTy
Definition: ASTContext.h:1223
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl) const
QualType getTypedefType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypedefNameDecl *Decl, QualType UnderlyingType=QualType(), std::optional< bool > TypeMatchesDeclOrNone=std::nullopt) const
Return the unique reference to the type for the specified typedef-name decl.
QualType getDeducedTemplateSpecializationType(ElaboratedTypeKeyword Keyword, TemplateName Template, QualType DeducedType, bool IsDependent) const
C++17 deduced class template specialization type.
CanQualType getCanonicalTagType(const TagDecl *TD) const
PtrTy get() const
Definition: Ownership.h:171
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
Definition: Expr.cpp:4938
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2604
ExplicitSpecifier getExplicitSpecifier()
Definition: DeclCXX.h:2676
Represents a C++ deduction guide declaration.
Definition: DeclCXX.h:1979
static CXXDeductionGuideDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, SourceLocation EndLocation, CXXConstructorDecl *Ctor=nullptr, DeductionCandidate Kind=DeductionCandidate::Normal, const AssociatedConstraint &TrailingRequiresClause={}, const CXXDeductionGuideDecl *SourceDG=nullptr, SourceDeductionGuideKind SK=SourceDeductionGuideKind::None)
Definition: DeclCXX.cpp:2367
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
CXXRecordDecl * getDefinition() const
Definition: DeclCXX.h:548
Declaration of a class template.
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
ClassTemplateDecl * getInstantiatedFromMemberTemplate() const
const TypeClass * getTypePtr() const
Definition: TypeLoc.h:438
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1449
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2109
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
Definition: DeclBase.h:2238
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1358
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1879
bool isRecord() const
Definition: DeclBase.h:2189
void addDecl(Decl *D)
Add the declaration D into this context.
Definition: DeclBase.cpp:1793
Decl::Kind getDeclKind() const
Definition: DeclBase.h:2102
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
SourceLocation getEndLoc() const LLVM_READONLY
Definition: DeclBase.h:435
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:593
unsigned getTemplateDepth() const
Determine the number of levels of template parameter surrounding this declaration.
Definition: DeclBase.cpp:298
bool isInvalidDecl() const
Definition: DeclBase.h:588
SourceLocation getLocation() const
Definition: DeclBase.h:439
DeclContext * getDeclContext()
Definition: DeclBase.h:448
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
Definition: DeclBase.cpp:360
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition: DeclBase.h:918
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:978
DeclarationName getCXXDeductionGuideName(TemplateDecl *TD)
Returns the name of a C++ deduction guide for the given template.
The name of a declaration.
SourceLocation getInnerLocStart() const
Return start of source range ignoring outer template declarations.
Definition: Decl.h:821
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Decl.h:830
const AssociatedConstraint & getTrailingRequiresClause() const
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
Definition: Decl.h:854
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:808
Common base class for placeholders for types that get replaced by placeholder type deduction: C++11 a...
Definition: TypeBase.h:7146
auto * getDecl() const
Definition: TypeLoc.h:747
SourceLocation getElaboratedKeywordLoc() const
Definition: TypeLoc.h:757
SourceLocation getNameLoc() const
Definition: TypeLoc.h:766
NestedNameSpecifierLoc getQualifierLoc() const
Definition: TypeLoc.h:761
Store information needed for an explicit specifier.
Definition: DeclCXX.h:1924
This represents one expression.
Definition: Expr.h:112
Represents difference between two FPOptions values.
Definition: LangOptions.h:919
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
Definition: Decl.cpp:4146
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition: Decl.cpp:4134
QualType getReturnType() const
Definition: Decl.h:2842
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2771
Represents a prototype with parameter type info, e.g.
Definition: TypeBase.h:5282
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
Definition: Type.cpp:3991
bool isVariadic() const
Whether this function prototype is variadic.
Definition: TypeBase.h:5686
Declaration of a template function.
Definition: DeclTemplate.h:952
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
Definition: DeclTemplate.h:998
static FunctionTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
unsigned getNumParams() const
Definition: TypeLoc.h:1696
SourceLocation getLocalRangeEnd() const
Definition: TypeLoc.h:1648
void setLocalRangeBegin(SourceLocation L)
Definition: TypeLoc.h:1644
void setLParenLoc(SourceLocation Loc)
Definition: TypeLoc.h:1660
void setParam(unsigned i, ParmVarDecl *VD)
Definition: TypeLoc.h:1703
ArrayRef< ParmVarDecl * > getParams() const
Definition: TypeLoc.h:1687
void setRParenLoc(SourceLocation Loc)
Definition: TypeLoc.h:1668
void setLocalRangeEnd(SourceLocation L)
Definition: TypeLoc.h:1652
void setExceptionSpecRange(SourceRange R)
Definition: TypeLoc.h:1682
SourceLocation getLocalRangeBegin() const
Definition: TypeLoc.h:1640
SourceLocation getLParenLoc() const
Definition: TypeLoc.h:1656
SourceLocation getRParenLoc() const
Definition: TypeLoc.h:1664
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: TypeBase.h:4478
const TypeClass * getTypePtr() const
Definition: TypeLoc.h:531
The injected class name of a C++ class template or class template partial specialization.
Definition: TypeBase.h:6553
A stack-allocated class that identifies which local variable declaration instantiations are present i...
Definition: Template.h:365
void InstantiatedLocal(const Decl *D, Decl *Inst)
Represents the results of name lookup.
Definition: Lookup.h:147
Data structure that captures multiple levels of template argument lists for use in template instantia...
Definition: Template.h:76
void addOuterRetainedLevel()
Add an outermost level that we are not substituting.
Definition: Template.h:257
void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args, bool Final)
Add a new outmost level to the multi-level template argument list.
Definition: Template.h:210
void setKind(TemplateSubstitutionKind K)
Definition: Template.h:109
unsigned getNumSubstitutedLevels() const
Determine the number of substituted levels in this template argument list.
Definition: Template.h:129
void addOuterRetainedLevels(unsigned Num)
Definition: Template.h:260
This represents a decl that may have a name.
Definition: Decl.h:273
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:294
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:339
A C++ nested-name-specifier augmented with source location information.
NestedNameSpecifier getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1180
Represents a parameter to a function.
Definition: Decl.h:1789
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
Definition: Decl.h:1849
SourceRange getDefaultArgRange() const
Retrieve the source range that covers the entire default argument.
Definition: Decl.cpp:3019
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
Definition: Decl.h:1822
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Definition: Decl.cpp:2946
bool hasDefaultArg() const
Determines whether this parameter has a default argument, either parsed or not.
Definition: Decl.cpp:3050
unsigned getFunctionScopeDepth() const
Definition: Decl.h:1839
A (possibly-)qualified type.
Definition: TypeBase.h:937
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
Definition: Type.cpp:3591
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: TypeBase.h:1004
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: TypeBase.h:6502
bool isMemberSpecialization() const
Determines whether this template was a specialization of a member template.
Definition: DeclTemplate.h:852
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:41
RAII object used to change the argument pack substitution index within a Sema object.
Definition: Sema.h:13496
A RAII object to temporarily push a declaration context.
Definition: Sema.h:3468
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:850
bool SubstTypeConstraint(TemplateTypeParmDecl *Inst, const TypeConstraint *TC, const MultiLevelTemplateArgumentList &TemplateArgs, bool EvaluateConstraint)
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
Definition: Sema.h:12936
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)
Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.
Scope * getCurScope() const
Retrieve the parser's current scope.
Definition: Sema.h:1113
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition: Sema.h:9281
FunctionTemplateDecl * DeclareAggregateDeductionGuideFromInitList(TemplateDecl *Template, MutableArrayRef< QualType > ParamTypes, SourceLocation Loc)
FunctionDecl * InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD, const TemplateArgumentList *Args, SourceLocation Loc, CodeSynthesisContext::SynthesisKind CSC=CodeSynthesisContext::ExplicitTemplateArgumentSubstitution)
Instantiate (or find existing instantiation of) a function template with a given set of template argu...
ASTContext & Context
Definition: Sema.h:1276
QualType BuildFunctionType(QualType T, MutableArrayRef< QualType > ParamTypes, SourceLocation Loc, DeclarationName Entity, const FunctionProtoType::ExtProtoInfo &EPI)
Build a function type.
Definition: SemaType.cpp:2642
ExprResult SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)
ExprResult SubstConstraintExprWithoutSatisfaction(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)
ASTContext & getASTContext() const
Definition: Sema.h:918
TypeSourceInfo * SubstType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity, bool AllowDeducedTST=false)
Perform substitution on the type T with a given set of template arguments.
TemplateParameterList * GetTemplateParameterList(TemplateDecl *TD)
Returns the template parameter list with all default template argument information.
llvm::DenseMap< unsigned, CXXDeductionGuideDecl * > AggregateDeductionCandidates
Definition: Sema.h:8966
MultiLevelTemplateArgumentList getTemplateInstantiationArgs(const NamedDecl *D, const DeclContext *DC=nullptr, bool Final=false, std::optional< ArrayRef< TemplateArgument > > Innermost=std::nullopt, bool RelativeToPrimary=false, const FunctionDecl *Pattern=nullptr, bool ForConstraintInstantiation=false, bool SkipForSpecialization=false, bool ForDefaultArgumentSubstitution=false)
Retrieve the template argument list(s) that should be used to instantiate the definition of the given...
void DeclareImplicitDeductionGuides(TemplateDecl *Template, SourceLocation Loc)
Declare implicit deduction guides for a class template if we've not already done so.
Decl * SubstDecl(Decl *D, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs)
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
Definition: Sema.h:15279
bool SubstTemplateArgument(const TemplateArgumentLoc &Input, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentLoc &Output, SourceLocation Loc={}, const DeclarationName &Entity={})
void MarkUsedTemplateParameters(const Expr *E, bool OnlyDeduced, unsigned Depth, llvm::SmallBitVector &Used)
Mark which template parameters are used in a given expression.
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr, bool ForFoldExpression=false)
Definition: SemaExpr.cpp:15609
TemplateDeductionResult DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, ArrayRef< TemplateArgument > TemplateArgs, sema::TemplateDeductionInfo &Info)
DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class)
Look up the constructors for the given class.
TypeSourceInfo * CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc, UnsignedOrNone NumExpansions)
Construct a pack expansion type from the pattern of the pack expansion.
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
void setElaboratedKeywordLoc(SourceLocation Loc)
Definition: TypeLoc.h:810
A convenient class for passing around template argument information.
Definition: TemplateBase.h:634
static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument list that copies the given set of template arguments.
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:528
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:574
Represents a template argument.
Definition: TemplateBase.h:61
bool isNull() const
Determine whether this template argument has no value.
Definition: TemplateBase.h:299
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
Definition: TemplateBase.h:440
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:107
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:296
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:396
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:415
Represents a C++ template name within the type system.
Definition: TemplateName.h:222
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:74
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:146
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
Definition: DeclTemplate.h:182
SourceLocation getTemplateLoc() const
Definition: DeclTemplate.h:205
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: TypeBase.h:7290
ArrayRef< TemplateArgument > template_arguments() const
Definition: TypeBase.h:7357
Declaration of a template type parameter.
bool wasDeclaredWithTypename() const
Whether this template type parameter was declared with the 'typename' keyword.
SourceLocation getDefaultArgumentLoc() const
Retrieves the location of the default argument declaration.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
bool hasTypeConstraint() const
Determine whether this template parameter has a type-constraint.
const TypeConstraint * getTypeConstraint() const
Returns the type constraint associated with this template parameter (if any).
UnsignedOrNone getNumExpansionParameters() const
Whether this parameter is a template type parameter pack that has a known list of different type-cons...
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool isParameterPack() const
Returns whether this is a parameter pack.
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, UnsignedOrNone NumExpanded=std::nullopt)
A semantic tree transformation that allows one to transform one abstract syntax tree into another.
QualType TransformType(QualType T)
Transforms the given type into another type.
QualType RebuildTemplateSpecializationType(ElaboratedTypeKeyword Keyword, TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &Args)
Build a new template specialization type.
Derived & getDerived()
Retrieves a reference to the derived class.
static TypeAliasDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo)
Definition: Decl.cpp:5680
Declaration of an alias template.
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Decl.h:3544
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
TypeSourceInfo * getTypeSourceInfo(ASTContext &Context, QualType T)
Creates a TypeSourceInfo for the given type.
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition: TypeLoc.h:89
T castAs() const
Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type.
Definition: TypeLoc.h:78
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition: TypeLoc.h:2843
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:193
A container of type source information.
Definition: TypeBase.h:8314
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:272
QualType getType() const
Return the type wrapped by this type source info.
Definition: TypeBase.h:8325
static TypeTraitExpr * Create(const ASTContext &C, QualType T, SourceLocation Loc, TypeTrait Kind, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc, bool Value)
Create a new type trait expression.
Definition: ExprCXX.cpp:1914
The base class of the type hierarchy.
Definition: TypeBase.h:1833
bool isRValueReferenceType() const
Definition: TypeBase.h:8612
bool isArrayType() const
Definition: TypeBase.h:8679
const T * castAs() const
Member-template castAs<specific type>.
Definition: TypeBase.h:9226
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: TypeBase.h:2808
bool isLValueReferenceType() const
Definition: TypeBase.h:8608
bool isFunctionType() const
Definition: TypeBase.h:8576
const T * getAs() const
Member-template getAs<specific type>'.
Definition: TypeBase.h:9159
static TypedefDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo)
Definition: Decl.cpp:5629
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3559
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:3609
Wrapper for source info for typedefs.
Definition: TypeLoc.h:782
QualType getType() const
Definition: Decl.h:722
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition: Decl.h:1167
Provides information about an attempted template argument deduction, whose success or failure was des...
The JSON file list parser is used to communicate input to InstallAPI.
@ Rewrite
We are substituting template parameters for (typically) other template parameters in order to rewrite...
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition: Specifiers.h:151
@ AS_public
Definition: Specifiers.h:124
@ SC_None
Definition: Specifiers.h:250
std::pair< unsigned, unsigned > getDepthAndIndex(const NamedDecl *ND)
Retrieve the depth and index of a template parameter.
Definition: SemaInternal.h:62
@ Template
We are parsing a template declaration.
@ Keyword
The name has been typo-corrected to a keyword.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:135
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
Definition: Specifiers.h:144
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:139
const FunctionProtoType * T
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
Definition: TypeBase.h:5881
const Expr * ConstraintExpr
Definition: Decl.h:87
UnsignedOrNone ArgPackSubstIndex
Definition: Decl.h:88
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
Extra information about a function prototype.
Definition: TypeBase.h:5367
@ BuildingDeductionGuides
We are building deduction guides for a class.
Definition: Sema.h:13060
A stack object to be created when performing template instantiation.
Definition: Sema.h:13144