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