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