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