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/None.h"
30 #include "llvm/ADT/PointerUnion.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 <utility>
39 
40 using namespace clang;
41 
42 //===----------------------------------------------------------------------===//
43 // TemplateParameterList Implementation
44 //===----------------------------------------------------------------------===//
45 
46 TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
47                                              SourceLocation LAngleLoc,
48                                              ArrayRef<NamedDecl *> Params,
49                                              SourceLocation RAngleLoc,
50                                              Expr *RequiresClause)
51     : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
52       NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
53       HasRequiresClause(static_cast<bool>(RequiresClause)) {
54   for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
55     NamedDecl *P = Params[Idx];
56     begin()[Idx] = P;
57 
58     if (!P->isTemplateParameterPack()) {
59       if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
60         if (NTTP->getType()->containsUnexpandedParameterPack())
61           ContainsUnexpandedParameterPack = true;
62 
63       if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
64         if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
65           ContainsUnexpandedParameterPack = true;
66 
67       // FIXME: If a default argument contains an unexpanded parameter pack, the
68       // template parameter list does too.
69     }
70   }
71   if (RequiresClause) {
72     *getTrailingObjects<Expr *>() = RequiresClause;
73     if (RequiresClause->containsUnexpandedParameterPack())
74       ContainsUnexpandedParameterPack = true;
75   }
76 }
77 
78 TemplateParameterList *
79 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
80                               SourceLocation LAngleLoc,
81                               ArrayRef<NamedDecl *> Params,
82                               SourceLocation RAngleLoc, Expr *RequiresClause) {
83   void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
84                              Params.size(), RequiresClause ? 1u : 0u),
85                          alignof(TemplateParameterList));
86   return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
87                                          RAngleLoc, RequiresClause);
88 }
89 
90 unsigned TemplateParameterList::getMinRequiredArguments() const {
91   unsigned NumRequiredArgs = 0;
92   for (const NamedDecl *P : asArray()) {
93     if (P->isTemplateParameterPack()) {
94       if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
95         if (NTTP->isExpandedParameterPack()) {
96           NumRequiredArgs += NTTP->getNumExpansionTypes();
97           continue;
98         }
99 
100       break;
101     }
102 
103     if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
104       if (TTP->hasDefaultArgument())
105         break;
106     } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
107       if (NTTP->hasDefaultArgument())
108         break;
109     } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
110       break;
111 
112     ++NumRequiredArgs;
113   }
114 
115   return NumRequiredArgs;
116 }
117 
118 unsigned TemplateParameterList::getDepth() const {
119   if (size() == 0)
120     return 0;
121 
122   const NamedDecl *FirstParm = getParam(0);
123   if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
124     return TTP->getDepth();
125   else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
126     return NTTP->getDepth();
127   else
128     return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
129 }
130 
131 static void AdoptTemplateParameterList(TemplateParameterList *Params,
132                                        DeclContext *Owner) {
133   for (NamedDecl *P : *Params) {
134     P->setDeclContext(Owner);
135 
136     if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
137       AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
138   }
139 }
140 
141 void TemplateParameterList::
142 getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
143   // TODO: Concepts: Collect immediately-introduced constraints.
144   if (HasRequiresClause)
145     AC.push_back(getRequiresClause());
146 }
147 
148 bool TemplateParameterList::hasAssociatedConstraints() const {
149   // TODO: Concepts: Regard immediately-introduced constraints.
150   return HasRequiresClause;
151 }
152 
153 namespace clang {
154 
155 void *allocateDefaultArgStorageChain(const ASTContext &C) {
156   return new (C) char[sizeof(void*) * 2];
157 }
158 
159 } // namespace clang
160 
161 //===----------------------------------------------------------------------===//
162 // TemplateDecl Implementation
163 //===----------------------------------------------------------------------===//
164 
165 TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
166                            DeclarationName Name, TemplateParameterList *Params,
167                            NamedDecl *Decl)
168     : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
169 
170 void TemplateDecl::anchor() {}
171 
172 void TemplateDecl::
173 getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
174   TemplateParams->getAssociatedConstraints(AC);
175   if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
176     if (const Expr *TRC = FD->getTrailingRequiresClause())
177       AC.push_back(TRC);
178 }
179 
180 bool TemplateDecl::hasAssociatedConstraints() const {
181   if (TemplateParams->hasAssociatedConstraints())
182     return true;
183   if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
184     return FD->getTrailingRequiresClause();
185   return false;
186 }
187 
188 //===----------------------------------------------------------------------===//
189 // RedeclarableTemplateDecl Implementation
190 //===----------------------------------------------------------------------===//
191 
192 void RedeclarableTemplateDecl::anchor() {}
193 
194 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
195   if (Common)
196     return Common;
197 
198   // Walk the previous-declaration chain until we either find a declaration
199   // with a common pointer or we run out of previous declarations.
200   SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
201   for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
202        Prev = Prev->getPreviousDecl()) {
203     if (Prev->Common) {
204       Common = Prev->Common;
205       break;
206     }
207 
208     PrevDecls.push_back(Prev);
209   }
210 
211   // If we never found a common pointer, allocate one now.
212   if (!Common) {
213     // FIXME: If any of the declarations is from an AST file, we probably
214     // need an update record to add the common data.
215 
216     Common = newCommon(getASTContext());
217   }
218 
219   // Update any previous declarations we saw with the common pointer.
220   for (const RedeclarableTemplateDecl *Prev : PrevDecls)
221     Prev->Common = Common;
222 
223   return Common;
224 }
225 
226 void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
227   // Grab the most recent declaration to ensure we've loaded any lazy
228   // redeclarations of this template.
229   CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
230   if (CommonBasePtr->LazySpecializations) {
231     ASTContext &Context = getASTContext();
232     uint32_t *Specs = CommonBasePtr->LazySpecializations;
233     CommonBasePtr->LazySpecializations = nullptr;
234     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
235       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
236   }
237 }
238 
239 template<class EntryType, typename... ProfileArguments>
240 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
241 RedeclarableTemplateDecl::findSpecializationImpl(
242     llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
243     ProfileArguments&&... ProfileArgs) {
244   using SETraits = SpecEntryTraits<EntryType>;
245 
246   llvm::FoldingSetNodeID ID;
247   EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
248                      getASTContext());
249   EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
250   return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
251 }
252 
253 template<class Derived, class EntryType>
254 void RedeclarableTemplateDecl::addSpecializationImpl(
255     llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
256     void *InsertPos) {
257   using SETraits = SpecEntryTraits<EntryType>;
258 
259   if (InsertPos) {
260 #ifndef NDEBUG
261     void *CorrectInsertPos;
262     assert(!findSpecializationImpl(Specializations,
263                                    CorrectInsertPos,
264                                    SETraits::getTemplateArgs(Entry)) &&
265            InsertPos == CorrectInsertPos &&
266            "given incorrect InsertPos for specialization");
267 #endif
268     Specializations.InsertNode(Entry, InsertPos);
269   } else {
270     EntryType *Existing = Specializations.GetOrInsertNode(Entry);
271     (void)Existing;
272     assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
273            "non-canonical specialization?");
274   }
275 
276   if (ASTMutationListener *L = getASTMutationListener())
277     L->AddedCXXTemplateSpecialization(cast<Derived>(this),
278                                       SETraits::getDecl(Entry));
279 }
280 
281 //===----------------------------------------------------------------------===//
282 // FunctionTemplateDecl Implementation
283 //===----------------------------------------------------------------------===//
284 
285 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
286                                                    DeclContext *DC,
287                                                    SourceLocation L,
288                                                    DeclarationName Name,
289                                                TemplateParameterList *Params,
290                                                    NamedDecl *Decl) {
291   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
292   return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
293 }
294 
295 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
296                                                                unsigned ID) {
297   return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
298                                           DeclarationName(), nullptr, nullptr);
299 }
300 
301 RedeclarableTemplateDecl::CommonBase *
302 FunctionTemplateDecl::newCommon(ASTContext &C) const {
303   auto *CommonPtr = new (C) Common;
304   C.addDestruction(CommonPtr);
305   return CommonPtr;
306 }
307 
308 void FunctionTemplateDecl::LoadLazySpecializations() const {
309   loadLazySpecializationsImpl();
310 }
311 
312 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
313 FunctionTemplateDecl::getSpecializations() const {
314   LoadLazySpecializations();
315   return getCommonPtr()->Specializations;
316 }
317 
318 FunctionDecl *
319 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
320                                          void *&InsertPos) {
321   return findSpecializationImpl(getSpecializations(), InsertPos, Args);
322 }
323 
324 void FunctionTemplateDecl::addSpecialization(
325       FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
326   addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
327                                               InsertPos);
328 }
329 
330 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
331   TemplateParameterList *Params = getTemplateParameters();
332   Common *CommonPtr = getCommonPtr();
333   if (!CommonPtr->InjectedArgs) {
334     auto &Context = getASTContext();
335     SmallVector<TemplateArgument, 16> TemplateArgs;
336     Context.getInjectedTemplateArgs(Params, TemplateArgs);
337     CommonPtr->InjectedArgs =
338         new (Context) TemplateArgument[TemplateArgs.size()];
339     std::copy(TemplateArgs.begin(), TemplateArgs.end(),
340               CommonPtr->InjectedArgs);
341   }
342 
343   return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
344 }
345 
346 void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
347   using Base = RedeclarableTemplateDecl;
348 
349   // If we haven't created a common pointer yet, then it can just be created
350   // with the usual method.
351   if (!Base::Common)
352     return;
353 
354   Common *ThisCommon = static_cast<Common *>(Base::Common);
355   Common *PrevCommon = nullptr;
356   SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
357   for (; Prev; Prev = Prev->getPreviousDecl()) {
358     if (Prev->Base::Common) {
359       PrevCommon = static_cast<Common *>(Prev->Base::Common);
360       break;
361     }
362     PreviousDecls.push_back(Prev);
363   }
364 
365   // If the previous redecl chain hasn't created a common pointer yet, then just
366   // use this common pointer.
367   if (!PrevCommon) {
368     for (auto *D : PreviousDecls)
369       D->Base::Common = ThisCommon;
370     return;
371   }
372 
373   // Ensure we don't leak any important state.
374   assert(ThisCommon->Specializations.size() == 0 &&
375          "Can't merge incompatible declarations!");
376 
377   Base::Common = PrevCommon;
378 }
379 
380 //===----------------------------------------------------------------------===//
381 // ClassTemplateDecl Implementation
382 //===----------------------------------------------------------------------===//
383 
384 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
385                                              DeclContext *DC,
386                                              SourceLocation L,
387                                              DeclarationName Name,
388                                              TemplateParameterList *Params,
389                                              NamedDecl *Decl) {
390   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
391 
392   return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
393 }
394 
395 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
396                                                          unsigned ID) {
397   return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
398                                        DeclarationName(), nullptr, nullptr);
399 }
400 
401 void ClassTemplateDecl::LoadLazySpecializations() const {
402   loadLazySpecializationsImpl();
403 }
404 
405 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
406 ClassTemplateDecl::getSpecializations() const {
407   LoadLazySpecializations();
408   return getCommonPtr()->Specializations;
409 }
410 
411 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
412 ClassTemplateDecl::getPartialSpecializations() {
413   LoadLazySpecializations();
414   return getCommonPtr()->PartialSpecializations;
415 }
416 
417 RedeclarableTemplateDecl::CommonBase *
418 ClassTemplateDecl::newCommon(ASTContext &C) const {
419   auto *CommonPtr = new (C) Common;
420   C.addDestruction(CommonPtr);
421   return CommonPtr;
422 }
423 
424 ClassTemplateSpecializationDecl *
425 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
426                                       void *&InsertPos) {
427   return findSpecializationImpl(getSpecializations(), InsertPos, Args);
428 }
429 
430 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
431                                           void *InsertPos) {
432   addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
433 }
434 
435 ClassTemplatePartialSpecializationDecl *
436 ClassTemplateDecl::findPartialSpecialization(
437     ArrayRef<TemplateArgument> Args,
438     TemplateParameterList *TPL, void *&InsertPos) {
439   return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
440                                 TPL);
441 }
442 
443 static void ProfileTemplateParameterList(ASTContext &C,
444     llvm::FoldingSetNodeID &ID, const TemplateParameterList *TPL) {
445   const Expr *RC = TPL->getRequiresClause();
446   ID.AddBoolean(RC != nullptr);
447   if (RC)
448     RC->Profile(ID, C, /*Canonical=*/true);
449   ID.AddInteger(TPL->size());
450   for (NamedDecl *D : *TPL) {
451     if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
452       ID.AddInteger(0);
453       ID.AddBoolean(NTTP->isParameterPack());
454       NTTP->getType().getCanonicalType().Profile(ID);
455       continue;
456     }
457     if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {
458       ID.AddInteger(1);
459       ID.AddBoolean(TTP->isParameterPack());
460       // TODO: Concepts: profile type-constraints.
461       continue;
462     }
463     const auto *TTP = cast<TemplateTemplateParmDecl>(D);
464     ID.AddInteger(2);
465     ID.AddBoolean(TTP->isParameterPack());
466     ProfileTemplateParameterList(C, ID, TTP->getTemplateParameters());
467   }
468 }
469 
470 void
471 ClassTemplatePartialSpecializationDecl::Profile(llvm::FoldingSetNodeID &ID,
472     ArrayRef<TemplateArgument> TemplateArgs, TemplateParameterList *TPL,
473     ASTContext &Context) {
474   ID.AddInteger(TemplateArgs.size());
475   for (const TemplateArgument &TemplateArg : TemplateArgs)
476     TemplateArg.Profile(ID, Context);
477   ProfileTemplateParameterList(Context, ID, TPL);
478 }
479 
480 void ClassTemplateDecl::AddPartialSpecialization(
481                                       ClassTemplatePartialSpecializationDecl *D,
482                                       void *InsertPos) {
483   if (InsertPos)
484     getPartialSpecializations().InsertNode(D, InsertPos);
485   else {
486     ClassTemplatePartialSpecializationDecl *Existing
487       = getPartialSpecializations().GetOrInsertNode(D);
488     (void)Existing;
489     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
490   }
491 
492   if (ASTMutationListener *L = getASTMutationListener())
493     L->AddedCXXTemplateSpecialization(this, D);
494 }
495 
496 void ClassTemplateDecl::getPartialSpecializations(
497           SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
498   llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
499     = getPartialSpecializations();
500   PS.clear();
501   PS.reserve(PartialSpecs.size());
502   for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
503     PS.push_back(P.getMostRecentDecl());
504 }
505 
506 ClassTemplatePartialSpecializationDecl *
507 ClassTemplateDecl::findPartialSpecialization(QualType T) {
508   ASTContext &Context = getASTContext();
509   for (ClassTemplatePartialSpecializationDecl &P :
510        getPartialSpecializations()) {
511     if (Context.hasSameType(P.getInjectedSpecializationType(), T))
512       return P.getMostRecentDecl();
513   }
514 
515   return nullptr;
516 }
517 
518 ClassTemplatePartialSpecializationDecl *
519 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
520                                     ClassTemplatePartialSpecializationDecl *D) {
521   Decl *DCanon = D->getCanonicalDecl();
522   for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
523     if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
524       return P.getMostRecentDecl();
525   }
526 
527   return nullptr;
528 }
529 
530 QualType
531 ClassTemplateDecl::getInjectedClassNameSpecialization() {
532   Common *CommonPtr = getCommonPtr();
533   if (!CommonPtr->InjectedClassNameType.isNull())
534     return CommonPtr->InjectedClassNameType;
535 
536   // C++0x [temp.dep.type]p2:
537   //  The template argument list of a primary template is a template argument
538   //  list in which the nth template argument has the value of the nth template
539   //  parameter of the class template. If the nth template parameter is a
540   //  template parameter pack (14.5.3), the nth template argument is a pack
541   //  expansion (14.5.3) whose pattern is the name of the template parameter
542   //  pack.
543   ASTContext &Context = getASTContext();
544   TemplateParameterList *Params = getTemplateParameters();
545   SmallVector<TemplateArgument, 16> TemplateArgs;
546   Context.getInjectedTemplateArgs(Params, TemplateArgs);
547   CommonPtr->InjectedClassNameType
548     = Context.getTemplateSpecializationType(TemplateName(this),
549                                             TemplateArgs);
550   return CommonPtr->InjectedClassNameType;
551 }
552 
553 //===----------------------------------------------------------------------===//
554 // TemplateTypeParm Allocation/Deallocation Method Implementations
555 //===----------------------------------------------------------------------===//
556 
557 TemplateTypeParmDecl *
558 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
559                              SourceLocation KeyLoc, SourceLocation NameLoc,
560                              unsigned D, unsigned P, IdentifierInfo *Id,
561                              bool Typename, bool ParameterPack) {
562   auto *TTPDecl =
563       new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
564   QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
565   TTPDecl->setTypeForDecl(TTPType.getTypePtr());
566   return TTPDecl;
567 }
568 
569 TemplateTypeParmDecl *
570 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
571   return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
572                                           SourceLocation(), nullptr, false);
573 }
574 
575 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
576   return hasDefaultArgument()
577              ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
578              : SourceLocation();
579 }
580 
581 SourceRange TemplateTypeParmDecl::getSourceRange() const {
582   if (hasDefaultArgument() && !defaultArgumentWasInherited())
583     return SourceRange(getBeginLoc(),
584                        getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
585   // TypeDecl::getSourceRange returns a range containing name location, which is
586   // wrong for unnamed template parameters. e.g:
587   // it will return <[[typename>]] instead of <[[typename]]>
588   else if (getDeclName().isEmpty())
589     return SourceRange(getBeginLoc());
590   return TypeDecl::getSourceRange();
591 }
592 
593 unsigned TemplateTypeParmDecl::getDepth() const {
594   return getTypeForDecl()->castAs<TemplateTypeParmType>()->getDepth();
595 }
596 
597 unsigned TemplateTypeParmDecl::getIndex() const {
598   return getTypeForDecl()->castAs<TemplateTypeParmType>()->getIndex();
599 }
600 
601 bool TemplateTypeParmDecl::isParameterPack() const {
602   return getTypeForDecl()->castAs<TemplateTypeParmType>()->isParameterPack();
603 }
604 
605 //===----------------------------------------------------------------------===//
606 // NonTypeTemplateParmDecl Method Implementations
607 //===----------------------------------------------------------------------===//
608 
609 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
610     DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
611     unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
612     ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
613     : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
614       TemplateParmPosition(D, P), ParameterPack(true),
615       ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
616   if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
617     auto TypesAndInfos =
618         getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
619     for (unsigned I = 0; I != NumExpandedTypes; ++I) {
620       new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
621       TypesAndInfos[I].second = ExpandedTInfos[I];
622     }
623   }
624 }
625 
626 NonTypeTemplateParmDecl *
627 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
628                                 SourceLocation StartLoc, SourceLocation IdLoc,
629                                 unsigned D, unsigned P, IdentifierInfo *Id,
630                                 QualType T, bool ParameterPack,
631                                 TypeSourceInfo *TInfo) {
632   return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
633                                              T, ParameterPack, TInfo);
634 }
635 
636 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
637     const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
638     SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
639     QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
640     ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
641   return new (C, DC,
642               additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
643                   ExpandedTypes.size()))
644       NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
645                               ExpandedTypes, ExpandedTInfos);
646 }
647 
648 NonTypeTemplateParmDecl *
649 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
650   return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
651                                              SourceLocation(), 0, 0, nullptr,
652                                              QualType(), false, nullptr);
653 }
654 
655 NonTypeTemplateParmDecl *
656 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
657                                             unsigned NumExpandedTypes) {
658   auto *NTTP =
659       new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
660                       NumExpandedTypes))
661           NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
662                                   0, 0, nullptr, QualType(), nullptr, None,
663                                   None);
664   NTTP->NumExpandedTypes = NumExpandedTypes;
665   return NTTP;
666 }
667 
668 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
669   if (hasDefaultArgument() && !defaultArgumentWasInherited())
670     return SourceRange(getOuterLocStart(),
671                        getDefaultArgument()->getSourceRange().getEnd());
672   return DeclaratorDecl::getSourceRange();
673 }
674 
675 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
676   return hasDefaultArgument()
677     ? getDefaultArgument()->getSourceRange().getBegin()
678     : SourceLocation();
679 }
680 
681 //===----------------------------------------------------------------------===//
682 // TemplateTemplateParmDecl Method Implementations
683 //===----------------------------------------------------------------------===//
684 
685 void TemplateTemplateParmDecl::anchor() {}
686 
687 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
688     DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
689     IdentifierInfo *Id, TemplateParameterList *Params,
690     ArrayRef<TemplateParameterList *> Expansions)
691     : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
692       TemplateParmPosition(D, P), ParameterPack(true),
693       ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
694   if (!Expansions.empty())
695     std::uninitialized_copy(Expansions.begin(), Expansions.end(),
696                             getTrailingObjects<TemplateParameterList *>());
697 }
698 
699 TemplateTemplateParmDecl *
700 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
701                                  SourceLocation L, unsigned D, unsigned P,
702                                  bool ParameterPack, IdentifierInfo *Id,
703                                  TemplateParameterList *Params) {
704   return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
705                                               Params);
706 }
707 
708 TemplateTemplateParmDecl *
709 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
710                                  SourceLocation L, unsigned D, unsigned P,
711                                  IdentifierInfo *Id,
712                                  TemplateParameterList *Params,
713                                  ArrayRef<TemplateParameterList *> Expansions) {
714   return new (C, DC,
715               additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
716       TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
717 }
718 
719 TemplateTemplateParmDecl *
720 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
721   return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
722                                               false, nullptr, nullptr);
723 }
724 
725 TemplateTemplateParmDecl *
726 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
727                                              unsigned NumExpansions) {
728   auto *TTP =
729       new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
730           TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
731                                    nullptr, None);
732   TTP->NumExpandedParams = NumExpansions;
733   return TTP;
734 }
735 
736 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
737   return hasDefaultArgument() ? getDefaultArgument().getLocation()
738                               : SourceLocation();
739 }
740 
741 void TemplateTemplateParmDecl::setDefaultArgument(
742     const ASTContext &C, const TemplateArgumentLoc &DefArg) {
743   if (DefArg.getArgument().isNull())
744     DefaultArgument.set(nullptr);
745   else
746     DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
747 }
748 
749 //===----------------------------------------------------------------------===//
750 // TemplateArgumentList Implementation
751 //===----------------------------------------------------------------------===//
752 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
753     : Arguments(getTrailingObjects<TemplateArgument>()),
754       NumArguments(Args.size()) {
755   std::uninitialized_copy(Args.begin(), Args.end(),
756                           getTrailingObjects<TemplateArgument>());
757 }
758 
759 TemplateArgumentList *
760 TemplateArgumentList::CreateCopy(ASTContext &Context,
761                                  ArrayRef<TemplateArgument> Args) {
762   void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
763   return new (Mem) TemplateArgumentList(Args);
764 }
765 
766 FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
767     ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
768     TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
769     const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
770     MemberSpecializationInfo *MSInfo) {
771   const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
772   if (TemplateArgsAsWritten)
773     ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
774                                                         *TemplateArgsAsWritten);
775 
776   void *Mem =
777       C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
778   return new (Mem) FunctionTemplateSpecializationInfo(
779       FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
780 }
781 
782 //===----------------------------------------------------------------------===//
783 // ClassTemplateSpecializationDecl Implementation
784 //===----------------------------------------------------------------------===//
785 
786 ClassTemplateSpecializationDecl::
787 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
788                                 DeclContext *DC, SourceLocation StartLoc,
789                                 SourceLocation IdLoc,
790                                 ClassTemplateDecl *SpecializedTemplate,
791                                 ArrayRef<TemplateArgument> Args,
792                                 ClassTemplateSpecializationDecl *PrevDecl)
793     : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
794                     SpecializedTemplate->getIdentifier(), PrevDecl),
795     SpecializedTemplate(SpecializedTemplate),
796     TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
797     SpecializationKind(TSK_Undeclared) {
798 }
799 
800 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
801                                                                  Kind DK)
802     : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
803                     SourceLocation(), nullptr, nullptr),
804       SpecializationKind(TSK_Undeclared) {}
805 
806 ClassTemplateSpecializationDecl *
807 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
808                                         DeclContext *DC,
809                                         SourceLocation StartLoc,
810                                         SourceLocation IdLoc,
811                                         ClassTemplateDecl *SpecializedTemplate,
812                                         ArrayRef<TemplateArgument> Args,
813                                    ClassTemplateSpecializationDecl *PrevDecl) {
814   auto *Result =
815       new (Context, DC) ClassTemplateSpecializationDecl(
816           Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
817           SpecializedTemplate, Args, PrevDecl);
818   Result->setMayHaveOutOfDateDef(false);
819 
820   Context.getTypeDeclType(Result, PrevDecl);
821   return Result;
822 }
823 
824 ClassTemplateSpecializationDecl *
825 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
826                                                     unsigned ID) {
827   auto *Result =
828     new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
829   Result->setMayHaveOutOfDateDef(false);
830   return Result;
831 }
832 
833 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
834     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
835   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
836 
837   const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
838   if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
839           PS ? PS->getTemplateArgsAsWritten() : nullptr) {
840     printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
841   } else {
842     const TemplateArgumentList &TemplateArgs = getTemplateArgs();
843     printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
844   }
845 }
846 
847 ClassTemplateDecl *
848 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
849   if (const auto *PartialSpec =
850           SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
851     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
852   return SpecializedTemplate.get<ClassTemplateDecl*>();
853 }
854 
855 SourceRange
856 ClassTemplateSpecializationDecl::getSourceRange() const {
857   if (ExplicitInfo) {
858     SourceLocation Begin = getTemplateKeywordLoc();
859     if (Begin.isValid()) {
860       // Here we have an explicit (partial) specialization or instantiation.
861       assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
862              getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
863              getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
864       if (getExternLoc().isValid())
865         Begin = getExternLoc();
866       SourceLocation End = getBraceRange().getEnd();
867       if (End.isInvalid())
868         End = getTypeAsWritten()->getTypeLoc().getEndLoc();
869       return SourceRange(Begin, End);
870     }
871     // An implicit instantiation of a class template partial specialization
872     // uses ExplicitInfo to record the TypeAsWritten, but the source
873     // locations should be retrieved from the instantiation pattern.
874     using CTPSDecl = ClassTemplatePartialSpecializationDecl;
875     auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
876     CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
877     assert(inst_from != nullptr);
878     return inst_from->getSourceRange();
879   }
880   else {
881     // No explicit info available.
882     llvm::PointerUnion<ClassTemplateDecl *,
883                        ClassTemplatePartialSpecializationDecl *>
884       inst_from = getInstantiatedFrom();
885     if (inst_from.isNull())
886       return getSpecializedTemplate()->getSourceRange();
887     if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
888       return ctd->getSourceRange();
889     return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
890       ->getSourceRange();
891   }
892 }
893 
894 //===----------------------------------------------------------------------===//
895 // ConceptDecl Implementation
896 //===----------------------------------------------------------------------===//
897 ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
898                                  SourceLocation L, DeclarationName Name,
899                                  TemplateParameterList *Params,
900                                  Expr *ConstraintExpr) {
901   AdoptTemplateParameterList(Params, DC);
902   return new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
903 }
904 
905 ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C,
906                                              unsigned ID) {
907   ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
908                                                 DeclarationName(),
909                                                 nullptr, nullptr);
910 
911   return Result;
912 }
913 
914 //===----------------------------------------------------------------------===//
915 // ClassTemplatePartialSpecializationDecl Implementation
916 //===----------------------------------------------------------------------===//
917 void ClassTemplatePartialSpecializationDecl::anchor() {}
918 
919 ClassTemplatePartialSpecializationDecl::
920 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
921                                        DeclContext *DC,
922                                        SourceLocation StartLoc,
923                                        SourceLocation IdLoc,
924                                        TemplateParameterList *Params,
925                                        ClassTemplateDecl *SpecializedTemplate,
926                                        ArrayRef<TemplateArgument> Args,
927                                const ASTTemplateArgumentListInfo *ArgInfos,
928                                ClassTemplatePartialSpecializationDecl *PrevDecl)
929     : ClassTemplateSpecializationDecl(Context,
930                                       ClassTemplatePartialSpecialization,
931                                       TK, DC, StartLoc, IdLoc,
932                                       SpecializedTemplate, Args, PrevDecl),
933       TemplateParams(Params), ArgsAsWritten(ArgInfos),
934       InstantiatedFromMember(nullptr, false) {
935   AdoptTemplateParameterList(Params, this);
936 }
937 
938 ClassTemplatePartialSpecializationDecl *
939 ClassTemplatePartialSpecializationDecl::
940 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
941        SourceLocation StartLoc, SourceLocation IdLoc,
942        TemplateParameterList *Params,
943        ClassTemplateDecl *SpecializedTemplate,
944        ArrayRef<TemplateArgument> Args,
945        const TemplateArgumentListInfo &ArgInfos,
946        QualType CanonInjectedType,
947        ClassTemplatePartialSpecializationDecl *PrevDecl) {
948   const ASTTemplateArgumentListInfo *ASTArgInfos =
949     ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
950 
951   auto *Result = new (Context, DC)
952       ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
953                                              Params, SpecializedTemplate, Args,
954                                              ASTArgInfos, PrevDecl);
955   Result->setSpecializationKind(TSK_ExplicitSpecialization);
956   Result->setMayHaveOutOfDateDef(false);
957 
958   Context.getInjectedClassNameType(Result, CanonInjectedType);
959   return Result;
960 }
961 
962 ClassTemplatePartialSpecializationDecl *
963 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
964                                                            unsigned ID) {
965   auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
966   Result->setMayHaveOutOfDateDef(false);
967   return Result;
968 }
969 
970 //===----------------------------------------------------------------------===//
971 // FriendTemplateDecl Implementation
972 //===----------------------------------------------------------------------===//
973 
974 void FriendTemplateDecl::anchor() {}
975 
976 FriendTemplateDecl *
977 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
978                            SourceLocation L,
979                            MutableArrayRef<TemplateParameterList *> Params,
980                            FriendUnion Friend, SourceLocation FLoc) {
981   return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
982 }
983 
984 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
985                                                            unsigned ID) {
986   return new (C, ID) FriendTemplateDecl(EmptyShell());
987 }
988 
989 //===----------------------------------------------------------------------===//
990 // TypeAliasTemplateDecl Implementation
991 //===----------------------------------------------------------------------===//
992 
993 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
994                                                      DeclContext *DC,
995                                                      SourceLocation L,
996                                                      DeclarationName Name,
997                                                   TemplateParameterList *Params,
998                                                      NamedDecl *Decl) {
999   AdoptTemplateParameterList(Params, DC);
1000   return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1001 }
1002 
1003 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
1004                                                                  unsigned ID) {
1005   return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1006                                            DeclarationName(), nullptr, nullptr);
1007 }
1008 
1009 RedeclarableTemplateDecl::CommonBase *
1010 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
1011   auto *CommonPtr = new (C) Common;
1012   C.addDestruction(CommonPtr);
1013   return CommonPtr;
1014 }
1015 
1016 //===----------------------------------------------------------------------===//
1017 // ClassScopeFunctionSpecializationDecl Implementation
1018 //===----------------------------------------------------------------------===//
1019 
1020 void ClassScopeFunctionSpecializationDecl::anchor() {}
1021 
1022 ClassScopeFunctionSpecializationDecl *
1023 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
1024                                                          unsigned ID) {
1025   return new (C, ID) ClassScopeFunctionSpecializationDecl(
1026       nullptr, SourceLocation(), nullptr, nullptr);
1027 }
1028 
1029 //===----------------------------------------------------------------------===//
1030 // VarTemplateDecl Implementation
1031 //===----------------------------------------------------------------------===//
1032 
1033 VarTemplateDecl *VarTemplateDecl::getDefinition() {
1034   VarTemplateDecl *CurD = this;
1035   while (CurD) {
1036     if (CurD->isThisDeclarationADefinition())
1037       return CurD;
1038     CurD = CurD->getPreviousDecl();
1039   }
1040   return nullptr;
1041 }
1042 
1043 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
1044                                          SourceLocation L, DeclarationName Name,
1045                                          TemplateParameterList *Params,
1046                                          VarDecl *Decl) {
1047   AdoptTemplateParameterList(Params, DC);
1048   return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1049 }
1050 
1051 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
1052                                                      unsigned ID) {
1053   return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1054                                      DeclarationName(), nullptr, nullptr);
1055 }
1056 
1057 void VarTemplateDecl::LoadLazySpecializations() const {
1058   loadLazySpecializationsImpl();
1059 }
1060 
1061 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1062 VarTemplateDecl::getSpecializations() const {
1063   LoadLazySpecializations();
1064   return getCommonPtr()->Specializations;
1065 }
1066 
1067 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1068 VarTemplateDecl::getPartialSpecializations() {
1069   LoadLazySpecializations();
1070   return getCommonPtr()->PartialSpecializations;
1071 }
1072 
1073 RedeclarableTemplateDecl::CommonBase *
1074 VarTemplateDecl::newCommon(ASTContext &C) const {
1075   auto *CommonPtr = new (C) Common;
1076   C.addDestruction(CommonPtr);
1077   return CommonPtr;
1078 }
1079 
1080 VarTemplateSpecializationDecl *
1081 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1082                                     void *&InsertPos) {
1083   return findSpecializationImpl(getSpecializations(), InsertPos, Args);
1084 }
1085 
1086 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1087                                         void *InsertPos) {
1088   addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1089 }
1090 
1091 VarTemplatePartialSpecializationDecl *
1092 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1093      TemplateParameterList *TPL, void *&InsertPos) {
1094   return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1095                                 TPL);
1096 }
1097 
1098 void
1099 VarTemplatePartialSpecializationDecl::Profile(llvm::FoldingSetNodeID &ID,
1100     ArrayRef<TemplateArgument> TemplateArgs, TemplateParameterList *TPL,
1101     ASTContext &Context) {
1102   ID.AddInteger(TemplateArgs.size());
1103   for (const TemplateArgument &TemplateArg : TemplateArgs)
1104     TemplateArg.Profile(ID, Context);
1105   ProfileTemplateParameterList(Context, ID, TPL);
1106 }
1107 
1108 void VarTemplateDecl::AddPartialSpecialization(
1109     VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1110   if (InsertPos)
1111     getPartialSpecializations().InsertNode(D, InsertPos);
1112   else {
1113     VarTemplatePartialSpecializationDecl *Existing =
1114         getPartialSpecializations().GetOrInsertNode(D);
1115     (void)Existing;
1116     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1117   }
1118 
1119   if (ASTMutationListener *L = getASTMutationListener())
1120     L->AddedCXXTemplateSpecialization(this, D);
1121 }
1122 
1123 void VarTemplateDecl::getPartialSpecializations(
1124     SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1125   llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1126       getPartialSpecializations();
1127   PS.clear();
1128   PS.reserve(PartialSpecs.size());
1129   for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1130     PS.push_back(P.getMostRecentDecl());
1131 }
1132 
1133 VarTemplatePartialSpecializationDecl *
1134 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1135     VarTemplatePartialSpecializationDecl *D) {
1136   Decl *DCanon = D->getCanonicalDecl();
1137   for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1138     if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1139       return P.getMostRecentDecl();
1140   }
1141 
1142   return nullptr;
1143 }
1144 
1145 //===----------------------------------------------------------------------===//
1146 // VarTemplateSpecializationDecl Implementation
1147 //===----------------------------------------------------------------------===//
1148 
1149 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1150     Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1151     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1152     TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1153     : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1154               SpecializedTemplate->getIdentifier(), T, TInfo, S),
1155       SpecializedTemplate(SpecializedTemplate),
1156       TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1157       SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1158 
1159 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1160                                                              ASTContext &C)
1161     : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1162               QualType(), nullptr, SC_None),
1163       SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1164 
1165 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1166     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1167     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1168     TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1169   return new (Context, DC) VarTemplateSpecializationDecl(
1170       VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1171       SpecializedTemplate, T, TInfo, S, Args);
1172 }
1173 
1174 VarTemplateSpecializationDecl *
1175 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1176   return new (C, ID)
1177       VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1178 }
1179 
1180 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1181     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1182   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1183 
1184   const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1185   if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1186           PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1187     printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
1188   } else {
1189     const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1190     printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
1191   }
1192 }
1193 
1194 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1195   if (const auto *PartialSpec =
1196           SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1197     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1198   return SpecializedTemplate.get<VarTemplateDecl *>();
1199 }
1200 
1201 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1202     const TemplateArgumentListInfo &ArgsInfo) {
1203   TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1204   TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1205   for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1206     TemplateArgsInfo.addArgument(Loc);
1207 }
1208 
1209 //===----------------------------------------------------------------------===//
1210 // VarTemplatePartialSpecializationDecl Implementation
1211 //===----------------------------------------------------------------------===//
1212 
1213 void VarTemplatePartialSpecializationDecl::anchor() {}
1214 
1215 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1216     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1217     SourceLocation IdLoc, TemplateParameterList *Params,
1218     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1219     StorageClass S, ArrayRef<TemplateArgument> Args,
1220     const ASTTemplateArgumentListInfo *ArgInfos)
1221     : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1222                                     DC, StartLoc, IdLoc, SpecializedTemplate, T,
1223                                     TInfo, S, Args),
1224       TemplateParams(Params), ArgsAsWritten(ArgInfos),
1225       InstantiatedFromMember(nullptr, false) {
1226   // TODO: The template parameters should be in DC by now. Verify.
1227   // AdoptTemplateParameterList(Params, DC);
1228 }
1229 
1230 VarTemplatePartialSpecializationDecl *
1231 VarTemplatePartialSpecializationDecl::Create(
1232     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1233     SourceLocation IdLoc, TemplateParameterList *Params,
1234     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1235     StorageClass S, ArrayRef<TemplateArgument> Args,
1236     const TemplateArgumentListInfo &ArgInfos) {
1237   const ASTTemplateArgumentListInfo *ASTArgInfos
1238     = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1239 
1240   auto *Result =
1241       new (Context, DC) VarTemplatePartialSpecializationDecl(
1242           Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1243           S, Args, ASTArgInfos);
1244   Result->setSpecializationKind(TSK_ExplicitSpecialization);
1245   return Result;
1246 }
1247 
1248 VarTemplatePartialSpecializationDecl *
1249 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1250                                                          unsigned ID) {
1251   return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1252 }
1253 
1254 static TemplateParameterList *
1255 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1256   // typename T
1257   auto *T = TemplateTypeParmDecl::Create(
1258       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1259       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1260   T->setImplicit(true);
1261 
1262   // T ...Ints
1263   TypeSourceInfo *TI =
1264       C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1265   auto *N = NonTypeTemplateParmDecl::Create(
1266       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1267       /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1268   N->setImplicit(true);
1269 
1270   // <typename T, T ...Ints>
1271   NamedDecl *P[2] = {T, N};
1272   auto *TPL = TemplateParameterList::Create(
1273       C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1274 
1275   // template <typename T, ...Ints> class IntSeq
1276   auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1277       C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1278       /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1279   TemplateTemplateParm->setImplicit(true);
1280 
1281   // typename T
1282   auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1283       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1284       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1285   TemplateTypeParm->setImplicit(true);
1286 
1287   // T N
1288   TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1289       QualType(TemplateTypeParm->getTypeForDecl(), 0));
1290   auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1291       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1292       /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1293   NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1294                          NonTypeTemplateParm};
1295 
1296   // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1297   return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1298                                        Params, SourceLocation(), nullptr);
1299 }
1300 
1301 static TemplateParameterList *
1302 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1303   // std::size_t Index
1304   TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1305   auto *Index = NonTypeTemplateParmDecl::Create(
1306       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1307       /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1308 
1309   // typename ...T
1310   auto *Ts = TemplateTypeParmDecl::Create(
1311       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1312       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1313   Ts->setImplicit(true);
1314 
1315   // template <std::size_t Index, typename ...T>
1316   NamedDecl *Params[] = {Index, Ts};
1317   return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1318                                        llvm::makeArrayRef(Params),
1319                                        SourceLocation(), nullptr);
1320 }
1321 
1322 static TemplateParameterList *createBuiltinTemplateParameterList(
1323     const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1324   switch (BTK) {
1325   case BTK__make_integer_seq:
1326     return createMakeIntegerSeqParameterList(C, DC);
1327   case BTK__type_pack_element:
1328     return createTypePackElementParameterList(C, DC);
1329   }
1330 
1331   llvm_unreachable("unhandled BuiltinTemplateKind!");
1332 }
1333 
1334 void BuiltinTemplateDecl::anchor() {}
1335 
1336 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1337                                          DeclarationName Name,
1338                                          BuiltinTemplateKind BTK)
1339     : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1340                    createBuiltinTemplateParameterList(C, DC, BTK)),
1341       BTK(BTK) {}
1342