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