xref: /freebsd/contrib/llvm-project/clang/lib/AST/DeclTemplate.cpp (revision a03411e84728e9b267056fd31c7d1d9d1dc1b01e)
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(NestedNameSpecifierLoc NNS,
701     DeclarationNameInfo NameInfo, NamedDecl *FoundDecl, ConceptDecl *CD,
702     const ASTTemplateArgumentListInfo *ArgsAsWritten,
703     Expr *ImmediatelyDeclaredConstraint) {
704   assert(HasTypeConstraint &&
705          "HasTypeConstraint=true must be passed at construction in order to "
706          "call setTypeConstraint");
707   assert(!TypeConstraintInitialized &&
708          "TypeConstraint was already initialized!");
709   new (getTrailingObjects<TypeConstraint>()) TypeConstraint(NNS, NameInfo,
710       FoundDecl, CD, ArgsAsWritten, ImmediatelyDeclaredConstraint);
711   TypeConstraintInitialized = true;
712 }
713 
714 //===----------------------------------------------------------------------===//
715 // NonTypeTemplateParmDecl Method Implementations
716 //===----------------------------------------------------------------------===//
717 
718 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
719     DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
720     unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
721     ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
722     : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
723       TemplateParmPosition(D, P), ParameterPack(true),
724       ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
725   if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
726     auto TypesAndInfos =
727         getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
728     for (unsigned I = 0; I != NumExpandedTypes; ++I) {
729       new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
730       TypesAndInfos[I].second = ExpandedTInfos[I];
731     }
732   }
733 }
734 
735 NonTypeTemplateParmDecl *
736 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
737                                 SourceLocation StartLoc, SourceLocation IdLoc,
738                                 unsigned D, unsigned P, IdentifierInfo *Id,
739                                 QualType T, bool ParameterPack,
740                                 TypeSourceInfo *TInfo) {
741   AutoType *AT =
742       C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
743   return new (C, DC,
744               additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
745                                     Expr *>(0,
746                                             AT && AT->isConstrained() ? 1 : 0))
747       NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,
748                               TInfo);
749 }
750 
751 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
752     const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
753     SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
754     QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
755     ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
756   AutoType *AT = TInfo->getType()->getContainedAutoType();
757   return new (C, DC,
758               additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
759                                     Expr *>(
760                   ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))
761       NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
762                               ExpandedTypes, ExpandedTInfos);
763 }
764 
765 NonTypeTemplateParmDecl *
766 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
767                                             bool HasTypeConstraint) {
768   return new (C, ID, additionalSizeToAlloc<std::pair<QualType,
769                                                      TypeSourceInfo *>,
770                                            Expr *>(0,
771                                                    HasTypeConstraint ? 1 : 0))
772           NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
773                                   0, 0, nullptr, QualType(), false, nullptr);
774 }
775 
776 NonTypeTemplateParmDecl *
777 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
778                                             unsigned NumExpandedTypes,
779                                             bool HasTypeConstraint) {
780   auto *NTTP =
781       new (C, ID,
782            additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
783                NumExpandedTypes, HasTypeConstraint ? 1 : 0))
784           NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
785                                   0, 0, nullptr, QualType(), nullptr,
786                                   std::nullopt, std::nullopt);
787   NTTP->NumExpandedTypes = NumExpandedTypes;
788   return NTTP;
789 }
790 
791 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
792   if (hasDefaultArgument() && !defaultArgumentWasInherited())
793     return SourceRange(getOuterLocStart(),
794                        getDefaultArgument()->getSourceRange().getEnd());
795   return DeclaratorDecl::getSourceRange();
796 }
797 
798 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
799   return hasDefaultArgument()
800     ? getDefaultArgument()->getSourceRange().getBegin()
801     : SourceLocation();
802 }
803 
804 //===----------------------------------------------------------------------===//
805 // TemplateTemplateParmDecl Method Implementations
806 //===----------------------------------------------------------------------===//
807 
808 void TemplateTemplateParmDecl::anchor() {}
809 
810 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
811     DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
812     IdentifierInfo *Id, TemplateParameterList *Params,
813     ArrayRef<TemplateParameterList *> Expansions)
814     : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
815       TemplateParmPosition(D, P), ParameterPack(true),
816       ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
817   if (!Expansions.empty())
818     std::uninitialized_copy(Expansions.begin(), Expansions.end(),
819                             getTrailingObjects<TemplateParameterList *>());
820 }
821 
822 TemplateTemplateParmDecl *
823 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
824                                  SourceLocation L, unsigned D, unsigned P,
825                                  bool ParameterPack, IdentifierInfo *Id,
826                                  TemplateParameterList *Params) {
827   return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
828                                               Params);
829 }
830 
831 TemplateTemplateParmDecl *
832 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
833                                  SourceLocation L, unsigned D, unsigned P,
834                                  IdentifierInfo *Id,
835                                  TemplateParameterList *Params,
836                                  ArrayRef<TemplateParameterList *> Expansions) {
837   return new (C, DC,
838               additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
839       TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
840 }
841 
842 TemplateTemplateParmDecl *
843 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
844   return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
845                                               false, nullptr, nullptr);
846 }
847 
848 TemplateTemplateParmDecl *
849 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
850                                              unsigned NumExpansions) {
851   auto *TTP =
852       new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
853           TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
854                                    nullptr, std::nullopt);
855   TTP->NumExpandedParams = NumExpansions;
856   return TTP;
857 }
858 
859 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
860   return hasDefaultArgument() ? getDefaultArgument().getLocation()
861                               : SourceLocation();
862 }
863 
864 void TemplateTemplateParmDecl::setDefaultArgument(
865     const ASTContext &C, const TemplateArgumentLoc &DefArg) {
866   if (DefArg.getArgument().isNull())
867     DefaultArgument.set(nullptr);
868   else
869     DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
870 }
871 
872 //===----------------------------------------------------------------------===//
873 // TemplateArgumentList Implementation
874 //===----------------------------------------------------------------------===//
875 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
876     : Arguments(getTrailingObjects<TemplateArgument>()),
877       NumArguments(Args.size()) {
878   std::uninitialized_copy(Args.begin(), Args.end(),
879                           getTrailingObjects<TemplateArgument>());
880 }
881 
882 TemplateArgumentList *
883 TemplateArgumentList::CreateCopy(ASTContext &Context,
884                                  ArrayRef<TemplateArgument> Args) {
885   void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
886   return new (Mem) TemplateArgumentList(Args);
887 }
888 
889 FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
890     ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
891     TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
892     const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
893     MemberSpecializationInfo *MSInfo) {
894   const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
895   if (TemplateArgsAsWritten)
896     ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
897                                                         *TemplateArgsAsWritten);
898 
899   void *Mem =
900       C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
901   return new (Mem) FunctionTemplateSpecializationInfo(
902       FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
903 }
904 
905 //===----------------------------------------------------------------------===//
906 // ClassTemplateSpecializationDecl Implementation
907 //===----------------------------------------------------------------------===//
908 
909 ClassTemplateSpecializationDecl::
910 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
911                                 DeclContext *DC, SourceLocation StartLoc,
912                                 SourceLocation IdLoc,
913                                 ClassTemplateDecl *SpecializedTemplate,
914                                 ArrayRef<TemplateArgument> Args,
915                                 ClassTemplateSpecializationDecl *PrevDecl)
916     : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
917                     SpecializedTemplate->getIdentifier(), PrevDecl),
918     SpecializedTemplate(SpecializedTemplate),
919     TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
920     SpecializationKind(TSK_Undeclared) {
921 }
922 
923 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
924                                                                  Kind DK)
925     : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
926                     SourceLocation(), nullptr, nullptr),
927       SpecializationKind(TSK_Undeclared) {}
928 
929 ClassTemplateSpecializationDecl *
930 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
931                                         DeclContext *DC,
932                                         SourceLocation StartLoc,
933                                         SourceLocation IdLoc,
934                                         ClassTemplateDecl *SpecializedTemplate,
935                                         ArrayRef<TemplateArgument> Args,
936                                    ClassTemplateSpecializationDecl *PrevDecl) {
937   auto *Result =
938       new (Context, DC) ClassTemplateSpecializationDecl(
939           Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
940           SpecializedTemplate, Args, PrevDecl);
941   Result->setMayHaveOutOfDateDef(false);
942 
943   // If the template decl is incomplete, copy the external lexical storage from
944   // the base template. This allows instantiations of incomplete types to
945   // complete using the external AST if the template's declaration came from an
946   // external AST.
947   if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
948     Result->setHasExternalLexicalStorage(
949       SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
950 
951   Context.getTypeDeclType(Result, PrevDecl);
952   return Result;
953 }
954 
955 ClassTemplateSpecializationDecl *
956 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
957                                                     unsigned ID) {
958   auto *Result =
959     new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
960   Result->setMayHaveOutOfDateDef(false);
961   return Result;
962 }
963 
964 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
965     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
966   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
967 
968   const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
969   if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
970           PS ? PS->getTemplateArgsAsWritten() : nullptr) {
971     printTemplateArgumentList(
972         OS, ArgsAsWritten->arguments(), Policy,
973         getSpecializedTemplate()->getTemplateParameters());
974   } else {
975     const TemplateArgumentList &TemplateArgs = getTemplateArgs();
976     printTemplateArgumentList(
977         OS, TemplateArgs.asArray(), Policy,
978         getSpecializedTemplate()->getTemplateParameters());
979   }
980 }
981 
982 ClassTemplateDecl *
983 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
984   if (const auto *PartialSpec =
985           SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
986     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
987   return SpecializedTemplate.get<ClassTemplateDecl*>();
988 }
989 
990 SourceRange
991 ClassTemplateSpecializationDecl::getSourceRange() const {
992   if (ExplicitInfo) {
993     SourceLocation Begin = getTemplateKeywordLoc();
994     if (Begin.isValid()) {
995       // Here we have an explicit (partial) specialization or instantiation.
996       assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
997              getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
998              getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
999       if (getExternLoc().isValid())
1000         Begin = getExternLoc();
1001       SourceLocation End = getBraceRange().getEnd();
1002       if (End.isInvalid())
1003         End = getTypeAsWritten()->getTypeLoc().getEndLoc();
1004       return SourceRange(Begin, End);
1005     }
1006     // An implicit instantiation of a class template partial specialization
1007     // uses ExplicitInfo to record the TypeAsWritten, but the source
1008     // locations should be retrieved from the instantiation pattern.
1009     using CTPSDecl = ClassTemplatePartialSpecializationDecl;
1010     auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
1011     CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
1012     assert(inst_from != nullptr);
1013     return inst_from->getSourceRange();
1014   }
1015   else {
1016     // No explicit info available.
1017     llvm::PointerUnion<ClassTemplateDecl *,
1018                        ClassTemplatePartialSpecializationDecl *>
1019       inst_from = getInstantiatedFrom();
1020     if (inst_from.isNull())
1021       return getSpecializedTemplate()->getSourceRange();
1022     if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
1023       return ctd->getSourceRange();
1024     return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
1025       ->getSourceRange();
1026   }
1027 }
1028 
1029 //===----------------------------------------------------------------------===//
1030 // ConceptDecl Implementation
1031 //===----------------------------------------------------------------------===//
1032 ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
1033                                  SourceLocation L, DeclarationName Name,
1034                                  TemplateParameterList *Params,
1035                                  Expr *ConstraintExpr) {
1036   bool Invalid = AdoptTemplateParameterList(Params, DC);
1037   auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1038   if (Invalid)
1039     TD->setInvalidDecl();
1040   return TD;
1041 }
1042 
1043 ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C,
1044                                              unsigned ID) {
1045   ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1046                                                 DeclarationName(),
1047                                                 nullptr, nullptr);
1048 
1049   return Result;
1050 }
1051 
1052 //===----------------------------------------------------------------------===//
1053 // ImplicitConceptSpecializationDecl Implementation
1054 //===----------------------------------------------------------------------===//
1055 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1056     DeclContext *DC, SourceLocation SL,
1057     ArrayRef<TemplateArgument> ConvertedArgs)
1058     : Decl(ImplicitConceptSpecialization, DC, SL),
1059       NumTemplateArgs(ConvertedArgs.size()) {
1060   setTemplateArguments(ConvertedArgs);
1061 }
1062 
1063 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1064     EmptyShell Empty, unsigned NumTemplateArgs)
1065     : Decl(ImplicitConceptSpecialization, Empty),
1066       NumTemplateArgs(NumTemplateArgs) {}
1067 
1068 ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create(
1069     const ASTContext &C, DeclContext *DC, SourceLocation SL,
1070     ArrayRef<TemplateArgument> ConvertedArgs) {
1071   return new (C, DC,
1072               additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1073       ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1074 }
1075 
1076 ImplicitConceptSpecializationDecl *
1077 ImplicitConceptSpecializationDecl::CreateDeserialized(
1078     const ASTContext &C, unsigned ID, unsigned NumTemplateArgs) {
1079   return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1080       ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);
1081 }
1082 
1083 void ImplicitConceptSpecializationDecl::setTemplateArguments(
1084     ArrayRef<TemplateArgument> Converted) {
1085   assert(Converted.size() == NumTemplateArgs);
1086   std::uninitialized_copy(Converted.begin(), Converted.end(),
1087                           getTrailingObjects<TemplateArgument>());
1088 }
1089 
1090 //===----------------------------------------------------------------------===//
1091 // ClassTemplatePartialSpecializationDecl Implementation
1092 //===----------------------------------------------------------------------===//
1093 void ClassTemplatePartialSpecializationDecl::anchor() {}
1094 
1095 ClassTemplatePartialSpecializationDecl::
1096 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
1097                                        DeclContext *DC,
1098                                        SourceLocation StartLoc,
1099                                        SourceLocation IdLoc,
1100                                        TemplateParameterList *Params,
1101                                        ClassTemplateDecl *SpecializedTemplate,
1102                                        ArrayRef<TemplateArgument> Args,
1103                                const ASTTemplateArgumentListInfo *ArgInfos,
1104                                ClassTemplatePartialSpecializationDecl *PrevDecl)
1105     : ClassTemplateSpecializationDecl(Context,
1106                                       ClassTemplatePartialSpecialization,
1107                                       TK, DC, StartLoc, IdLoc,
1108                                       SpecializedTemplate, Args, PrevDecl),
1109       TemplateParams(Params), ArgsAsWritten(ArgInfos),
1110       InstantiatedFromMember(nullptr, false) {
1111   if (AdoptTemplateParameterList(Params, this))
1112     setInvalidDecl();
1113 }
1114 
1115 ClassTemplatePartialSpecializationDecl *
1116 ClassTemplatePartialSpecializationDecl::
1117 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
1118        SourceLocation StartLoc, SourceLocation IdLoc,
1119        TemplateParameterList *Params,
1120        ClassTemplateDecl *SpecializedTemplate,
1121        ArrayRef<TemplateArgument> Args,
1122        const TemplateArgumentListInfo &ArgInfos,
1123        QualType CanonInjectedType,
1124        ClassTemplatePartialSpecializationDecl *PrevDecl) {
1125   const ASTTemplateArgumentListInfo *ASTArgInfos =
1126     ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1127 
1128   auto *Result = new (Context, DC)
1129       ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
1130                                              Params, SpecializedTemplate, Args,
1131                                              ASTArgInfos, PrevDecl);
1132   Result->setSpecializationKind(TSK_ExplicitSpecialization);
1133   Result->setMayHaveOutOfDateDef(false);
1134 
1135   Context.getInjectedClassNameType(Result, CanonInjectedType);
1136   return Result;
1137 }
1138 
1139 ClassTemplatePartialSpecializationDecl *
1140 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1141                                                            unsigned ID) {
1142   auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
1143   Result->setMayHaveOutOfDateDef(false);
1144   return Result;
1145 }
1146 
1147 //===----------------------------------------------------------------------===//
1148 // FriendTemplateDecl Implementation
1149 //===----------------------------------------------------------------------===//
1150 
1151 void FriendTemplateDecl::anchor() {}
1152 
1153 FriendTemplateDecl *
1154 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
1155                            SourceLocation L,
1156                            MutableArrayRef<TemplateParameterList *> Params,
1157                            FriendUnion Friend, SourceLocation FLoc) {
1158   TemplateParameterList **TPL = nullptr;
1159   if (!Params.empty()) {
1160     TPL = new (Context) TemplateParameterList *[Params.size()];
1161     llvm::copy(Params, TPL);
1162   }
1163   return new (Context, DC)
1164       FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
1165 }
1166 
1167 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
1168                                                            unsigned ID) {
1169   return new (C, ID) FriendTemplateDecl(EmptyShell());
1170 }
1171 
1172 //===----------------------------------------------------------------------===//
1173 // TypeAliasTemplateDecl Implementation
1174 //===----------------------------------------------------------------------===//
1175 
1176 TypeAliasTemplateDecl *
1177 TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
1178                               DeclarationName Name,
1179                               TemplateParameterList *Params, NamedDecl *Decl) {
1180   bool Invalid = AdoptTemplateParameterList(Params, DC);
1181   auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1182   if (Invalid)
1183     TD->setInvalidDecl();
1184   return TD;
1185 }
1186 
1187 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
1188                                                                  unsigned ID) {
1189   return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1190                                            DeclarationName(), nullptr, nullptr);
1191 }
1192 
1193 RedeclarableTemplateDecl::CommonBase *
1194 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
1195   auto *CommonPtr = new (C) Common;
1196   C.addDestruction(CommonPtr);
1197   return CommonPtr;
1198 }
1199 
1200 //===----------------------------------------------------------------------===//
1201 // ClassScopeFunctionSpecializationDecl Implementation
1202 //===----------------------------------------------------------------------===//
1203 
1204 void ClassScopeFunctionSpecializationDecl::anchor() {}
1205 
1206 ClassScopeFunctionSpecializationDecl *
1207 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
1208                                                          unsigned ID) {
1209   return new (C, ID) ClassScopeFunctionSpecializationDecl(
1210       nullptr, SourceLocation(), nullptr, nullptr);
1211 }
1212 
1213 //===----------------------------------------------------------------------===//
1214 // VarTemplateDecl Implementation
1215 //===----------------------------------------------------------------------===//
1216 
1217 VarTemplateDecl *VarTemplateDecl::getDefinition() {
1218   VarTemplateDecl *CurD = this;
1219   while (CurD) {
1220     if (CurD->isThisDeclarationADefinition())
1221       return CurD;
1222     CurD = CurD->getPreviousDecl();
1223   }
1224   return nullptr;
1225 }
1226 
1227 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
1228                                          SourceLocation L, DeclarationName Name,
1229                                          TemplateParameterList *Params,
1230                                          VarDecl *Decl) {
1231   bool Invalid = AdoptTemplateParameterList(Params, DC);
1232   auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1233   if (Invalid)
1234     TD->setInvalidDecl();
1235   return TD;
1236 }
1237 
1238 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
1239                                                      unsigned ID) {
1240   return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1241                                      DeclarationName(), nullptr, nullptr);
1242 }
1243 
1244 void VarTemplateDecl::LoadLazySpecializations() const {
1245   loadLazySpecializationsImpl();
1246 }
1247 
1248 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1249 VarTemplateDecl::getSpecializations() const {
1250   LoadLazySpecializations();
1251   return getCommonPtr()->Specializations;
1252 }
1253 
1254 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1255 VarTemplateDecl::getPartialSpecializations() const {
1256   LoadLazySpecializations();
1257   return getCommonPtr()->PartialSpecializations;
1258 }
1259 
1260 RedeclarableTemplateDecl::CommonBase *
1261 VarTemplateDecl::newCommon(ASTContext &C) const {
1262   auto *CommonPtr = new (C) Common;
1263   C.addDestruction(CommonPtr);
1264   return CommonPtr;
1265 }
1266 
1267 VarTemplateSpecializationDecl *
1268 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1269                                     void *&InsertPos) {
1270   return findSpecializationImpl(getSpecializations(), InsertPos, Args);
1271 }
1272 
1273 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1274                                         void *InsertPos) {
1275   addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1276 }
1277 
1278 VarTemplatePartialSpecializationDecl *
1279 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1280      TemplateParameterList *TPL, void *&InsertPos) {
1281   return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1282                                 TPL);
1283 }
1284 
1285 void VarTemplatePartialSpecializationDecl::Profile(
1286     llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1287     TemplateParameterList *TPL, const ASTContext &Context) {
1288   ID.AddInteger(TemplateArgs.size());
1289   for (const TemplateArgument &TemplateArg : TemplateArgs)
1290     TemplateArg.Profile(ID, Context);
1291   TPL->Profile(ID, Context);
1292 }
1293 
1294 void VarTemplateDecl::AddPartialSpecialization(
1295     VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1296   if (InsertPos)
1297     getPartialSpecializations().InsertNode(D, InsertPos);
1298   else {
1299     VarTemplatePartialSpecializationDecl *Existing =
1300         getPartialSpecializations().GetOrInsertNode(D);
1301     (void)Existing;
1302     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1303   }
1304 
1305   if (ASTMutationListener *L = getASTMutationListener())
1306     L->AddedCXXTemplateSpecialization(this, D);
1307 }
1308 
1309 void VarTemplateDecl::getPartialSpecializations(
1310     SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const {
1311   llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1312       getPartialSpecializations();
1313   PS.clear();
1314   PS.reserve(PartialSpecs.size());
1315   for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1316     PS.push_back(P.getMostRecentDecl());
1317 }
1318 
1319 VarTemplatePartialSpecializationDecl *
1320 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1321     VarTemplatePartialSpecializationDecl *D) {
1322   Decl *DCanon = D->getCanonicalDecl();
1323   for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1324     if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1325       return P.getMostRecentDecl();
1326   }
1327 
1328   return nullptr;
1329 }
1330 
1331 //===----------------------------------------------------------------------===//
1332 // VarTemplateSpecializationDecl Implementation
1333 //===----------------------------------------------------------------------===//
1334 
1335 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1336     Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1337     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1338     TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1339     : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1340               SpecializedTemplate->getIdentifier(), T, TInfo, S),
1341       SpecializedTemplate(SpecializedTemplate),
1342       TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1343       SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1344 
1345 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1346                                                              ASTContext &C)
1347     : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1348               QualType(), nullptr, SC_None),
1349       SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1350 
1351 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1352     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1353     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1354     TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1355   return new (Context, DC) VarTemplateSpecializationDecl(
1356       VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1357       SpecializedTemplate, T, TInfo, S, Args);
1358 }
1359 
1360 VarTemplateSpecializationDecl *
1361 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1362   return new (C, ID)
1363       VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1364 }
1365 
1366 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1367     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1368   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1369 
1370   const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1371   if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1372           PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1373     printTemplateArgumentList(
1374         OS, ArgsAsWritten->arguments(), Policy,
1375         getSpecializedTemplate()->getTemplateParameters());
1376   } else {
1377     const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1378     printTemplateArgumentList(
1379         OS, TemplateArgs.asArray(), Policy,
1380         getSpecializedTemplate()->getTemplateParameters());
1381   }
1382 }
1383 
1384 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1385   if (const auto *PartialSpec =
1386           SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1387     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1388   return SpecializedTemplate.get<VarTemplateDecl *>();
1389 }
1390 
1391 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1392     const TemplateArgumentListInfo &ArgsInfo) {
1393   TemplateArgsInfo =
1394       ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo);
1395 }
1396 
1397 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1398     const ASTTemplateArgumentListInfo *ArgsInfo) {
1399   TemplateArgsInfo =
1400       ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo);
1401 }
1402 
1403 SourceRange VarTemplateSpecializationDecl::getSourceRange() const {
1404   if (isExplicitSpecialization() && !hasInit()) {
1405     if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsInfo())
1406       return SourceRange(getOuterLocStart(), Info->getRAngleLoc());
1407   }
1408   return VarDecl::getSourceRange();
1409 }
1410 
1411 
1412 //===----------------------------------------------------------------------===//
1413 // VarTemplatePartialSpecializationDecl Implementation
1414 //===----------------------------------------------------------------------===//
1415 
1416 void VarTemplatePartialSpecializationDecl::anchor() {}
1417 
1418 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1419     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1420     SourceLocation IdLoc, TemplateParameterList *Params,
1421     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1422     StorageClass S, ArrayRef<TemplateArgument> Args,
1423     const ASTTemplateArgumentListInfo *ArgInfos)
1424     : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1425                                     DC, StartLoc, IdLoc, SpecializedTemplate, T,
1426                                     TInfo, S, Args),
1427       TemplateParams(Params), ArgsAsWritten(ArgInfos),
1428       InstantiatedFromMember(nullptr, false) {
1429   if (AdoptTemplateParameterList(Params, DC))
1430     setInvalidDecl();
1431 }
1432 
1433 VarTemplatePartialSpecializationDecl *
1434 VarTemplatePartialSpecializationDecl::Create(
1435     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1436     SourceLocation IdLoc, TemplateParameterList *Params,
1437     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1438     StorageClass S, ArrayRef<TemplateArgument> Args,
1439     const TemplateArgumentListInfo &ArgInfos) {
1440   const ASTTemplateArgumentListInfo *ASTArgInfos
1441     = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1442 
1443   auto *Result =
1444       new (Context, DC) VarTemplatePartialSpecializationDecl(
1445           Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1446           S, Args, ASTArgInfos);
1447   Result->setSpecializationKind(TSK_ExplicitSpecialization);
1448   return Result;
1449 }
1450 
1451 VarTemplatePartialSpecializationDecl *
1452 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1453                                                          unsigned ID) {
1454   return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1455 }
1456 
1457 SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {
1458   if (isExplicitSpecialization() && !hasInit()) {
1459     if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsAsWritten())
1460       return SourceRange(getOuterLocStart(), Info->getRAngleLoc());
1461   }
1462   return VarDecl::getSourceRange();
1463 }
1464 
1465 static TemplateParameterList *
1466 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1467   // typename T
1468   auto *T = TemplateTypeParmDecl::Create(
1469       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1470       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1471       /*HasTypeConstraint=*/false);
1472   T->setImplicit(true);
1473 
1474   // T ...Ints
1475   TypeSourceInfo *TI =
1476       C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1477   auto *N = NonTypeTemplateParmDecl::Create(
1478       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1479       /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1480   N->setImplicit(true);
1481 
1482   // <typename T, T ...Ints>
1483   NamedDecl *P[2] = {T, N};
1484   auto *TPL = TemplateParameterList::Create(
1485       C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1486 
1487   // template <typename T, ...Ints> class IntSeq
1488   auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1489       C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1490       /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1491   TemplateTemplateParm->setImplicit(true);
1492 
1493   // typename T
1494   auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1495       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1496       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1497       /*HasTypeConstraint=*/false);
1498   TemplateTypeParm->setImplicit(true);
1499 
1500   // T N
1501   TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1502       QualType(TemplateTypeParm->getTypeForDecl(), 0));
1503   auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1504       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1505       /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1506   NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1507                          NonTypeTemplateParm};
1508 
1509   // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1510   return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1511                                        Params, SourceLocation(), nullptr);
1512 }
1513 
1514 static TemplateParameterList *
1515 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1516   // std::size_t Index
1517   TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1518   auto *Index = NonTypeTemplateParmDecl::Create(
1519       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1520       /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1521 
1522   // typename ...T
1523   auto *Ts = TemplateTypeParmDecl::Create(
1524       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1525       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
1526       /*HasTypeConstraint=*/false);
1527   Ts->setImplicit(true);
1528 
1529   // template <std::size_t Index, typename ...T>
1530   NamedDecl *Params[] = {Index, Ts};
1531   return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1532                                        llvm::ArrayRef(Params), SourceLocation(),
1533                                        nullptr);
1534 }
1535 
1536 static TemplateParameterList *createBuiltinTemplateParameterList(
1537     const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1538   switch (BTK) {
1539   case BTK__make_integer_seq:
1540     return createMakeIntegerSeqParameterList(C, DC);
1541   case BTK__type_pack_element:
1542     return createTypePackElementParameterList(C, DC);
1543   }
1544 
1545   llvm_unreachable("unhandled BuiltinTemplateKind!");
1546 }
1547 
1548 void BuiltinTemplateDecl::anchor() {}
1549 
1550 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1551                                          DeclarationName Name,
1552                                          BuiltinTemplateKind BTK)
1553     : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1554                    createBuiltinTemplateParameterList(C, DC, BTK)),
1555       BTK(BTK) {}
1556 
1557 void TypeConstraint::print(llvm::raw_ostream &OS, PrintingPolicy Policy) const {
1558   if (NestedNameSpec)
1559     NestedNameSpec.getNestedNameSpecifier()->print(OS, Policy);
1560   ConceptName.printName(OS, Policy);
1561   if (hasExplicitTemplateArgs()) {
1562     OS << "<";
1563     // FIXME: Find corresponding parameter for argument
1564     for (auto &ArgLoc : ArgsAsWritten->arguments())
1565       ArgLoc.getArgument().print(Policy, OS, /*IncludeType*/ false);
1566     OS << ">";
1567   }
1568 }
1569 
1570 TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1571                                                          QualType T,
1572                                                          const APValue &V) {
1573   DeclContext *DC = C.getTranslationUnitDecl();
1574   auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1575   C.addDestruction(&TPOD->Value);
1576   return TPOD;
1577 }
1578 
1579 TemplateParamObjectDecl *
1580 TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1581   auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1582   C.addDestruction(&TPOD->Value);
1583   return TPOD;
1584 }
1585 
1586 void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1587                                         const PrintingPolicy &Policy) const {
1588   OS << "<template param ";
1589   printAsExpr(OS, Policy);
1590   OS << ">";
1591 }
1592 
1593 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1594   printAsExpr(OS, getASTContext().getPrintingPolicy());
1595 }
1596 
1597 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1598                                           const PrintingPolicy &Policy) const {
1599   getType().getUnqualifiedType().print(OS, Policy);
1600   printAsInit(OS, Policy);
1601 }
1602 
1603 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1604   printAsInit(OS, getASTContext().getPrintingPolicy());
1605 }
1606 
1607 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1608                                           const PrintingPolicy &Policy) const {
1609   getValue().printPretty(OS, Policy, getType(), &getASTContext());
1610 }
1611 
1612 TemplateParameterList *clang::getReplacedTemplateParameterList(Decl *D) {
1613   switch (D->getKind()) {
1614   case Decl::Kind::ClassTemplate:
1615     return cast<ClassTemplateDecl>(D)->getTemplateParameters();
1616   case Decl::Kind::ClassTemplateSpecialization: {
1617     const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1618     auto P = CTSD->getSpecializedTemplateOrPartial();
1619     if (const auto *CTPSD =
1620             P.dyn_cast<ClassTemplatePartialSpecializationDecl *>())
1621       return CTPSD->getTemplateParameters();
1622     return cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1623   }
1624   case Decl::Kind::ClassTemplatePartialSpecialization:
1625     return cast<ClassTemplatePartialSpecializationDecl>(D)
1626         ->getTemplateParameters();
1627   case Decl::Kind::TypeAliasTemplate:
1628     return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
1629   case Decl::Kind::BuiltinTemplate:
1630     return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
1631   case Decl::Kind::CXXDeductionGuide:
1632   case Decl::Kind::CXXConversion:
1633   case Decl::Kind::CXXConstructor:
1634   case Decl::Kind::CXXDestructor:
1635   case Decl::Kind::CXXMethod:
1636   case Decl::Kind::Function:
1637     return cast<FunctionDecl>(D)
1638         ->getTemplateSpecializationInfo()
1639         ->getTemplate()
1640         ->getTemplateParameters();
1641   case Decl::Kind::FunctionTemplate:
1642     return cast<FunctionTemplateDecl>(D)->getTemplateParameters();
1643   case Decl::Kind::VarTemplate:
1644     return cast<VarTemplateDecl>(D)->getTemplateParameters();
1645   case Decl::Kind::VarTemplateSpecialization: {
1646     const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1647     auto P = VTSD->getSpecializedTemplateOrPartial();
1648     if (const auto *VTPSD =
1649             P.dyn_cast<VarTemplatePartialSpecializationDecl *>())
1650       return VTPSD->getTemplateParameters();
1651     return cast<VarTemplateDecl *>(P)->getTemplateParameters();
1652   }
1653   case Decl::Kind::VarTemplatePartialSpecialization:
1654     return cast<VarTemplatePartialSpecializationDecl>(D)
1655         ->getTemplateParameters();
1656   case Decl::Kind::TemplateTemplateParm:
1657     return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();
1658   case Decl::Kind::Concept:
1659     return cast<ConceptDecl>(D)->getTemplateParameters();
1660   default:
1661     llvm_unreachable("Unhandled templated declaration kind");
1662   }
1663 }
1664