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/Builtins.h"
22#include "clang/Basic/IdentifierTable.h"
23#include "llvm/ADT/STLExtras.h"
24#include <memory>
25using namespace clang;
26
27//===----------------------------------------------------------------------===//
28// TemplateParameterList Implementation
29//===----------------------------------------------------------------------===//
30
31TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
32                                             SourceLocation LAngleLoc,
33                                             ArrayRef<NamedDecl *> Params,
34                                             SourceLocation RAngleLoc)
35  : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
36    NumParams(Params.size()), ContainsUnexpandedParameterPack(false) {
37  assert(this->NumParams == NumParams && "Too many template parameters");
38  for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
39    NamedDecl *P = Params[Idx];
40    begin()[Idx] = P;
41
42    if (!P->isTemplateParameterPack()) {
43      if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
44        if (NTTP->getType()->containsUnexpandedParameterPack())
45          ContainsUnexpandedParameterPack = true;
46
47      if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
48        if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
49          ContainsUnexpandedParameterPack = true;
50
51      // FIXME: If a default argument contains an unexpanded parameter pack, the
52      // template parameter list does too.
53    }
54  }
55}
56
57TemplateParameterList *TemplateParameterList::Create(
58    const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc,
59    ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc) {
60  void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *>(Params.size()),
61                         llvm::alignOf<TemplateParameterList>());
62  return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
63                                         RAngleLoc);
64}
65
66unsigned TemplateParameterList::getMinRequiredArguments() const {
67  unsigned NumRequiredArgs = 0;
68  for (const NamedDecl *P : asArray()) {
69    if (P->isTemplateParameterPack()) {
70      if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
71        if (NTTP->isExpandedParameterPack()) {
72          NumRequiredArgs += NTTP->getNumExpansionTypes();
73          continue;
74        }
75
76      break;
77    }
78
79    if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
80      if (TTP->hasDefaultArgument())
81        break;
82    } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
83      if (NTTP->hasDefaultArgument())
84        break;
85    } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
86      break;
87
88    ++NumRequiredArgs;
89  }
90
91  return NumRequiredArgs;
92}
93
94unsigned TemplateParameterList::getDepth() const {
95  if (size() == 0)
96    return 0;
97
98  const NamedDecl *FirstParm = getParam(0);
99  if (const TemplateTypeParmDecl *TTP
100        = dyn_cast<TemplateTypeParmDecl>(FirstParm))
101    return TTP->getDepth();
102  else if (const NonTypeTemplateParmDecl *NTTP
103             = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
104    return NTTP->getDepth();
105  else
106    return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
107}
108
109static void AdoptTemplateParameterList(TemplateParameterList *Params,
110                                       DeclContext *Owner) {
111  for (NamedDecl *P : *Params) {
112    P->setDeclContext(Owner);
113
114    if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
115      AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
116  }
117}
118
119namespace clang {
120void *allocateDefaultArgStorageChain(const ASTContext &C) {
121  return new (C) char[sizeof(void*) * 2];
122}
123}
124
125//===----------------------------------------------------------------------===//
126// RedeclarableTemplateDecl Implementation
127//===----------------------------------------------------------------------===//
128
129RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
130  if (Common)
131    return Common;
132
133  // Walk the previous-declaration chain until we either find a declaration
134  // with a common pointer or we run out of previous declarations.
135  SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
136  for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
137       Prev = Prev->getPreviousDecl()) {
138    if (Prev->Common) {
139      Common = Prev->Common;
140      break;
141    }
142
143    PrevDecls.push_back(Prev);
144  }
145
146  // If we never found a common pointer, allocate one now.
147  if (!Common) {
148    // FIXME: If any of the declarations is from an AST file, we probably
149    // need an update record to add the common data.
150
151    Common = newCommon(getASTContext());
152  }
153
154  // Update any previous declarations we saw with the common pointer.
155  for (const RedeclarableTemplateDecl *Prev : PrevDecls)
156    Prev->Common = Common;
157
158  return Common;
159}
160
161template<class EntryType>
162typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
163RedeclarableTemplateDecl::findSpecializationImpl(
164    llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
165    void *&InsertPos) {
166  typedef SpecEntryTraits<EntryType> SETraits;
167  llvm::FoldingSetNodeID ID;
168  EntryType::Profile(ID,Args, getASTContext());
169  EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
170  return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
171}
172
173template<class Derived, class EntryType>
174void RedeclarableTemplateDecl::addSpecializationImpl(
175    llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
176    void *InsertPos) {
177  typedef SpecEntryTraits<EntryType> SETraits;
178  if (InsertPos) {
179#ifndef NDEBUG
180    void *CorrectInsertPos;
181    assert(!findSpecializationImpl(Specializations,
182                                   SETraits::getTemplateArgs(Entry),
183                                   CorrectInsertPos) &&
184           InsertPos == CorrectInsertPos &&
185           "given incorrect InsertPos for specialization");
186#endif
187    Specializations.InsertNode(Entry, InsertPos);
188  } else {
189    EntryType *Existing = Specializations.GetOrInsertNode(Entry);
190    (void)Existing;
191    assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
192           "non-canonical specialization?");
193  }
194
195  if (ASTMutationListener *L = getASTMutationListener())
196    L->AddedCXXTemplateSpecialization(cast<Derived>(this),
197                                      SETraits::getDecl(Entry));
198}
199
200/// \brief Generate the injected template arguments for the given template
201/// parameter list, e.g., for the injected-class-name of a class template.
202static void GenerateInjectedTemplateArgs(ASTContext &Context,
203                                         TemplateParameterList *Params,
204                                         TemplateArgument *Args) {
205  for (NamedDecl *Param : *Params) {
206    TemplateArgument Arg;
207    if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
208      QualType ArgType = Context.getTypeDeclType(TTP);
209      if (TTP->isParameterPack())
210        ArgType = Context.getPackExpansionType(ArgType, None);
211
212      Arg = TemplateArgument(ArgType);
213    } else if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
214      Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
215                                  NTTP->getType().getNonLValueExprType(Context),
216                                  Expr::getValueKindForType(NTTP->getType()),
217                                          NTTP->getLocation());
218
219      if (NTTP->isParameterPack())
220        E = new (Context) PackExpansionExpr(Context.DependentTy, E,
221                                            NTTP->getLocation(), None);
222      Arg = TemplateArgument(E);
223    } else {
224      auto *TTP = cast<TemplateTemplateParmDecl>(Param);
225      if (TTP->isParameterPack())
226        Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
227      else
228        Arg = TemplateArgument(TemplateName(TTP));
229    }
230
231    if (Param->isTemplateParameterPack())
232      Arg = TemplateArgument::CreatePackCopy(Context, Arg);
233
234    *Args++ = Arg;
235  }
236}
237
238//===----------------------------------------------------------------------===//
239// FunctionTemplateDecl Implementation
240//===----------------------------------------------------------------------===//
241
242void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
243  static_cast<Common *>(Ptr)->~Common();
244}
245
246FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
247                                                   DeclContext *DC,
248                                                   SourceLocation L,
249                                                   DeclarationName Name,
250                                               TemplateParameterList *Params,
251                                                   NamedDecl *Decl) {
252  AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
253  return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
254}
255
256FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
257                                                               unsigned ID) {
258  return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
259                                          DeclarationName(), nullptr, nullptr);
260}
261
262RedeclarableTemplateDecl::CommonBase *
263FunctionTemplateDecl::newCommon(ASTContext &C) const {
264  Common *CommonPtr = new (C) Common;
265  C.AddDeallocation(DeallocateCommon, CommonPtr);
266  return CommonPtr;
267}
268
269void FunctionTemplateDecl::LoadLazySpecializations() const {
270  // Grab the most recent declaration to ensure we've loaded any lazy
271  // redeclarations of this template.
272  //
273  // FIXME: Avoid walking the entire redeclaration chain here.
274  Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
275  if (CommonPtr->LazySpecializations) {
276    ASTContext &Context = getASTContext();
277    uint32_t *Specs = CommonPtr->LazySpecializations;
278    CommonPtr->LazySpecializations = nullptr;
279    for (uint32_t I = 0, N = *Specs++; I != N; ++I)
280      (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
281  }
282}
283
284llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
285FunctionTemplateDecl::getSpecializations() const {
286  LoadLazySpecializations();
287  return getCommonPtr()->Specializations;
288}
289
290FunctionDecl *
291FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
292                                         void *&InsertPos) {
293  return findSpecializationImpl(getSpecializations(), Args, InsertPos);
294}
295
296void FunctionTemplateDecl::addSpecialization(
297      FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
298  addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
299                                              InsertPos);
300}
301
302ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
303  TemplateParameterList *Params = getTemplateParameters();
304  Common *CommonPtr = getCommonPtr();
305  if (!CommonPtr->InjectedArgs) {
306    CommonPtr->InjectedArgs
307      = new (getASTContext()) TemplateArgument[Params->size()];
308    GenerateInjectedTemplateArgs(getASTContext(), Params,
309                                 CommonPtr->InjectedArgs);
310  }
311
312  return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
313}
314
315//===----------------------------------------------------------------------===//
316// ClassTemplateDecl Implementation
317//===----------------------------------------------------------------------===//
318
319void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
320  static_cast<Common *>(Ptr)->~Common();
321}
322
323ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
324                                             DeclContext *DC,
325                                             SourceLocation L,
326                                             DeclarationName Name,
327                                             TemplateParameterList *Params,
328                                             NamedDecl *Decl,
329                                             ClassTemplateDecl *PrevDecl) {
330  AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
331  ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
332                                                         Params, Decl);
333  New->setPreviousDecl(PrevDecl);
334  return New;
335}
336
337ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
338                                                         unsigned ID) {
339  return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
340                                       DeclarationName(), nullptr, nullptr);
341}
342
343void ClassTemplateDecl::LoadLazySpecializations() const {
344  // Grab the most recent declaration to ensure we've loaded any lazy
345  // redeclarations of this template.
346  //
347  // FIXME: Avoid walking the entire redeclaration chain here.
348  Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
349  if (CommonPtr->LazySpecializations) {
350    ASTContext &Context = getASTContext();
351    uint32_t *Specs = CommonPtr->LazySpecializations;
352    CommonPtr->LazySpecializations = nullptr;
353    for (uint32_t I = 0, N = *Specs++; I != N; ++I)
354      (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
355  }
356}
357
358llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
359ClassTemplateDecl::getSpecializations() const {
360  LoadLazySpecializations();
361  return getCommonPtr()->Specializations;
362}
363
364llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
365ClassTemplateDecl::getPartialSpecializations() {
366  LoadLazySpecializations();
367  return getCommonPtr()->PartialSpecializations;
368}
369
370RedeclarableTemplateDecl::CommonBase *
371ClassTemplateDecl::newCommon(ASTContext &C) const {
372  Common *CommonPtr = new (C) Common;
373  C.AddDeallocation(DeallocateCommon, CommonPtr);
374  return CommonPtr;
375}
376
377ClassTemplateSpecializationDecl *
378ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
379                                      void *&InsertPos) {
380  return findSpecializationImpl(getSpecializations(), Args, InsertPos);
381}
382
383void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
384                                          void *InsertPos) {
385  addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
386}
387
388ClassTemplatePartialSpecializationDecl *
389ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
390                                             void *&InsertPos) {
391  return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
392}
393
394void ClassTemplateDecl::AddPartialSpecialization(
395                                      ClassTemplatePartialSpecializationDecl *D,
396                                      void *InsertPos) {
397  if (InsertPos)
398    getPartialSpecializations().InsertNode(D, InsertPos);
399  else {
400    ClassTemplatePartialSpecializationDecl *Existing
401      = getPartialSpecializations().GetOrInsertNode(D);
402    (void)Existing;
403    assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
404  }
405
406  if (ASTMutationListener *L = getASTMutationListener())
407    L->AddedCXXTemplateSpecialization(this, D);
408}
409
410void ClassTemplateDecl::getPartialSpecializations(
411          SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
412  llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
413    = getPartialSpecializations();
414  PS.clear();
415  PS.reserve(PartialSpecs.size());
416  for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
417    PS.push_back(P.getMostRecentDecl());
418}
419
420ClassTemplatePartialSpecializationDecl *
421ClassTemplateDecl::findPartialSpecialization(QualType T) {
422  ASTContext &Context = getASTContext();
423  for (ClassTemplatePartialSpecializationDecl &P :
424       getPartialSpecializations()) {
425    if (Context.hasSameType(P.getInjectedSpecializationType(), T))
426      return P.getMostRecentDecl();
427  }
428
429  return nullptr;
430}
431
432ClassTemplatePartialSpecializationDecl *
433ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
434                                    ClassTemplatePartialSpecializationDecl *D) {
435  Decl *DCanon = D->getCanonicalDecl();
436  for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
437    if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
438      return P.getMostRecentDecl();
439  }
440
441  return nullptr;
442}
443
444QualType
445ClassTemplateDecl::getInjectedClassNameSpecialization() {
446  Common *CommonPtr = getCommonPtr();
447  if (!CommonPtr->InjectedClassNameType.isNull())
448    return CommonPtr->InjectedClassNameType;
449
450  // C++0x [temp.dep.type]p2:
451  //  The template argument list of a primary template is a template argument
452  //  list in which the nth template argument has the value of the nth template
453  //  parameter of the class template. If the nth template parameter is a
454  //  template parameter pack (14.5.3), the nth template argument is a pack
455  //  expansion (14.5.3) whose pattern is the name of the template parameter
456  //  pack.
457  ASTContext &Context = getASTContext();
458  TemplateParameterList *Params = getTemplateParameters();
459  SmallVector<TemplateArgument, 16> TemplateArgs;
460  TemplateArgs.resize(Params->size());
461  GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
462  CommonPtr->InjectedClassNameType
463    = Context.getTemplateSpecializationType(TemplateName(this),
464                                            TemplateArgs);
465  return CommonPtr->InjectedClassNameType;
466}
467
468//===----------------------------------------------------------------------===//
469// TemplateTypeParm Allocation/Deallocation Method Implementations
470//===----------------------------------------------------------------------===//
471
472TemplateTypeParmDecl *
473TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
474                             SourceLocation KeyLoc, SourceLocation NameLoc,
475                             unsigned D, unsigned P, IdentifierInfo *Id,
476                             bool Typename, bool ParameterPack) {
477  TemplateTypeParmDecl *TTPDecl =
478    new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
479  QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
480  TTPDecl->setTypeForDecl(TTPType.getTypePtr());
481  return TTPDecl;
482}
483
484TemplateTypeParmDecl *
485TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
486  return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
487                                          SourceLocation(), nullptr, false);
488}
489
490SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
491  return hasDefaultArgument()
492             ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
493             : SourceLocation();
494}
495
496SourceRange TemplateTypeParmDecl::getSourceRange() const {
497  if (hasDefaultArgument() && !defaultArgumentWasInherited())
498    return SourceRange(getLocStart(),
499                       getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
500  else
501    return TypeDecl::getSourceRange();
502}
503
504unsigned TemplateTypeParmDecl::getDepth() const {
505  return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
506}
507
508unsigned TemplateTypeParmDecl::getIndex() const {
509  return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
510}
511
512bool TemplateTypeParmDecl::isParameterPack() const {
513  return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
514}
515
516//===----------------------------------------------------------------------===//
517// NonTypeTemplateParmDecl Method Implementations
518//===----------------------------------------------------------------------===//
519
520NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
521    DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
522    unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
523    ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
524    : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
525      TemplateParmPosition(D, P), ParameterPack(true),
526      ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
527  if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
528    auto TypesAndInfos =
529        getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
530    for (unsigned I = 0; I != NumExpandedTypes; ++I) {
531      new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
532      TypesAndInfos[I].second = ExpandedTInfos[I];
533    }
534  }
535}
536
537NonTypeTemplateParmDecl *
538NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
539                                SourceLocation StartLoc, SourceLocation IdLoc,
540                                unsigned D, unsigned P, IdentifierInfo *Id,
541                                QualType T, bool ParameterPack,
542                                TypeSourceInfo *TInfo) {
543  return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
544                                             T, ParameterPack, TInfo);
545}
546
547NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
548    const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
549    SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
550    QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
551    ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
552  return new (C, DC,
553              additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
554                  ExpandedTypes.size()))
555      NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
556                              ExpandedTypes, ExpandedTInfos);
557}
558
559NonTypeTemplateParmDecl *
560NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
561  return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
562                                             SourceLocation(), 0, 0, nullptr,
563                                             QualType(), false, nullptr);
564}
565
566NonTypeTemplateParmDecl *
567NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
568                                            unsigned NumExpandedTypes) {
569  auto *NTTP =
570      new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
571                      NumExpandedTypes))
572          NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
573                                  0, 0, nullptr, QualType(), nullptr, None,
574                                  None);
575  NTTP->NumExpandedTypes = NumExpandedTypes;
576  return NTTP;
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    ArrayRef<TemplateParameterList *> Expansions)
602    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
603      TemplateParmPosition(D, P), ParameterPack(true),
604      ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
605  if (!Expansions.empty())
606    std::uninitialized_copy(Expansions.begin(), Expansions.end(),
607                            getTrailingObjects<TemplateParameterList *>());
608}
609
610TemplateTemplateParmDecl *
611TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
612                                 SourceLocation L, unsigned D, unsigned P,
613                                 bool ParameterPack, IdentifierInfo *Id,
614                                 TemplateParameterList *Params) {
615  return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
616                                              Params);
617}
618
619TemplateTemplateParmDecl *
620TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
621                                 SourceLocation L, unsigned D, unsigned P,
622                                 IdentifierInfo *Id,
623                                 TemplateParameterList *Params,
624                                 ArrayRef<TemplateParameterList *> Expansions) {
625  return new (C, DC,
626              additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
627      TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
628}
629
630TemplateTemplateParmDecl *
631TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
632  return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
633                                              false, nullptr, nullptr);
634}
635
636TemplateTemplateParmDecl *
637TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
638                                             unsigned NumExpansions) {
639  auto *TTP =
640      new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
641          TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
642                                   nullptr, None);
643  TTP->NumExpandedParams = NumExpansions;
644  return TTP;
645}
646
647SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
648  return hasDefaultArgument() ? getDefaultArgument().getLocation()
649                              : SourceLocation();
650}
651
652void TemplateTemplateParmDecl::setDefaultArgument(
653    const ASTContext &C, const TemplateArgumentLoc &DefArg) {
654  if (DefArg.getArgument().isNull())
655    DefaultArgument.set(nullptr);
656  else
657    DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
658}
659
660//===----------------------------------------------------------------------===//
661// TemplateArgumentList Implementation
662//===----------------------------------------------------------------------===//
663TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
664    : Arguments(getTrailingObjects<TemplateArgument>()),
665      NumArguments(Args.size()) {
666  std::uninitialized_copy(Args.begin(), Args.end(),
667                          getTrailingObjects<TemplateArgument>());
668}
669
670TemplateArgumentList *
671TemplateArgumentList::CreateCopy(ASTContext &Context,
672                                 ArrayRef<TemplateArgument> Args) {
673  void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
674  return new (Mem) TemplateArgumentList(Args);
675}
676
677FunctionTemplateSpecializationInfo *
678FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
679                                           FunctionTemplateDecl *Template,
680                                           TemplateSpecializationKind TSK,
681                                       const TemplateArgumentList *TemplateArgs,
682                          const TemplateArgumentListInfo *TemplateArgsAsWritten,
683                                           SourceLocation POI) {
684  const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
685  if (TemplateArgsAsWritten)
686    ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
687                                                        *TemplateArgsAsWritten);
688
689  return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
690                                                    TemplateArgs,
691                                                    ArgsAsWritten,
692                                                    POI);
693}
694
695//===----------------------------------------------------------------------===//
696// TemplateDecl Implementation
697//===----------------------------------------------------------------------===//
698
699void TemplateDecl::anchor() { }
700
701//===----------------------------------------------------------------------===//
702// ClassTemplateSpecializationDecl Implementation
703//===----------------------------------------------------------------------===//
704ClassTemplateSpecializationDecl::
705ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
706                                DeclContext *DC, SourceLocation StartLoc,
707                                SourceLocation IdLoc,
708                                ClassTemplateDecl *SpecializedTemplate,
709                                ArrayRef<TemplateArgument> Args,
710                                ClassTemplateSpecializationDecl *PrevDecl)
711  : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
712                  SpecializedTemplate->getIdentifier(),
713                  PrevDecl),
714    SpecializedTemplate(SpecializedTemplate),
715    ExplicitInfo(nullptr),
716    TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
717    SpecializationKind(TSK_Undeclared) {
718}
719
720ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
721                                                                 Kind DK)
722    : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
723                    SourceLocation(), nullptr, nullptr),
724      ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
725
726ClassTemplateSpecializationDecl *
727ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
728                                        DeclContext *DC,
729                                        SourceLocation StartLoc,
730                                        SourceLocation IdLoc,
731                                        ClassTemplateDecl *SpecializedTemplate,
732                                        ArrayRef<TemplateArgument> Args,
733                                   ClassTemplateSpecializationDecl *PrevDecl) {
734  ClassTemplateSpecializationDecl *Result =
735      new (Context, DC) ClassTemplateSpecializationDecl(
736          Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
737          SpecializedTemplate, Args, PrevDecl);
738  Result->MayHaveOutOfDateDef = false;
739
740  Context.getTypeDeclType(Result, PrevDecl);
741  return Result;
742}
743
744ClassTemplateSpecializationDecl *
745ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
746                                                    unsigned ID) {
747  ClassTemplateSpecializationDecl *Result =
748    new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
749  Result->MayHaveOutOfDateDef = false;
750  return Result;
751}
752
753void ClassTemplateSpecializationDecl::getNameForDiagnostic(
754    raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
755  NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
756
757  const TemplateArgumentList &TemplateArgs = getTemplateArgs();
758  TemplateSpecializationType::PrintTemplateArgumentList(
759      OS, TemplateArgs.asArray(), Policy);
760}
761
762ClassTemplateDecl *
763ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
764  if (SpecializedPartialSpecialization *PartialSpec
765      = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
766    return PartialSpec->PartialSpecialization->getSpecializedTemplate();
767  return SpecializedTemplate.get<ClassTemplateDecl*>();
768}
769
770SourceRange
771ClassTemplateSpecializationDecl::getSourceRange() const {
772  if (ExplicitInfo) {
773    SourceLocation Begin = getTemplateKeywordLoc();
774    if (Begin.isValid()) {
775      // Here we have an explicit (partial) specialization or instantiation.
776      assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
777             getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
778             getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
779      if (getExternLoc().isValid())
780        Begin = getExternLoc();
781      SourceLocation End = getRBraceLoc();
782      if (End.isInvalid())
783        End = getTypeAsWritten()->getTypeLoc().getEndLoc();
784      return SourceRange(Begin, End);
785    }
786    // An implicit instantiation of a class template partial specialization
787    // uses ExplicitInfo to record the TypeAsWritten, but the source
788    // locations should be retrieved from the instantiation pattern.
789    typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
790    CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
791    CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
792    assert(inst_from != nullptr);
793    return inst_from->getSourceRange();
794  }
795  else {
796    // No explicit info available.
797    llvm::PointerUnion<ClassTemplateDecl *,
798                       ClassTemplatePartialSpecializationDecl *>
799      inst_from = getInstantiatedFrom();
800    if (inst_from.isNull())
801      return getSpecializedTemplate()->getSourceRange();
802    if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
803      return ctd->getSourceRange();
804    return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
805      ->getSourceRange();
806  }
807}
808
809//===----------------------------------------------------------------------===//
810// ClassTemplatePartialSpecializationDecl Implementation
811//===----------------------------------------------------------------------===//
812void ClassTemplatePartialSpecializationDecl::anchor() { }
813
814ClassTemplatePartialSpecializationDecl::
815ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
816                                       DeclContext *DC,
817                                       SourceLocation StartLoc,
818                                       SourceLocation IdLoc,
819                                       TemplateParameterList *Params,
820                                       ClassTemplateDecl *SpecializedTemplate,
821                                       ArrayRef<TemplateArgument> Args,
822                               const ASTTemplateArgumentListInfo *ArgInfos,
823                               ClassTemplatePartialSpecializationDecl *PrevDecl)
824  : ClassTemplateSpecializationDecl(Context,
825                                    ClassTemplatePartialSpecialization,
826                                    TK, DC, StartLoc, IdLoc,
827                                    SpecializedTemplate,
828                                    Args, PrevDecl),
829    TemplateParams(Params), ArgsAsWritten(ArgInfos),
830    InstantiatedFromMember(nullptr, false)
831{
832  AdoptTemplateParameterList(Params, this);
833}
834
835ClassTemplatePartialSpecializationDecl *
836ClassTemplatePartialSpecializationDecl::
837Create(ASTContext &Context, TagKind TK,DeclContext *DC,
838       SourceLocation StartLoc, SourceLocation IdLoc,
839       TemplateParameterList *Params,
840       ClassTemplateDecl *SpecializedTemplate,
841       ArrayRef<TemplateArgument> Args,
842       const TemplateArgumentListInfo &ArgInfos,
843       QualType CanonInjectedType,
844       ClassTemplatePartialSpecializationDecl *PrevDecl) {
845  const ASTTemplateArgumentListInfo *ASTArgInfos =
846    ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
847
848  ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
849      ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
850                                             Params, SpecializedTemplate, Args,
851                                             ASTArgInfos, PrevDecl);
852  Result->setSpecializationKind(TSK_ExplicitSpecialization);
853  Result->MayHaveOutOfDateDef = false;
854
855  Context.getInjectedClassNameType(Result, CanonInjectedType);
856  return Result;
857}
858
859ClassTemplatePartialSpecializationDecl *
860ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
861                                                           unsigned ID) {
862  ClassTemplatePartialSpecializationDecl *Result =
863      new (C, ID) ClassTemplatePartialSpecializationDecl(C);
864  Result->MayHaveOutOfDateDef = false;
865  return Result;
866}
867
868//===----------------------------------------------------------------------===//
869// FriendTemplateDecl Implementation
870//===----------------------------------------------------------------------===//
871
872void FriendTemplateDecl::anchor() { }
873
874FriendTemplateDecl *
875FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
876                           SourceLocation L,
877                           MutableArrayRef<TemplateParameterList *> Params,
878                           FriendUnion Friend, SourceLocation FLoc) {
879  return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
880}
881
882FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
883                                                           unsigned ID) {
884  return new (C, ID) FriendTemplateDecl(EmptyShell());
885}
886
887//===----------------------------------------------------------------------===//
888// TypeAliasTemplateDecl Implementation
889//===----------------------------------------------------------------------===//
890
891TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
892                                                     DeclContext *DC,
893                                                     SourceLocation L,
894                                                     DeclarationName Name,
895                                                  TemplateParameterList *Params,
896                                                     NamedDecl *Decl) {
897  AdoptTemplateParameterList(Params, DC);
898  return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
899}
900
901TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
902                                                                 unsigned ID) {
903  return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
904                                           DeclarationName(), nullptr, nullptr);
905}
906
907void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
908  static_cast<Common *>(Ptr)->~Common();
909}
910RedeclarableTemplateDecl::CommonBase *
911TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
912  Common *CommonPtr = new (C) Common;
913  C.AddDeallocation(DeallocateCommon, CommonPtr);
914  return CommonPtr;
915}
916
917//===----------------------------------------------------------------------===//
918// ClassScopeFunctionSpecializationDecl Implementation
919//===----------------------------------------------------------------------===//
920
921void ClassScopeFunctionSpecializationDecl::anchor() { }
922
923ClassScopeFunctionSpecializationDecl *
924ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
925                                                         unsigned ID) {
926  return new (C, ID) ClassScopeFunctionSpecializationDecl(
927      nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
928}
929
930//===----------------------------------------------------------------------===//
931// VarTemplateDecl Implementation
932//===----------------------------------------------------------------------===//
933
934void VarTemplateDecl::DeallocateCommon(void *Ptr) {
935  static_cast<Common *>(Ptr)->~Common();
936}
937
938VarTemplateDecl *VarTemplateDecl::getDefinition() {
939  VarTemplateDecl *CurD = this;
940  while (CurD) {
941    if (CurD->isThisDeclarationADefinition())
942      return CurD;
943    CurD = CurD->getPreviousDecl();
944  }
945  return nullptr;
946}
947
948VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
949                                         SourceLocation L, DeclarationName Name,
950                                         TemplateParameterList *Params,
951                                         VarDecl *Decl) {
952  return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
953}
954
955VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
956                                                     unsigned ID) {
957  return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
958                                     DeclarationName(), nullptr, nullptr);
959}
960
961// TODO: Unify across class, function and variable templates?
962//       May require moving this and Common to RedeclarableTemplateDecl.
963void VarTemplateDecl::LoadLazySpecializations() const {
964  // Grab the most recent declaration to ensure we've loaded any lazy
965  // redeclarations of this template.
966  //
967  // FIXME: Avoid walking the entire redeclaration chain here.
968  Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
969  if (CommonPtr->LazySpecializations) {
970    ASTContext &Context = getASTContext();
971    uint32_t *Specs = CommonPtr->LazySpecializations;
972    CommonPtr->LazySpecializations = nullptr;
973    for (uint32_t I = 0, N = *Specs++; I != N; ++I)
974      (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
975  }
976}
977
978llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
979VarTemplateDecl::getSpecializations() const {
980  LoadLazySpecializations();
981  return getCommonPtr()->Specializations;
982}
983
984llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
985VarTemplateDecl::getPartialSpecializations() {
986  LoadLazySpecializations();
987  return getCommonPtr()->PartialSpecializations;
988}
989
990RedeclarableTemplateDecl::CommonBase *
991VarTemplateDecl::newCommon(ASTContext &C) const {
992  Common *CommonPtr = new (C) Common;
993  C.AddDeallocation(DeallocateCommon, CommonPtr);
994  return CommonPtr;
995}
996
997VarTemplateSpecializationDecl *
998VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
999                                    void *&InsertPos) {
1000  return findSpecializationImpl(getSpecializations(), Args, InsertPos);
1001}
1002
1003void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1004                                        void *InsertPos) {
1005  addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1006}
1007
1008VarTemplatePartialSpecializationDecl *
1009VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1010                                           void *&InsertPos) {
1011  return findSpecializationImpl(getPartialSpecializations(), Args, 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 (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1036    PS.push_back(P.getMostRecentDecl());
1037}
1038
1039VarTemplatePartialSpecializationDecl *
1040VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1041    VarTemplatePartialSpecializationDecl *D) {
1042  Decl *DCanon = D->getCanonicalDecl();
1043  for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1044    if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1045      return P.getMostRecentDecl();
1046  }
1047
1048  return nullptr;
1049}
1050
1051//===----------------------------------------------------------------------===//
1052// VarTemplateSpecializationDecl Implementation
1053//===----------------------------------------------------------------------===//
1054VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1055    Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1056    SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1057    TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1058    : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1059              SpecializedTemplate->getIdentifier(), T, TInfo, S),
1060      SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
1061      TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1062      SpecializationKind(TSK_Undeclared) {}
1063
1064VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1065                                                             ASTContext &C)
1066    : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1067              QualType(), nullptr, SC_None),
1068      ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
1069
1070VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1071    ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1072    SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1073    TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1074  return new (Context, DC) VarTemplateSpecializationDecl(
1075      VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1076      SpecializedTemplate, T, TInfo, S, Args);
1077}
1078
1079VarTemplateSpecializationDecl *
1080VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1081  return new (C, ID)
1082      VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1083}
1084
1085void VarTemplateSpecializationDecl::getNameForDiagnostic(
1086    raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1087  NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1088
1089  const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1090  TemplateSpecializationType::PrintTemplateArgumentList(
1091      OS, TemplateArgs.asArray(), Policy);
1092}
1093
1094VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1095  if (SpecializedPartialSpecialization *PartialSpec =
1096          SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1097    return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1098  return SpecializedTemplate.get<VarTemplateDecl *>();
1099}
1100
1101void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1102    const TemplateArgumentListInfo &ArgsInfo) {
1103  TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1104  TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1105  for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1106    TemplateArgsInfo.addArgument(Loc);
1107}
1108
1109//===----------------------------------------------------------------------===//
1110// VarTemplatePartialSpecializationDecl Implementation
1111//===----------------------------------------------------------------------===//
1112void VarTemplatePartialSpecializationDecl::anchor() {}
1113
1114VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1115    ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1116    SourceLocation IdLoc, TemplateParameterList *Params,
1117    VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1118    StorageClass S, ArrayRef<TemplateArgument> Args,
1119    const ASTTemplateArgumentListInfo *ArgInfos)
1120    : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1121                                    DC, StartLoc, IdLoc, SpecializedTemplate, T,
1122                                    TInfo, S, Args),
1123      TemplateParams(Params), ArgsAsWritten(ArgInfos),
1124      InstantiatedFromMember(nullptr, false) {
1125  // TODO: The template parameters should be in DC by now. Verify.
1126  // AdoptTemplateParameterList(Params, DC);
1127}
1128
1129VarTemplatePartialSpecializationDecl *
1130VarTemplatePartialSpecializationDecl::Create(
1131    ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1132    SourceLocation IdLoc, TemplateParameterList *Params,
1133    VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1134    StorageClass S, ArrayRef<TemplateArgument> Args,
1135    const TemplateArgumentListInfo &ArgInfos) {
1136  const ASTTemplateArgumentListInfo *ASTArgInfos
1137    = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1138
1139  VarTemplatePartialSpecializationDecl *Result =
1140      new (Context, DC) VarTemplatePartialSpecializationDecl(
1141          Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1142          S, Args, ASTArgInfos);
1143  Result->setSpecializationKind(TSK_ExplicitSpecialization);
1144  return Result;
1145}
1146
1147VarTemplatePartialSpecializationDecl *
1148VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1149                                                         unsigned ID) {
1150  return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1151}
1152
1153static TemplateParameterList *
1154createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1155  // typename T
1156  auto *T = TemplateTypeParmDecl::Create(
1157      C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1158      /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1159  T->setImplicit(true);
1160
1161  // T ...Ints
1162  TypeSourceInfo *TI =
1163      C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1164  auto *N = NonTypeTemplateParmDecl::Create(
1165      C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1166      /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1167  N->setImplicit(true);
1168
1169  // <typename T, T ...Ints>
1170  NamedDecl *P[2] = {T, N};
1171  auto *TPL = TemplateParameterList::Create(
1172      C, SourceLocation(), SourceLocation(), P, SourceLocation());
1173
1174  // template <typename T, ...Ints> class IntSeq
1175  auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1176      C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1177      /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1178  TemplateTemplateParm->setImplicit(true);
1179
1180  // typename T
1181  auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1182      C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1183      /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1184  TemplateTypeParm->setImplicit(true);
1185
1186  // T N
1187  TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1188      QualType(TemplateTypeParm->getTypeForDecl(), 0));
1189  auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1190      C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1191      /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1192  NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1193                         NonTypeTemplateParm};
1194
1195  // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1196  return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1197                                       Params, SourceLocation());
1198}
1199
1200static TemplateParameterList *
1201createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1202  // std::size_t Index
1203  TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1204  auto *Index = NonTypeTemplateParmDecl::Create(
1205      C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1206      /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1207
1208  // typename ...T
1209  auto *Ts = TemplateTypeParmDecl::Create(
1210      C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1211      /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1212  Ts->setImplicit(true);
1213
1214  // template <std::size_t Index, typename ...T>
1215  NamedDecl *Params[] = {Index, Ts};
1216  return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1217                                       llvm::makeArrayRef(Params),
1218                                       SourceLocation());
1219}
1220
1221static TemplateParameterList *createBuiltinTemplateParameterList(
1222    const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1223  switch (BTK) {
1224  case BTK__make_integer_seq:
1225    return createMakeIntegerSeqParameterList(C, DC);
1226  case BTK__type_pack_element:
1227    return createTypePackElementParameterList(C, DC);
1228  }
1229
1230  llvm_unreachable("unhandled BuiltinTemplateKind!");
1231}
1232
1233void BuiltinTemplateDecl::anchor() {}
1234
1235BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1236                                         DeclarationName Name,
1237                                         BuiltinTemplateKind BTK)
1238    : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1239                   createBuiltinTemplateParameterList(C, DC, BTK)),
1240      BTK(BTK) {}
1241