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