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