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     // Walk the previous-declaration chain until we either find a declaration
134     // with a common pointer or we run out of previous declarations.
135     SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
136     for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
137          Prev = Prev->getPreviousDecl()) {
138       if (Prev->Common) {
139         Common = Prev->Common;
140         break;
141       }
142 
143       PrevDecls.push_back(Prev);
144     }
145 
146     // If we never found a common pointer, allocate one now.
147     if (!Common) {
148       // FIXME: If any of the declarations is from an AST file, we probably
149       // need an update record to add the common data.
150 
151       Common = newCommon(getASTContext());
152     }
153 
154     // Update any previous declarations we saw with the common pointer.
155     for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I)
156       PrevDecls[I]->Common = Common;
157   }
158 
159   return Common;
160 }
161 
162 template <class EntryType>
163 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
164 RedeclarableTemplateDecl::findSpecializationImpl(
165                                  llvm::FoldingSetVector<EntryType> &Specs,
166                                  const TemplateArgument *Args, unsigned NumArgs,
167                                  void *&InsertPos) {
168   typedef SpecEntryTraits<EntryType> SETraits;
169   llvm::FoldingSetNodeID ID;
170   EntryType::Profile(ID,Args,NumArgs, getASTContext());
171   EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
172   return Entry ? SETraits::getMostRecentDecl(Entry) : 0;
173 }
174 
175 /// \brief Generate the injected template arguments for the given template
176 /// parameter list, e.g., for the injected-class-name of a class template.
177 static void GenerateInjectedTemplateArgs(ASTContext &Context,
178                                         TemplateParameterList *Params,
179                                          TemplateArgument *Args) {
180   for (TemplateParameterList::iterator Param = Params->begin(),
181                                     ParamEnd = Params->end();
182        Param != ParamEnd; ++Param) {
183     TemplateArgument Arg;
184     if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
185       QualType ArgType = Context.getTypeDeclType(TTP);
186       if (TTP->isParameterPack())
187         ArgType = Context.getPackExpansionType(ArgType, None);
188 
189       Arg = TemplateArgument(ArgType);
190     } else if (NonTypeTemplateParmDecl *NTTP =
191                dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
192       Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
193                                   NTTP->getType().getNonLValueExprType(Context),
194                                   Expr::getValueKindForType(NTTP->getType()),
195                                           NTTP->getLocation());
196 
197       if (NTTP->isParameterPack())
198         E = new (Context) PackExpansionExpr(Context.DependentTy, E,
199                                             NTTP->getLocation(), None);
200       Arg = TemplateArgument(E);
201     } else {
202       TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
203       if (TTP->isParameterPack())
204         Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
205       else
206         Arg = TemplateArgument(TemplateName(TTP));
207     }
208 
209     if ((*Param)->isTemplateParameterPack())
210       Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
211 
212     *Args++ = Arg;
213   }
214 }
215 
216 //===----------------------------------------------------------------------===//
217 // FunctionTemplateDecl Implementation
218 //===----------------------------------------------------------------------===//
219 
220 void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
221   static_cast<Common *>(Ptr)->~Common();
222 }
223 
224 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
225                                                    DeclContext *DC,
226                                                    SourceLocation L,
227                                                    DeclarationName Name,
228                                                TemplateParameterList *Params,
229                                                    NamedDecl *Decl) {
230   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
231   return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
232 }
233 
234 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
235                                                                unsigned ID) {
236   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FunctionTemplateDecl));
237   return new (Mem) 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 = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
311   New->setPreviousDeclaration(PrevDecl);
312   return New;
313 }
314 
315 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
316                                                          unsigned ID) {
317   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ClassTemplateDecl));
318   return new (Mem) 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) 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   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTypeParmDecl));
482   return new (Mem) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(),
483                                         0, 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 TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
502 }
503 
504 unsigned TemplateTypeParmDecl::getIndex() const {
505   return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
506 }
507 
508 bool TemplateTypeParmDecl::isParameterPack() const {
509   return TypeForDecl->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(0, 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) 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 Size = sizeof(NonTypeTemplateParmDecl)
560                 + NumExpandedTypes * 2 * sizeof(void*);
561   void *Mem = C.Allocate(Size);
562   return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc,
563                                            D, P, Id, T, TInfo,
564                                            ExpandedTypes, NumExpandedTypes,
565                                            ExpandedTInfos);
566 }
567 
568 NonTypeTemplateParmDecl *
569 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
570   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NonTypeTemplateParmDecl));
571   return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
572                                            SourceLocation(), 0, 0, 0,
573                                            QualType(), false, 0);
574 }
575 
576 NonTypeTemplateParmDecl *
577 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
578                                             unsigned NumExpandedTypes) {
579   unsigned Size = sizeof(NonTypeTemplateParmDecl)
580                 + NumExpandedTypes * 2 * sizeof(void*);
581 
582   void *Mem = AllocateDeserializedDecl(C, ID, Size);
583   return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
584                                            SourceLocation(), 0, 0, 0,
585                                            QualType(), 0, 0, NumExpandedTypes,
586                                            0);
587 }
588 
589 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
590   if (hasDefaultArgument() && !defaultArgumentWasInherited())
591     return SourceRange(getOuterLocStart(),
592                        getDefaultArgument()->getSourceRange().getEnd());
593   return DeclaratorDecl::getSourceRange();
594 }
595 
596 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
597   return hasDefaultArgument()
598     ? getDefaultArgument()->getSourceRange().getBegin()
599     : SourceLocation();
600 }
601 
602 //===----------------------------------------------------------------------===//
603 // TemplateTemplateParmDecl Method Implementations
604 //===----------------------------------------------------------------------===//
605 
606 void TemplateTemplateParmDecl::anchor() { }
607 
608 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
609     DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
610     IdentifierInfo *Id, TemplateParameterList *Params,
611     unsigned NumExpansions, TemplateParameterList * const *Expansions)
612   : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
613     TemplateParmPosition(D, P), DefaultArgument(),
614     DefaultArgumentWasInherited(false), ParameterPack(true),
615     ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
616   if (Expansions)
617     std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
618                 sizeof(TemplateParameterList*) * NumExpandedParams);
619 }
620 
621 TemplateTemplateParmDecl *
622 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
623                                  SourceLocation L, unsigned D, unsigned P,
624                                  bool ParameterPack, IdentifierInfo *Id,
625                                  TemplateParameterList *Params) {
626   return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
627                                           Params);
628 }
629 
630 TemplateTemplateParmDecl *
631 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
632                                  SourceLocation L, unsigned D, unsigned P,
633                                  IdentifierInfo *Id,
634                                  TemplateParameterList *Params,
635                                  ArrayRef<TemplateParameterList *> Expansions) {
636   void *Mem = C.Allocate(sizeof(TemplateTemplateParmDecl) +
637                          sizeof(TemplateParameterList*) * Expansions.size());
638   return new (Mem) TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
639                                             Expansions.size(),
640                                             Expansions.data());
641 }
642 
643 TemplateTemplateParmDecl *
644 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
645   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTemplateParmDecl));
646   return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, false,
647                                             0, 0);
648 }
649 
650 TemplateTemplateParmDecl *
651 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
652                                              unsigned NumExpansions) {
653   unsigned Size = sizeof(TemplateTemplateParmDecl) +
654                   sizeof(TemplateParameterList*) * NumExpansions;
655   void *Mem = AllocateDeserializedDecl(C, ID, Size);
656   return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, 0, 0,
657                                             NumExpansions, 0);
658 }
659 
660 //===----------------------------------------------------------------------===//
661 // TemplateArgumentList Implementation
662 //===----------------------------------------------------------------------===//
663 TemplateArgumentList *
664 TemplateArgumentList::CreateCopy(ASTContext &Context,
665                                  const TemplateArgument *Args,
666                                  unsigned NumArgs) {
667   std::size_t Size = sizeof(TemplateArgumentList)
668                    + NumArgs * sizeof(TemplateArgument);
669   void *Mem = Context.Allocate(Size);
670   TemplateArgument *StoredArgs
671     = reinterpret_cast<TemplateArgument *>(
672                                 static_cast<TemplateArgumentList *>(Mem) + 1);
673   std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
674   return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
675 }
676 
677 FunctionTemplateSpecializationInfo *
678 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
679                                            FunctionTemplateDecl *Template,
680                                            TemplateSpecializationKind TSK,
681                                        const TemplateArgumentList *TemplateArgs,
682                           const TemplateArgumentListInfo *TemplateArgsAsWritten,
683                                            SourceLocation POI) {
684   const ASTTemplateArgumentListInfo *ArgsAsWritten = 0;
685   if (TemplateArgsAsWritten)
686     ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
687                                                         *TemplateArgsAsWritten);
688 
689   return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
690                                                     TemplateArgs,
691                                                     ArgsAsWritten,
692                                                     POI);
693 }
694 
695 //===----------------------------------------------------------------------===//
696 // TemplateDecl Implementation
697 //===----------------------------------------------------------------------===//
698 
699 void TemplateDecl::anchor() { }
700 
701 //===----------------------------------------------------------------------===//
702 // ClassTemplateSpecializationDecl Implementation
703 //===----------------------------------------------------------------------===//
704 ClassTemplateSpecializationDecl::
705 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
706                                 DeclContext *DC, SourceLocation StartLoc,
707                                 SourceLocation IdLoc,
708                                 ClassTemplateDecl *SpecializedTemplate,
709                                 const TemplateArgument *Args,
710                                 unsigned NumArgs,
711                                 ClassTemplateSpecializationDecl *PrevDecl)
712   : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc,
713                   SpecializedTemplate->getIdentifier(),
714                   PrevDecl),
715     SpecializedTemplate(SpecializedTemplate),
716     ExplicitInfo(0),
717     TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
718     SpecializationKind(TSK_Undeclared) {
719 }
720 
721 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
722   : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0),
723     ExplicitInfo(0),
724     SpecializationKind(TSK_Undeclared) {
725 }
726 
727 ClassTemplateSpecializationDecl *
728 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
729                                         DeclContext *DC,
730                                         SourceLocation StartLoc,
731                                         SourceLocation IdLoc,
732                                         ClassTemplateDecl *SpecializedTemplate,
733                                         const TemplateArgument *Args,
734                                         unsigned NumArgs,
735                                    ClassTemplateSpecializationDecl *PrevDecl) {
736   ClassTemplateSpecializationDecl *Result
737     = new (Context)ClassTemplateSpecializationDecl(Context,
738                                                    ClassTemplateSpecialization,
739                                                    TK, DC, StartLoc, IdLoc,
740                                                    SpecializedTemplate,
741                                                    Args, NumArgs,
742                                                    PrevDecl);
743   Result->MayHaveOutOfDateDef = false;
744 
745   Context.getTypeDeclType(Result, PrevDecl);
746   return Result;
747 }
748 
749 ClassTemplateSpecializationDecl *
750 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
751                                                     unsigned ID) {
752   void *Mem = AllocateDeserializedDecl(C, ID,
753                                        sizeof(ClassTemplateSpecializationDecl));
754   ClassTemplateSpecializationDecl *Result =
755     new (Mem) ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
756   Result->MayHaveOutOfDateDef = false;
757   return Result;
758 }
759 
760 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
761     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
762   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
763 
764   const TemplateArgumentList &TemplateArgs = getTemplateArgs();
765   TemplateSpecializationType::PrintTemplateArgumentList(
766       OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
767 }
768 
769 ClassTemplateDecl *
770 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
771   if (SpecializedPartialSpecialization *PartialSpec
772       = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
773     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
774   return SpecializedTemplate.get<ClassTemplateDecl*>();
775 }
776 
777 SourceRange
778 ClassTemplateSpecializationDecl::getSourceRange() const {
779   if (ExplicitInfo) {
780     SourceLocation Begin = getTemplateKeywordLoc();
781     if (Begin.isValid()) {
782       // Here we have an explicit (partial) specialization or instantiation.
783       assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
784              getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
785              getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
786       if (getExternLoc().isValid())
787         Begin = getExternLoc();
788       SourceLocation End = getRBraceLoc();
789       if (End.isInvalid())
790         End = getTypeAsWritten()->getTypeLoc().getEndLoc();
791       return SourceRange(Begin, End);
792     }
793     // An implicit instantiation of a class template partial specialization
794     // uses ExplicitInfo to record the TypeAsWritten, but the source
795     // locations should be retrieved from the instantiation pattern.
796     typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
797     CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
798     CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
799     assert(inst_from != 0);
800     return inst_from->getSourceRange();
801   }
802   else {
803     // No explicit info available.
804     llvm::PointerUnion<ClassTemplateDecl *,
805                        ClassTemplatePartialSpecializationDecl *>
806       inst_from = getInstantiatedFrom();
807     if (inst_from.isNull())
808       return getSpecializedTemplate()->getSourceRange();
809     if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
810       return ctd->getSourceRange();
811     return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
812       ->getSourceRange();
813   }
814 }
815 
816 //===----------------------------------------------------------------------===//
817 // ClassTemplatePartialSpecializationDecl Implementation
818 //===----------------------------------------------------------------------===//
819 void ClassTemplatePartialSpecializationDecl::anchor() { }
820 
821 ClassTemplatePartialSpecializationDecl::
822 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
823                                        DeclContext *DC,
824                                        SourceLocation StartLoc,
825                                        SourceLocation IdLoc,
826                                        TemplateParameterList *Params,
827                                        ClassTemplateDecl *SpecializedTemplate,
828                                        const TemplateArgument *Args,
829                                        unsigned NumArgs,
830                                const ASTTemplateArgumentListInfo *ArgInfos,
831                                ClassTemplatePartialSpecializationDecl *PrevDecl)
832   : ClassTemplateSpecializationDecl(Context,
833                                     ClassTemplatePartialSpecialization,
834                                     TK, DC, StartLoc, IdLoc,
835                                     SpecializedTemplate,
836                                     Args, NumArgs, PrevDecl),
837     TemplateParams(Params), ArgsAsWritten(ArgInfos),
838     InstantiatedFromMember(0, false)
839 {
840   AdoptTemplateParameterList(Params, this);
841 }
842 
843 ClassTemplatePartialSpecializationDecl *
844 ClassTemplatePartialSpecializationDecl::
845 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
846        SourceLocation StartLoc, SourceLocation IdLoc,
847        TemplateParameterList *Params,
848        ClassTemplateDecl *SpecializedTemplate,
849        const TemplateArgument *Args,
850        unsigned NumArgs,
851        const TemplateArgumentListInfo &ArgInfos,
852        QualType CanonInjectedType,
853        ClassTemplatePartialSpecializationDecl *PrevDecl) {
854   const ASTTemplateArgumentListInfo *ASTArgInfos =
855     ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
856 
857   ClassTemplatePartialSpecializationDecl *Result
858     = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC,
859                                                           StartLoc, IdLoc,
860                                                           Params,
861                                                           SpecializedTemplate,
862                                                           Args, NumArgs,
863                                                           ASTArgInfos,
864                                                           PrevDecl);
865   Result->setSpecializationKind(TSK_ExplicitSpecialization);
866   Result->MayHaveOutOfDateDef = false;
867 
868   Context.getInjectedClassNameType(Result, CanonInjectedType);
869   return Result;
870 }
871 
872 ClassTemplatePartialSpecializationDecl *
873 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
874                                                            unsigned ID) {
875   void *Mem = AllocateDeserializedDecl(C, ID,
876                 sizeof(ClassTemplatePartialSpecializationDecl));
877   ClassTemplatePartialSpecializationDecl *Result
878     = new (Mem) ClassTemplatePartialSpecializationDecl();
879   Result->MayHaveOutOfDateDef = false;
880   return Result;
881 }
882 
883 //===----------------------------------------------------------------------===//
884 // FriendTemplateDecl Implementation
885 //===----------------------------------------------------------------------===//
886 
887 void FriendTemplateDecl::anchor() { }
888 
889 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
890                                                DeclContext *DC,
891                                                SourceLocation L,
892                                                unsigned NParams,
893                                                TemplateParameterList **Params,
894                                                FriendUnion Friend,
895                                                SourceLocation FLoc) {
896   FriendTemplateDecl *Result
897     = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
898   return Result;
899 }
900 
901 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
902                                                            unsigned ID) {
903   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FriendTemplateDecl));
904   return new (Mem) FriendTemplateDecl(EmptyShell());
905 }
906 
907 //===----------------------------------------------------------------------===//
908 // TypeAliasTemplateDecl Implementation
909 //===----------------------------------------------------------------------===//
910 
911 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
912                                                      DeclContext *DC,
913                                                      SourceLocation L,
914                                                      DeclarationName Name,
915                                                   TemplateParameterList *Params,
916                                                      NamedDecl *Decl) {
917   AdoptTemplateParameterList(Params, DC);
918   return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl);
919 }
920 
921 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
922                                                                  unsigned ID) {
923   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasTemplateDecl));
924   return new (Mem) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(),
925                                          0, 0);
926 }
927 
928 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
929   static_cast<Common *>(Ptr)->~Common();
930 }
931 RedeclarableTemplateDecl::CommonBase *
932 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
933   Common *CommonPtr = new (C) Common;
934   C.AddDeallocation(DeallocateCommon, CommonPtr);
935   return CommonPtr;
936 }
937 
938 //===----------------------------------------------------------------------===//
939 // ClassScopeFunctionSpecializationDecl Implementation
940 //===----------------------------------------------------------------------===//
941 
942 void ClassScopeFunctionSpecializationDecl::anchor() { }
943 
944 ClassScopeFunctionSpecializationDecl *
945 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
946                                                          unsigned ID) {
947   void *Mem = AllocateDeserializedDecl(C, ID,
948                 sizeof(ClassScopeFunctionSpecializationDecl));
949   return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0,
950                                              false, TemplateArgumentListInfo());
951 }
952 
953 //===----------------------------------------------------------------------===//
954 // VarTemplateDecl Implementation
955 //===----------------------------------------------------------------------===//
956 
957 void VarTemplateDecl::DeallocateCommon(void *Ptr) {
958   static_cast<Common *>(Ptr)->~Common();
959 }
960 
961 VarTemplateDecl *VarTemplateDecl::getDefinition() {
962   VarTemplateDecl *CurD = this;
963   while (CurD) {
964     if (CurD->isThisDeclarationADefinition())
965       return CurD;
966     CurD = CurD->getPreviousDecl();
967   }
968   return 0;
969 }
970 
971 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
972                                          SourceLocation L, DeclarationName Name,
973                                          TemplateParameterList *Params,
974                                          NamedDecl *Decl,
975                                          VarTemplateDecl *PrevDecl) {
976   VarTemplateDecl *New = new (C) VarTemplateDecl(DC, L, Name, Params, Decl);
977   New->setPreviousDeclaration(PrevDecl);
978   return New;
979 }
980 
981 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
982                                                      unsigned ID) {
983   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(VarTemplateDecl));
984   return new (Mem) VarTemplateDecl(EmptyShell());
985 }
986 
987 // TODO: Unify accross class, function and variable templates?
988 //       May require moving this and Common to RedeclarableTemplateDecl.
989 void VarTemplateDecl::LoadLazySpecializations() const {
990   Common *CommonPtr = getCommonPtr();
991   if (CommonPtr->LazySpecializations) {
992     ASTContext &Context = getASTContext();
993     uint32_t *Specs = CommonPtr->LazySpecializations;
994     CommonPtr->LazySpecializations = 0;
995     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
996       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
997   }
998 }
999 
1000 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1001 VarTemplateDecl::getSpecializations() const {
1002   LoadLazySpecializations();
1003   return getCommonPtr()->Specializations;
1004 }
1005 
1006 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1007 VarTemplateDecl::getPartialSpecializations() {
1008   LoadLazySpecializations();
1009   return getCommonPtr()->PartialSpecializations;
1010 }
1011 
1012 RedeclarableTemplateDecl::CommonBase *
1013 VarTemplateDecl::newCommon(ASTContext &C) const {
1014   Common *CommonPtr = new (C) Common;
1015   C.AddDeallocation(DeallocateCommon, CommonPtr);
1016   return CommonPtr;
1017 }
1018 
1019 VarTemplateSpecializationDecl *
1020 VarTemplateDecl::findSpecialization(const TemplateArgument *Args,
1021                                     unsigned NumArgs, void *&InsertPos) {
1022   return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
1023 }
1024 
1025 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1026                                         void *InsertPos) {
1027   if (InsertPos)
1028     getSpecializations().InsertNode(D, InsertPos);
1029   else {
1030     VarTemplateSpecializationDecl *Existing =
1031         getSpecializations().GetOrInsertNode(D);
1032     (void)Existing;
1033     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1034   }
1035   if (ASTMutationListener *L = getASTMutationListener())
1036     L->AddedCXXTemplateSpecialization(this, D);
1037 }
1038 
1039 VarTemplatePartialSpecializationDecl *
1040 VarTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
1041                                            unsigned NumArgs, void *&InsertPos) {
1042   return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
1043                                 InsertPos);
1044 }
1045 
1046 void VarTemplateDecl::AddPartialSpecialization(
1047     VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1048   if (InsertPos)
1049     getPartialSpecializations().InsertNode(D, InsertPos);
1050   else {
1051     VarTemplatePartialSpecializationDecl *Existing =
1052         getPartialSpecializations().GetOrInsertNode(D);
1053     (void)Existing;
1054     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1055   }
1056 
1057   if (ASTMutationListener *L = getASTMutationListener())
1058     L->AddedCXXTemplateSpecialization(this, D);
1059 }
1060 
1061 void VarTemplateDecl::getPartialSpecializations(
1062     SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1063   llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1064       getPartialSpecializations();
1065   PS.clear();
1066   PS.reserve(PartialSpecs.size());
1067   for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1068            P = PartialSpecs.begin(),
1069            PEnd = PartialSpecs.end();
1070        P != PEnd; ++P)
1071     PS.push_back(P->getMostRecentDecl());
1072 }
1073 
1074 VarTemplatePartialSpecializationDecl *
1075 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1076     VarTemplatePartialSpecializationDecl *D) {
1077   Decl *DCanon = D->getCanonicalDecl();
1078   for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1079            P = getPartialSpecializations().begin(),
1080            PEnd = getPartialSpecializations().end();
1081        P != PEnd; ++P) {
1082     if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1083       return P->getMostRecentDecl();
1084   }
1085 
1086   return 0;
1087 }
1088 
1089 //===----------------------------------------------------------------------===//
1090 // VarTemplateSpecializationDecl Implementation
1091 //===----------------------------------------------------------------------===//
1092 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1093     ASTContext &Context, Kind DK, DeclContext *DC, SourceLocation StartLoc,
1094     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1095     TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1096     unsigned NumArgs)
1097     : VarDecl(DK, DC, StartLoc, IdLoc, SpecializedTemplate->getIdentifier(), T,
1098               TInfo, S),
1099       SpecializedTemplate(SpecializedTemplate), ExplicitInfo(0),
1100       TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
1101       SpecializationKind(TSK_Undeclared) {}
1102 
1103 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK)
1104     : VarDecl(DK, 0, SourceLocation(), SourceLocation(), 0, QualType(), 0,
1105               SC_None),
1106       ExplicitInfo(0), SpecializationKind(TSK_Undeclared) {}
1107 
1108 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1109     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1110     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1111     TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1112     unsigned NumArgs) {
1113   VarTemplateSpecializationDecl *Result = new (Context)
1114       VarTemplateSpecializationDecl(Context, VarTemplateSpecialization, DC,
1115                                     StartLoc, IdLoc, SpecializedTemplate, T,
1116                                     TInfo, S, Args, NumArgs);
1117   return Result;
1118 }
1119 
1120 VarTemplateSpecializationDecl *
1121 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1122   void *Mem =
1123       AllocateDeserializedDecl(C, ID, sizeof(VarTemplateSpecializationDecl));
1124   VarTemplateSpecializationDecl *Result =
1125       new (Mem) VarTemplateSpecializationDecl(VarTemplateSpecialization);
1126   return Result;
1127 }
1128 
1129 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1130     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1131   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1132 
1133   const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1134   TemplateSpecializationType::PrintTemplateArgumentList(
1135       OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
1136 }
1137 
1138 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1139   if (SpecializedPartialSpecialization *PartialSpec =
1140           SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1141     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1142   return SpecializedTemplate.get<VarTemplateDecl *>();
1143 }
1144 
1145 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1146     const TemplateArgumentListInfo &ArgsInfo) {
1147   unsigned N = ArgsInfo.size();
1148   TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1149   TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1150   for (unsigned I = 0; I != N; ++I)
1151     TemplateArgsInfo.addArgument(ArgsInfo[I]);
1152 }
1153 
1154 //===----------------------------------------------------------------------===//
1155 // VarTemplatePartialSpecializationDecl Implementation
1156 //===----------------------------------------------------------------------===//
1157 void VarTemplatePartialSpecializationDecl::anchor() {}
1158 
1159 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1160     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1161     SourceLocation IdLoc, TemplateParameterList *Params,
1162     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1163     StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
1164     const ASTTemplateArgumentListInfo *ArgInfos)
1165     : VarTemplateSpecializationDecl(Context, VarTemplatePartialSpecialization,
1166                                     DC, StartLoc, IdLoc, SpecializedTemplate, T,
1167                                     TInfo, S, Args, NumArgs),
1168       TemplateParams(Params), ArgsAsWritten(ArgInfos),
1169       InstantiatedFromMember(0, false) {
1170   // TODO: The template parameters should be in DC by now. Verify.
1171   // AdoptTemplateParameterList(Params, DC);
1172 }
1173 
1174 VarTemplatePartialSpecializationDecl *
1175 VarTemplatePartialSpecializationDecl::Create(
1176     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1177     SourceLocation IdLoc, TemplateParameterList *Params,
1178     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1179     StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
1180     const TemplateArgumentListInfo &ArgInfos) {
1181   const ASTTemplateArgumentListInfo *ASTArgInfos
1182     = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1183 
1184   VarTemplatePartialSpecializationDecl *Result =
1185       new (Context) VarTemplatePartialSpecializationDecl(
1186           Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1187           S, Args, NumArgs, ASTArgInfos);
1188   Result->setSpecializationKind(TSK_ExplicitSpecialization);
1189   return Result;
1190 }
1191 
1192 VarTemplatePartialSpecializationDecl *
1193 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1194                                                          unsigned ID) {
1195   void *Mem = AllocateDeserializedDecl(
1196       C, ID, sizeof(VarTemplatePartialSpecializationDecl));
1197   VarTemplatePartialSpecializationDecl *Result =
1198       new (Mem) VarTemplatePartialSpecializationDecl();
1199   return Result;
1200 }
1201