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