clang 23.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
58/// Return true if two associated-constraint sets are semantically equal.
59static bool HaveSameAssociatedConstraints(
60 Sema &SemaRef, const NamedDecl *Old, ArrayRef<AssociatedConstraint> OldACs,
62 if (OldACs.size() != NewACs.size())
63 return false;
64 if (OldACs.empty())
65 return true;
66
67 // General case: pairwise compare each associated constraint expression.
68 for (size_t I = 0, E = OldACs.size(); I != E; ++I)
69 if (!SemaRef.AreConstraintExpressionsEqual(Old, OldACs[I].ConstraintExpr,
70 New, NewACs[I].ConstraintExpr))
71 return false;
72
73 return true;
74}
75
76/// Tree transform to "extract" a transformed type from a class template's
77/// constructor to a deduction guide.
78class ExtractTypeForDeductionGuide
79 : public TreeTransform<ExtractTypeForDeductionGuide> {
80 llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs;
81 ClassTemplateDecl *NestedPattern;
82 const MultiLevelTemplateArgumentList *OuterInstantiationArgs;
83 std::optional<TemplateDeclInstantiator> TypedefNameInstantiator;
84
85public:
86 typedef TreeTransform<ExtractTypeForDeductionGuide> Base;
87 ExtractTypeForDeductionGuide(
88 Sema &SemaRef,
89 llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs,
90 ClassTemplateDecl *NestedPattern = nullptr,
91 const MultiLevelTemplateArgumentList *OuterInstantiationArgs = nullptr)
92 : Base(SemaRef), MaterializedTypedefs(MaterializedTypedefs),
93 NestedPattern(NestedPattern),
94 OuterInstantiationArgs(OuterInstantiationArgs) {
95 if (OuterInstantiationArgs)
96 TypedefNameInstantiator.emplace(
97 SemaRef, SemaRef.getASTContext().getTranslationUnitDecl(),
98 *OuterInstantiationArgs);
99 }
100
101 TypeSourceInfo *transform(TypeSourceInfo *TSI) { return TransformType(TSI); }
102
103 /// Returns true if it's safe to substitute \p Typedef with
104 /// \p OuterInstantiationArgs.
105 bool mightReferToOuterTemplateParameters(TypedefNameDecl *Typedef) {
106 if (!NestedPattern)
107 return false;
108
109 static auto WalkUp = [](DeclContext *DC, DeclContext *TargetDC) {
110 if (DC->Equals(TargetDC))
111 return true;
112 while (DC->isRecord()) {
113 if (DC->Equals(TargetDC))
114 return true;
115 DC = DC->getParent();
116 }
117 return false;
118 };
119
120 if (WalkUp(Typedef->getDeclContext(), NestedPattern->getTemplatedDecl()))
121 return true;
122 if (WalkUp(NestedPattern->getTemplatedDecl(), Typedef->getDeclContext()))
123 return true;
124 return false;
125 }
126
127 QualType RebuildTemplateSpecializationType(
129 SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {
130 if (!OuterInstantiationArgs ||
131 !isa_and_present<TypeAliasTemplateDecl>(Template.getAsTemplateDecl()))
133 Keyword, Template, TemplateNameLoc, TemplateArgs);
134
135 auto *TATD = cast<TypeAliasTemplateDecl>(Template.getAsTemplateDecl());
136 auto *Pattern = TATD;
137 while (Pattern->getInstantiatedFromMemberTemplate())
138 Pattern = Pattern->getInstantiatedFromMemberTemplate();
139 if (!mightReferToOuterTemplateParameters(Pattern->getTemplatedDecl()))
141 Keyword, Template, TemplateNameLoc, TemplateArgs);
142
143 Decl *NewD =
144 TypedefNameInstantiator->InstantiateTypeAliasTemplateDecl(TATD);
145 if (!NewD)
146 return QualType();
147
148 auto *NewTATD = cast<TypeAliasTemplateDecl>(NewD);
149 MaterializedTypedefs.push_back(NewTATD->getTemplatedDecl());
150
152 Keyword, TemplateName(NewTATD), TemplateNameLoc, TemplateArgs);
153 }
154
155 QualType TransformTypedefType(TypeLocBuilder &TLB, TypedefTypeLoc TL) {
156 ASTContext &Context = SemaRef.getASTContext();
157 TypedefNameDecl *OrigDecl = TL.getDecl();
158 TypedefNameDecl *Decl = OrigDecl;
159 const TypedefType *T = TL.getTypePtr();
160 // Transform the underlying type of the typedef and clone the Decl only if
161 // the typedef has a dependent context.
162 bool InDependentContext = OrigDecl->getDeclContext()->isDependentContext();
163
164 // A typedef/alias Decl within the NestedPattern may reference the outer
165 // template parameters. They're substituted with corresponding instantiation
166 // arguments here and in RebuildTemplateSpecializationType() above.
167 // Otherwise, we would have a CTAD guide with "dangling" template
168 // parameters.
169 // For example,
170 // template <class T> struct Outer {
171 // using Alias = S<T>;
172 // template <class U> struct Inner {
173 // Inner(Alias);
174 // };
175 // };
176 if (OuterInstantiationArgs && InDependentContext &&
178 Decl = cast_if_present<TypedefNameDecl>(
179 TypedefNameInstantiator->InstantiateTypedefNameDecl(
180 OrigDecl, /*IsTypeAlias=*/isa<TypeAliasDecl>(OrigDecl)));
181 if (!Decl)
182 return QualType();
183 MaterializedTypedefs.push_back(Decl);
184 } else if (InDependentContext) {
185 TypeLocBuilder InnerTLB;
186 QualType Transformed =
187 TransformType(InnerTLB, OrigDecl->getTypeSourceInfo()->getTypeLoc());
188 TypeSourceInfo *TSI = InnerTLB.getTypeSourceInfo(Context, Transformed);
189 if (isa<TypeAliasDecl>(OrigDecl))
191 Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
192 OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
193 else {
194 assert(isa<TypedefDecl>(OrigDecl) && "Not a Type alias or typedef");
196 Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
197 OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
198 }
199 MaterializedTypedefs.push_back(Decl);
200 }
201
202 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
203 if (QualifierLoc) {
204 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
205 if (!QualifierLoc)
206 return QualType();
207 }
208
209 QualType TDTy = Context.getTypedefType(
210 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), Decl);
211 TLB.push<TypedefTypeLoc>(TDTy).set(TL.getElaboratedKeywordLoc(),
212 QualifierLoc, TL.getNameLoc());
213 return TDTy;
214 }
215};
216
217// Build a deduction guide using the provided information.
218//
219// A deduction guide can be either a template or a non-template function
220// declaration. If \p TemplateParams is null, a non-template function
221// declaration will be created.
223buildDeductionGuide(Sema &SemaRef, TemplateDecl *OriginalTemplate,
224 TemplateParameterList *TemplateParams,
226 TypeSourceInfo *TInfo, SourceLocation LocStart,
227 SourceLocation Loc, SourceLocation LocEnd, bool IsImplicit,
228 llvm::ArrayRef<TypedefNameDecl *> MaterializedTypedefs = {},
229 const AssociatedConstraint &FunctionTrailingRC = {}) {
230 DeclContext *DC = OriginalTemplate->getDeclContext();
231 auto DeductionGuideName =
233 OriginalTemplate);
234
235 DeclarationNameInfo Name(DeductionGuideName, Loc);
237 TInfo->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams();
238
239 // Build the implicit deduction guide template.
240 QualType GuideType = TInfo->getType();
241
242 // In CUDA/HIP mode, avoid duplicate implicit guides that differ only in CUDA
243 // target attributes (same constructor signature and constraints).
244 if (IsImplicit && Ctor && SemaRef.getLangOpts().CUDA) {
246 Ctor->getAssociatedConstraints(NewACs);
247
248 for (NamedDecl *Existing : DC->lookup(DeductionGuideName)) {
249 auto *ExistingFT = dyn_cast<FunctionTemplateDecl>(Existing);
250 auto *ExistingGuide =
251 ExistingFT
252 ? dyn_cast<CXXDeductionGuideDecl>(ExistingFT->getTemplatedDecl())
253 : dyn_cast<CXXDeductionGuideDecl>(Existing);
254 if (!ExistingGuide)
255 continue;
256
257 // Only consider guides that were also synthesized from a constructor.
258 auto *ExistingCtor = ExistingGuide->getCorrespondingConstructor();
259 if (!ExistingCtor)
260 continue;
261
262 // If the underlying constructors are overloads (different signatures once
263 // CUDA attributes are ignored), they should each get their own guides.
264 if (SemaRef.IsOverload(Ctor, ExistingCtor,
265 /*UseMemberUsingDeclRules=*/false,
266 /*ConsiderCudaAttrs=*/false))
267 continue;
268
269 // At this point, the constructors have the same signature ignoring CUDA
270 // attributes. Decide whether their associated constraints are also the
271 // same; only in that case do we treat one guide as a duplicate of the
272 // other.
274 ExistingCtor->getAssociatedConstraints(ExistingACs);
275
276 if (HaveSameAssociatedConstraints(SemaRef, ExistingCtor, ExistingACs,
277 Ctor, NewACs))
278 return ExistingGuide;
279 }
280 }
281
282 auto *Guide = CXXDeductionGuideDecl::Create(
283 SemaRef.Context, DC, LocStart, ES, Name, GuideType, TInfo, LocEnd, Ctor,
284 DeductionCandidate::Normal, FunctionTrailingRC);
285 Guide->setImplicit(IsImplicit);
286 Guide->setParams(Params);
287
288 for (auto *Param : Params)
289 Param->setDeclContext(Guide);
290 for (auto *TD : MaterializedTypedefs)
291 TD->setDeclContext(Guide);
292 if (isa<CXXRecordDecl>(DC))
293 Guide->setAccess(AS_public);
294
295 if (!TemplateParams) {
296 DC->addDecl(Guide);
297 return Guide;
298 }
299
300 auto *GuideTemplate = FunctionTemplateDecl::Create(
301 SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide);
302 GuideTemplate->setImplicit(IsImplicit);
303 Guide->setDescribedFunctionTemplate(GuideTemplate);
304
305 if (isa<CXXRecordDecl>(DC))
306 GuideTemplate->setAccess(AS_public);
307
308 DC->addDecl(GuideTemplate);
309 return Guide;
310}
311
312// Transform a given template type parameter `TTP`.
314transformTemplateParam(Sema &SemaRef, DeclContext *DC,
316 MultiLevelTemplateArgumentList &Args, unsigned NewDepth,
317 unsigned NewIndex, bool EvaluateConstraint) {
318 // TemplateTypeParmDecl's index cannot be changed after creation, so
319 // substitute it directly.
320 auto *NewTTP = TemplateTypeParmDecl::Create(
321 SemaRef.Context, DC, TTP->getBeginLoc(), TTP->getLocation(), NewDepth,
322 NewIndex, TTP->getIdentifier(), TTP->wasDeclaredWithTypename(),
323 TTP->isParameterPack(), TTP->hasTypeConstraint(),
325 if (const auto *TC = TTP->getTypeConstraint())
326 SemaRef.SubstTypeConstraint(NewTTP, TC, Args,
327 /*EvaluateConstraint=*/EvaluateConstraint);
328 if (TTP->hasDefaultArgument()) {
329 TemplateArgumentLoc InstantiatedDefaultArg;
330 if (!SemaRef.SubstTemplateArgument(
331 TTP->getDefaultArgument(), Args, InstantiatedDefaultArg,
332 TTP->getDefaultArgumentLoc(), TTP->getDeclName()))
333 NewTTP->setDefaultArgument(SemaRef.Context, InstantiatedDefaultArg);
334 }
335 SemaRef.CurrentInstantiationScope->InstantiatedLocal(TTP, NewTTP);
336 return NewTTP;
337}
338
340transformTemplateParam(Sema &SemaRef, DeclContext *DC,
341 NonTypeTemplateParmDecl *TTP, unsigned NewDepth,
342 unsigned NewIndex,
345 if (TTP->isExpandedParameterPack()) {
346 SmallVector<TypeSourceInfo *, 4> ExpandedTypeSourceInfos(
347 TTP->getNumExpansionTypes());
349 for (unsigned I = 0, N = TTP->getNumExpansionTypes(); I != N; ++I) {
350 TypeSourceInfo *NewTSI =
351 SemaRef.SubstType(TTP->getExpansionTypeSourceInfo(I), Args,
352 TTP->getLocation(), TTP->getDeclName());
353 assert(NewTSI);
354
355 QualType NewT =
356 SemaRef.CheckNonTypeTemplateParameterType(NewTSI, TTP->getLocation());
357 assert(!NewT.isNull());
358
359 ExpandedTypeSourceInfos[I] = NewTSI;
360 ExpandedTypes[I] = NewT;
361 }
363 SemaRef.Context, DC, TTP->getBeginLoc(), TTP->getLocation(), NewDepth,
364 NewIndex, TTP->getIdentifier(), TTP->getType(),
365 TTP->getTypeSourceInfo(), ExpandedTypes, ExpandedTypeSourceInfos);
366 } else {
367 TypeSourceInfo *NewTSI = SemaRef.SubstType(
368 TTP->getTypeSourceInfo(), Args, TTP->getLocation(), TTP->getDeclName());
369 assert(NewTSI);
370
371 QualType NewT =
372 SemaRef.CheckNonTypeTemplateParameterType(NewTSI, TTP->getLocation());
373 assert(!NewT.isNull());
374
376 SemaRef.Context, DC, TTP->getBeginLoc(), TTP->getLocation(), NewDepth,
377 NewIndex, TTP->getIdentifier(), NewT, TTP->isParameterPack(), NewTSI);
378 }
379
380 if (TypeSourceInfo *TSI = TTP->getTypeSourceInfo();
382 if (AutoLoc.isConstrained()) {
383 SourceLocation EllipsisLoc;
384 if (TTP->isExpandedParameterPack())
385 EllipsisLoc =
386 TSI->getTypeLoc().getAs<PackExpansionTypeLoc>().getEllipsisLoc();
387 else if (auto *Constraint = dyn_cast_if_present<CXXFoldExpr>(
389 EllipsisLoc = Constraint->getEllipsisLoc();
390 // Note: We attach the non-instantiated constraint here, so that it can be
391 // instantiated relative to the top level, like all our other
392 // constraints.
393 if (SemaRef.AttachTypeConstraint(AutoLoc, /*NewConstrainedParm=*/NewTTP,
394 /*OrigConstrainedParm=*/TTP,
395 EllipsisLoc))
396 llvm_unreachable("unexpected failure attaching type constraint");
397 }
398 }
399
400 NewTTP->setAccess(AS_public);
401 NewTTP->setImplicit(TTP->isImplicit());
402
403 if (TTP->hasDefaultArgument()) {
404 TemplateArgumentLoc InstantiatedDefaultArg;
405 if (!SemaRef.SubstTemplateArgument(
406 TTP->getDefaultArgument(), Args, InstantiatedDefaultArg,
407 TTP->getDefaultArgumentLoc(), TTP->getDeclName()))
408 NewTTP->setDefaultArgument(SemaRef.Context, InstantiatedDefaultArg);
409 }
410
411 SemaRef.CurrentInstantiationScope->InstantiatedLocal(TTP, NewTTP);
412 return NewTTP;
413}
414
416transformTemplateParameters(Sema &SemaRef, DeclContext *DC,
419 unsigned NewDepth, bool EvaluateConstraint);
420
422transformTemplateParam(Sema &SemaRef, DeclContext *DC,
423 TemplateTemplateParmDecl *TTP, unsigned NewDepth,
424 unsigned NewIndex, MultiLevelTemplateArgumentList &Args,
425 bool EvaluateConstraint) {
427 if (TTP->isExpandedParameterPack()) {
430 for (unsigned I = 0, N = TTP->getNumExpansionTemplateParameters(); I != N;
431 ++I)
432 ExpandedTPLs[I] = transformTemplateParameters(
433 SemaRef, DC, TTP->getExpansionTemplateParameters(I), Args,
434 NewDepth + 1, EvaluateConstraint);
436 SemaRef.Context, DC, TTP->getLocation(), NewDepth, NewIndex,
439 ExpandedTPLs);
440 } else {
441 TemplateParameterList *NewTPL =
442 transformTemplateParameters(SemaRef, DC, TTP->getTemplateParameters(),
443 Args, NewDepth + 1, EvaluateConstraint);
445 SemaRef.Context, DC, TTP->getLocation(), NewDepth, NewIndex,
446 TTP->isParameterPack(), TTP->getIdentifier(),
447 TTP->templateParameterKind(), TTP->wasDeclaredWithTypename(), NewTPL);
448 }
449
450 NewTTP->setAccess(AS_public);
451 NewTTP->setImplicit(TTP->isImplicit());
452
453 if (TTP->hasDefaultArgument()) {
454 TemplateArgumentLoc InstantiatedDefaultArg;
455 if (!SemaRef.SubstTemplateArgument(
456 TTP->getDefaultArgument(), Args, InstantiatedDefaultArg,
457 TTP->getDefaultArgumentLoc(), TTP->getDeclName()))
458 NewTTP->setDefaultArgument(SemaRef.Context, InstantiatedDefaultArg);
459 }
460
461 SemaRef.CurrentInstantiationScope->InstantiatedLocal(TTP, NewTTP);
462 return NewTTP;
463}
464
465NamedDecl *transformTemplateParameter(Sema &SemaRef, DeclContext *DC,
468 unsigned NewIndex, unsigned NewDepth,
469 bool EvaluateConstraint = true) {
470 if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
471 return transformTemplateParam(SemaRef, DC, TTP, Args, NewDepth, NewIndex,
472 EvaluateConstraint);
473 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
474 return transformTemplateParam(SemaRef, DC, NTTP, NewDepth, NewIndex, Args);
475 if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
476 return transformTemplateParam(SemaRef, DC, TTP, NewDepth, NewIndex, Args,
477 EvaluateConstraint);
478 llvm_unreachable("Unhandled template parameter types");
479}
480
482transformTemplateParameters(Sema &SemaRef, DeclContext *DC,
485 unsigned NewDepth, bool EvaluateConstraint) {
486 SmallVector<NamedDecl *, 4> Params(TPL->size());
487 for (unsigned I = 0, E = TPL->size(); I < E; ++I) {
488 Params[I] = transformTemplateParameter(SemaRef, DC, TPL->getParam(I), Args,
489 /*NewIndex=*/I, NewDepth,
490 EvaluateConstraint);
491 }
493 SemaRef.Context, TPL->getTemplateLoc(), TPL->getLAngleLoc(), Params,
494 TPL->getRAngleLoc(), TPL->getRequiresClause());
495}
496
497/// Transform to convert portions of a constructor declaration into the
498/// corresponding deduction guide, per C++1z [over.match.class.deduct]p1.
499struct ConvertConstructorToDeductionGuideTransform {
500 ConvertConstructorToDeductionGuideTransform(Sema &S,
501 ClassTemplateDecl *Template)
502 : SemaRef(S), Template(Template) {
503 // If the template is nested, then we need to use the original
504 // pattern to iterate over the constructors.
505 // FIXME: Should this just use getTemplateInstantiationPattern?
506 ClassTemplateDecl *Pattern = Template;
507 while (Pattern->getInstantiatedFromMemberTemplate()) {
508 if (Pattern->isMemberSpecialization())
509 break;
510 Pattern = Pattern->getInstantiatedFromMemberTemplate();
511 NestedPattern = Pattern;
512 }
513 if (NestedPattern)
514 OuterInstantiationArgs = SemaRef.getTemplateInstantiationArgs(
515 Decl::castFromDeclContext(Template->getDeclContext()));
516 }
517
518 Sema &SemaRef;
519 ClassTemplateDecl *Template;
520 ClassTemplateDecl *NestedPattern = nullptr;
521
522 DeclContext *DC = Template->getDeclContext();
523 CXXRecordDecl *Primary = Template->getTemplatedDecl();
524 DeclarationName DeductionGuideName =
525 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(Template);
526
527 QualType DeducedType = SemaRef.Context.getCanonicalTagType(Primary);
528
529 // Index adjustment to apply to convert depth-1 template parameters into
530 // depth-0 template parameters.
531 unsigned Depth1IndexAdjustment = Template->getTemplateParameters()->size();
532
533 // Instantiation arguments for the outermost depth-1 templates
534 // when the template is nested
535 MultiLevelTemplateArgumentList OuterInstantiationArgs;
536
537 /// Transform a constructor declaration into a deduction guide.
538 NamedDecl *transformConstructor(FunctionTemplateDecl *FTD,
539 CXXConstructorDecl *CD) {
540 SmallVector<TemplateArgument, 16> SubstArgs;
541
542 LocalInstantiationScope Scope(SemaRef);
543
544 // C++ [over.match.class.deduct]p1:
545 // -- For each constructor of the class template designated by the
546 // template-name, a function template with the following properties:
547
548 // -- The template parameters are the template parameters of the class
549 // template followed by the template parameters (including default
550 // template arguments) of the constructor, if any.
551 TemplateParameterList *TemplateParams =
552 SemaRef.GetTemplateParameterList(Template);
553 SmallVector<TemplateArgument, 16> Depth1Args;
554 AssociatedConstraint OuterRC(TemplateParams->getRequiresClause());
555 if (FTD) {
556 TemplateParameterList *InnerParams = FTD->getTemplateParameters();
557 SmallVector<NamedDecl *, 16> AllParams;
558 AllParams.reserve(TemplateParams->size() + InnerParams->size());
559 AllParams.insert(AllParams.begin(), TemplateParams->begin(),
560 TemplateParams->end());
561 SubstArgs.reserve(InnerParams->size());
562 Depth1Args.reserve(InnerParams->size());
563
564 // Later template parameters could refer to earlier ones, so build up
565 // a list of substituted template arguments as we go.
566 for (NamedDecl *Param : *InnerParams) {
567 MultiLevelTemplateArgumentList Args;
568 Args.setKind(TemplateSubstitutionKind::Rewrite);
569 Args.addOuterTemplateArguments(Depth1Args);
571 if (NestedPattern)
572 Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
573 auto [Depth, Index] = getDepthAndIndex(Param);
574 // Depth can be 0 if FTD belongs to a non-template class/a class
575 // template specialization with an empty template parameter list. In
576 // that case, we don't want the NewDepth to overflow, and it should
577 // remain 0.
578 NamedDecl *NewParam = transformTemplateParameter(
579 SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment,
580 Depth ? Depth - 1 : 0);
581 if (!NewParam)
582 return nullptr;
583 // Constraints require that we substitute depth-1 arguments
584 // to match depths when substituted for evaluation later
585 Depth1Args.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam));
586
587 if (NestedPattern) {
588 auto [Depth, Index] = getDepthAndIndex(NewParam);
589 NewParam = transformTemplateParameter(
590 SemaRef, DC, NewParam, OuterInstantiationArgs, Index,
591 Depth - OuterInstantiationArgs.getNumSubstitutedLevels(),
592 /*EvaluateConstraint=*/false);
593 }
594
595 assert(getDepthAndIndex(NewParam).first == 0 &&
596 "Unexpected template parameter depth");
597
598 AllParams.push_back(NewParam);
599 SubstArgs.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam));
600 }
601
602 // Substitute new template parameters into requires-clause if present.
603 Expr *RequiresClause = nullptr;
604 if (Expr *InnerRC = InnerParams->getRequiresClause()) {
605 MultiLevelTemplateArgumentList Args;
606 Args.setKind(TemplateSubstitutionKind::Rewrite);
607 Args.addOuterTemplateArguments(Depth1Args);
609 if (NestedPattern)
610 Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
611 ExprResult E =
612 SemaRef.SubstConstraintExprWithoutSatisfaction(InnerRC, Args);
613 if (!E.isUsable())
614 return nullptr;
615 RequiresClause = E.get();
616 }
617
618 TemplateParams = TemplateParameterList::Create(
619 SemaRef.Context, InnerParams->getTemplateLoc(),
620 InnerParams->getLAngleLoc(), AllParams, InnerParams->getRAngleLoc(),
621 RequiresClause);
622 }
623
624 // If we built a new template-parameter-list, track that we need to
625 // substitute references to the old parameters into references to the
626 // new ones.
627 MultiLevelTemplateArgumentList Args;
628 Args.setKind(TemplateSubstitutionKind::Rewrite);
629 if (FTD) {
630 Args.addOuterTemplateArguments(SubstArgs);
632 }
633
634 FunctionProtoTypeLoc FPTL = CD->getTypeSourceInfo()
635 ->getTypeLoc()
636 .getAsAdjusted<FunctionProtoTypeLoc>();
637 assert(FPTL && "no prototype for constructor declaration");
638
639 // Transform the type of the function, adjusting the return type and
640 // replacing references to the old parameters with references to the
641 // new ones.
642 TypeLocBuilder TLB;
643 SmallVector<ParmVarDecl *, 8> Params;
644 SmallVector<TypedefNameDecl *, 4> MaterializedTypedefs;
645 QualType NewType = transformFunctionProtoType(TLB, FPTL, Params, Args,
646 MaterializedTypedefs);
647 if (NewType.isNull())
648 return nullptr;
649 TypeSourceInfo *NewTInfo = TLB.getTypeSourceInfo(SemaRef.Context, NewType);
650
651 // At this point, the function parameters are already 'instantiated' in the
652 // current scope. Substitute into the constructor's trailing
653 // requires-clause, if any.
654 AssociatedConstraint FunctionTrailingRC;
655 if (const AssociatedConstraint &RC = CD->getTrailingRequiresClause()) {
656 MultiLevelTemplateArgumentList Args;
657 Args.setKind(TemplateSubstitutionKind::Rewrite);
658 Args.addOuterTemplateArguments(Depth1Args);
660 if (NestedPattern)
661 Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth());
662 ExprResult E = SemaRef.SubstConstraintExprWithoutSatisfaction(
663 const_cast<Expr *>(RC.ConstraintExpr), Args);
664 if (!E.isUsable())
665 return nullptr;
666 FunctionTrailingRC = AssociatedConstraint(E.get(), RC.ArgPackSubstIndex);
667 }
668
669 // C++ [over.match.class.deduct]p1:
670 // If C is defined, for each constructor of C, a function template with
671 // the following properties:
672 // [...]
673 // - The associated constraints are the conjunction of the associated
674 // constraints of C and the associated constraints of the constructor, if
675 // any.
676 if (OuterRC) {
677 // The outer template parameters are not transformed, so their
678 // associated constraints don't need substitution.
679 // FIXME: Should simply add another field for the OuterRC, instead of
680 // combining them like this.
681 if (!FunctionTrailingRC)
682 FunctionTrailingRC = OuterRC;
683 else
684 FunctionTrailingRC = AssociatedConstraint(
686 SemaRef.Context,
687 /*lhs=*/const_cast<Expr *>(OuterRC.ConstraintExpr),
688 /*rhs=*/const_cast<Expr *>(FunctionTrailingRC.ConstraintExpr),
689 BO_LAnd, SemaRef.Context.BoolTy, VK_PRValue, OK_Ordinary,
690 TemplateParams->getTemplateLoc(), FPOptionsOverride()),
691 FunctionTrailingRC.ArgPackSubstIndex);
692 }
693
694 return buildDeductionGuide(
695 SemaRef, Template, TemplateParams, CD, CD->getExplicitSpecifier(),
696 NewTInfo, CD->getBeginLoc(), CD->getLocation(), CD->getEndLoc(),
697 /*IsImplicit=*/true, MaterializedTypedefs, FunctionTrailingRC);
698 }
699
700 /// Build a deduction guide with the specified parameter types.
701 CXXDeductionGuideDecl *
702 buildSimpleDeductionGuide(MutableArrayRef<QualType> ParamTypes) {
703 SourceLocation Loc = Template->getLocation();
704
705 // Build the requested type.
706 FunctionProtoType::ExtProtoInfo EPI;
707 EPI.HasTrailingReturn = true;
708 QualType Result = SemaRef.BuildFunctionType(DeducedType, ParamTypes, Loc,
709 DeductionGuideName, EPI);
710 TypeSourceInfo *TSI = SemaRef.Context.getTrivialTypeSourceInfo(Result, Loc);
711 if (NestedPattern)
712 TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,
713 DeductionGuideName);
714
715 if (!TSI)
716 return nullptr;
717
718 FunctionProtoTypeLoc FPTL =
719 TSI->getTypeLoc().castAs<FunctionProtoTypeLoc>();
720
721 // Build the parameters, needed during deduction / substitution.
722 SmallVector<ParmVarDecl *, 4> Params;
723 for (auto T : ParamTypes) {
724 auto *TSI = SemaRef.Context.getTrivialTypeSourceInfo(T, Loc);
725 if (NestedPattern)
726 TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,
727 DeclarationName());
728 if (!TSI)
729 return nullptr;
730
731 ParmVarDecl *NewParam =
732 ParmVarDecl::Create(SemaRef.Context, DC, Loc, Loc, nullptr,
733 TSI->getType(), TSI, SC_None, nullptr);
734 NewParam->setScopeInfo(0, Params.size());
735 FPTL.setParam(Params.size(), NewParam);
736 Params.push_back(NewParam);
737 }
738
739 return buildDeductionGuide(
740 SemaRef, Template, SemaRef.GetTemplateParameterList(Template), nullptr,
741 ExplicitSpecifier(), TSI, Loc, Loc, Loc, /*IsImplicit=*/true);
742 }
743
744private:
745 QualType transformFunctionProtoType(
746 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL,
747 SmallVectorImpl<ParmVarDecl *> &Params,
748 MultiLevelTemplateArgumentList &Args,
749 SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs) {
750 SmallVector<QualType, 4> ParamTypes;
751 const FunctionProtoType *T = TL.getTypePtr();
752
753 // -- The types of the function parameters are those of the constructor.
754 for (auto *OldParam : TL.getParams()) {
755 ParmVarDecl *NewParam = OldParam;
756 // Given
757 // template <class T> struct C {
758 // template <class U> struct D {
759 // template <class V> D(U, V);
760 // };
761 // };
762 // First, transform all the references to template parameters that are
763 // defined outside of the surrounding class template. That is T in the
764 // above example.
765 if (NestedPattern) {
766 NewParam = transformFunctionTypeParam(
767 NewParam, OuterInstantiationArgs, MaterializedTypedefs,
768 /*TransformingOuterPatterns=*/true);
769 if (!NewParam)
770 return QualType();
771 }
772 // Then, transform all the references to template parameters that are
773 // defined at the class template and the constructor. In this example,
774 // they're U and V, respectively.
775 NewParam =
776 transformFunctionTypeParam(NewParam, Args, MaterializedTypedefs,
777 /*TransformingOuterPatterns=*/false);
778 if (!NewParam)
779 return QualType();
780 ParamTypes.push_back(NewParam->getType());
781 Params.push_back(NewParam);
782 }
783
784 // -- The return type is the class template specialization designated by
785 // the template-name and template arguments corresponding to the
786 // template parameters obtained from the class template.
787 //
788 // We use the injected-class-name type of the primary template instead.
789 // This has the convenient property that it is different from any type that
790 // the user can write in a deduction-guide (because they cannot enter the
791 // context of the template), so implicit deduction guides can never collide
792 // with explicit ones.
793 QualType ReturnType = DeducedType;
794 auto TTL = TLB.push<TagTypeLoc>(ReturnType);
795 TTL.setElaboratedKeywordLoc(SourceLocation());
796 TTL.setQualifierLoc(NestedNameSpecifierLoc());
797 TTL.setNameLoc(Primary->getLocation());
798
799 // Resolving a wording defect, we also inherit the variadicness of the
800 // constructor.
801 FunctionProtoType::ExtProtoInfo EPI;
802 EPI.Variadic = T->isVariadic();
803 EPI.HasTrailingReturn = true;
804
805 QualType Result = SemaRef.BuildFunctionType(
806 ReturnType, ParamTypes, TL.getBeginLoc(), DeductionGuideName, EPI);
807 if (Result.isNull())
808 return QualType();
809
810 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
812 NewTL.setLParenLoc(TL.getLParenLoc());
813 NewTL.setRParenLoc(TL.getRParenLoc());
814 NewTL.setExceptionSpecRange(SourceRange());
816 for (unsigned I = 0, E = NewTL.getNumParams(); I != E; ++I)
817 NewTL.setParam(I, Params[I]);
818
819 return Result;
820 }
821
822 ParmVarDecl *transformFunctionTypeParam(
823 ParmVarDecl *OldParam, MultiLevelTemplateArgumentList &Args,
824 llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs,
825 bool TransformingOuterPatterns) {
826 TypeSourceInfo *OldTSI = OldParam->getTypeSourceInfo();
827 TypeSourceInfo *NewTSI;
828 if (auto PackTL = OldTSI->getTypeLoc().getAs<PackExpansionTypeLoc>()) {
829 // Expand out the one and only element in each inner pack.
830 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, 0u);
831 NewTSI =
832 SemaRef.SubstType(PackTL.getPatternLoc(), Args,
833 OldParam->getLocation(), OldParam->getDeclName());
834 if (!NewTSI)
835 return nullptr;
836 NewTSI =
837 SemaRef.CheckPackExpansion(NewTSI, PackTL.getEllipsisLoc(),
838 PackTL.getTypePtr()->getNumExpansions());
839 } else
840 NewTSI = SemaRef.SubstType(OldTSI, Args, OldParam->getLocation(),
841 OldParam->getDeclName());
842 if (!NewTSI)
843 return nullptr;
844
845 // Extract the type. This (for instance) replaces references to typedef
846 // members of the current instantiations with the definitions of those
847 // typedefs, avoiding triggering instantiation of the deduced type during
848 // deduction.
849 NewTSI = ExtractTypeForDeductionGuide(
850 SemaRef, MaterializedTypedefs, NestedPattern,
851 TransformingOuterPatterns ? &Args : nullptr)
852 .transform(NewTSI);
853 if (!NewTSI)
854 return nullptr;
855 // Resolving a wording defect, we also inherit default arguments from the
856 // constructor.
857 ExprResult NewDefArg;
858 if (OldParam->hasDefaultArg()) {
859 // We don't care what the value is (we won't use it); just create a
860 // placeholder to indicate there is a default argument.
861 QualType ParamTy = NewTSI->getType();
862 NewDefArg = new (SemaRef.Context)
863 OpaqueValueExpr(OldParam->getDefaultArgRange().getBegin(),
864 ParamTy.getNonLValueExprType(SemaRef.Context),
866 : ParamTy->isRValueReferenceType() ? VK_XValue
867 : VK_PRValue);
868 }
869 // Handle arrays and functions decay.
870 auto NewType = NewTSI->getType();
871 if (NewType->isArrayType() || NewType->isFunctionType())
872 NewType = SemaRef.Context.getDecayedType(NewType);
873
874 ParmVarDecl *NewParam = ParmVarDecl::Create(
875 SemaRef.Context, DC, OldParam->getInnerLocStart(),
876 OldParam->getLocation(), OldParam->getIdentifier(), NewType, NewTSI,
877 OldParam->getStorageClass(), NewDefArg.get());
878 NewParam->setScopeInfo(OldParam->getFunctionScopeDepth(),
879 OldParam->getFunctionScopeIndex());
880 SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam);
881 return NewParam;
882 }
883};
884
885// Find all template parameters that appear in the given DeducedArgs.
886// Return the indices of the template parameters in the TemplateParams.
887SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
888 Sema &SemaRef, const TemplateParameterList *TemplateParamsList,
889 ArrayRef<TemplateArgument> DeducedArgs) {
890
891 llvm::SmallBitVector ReferencedTemplateParams(TemplateParamsList->size());
893 DeducedArgs, TemplateParamsList->getDepth(), ReferencedTemplateParams);
894
895 auto MarkDefaultArgs = [&](auto *Param) {
896 if (!Param->hasDefaultArgument())
897 return;
899 Param->getDefaultArgument().getArgument(),
900 TemplateParamsList->getDepth(), ReferencedTemplateParams);
901 };
902
903 for (unsigned Index = 0; Index < TemplateParamsList->size(); ++Index) {
904 if (!ReferencedTemplateParams[Index])
905 continue;
906 auto *Param = TemplateParamsList->getParam(Index);
907 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param))
908 MarkDefaultArgs(TTPD);
909 else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param))
910 MarkDefaultArgs(NTTPD);
911 else
912 MarkDefaultArgs(cast<TemplateTemplateParmDecl>(Param));
913 }
914
915 SmallVector<unsigned> Results;
916 for (unsigned Index = 0; Index < TemplateParamsList->size(); ++Index) {
917 if (ReferencedTemplateParams[Index])
918 Results.push_back(Index);
919 }
920 return Results;
921}
922
923bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) {
924 // Check whether we've already declared deduction guides for this template.
925 // FIXME: Consider storing a flag on the template to indicate this.
926 assert(Name.getNameKind() ==
928 "name must be a deduction guide name");
929 auto Existing = DC->lookup(Name);
930 for (auto *D : Existing)
931 if (D->isImplicit())
932 return true;
933 return false;
934}
935
936// Returns all source deduction guides associated with the declared
937// deduction guides that have the specified deduction guide name.
938llvm::DenseSet<const NamedDecl *> getSourceDeductionGuides(DeclarationName Name,
939 DeclContext *DC) {
940 assert(Name.getNameKind() ==
942 "name must be a deduction guide name");
943 llvm::DenseSet<const NamedDecl *> Result;
944 for (auto *D : DC->lookup(Name)) {
945 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
946 D = FTD->getTemplatedDecl();
947
948 if (const auto *GD = dyn_cast<CXXDeductionGuideDecl>(D)) {
949 assert(GD->getSourceDeductionGuide() &&
950 "deduction guide for alias template must have a source deduction "
951 "guide");
952 Result.insert(GD->getSourceDeductionGuide());
953 }
954 }
955 return Result;
956}
957
958// Build the associated constraints for the alias deduction guides.
959// C++ [over.match.class.deduct]p3.3:
960// The associated constraints ([temp.constr.decl]) are the conjunction of the
961// associated constraints of g and a constraint that is satisfied if and only
962// if the arguments of A are deducible (see below) from the return type.
963//
964// The return result is expected to be the require-clause for the synthesized
965// alias deduction guide.
966Expr *
967buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F,
970 unsigned FirstUndeducedParamIdx, Expr *IsDeducible) {
972 if (!RC)
973 return IsDeducible;
974
975 ASTContext &Context = SemaRef.Context;
977
978 // In the clang AST, constraint nodes are deliberately not instantiated unless
979 // they are actively being evaluated. Consequently, occurrences of template
980 // parameters in the require-clause expression have a subtle "depth"
981 // difference compared to normal occurrences in places, such as function
982 // parameters. When transforming the require-clause, we must take this
983 // distinction into account:
984 //
985 // 1) In the transformed require-clause, occurrences of template parameters
986 // must use the "uninstantiated" depth;
987 // 2) When substituting on the require-clause expr of the underlying
988 // deduction guide, we must use the entire set of template argument lists;
989 //
990 // It's important to note that we're performing this transformation on an
991 // *instantiated* AliasTemplate.
992
993 // For 1), if the alias template is nested within a class template, we
994 // calcualte the 'uninstantiated' depth by adding the substitution level back.
995 unsigned AdjustDepth = 0;
996 if (auto *PrimaryTemplate =
997 AliasTemplate->getInstantiatedFromMemberTemplate())
998 AdjustDepth = PrimaryTemplate->getTemplateDepth();
999
1000 // We rebuild all template parameters with the uninstantiated depth, and
1001 // build template arguments refer to them.
1002 SmallVector<TemplateArgument> AdjustedAliasTemplateArgs;
1003
1004 for (auto *TP : *AliasTemplate->getTemplateParameters()) {
1005 // Rebuild any internal references to earlier parameters and reindex
1006 // as we go.
1009 Args.addOuterTemplateArguments(AdjustedAliasTemplateArgs);
1010 NamedDecl *NewParam = transformTemplateParameter(
1011 SemaRef, AliasTemplate->getDeclContext(), TP, Args,
1012 /*NewIndex=*/AdjustedAliasTemplateArgs.size(),
1013 getDepthAndIndex(TP).first + AdjustDepth);
1014
1015 TemplateArgument NewTemplateArgument =
1016 Context.getInjectedTemplateArg(NewParam);
1017 AdjustedAliasTemplateArgs.push_back(NewTemplateArgument);
1018 }
1019 // Template arguments used to transform the template arguments in
1020 // DeducedResults.
1021 SmallVector<TemplateArgument> TemplateArgsForBuildingRC(
1022 F->getTemplateParameters()->size());
1023 // Transform the transformed template args
1026 Args.addOuterTemplateArguments(AdjustedAliasTemplateArgs);
1027
1028 for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
1029 const auto &D = DeduceResults[Index];
1030 if (D.isNull()) { // non-deduced template parameters of f
1031 NamedDecl *TP = F->getTemplateParameters()->getParam(Index);
1034 Args.addOuterTemplateArguments(TemplateArgsForBuildingRC);
1035 // Rebuild the template parameter with updated depth and index.
1036 NamedDecl *NewParam =
1037 transformTemplateParameter(SemaRef, F->getDeclContext(), TP, Args,
1038 /*NewIndex=*/FirstUndeducedParamIdx,
1039 getDepthAndIndex(TP).first + AdjustDepth);
1040 FirstUndeducedParamIdx += 1;
1041 assert(TemplateArgsForBuildingRC[Index].isNull());
1042 TemplateArgsForBuildingRC[Index] =
1043 Context.getInjectedTemplateArg(NewParam);
1044 continue;
1045 }
1046 TemplateArgumentLoc Input =
1048 TemplateArgumentLoc Output;
1049 if (!SemaRef.SubstTemplateArgument(Input, Args, Output)) {
1050 assert(TemplateArgsForBuildingRC[Index].isNull() &&
1051 "InstantiatedArgs must be null before setting");
1052 TemplateArgsForBuildingRC[Index] = Output.getArgument();
1053 }
1054 }
1055
1056 MultiLevelTemplateArgumentList ArgsForBuildingRC =
1057 SemaRef.getTemplateInstantiationArgs(F, TemplateArgsForBuildingRC);
1059
1060 ExprResult E = SemaRef.SubstExpr(RC, ArgsForBuildingRC);
1061 if (E.isInvalid())
1062 return nullptr;
1063
1064 auto Conjunction =
1065 SemaRef.BuildBinOp(SemaRef.getCurScope(), SourceLocation{},
1066 BinaryOperatorKind::BO_LAnd, E.get(), IsDeducible);
1067 if (Conjunction.isInvalid())
1068 return nullptr;
1069 return Conjunction.getAs<Expr>();
1070}
1071// Build the is_deducible constraint for the alias deduction guides.
1072// [over.match.class.deduct]p3.3:
1073// ... and a constraint that is satisfied if and only if the arguments
1074// of A are deducible (see below) from the return type.
1075Expr *buildIsDeducibleConstraint(Sema &SemaRef,
1077 QualType ReturnType,
1078 SmallVector<NamedDecl *> TemplateParams) {
1079 ASTContext &Context = SemaRef.Context;
1080 // Constraint AST nodes must use uninstantiated depth.
1081 if (auto *PrimaryTemplate =
1082 AliasTemplate->getInstantiatedFromMemberTemplate();
1083 PrimaryTemplate && TemplateParams.size() > 0) {
1085
1086 // Adjust the depth for TemplateParams.
1087 unsigned AdjustDepth = PrimaryTemplate->getTemplateDepth();
1088 SmallVector<TemplateArgument> TransformedTemplateArgs;
1089 for (auto *TP : TemplateParams) {
1090 // Rebuild any internal references to earlier parameters and reindex
1091 // as we go.
1094 Args.addOuterTemplateArguments(TransformedTemplateArgs);
1095 NamedDecl *NewParam = transformTemplateParameter(
1096 SemaRef, AliasTemplate->getDeclContext(), TP, Args,
1097 /*NewIndex=*/TransformedTemplateArgs.size(),
1098 getDepthAndIndex(TP).first + AdjustDepth);
1099
1100 TemplateArgument NewTemplateArgument =
1101 Context.getInjectedTemplateArg(NewParam);
1102 TransformedTemplateArgs.push_back(NewTemplateArgument);
1103 }
1104 // Transformed the ReturnType to restore the uninstantiated depth.
1107 Args.addOuterTemplateArguments(TransformedTemplateArgs);
1108 ReturnType = SemaRef.SubstType(
1109 ReturnType, Args, AliasTemplate->getLocation(),
1110 Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate));
1111 }
1112
1113 SmallVector<TypeSourceInfo *> IsDeducibleTypeTraitArgs = {
1114 Context.getTrivialTypeSourceInfo(
1115 Context.getDeducedTemplateSpecializationType(
1117 /*DeducedAsType=*/QualType(), ElaboratedTypeKeyword::None,
1119 AliasTemplate->getLocation()), // template specialization type whose
1120 // arguments will be deduced.
1121 Context.getTrivialTypeSourceInfo(
1122 ReturnType, AliasTemplate->getLocation()), // type from which template
1123 // arguments are deduced.
1124 };
1125 return TypeTraitExpr::Create(
1126 Context, Context.getLogicalOperationType(), AliasTemplate->getLocation(),
1127 TypeTrait::BTT_IsDeducible, IsDeducibleTypeTraitArgs,
1128 AliasTemplate->getLocation(), /*Value*/ false);
1129}
1130
1131std::pair<TemplateDecl *, llvm::ArrayRef<TemplateArgument>>
1132getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) {
1133 auto RhsType = AliasTemplate->getTemplatedDecl()->getUnderlyingType();
1134 TemplateDecl *Template = nullptr;
1135 llvm::ArrayRef<TemplateArgument> AliasRhsTemplateArgs;
1136 if (const auto *TST = RhsType->getAs<TemplateSpecializationType>()) {
1137 // Cases where the RHS of the alias is dependent. e.g.
1138 // template<typename T>
1139 // using AliasFoo1 = Foo<T>; // a class/type alias template specialization
1140 Template = TST->getTemplateName().getAsTemplateDecl();
1141 AliasRhsTemplateArgs =
1142 TST->getAsNonAliasTemplateSpecializationType()->template_arguments();
1143 } else if (const auto *RT = RhsType->getAs<RecordType>()) {
1144 // Cases where template arguments in the RHS of the alias are not
1145 // dependent. e.g.
1146 // using AliasFoo = Foo<bool>;
1147 if (const auto *CTSD =
1148 dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl())) {
1149 Template = CTSD->getSpecializedTemplate();
1150 AliasRhsTemplateArgs = CTSD->getTemplateArgs().asArray();
1151 }
1152 }
1153 return {Template, AliasRhsTemplateArgs};
1154}
1155
1156bool IsNonDeducedArgument(const TemplateArgument &TA) {
1157 // The following cases indicate the template argument is non-deducible:
1158 // 1. The result is null. E.g. When it comes from a default template
1159 // argument that doesn't appear in the alias declaration.
1160 // 2. The template parameter is a pack and that cannot be deduced from
1161 // the arguments within the alias declaration.
1162 // Non-deducible template parameters will persist in the transformed
1163 // deduction guide.
1164 return TA.isNull() ||
1166 llvm::any_of(TA.pack_elements(), IsNonDeducedArgument));
1167}
1168
1169// Build deduction guides for a type alias template from the given underlying
1170// source deduction guide.
1171CXXDeductionGuideDecl *BuildDeductionGuideForTypeAlias(
1173 CXXDeductionGuideDecl *SourceDeductionGuide, SourceLocation Loc) {
1175 SourceDeductionGuide->getDescribedFunctionTemplate();
1176 assert(F && "deduction guide for alias template must be a function template");
1177
1179 Sema::NonSFINAEContext _1(SemaRef);
1180 Sema::InstantiatingTemplate BuildingDeductionGuides(
1181 SemaRef, AliasTemplate->getLocation(), F,
1183 if (BuildingDeductionGuides.isInvalid())
1184 return nullptr;
1185
1186 auto &Context = SemaRef.Context;
1187 auto [Template, AliasRhsTemplateArgs] =
1188 getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
1189
1190 // We need both types desugared, before we continue to perform type deduction.
1191 // The intent is to get the template argument list 'matched', e.g. in the
1192 // following case:
1193 //
1194 //
1195 // template <class T>
1196 // struct A {};
1197 // template <class T>
1198 // using Foo = A<A<T>>;
1199 // template <class U = int>
1200 // using Bar = Foo<U>;
1201 //
1202 // In terms of Bar, we want U (which has the default argument) to appear in
1203 // the synthesized deduction guide, but U would remain undeduced if we deduced
1204 // A<A<T>> using Foo<U> directly.
1205 //
1206 // Instead, we need to canonicalize both against A, i.e. A<A<T>> and A<A<U>>,
1207 // such that T can be deduced as U.
1208 auto RType = SourceDeductionGuide->getReturnType();
1209 // The (trailing) return type of the deduction guide.
1210 const auto *FReturnType = RType->getAs<TemplateSpecializationType>();
1211 if (const auto *ICNT = RType->getAsCanonical<InjectedClassNameType>())
1212 // implicitly-generated deduction guide.
1214 ICNT->getDecl()->getCanonicalTemplateSpecializationType(
1215 SemaRef.Context));
1216
1217 ArrayRef<TemplateArgument> FReturnTemplateArgs;
1218 if (FReturnType) {
1219 FReturnTemplateArgs = FReturnType->template_arguments();
1220 } else if (const auto *RT = RType->getAs<RecordType>()) {
1221 // If the return type is a non-dependent class template specialization,
1222 // it might be resolved to a RecordType.
1223 if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()))
1224 FReturnTemplateArgs = CTSD->getTemplateArgs().asArray();
1225 }
1226 assert(!FReturnTemplateArgs.empty() && "expected to see template arguments");
1227
1228 // Deduce template arguments of the deduction guide f from the RHS of
1229 // the alias.
1230 //
1231 // C++ [over.match.class.deduct]p3: ...For each function or function
1232 // template f in the guides of the template named by the
1233 // simple-template-id of the defining-type-id, the template arguments
1234 // of the return type of f are deduced from the defining-type-id of A
1235 // according to the process in [temp.deduct.type] with the exception
1236 // that deduction does not fail if not all template arguments are
1237 // deduced.
1238 //
1239 //
1240 // template<typename X, typename Y>
1241 // f(X, Y) -> f<Y, X>;
1242 //
1243 // template<typename U>
1244 // using alias = f<int, U>;
1245 //
1246 // The RHS of alias is f<int, U>, we deduced the template arguments of
1247 // the return type of the deduction guide from it: Y->int, X->U
1248 sema::TemplateDeductionInfo TDeduceInfo(Loc);
1249 // Must initialize n elements, this is required by DeduceTemplateArguments.
1251 F->getTemplateParameters()->size());
1252
1253 // FIXME: DeduceTemplateArguments stops immediately at the first
1254 // non-deducible template argument. However, this doesn't seem to cause
1255 // issues for practice cases, we probably need to extend it to continue
1256 // performing deduction for rest of arguments to align with the C++
1257 // standard.
1259 F->getTemplateParameters(), FReturnTemplateArgs,
1260 AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
1261 /*NumberOfArgumentsMustMatch=*/false);
1262
1264 SmallVector<unsigned> NonDeducedTemplateParamsInFIndex;
1265 // !!NOTE: DeduceResults respects the sequence of template parameters of
1266 // the deduction guide f.
1267 for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
1268 const auto &D = DeduceResults[Index];
1269 if (!IsNonDeducedArgument(D))
1270 DeducedArgs.push_back(D);
1271 else
1272 NonDeducedTemplateParamsInFIndex.push_back(Index);
1273 }
1274 auto DeducedAliasTemplateParams =
1275 TemplateParamsReferencedInTemplateArgumentList(
1276 SemaRef, AliasTemplate->getTemplateParameters(), DeducedArgs);
1277 // All template arguments null by default.
1278 SmallVector<TemplateArgument> TemplateArgsForBuildingFPrime(
1279 F->getTemplateParameters()->size());
1280
1281 // Create a template parameter list for the synthesized deduction guide f'.
1282 //
1283 // C++ [over.match.class.deduct]p3.2:
1284 // If f is a function template, f' is a function template whose template
1285 // parameter list consists of all the template parameters of A
1286 // (including their default template arguments) that appear in the above
1287 // deductions or (recursively) in their default template arguments
1288 SmallVector<NamedDecl *> FPrimeTemplateParams;
1289 // Store template arguments that refer to the newly-created template
1290 // parameters, used for building `TemplateArgsForBuildingFPrime`.
1291 SmallVector<TemplateArgument, 16> TransformedDeducedAliasArgs(
1292 AliasTemplate->getTemplateParameters()->size());
1293 // We might be already within a pack expansion, but rewriting template
1294 // parameters is independent of that. (We may or may not expand new packs
1295 // when rewriting. So clear the state)
1296 Sema::ArgPackSubstIndexRAII PackSubstReset(SemaRef, std::nullopt);
1297
1298 for (unsigned AliasTemplateParamIdx : DeducedAliasTemplateParams) {
1299 auto *TP =
1300 AliasTemplate->getTemplateParameters()->getParam(AliasTemplateParamIdx);
1301 // Rebuild any internal references to earlier parameters and reindex as
1302 // we go.
1305 Args.addOuterTemplateArguments(TransformedDeducedAliasArgs);
1306 NamedDecl *NewParam = transformTemplateParameter(
1307 SemaRef, AliasTemplate->getDeclContext(), TP, Args,
1308 /*NewIndex=*/FPrimeTemplateParams.size(), getDepthAndIndex(TP).first);
1309 FPrimeTemplateParams.push_back(NewParam);
1310
1311 TemplateArgument NewTemplateArgument =
1312 Context.getInjectedTemplateArg(NewParam);
1313 TransformedDeducedAliasArgs[AliasTemplateParamIdx] = NewTemplateArgument;
1314 }
1315 unsigned FirstUndeducedParamIdx = FPrimeTemplateParams.size();
1316
1317 // To form a deduction guide f' from f, we leverage clang's instantiation
1318 // mechanism, we construct a template argument list where the template
1319 // arguments refer to the newly-created template parameters of f', and
1320 // then apply instantiation on this template argument list to instantiate
1321 // f, this ensures all template parameter occurrences are updated
1322 // correctly.
1323 //
1324 // The template argument list is formed, in order, from
1325 // 1) For the template parameters of the alias, the corresponding deduced
1326 // template arguments
1327 // 2) For the non-deduced template parameters of f. the
1328 // (rebuilt) template arguments corresponding.
1329 //
1330 // Note: the non-deduced template arguments of `f` might refer to arguments
1331 // deduced in 1), as in a type constraint.
1334 Args.addOuterTemplateArguments(TransformedDeducedAliasArgs);
1335 for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
1336 const auto &D = DeduceResults[Index];
1337 auto *TP = F->getTemplateParameters()->getParam(Index);
1338 if (IsNonDeducedArgument(D)) {
1339 // 2): Non-deduced template parameters would be substituted later.
1340 continue;
1341 }
1342 TemplateArgumentLoc Input =
1345 if (SemaRef.SubstTemplateArguments(Input, Args, Output))
1346 return nullptr;
1347 assert(TemplateArgsForBuildingFPrime[Index].isNull() &&
1348 "InstantiatedArgs must be null before setting");
1349 // CheckTemplateArgument is necessary for NTTP initializations.
1350 // FIXME: We may want to call CheckTemplateArguments instead, but we cannot
1351 // match packs as usual, since packs can appear in the middle of the
1352 // parameter list of a synthesized CTAD guide. See also the FIXME in
1353 // test/SemaCXX/cxx20-ctad-type-alias.cpp:test25.
1355 for (auto TA : Output.arguments())
1356 if (SemaRef.CheckTemplateArgument(
1357 TP, TA, F, F->getLocation(), F->getLocation(),
1358 /*ArgumentPackIndex=*/-1, CTAI,
1360 return nullptr;
1361 if (Input.getArgument().getKind() == TemplateArgument::Pack) {
1362 // We will substitute the non-deduced template arguments with these
1363 // transformed (unpacked at this point) arguments, where that substitution
1364 // requires a pack for the corresponding parameter packs.
1365 TemplateArgsForBuildingFPrime[Index] =
1367 } else {
1368 assert(Output.arguments().size() == 1);
1369 TemplateArgsForBuildingFPrime[Index] = CTAI.SugaredConverted[0];
1370 }
1371 }
1372
1373 // Case 2)
1374 // ...followed by the template parameters of f that were not deduced
1375 // (including their default template arguments)
1376 for (unsigned FTemplateParamIdx : NonDeducedTemplateParamsInFIndex) {
1377 auto *TP = F->getTemplateParameters()->getParam(FTemplateParamIdx);
1380 // We take a shortcut here, it is ok to reuse the
1381 // TemplateArgsForBuildingFPrime.
1382 Args.addOuterTemplateArguments(TemplateArgsForBuildingFPrime);
1383 NamedDecl *NewParam = transformTemplateParameter(
1384 SemaRef, F->getDeclContext(), TP, Args, FPrimeTemplateParams.size(),
1385 getDepthAndIndex(TP).first);
1386 FPrimeTemplateParams.push_back(NewParam);
1387
1388 assert(TemplateArgsForBuildingFPrime[FTemplateParamIdx].isNull() &&
1389 "The argument must be null before setting");
1390 TemplateArgsForBuildingFPrime[FTemplateParamIdx] =
1391 Context.getInjectedTemplateArg(NewParam);
1392 }
1393
1394 auto *TemplateArgListForBuildingFPrime =
1395 TemplateArgumentList::CreateCopy(Context, TemplateArgsForBuildingFPrime);
1396 // Form the f' by substituting the template arguments into f.
1397 if (auto *FPrime = SemaRef.InstantiateFunctionDeclaration(
1398 F, TemplateArgListForBuildingFPrime, AliasTemplate->getLocation(),
1400 auto *GG = cast<CXXDeductionGuideDecl>(FPrime);
1401
1402 Expr *IsDeducible = buildIsDeducibleConstraint(
1403 SemaRef, AliasTemplate, FPrime->getReturnType(), FPrimeTemplateParams);
1404 Expr *RequiresClause =
1405 buildAssociatedConstraints(SemaRef, F, AliasTemplate, DeduceResults,
1406 FirstUndeducedParamIdx, IsDeducible);
1407
1408 TemplateParameterList *FPrimeTemplateParamList = nullptr;
1409 if (!FPrimeTemplateParams.empty())
1410 FPrimeTemplateParamList = TemplateParameterList::Create(
1411 Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(),
1412 AliasTemplate->getTemplateParameters()->getLAngleLoc(),
1413 FPrimeTemplateParams,
1414 AliasTemplate->getTemplateParameters()->getRAngleLoc(),
1415 /*RequiresClause=*/RequiresClause);
1416
1417 auto *DGuide = buildDeductionGuide(
1418 SemaRef, AliasTemplate, FPrimeTemplateParamList,
1419 GG->getCorrespondingConstructor(), GG->getExplicitSpecifier(),
1420 GG->getTypeSourceInfo(), AliasTemplate->getBeginLoc(),
1421 AliasTemplate->getLocation(), AliasTemplate->getEndLoc(),
1422 F->isImplicit());
1423 DGuide->setDeductionCandidateKind(GG->getDeductionCandidateKind());
1424 DGuide->setSourceDeductionGuide(SourceDeductionGuide);
1425 DGuide->setSourceDeductionGuideKind(
1427 return DGuide;
1428 }
1429 return nullptr;
1430}
1431
1432void DeclareImplicitDeductionGuidesForTypeAlias(
1434 if (AliasTemplate->isInvalidDecl())
1435 return;
1436 auto &Context = SemaRef.Context;
1437 auto [Template, AliasRhsTemplateArgs] =
1438 getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);
1439 if (!Template)
1440 return;
1441 auto SourceDeductionGuides = getSourceDeductionGuides(
1442 Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate),
1443 AliasTemplate->getDeclContext());
1444
1445 DeclarationNameInfo NameInfo(
1446 Context.DeclarationNames.getCXXDeductionGuideName(Template), Loc);
1447 LookupResult Guides(SemaRef, NameInfo, clang::Sema::LookupOrdinaryName);
1448 SemaRef.LookupQualifiedName(Guides, Template->getDeclContext());
1449 Guides.suppressDiagnostics();
1450
1451 for (auto *G : Guides) {
1452 if (auto *DG = dyn_cast<CXXDeductionGuideDecl>(G)) {
1453 if (SourceDeductionGuides.contains(DG))
1454 continue;
1455 // The deduction guide is a non-template function decl, we just clone it.
1456 auto *FunctionType =
1457 SemaRef.Context.getTrivialTypeSourceInfo(DG->getType());
1459 FunctionType->getTypeLoc().castAs<FunctionProtoTypeLoc>();
1460
1461 // Clone the parameters.
1462 for (unsigned I = 0, N = DG->getNumParams(); I != N; ++I) {
1463 const auto *P = DG->getParamDecl(I);
1464 auto *TSI = SemaRef.Context.getTrivialTypeSourceInfo(P->getType());
1465 ParmVarDecl *NewParam = ParmVarDecl::Create(
1466 SemaRef.Context, G->getDeclContext(),
1467 DG->getParamDecl(I)->getBeginLoc(), P->getLocation(), nullptr,
1468 TSI->getType(), TSI, SC_None, nullptr);
1469 NewParam->setScopeInfo(0, I);
1470 FPTL.setParam(I, NewParam);
1471 }
1472 auto *Transformed = cast<CXXDeductionGuideDecl>(buildDeductionGuide(
1473 SemaRef, AliasTemplate, /*TemplateParams=*/nullptr,
1474 /*Constructor=*/nullptr, DG->getExplicitSpecifier(), FunctionType,
1475 AliasTemplate->getBeginLoc(), AliasTemplate->getLocation(),
1476 AliasTemplate->getEndLoc(), DG->isImplicit()));
1477 Transformed->setSourceDeductionGuide(DG);
1478 Transformed->setSourceDeductionGuideKind(
1480
1481 // FIXME: Here the synthesized deduction guide is not a templated
1482 // function. Per [dcl.decl]p4, the requires-clause shall be present only
1483 // if the declarator declares a templated function, a bug in standard?
1484 AssociatedConstraint Constraint(buildIsDeducibleConstraint(
1485 SemaRef, AliasTemplate, Transformed->getReturnType(), {}));
1486 if (const AssociatedConstraint &RC = DG->getTrailingRequiresClause()) {
1487 auto Conjunction = SemaRef.BuildBinOp(
1488 SemaRef.getCurScope(), SourceLocation{},
1489 BinaryOperatorKind::BO_LAnd, const_cast<Expr *>(RC.ConstraintExpr),
1490 const_cast<Expr *>(Constraint.ConstraintExpr));
1491 if (!Conjunction.isInvalid()) {
1492 Constraint.ConstraintExpr = Conjunction.getAs<Expr>();
1493 Constraint.ArgPackSubstIndex = RC.ArgPackSubstIndex;
1494 }
1495 }
1496 Transformed->setTrailingRequiresClause(Constraint);
1497 continue;
1498 }
1499 FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(G);
1500 if (!F || SourceDeductionGuides.contains(F->getTemplatedDecl()))
1501 continue;
1502 // The **aggregate** deduction guides are handled in a different code path
1503 // (DeclareAggregateDeductionGuideFromInitList), which involves the tricky
1504 // cache.
1505 auto *DGuide = cast<CXXDeductionGuideDecl>(F->getTemplatedDecl());
1506 if (DGuide->getDeductionCandidateKind() == DeductionCandidate::Aggregate)
1507 continue;
1508
1509 BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate, DGuide, Loc);
1510 }
1511}
1512
1513// Build an aggregate deduction guide for a type alias template.
1514CXXDeductionGuideDecl *DeclareAggregateDeductionGuideForTypeAlias(
1516 MutableArrayRef<QualType> ParamTypes, SourceLocation Loc) {
1517 TemplateDecl *RHSTemplate =
1518 getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate).first;
1519 if (!RHSTemplate)
1520 return nullptr;
1521
1523 llvm::SmallVector<QualType> NewParamTypes;
1524 ExtractTypeForDeductionGuide TypeAliasTransformer(SemaRef, TypedefDecls);
1525 for (QualType P : ParamTypes) {
1526 QualType Type = TypeAliasTransformer.TransformType(P);
1527 if (Type.isNull())
1528 return nullptr;
1529 NewParamTypes.push_back(Type);
1530 }
1531
1532 auto *RHSDeductionGuide = SemaRef.DeclareAggregateDeductionGuideFromInitList(
1533 RHSTemplate, NewParamTypes, Loc);
1534 if (!RHSDeductionGuide)
1535 return nullptr;
1536
1537 for (TypedefNameDecl *TD : TypedefDecls)
1538 TD->setDeclContext(RHSDeductionGuide);
1539
1540 return BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate,
1541 RHSDeductionGuide, Loc);
1542}
1543
1544} // namespace
1545
1548 SourceLocation Loc) {
1549 llvm::FoldingSetNodeID ID;
1550 ID.AddPointer(Template);
1551 for (auto &T : ParamTypes)
1552 T.getCanonicalType().Profile(ID);
1553 unsigned Hash = ID.ComputeHash();
1554
1555 auto Found = AggregateDeductionCandidates.find(Hash);
1557 return Found->getSecond();
1558
1559 if (auto *AliasTemplate = llvm::dyn_cast<TypeAliasTemplateDecl>(Template)) {
1560 if (auto *GD = DeclareAggregateDeductionGuideForTypeAlias(
1561 *this, AliasTemplate, ParamTypes, Loc)) {
1562 GD->setDeductionCandidateKind(DeductionCandidate::Aggregate);
1564 return GD;
1565 }
1566 }
1567
1568 if (CXXRecordDecl *DefRecord =
1569 cast<CXXRecordDecl>(Template->getTemplatedDecl())->getDefinition()) {
1570 if (TemplateDecl *DescribedTemplate =
1571 DefRecord->getDescribedClassTemplate())
1572 Template = DescribedTemplate;
1573 }
1574
1575 DeclContext *DC = Template->getDeclContext();
1576 if (DC->isDependentContext())
1577 return nullptr;
1578
1579 ConvertConstructorToDeductionGuideTransform Transform(
1581 if (!isCompleteType(Loc, Transform.DeducedType))
1582 return nullptr;
1583
1584 // In case we were expanding a pack when we attempted to declare deduction
1585 // guides, turn off pack expansion for everything we're about to do.
1586 ArgPackSubstIndexRAII SubstIndex(*this, std::nullopt);
1587 // Create a template instantiation record to track the "instantiation" of
1588 // constructors into deduction guides.
1589 InstantiatingTemplate BuildingDeductionGuides(
1590 *this, Loc, Template,
1592 if (BuildingDeductionGuides.isInvalid())
1593 return nullptr;
1594
1595 ClassTemplateDecl *Pattern =
1596 Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
1597 ContextRAII SavedContext(*this, Pattern->getTemplatedDecl());
1598
1599 CXXDeductionGuideDecl *GD = Transform.buildSimpleDeductionGuide(ParamTypes);
1600 SavedContext.pop();
1603 return GD;
1604}
1605
1607 SourceLocation Loc) {
1608 if (auto *AliasTemplate = llvm::dyn_cast<TypeAliasTemplateDecl>(Template)) {
1609 DeclareImplicitDeductionGuidesForTypeAlias(*this, AliasTemplate, Loc);
1610 return;
1611 }
1612 CXXRecordDecl *DefRecord =
1613 dyn_cast_or_null<CXXRecordDecl>(Template->getTemplatedDecl());
1614 if (!DefRecord)
1615 return;
1616 if (const CXXRecordDecl *Definition = DefRecord->getDefinition()) {
1617 if (TemplateDecl *DescribedTemplate =
1618 Definition->getDescribedClassTemplate())
1619 Template = DescribedTemplate;
1620 }
1621
1622 DeclContext *DC = Template->getDeclContext();
1623 if (DC->isDependentContext())
1624 return;
1625
1626 ConvertConstructorToDeductionGuideTransform Transform(
1628 if (!isCompleteType(Loc, Transform.DeducedType))
1629 return;
1630
1631 if (hasDeclaredDeductionGuides(Transform.DeductionGuideName, DC))
1632 return;
1633
1634 // In case we were expanding a pack when we attempted to declare deduction
1635 // guides, turn off pack expansion for everything we're about to do.
1636 ArgPackSubstIndexRAII SubstIndex(*this, std::nullopt);
1637 // Create a template instantiation record to track the "instantiation" of
1638 // constructors into deduction guides.
1639 InstantiatingTemplate BuildingDeductionGuides(
1640 *this, Loc, Template,
1642 if (BuildingDeductionGuides.isInvalid())
1643 return;
1644
1645 // Convert declared constructors into deduction guide templates.
1646 // FIXME: Skip constructors for which deduction must necessarily fail (those
1647 // for which some class template parameter without a default argument never
1648 // appears in a deduced context).
1649 ClassTemplateDecl *Pattern =
1650 Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
1651 ContextRAII SavedContext(*this, Pattern->getTemplatedDecl());
1652 llvm::SmallPtrSet<NamedDecl *, 8> ProcessedCtors;
1653 bool AddedAny = false;
1654 for (NamedDecl *D : LookupConstructors(Pattern->getTemplatedDecl())) {
1655 D = D->getUnderlyingDecl();
1656 if (D->isInvalidDecl() || D->isImplicit())
1657 continue;
1658
1659 D = cast<NamedDecl>(D->getCanonicalDecl());
1660
1661 // Within C++20 modules, we may have multiple same constructors in
1662 // multiple same RecordDecls. And it doesn't make sense to create
1663 // duplicated deduction guides for the duplicated constructors.
1664 if (ProcessedCtors.count(D))
1665 continue;
1666
1667 auto *FTD = dyn_cast<FunctionTemplateDecl>(D);
1668 auto *CD =
1669 dyn_cast_or_null<CXXConstructorDecl>(FTD ? FTD->getTemplatedDecl() : D);
1670 // Class-scope explicit specializations (MS extension) do not result in
1671 // deduction guides.
1672 if (!CD || (!FTD && CD->isFunctionTemplateSpecialization()))
1673 continue;
1674
1675 // Cannot make a deduction guide when unparsed arguments are present.
1676 if (llvm::any_of(CD->parameters(), [](ParmVarDecl *P) {
1677 return !P || P->hasUnparsedDefaultArg();
1678 }))
1679 continue;
1680
1681 ProcessedCtors.insert(D);
1682 Transform.transformConstructor(FTD, CD);
1683 AddedAny = true;
1684 }
1685
1686 // C++17 [over.match.class.deduct]
1687 // -- If C is not defined or does not declare any constructors, an
1688 // additional function template derived as above from a hypothetical
1689 // constructor C().
1690 if (!AddedAny)
1691 Transform.buildSimpleDeductionGuide({});
1692
1693 // -- An additional function template derived as above from a hypothetical
1694 // constructor C(C), called the copy deduction candidate.
1695 Transform.buildSimpleDeductionGuide(Transform.DeducedType)
1696 ->setDeductionCandidateKind(DeductionCandidate::Copy);
1697
1698 SavedContext.pop();
1699}
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines the classes used to store parsed information about declaration-specifiers and decla...
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Result
Implement __builtin_bit_cast and related operations.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
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:223
TranslationUnitDecl * getTranslationUnitDecl() const
DeclarationNameTable DeclarationNames
Definition ASTContext.h:806
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
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.
PtrTy get() const
Definition Ownership.h:171
bool isInvalid() const
Definition Ownership.h:167
bool isUsable() const
Definition Ownership.h:169
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:5102
Represents a C++ constructor within a class.
Definition DeclCXX.h:2620
ExplicitSpecifier getExplicitSpecifier() const
Definition DeclCXX.h:2692
Represents a C++ deduction guide declaration.
Definition DeclCXX.h:1983
void setDeductionCandidateKind(DeductionCandidate K)
Definition DeclCXX.h:2074
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:2380
CXXConstructorDecl * getCorrespondingConstructor() const
Get the constructor from which this deduction guide was generated, if this is an implicit deduction g...
Definition DeclCXX.h:2053
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:433
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1462
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2122
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
Definition DeclBase.h:2251
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
bool isRecord() const
Definition DeclBase.h:2202
void addDecl(Decl *D)
Add the declaration D into this context.
SourceLocation getEndLoc() const LLVM_READONLY
Definition DeclBase.h:443
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition DeclBase.h:601
static Decl * castFromDeclContext(const DeclContext *)
void setAccess(AccessSpecifier AS)
Definition DeclBase.h:510
SourceLocation getLocation() const
Definition DeclBase.h:447
void setImplicit(bool I=true)
Definition DeclBase.h:602
DeclContext * getDeclContext()
Definition DeclBase.h:456
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
Definition DeclBase.cpp:382
DeclarationName getCXXDeductionGuideName(TemplateDecl *TD)
Returns the name of a C++ deduction guide for the given template.
The name of a declaration.
NameKind getNameKind() const
Determine what kind of name this is.
SourceLocation getInnerLocStart() const
Return start of source range ignoring outer template declarations.
Definition Decl.h:822
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:831
const AssociatedConstraint & getTrailingRequiresClause() const
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
Definition Decl.h:855
TypeSourceInfo * getTypeSourceInfo() const
Definition Decl.h:809
SourceLocation getElaboratedKeywordLoc() const
Definition TypeLoc.h:752
SourceLocation getNameLoc() const
Definition TypeLoc.h:761
NestedNameSpecifierLoc getQualifierLoc() const
Definition TypeLoc.h:756
Store information needed for an explicit specifier.
Definition DeclCXX.h:1931
This represents one expression.
Definition Expr.h:112
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
Definition Decl.cpp:4180
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition Decl.cpp:4168
QualType getReturnType() const
Definition Decl.h:2837
ArrayRef< ParmVarDecl * > parameters() const
Definition Decl.h:2766
void getAssociatedConstraints(SmallVectorImpl< AssociatedConstraint > &ACs) const
Get the associated-constraints of this function declaration.
Definition Decl.h:2744
bool isVariadic() const
Whether this function prototype is variadic.
Definition TypeBase.h:5773
Declaration of a template function.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
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:1716
SourceLocation getLocalRangeEnd() const
Definition TypeLoc.h:1668
void setLocalRangeBegin(SourceLocation L)
Definition TypeLoc.h:1664
void setLParenLoc(SourceLocation Loc)
Definition TypeLoc.h:1680
void setParam(unsigned i, ParmVarDecl *VD)
Definition TypeLoc.h:1723
ArrayRef< ParmVarDecl * > getParams() const
Definition TypeLoc.h:1707
void setRParenLoc(SourceLocation Loc)
Definition TypeLoc.h:1688
void setLocalRangeEnd(SourceLocation L)
Definition TypeLoc.h:1672
void setExceptionSpecRange(SourceRange R)
Definition TypeLoc.h:1702
SourceLocation getLocalRangeBegin() const
Definition TypeLoc.h:1660
SourceLocation getLParenLoc() const
Definition TypeLoc.h:1676
SourceLocation getRParenLoc() const
Definition TypeLoc.h:1684
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition TypeBase.h:4565
const TypeClass * getTypePtr() const
Definition TypeLoc.h:526
ElaboratedTypeKeyword getKeyword() const
Definition TypeBase.h:6046
A stack-allocated class that identifies which local variable declaration instantiations are present i...
Definition Template.h:371
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:263
void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args, bool Final)
Add a new outmost level to the multi-level template argument list.
Definition Template.h:212
void setKind(TemplateSubstitutionKind K)
Definition Template.h:109
void addOuterRetainedLevels(unsigned Num)
Definition Template.h:266
This represents a decl that may have a name.
Definition Decl.h:274
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:295
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
NestedNameSpecifier getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo)
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
TypeSourceInfo * getExpansionTypeSourceInfo(unsigned I) const
Retrieve a particular expansion type source info within an expanded parameter pack.
unsigned getNumExpansionTypes() const
Retrieves the number of expansion types in an expanded parameter pack.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
bool isExpandedParameterPack() const
Whether this parameter is a non-type template parameter pack that has a known list of different types...
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
Expr * getPlaceholderTypeConstraint() const
Return the constraint introduced by the placeholder type of this non-type template parameter (if any)...
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
Represents a parameter to a function.
Definition Decl.h:1808
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
Definition Decl.h:1868
SourceRange getDefaultArgRange() const
Retrieve the source range that covers the entire default argument.
Definition Decl.cpp:3002
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
Definition Decl.h:1841
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:2932
bool hasDefaultArg() const
Determines whether this parameter has a default argument, either parsed or not.
Definition Decl.cpp:3033
unsigned getFunctionScopeDepth() const
Definition Decl.h:1858
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:3679
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
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:13685
A RAII object to temporarily push a declaration context.
Definition Sema.h:3526
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:868
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:13101
Scope * getCurScope() const
Retrieve the parser's current scope.
Definition Sema.h:1141
bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool UseMemberUsingDeclRules, bool ConsiderCudaAttrs=true)
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition Sema.h:9420
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...
@ CTAK_Specified
The template argument was specified in the code or was instantiated with some deduced template argume...
Definition Sema.h:12067
ASTContext & Context
Definition Sema.h:1308
ExprResult SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)
ASTContext & getASTContext() const
Definition Sema.h:939
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.
bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)
bool CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &Arg, NamedDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, unsigned ArgumentPackIndex, CheckTemplateArgumentInfo &CTAI, CheckTemplateArgumentKind CTAK)
Check that the given template argument corresponds to the given template parameter.
const LangOptions & getLangOpts() const
Definition Sema.h:932
llvm::DenseMap< unsigned, CXXDeductionGuideDecl * > AggregateDeductionCandidates
Definition Sema.h:9105
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc)
Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.
MultiLevelTemplateArgumentList getTemplateInstantiationArgs(const Decl *D, std::optional< ArrayRef< TemplateArgument > > Innermost=std::nullopt, UnsignedOrNone NumLevels=std::nullopt, bool SkipInnerNonInstantiated=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.
QualType CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI, SourceLocation Loc)
Check that the type of a non-type template parameter is well-formed.
bool AttachTypeConstraint(NestedNameSpecifierLoc NS, DeclarationNameInfo NameInfo, TemplateDecl *NamedConcept, NamedDecl *FoundDecl, const TemplateArgumentListInfo *TemplateArgs, TemplateTypeParmDecl *ConstrainedParameter, SourceLocation EllipsisLoc)
Attach a type-constraint to a template parameter.
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
Definition Sema.h:15512
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.
bool AreConstraintExpressionsEqual(const Decl *Old, const Expr *OldConstr, const Decl *New, const Expr *NewConstr)
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr, bool ForFoldExpression=false)
CXXDeductionGuideDecl * DeclareAggregateDeductionGuideFromInitList(TemplateDecl *Template, MutableArrayRef< QualType > ParamTypes, SourceLocation Loc)
TemplateDeductionResult DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, ArrayRef< TemplateArgument > TemplateArgs, sema::TemplateDeductionInfo &Info)
DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class)
Look up the constructors for the given class.
Encodes a location in the source.
SourceLocation getBegin() const
A convenient class for passing around template argument information.
ArrayRef< TemplateArgumentLoc > arguments() const
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.
const TemplateArgument & getArgument() const
Represents a template argument.
static TemplateArgument CreatePackCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument pack by copying the given set of template arguments.
bool isNull() const
Determine whether this template argument has no value.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Pack
The template argument is actually a parameter pack.
ArgKind getKind() const
Return the kind of stored template argument.
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
SourceLocation getRAngleLoc() const
SourceLocation getLAngleLoc() const
SourceLocation getTemplateLoc() const
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
bool wasDeclaredWithTypename() const
Whether this template template parameter was declared with the 'typename' keyword.
TemplateParameterList * getExpansionTemplateParameters(unsigned I) const
Retrieve a particular expansion type within an expanded parameter pack.
unsigned getNumExpansionTemplateParameters() const
Retrieves the number of expansion template parameters in an expanded parameter pack.
TemplateNameKind templateParameterKind() const
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
bool isParameterPack() const
Whether this template template parameter is a template parameter pack.
static TemplateTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P, bool ParameterPack, IdentifierInfo *Id, TemplateNameKind ParameterKind, bool Typename, TemplateParameterList *Params)
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
bool isExpandedParameterPack() const
Whether this parameter is a template template parameter pack that has a known list of different templ...
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
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.
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, int D, int P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, UnsignedOrNone NumExpanded=std::nullopt)
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.
A semantic tree transformation that allows one to transform one abstract syntax tree into another.
QualType RebuildTemplateSpecializationType(ElaboratedTypeKeyword Keyword, TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &Args)
static TypeAliasDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo)
Definition Decl.cpp:5838
Declaration of an alias template.
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:3553
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
AutoTypeLoc getContainedAutoTypeLoc() const
Get the typeloc of an AutoType whose type will be deduced for a variable with an initializer of this ...
Definition TypeLoc.cpp:884
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition TypeLoc.h:2735
SourceLocation getBeginLoc() const
Get the begin source location.
Definition TypeLoc.cpp:193
A container of type source information.
Definition TypeBase.h:8411
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition TypeLoc.h:267
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8422
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:1907
The base class of the type hierarchy.
Definition TypeBase.h:1875
bool isRValueReferenceType() const
Definition TypeBase.h:8709
bool isArrayType() const
Definition TypeBase.h:8776
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9337
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition TypeBase.h:2852
bool isLValueReferenceType() const
Definition TypeBase.h:8705
bool isFunctionType() const
Definition TypeBase.h:8673
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9270
static TypedefDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo)
Definition Decl.cpp:5787
Base class for declarations which introduce a typedef-name.
Definition Decl.h:3568
TypeSourceInfo * getTypeSourceInfo() const
Definition Decl.h:3618
QualType getType() const
Definition Decl.h:723
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition Decl.h:1166
Provides information about an attempted template argument deduction, whose success or failure was des...
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ Rewrite
We are substituting template parameters for (typically) other template parameters in order to rewrite...
Definition Template.h:54
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
Definition Parser.h:61
@ OK_Ordinary
An ordinary object is located at an address in memory.
Definition Specifiers.h:152
@ AS_public
Definition Specifiers.h:125
@ SC_None
Definition Specifiers.h:254
@ Result
The result type of a method or function.
Definition TypeBase.h:905
std::pair< unsigned, unsigned > getDepthAndIndex(const NamedDecl *ND)
Retrieve the depth and index of a template parameter.
@ Template
We are parsing a template declaration.
Definition Parser.h:81
@ Keyword
The name has been typo-corrected to a keyword.
Definition Sema.h:562
@ DeducedAsDependent
This is a special case where the initializer is dependent, so we can't deduce a type yet.
Definition TypeBase.h:1824
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition Specifiers.h:136
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
Definition Specifiers.h:145
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition Specifiers.h:140
U cast(CodeGen::Address addr)
Definition Address.h:327
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
Definition TypeBase.h:5968
@ None
No keyword precedes the qualified type name.
Definition TypeBase.h:5989
ActionResult< Expr * > ExprResult
Definition Ownership.h:249
const Expr * ConstraintExpr
Definition Decl.h:88
UnsignedOrNone ArgPackSubstIndex
Definition Decl.h:89
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
SmallVector< TemplateArgument, 4 > SugaredConverted
The checked, converted argument will be added to the end of these vectors.
Definition Sema.h:12088
@ BuildingDeductionGuides
We are building deduction guides for a class.
Definition Sema.h:13256
A stack object to be created when performing template instantiation.
Definition Sema.h:13343