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) : 0;
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(DC, L, Name, Params, Decl);
233 }
234 
235 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
236                                                                unsigned ID) {
237   return new (C, ID) FunctionTemplateDecl(0, SourceLocation(), DeclarationName(),
238                                           0, 0);
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 = 0;
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 =
311       new (C, DC) ClassTemplateDecl(DC, L, Name, 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(EmptyShell());
319 }
320 
321 void ClassTemplateDecl::LoadLazySpecializations() const {
322   Common *CommonPtr = getCommonPtr();
323   if (CommonPtr->LazySpecializations) {
324     ASTContext &Context = getASTContext();
325     uint32_t *Specs = CommonPtr->LazySpecializations;
326     CommonPtr->LazySpecializations = 0;
327     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
328       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
329   }
330 }
331 
332 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
333 ClassTemplateDecl::getSpecializations() const {
334   LoadLazySpecializations();
335   return getCommonPtr()->Specializations;
336 }
337 
338 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
339 ClassTemplateDecl::getPartialSpecializations() {
340   LoadLazySpecializations();
341   return getCommonPtr()->PartialSpecializations;
342 }
343 
344 RedeclarableTemplateDecl::CommonBase *
345 ClassTemplateDecl::newCommon(ASTContext &C) const {
346   Common *CommonPtr = new (C) Common;
347   C.AddDeallocation(DeallocateCommon, CommonPtr);
348   return CommonPtr;
349 }
350 
351 ClassTemplateSpecializationDecl *
352 ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
353                                       unsigned NumArgs, void *&InsertPos) {
354   return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
355 }
356 
357 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
358                                           void *InsertPos) {
359   if (InsertPos)
360     getSpecializations().InsertNode(D, InsertPos);
361   else {
362     ClassTemplateSpecializationDecl *Existing
363       = getSpecializations().GetOrInsertNode(D);
364     (void)Existing;
365     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
366   }
367   if (ASTMutationListener *L = getASTMutationListener())
368     L->AddedCXXTemplateSpecialization(this, D);
369 }
370 
371 ClassTemplatePartialSpecializationDecl *
372 ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
373                                              unsigned NumArgs,
374                                              void *&InsertPos) {
375   return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
376                                 InsertPos);
377 }
378 
379 void ClassTemplateDecl::AddPartialSpecialization(
380                                       ClassTemplatePartialSpecializationDecl *D,
381                                       void *InsertPos) {
382   if (InsertPos)
383     getPartialSpecializations().InsertNode(D, InsertPos);
384   else {
385     ClassTemplatePartialSpecializationDecl *Existing
386       = getPartialSpecializations().GetOrInsertNode(D);
387     (void)Existing;
388     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
389   }
390 
391   if (ASTMutationListener *L = getASTMutationListener())
392     L->AddedCXXTemplateSpecialization(this, D);
393 }
394 
395 void ClassTemplateDecl::getPartialSpecializations(
396           SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
397   llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
398     = getPartialSpecializations();
399   PS.clear();
400   PS.reserve(PartialSpecs.size());
401   for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
402        P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
403        P != PEnd; ++P)
404     PS.push_back(P->getMostRecentDecl());
405 }
406 
407 ClassTemplatePartialSpecializationDecl *
408 ClassTemplateDecl::findPartialSpecialization(QualType T) {
409   ASTContext &Context = getASTContext();
410   using llvm::FoldingSetVector;
411   typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
412     partial_spec_iterator;
413   for (partial_spec_iterator P = getPartialSpecializations().begin(),
414                           PEnd = getPartialSpecializations().end();
415        P != PEnd; ++P) {
416     if (Context.hasSameType(P->getInjectedSpecializationType(), T))
417       return P->getMostRecentDecl();
418   }
419 
420   return 0;
421 }
422 
423 ClassTemplatePartialSpecializationDecl *
424 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
425                                     ClassTemplatePartialSpecializationDecl *D) {
426   Decl *DCanon = D->getCanonicalDecl();
427   for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
428             P = getPartialSpecializations().begin(),
429          PEnd = getPartialSpecializations().end();
430        P != PEnd; ++P) {
431     if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
432       return P->getMostRecentDecl();
433   }
434 
435   return 0;
436 }
437 
438 QualType
439 ClassTemplateDecl::getInjectedClassNameSpecialization() {
440   Common *CommonPtr = getCommonPtr();
441   if (!CommonPtr->InjectedClassNameType.isNull())
442     return CommonPtr->InjectedClassNameType;
443 
444   // C++0x [temp.dep.type]p2:
445   //  The template argument list of a primary template is a template argument
446   //  list in which the nth template argument has the value of the nth template
447   //  parameter of the class template. If the nth template parameter is a
448   //  template parameter pack (14.5.3), the nth template argument is a pack
449   //  expansion (14.5.3) whose pattern is the name of the template parameter
450   //  pack.
451   ASTContext &Context = getASTContext();
452   TemplateParameterList *Params = getTemplateParameters();
453   SmallVector<TemplateArgument, 16> TemplateArgs;
454   TemplateArgs.resize(Params->size());
455   GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
456   CommonPtr->InjectedClassNameType
457     = Context.getTemplateSpecializationType(TemplateName(this),
458                                             &TemplateArgs[0],
459                                             TemplateArgs.size());
460   return CommonPtr->InjectedClassNameType;
461 }
462 
463 //===----------------------------------------------------------------------===//
464 // TemplateTypeParm Allocation/Deallocation Method Implementations
465 //===----------------------------------------------------------------------===//
466 
467 TemplateTypeParmDecl *
468 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
469                              SourceLocation KeyLoc, SourceLocation NameLoc,
470                              unsigned D, unsigned P, IdentifierInfo *Id,
471                              bool Typename, bool ParameterPack) {
472   TemplateTypeParmDecl *TTPDecl =
473     new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
474   QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
475   TTPDecl->TypeForDecl = TTPType.getTypePtr();
476   return TTPDecl;
477 }
478 
479 TemplateTypeParmDecl *
480 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
481   return new (C, ID) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(),
482                                           0, false);
483 }
484 
485 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
486   return hasDefaultArgument()
487     ? DefaultArgument->getTypeLoc().getBeginLoc()
488     : SourceLocation();
489 }
490 
491 SourceRange TemplateTypeParmDecl::getSourceRange() const {
492   if (hasDefaultArgument() && !defaultArgumentWasInherited())
493     return SourceRange(getLocStart(),
494                        DefaultArgument->getTypeLoc().getEndLoc());
495   else
496     return TypeDecl::getSourceRange();
497 }
498 
499 unsigned TemplateTypeParmDecl::getDepth() const {
500   return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
501 }
502 
503 unsigned TemplateTypeParmDecl::getIndex() const {
504   return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
505 }
506 
507 bool TemplateTypeParmDecl::isParameterPack() const {
508   return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack();
509 }
510 
511 //===----------------------------------------------------------------------===//
512 // NonTypeTemplateParmDecl Method Implementations
513 //===----------------------------------------------------------------------===//
514 
515 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
516                                                  SourceLocation StartLoc,
517                                                  SourceLocation IdLoc,
518                                                  unsigned D, unsigned P,
519                                                  IdentifierInfo *Id,
520                                                  QualType T,
521                                                  TypeSourceInfo *TInfo,
522                                                  const QualType *ExpandedTypes,
523                                                  unsigned NumExpandedTypes,
524                                                 TypeSourceInfo **ExpandedTInfos)
525   : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
526     TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
527     ParameterPack(true), ExpandedParameterPack(true),
528     NumExpandedTypes(NumExpandedTypes)
529 {
530   if (ExpandedTypes && ExpandedTInfos) {
531     void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
532     for (unsigned I = 0; I != NumExpandedTypes; ++I) {
533       TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
534       TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
535     }
536   }
537 }
538 
539 NonTypeTemplateParmDecl *
540 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
541                                 SourceLocation StartLoc, SourceLocation IdLoc,
542                                 unsigned D, unsigned P, IdentifierInfo *Id,
543                                 QualType T, bool ParameterPack,
544                                 TypeSourceInfo *TInfo) {
545   return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
546                                              T, ParameterPack, TInfo);
547 }
548 
549 NonTypeTemplateParmDecl *
550 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
551                                 SourceLocation StartLoc, SourceLocation IdLoc,
552                                 unsigned D, unsigned P,
553                                 IdentifierInfo *Id, QualType T,
554                                 TypeSourceInfo *TInfo,
555                                 const QualType *ExpandedTypes,
556                                 unsigned NumExpandedTypes,
557                                 TypeSourceInfo **ExpandedTInfos) {
558   unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
559   return new (C, DC, Extra) NonTypeTemplateParmDecl(
560       DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
561       ExpandedTypes, NumExpandedTypes, ExpandedTInfos);
562 }
563 
564 NonTypeTemplateParmDecl *
565 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
566   return new (C, ID) NonTypeTemplateParmDecl(0, SourceLocation(),
567                                              SourceLocation(), 0, 0, 0,
568                                              QualType(), false, 0);
569 }
570 
571 NonTypeTemplateParmDecl *
572 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
573                                             unsigned NumExpandedTypes) {
574   unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
575   return new (C, ID, Extra) NonTypeTemplateParmDecl(
576       0, SourceLocation(), SourceLocation(), 0, 0, 0, QualType(), 0,
577       0, NumExpandedTypes, 0);
578 }
579 
580 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
581   if (hasDefaultArgument() && !defaultArgumentWasInherited())
582     return SourceRange(getOuterLocStart(),
583                        getDefaultArgument()->getSourceRange().getEnd());
584   return DeclaratorDecl::getSourceRange();
585 }
586 
587 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
588   return hasDefaultArgument()
589     ? getDefaultArgument()->getSourceRange().getBegin()
590     : SourceLocation();
591 }
592 
593 //===----------------------------------------------------------------------===//
594 // TemplateTemplateParmDecl Method Implementations
595 //===----------------------------------------------------------------------===//
596 
597 void TemplateTemplateParmDecl::anchor() { }
598 
599 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
600     DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
601     IdentifierInfo *Id, TemplateParameterList *Params,
602     unsigned NumExpansions, TemplateParameterList * const *Expansions)
603   : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
604     TemplateParmPosition(D, P), DefaultArgument(),
605     DefaultArgumentWasInherited(false), ParameterPack(true),
606     ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
607   if (Expansions)
608     std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
609                 sizeof(TemplateParameterList*) * NumExpandedParams);
610 }
611 
612 TemplateTemplateParmDecl *
613 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
614                                  SourceLocation L, unsigned D, unsigned P,
615                                  bool ParameterPack, IdentifierInfo *Id,
616                                  TemplateParameterList *Params) {
617   return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
618                                               Params);
619 }
620 
621 TemplateTemplateParmDecl *
622 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
623                                  SourceLocation L, unsigned D, unsigned P,
624                                  IdentifierInfo *Id,
625                                  TemplateParameterList *Params,
626                                  ArrayRef<TemplateParameterList *> Expansions) {
627   return new (C, DC, sizeof(TemplateParameterList*) * Expansions.size())
628       TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
629                                Expansions.size(), Expansions.data());
630 }
631 
632 TemplateTemplateParmDecl *
633 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
634   return new (C, ID) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, false,
635                                               0, 0);
636 }
637 
638 TemplateTemplateParmDecl *
639 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
640                                              unsigned NumExpansions) {
641   return new (C, ID, sizeof(TemplateParameterList*) * NumExpansions)
642       TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, 0, 0,
643                                NumExpansions, 0);
644 }
645 
646 //===----------------------------------------------------------------------===//
647 // TemplateArgumentList Implementation
648 //===----------------------------------------------------------------------===//
649 TemplateArgumentList *
650 TemplateArgumentList::CreateCopy(ASTContext &Context,
651                                  const TemplateArgument *Args,
652                                  unsigned NumArgs) {
653   std::size_t Size = sizeof(TemplateArgumentList)
654                    + NumArgs * sizeof(TemplateArgument);
655   void *Mem = Context.Allocate(Size);
656   TemplateArgument *StoredArgs
657     = reinterpret_cast<TemplateArgument *>(
658                                 static_cast<TemplateArgumentList *>(Mem) + 1);
659   std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
660   return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
661 }
662 
663 FunctionTemplateSpecializationInfo *
664 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
665                                            FunctionTemplateDecl *Template,
666                                            TemplateSpecializationKind TSK,
667                                        const TemplateArgumentList *TemplateArgs,
668                           const TemplateArgumentListInfo *TemplateArgsAsWritten,
669                                            SourceLocation POI) {
670   const ASTTemplateArgumentListInfo *ArgsAsWritten = 0;
671   if (TemplateArgsAsWritten)
672     ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
673                                                         *TemplateArgsAsWritten);
674 
675   return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
676                                                     TemplateArgs,
677                                                     ArgsAsWritten,
678                                                     POI);
679 }
680 
681 //===----------------------------------------------------------------------===//
682 // TemplateDecl Implementation
683 //===----------------------------------------------------------------------===//
684 
685 void TemplateDecl::anchor() { }
686 
687 //===----------------------------------------------------------------------===//
688 // ClassTemplateSpecializationDecl Implementation
689 //===----------------------------------------------------------------------===//
690 ClassTemplateSpecializationDecl::
691 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
692                                 DeclContext *DC, SourceLocation StartLoc,
693                                 SourceLocation IdLoc,
694                                 ClassTemplateDecl *SpecializedTemplate,
695                                 const TemplateArgument *Args,
696                                 unsigned NumArgs,
697                                 ClassTemplateSpecializationDecl *PrevDecl)
698   : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc,
699                   SpecializedTemplate->getIdentifier(),
700                   PrevDecl),
701     SpecializedTemplate(SpecializedTemplate),
702     ExplicitInfo(0),
703     TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
704     SpecializationKind(TSK_Undeclared) {
705 }
706 
707 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
708   : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0),
709     ExplicitInfo(0),
710     SpecializationKind(TSK_Undeclared) {
711 }
712 
713 ClassTemplateSpecializationDecl *
714 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
715                                         DeclContext *DC,
716                                         SourceLocation StartLoc,
717                                         SourceLocation IdLoc,
718                                         ClassTemplateDecl *SpecializedTemplate,
719                                         const TemplateArgument *Args,
720                                         unsigned NumArgs,
721                                    ClassTemplateSpecializationDecl *PrevDecl) {
722   ClassTemplateSpecializationDecl *Result =
723       new (Context, DC) ClassTemplateSpecializationDecl(
724           Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
725           SpecializedTemplate, Args, NumArgs, PrevDecl);
726   Result->MayHaveOutOfDateDef = false;
727 
728   Context.getTypeDeclType(Result, PrevDecl);
729   return Result;
730 }
731 
732 ClassTemplateSpecializationDecl *
733 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
734                                                     unsigned ID) {
735   ClassTemplateSpecializationDecl *Result =
736     new (C, ID) ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
737   Result->MayHaveOutOfDateDef = false;
738   return Result;
739 }
740 
741 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
742     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
743   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
744 
745   const TemplateArgumentList &TemplateArgs = getTemplateArgs();
746   TemplateSpecializationType::PrintTemplateArgumentList(
747       OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
748 }
749 
750 ClassTemplateDecl *
751 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
752   if (SpecializedPartialSpecialization *PartialSpec
753       = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
754     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
755   return SpecializedTemplate.get<ClassTemplateDecl*>();
756 }
757 
758 SourceRange
759 ClassTemplateSpecializationDecl::getSourceRange() const {
760   if (ExplicitInfo) {
761     SourceLocation Begin = getTemplateKeywordLoc();
762     if (Begin.isValid()) {
763       // Here we have an explicit (partial) specialization or instantiation.
764       assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
765              getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
766              getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
767       if (getExternLoc().isValid())
768         Begin = getExternLoc();
769       SourceLocation End = getRBraceLoc();
770       if (End.isInvalid())
771         End = getTypeAsWritten()->getTypeLoc().getEndLoc();
772       return SourceRange(Begin, End);
773     }
774     // An implicit instantiation of a class template partial specialization
775     // uses ExplicitInfo to record the TypeAsWritten, but the source
776     // locations should be retrieved from the instantiation pattern.
777     typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
778     CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
779     CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
780     assert(inst_from != 0);
781     return inst_from->getSourceRange();
782   }
783   else {
784     // No explicit info available.
785     llvm::PointerUnion<ClassTemplateDecl *,
786                        ClassTemplatePartialSpecializationDecl *>
787       inst_from = getInstantiatedFrom();
788     if (inst_from.isNull())
789       return getSpecializedTemplate()->getSourceRange();
790     if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
791       return ctd->getSourceRange();
792     return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
793       ->getSourceRange();
794   }
795 }
796 
797 //===----------------------------------------------------------------------===//
798 // ClassTemplatePartialSpecializationDecl Implementation
799 //===----------------------------------------------------------------------===//
800 void ClassTemplatePartialSpecializationDecl::anchor() { }
801 
802 ClassTemplatePartialSpecializationDecl::
803 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
804                                        DeclContext *DC,
805                                        SourceLocation StartLoc,
806                                        SourceLocation IdLoc,
807                                        TemplateParameterList *Params,
808                                        ClassTemplateDecl *SpecializedTemplate,
809                                        const TemplateArgument *Args,
810                                        unsigned NumArgs,
811                                const ASTTemplateArgumentListInfo *ArgInfos,
812                                ClassTemplatePartialSpecializationDecl *PrevDecl)
813   : ClassTemplateSpecializationDecl(Context,
814                                     ClassTemplatePartialSpecialization,
815                                     TK, DC, StartLoc, IdLoc,
816                                     SpecializedTemplate,
817                                     Args, NumArgs, PrevDecl),
818     TemplateParams(Params), ArgsAsWritten(ArgInfos),
819     InstantiatedFromMember(0, false)
820 {
821   AdoptTemplateParameterList(Params, this);
822 }
823 
824 ClassTemplatePartialSpecializationDecl *
825 ClassTemplatePartialSpecializationDecl::
826 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
827        SourceLocation StartLoc, SourceLocation IdLoc,
828        TemplateParameterList *Params,
829        ClassTemplateDecl *SpecializedTemplate,
830        const TemplateArgument *Args,
831        unsigned NumArgs,
832        const TemplateArgumentListInfo &ArgInfos,
833        QualType CanonInjectedType,
834        ClassTemplatePartialSpecializationDecl *PrevDecl) {
835   const ASTTemplateArgumentListInfo *ASTArgInfos =
836     ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
837 
838   ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
839       ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
840                                              Params, SpecializedTemplate, Args,
841                                              NumArgs, ASTArgInfos, PrevDecl);
842   Result->setSpecializationKind(TSK_ExplicitSpecialization);
843   Result->MayHaveOutOfDateDef = false;
844 
845   Context.getInjectedClassNameType(Result, CanonInjectedType);
846   return Result;
847 }
848 
849 ClassTemplatePartialSpecializationDecl *
850 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
851                                                            unsigned ID) {
852   ClassTemplatePartialSpecializationDecl *Result =
853       new (C, ID) ClassTemplatePartialSpecializationDecl();
854   Result->MayHaveOutOfDateDef = false;
855   return Result;
856 }
857 
858 //===----------------------------------------------------------------------===//
859 // FriendTemplateDecl Implementation
860 //===----------------------------------------------------------------------===//
861 
862 void FriendTemplateDecl::anchor() { }
863 
864 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
865                                                DeclContext *DC,
866                                                SourceLocation L,
867                                                unsigned NParams,
868                                                TemplateParameterList **Params,
869                                                FriendUnion Friend,
870                                                SourceLocation FLoc) {
871   return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params,
872                                               Friend, FLoc);
873 }
874 
875 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
876                                                            unsigned ID) {
877   return new (C, ID) FriendTemplateDecl(EmptyShell());
878 }
879 
880 //===----------------------------------------------------------------------===//
881 // TypeAliasTemplateDecl Implementation
882 //===----------------------------------------------------------------------===//
883 
884 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
885                                                      DeclContext *DC,
886                                                      SourceLocation L,
887                                                      DeclarationName Name,
888                                                   TemplateParameterList *Params,
889                                                      NamedDecl *Decl) {
890   AdoptTemplateParameterList(Params, DC);
891   return new (C, DC) TypeAliasTemplateDecl(DC, L, Name, Params, Decl);
892 }
893 
894 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
895                                                                  unsigned ID) {
896   return new (C, ID) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(),
897                                            0, 0);
898 }
899 
900 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
901   static_cast<Common *>(Ptr)->~Common();
902 }
903 RedeclarableTemplateDecl::CommonBase *
904 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
905   Common *CommonPtr = new (C) Common;
906   C.AddDeallocation(DeallocateCommon, CommonPtr);
907   return CommonPtr;
908 }
909 
910 //===----------------------------------------------------------------------===//
911 // ClassScopeFunctionSpecializationDecl Implementation
912 //===----------------------------------------------------------------------===//
913 
914 void ClassScopeFunctionSpecializationDecl::anchor() { }
915 
916 ClassScopeFunctionSpecializationDecl *
917 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
918                                                          unsigned ID) {
919   return new (C, ID) ClassScopeFunctionSpecializationDecl(
920       0, SourceLocation(), 0, false, TemplateArgumentListInfo());
921 }
922 
923 //===----------------------------------------------------------------------===//
924 // VarTemplateDecl Implementation
925 //===----------------------------------------------------------------------===//
926 
927 void VarTemplateDecl::DeallocateCommon(void *Ptr) {
928   static_cast<Common *>(Ptr)->~Common();
929 }
930 
931 VarTemplateDecl *VarTemplateDecl::getDefinition() {
932   VarTemplateDecl *CurD = this;
933   while (CurD) {
934     if (CurD->isThisDeclarationADefinition())
935       return CurD;
936     CurD = CurD->getPreviousDecl();
937   }
938   return 0;
939 }
940 
941 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
942                                          SourceLocation L, DeclarationName Name,
943                                          TemplateParameterList *Params,
944                                          VarDecl *Decl) {
945   return new (C, DC) VarTemplateDecl(DC, L, Name, Params, Decl);
946 }
947 
948 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
949                                                      unsigned ID) {
950   return new (C, ID) VarTemplateDecl(EmptyShell());
951 }
952 
953 // TODO: Unify across class, function and variable templates?
954 //       May require moving this and Common to RedeclarableTemplateDecl.
955 void VarTemplateDecl::LoadLazySpecializations() const {
956   Common *CommonPtr = getCommonPtr();
957   if (CommonPtr->LazySpecializations) {
958     ASTContext &Context = getASTContext();
959     uint32_t *Specs = CommonPtr->LazySpecializations;
960     CommonPtr->LazySpecializations = 0;
961     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
962       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
963   }
964 }
965 
966 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
967 VarTemplateDecl::getSpecializations() const {
968   LoadLazySpecializations();
969   return getCommonPtr()->Specializations;
970 }
971 
972 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
973 VarTemplateDecl::getPartialSpecializations() {
974   LoadLazySpecializations();
975   return getCommonPtr()->PartialSpecializations;
976 }
977 
978 RedeclarableTemplateDecl::CommonBase *
979 VarTemplateDecl::newCommon(ASTContext &C) const {
980   Common *CommonPtr = new (C) Common;
981   C.AddDeallocation(DeallocateCommon, CommonPtr);
982   return CommonPtr;
983 }
984 
985 VarTemplateSpecializationDecl *
986 VarTemplateDecl::findSpecialization(const TemplateArgument *Args,
987                                     unsigned NumArgs, void *&InsertPos) {
988   return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
989 }
990 
991 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
992                                         void *InsertPos) {
993   if (InsertPos)
994     getSpecializations().InsertNode(D, InsertPos);
995   else {
996     VarTemplateSpecializationDecl *Existing =
997         getSpecializations().GetOrInsertNode(D);
998     (void)Existing;
999     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1000   }
1001   if (ASTMutationListener *L = getASTMutationListener())
1002     L->AddedCXXTemplateSpecialization(this, D);
1003 }
1004 
1005 VarTemplatePartialSpecializationDecl *
1006 VarTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
1007                                            unsigned NumArgs, void *&InsertPos) {
1008   return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
1009                                 InsertPos);
1010 }
1011 
1012 void VarTemplateDecl::AddPartialSpecialization(
1013     VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1014   if (InsertPos)
1015     getPartialSpecializations().InsertNode(D, InsertPos);
1016   else {
1017     VarTemplatePartialSpecializationDecl *Existing =
1018         getPartialSpecializations().GetOrInsertNode(D);
1019     (void)Existing;
1020     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1021   }
1022 
1023   if (ASTMutationListener *L = getASTMutationListener())
1024     L->AddedCXXTemplateSpecialization(this, D);
1025 }
1026 
1027 void VarTemplateDecl::getPartialSpecializations(
1028     SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1029   llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1030       getPartialSpecializations();
1031   PS.clear();
1032   PS.reserve(PartialSpecs.size());
1033   for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1034            P = PartialSpecs.begin(),
1035            PEnd = PartialSpecs.end();
1036        P != PEnd; ++P)
1037     PS.push_back(P->getMostRecentDecl());
1038 }
1039 
1040 VarTemplatePartialSpecializationDecl *
1041 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1042     VarTemplatePartialSpecializationDecl *D) {
1043   Decl *DCanon = D->getCanonicalDecl();
1044   for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1045            P = getPartialSpecializations().begin(),
1046            PEnd = getPartialSpecializations().end();
1047        P != PEnd; ++P) {
1048     if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1049       return P->getMostRecentDecl();
1050   }
1051 
1052   return 0;
1053 }
1054 
1055 //===----------------------------------------------------------------------===//
1056 // VarTemplateSpecializationDecl Implementation
1057 //===----------------------------------------------------------------------===//
1058 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1059     ASTContext &Context, Kind DK, DeclContext *DC, SourceLocation StartLoc,
1060     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1061     TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1062     unsigned NumArgs)
1063     : VarDecl(DK, DC, StartLoc, IdLoc, SpecializedTemplate->getIdentifier(), T,
1064               TInfo, S),
1065       SpecializedTemplate(SpecializedTemplate), ExplicitInfo(0),
1066       TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
1067       SpecializationKind(TSK_Undeclared) {}
1068 
1069 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK)
1070     : VarDecl(DK, 0, SourceLocation(), SourceLocation(), 0, QualType(), 0,
1071               SC_None),
1072       ExplicitInfo(0), SpecializationKind(TSK_Undeclared) {}
1073 
1074 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1075     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1076     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1077     TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1078     unsigned NumArgs) {
1079   return new (Context, DC) VarTemplateSpecializationDecl(
1080       Context, VarTemplateSpecialization, DC, StartLoc, IdLoc,
1081       SpecializedTemplate, T, TInfo, S, Args, NumArgs);
1082 }
1083 
1084 VarTemplateSpecializationDecl *
1085 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1086   return new (C, ID) VarTemplateSpecializationDecl(VarTemplateSpecialization);
1087 }
1088 
1089 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1090     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1091   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1092 
1093   const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1094   TemplateSpecializationType::PrintTemplateArgumentList(
1095       OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
1096 }
1097 
1098 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1099   if (SpecializedPartialSpecialization *PartialSpec =
1100           SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1101     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1102   return SpecializedTemplate.get<VarTemplateDecl *>();
1103 }
1104 
1105 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1106     const TemplateArgumentListInfo &ArgsInfo) {
1107   unsigned N = ArgsInfo.size();
1108   TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1109   TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1110   for (unsigned I = 0; I != N; ++I)
1111     TemplateArgsInfo.addArgument(ArgsInfo[I]);
1112 }
1113 
1114 //===----------------------------------------------------------------------===//
1115 // VarTemplatePartialSpecializationDecl Implementation
1116 //===----------------------------------------------------------------------===//
1117 void VarTemplatePartialSpecializationDecl::anchor() {}
1118 
1119 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1120     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1121     SourceLocation IdLoc, TemplateParameterList *Params,
1122     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1123     StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
1124     const ASTTemplateArgumentListInfo *ArgInfos)
1125     : VarTemplateSpecializationDecl(Context, VarTemplatePartialSpecialization,
1126                                     DC, StartLoc, IdLoc, SpecializedTemplate, T,
1127                                     TInfo, S, Args, NumArgs),
1128       TemplateParams(Params), ArgsAsWritten(ArgInfos),
1129       InstantiatedFromMember(0, false) {
1130   // TODO: The template parameters should be in DC by now. Verify.
1131   // AdoptTemplateParameterList(Params, DC);
1132 }
1133 
1134 VarTemplatePartialSpecializationDecl *
1135 VarTemplatePartialSpecializationDecl::Create(
1136     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1137     SourceLocation IdLoc, TemplateParameterList *Params,
1138     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1139     StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
1140     const TemplateArgumentListInfo &ArgInfos) {
1141   const ASTTemplateArgumentListInfo *ASTArgInfos
1142     = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1143 
1144   VarTemplatePartialSpecializationDecl *Result =
1145       new (Context, DC) VarTemplatePartialSpecializationDecl(
1146           Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1147           S, Args, NumArgs, ASTArgInfos);
1148   Result->setSpecializationKind(TSK_ExplicitSpecialization);
1149   return Result;
1150 }
1151 
1152 VarTemplatePartialSpecializationDecl *
1153 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1154                                                          unsigned ID) {
1155   return new (C, ID) VarTemplatePartialSpecializationDecl();
1156 }
1157