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