DeclTemplate.cpp revision 263508
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>
24using namespace clang;
25
26//===----------------------------------------------------------------------===//
27// TemplateParameterList Implementation
28//===----------------------------------------------------------------------===//
29
30TemplateParameterList::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
56TemplateParameterList *
57TemplateParameterList::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
69unsigned 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
100unsigned 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
115static 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
131RedeclarableTemplateDecl::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
163template <class EntryType>
164typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
165RedeclarableTemplateDecl::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.
178static 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
221void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
222  static_cast<Common *>(Ptr)->~Common();
223}
224
225FunctionTemplateDecl *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
235FunctionTemplateDecl *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
242RedeclarableTemplateDecl::CommonBase *
243FunctionTemplateDecl::newCommon(ASTContext &C) const {
244  Common *CommonPtr = new (C) Common;
245  C.AddDeallocation(DeallocateCommon, CommonPtr);
246  return CommonPtr;
247}
248
249void 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
260llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
261FunctionTemplateDecl::getSpecializations() const {
262  LoadLazySpecializations();
263  return getCommonPtr()->Specializations;
264}
265
266FunctionDecl *
267FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
268                                         unsigned NumArgs, void *&InsertPos) {
269  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
270}
271
272void 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
282ArrayRef<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
299void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
300  static_cast<Common *>(Ptr)->~Common();
301}
302
303ClassTemplateDecl *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
316ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
317                                                         unsigned ID) {
318  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ClassTemplateDecl));
319  return new (Mem) ClassTemplateDecl(EmptyShell());
320}
321
322void 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
333llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
334ClassTemplateDecl::getSpecializations() const {
335  LoadLazySpecializations();
336  return getCommonPtr()->Specializations;
337}
338
339llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
340ClassTemplateDecl::getPartialSpecializations() {
341  LoadLazySpecializations();
342  return getCommonPtr()->PartialSpecializations;
343}
344
345RedeclarableTemplateDecl::CommonBase *
346ClassTemplateDecl::newCommon(ASTContext &C) const {
347  Common *CommonPtr = new (C) Common;
348  C.AddDeallocation(DeallocateCommon, CommonPtr);
349  return CommonPtr;
350}
351
352ClassTemplateSpecializationDecl *
353ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
354                                      unsigned NumArgs, void *&InsertPos) {
355  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
356}
357
358void 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
372ClassTemplatePartialSpecializationDecl *
373ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
374                                             unsigned NumArgs,
375                                             void *&InsertPos) {
376  return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
377                                InsertPos);
378}
379
380void 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
396void 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
408ClassTemplatePartialSpecializationDecl *
409ClassTemplateDecl::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
424ClassTemplatePartialSpecializationDecl *
425ClassTemplateDecl::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
439QualType
440ClassTemplateDecl::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
468TemplateTypeParmDecl *
469TemplateTypeParmDecl::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
480TemplateTypeParmDecl *
481TemplateTypeParmDecl::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
487SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
488  return hasDefaultArgument()
489    ? DefaultArgument->getTypeLoc().getBeginLoc()
490    : SourceLocation();
491}
492
493SourceRange TemplateTypeParmDecl::getSourceRange() const {
494  if (hasDefaultArgument() && !defaultArgumentWasInherited())
495    return SourceRange(getLocStart(),
496                       DefaultArgument->getTypeLoc().getEndLoc());
497  else
498    return TypeDecl::getSourceRange();
499}
500
501unsigned TemplateTypeParmDecl::getDepth() const {
502  return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
503}
504
505unsigned TemplateTypeParmDecl::getIndex() const {
506  return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
507}
508
509bool TemplateTypeParmDecl::isParameterPack() const {
510  return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack();
511}
512
513//===----------------------------------------------------------------------===//
514// NonTypeTemplateParmDecl Method Implementations
515//===----------------------------------------------------------------------===//
516
517NonTypeTemplateParmDecl::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
541NonTypeTemplateParmDecl *
542NonTypeTemplateParmDecl::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
551NonTypeTemplateParmDecl *
552NonTypeTemplateParmDecl::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
569NonTypeTemplateParmDecl *
570NonTypeTemplateParmDecl::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
577NonTypeTemplateParmDecl *
578NonTypeTemplateParmDecl::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
590SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
591  if (hasDefaultArgument() && !defaultArgumentWasInherited())
592    return SourceRange(getOuterLocStart(),
593                       getDefaultArgument()->getSourceRange().getEnd());
594  return DeclaratorDecl::getSourceRange();
595}
596
597SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
598  return hasDefaultArgument()
599    ? getDefaultArgument()->getSourceRange().getBegin()
600    : SourceLocation();
601}
602
603//===----------------------------------------------------------------------===//
604// TemplateTemplateParmDecl Method Implementations
605//===----------------------------------------------------------------------===//
606
607void TemplateTemplateParmDecl::anchor() { }
608
609TemplateTemplateParmDecl::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
622TemplateTemplateParmDecl *
623TemplateTemplateParmDecl::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
631TemplateTemplateParmDecl *
632TemplateTemplateParmDecl::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
644TemplateTemplateParmDecl *
645TemplateTemplateParmDecl::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
651TemplateTemplateParmDecl *
652TemplateTemplateParmDecl::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//===----------------------------------------------------------------------===//
664TemplateArgumentList *
665TemplateArgumentList::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
678FunctionTemplateSpecializationInfo *
679FunctionTemplateSpecializationInfo::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
700void TemplateDecl::anchor() { }
701
702//===----------------------------------------------------------------------===//
703// ClassTemplateSpecializationDecl Implementation
704//===----------------------------------------------------------------------===//
705ClassTemplateSpecializationDecl::
706ClassTemplateSpecializationDecl(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
722ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
723  : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0),
724    ExplicitInfo(0),
725    SpecializationKind(TSK_Undeclared) {
726}
727
728ClassTemplateSpecializationDecl *
729ClassTemplateSpecializationDecl::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
750ClassTemplateSpecializationDecl *
751ClassTemplateSpecializationDecl::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
761void 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
770ClassTemplateDecl *
771ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
772  if (SpecializedPartialSpecialization *PartialSpec
773      = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
774    return PartialSpec->PartialSpecialization->getSpecializedTemplate();
775  return SpecializedTemplate.get<ClassTemplateDecl*>();
776}
777
778SourceRange
779ClassTemplateSpecializationDecl::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//===----------------------------------------------------------------------===//
820void ClassTemplatePartialSpecializationDecl::anchor() { }
821
822ClassTemplatePartialSpecializationDecl::
823ClassTemplatePartialSpecializationDecl(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
844ClassTemplatePartialSpecializationDecl *
845ClassTemplatePartialSpecializationDecl::
846Create(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
873ClassTemplatePartialSpecializationDecl *
874ClassTemplatePartialSpecializationDecl::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
888void FriendTemplateDecl::anchor() { }
889
890FriendTemplateDecl *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
902FriendTemplateDecl *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
912TypeAliasTemplateDecl *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
922TypeAliasTemplateDecl *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
929void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
930  static_cast<Common *>(Ptr)->~Common();
931}
932RedeclarableTemplateDecl::CommonBase *
933TypeAliasTemplateDecl::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
943void ClassScopeFunctionSpecializationDecl::anchor() { }
944
945ClassScopeFunctionSpecializationDecl *
946ClassScopeFunctionSpecializationDecl::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
958void VarTemplateDecl::DeallocateCommon(void *Ptr) {
959  static_cast<Common *>(Ptr)->~Common();
960}
961
962VarTemplateDecl *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
972VarTemplateDecl *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
982VarTemplateDecl *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.
990void 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
1001llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1002VarTemplateDecl::getSpecializations() const {
1003  LoadLazySpecializations();
1004  return getCommonPtr()->Specializations;
1005}
1006
1007llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1008VarTemplateDecl::getPartialSpecializations() {
1009  LoadLazySpecializations();
1010  return getCommonPtr()->PartialSpecializations;
1011}
1012
1013RedeclarableTemplateDecl::CommonBase *
1014VarTemplateDecl::newCommon(ASTContext &C) const {
1015  Common *CommonPtr = new (C) Common;
1016  C.AddDeallocation(DeallocateCommon, CommonPtr);
1017  return CommonPtr;
1018}
1019
1020VarTemplateSpecializationDecl *
1021VarTemplateDecl::findSpecialization(const TemplateArgument *Args,
1022                                    unsigned NumArgs, void *&InsertPos) {
1023  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
1024}
1025
1026void 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
1040VarTemplatePartialSpecializationDecl *
1041VarTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
1042                                           unsigned NumArgs, void *&InsertPos) {
1043  return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
1044                                InsertPos);
1045}
1046
1047void 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
1062void 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
1075VarTemplatePartialSpecializationDecl *
1076VarTemplateDecl::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//===----------------------------------------------------------------------===//
1093VarTemplateSpecializationDecl::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
1104VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK)
1105    : VarDecl(DK, 0, SourceLocation(), SourceLocation(), 0, QualType(), 0,
1106              SC_None),
1107      ExplicitInfo(0), SpecializationKind(TSK_Undeclared) {}
1108
1109VarTemplateSpecializationDecl *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
1121VarTemplateSpecializationDecl *
1122VarTemplateSpecializationDecl::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
1130void 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
1139VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1140  if (SpecializedPartialSpecialization *PartialSpec =
1141          SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1142    return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1143  return SpecializedTemplate.get<VarTemplateDecl *>();
1144}
1145
1146void 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//===----------------------------------------------------------------------===//
1158void VarTemplatePartialSpecializationDecl::anchor() {}
1159
1160VarTemplatePartialSpecializationDecl::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
1175VarTemplatePartialSpecializationDecl *
1176VarTemplatePartialSpecializationDecl::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
1193VarTemplatePartialSpecializationDecl *
1194VarTemplatePartialSpecializationDecl::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}
1202