1 //===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===//
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 the C++ related Decl classes for templates.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/AST/DeclTemplate.h"
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/ASTMutationListener.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclarationName.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/ExternalASTSource.h"
20 #include "clang/AST/TemplateBase.h"
21 #include "clang/AST/TemplateName.h"
22 #include "clang/AST/Type.h"
23 #include "clang/AST/TypeLoc.h"
24 #include "clang/Basic/Builtins.h"
25 #include "clang/Basic/LLVM.h"
26 #include "clang/Basic/SourceLocation.h"
27 #include "llvm/ADT/ArrayRef.h"
28 #include "llvm/ADT/FoldingSet.h"
29 #include "llvm/ADT/PointerUnion.h"
30 #include "llvm/ADT/STLExtras.h"
31 #include "llvm/ADT/SmallVector.h"
32 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include <algorithm>
35 #include <cassert>
36 #include <cstdint>
37 #include <memory>
38 #include <optional>
39 #include <utility>
40 
41 using namespace clang;
42 
43 //===----------------------------------------------------------------------===//
44 // TemplateParameterList Implementation
45 //===----------------------------------------------------------------------===//
46 
47 
48 TemplateParameterList::TemplateParameterList(const ASTContext& C,
49                                              SourceLocation TemplateLoc,
50                                              SourceLocation LAngleLoc,
51                                              ArrayRef<NamedDecl *> Params,
52                                              SourceLocation RAngleLoc,
53                                              Expr *RequiresClause)
54     : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
55       NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
56       HasRequiresClause(RequiresClause != nullptr),
57       HasConstrainedParameters(false) {
58   for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
59     NamedDecl *P = Params[Idx];
60     begin()[Idx] = P;
61 
62     bool IsPack = P->isTemplateParameterPack();
63     if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
64       if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())
65         ContainsUnexpandedParameterPack = true;
66       if (NTTP->hasPlaceholderTypeConstraint())
67         HasConstrainedParameters = true;
68     } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
69       if (!IsPack &&
70           TTP->getTemplateParameters()->containsUnexpandedParameterPack())
71         ContainsUnexpandedParameterPack = true;
72     } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
73       if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
74         if (TC->getImmediatelyDeclaredConstraint()
75             ->containsUnexpandedParameterPack())
76           ContainsUnexpandedParameterPack = true;
77       }
78       if (TTP->hasTypeConstraint())
79         HasConstrainedParameters = true;
80     } else {
81       llvm_unreachable("unexpected template parameter type");
82     }
83     // FIXME: If a default argument contains an unexpanded parameter pack, the
84     // template parameter list does too.
85   }
86 
87   if (HasRequiresClause) {
88     if (RequiresClause->containsUnexpandedParameterPack())
89       ContainsUnexpandedParameterPack = true;
90     *getTrailingObjects<Expr *>() = RequiresClause;
91   }
92 }
93 
94 bool TemplateParameterList::containsUnexpandedParameterPack() const {
95   if (ContainsUnexpandedParameterPack)
96     return true;
97   if (!HasConstrainedParameters)
98     return false;
99 
100   // An implicit constrained parameter might have had a use of an unexpanded
101   // pack added to it after the template parameter list was created. All
102   // implicit parameters are at the end of the parameter list.
103   for (const NamedDecl *Param : llvm::reverse(asArray())) {
104     if (!Param->isImplicit())
105       break;
106 
107     if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
108       const auto *TC = TTP->getTypeConstraint();
109       if (TC && TC->getImmediatelyDeclaredConstraint()
110                     ->containsUnexpandedParameterPack())
111         return true;
112     }
113   }
114 
115   return false;
116 }
117 
118 TemplateParameterList *
119 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
120                               SourceLocation LAngleLoc,
121                               ArrayRef<NamedDecl *> Params,
122                               SourceLocation RAngleLoc, Expr *RequiresClause) {
123   void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
124                              Params.size(), RequiresClause ? 1u : 0u),
125                          alignof(TemplateParameterList));
126   return new (Mem) TemplateParameterList(C, TemplateLoc, LAngleLoc, Params,
127                                          RAngleLoc, RequiresClause);
128 }
129 
130 void TemplateParameterList::Profile(llvm::FoldingSetNodeID &ID,
131                                     const ASTContext &C) const {
132   const Expr *RC = getRequiresClause();
133   ID.AddBoolean(RC != nullptr);
134   if (RC)
135     RC->Profile(ID, C, /*Canonical=*/true);
136   ID.AddInteger(size());
137   for (NamedDecl *D : *this) {
138     if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
139       ID.AddInteger(0);
140       ID.AddBoolean(NTTP->isParameterPack());
141       NTTP->getType().getCanonicalType().Profile(ID);
142       ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint());
143       if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
144         E->Profile(ID, C, /*Canonical=*/true);
145       continue;
146     }
147     if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {
148       ID.AddInteger(1);
149       ID.AddBoolean(TTP->isParameterPack());
150       ID.AddBoolean(TTP->hasTypeConstraint());
151       if (const TypeConstraint *TC = TTP->getTypeConstraint())
152         TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,
153                                                         /*Canonical=*/true);
154       continue;
155     }
156     const auto *TTP = cast<TemplateTemplateParmDecl>(D);
157     ID.AddInteger(2);
158     ID.AddBoolean(TTP->isParameterPack());
159     TTP->getTemplateParameters()->Profile(ID, C);
160   }
161 }
162 
163 unsigned TemplateParameterList::getMinRequiredArguments() const {
164   unsigned NumRequiredArgs = 0;
165   for (const NamedDecl *P : asArray()) {
166     if (P->isTemplateParameterPack()) {
167       if (std::optional<unsigned> Expansions = getExpandedPackSize(P)) {
168         NumRequiredArgs += *Expansions;
169         continue;
170       }
171       break;
172     }
173 
174     if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
175       if (TTP->hasDefaultArgument())
176         break;
177     } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
178       if (NTTP->hasDefaultArgument())
179         break;
180     } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
181       break;
182 
183     ++NumRequiredArgs;
184   }
185 
186   return NumRequiredArgs;
187 }
188 
189 unsigned TemplateParameterList::getDepth() const {
190   if (size() == 0)
191     return 0;
192 
193   const NamedDecl *FirstParm = getParam(0);
194   if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
195     return TTP->getDepth();
196   else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
197     return NTTP->getDepth();
198   else
199     return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
200 }
201 
202 static bool AdoptTemplateParameterList(TemplateParameterList *Params,
203                                        DeclContext *Owner) {
204   bool Invalid = false;
205   for (NamedDecl *P : *Params) {
206     P->setDeclContext(Owner);
207 
208     if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
209       if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner))
210         Invalid = true;
211 
212     if (P->isInvalidDecl())
213       Invalid = true;
214   }
215   return Invalid;
216 }
217 
218 void TemplateParameterList::
219 getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
220   if (HasConstrainedParameters)
221     for (const NamedDecl *Param : *this) {
222       if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
223         if (const auto *TC = TTP->getTypeConstraint())
224           AC.push_back(TC->getImmediatelyDeclaredConstraint());
225       } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
226         if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
227           AC.push_back(E);
228       }
229     }
230   if (HasRequiresClause)
231     AC.push_back(getRequiresClause());
232 }
233 
234 bool TemplateParameterList::hasAssociatedConstraints() const {
235   return HasRequiresClause || HasConstrainedParameters;
236 }
237 
238 bool TemplateParameterList::shouldIncludeTypeForArgument(
239     const PrintingPolicy &Policy, const TemplateParameterList *TPL,
240     unsigned Idx) {
241   if (!TPL || Idx >= TPL->size() || Policy.AlwaysIncludeTypeForTemplateArgument)
242     return true;
243   const NamedDecl *TemplParam = TPL->getParam(Idx);
244   if (const auto *ParamValueDecl =
245           dyn_cast<NonTypeTemplateParmDecl>(TemplParam))
246     if (ParamValueDecl->getType()->getContainedDeducedType())
247       return true;
248   return false;
249 }
250 
251 namespace clang {
252 
253 void *allocateDefaultArgStorageChain(const ASTContext &C) {
254   return new (C) char[sizeof(void*) * 2];
255 }
256 
257 } // namespace clang
258 
259 //===----------------------------------------------------------------------===//
260 // TemplateDecl Implementation
261 //===----------------------------------------------------------------------===//
262 
263 TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
264                            DeclarationName Name, TemplateParameterList *Params,
265                            NamedDecl *Decl)
266     : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
267 
268 void TemplateDecl::anchor() {}
269 
270 void TemplateDecl::
271 getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
272   TemplateParams->getAssociatedConstraints(AC);
273   if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
274     if (const Expr *TRC = FD->getTrailingRequiresClause())
275       AC.push_back(TRC);
276 }
277 
278 bool TemplateDecl::hasAssociatedConstraints() const {
279   if (TemplateParams->hasAssociatedConstraints())
280     return true;
281   if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
282     return FD->getTrailingRequiresClause();
283   return false;
284 }
285 
286 bool TemplateDecl::isTypeAlias() const {
287   switch (getKind()) {
288   case TemplateDecl::TypeAliasTemplate:
289   case TemplateDecl::BuiltinTemplate:
290     return true;
291   default:
292     return false;
293   };
294 }
295 
296 //===----------------------------------------------------------------------===//
297 // RedeclarableTemplateDecl Implementation
298 //===----------------------------------------------------------------------===//
299 
300 void RedeclarableTemplateDecl::anchor() {}
301 
302 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
303   if (Common)
304     return Common;
305 
306   // Walk the previous-declaration chain until we either find a declaration
307   // with a common pointer or we run out of previous declarations.
308   SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
309   for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
310        Prev = Prev->getPreviousDecl()) {
311     if (Prev->Common) {
312       Common = Prev->Common;
313       break;
314     }
315 
316     PrevDecls.push_back(Prev);
317   }
318 
319   // If we never found a common pointer, allocate one now.
320   if (!Common) {
321     // FIXME: If any of the declarations is from an AST file, we probably
322     // need an update record to add the common data.
323 
324     Common = newCommon(getASTContext());
325   }
326 
327   // Update any previous declarations we saw with the common pointer.
328   for (const RedeclarableTemplateDecl *Prev : PrevDecls)
329     Prev->Common = Common;
330 
331   return Common;
332 }
333 
334 void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
335   // Grab the most recent declaration to ensure we've loaded any lazy
336   // redeclarations of this template.
337   CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
338   if (CommonBasePtr->LazySpecializations) {
339     ASTContext &Context = getASTContext();
340     uint32_t *Specs = CommonBasePtr->LazySpecializations;
341     CommonBasePtr->LazySpecializations = nullptr;
342     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
343       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
344   }
345 }
346 
347 template<class EntryType, typename... ProfileArguments>
348 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
349 RedeclarableTemplateDecl::findSpecializationImpl(
350     llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
351     ProfileArguments&&... ProfileArgs) {
352   using SETraits = SpecEntryTraits<EntryType>;
353 
354   llvm::FoldingSetNodeID ID;
355   EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
356                      getASTContext());
357   EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
358   return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
359 }
360 
361 template<class Derived, class EntryType>
362 void RedeclarableTemplateDecl::addSpecializationImpl(
363     llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
364     void *InsertPos) {
365   using SETraits = SpecEntryTraits<EntryType>;
366 
367   if (InsertPos) {
368 #ifndef NDEBUG
369     void *CorrectInsertPos;
370     assert(!findSpecializationImpl(Specializations,
371                                    CorrectInsertPos,
372                                    SETraits::getTemplateArgs(Entry)) &&
373            InsertPos == CorrectInsertPos &&
374            "given incorrect InsertPos for specialization");
375 #endif
376     Specializations.InsertNode(Entry, InsertPos);
377   } else {
378     EntryType *Existing = Specializations.GetOrInsertNode(Entry);
379     (void)Existing;
380     assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
381            "non-canonical specialization?");
382   }
383 
384   if (ASTMutationListener *L = getASTMutationListener())
385     L->AddedCXXTemplateSpecialization(cast<Derived>(this),
386                                       SETraits::getDecl(Entry));
387 }
388 
389 ArrayRef<TemplateArgument> RedeclarableTemplateDecl::getInjectedTemplateArgs() {
390   TemplateParameterList *Params = getTemplateParameters();
391   auto *CommonPtr = getCommonPtr();
392   if (!CommonPtr->InjectedArgs) {
393     auto &Context = getASTContext();
394     SmallVector<TemplateArgument, 16> TemplateArgs;
395     Context.getInjectedTemplateArgs(Params, TemplateArgs);
396     CommonPtr->InjectedArgs =
397         new (Context) TemplateArgument[TemplateArgs.size()];
398     std::copy(TemplateArgs.begin(), TemplateArgs.end(),
399               CommonPtr->InjectedArgs);
400   }
401 
402   return llvm::ArrayRef(CommonPtr->InjectedArgs, Params->size());
403 }
404 
405 //===----------------------------------------------------------------------===//
406 // FunctionTemplateDecl Implementation
407 //===----------------------------------------------------------------------===//
408 
409 FunctionTemplateDecl *
410 FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
411                              DeclarationName Name,
412                              TemplateParameterList *Params, NamedDecl *Decl) {
413   bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
414   auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
415   if (Invalid)
416     TD->setInvalidDecl();
417   return TD;
418 }
419 
420 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
421                                                                unsigned ID) {
422   return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
423                                           DeclarationName(), nullptr, nullptr);
424 }
425 
426 RedeclarableTemplateDecl::CommonBase *
427 FunctionTemplateDecl::newCommon(ASTContext &C) const {
428   auto *CommonPtr = new (C) Common;
429   C.addDestruction(CommonPtr);
430   return CommonPtr;
431 }
432 
433 void FunctionTemplateDecl::LoadLazySpecializations() const {
434   loadLazySpecializationsImpl();
435 }
436 
437 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
438 FunctionTemplateDecl::getSpecializations() const {
439   LoadLazySpecializations();
440   return getCommonPtr()->Specializations;
441 }
442 
443 FunctionDecl *
444 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
445                                          void *&InsertPos) {
446   return findSpecializationImpl(getSpecializations(), InsertPos, Args);
447 }
448 
449 void FunctionTemplateDecl::addSpecialization(
450       FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
451   addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
452                                               InsertPos);
453 }
454 
455 void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
456   using Base = RedeclarableTemplateDecl;
457 
458   // If we haven't created a common pointer yet, then it can just be created
459   // with the usual method.
460   if (!Base::Common)
461     return;
462 
463   Common *ThisCommon = static_cast<Common *>(Base::Common);
464   Common *PrevCommon = nullptr;
465   SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
466   for (; Prev; Prev = Prev->getPreviousDecl()) {
467     if (Prev->Base::Common) {
468       PrevCommon = static_cast<Common *>(Prev->Base::Common);
469       break;
470     }
471     PreviousDecls.push_back(Prev);
472   }
473 
474   // If the previous redecl chain hasn't created a common pointer yet, then just
475   // use this common pointer.
476   if (!PrevCommon) {
477     for (auto *D : PreviousDecls)
478       D->Base::Common = ThisCommon;
479     return;
480   }
481 
482   // Ensure we don't leak any important state.
483   assert(ThisCommon->Specializations.size() == 0 &&
484          "Can't merge incompatible declarations!");
485 
486   Base::Common = PrevCommon;
487 }
488 
489 //===----------------------------------------------------------------------===//
490 // ClassTemplateDecl Implementation
491 //===----------------------------------------------------------------------===//
492 
493 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC,
494                                              SourceLocation L,
495                                              DeclarationName Name,
496                                              TemplateParameterList *Params,
497                                              NamedDecl *Decl) {
498   bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
499   auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
500   if (Invalid)
501     TD->setInvalidDecl();
502   return TD;
503 }
504 
505 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
506                                                          unsigned ID) {
507   return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
508                                        DeclarationName(), nullptr, nullptr);
509 }
510 
511 void ClassTemplateDecl::LoadLazySpecializations() const {
512   loadLazySpecializationsImpl();
513 }
514 
515 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
516 ClassTemplateDecl::getSpecializations() const {
517   LoadLazySpecializations();
518   return getCommonPtr()->Specializations;
519 }
520 
521 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
522 ClassTemplateDecl::getPartialSpecializations() const {
523   LoadLazySpecializations();
524   return getCommonPtr()->PartialSpecializations;
525 }
526 
527 RedeclarableTemplateDecl::CommonBase *
528 ClassTemplateDecl::newCommon(ASTContext &C) const {
529   auto *CommonPtr = new (C) Common;
530   C.addDestruction(CommonPtr);
531   return CommonPtr;
532 }
533 
534 ClassTemplateSpecializationDecl *
535 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
536                                       void *&InsertPos) {
537   return findSpecializationImpl(getSpecializations(), InsertPos, Args);
538 }
539 
540 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
541                                           void *InsertPos) {
542   addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
543 }
544 
545 ClassTemplatePartialSpecializationDecl *
546 ClassTemplateDecl::findPartialSpecialization(
547     ArrayRef<TemplateArgument> Args,
548     TemplateParameterList *TPL, void *&InsertPos) {
549   return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
550                                 TPL);
551 }
552 
553 void ClassTemplatePartialSpecializationDecl::Profile(
554     llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
555     TemplateParameterList *TPL, const ASTContext &Context) {
556   ID.AddInteger(TemplateArgs.size());
557   for (const TemplateArgument &TemplateArg : TemplateArgs)
558     TemplateArg.Profile(ID, Context);
559   TPL->Profile(ID, Context);
560 }
561 
562 void ClassTemplateDecl::AddPartialSpecialization(
563                                       ClassTemplatePartialSpecializationDecl *D,
564                                       void *InsertPos) {
565   if (InsertPos)
566     getPartialSpecializations().InsertNode(D, InsertPos);
567   else {
568     ClassTemplatePartialSpecializationDecl *Existing
569       = getPartialSpecializations().GetOrInsertNode(D);
570     (void)Existing;
571     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
572   }
573 
574   if (ASTMutationListener *L = getASTMutationListener())
575     L->AddedCXXTemplateSpecialization(this, D);
576 }
577 
578 void ClassTemplateDecl::getPartialSpecializations(
579     SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) const {
580   llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
581     = getPartialSpecializations();
582   PS.clear();
583   PS.reserve(PartialSpecs.size());
584   for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
585     PS.push_back(P.getMostRecentDecl());
586 }
587 
588 ClassTemplatePartialSpecializationDecl *
589 ClassTemplateDecl::findPartialSpecialization(QualType T) {
590   ASTContext &Context = getASTContext();
591   for (ClassTemplatePartialSpecializationDecl &P :
592        getPartialSpecializations()) {
593     if (Context.hasSameType(P.getInjectedSpecializationType(), T))
594       return P.getMostRecentDecl();
595   }
596 
597   return nullptr;
598 }
599 
600 ClassTemplatePartialSpecializationDecl *
601 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
602                                     ClassTemplatePartialSpecializationDecl *D) {
603   Decl *DCanon = D->getCanonicalDecl();
604   for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
605     if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
606       return P.getMostRecentDecl();
607   }
608 
609   return nullptr;
610 }
611 
612 QualType
613 ClassTemplateDecl::getInjectedClassNameSpecialization() {
614   Common *CommonPtr = getCommonPtr();
615   if (!CommonPtr->InjectedClassNameType.isNull())
616     return CommonPtr->InjectedClassNameType;
617 
618   // C++0x [temp.dep.type]p2:
619   //  The template argument list of a primary template is a template argument
620   //  list in which the nth template argument has the value of the nth template
621   //  parameter of the class template. If the nth template parameter is a
622   //  template parameter pack (14.5.3), the nth template argument is a pack
623   //  expansion (14.5.3) whose pattern is the name of the template parameter
624   //  pack.
625   ASTContext &Context = getASTContext();
626   TemplateParameterList *Params = getTemplateParameters();
627   SmallVector<TemplateArgument, 16> TemplateArgs;
628   Context.getInjectedTemplateArgs(Params, TemplateArgs);
629   CommonPtr->InjectedClassNameType
630     = Context.getTemplateSpecializationType(TemplateName(this),
631                                             TemplateArgs);
632   return CommonPtr->InjectedClassNameType;
633 }
634 
635 //===----------------------------------------------------------------------===//
636 // TemplateTypeParm Allocation/Deallocation Method Implementations
637 //===----------------------------------------------------------------------===//
638 
639 TemplateTypeParmDecl *TemplateTypeParmDecl::Create(
640     const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
641     SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
642     bool Typename, bool ParameterPack, bool HasTypeConstraint,
643     std::optional<unsigned> NumExpanded) {
644   auto *TTPDecl =
645       new (C, DC,
646            additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
647       TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
648                            HasTypeConstraint, NumExpanded);
649   QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
650   TTPDecl->setTypeForDecl(TTPType.getTypePtr());
651   return TTPDecl;
652 }
653 
654 TemplateTypeParmDecl *
655 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
656   return new (C, ID)
657       TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
658                            false, false, std::nullopt);
659 }
660 
661 TemplateTypeParmDecl *
662 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID,
663                                          bool HasTypeConstraint) {
664   return new (C, ID,
665               additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
666       TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
667                            false, HasTypeConstraint, std::nullopt);
668 }
669 
670 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
671   return hasDefaultArgument()
672              ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
673              : SourceLocation();
674 }
675 
676 SourceRange TemplateTypeParmDecl::getSourceRange() const {
677   if (hasDefaultArgument() && !defaultArgumentWasInherited())
678     return SourceRange(getBeginLoc(),
679                        getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
680   // TypeDecl::getSourceRange returns a range containing name location, which is
681   // wrong for unnamed template parameters. e.g:
682   // it will return <[[typename>]] instead of <[[typename]]>
683   else if (getDeclName().isEmpty())
684     return SourceRange(getBeginLoc());
685   return TypeDecl::getSourceRange();
686 }
687 
688 unsigned TemplateTypeParmDecl::getDepth() const {
689   return getTypeForDecl()->castAs<TemplateTypeParmType>()->getDepth();
690 }
691 
692 unsigned TemplateTypeParmDecl::getIndex() const {
693   return getTypeForDecl()->castAs<TemplateTypeParmType>()->getIndex();
694 }
695 
696 bool TemplateTypeParmDecl::isParameterPack() const {
697   return getTypeForDecl()->castAs<TemplateTypeParmType>()->isParameterPack();
698 }
699 
700 void TemplateTypeParmDecl::setTypeConstraint(
701     ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint) {
702   assert(HasTypeConstraint &&
703          "HasTypeConstraint=true must be passed at construction in order to "
704          "call setTypeConstraint");
705   assert(!TypeConstraintInitialized &&
706          "TypeConstraint was already initialized!");
707   new (getTrailingObjects<TypeConstraint>())
708       TypeConstraint(Loc, ImmediatelyDeclaredConstraint);
709   TypeConstraintInitialized = true;
710 }
711 
712 //===----------------------------------------------------------------------===//
713 // NonTypeTemplateParmDecl Method Implementations
714 //===----------------------------------------------------------------------===//
715 
716 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
717     DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
718     unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
719     ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
720     : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
721       TemplateParmPosition(D, P), ParameterPack(true),
722       ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
723   if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
724     auto TypesAndInfos =
725         getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
726     for (unsigned I = 0; I != NumExpandedTypes; ++I) {
727       new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
728       TypesAndInfos[I].second = ExpandedTInfos[I];
729     }
730   }
731 }
732 
733 NonTypeTemplateParmDecl *
734 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
735                                 SourceLocation StartLoc, SourceLocation IdLoc,
736                                 unsigned D, unsigned P, IdentifierInfo *Id,
737                                 QualType T, bool ParameterPack,
738                                 TypeSourceInfo *TInfo) {
739   AutoType *AT =
740       C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
741   return new (C, DC,
742               additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
743                                     Expr *>(0,
744                                             AT && AT->isConstrained() ? 1 : 0))
745       NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,
746                               TInfo);
747 }
748 
749 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
750     const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
751     SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
752     QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
753     ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
754   AutoType *AT = TInfo->getType()->getContainedAutoType();
755   return new (C, DC,
756               additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
757                                     Expr *>(
758                   ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))
759       NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
760                               ExpandedTypes, ExpandedTInfos);
761 }
762 
763 NonTypeTemplateParmDecl *
764 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
765                                             bool HasTypeConstraint) {
766   return new (C, ID, additionalSizeToAlloc<std::pair<QualType,
767                                                      TypeSourceInfo *>,
768                                            Expr *>(0,
769                                                    HasTypeConstraint ? 1 : 0))
770           NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
771                                   0, 0, nullptr, QualType(), false, nullptr);
772 }
773 
774 NonTypeTemplateParmDecl *
775 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
776                                             unsigned NumExpandedTypes,
777                                             bool HasTypeConstraint) {
778   auto *NTTP =
779       new (C, ID,
780            additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
781                NumExpandedTypes, HasTypeConstraint ? 1 : 0))
782           NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
783                                   0, 0, nullptr, QualType(), nullptr,
784                                   std::nullopt, std::nullopt);
785   NTTP->NumExpandedTypes = NumExpandedTypes;
786   return NTTP;
787 }
788 
789 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
790   if (hasDefaultArgument() && !defaultArgumentWasInherited())
791     return SourceRange(getOuterLocStart(),
792                        getDefaultArgument()->getSourceRange().getEnd());
793   return DeclaratorDecl::getSourceRange();
794 }
795 
796 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
797   return hasDefaultArgument()
798     ? getDefaultArgument()->getSourceRange().getBegin()
799     : SourceLocation();
800 }
801 
802 //===----------------------------------------------------------------------===//
803 // TemplateTemplateParmDecl Method Implementations
804 //===----------------------------------------------------------------------===//
805 
806 void TemplateTemplateParmDecl::anchor() {}
807 
808 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
809     DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
810     IdentifierInfo *Id, TemplateParameterList *Params,
811     ArrayRef<TemplateParameterList *> Expansions)
812     : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
813       TemplateParmPosition(D, P), ParameterPack(true),
814       ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
815   if (!Expansions.empty())
816     std::uninitialized_copy(Expansions.begin(), Expansions.end(),
817                             getTrailingObjects<TemplateParameterList *>());
818 }
819 
820 TemplateTemplateParmDecl *
821 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
822                                  SourceLocation L, unsigned D, unsigned P,
823                                  bool ParameterPack, IdentifierInfo *Id,
824                                  TemplateParameterList *Params) {
825   return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
826                                               Params);
827 }
828 
829 TemplateTemplateParmDecl *
830 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
831                                  SourceLocation L, unsigned D, unsigned P,
832                                  IdentifierInfo *Id,
833                                  TemplateParameterList *Params,
834                                  ArrayRef<TemplateParameterList *> Expansions) {
835   return new (C, DC,
836               additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
837       TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
838 }
839 
840 TemplateTemplateParmDecl *
841 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
842   return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
843                                               false, nullptr, nullptr);
844 }
845 
846 TemplateTemplateParmDecl *
847 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
848                                              unsigned NumExpansions) {
849   auto *TTP =
850       new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
851           TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
852                                    nullptr, std::nullopt);
853   TTP->NumExpandedParams = NumExpansions;
854   return TTP;
855 }
856 
857 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
858   return hasDefaultArgument() ? getDefaultArgument().getLocation()
859                               : SourceLocation();
860 }
861 
862 void TemplateTemplateParmDecl::setDefaultArgument(
863     const ASTContext &C, const TemplateArgumentLoc &DefArg) {
864   if (DefArg.getArgument().isNull())
865     DefaultArgument.set(nullptr);
866   else
867     DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
868 }
869 
870 //===----------------------------------------------------------------------===//
871 // TemplateArgumentList Implementation
872 //===----------------------------------------------------------------------===//
873 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
874     : Arguments(getTrailingObjects<TemplateArgument>()),
875       NumArguments(Args.size()) {
876   std::uninitialized_copy(Args.begin(), Args.end(),
877                           getTrailingObjects<TemplateArgument>());
878 }
879 
880 TemplateArgumentList *
881 TemplateArgumentList::CreateCopy(ASTContext &Context,
882                                  ArrayRef<TemplateArgument> Args) {
883   void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
884   return new (Mem) TemplateArgumentList(Args);
885 }
886 
887 FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
888     ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
889     TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
890     const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
891     MemberSpecializationInfo *MSInfo) {
892   const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
893   if (TemplateArgsAsWritten)
894     ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
895                                                         *TemplateArgsAsWritten);
896 
897   void *Mem =
898       C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
899   return new (Mem) FunctionTemplateSpecializationInfo(
900       FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
901 }
902 
903 //===----------------------------------------------------------------------===//
904 // ClassTemplateSpecializationDecl Implementation
905 //===----------------------------------------------------------------------===//
906 
907 ClassTemplateSpecializationDecl::
908 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
909                                 DeclContext *DC, SourceLocation StartLoc,
910                                 SourceLocation IdLoc,
911                                 ClassTemplateDecl *SpecializedTemplate,
912                                 ArrayRef<TemplateArgument> Args,
913                                 ClassTemplateSpecializationDecl *PrevDecl)
914     : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
915                     SpecializedTemplate->getIdentifier(), PrevDecl),
916     SpecializedTemplate(SpecializedTemplate),
917     TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
918     SpecializationKind(TSK_Undeclared) {
919 }
920 
921 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
922                                                                  Kind DK)
923     : CXXRecordDecl(DK, TagTypeKind::Struct, C, nullptr, SourceLocation(),
924                     SourceLocation(), nullptr, nullptr),
925       SpecializationKind(TSK_Undeclared) {}
926 
927 ClassTemplateSpecializationDecl *
928 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
929                                         DeclContext *DC,
930                                         SourceLocation StartLoc,
931                                         SourceLocation IdLoc,
932                                         ClassTemplateDecl *SpecializedTemplate,
933                                         ArrayRef<TemplateArgument> Args,
934                                    ClassTemplateSpecializationDecl *PrevDecl) {
935   auto *Result =
936       new (Context, DC) ClassTemplateSpecializationDecl(
937           Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
938           SpecializedTemplate, Args, PrevDecl);
939   Result->setMayHaveOutOfDateDef(false);
940 
941   // If the template decl is incomplete, copy the external lexical storage from
942   // the base template. This allows instantiations of incomplete types to
943   // complete using the external AST if the template's declaration came from an
944   // external AST.
945   if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
946     Result->setHasExternalLexicalStorage(
947       SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
948 
949   Context.getTypeDeclType(Result, PrevDecl);
950   return Result;
951 }
952 
953 ClassTemplateSpecializationDecl *
954 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
955                                                     unsigned ID) {
956   auto *Result =
957     new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
958   Result->setMayHaveOutOfDateDef(false);
959   return Result;
960 }
961 
962 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
963     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
964   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
965 
966   const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
967   if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
968           PS ? PS->getTemplateArgsAsWritten() : nullptr) {
969     printTemplateArgumentList(
970         OS, ArgsAsWritten->arguments(), Policy,
971         getSpecializedTemplate()->getTemplateParameters());
972   } else {
973     const TemplateArgumentList &TemplateArgs = getTemplateArgs();
974     printTemplateArgumentList(
975         OS, TemplateArgs.asArray(), Policy,
976         getSpecializedTemplate()->getTemplateParameters());
977   }
978 }
979 
980 ClassTemplateDecl *
981 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
982   if (const auto *PartialSpec =
983           SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
984     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
985   return SpecializedTemplate.get<ClassTemplateDecl*>();
986 }
987 
988 SourceRange
989 ClassTemplateSpecializationDecl::getSourceRange() const {
990   if (ExplicitInfo) {
991     SourceLocation Begin = getTemplateKeywordLoc();
992     if (Begin.isValid()) {
993       // Here we have an explicit (partial) specialization or instantiation.
994       assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
995              getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
996              getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
997       if (getExternLoc().isValid())
998         Begin = getExternLoc();
999       SourceLocation End = getBraceRange().getEnd();
1000       if (End.isInvalid())
1001         End = getTypeAsWritten()->getTypeLoc().getEndLoc();
1002       return SourceRange(Begin, End);
1003     }
1004     // An implicit instantiation of a class template partial specialization
1005     // uses ExplicitInfo to record the TypeAsWritten, but the source
1006     // locations should be retrieved from the instantiation pattern.
1007     using CTPSDecl = ClassTemplatePartialSpecializationDecl;
1008     auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
1009     CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
1010     assert(inst_from != nullptr);
1011     return inst_from->getSourceRange();
1012   }
1013   else {
1014     // No explicit info available.
1015     llvm::PointerUnion<ClassTemplateDecl *,
1016                        ClassTemplatePartialSpecializationDecl *>
1017       inst_from = getInstantiatedFrom();
1018     if (inst_from.isNull())
1019       return getSpecializedTemplate()->getSourceRange();
1020     if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
1021       return ctd->getSourceRange();
1022     return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
1023       ->getSourceRange();
1024   }
1025 }
1026 
1027 //===----------------------------------------------------------------------===//
1028 // ConceptDecl Implementation
1029 //===----------------------------------------------------------------------===//
1030 ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
1031                                  SourceLocation L, DeclarationName Name,
1032                                  TemplateParameterList *Params,
1033                                  Expr *ConstraintExpr) {
1034   bool Invalid = AdoptTemplateParameterList(Params, DC);
1035   auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1036   if (Invalid)
1037     TD->setInvalidDecl();
1038   return TD;
1039 }
1040 
1041 ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C,
1042                                              unsigned ID) {
1043   ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1044                                                 DeclarationName(),
1045                                                 nullptr, nullptr);
1046 
1047   return Result;
1048 }
1049 
1050 //===----------------------------------------------------------------------===//
1051 // ImplicitConceptSpecializationDecl Implementation
1052 //===----------------------------------------------------------------------===//
1053 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1054     DeclContext *DC, SourceLocation SL,
1055     ArrayRef<TemplateArgument> ConvertedArgs)
1056     : Decl(ImplicitConceptSpecialization, DC, SL),
1057       NumTemplateArgs(ConvertedArgs.size()) {
1058   setTemplateArguments(ConvertedArgs);
1059 }
1060 
1061 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1062     EmptyShell Empty, unsigned NumTemplateArgs)
1063     : Decl(ImplicitConceptSpecialization, Empty),
1064       NumTemplateArgs(NumTemplateArgs) {}
1065 
1066 ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create(
1067     const ASTContext &C, DeclContext *DC, SourceLocation SL,
1068     ArrayRef<TemplateArgument> ConvertedArgs) {
1069   return new (C, DC,
1070               additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1071       ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1072 }
1073 
1074 ImplicitConceptSpecializationDecl *
1075 ImplicitConceptSpecializationDecl::CreateDeserialized(
1076     const ASTContext &C, unsigned ID, unsigned NumTemplateArgs) {
1077   return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1078       ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);
1079 }
1080 
1081 void ImplicitConceptSpecializationDecl::setTemplateArguments(
1082     ArrayRef<TemplateArgument> Converted) {
1083   assert(Converted.size() == NumTemplateArgs);
1084   std::uninitialized_copy(Converted.begin(), Converted.end(),
1085                           getTrailingObjects<TemplateArgument>());
1086 }
1087 
1088 //===----------------------------------------------------------------------===//
1089 // ClassTemplatePartialSpecializationDecl Implementation
1090 //===----------------------------------------------------------------------===//
1091 void ClassTemplatePartialSpecializationDecl::anchor() {}
1092 
1093 ClassTemplatePartialSpecializationDecl::
1094 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
1095                                        DeclContext *DC,
1096                                        SourceLocation StartLoc,
1097                                        SourceLocation IdLoc,
1098                                        TemplateParameterList *Params,
1099                                        ClassTemplateDecl *SpecializedTemplate,
1100                                        ArrayRef<TemplateArgument> Args,
1101                                const ASTTemplateArgumentListInfo *ArgInfos,
1102                                ClassTemplatePartialSpecializationDecl *PrevDecl)
1103     : ClassTemplateSpecializationDecl(Context,
1104                                       ClassTemplatePartialSpecialization,
1105                                       TK, DC, StartLoc, IdLoc,
1106                                       SpecializedTemplate, Args, PrevDecl),
1107       TemplateParams(Params), ArgsAsWritten(ArgInfos),
1108       InstantiatedFromMember(nullptr, false) {
1109   if (AdoptTemplateParameterList(Params, this))
1110     setInvalidDecl();
1111 }
1112 
1113 ClassTemplatePartialSpecializationDecl *
1114 ClassTemplatePartialSpecializationDecl::
1115 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
1116        SourceLocation StartLoc, SourceLocation IdLoc,
1117        TemplateParameterList *Params,
1118        ClassTemplateDecl *SpecializedTemplate,
1119        ArrayRef<TemplateArgument> Args,
1120        const TemplateArgumentListInfo &ArgInfos,
1121        QualType CanonInjectedType,
1122        ClassTemplatePartialSpecializationDecl *PrevDecl) {
1123   const ASTTemplateArgumentListInfo *ASTArgInfos =
1124     ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1125 
1126   auto *Result = new (Context, DC)
1127       ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
1128                                              Params, SpecializedTemplate, Args,
1129                                              ASTArgInfos, PrevDecl);
1130   Result->setSpecializationKind(TSK_ExplicitSpecialization);
1131   Result->setMayHaveOutOfDateDef(false);
1132 
1133   Context.getInjectedClassNameType(Result, CanonInjectedType);
1134   return Result;
1135 }
1136 
1137 ClassTemplatePartialSpecializationDecl *
1138 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1139                                                            unsigned ID) {
1140   auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
1141   Result->setMayHaveOutOfDateDef(false);
1142   return Result;
1143 }
1144 
1145 //===----------------------------------------------------------------------===//
1146 // FriendTemplateDecl Implementation
1147 //===----------------------------------------------------------------------===//
1148 
1149 void FriendTemplateDecl::anchor() {}
1150 
1151 FriendTemplateDecl *
1152 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
1153                            SourceLocation L,
1154                            MutableArrayRef<TemplateParameterList *> Params,
1155                            FriendUnion Friend, SourceLocation FLoc) {
1156   TemplateParameterList **TPL = nullptr;
1157   if (!Params.empty()) {
1158     TPL = new (Context) TemplateParameterList *[Params.size()];
1159     llvm::copy(Params, TPL);
1160   }
1161   return new (Context, DC)
1162       FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
1163 }
1164 
1165 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
1166                                                            unsigned ID) {
1167   return new (C, ID) FriendTemplateDecl(EmptyShell());
1168 }
1169 
1170 //===----------------------------------------------------------------------===//
1171 // TypeAliasTemplateDecl Implementation
1172 //===----------------------------------------------------------------------===//
1173 
1174 TypeAliasTemplateDecl *
1175 TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
1176                               DeclarationName Name,
1177                               TemplateParameterList *Params, NamedDecl *Decl) {
1178   bool Invalid = AdoptTemplateParameterList(Params, DC);
1179   auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1180   if (Invalid)
1181     TD->setInvalidDecl();
1182   return TD;
1183 }
1184 
1185 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
1186                                                                  unsigned ID) {
1187   return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1188                                            DeclarationName(), nullptr, nullptr);
1189 }
1190 
1191 RedeclarableTemplateDecl::CommonBase *
1192 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
1193   auto *CommonPtr = new (C) Common;
1194   C.addDestruction(CommonPtr);
1195   return CommonPtr;
1196 }
1197 
1198 //===----------------------------------------------------------------------===//
1199 // VarTemplateDecl Implementation
1200 //===----------------------------------------------------------------------===//
1201 
1202 VarTemplateDecl *VarTemplateDecl::getDefinition() {
1203   VarTemplateDecl *CurD = this;
1204   while (CurD) {
1205     if (CurD->isThisDeclarationADefinition())
1206       return CurD;
1207     CurD = CurD->getPreviousDecl();
1208   }
1209   return nullptr;
1210 }
1211 
1212 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
1213                                          SourceLocation L, DeclarationName Name,
1214                                          TemplateParameterList *Params,
1215                                          VarDecl *Decl) {
1216   bool Invalid = AdoptTemplateParameterList(Params, DC);
1217   auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1218   if (Invalid)
1219     TD->setInvalidDecl();
1220   return TD;
1221 }
1222 
1223 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
1224                                                      unsigned ID) {
1225   return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1226                                      DeclarationName(), nullptr, nullptr);
1227 }
1228 
1229 void VarTemplateDecl::LoadLazySpecializations() const {
1230   loadLazySpecializationsImpl();
1231 }
1232 
1233 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1234 VarTemplateDecl::getSpecializations() const {
1235   LoadLazySpecializations();
1236   return getCommonPtr()->Specializations;
1237 }
1238 
1239 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1240 VarTemplateDecl::getPartialSpecializations() const {
1241   LoadLazySpecializations();
1242   return getCommonPtr()->PartialSpecializations;
1243 }
1244 
1245 RedeclarableTemplateDecl::CommonBase *
1246 VarTemplateDecl::newCommon(ASTContext &C) const {
1247   auto *CommonPtr = new (C) Common;
1248   C.addDestruction(CommonPtr);
1249   return CommonPtr;
1250 }
1251 
1252 VarTemplateSpecializationDecl *
1253 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1254                                     void *&InsertPos) {
1255   return findSpecializationImpl(getSpecializations(), InsertPos, Args);
1256 }
1257 
1258 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1259                                         void *InsertPos) {
1260   addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1261 }
1262 
1263 VarTemplatePartialSpecializationDecl *
1264 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1265      TemplateParameterList *TPL, void *&InsertPos) {
1266   return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1267                                 TPL);
1268 }
1269 
1270 void VarTemplatePartialSpecializationDecl::Profile(
1271     llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1272     TemplateParameterList *TPL, const ASTContext &Context) {
1273   ID.AddInteger(TemplateArgs.size());
1274   for (const TemplateArgument &TemplateArg : TemplateArgs)
1275     TemplateArg.Profile(ID, Context);
1276   TPL->Profile(ID, Context);
1277 }
1278 
1279 void VarTemplateDecl::AddPartialSpecialization(
1280     VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1281   if (InsertPos)
1282     getPartialSpecializations().InsertNode(D, InsertPos);
1283   else {
1284     VarTemplatePartialSpecializationDecl *Existing =
1285         getPartialSpecializations().GetOrInsertNode(D);
1286     (void)Existing;
1287     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1288   }
1289 
1290   if (ASTMutationListener *L = getASTMutationListener())
1291     L->AddedCXXTemplateSpecialization(this, D);
1292 }
1293 
1294 void VarTemplateDecl::getPartialSpecializations(
1295     SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const {
1296   llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1297       getPartialSpecializations();
1298   PS.clear();
1299   PS.reserve(PartialSpecs.size());
1300   for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1301     PS.push_back(P.getMostRecentDecl());
1302 }
1303 
1304 VarTemplatePartialSpecializationDecl *
1305 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1306     VarTemplatePartialSpecializationDecl *D) {
1307   Decl *DCanon = D->getCanonicalDecl();
1308   for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1309     if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1310       return P.getMostRecentDecl();
1311   }
1312 
1313   return nullptr;
1314 }
1315 
1316 //===----------------------------------------------------------------------===//
1317 // VarTemplateSpecializationDecl Implementation
1318 //===----------------------------------------------------------------------===//
1319 
1320 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1321     Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1322     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1323     TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1324     : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1325               SpecializedTemplate->getIdentifier(), T, TInfo, S),
1326       SpecializedTemplate(SpecializedTemplate),
1327       TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1328       SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1329 
1330 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1331                                                              ASTContext &C)
1332     : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1333               QualType(), nullptr, SC_None),
1334       SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1335 
1336 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1337     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1338     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1339     TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1340   return new (Context, DC) VarTemplateSpecializationDecl(
1341       VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1342       SpecializedTemplate, T, TInfo, S, Args);
1343 }
1344 
1345 VarTemplateSpecializationDecl *
1346 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1347   return new (C, ID)
1348       VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1349 }
1350 
1351 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1352     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1353   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1354 
1355   const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1356   if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1357           PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1358     printTemplateArgumentList(
1359         OS, ArgsAsWritten->arguments(), Policy,
1360         getSpecializedTemplate()->getTemplateParameters());
1361   } else {
1362     const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1363     printTemplateArgumentList(
1364         OS, TemplateArgs.asArray(), Policy,
1365         getSpecializedTemplate()->getTemplateParameters());
1366   }
1367 }
1368 
1369 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1370   if (const auto *PartialSpec =
1371           SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1372     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1373   return SpecializedTemplate.get<VarTemplateDecl *>();
1374 }
1375 
1376 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1377     const TemplateArgumentListInfo &ArgsInfo) {
1378   TemplateArgsInfo =
1379       ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo);
1380 }
1381 
1382 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1383     const ASTTemplateArgumentListInfo *ArgsInfo) {
1384   TemplateArgsInfo =
1385       ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo);
1386 }
1387 
1388 SourceRange VarTemplateSpecializationDecl::getSourceRange() const {
1389   if (isExplicitSpecialization() && !hasInit()) {
1390     if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsInfo())
1391       return SourceRange(getOuterLocStart(), Info->getRAngleLoc());
1392   }
1393   return VarDecl::getSourceRange();
1394 }
1395 
1396 
1397 //===----------------------------------------------------------------------===//
1398 // VarTemplatePartialSpecializationDecl Implementation
1399 //===----------------------------------------------------------------------===//
1400 
1401 void VarTemplatePartialSpecializationDecl::anchor() {}
1402 
1403 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1404     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1405     SourceLocation IdLoc, TemplateParameterList *Params,
1406     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1407     StorageClass S, ArrayRef<TemplateArgument> Args,
1408     const ASTTemplateArgumentListInfo *ArgInfos)
1409     : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1410                                     DC, StartLoc, IdLoc, SpecializedTemplate, T,
1411                                     TInfo, S, Args),
1412       TemplateParams(Params), ArgsAsWritten(ArgInfos),
1413       InstantiatedFromMember(nullptr, false) {
1414   if (AdoptTemplateParameterList(Params, DC))
1415     setInvalidDecl();
1416 }
1417 
1418 VarTemplatePartialSpecializationDecl *
1419 VarTemplatePartialSpecializationDecl::Create(
1420     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1421     SourceLocation IdLoc, TemplateParameterList *Params,
1422     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1423     StorageClass S, ArrayRef<TemplateArgument> Args,
1424     const TemplateArgumentListInfo &ArgInfos) {
1425   const ASTTemplateArgumentListInfo *ASTArgInfos
1426     = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1427 
1428   auto *Result =
1429       new (Context, DC) VarTemplatePartialSpecializationDecl(
1430           Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1431           S, Args, ASTArgInfos);
1432   Result->setSpecializationKind(TSK_ExplicitSpecialization);
1433   return Result;
1434 }
1435 
1436 VarTemplatePartialSpecializationDecl *
1437 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1438                                                          unsigned ID) {
1439   return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1440 }
1441 
1442 SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {
1443   if (isExplicitSpecialization() && !hasInit()) {
1444     if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsAsWritten())
1445       return SourceRange(getOuterLocStart(), Info->getRAngleLoc());
1446   }
1447   return VarDecl::getSourceRange();
1448 }
1449 
1450 static TemplateParameterList *
1451 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1452   // typename T
1453   auto *T = TemplateTypeParmDecl::Create(
1454       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1455       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1456       /*HasTypeConstraint=*/false);
1457   T->setImplicit(true);
1458 
1459   // T ...Ints
1460   TypeSourceInfo *TI =
1461       C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1462   auto *N = NonTypeTemplateParmDecl::Create(
1463       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1464       /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1465   N->setImplicit(true);
1466 
1467   // <typename T, T ...Ints>
1468   NamedDecl *P[2] = {T, N};
1469   auto *TPL = TemplateParameterList::Create(
1470       C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1471 
1472   // template <typename T, ...Ints> class IntSeq
1473   auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1474       C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1475       /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1476   TemplateTemplateParm->setImplicit(true);
1477 
1478   // typename T
1479   auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1480       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1481       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1482       /*HasTypeConstraint=*/false);
1483   TemplateTypeParm->setImplicit(true);
1484 
1485   // T N
1486   TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1487       QualType(TemplateTypeParm->getTypeForDecl(), 0));
1488   auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1489       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1490       /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1491   NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1492                          NonTypeTemplateParm};
1493 
1494   // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1495   return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1496                                        Params, SourceLocation(), nullptr);
1497 }
1498 
1499 static TemplateParameterList *
1500 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1501   // std::size_t Index
1502   TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1503   auto *Index = NonTypeTemplateParmDecl::Create(
1504       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1505       /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1506 
1507   // typename ...T
1508   auto *Ts = TemplateTypeParmDecl::Create(
1509       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1510       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
1511       /*HasTypeConstraint=*/false);
1512   Ts->setImplicit(true);
1513 
1514   // template <std::size_t Index, typename ...T>
1515   NamedDecl *Params[] = {Index, Ts};
1516   return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1517                                        llvm::ArrayRef(Params), SourceLocation(),
1518                                        nullptr);
1519 }
1520 
1521 static TemplateParameterList *createBuiltinTemplateParameterList(
1522     const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1523   switch (BTK) {
1524   case BTK__make_integer_seq:
1525     return createMakeIntegerSeqParameterList(C, DC);
1526   case BTK__type_pack_element:
1527     return createTypePackElementParameterList(C, DC);
1528   }
1529 
1530   llvm_unreachable("unhandled BuiltinTemplateKind!");
1531 }
1532 
1533 void BuiltinTemplateDecl::anchor() {}
1534 
1535 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1536                                          DeclarationName Name,
1537                                          BuiltinTemplateKind BTK)
1538     : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1539                    createBuiltinTemplateParameterList(C, DC, BTK)),
1540       BTK(BTK) {}
1541 
1542 TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1543                                                          QualType T,
1544                                                          const APValue &V) {
1545   DeclContext *DC = C.getTranslationUnitDecl();
1546   auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1547   C.addDestruction(&TPOD->Value);
1548   return TPOD;
1549 }
1550 
1551 TemplateParamObjectDecl *
1552 TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1553   auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1554   C.addDestruction(&TPOD->Value);
1555   return TPOD;
1556 }
1557 
1558 void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1559                                         const PrintingPolicy &Policy) const {
1560   OS << "<template param ";
1561   printAsExpr(OS, Policy);
1562   OS << ">";
1563 }
1564 
1565 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1566   printAsExpr(OS, getASTContext().getPrintingPolicy());
1567 }
1568 
1569 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1570                                           const PrintingPolicy &Policy) const {
1571   getType().getUnqualifiedType().print(OS, Policy);
1572   printAsInit(OS, Policy);
1573 }
1574 
1575 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1576   printAsInit(OS, getASTContext().getPrintingPolicy());
1577 }
1578 
1579 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1580                                           const PrintingPolicy &Policy) const {
1581   getValue().printPretty(OS, Policy, getType(), &getASTContext());
1582 }
1583 
1584 TemplateParameterList *clang::getReplacedTemplateParameterList(Decl *D) {
1585   switch (D->getKind()) {
1586   case Decl::Kind::ClassTemplate:
1587     return cast<ClassTemplateDecl>(D)->getTemplateParameters();
1588   case Decl::Kind::ClassTemplateSpecialization: {
1589     const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1590     auto P = CTSD->getSpecializedTemplateOrPartial();
1591     if (const auto *CTPSD =
1592             P.dyn_cast<ClassTemplatePartialSpecializationDecl *>())
1593       return CTPSD->getTemplateParameters();
1594     return cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1595   }
1596   case Decl::Kind::ClassTemplatePartialSpecialization:
1597     return cast<ClassTemplatePartialSpecializationDecl>(D)
1598         ->getTemplateParameters();
1599   case Decl::Kind::TypeAliasTemplate:
1600     return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
1601   case Decl::Kind::BuiltinTemplate:
1602     return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
1603   case Decl::Kind::CXXDeductionGuide:
1604   case Decl::Kind::CXXConversion:
1605   case Decl::Kind::CXXConstructor:
1606   case Decl::Kind::CXXDestructor:
1607   case Decl::Kind::CXXMethod:
1608   case Decl::Kind::Function:
1609     return cast<FunctionDecl>(D)
1610         ->getTemplateSpecializationInfo()
1611         ->getTemplate()
1612         ->getTemplateParameters();
1613   case Decl::Kind::FunctionTemplate:
1614     return cast<FunctionTemplateDecl>(D)->getTemplateParameters();
1615   case Decl::Kind::VarTemplate:
1616     return cast<VarTemplateDecl>(D)->getTemplateParameters();
1617   case Decl::Kind::VarTemplateSpecialization: {
1618     const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1619     auto P = VTSD->getSpecializedTemplateOrPartial();
1620     if (const auto *VTPSD =
1621             P.dyn_cast<VarTemplatePartialSpecializationDecl *>())
1622       return VTPSD->getTemplateParameters();
1623     return cast<VarTemplateDecl *>(P)->getTemplateParameters();
1624   }
1625   case Decl::Kind::VarTemplatePartialSpecialization:
1626     return cast<VarTemplatePartialSpecializationDecl>(D)
1627         ->getTemplateParameters();
1628   case Decl::Kind::TemplateTemplateParm:
1629     return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();
1630   case Decl::Kind::Concept:
1631     return cast<ConceptDecl>(D)->getTemplateParameters();
1632   default:
1633     llvm_unreachable("Unhandled templated declaration kind");
1634   }
1635 }
1636