1 //===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the C++ related Decl classes for templates.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/AST/DeclTemplate.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/ASTMutationListener.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/ExprCXX.h"
20 #include "clang/AST/TypeLoc.h"
21 #include "clang/Basic/IdentifierTable.h"
22 #include "llvm/ADT/STLExtras.h"
23 #include <memory>
24 using namespace clang;
25 
26 //===----------------------------------------------------------------------===//
27 // TemplateParameterList Implementation
28 //===----------------------------------------------------------------------===//
29 
30 TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
31                                              SourceLocation LAngleLoc,
32                                              NamedDecl **Params, unsigned NumParams,
33                                              SourceLocation RAngleLoc)
34   : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
35     NumParams(NumParams), ContainsUnexpandedParameterPack(false) {
36   assert(this->NumParams == NumParams && "Too many template parameters");
37   for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
38     NamedDecl *P = Params[Idx];
39     begin()[Idx] = P;
40 
41     if (!P->isTemplateParameterPack()) {
42       if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
43         if (NTTP->getType()->containsUnexpandedParameterPack())
44           ContainsUnexpandedParameterPack = true;
45 
46       if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
47         if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
48           ContainsUnexpandedParameterPack = true;
49 
50       // FIXME: If a default argument contains an unexpanded parameter pack, the
51       // template parameter list does too.
52     }
53   }
54 }
55 
56 TemplateParameterList *
57 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
58                               SourceLocation LAngleLoc, NamedDecl **Params,
59                               unsigned NumParams, SourceLocation RAngleLoc) {
60   unsigned Size = sizeof(TemplateParameterList)
61                 + sizeof(NamedDecl *) * NumParams;
62   unsigned Align = std::max(llvm::alignOf<TemplateParameterList>(),
63                             llvm::alignOf<NamedDecl*>());
64   void *Mem = C.Allocate(Size, Align);
65   return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
66                                          NumParams, RAngleLoc);
67 }
68 
69 unsigned TemplateParameterList::getMinRequiredArguments() const {
70   unsigned NumRequiredArgs = 0;
71   for (iterator P = const_cast<TemplateParameterList *>(this)->begin(),
72              PEnd = const_cast<TemplateParameterList *>(this)->end();
73        P != PEnd; ++P) {
74     if ((*P)->isTemplateParameterPack()) {
75       if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P))
76         if (NTTP->isExpandedParameterPack()) {
77           NumRequiredArgs += NTTP->getNumExpansionTypes();
78           continue;
79         }
80 
81       break;
82     }
83 
84     if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
85       if (TTP->hasDefaultArgument())
86         break;
87     } else if (NonTypeTemplateParmDecl *NTTP
88                                     = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
89       if (NTTP->hasDefaultArgument())
90         break;
91     } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument())
92       break;
93 
94     ++NumRequiredArgs;
95   }
96 
97   return NumRequiredArgs;
98 }
99 
100 unsigned TemplateParameterList::getDepth() const {
101   if (size() == 0)
102     return 0;
103 
104   const NamedDecl *FirstParm = getParam(0);
105   if (const TemplateTypeParmDecl *TTP
106         = dyn_cast<TemplateTypeParmDecl>(FirstParm))
107     return TTP->getDepth();
108   else if (const NonTypeTemplateParmDecl *NTTP
109              = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
110     return NTTP->getDepth();
111   else
112     return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
113 }
114 
115 static void AdoptTemplateParameterList(TemplateParameterList *Params,
116                                        DeclContext *Owner) {
117   for (TemplateParameterList::iterator P = Params->begin(),
118                                     PEnd = Params->end();
119        P != PEnd; ++P) {
120     (*P)->setDeclContext(Owner);
121 
122     if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P))
123       AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
124   }
125 }
126 
127 //===----------------------------------------------------------------------===//
128 // RedeclarableTemplateDecl Implementation
129 //===----------------------------------------------------------------------===//
130 
131 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
132   if (Common)
133     return Common;
134 
135   // Walk the previous-declaration chain until we either find a declaration
136   // with a common pointer or we run out of previous declarations.
137   SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
138   for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
139        Prev = Prev->getPreviousDecl()) {
140     if (Prev->Common) {
141       Common = Prev->Common;
142       break;
143     }
144 
145     PrevDecls.push_back(Prev);
146   }
147 
148   // If we never found a common pointer, allocate one now.
149   if (!Common) {
150     // FIXME: If any of the declarations is from an AST file, we probably
151     // need an update record to add the common data.
152 
153     Common = newCommon(getASTContext());
154   }
155 
156   // Update any previous declarations we saw with the common pointer.
157   for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I)
158     PrevDecls[I]->Common = Common;
159 
160   return Common;
161 }
162 
163 template <class EntryType>
164 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
165 RedeclarableTemplateDecl::findSpecializationImpl(
166                                  llvm::FoldingSetVector<EntryType> &Specs,
167                                  const TemplateArgument *Args, unsigned NumArgs,
168                                  void *&InsertPos) {
169   typedef SpecEntryTraits<EntryType> SETraits;
170   llvm::FoldingSetNodeID ID;
171   EntryType::Profile(ID,Args,NumArgs, getASTContext());
172   EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
173   return Entry ? SETraits::getMostRecentDecl(Entry) : nullptr;
174 }
175 
176 /// \brief Generate the injected template arguments for the given template
177 /// parameter list, e.g., for the injected-class-name of a class template.
178 static void GenerateInjectedTemplateArgs(ASTContext &Context,
179                                         TemplateParameterList *Params,
180                                          TemplateArgument *Args) {
181   for (TemplateParameterList::iterator Param = Params->begin(),
182                                     ParamEnd = Params->end();
183        Param != ParamEnd; ++Param) {
184     TemplateArgument Arg;
185     if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
186       QualType ArgType = Context.getTypeDeclType(TTP);
187       if (TTP->isParameterPack())
188         ArgType = Context.getPackExpansionType(ArgType, None);
189 
190       Arg = TemplateArgument(ArgType);
191     } else if (NonTypeTemplateParmDecl *NTTP =
192                dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
193       Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
194                                   NTTP->getType().getNonLValueExprType(Context),
195                                   Expr::getValueKindForType(NTTP->getType()),
196                                           NTTP->getLocation());
197 
198       if (NTTP->isParameterPack())
199         E = new (Context) PackExpansionExpr(Context.DependentTy, E,
200                                             NTTP->getLocation(), None);
201       Arg = TemplateArgument(E);
202     } else {
203       TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
204       if (TTP->isParameterPack())
205         Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
206       else
207         Arg = TemplateArgument(TemplateName(TTP));
208     }
209 
210     if ((*Param)->isTemplateParameterPack())
211       Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
212 
213     *Args++ = Arg;
214   }
215 }
216 
217 //===----------------------------------------------------------------------===//
218 // FunctionTemplateDecl Implementation
219 //===----------------------------------------------------------------------===//
220 
221 void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
222   static_cast<Common *>(Ptr)->~Common();
223 }
224 
225 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
226                                                    DeclContext *DC,
227                                                    SourceLocation L,
228                                                    DeclarationName Name,
229                                                TemplateParameterList *Params,
230                                                    NamedDecl *Decl) {
231   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
232   return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
233 }
234 
235 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
236                                                                unsigned ID) {
237   return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
238                                           DeclarationName(), nullptr, nullptr);
239 }
240 
241 RedeclarableTemplateDecl::CommonBase *
242 FunctionTemplateDecl::newCommon(ASTContext &C) const {
243   Common *CommonPtr = new (C) Common;
244   C.AddDeallocation(DeallocateCommon, CommonPtr);
245   return CommonPtr;
246 }
247 
248 void FunctionTemplateDecl::LoadLazySpecializations() const {
249   Common *CommonPtr = getCommonPtr();
250   if (CommonPtr->LazySpecializations) {
251     ASTContext &Context = getASTContext();
252     uint32_t *Specs = CommonPtr->LazySpecializations;
253     CommonPtr->LazySpecializations = nullptr;
254     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
255       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
256   }
257 }
258 
259 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
260 FunctionTemplateDecl::getSpecializations() const {
261   LoadLazySpecializations();
262   return getCommonPtr()->Specializations;
263 }
264 
265 FunctionDecl *
266 FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
267                                          unsigned NumArgs, void *&InsertPos) {
268   return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
269 }
270 
271 void FunctionTemplateDecl::addSpecialization(
272       FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
273   if (InsertPos)
274     getSpecializations().InsertNode(Info, InsertPos);
275   else
276     getSpecializations().GetOrInsertNode(Info);
277   if (ASTMutationListener *L = getASTMutationListener())
278     L->AddedCXXTemplateSpecialization(this, Info->Function);
279 }
280 
281 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
282   TemplateParameterList *Params = getTemplateParameters();
283   Common *CommonPtr = getCommonPtr();
284   if (!CommonPtr->InjectedArgs) {
285     CommonPtr->InjectedArgs
286       = new (getASTContext()) TemplateArgument[Params->size()];
287     GenerateInjectedTemplateArgs(getASTContext(), Params,
288                                  CommonPtr->InjectedArgs);
289   }
290 
291   return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
292 }
293 
294 //===----------------------------------------------------------------------===//
295 // ClassTemplateDecl Implementation
296 //===----------------------------------------------------------------------===//
297 
298 void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
299   static_cast<Common *>(Ptr)->~Common();
300 }
301 
302 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
303                                              DeclContext *DC,
304                                              SourceLocation L,
305                                              DeclarationName Name,
306                                              TemplateParameterList *Params,
307                                              NamedDecl *Decl,
308                                              ClassTemplateDecl *PrevDecl) {
309   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
310   ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
311                                                          Params, Decl);
312   New->setPreviousDecl(PrevDecl);
313   return New;
314 }
315 
316 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
317                                                          unsigned ID) {
318   return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
319                                        DeclarationName(), nullptr, nullptr);
320 }
321 
322 void ClassTemplateDecl::LoadLazySpecializations() const {
323   Common *CommonPtr = getCommonPtr();
324   if (CommonPtr->LazySpecializations) {
325     ASTContext &Context = getASTContext();
326     uint32_t *Specs = CommonPtr->LazySpecializations;
327     CommonPtr->LazySpecializations = nullptr;
328     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
329       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
330   }
331 }
332 
333 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
334 ClassTemplateDecl::getSpecializations() const {
335   LoadLazySpecializations();
336   return getCommonPtr()->Specializations;
337 }
338 
339 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
340 ClassTemplateDecl::getPartialSpecializations() {
341   LoadLazySpecializations();
342   return getCommonPtr()->PartialSpecializations;
343 }
344 
345 RedeclarableTemplateDecl::CommonBase *
346 ClassTemplateDecl::newCommon(ASTContext &C) const {
347   Common *CommonPtr = new (C) Common;
348   C.AddDeallocation(DeallocateCommon, CommonPtr);
349   return CommonPtr;
350 }
351 
352 ClassTemplateSpecializationDecl *
353 ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
354                                       unsigned NumArgs, void *&InsertPos) {
355   return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
356 }
357 
358 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
359                                           void *InsertPos) {
360   if (InsertPos)
361     getSpecializations().InsertNode(D, InsertPos);
362   else {
363     ClassTemplateSpecializationDecl *Existing
364       = getSpecializations().GetOrInsertNode(D);
365     (void)Existing;
366     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
367   }
368   if (ASTMutationListener *L = getASTMutationListener())
369     L->AddedCXXTemplateSpecialization(this, D);
370 }
371 
372 ClassTemplatePartialSpecializationDecl *
373 ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
374                                              unsigned NumArgs,
375                                              void *&InsertPos) {
376   return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
377                                 InsertPos);
378 }
379 
380 void ClassTemplateDecl::AddPartialSpecialization(
381                                       ClassTemplatePartialSpecializationDecl *D,
382                                       void *InsertPos) {
383   if (InsertPos)
384     getPartialSpecializations().InsertNode(D, InsertPos);
385   else {
386     ClassTemplatePartialSpecializationDecl *Existing
387       = getPartialSpecializations().GetOrInsertNode(D);
388     (void)Existing;
389     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
390   }
391 
392   if (ASTMutationListener *L = getASTMutationListener())
393     L->AddedCXXTemplateSpecialization(this, D);
394 }
395 
396 void ClassTemplateDecl::getPartialSpecializations(
397           SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
398   llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
399     = getPartialSpecializations();
400   PS.clear();
401   PS.reserve(PartialSpecs.size());
402   for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
403        P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
404        P != PEnd; ++P)
405     PS.push_back(P->getMostRecentDecl());
406 }
407 
408 ClassTemplatePartialSpecializationDecl *
409 ClassTemplateDecl::findPartialSpecialization(QualType T) {
410   ASTContext &Context = getASTContext();
411   using llvm::FoldingSetVector;
412   typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
413     partial_spec_iterator;
414   for (partial_spec_iterator P = getPartialSpecializations().begin(),
415                           PEnd = getPartialSpecializations().end();
416        P != PEnd; ++P) {
417     if (Context.hasSameType(P->getInjectedSpecializationType(), T))
418       return P->getMostRecentDecl();
419   }
420 
421   return nullptr;
422 }
423 
424 ClassTemplatePartialSpecializationDecl *
425 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
426                                     ClassTemplatePartialSpecializationDecl *D) {
427   Decl *DCanon = D->getCanonicalDecl();
428   for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
429             P = getPartialSpecializations().begin(),
430          PEnd = getPartialSpecializations().end();
431        P != PEnd; ++P) {
432     if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
433       return P->getMostRecentDecl();
434   }
435 
436   return nullptr;
437 }
438 
439 QualType
440 ClassTemplateDecl::getInjectedClassNameSpecialization() {
441   Common *CommonPtr = getCommonPtr();
442   if (!CommonPtr->InjectedClassNameType.isNull())
443     return CommonPtr->InjectedClassNameType;
444 
445   // C++0x [temp.dep.type]p2:
446   //  The template argument list of a primary template is a template argument
447   //  list in which the nth template argument has the value of the nth template
448   //  parameter of the class template. If the nth template parameter is a
449   //  template parameter pack (14.5.3), the nth template argument is a pack
450   //  expansion (14.5.3) whose pattern is the name of the template parameter
451   //  pack.
452   ASTContext &Context = getASTContext();
453   TemplateParameterList *Params = getTemplateParameters();
454   SmallVector<TemplateArgument, 16> TemplateArgs;
455   TemplateArgs.resize(Params->size());
456   GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
457   CommonPtr->InjectedClassNameType
458     = Context.getTemplateSpecializationType(TemplateName(this),
459                                             &TemplateArgs[0],
460                                             TemplateArgs.size());
461   return CommonPtr->InjectedClassNameType;
462 }
463 
464 //===----------------------------------------------------------------------===//
465 // TemplateTypeParm Allocation/Deallocation Method Implementations
466 //===----------------------------------------------------------------------===//
467 
468 TemplateTypeParmDecl *
469 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
470                              SourceLocation KeyLoc, SourceLocation NameLoc,
471                              unsigned D, unsigned P, IdentifierInfo *Id,
472                              bool Typename, bool ParameterPack) {
473   TemplateTypeParmDecl *TTPDecl =
474     new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
475   QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
476   TTPDecl->setTypeForDecl(TTPType.getTypePtr());
477   return TTPDecl;
478 }
479 
480 TemplateTypeParmDecl *
481 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
482   return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
483                                           SourceLocation(), nullptr, false);
484 }
485 
486 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
487   return hasDefaultArgument()
488     ? DefaultArgument->getTypeLoc().getBeginLoc()
489     : SourceLocation();
490 }
491 
492 SourceRange TemplateTypeParmDecl::getSourceRange() const {
493   if (hasDefaultArgument() && !defaultArgumentWasInherited())
494     return SourceRange(getLocStart(),
495                        DefaultArgument->getTypeLoc().getEndLoc());
496   else
497     return TypeDecl::getSourceRange();
498 }
499 
500 unsigned TemplateTypeParmDecl::getDepth() const {
501   return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
502 }
503 
504 unsigned TemplateTypeParmDecl::getIndex() const {
505   return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
506 }
507 
508 bool TemplateTypeParmDecl::isParameterPack() const {
509   return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
510 }
511 
512 //===----------------------------------------------------------------------===//
513 // NonTypeTemplateParmDecl Method Implementations
514 //===----------------------------------------------------------------------===//
515 
516 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
517                                                  SourceLocation StartLoc,
518                                                  SourceLocation IdLoc,
519                                                  unsigned D, unsigned P,
520                                                  IdentifierInfo *Id,
521                                                  QualType T,
522                                                  TypeSourceInfo *TInfo,
523                                                  const QualType *ExpandedTypes,
524                                                  unsigned NumExpandedTypes,
525                                                 TypeSourceInfo **ExpandedTInfos)
526   : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
527     TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false),
528     ParameterPack(true), ExpandedParameterPack(true),
529     NumExpandedTypes(NumExpandedTypes)
530 {
531   if (ExpandedTypes && ExpandedTInfos) {
532     void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
533     for (unsigned I = 0; I != NumExpandedTypes; ++I) {
534       TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
535       TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
536     }
537   }
538 }
539 
540 NonTypeTemplateParmDecl *
541 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
542                                 SourceLocation StartLoc, SourceLocation IdLoc,
543                                 unsigned D, unsigned P, IdentifierInfo *Id,
544                                 QualType T, bool ParameterPack,
545                                 TypeSourceInfo *TInfo) {
546   return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
547                                              T, ParameterPack, TInfo);
548 }
549 
550 NonTypeTemplateParmDecl *
551 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
552                                 SourceLocation StartLoc, SourceLocation IdLoc,
553                                 unsigned D, unsigned P,
554                                 IdentifierInfo *Id, QualType T,
555                                 TypeSourceInfo *TInfo,
556                                 const QualType *ExpandedTypes,
557                                 unsigned NumExpandedTypes,
558                                 TypeSourceInfo **ExpandedTInfos) {
559   unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
560   return new (C, DC, Extra) NonTypeTemplateParmDecl(
561       DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
562       ExpandedTypes, NumExpandedTypes, ExpandedTInfos);
563 }
564 
565 NonTypeTemplateParmDecl *
566 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
567   return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
568                                              SourceLocation(), 0, 0, nullptr,
569                                              QualType(), false, nullptr);
570 }
571 
572 NonTypeTemplateParmDecl *
573 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
574                                             unsigned NumExpandedTypes) {
575   unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
576   return new (C, ID, Extra) NonTypeTemplateParmDecl(
577       nullptr, SourceLocation(), SourceLocation(), 0, 0, nullptr, QualType(),
578       nullptr, nullptr, NumExpandedTypes, nullptr);
579 }
580 
581 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
582   if (hasDefaultArgument() && !defaultArgumentWasInherited())
583     return SourceRange(getOuterLocStart(),
584                        getDefaultArgument()->getSourceRange().getEnd());
585   return DeclaratorDecl::getSourceRange();
586 }
587 
588 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
589   return hasDefaultArgument()
590     ? getDefaultArgument()->getSourceRange().getBegin()
591     : SourceLocation();
592 }
593 
594 //===----------------------------------------------------------------------===//
595 // TemplateTemplateParmDecl Method Implementations
596 //===----------------------------------------------------------------------===//
597 
598 void TemplateTemplateParmDecl::anchor() { }
599 
600 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
601     DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
602     IdentifierInfo *Id, TemplateParameterList *Params,
603     unsigned NumExpansions, TemplateParameterList * const *Expansions)
604   : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
605     TemplateParmPosition(D, P), DefaultArgument(),
606     DefaultArgumentWasInherited(false), ParameterPack(true),
607     ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
608   if (Expansions)
609     std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
610                 sizeof(TemplateParameterList*) * NumExpandedParams);
611 }
612 
613 TemplateTemplateParmDecl *
614 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
615                                  SourceLocation L, unsigned D, unsigned P,
616                                  bool ParameterPack, IdentifierInfo *Id,
617                                  TemplateParameterList *Params) {
618   return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
619                                               Params);
620 }
621 
622 TemplateTemplateParmDecl *
623 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
624                                  SourceLocation L, unsigned D, unsigned P,
625                                  IdentifierInfo *Id,
626                                  TemplateParameterList *Params,
627                                  ArrayRef<TemplateParameterList *> Expansions) {
628   return new (C, DC, sizeof(TemplateParameterList*) * Expansions.size())
629       TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
630                                Expansions.size(), Expansions.data());
631 }
632 
633 TemplateTemplateParmDecl *
634 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
635   return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
636                                               false, nullptr, nullptr);
637 }
638 
639 TemplateTemplateParmDecl *
640 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
641                                              unsigned NumExpansions) {
642   return new (C, ID, sizeof(TemplateParameterList*) * NumExpansions)
643       TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
644                                nullptr, NumExpansions, nullptr);
645 }
646 
647 //===----------------------------------------------------------------------===//
648 // TemplateArgumentList Implementation
649 //===----------------------------------------------------------------------===//
650 TemplateArgumentList *
651 TemplateArgumentList::CreateCopy(ASTContext &Context,
652                                  const TemplateArgument *Args,
653                                  unsigned NumArgs) {
654   std::size_t Size = sizeof(TemplateArgumentList)
655                    + NumArgs * sizeof(TemplateArgument);
656   void *Mem = Context.Allocate(Size);
657   TemplateArgument *StoredArgs
658     = reinterpret_cast<TemplateArgument *>(
659                                 static_cast<TemplateArgumentList *>(Mem) + 1);
660   std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
661   return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
662 }
663 
664 FunctionTemplateSpecializationInfo *
665 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
666                                            FunctionTemplateDecl *Template,
667                                            TemplateSpecializationKind TSK,
668                                        const TemplateArgumentList *TemplateArgs,
669                           const TemplateArgumentListInfo *TemplateArgsAsWritten,
670                                            SourceLocation POI) {
671   const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
672   if (TemplateArgsAsWritten)
673     ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
674                                                         *TemplateArgsAsWritten);
675 
676   return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
677                                                     TemplateArgs,
678                                                     ArgsAsWritten,
679                                                     POI);
680 }
681 
682 //===----------------------------------------------------------------------===//
683 // TemplateDecl Implementation
684 //===----------------------------------------------------------------------===//
685 
686 void TemplateDecl::anchor() { }
687 
688 //===----------------------------------------------------------------------===//
689 // ClassTemplateSpecializationDecl Implementation
690 //===----------------------------------------------------------------------===//
691 ClassTemplateSpecializationDecl::
692 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
693                                 DeclContext *DC, SourceLocation StartLoc,
694                                 SourceLocation IdLoc,
695                                 ClassTemplateDecl *SpecializedTemplate,
696                                 const TemplateArgument *Args,
697                                 unsigned NumArgs,
698                                 ClassTemplateSpecializationDecl *PrevDecl)
699   : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
700                   SpecializedTemplate->getIdentifier(),
701                   PrevDecl),
702     SpecializedTemplate(SpecializedTemplate),
703     ExplicitInfo(nullptr),
704     TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
705     SpecializationKind(TSK_Undeclared) {
706 }
707 
708 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
709                                                                  Kind DK)
710     : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
711                     SourceLocation(), nullptr, nullptr),
712       ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
713 
714 ClassTemplateSpecializationDecl *
715 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
716                                         DeclContext *DC,
717                                         SourceLocation StartLoc,
718                                         SourceLocation IdLoc,
719                                         ClassTemplateDecl *SpecializedTemplate,
720                                         const TemplateArgument *Args,
721                                         unsigned NumArgs,
722                                    ClassTemplateSpecializationDecl *PrevDecl) {
723   ClassTemplateSpecializationDecl *Result =
724       new (Context, DC) ClassTemplateSpecializationDecl(
725           Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
726           SpecializedTemplate, Args, NumArgs, PrevDecl);
727   Result->MayHaveOutOfDateDef = false;
728 
729   Context.getTypeDeclType(Result, PrevDecl);
730   return Result;
731 }
732 
733 ClassTemplateSpecializationDecl *
734 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
735                                                     unsigned ID) {
736   ClassTemplateSpecializationDecl *Result =
737     new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
738   Result->MayHaveOutOfDateDef = false;
739   return Result;
740 }
741 
742 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
743     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
744   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
745 
746   const TemplateArgumentList &TemplateArgs = getTemplateArgs();
747   TemplateSpecializationType::PrintTemplateArgumentList(
748       OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
749 }
750 
751 ClassTemplateDecl *
752 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
753   if (SpecializedPartialSpecialization *PartialSpec
754       = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
755     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
756   return SpecializedTemplate.get<ClassTemplateDecl*>();
757 }
758 
759 SourceRange
760 ClassTemplateSpecializationDecl::getSourceRange() const {
761   if (ExplicitInfo) {
762     SourceLocation Begin = getTemplateKeywordLoc();
763     if (Begin.isValid()) {
764       // Here we have an explicit (partial) specialization or instantiation.
765       assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
766              getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
767              getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
768       if (getExternLoc().isValid())
769         Begin = getExternLoc();
770       SourceLocation End = getRBraceLoc();
771       if (End.isInvalid())
772         End = getTypeAsWritten()->getTypeLoc().getEndLoc();
773       return SourceRange(Begin, End);
774     }
775     // An implicit instantiation of a class template partial specialization
776     // uses ExplicitInfo to record the TypeAsWritten, but the source
777     // locations should be retrieved from the instantiation pattern.
778     typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
779     CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
780     CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
781     assert(inst_from != nullptr);
782     return inst_from->getSourceRange();
783   }
784   else {
785     // No explicit info available.
786     llvm::PointerUnion<ClassTemplateDecl *,
787                        ClassTemplatePartialSpecializationDecl *>
788       inst_from = getInstantiatedFrom();
789     if (inst_from.isNull())
790       return getSpecializedTemplate()->getSourceRange();
791     if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
792       return ctd->getSourceRange();
793     return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
794       ->getSourceRange();
795   }
796 }
797 
798 //===----------------------------------------------------------------------===//
799 // ClassTemplatePartialSpecializationDecl Implementation
800 //===----------------------------------------------------------------------===//
801 void ClassTemplatePartialSpecializationDecl::anchor() { }
802 
803 ClassTemplatePartialSpecializationDecl::
804 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
805                                        DeclContext *DC,
806                                        SourceLocation StartLoc,
807                                        SourceLocation IdLoc,
808                                        TemplateParameterList *Params,
809                                        ClassTemplateDecl *SpecializedTemplate,
810                                        const TemplateArgument *Args,
811                                        unsigned NumArgs,
812                                const ASTTemplateArgumentListInfo *ArgInfos,
813                                ClassTemplatePartialSpecializationDecl *PrevDecl)
814   : ClassTemplateSpecializationDecl(Context,
815                                     ClassTemplatePartialSpecialization,
816                                     TK, DC, StartLoc, IdLoc,
817                                     SpecializedTemplate,
818                                     Args, NumArgs, PrevDecl),
819     TemplateParams(Params), ArgsAsWritten(ArgInfos),
820     InstantiatedFromMember(nullptr, false)
821 {
822   AdoptTemplateParameterList(Params, this);
823 }
824 
825 ClassTemplatePartialSpecializationDecl *
826 ClassTemplatePartialSpecializationDecl::
827 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
828        SourceLocation StartLoc, SourceLocation IdLoc,
829        TemplateParameterList *Params,
830        ClassTemplateDecl *SpecializedTemplate,
831        const TemplateArgument *Args,
832        unsigned NumArgs,
833        const TemplateArgumentListInfo &ArgInfos,
834        QualType CanonInjectedType,
835        ClassTemplatePartialSpecializationDecl *PrevDecl) {
836   const ASTTemplateArgumentListInfo *ASTArgInfos =
837     ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
838 
839   ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
840       ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
841                                              Params, SpecializedTemplate, Args,
842                                              NumArgs, ASTArgInfos, PrevDecl);
843   Result->setSpecializationKind(TSK_ExplicitSpecialization);
844   Result->MayHaveOutOfDateDef = false;
845 
846   Context.getInjectedClassNameType(Result, CanonInjectedType);
847   return Result;
848 }
849 
850 ClassTemplatePartialSpecializationDecl *
851 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
852                                                            unsigned ID) {
853   ClassTemplatePartialSpecializationDecl *Result =
854       new (C, ID) ClassTemplatePartialSpecializationDecl(C);
855   Result->MayHaveOutOfDateDef = false;
856   return Result;
857 }
858 
859 //===----------------------------------------------------------------------===//
860 // FriendTemplateDecl Implementation
861 //===----------------------------------------------------------------------===//
862 
863 void FriendTemplateDecl::anchor() { }
864 
865 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
866                                                DeclContext *DC,
867                                                SourceLocation L,
868                                                unsigned NParams,
869                                                TemplateParameterList **Params,
870                                                FriendUnion Friend,
871                                                SourceLocation FLoc) {
872   return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params,
873                                               Friend, FLoc);
874 }
875 
876 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
877                                                            unsigned ID) {
878   return new (C, ID) FriendTemplateDecl(EmptyShell());
879 }
880 
881 //===----------------------------------------------------------------------===//
882 // TypeAliasTemplateDecl Implementation
883 //===----------------------------------------------------------------------===//
884 
885 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
886                                                      DeclContext *DC,
887                                                      SourceLocation L,
888                                                      DeclarationName Name,
889                                                   TemplateParameterList *Params,
890                                                      NamedDecl *Decl) {
891   AdoptTemplateParameterList(Params, DC);
892   return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
893 }
894 
895 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
896                                                                  unsigned ID) {
897   return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
898                                            DeclarationName(), nullptr, nullptr);
899 }
900 
901 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
902   static_cast<Common *>(Ptr)->~Common();
903 }
904 RedeclarableTemplateDecl::CommonBase *
905 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
906   Common *CommonPtr = new (C) Common;
907   C.AddDeallocation(DeallocateCommon, CommonPtr);
908   return CommonPtr;
909 }
910 
911 //===----------------------------------------------------------------------===//
912 // ClassScopeFunctionSpecializationDecl Implementation
913 //===----------------------------------------------------------------------===//
914 
915 void ClassScopeFunctionSpecializationDecl::anchor() { }
916 
917 ClassScopeFunctionSpecializationDecl *
918 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
919                                                          unsigned ID) {
920   return new (C, ID) ClassScopeFunctionSpecializationDecl(
921       nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
922 }
923 
924 //===----------------------------------------------------------------------===//
925 // VarTemplateDecl Implementation
926 //===----------------------------------------------------------------------===//
927 
928 void VarTemplateDecl::DeallocateCommon(void *Ptr) {
929   static_cast<Common *>(Ptr)->~Common();
930 }
931 
932 VarTemplateDecl *VarTemplateDecl::getDefinition() {
933   VarTemplateDecl *CurD = this;
934   while (CurD) {
935     if (CurD->isThisDeclarationADefinition())
936       return CurD;
937     CurD = CurD->getPreviousDecl();
938   }
939   return nullptr;
940 }
941 
942 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
943                                          SourceLocation L, DeclarationName Name,
944                                          TemplateParameterList *Params,
945                                          VarDecl *Decl) {
946   return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
947 }
948 
949 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
950                                                      unsigned ID) {
951   return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
952                                      DeclarationName(), nullptr, nullptr);
953 }
954 
955 // TODO: Unify across class, function and variable templates?
956 //       May require moving this and Common to RedeclarableTemplateDecl.
957 void VarTemplateDecl::LoadLazySpecializations() const {
958   Common *CommonPtr = getCommonPtr();
959   if (CommonPtr->LazySpecializations) {
960     ASTContext &Context = getASTContext();
961     uint32_t *Specs = CommonPtr->LazySpecializations;
962     CommonPtr->LazySpecializations = nullptr;
963     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
964       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
965   }
966 }
967 
968 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
969 VarTemplateDecl::getSpecializations() const {
970   LoadLazySpecializations();
971   return getCommonPtr()->Specializations;
972 }
973 
974 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
975 VarTemplateDecl::getPartialSpecializations() {
976   LoadLazySpecializations();
977   return getCommonPtr()->PartialSpecializations;
978 }
979 
980 RedeclarableTemplateDecl::CommonBase *
981 VarTemplateDecl::newCommon(ASTContext &C) const {
982   Common *CommonPtr = new (C) Common;
983   C.AddDeallocation(DeallocateCommon, CommonPtr);
984   return CommonPtr;
985 }
986 
987 VarTemplateSpecializationDecl *
988 VarTemplateDecl::findSpecialization(const TemplateArgument *Args,
989                                     unsigned NumArgs, void *&InsertPos) {
990   return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
991 }
992 
993 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
994                                         void *InsertPos) {
995   if (InsertPos)
996     getSpecializations().InsertNode(D, InsertPos);
997   else {
998     VarTemplateSpecializationDecl *Existing =
999         getSpecializations().GetOrInsertNode(D);
1000     (void)Existing;
1001     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1002   }
1003   if (ASTMutationListener *L = getASTMutationListener())
1004     L->AddedCXXTemplateSpecialization(this, D);
1005 }
1006 
1007 VarTemplatePartialSpecializationDecl *
1008 VarTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
1009                                            unsigned NumArgs, void *&InsertPos) {
1010   return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
1011                                 InsertPos);
1012 }
1013 
1014 void VarTemplateDecl::AddPartialSpecialization(
1015     VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1016   if (InsertPos)
1017     getPartialSpecializations().InsertNode(D, InsertPos);
1018   else {
1019     VarTemplatePartialSpecializationDecl *Existing =
1020         getPartialSpecializations().GetOrInsertNode(D);
1021     (void)Existing;
1022     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1023   }
1024 
1025   if (ASTMutationListener *L = getASTMutationListener())
1026     L->AddedCXXTemplateSpecialization(this, D);
1027 }
1028 
1029 void VarTemplateDecl::getPartialSpecializations(
1030     SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1031   llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1032       getPartialSpecializations();
1033   PS.clear();
1034   PS.reserve(PartialSpecs.size());
1035   for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1036            P = PartialSpecs.begin(),
1037            PEnd = PartialSpecs.end();
1038        P != PEnd; ++P)
1039     PS.push_back(P->getMostRecentDecl());
1040 }
1041 
1042 VarTemplatePartialSpecializationDecl *
1043 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1044     VarTemplatePartialSpecializationDecl *D) {
1045   Decl *DCanon = D->getCanonicalDecl();
1046   for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1047            P = getPartialSpecializations().begin(),
1048            PEnd = getPartialSpecializations().end();
1049        P != PEnd; ++P) {
1050     if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1051       return P->getMostRecentDecl();
1052   }
1053 
1054   return nullptr;
1055 }
1056 
1057 //===----------------------------------------------------------------------===//
1058 // VarTemplateSpecializationDecl Implementation
1059 //===----------------------------------------------------------------------===//
1060 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1061     Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1062     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1063     TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1064     unsigned NumArgs)
1065     : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1066               SpecializedTemplate->getIdentifier(), T, TInfo, S),
1067       SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
1068       TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
1069       SpecializationKind(TSK_Undeclared) {}
1070 
1071 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1072                                                              ASTContext &C)
1073     : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1074               QualType(), nullptr, SC_None),
1075       ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
1076 
1077 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1078     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1079     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1080     TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1081     unsigned NumArgs) {
1082   return new (Context, DC) VarTemplateSpecializationDecl(
1083       VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1084       SpecializedTemplate, T, TInfo, S, Args, NumArgs);
1085 }
1086 
1087 VarTemplateSpecializationDecl *
1088 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1089   return new (C, ID)
1090       VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1091 }
1092 
1093 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1094     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1095   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1096 
1097   const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1098   TemplateSpecializationType::PrintTemplateArgumentList(
1099       OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
1100 }
1101 
1102 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1103   if (SpecializedPartialSpecialization *PartialSpec =
1104           SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1105     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1106   return SpecializedTemplate.get<VarTemplateDecl *>();
1107 }
1108 
1109 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1110     const TemplateArgumentListInfo &ArgsInfo) {
1111   unsigned N = ArgsInfo.size();
1112   TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1113   TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1114   for (unsigned I = 0; I != N; ++I)
1115     TemplateArgsInfo.addArgument(ArgsInfo[I]);
1116 }
1117 
1118 //===----------------------------------------------------------------------===//
1119 // VarTemplatePartialSpecializationDecl Implementation
1120 //===----------------------------------------------------------------------===//
1121 void VarTemplatePartialSpecializationDecl::anchor() {}
1122 
1123 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1124     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1125     SourceLocation IdLoc, TemplateParameterList *Params,
1126     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1127     StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
1128     const ASTTemplateArgumentListInfo *ArgInfos)
1129     : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1130                                     DC, StartLoc, IdLoc, SpecializedTemplate, T,
1131                                     TInfo, S, Args, NumArgs),
1132       TemplateParams(Params), ArgsAsWritten(ArgInfos),
1133       InstantiatedFromMember(nullptr, false) {
1134   // TODO: The template parameters should be in DC by now. Verify.
1135   // AdoptTemplateParameterList(Params, DC);
1136 }
1137 
1138 VarTemplatePartialSpecializationDecl *
1139 VarTemplatePartialSpecializationDecl::Create(
1140     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1141     SourceLocation IdLoc, TemplateParameterList *Params,
1142     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1143     StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
1144     const TemplateArgumentListInfo &ArgInfos) {
1145   const ASTTemplateArgumentListInfo *ASTArgInfos
1146     = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1147 
1148   VarTemplatePartialSpecializationDecl *Result =
1149       new (Context, DC) VarTemplatePartialSpecializationDecl(
1150           Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1151           S, Args, NumArgs, ASTArgInfos);
1152   Result->setSpecializationKind(TSK_ExplicitSpecialization);
1153   return Result;
1154 }
1155 
1156 VarTemplatePartialSpecializationDecl *
1157 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1158                                                          unsigned ID) {
1159   return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1160 }
1161