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