Clang Project

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