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
46
47TemplateParameterList::TemplateParameterList(const ASTContext& C,
48                                             SourceLocation TemplateLoc,
49                                             SourceLocation LAngleLoc,
50                                             ArrayRef<NamedDecl *> Params,
51                                             SourceLocation RAngleLoc,
52                                             Expr *RequiresClause)
53    : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
54      NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
55      HasRequiresClause(RequiresClause != nullptr),
56      HasConstrainedParameters(false) {
57  for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
58    NamedDecl *P = Params[Idx];
59    begin()[Idx] = P;
60
61    bool IsPack = P->isTemplateParameterPack();
62    if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
63      if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())
64        ContainsUnexpandedParameterPack = true;
65      if (NTTP->hasPlaceholderTypeConstraint())
66        HasConstrainedParameters = true;
67    } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
68      if (!IsPack &&
69          TTP->getTemplateParameters()->containsUnexpandedParameterPack())
70        ContainsUnexpandedParameterPack = true;
71    } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
72      if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
73        if (TC->getImmediatelyDeclaredConstraint()
74            ->containsUnexpandedParameterPack())
75          ContainsUnexpandedParameterPack = true;
76      }
77      HasConstrainedParameters = TTP->hasTypeConstraint();
78    } else {
79      llvm_unreachable("unexpcted template parameter type");
80    }
81    // FIXME: If a default argument contains an unexpanded parameter pack, the
82    // template parameter list does too.
83  }
84
85  if (HasRequiresClause) {
86    if (RequiresClause->containsUnexpandedParameterPack())
87      ContainsUnexpandedParameterPack = true;
88    *getTrailingObjects<Expr *>() = RequiresClause;
89  }
90}
91
92bool TemplateParameterList::containsUnexpandedParameterPack() const {
93  if (ContainsUnexpandedParameterPack)
94    return true;
95  if (!HasConstrainedParameters)
96    return false;
97
98  // An implicit constrained parameter might have had a use of an unexpanded
99  // pack added to it after the template parameter list was created. All
100  // implicit parameters are at the end of the parameter list.
101  for (const NamedDecl *Param : llvm::reverse(asArray())) {
102    if (!Param->isImplicit())
103      break;
104
105    if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
106      const auto *TC = TTP->getTypeConstraint();
107      if (TC && TC->getImmediatelyDeclaredConstraint()
108                    ->containsUnexpandedParameterPack())
109        return true;
110    }
111  }
112
113  return false;
114}
115
116TemplateParameterList *
117TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
118                              SourceLocation LAngleLoc,
119                              ArrayRef<NamedDecl *> Params,
120                              SourceLocation RAngleLoc, Expr *RequiresClause) {
121  void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
122                             Params.size(), RequiresClause ? 1u : 0u),
123                         alignof(TemplateParameterList));
124  return new (Mem) TemplateParameterList(C, TemplateLoc, LAngleLoc, Params,
125                                         RAngleLoc, RequiresClause);
126}
127
128unsigned TemplateParameterList::getMinRequiredArguments() const {
129  unsigned NumRequiredArgs = 0;
130  for (const NamedDecl *P : asArray()) {
131    if (P->isTemplateParameterPack()) {
132      if (Optional<unsigned> Expansions = getExpandedPackSize(P)) {
133        NumRequiredArgs += *Expansions;
134        continue;
135      }
136      break;
137    }
138
139    if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
140      if (TTP->hasDefaultArgument())
141        break;
142    } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
143      if (NTTP->hasDefaultArgument())
144        break;
145    } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
146      break;
147
148    ++NumRequiredArgs;
149  }
150
151  return NumRequiredArgs;
152}
153
154unsigned TemplateParameterList::getDepth() const {
155  if (size() == 0)
156    return 0;
157
158  const NamedDecl *FirstParm = getParam(0);
159  if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
160    return TTP->getDepth();
161  else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
162    return NTTP->getDepth();
163  else
164    return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
165}
166
167static void AdoptTemplateParameterList(TemplateParameterList *Params,
168                                       DeclContext *Owner) {
169  for (NamedDecl *P : *Params) {
170    P->setDeclContext(Owner);
171
172    if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
173      AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
174  }
175}
176
177void TemplateParameterList::
178getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
179  if (HasConstrainedParameters)
180    for (const NamedDecl *Param : *this) {
181      if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
182        if (const auto *TC = TTP->getTypeConstraint())
183          AC.push_back(TC->getImmediatelyDeclaredConstraint());
184      } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
185        if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
186          AC.push_back(E);
187      }
188    }
189  if (HasRequiresClause)
190    AC.push_back(getRequiresClause());
191}
192
193bool TemplateParameterList::hasAssociatedConstraints() const {
194  return HasRequiresClause || HasConstrainedParameters;
195}
196
197bool TemplateParameterList::shouldIncludeTypeForArgument(
198    const TemplateParameterList *TPL, unsigned Idx) {
199  if (!TPL || Idx >= TPL->size())
200    return true;
201  const NamedDecl *TemplParam = TPL->getParam(Idx);
202  if (const auto *ParamValueDecl =
203          dyn_cast<NonTypeTemplateParmDecl>(TemplParam))
204    if (ParamValueDecl->getType()->getContainedDeducedType())
205      return true;
206  return false;
207}
208
209namespace clang {
210
211void *allocateDefaultArgStorageChain(const ASTContext &C) {
212  return new (C) char[sizeof(void*) * 2];
213}
214
215} // namespace clang
216
217//===----------------------------------------------------------------------===//
218// TemplateDecl Implementation
219//===----------------------------------------------------------------------===//
220
221TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
222                           DeclarationName Name, TemplateParameterList *Params,
223                           NamedDecl *Decl)
224    : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
225
226void TemplateDecl::anchor() {}
227
228void TemplateDecl::
229getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
230  TemplateParams->getAssociatedConstraints(AC);
231  if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
232    if (const Expr *TRC = FD->getTrailingRequiresClause())
233      AC.push_back(TRC);
234}
235
236bool TemplateDecl::hasAssociatedConstraints() const {
237  if (TemplateParams->hasAssociatedConstraints())
238    return true;
239  if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
240    return FD->getTrailingRequiresClause();
241  return false;
242}
243
244//===----------------------------------------------------------------------===//
245// RedeclarableTemplateDecl Implementation
246//===----------------------------------------------------------------------===//
247
248void RedeclarableTemplateDecl::anchor() {}
249
250RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
251  if (Common)
252    return Common;
253
254  // Walk the previous-declaration chain until we either find a declaration
255  // with a common pointer or we run out of previous declarations.
256  SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
257  for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
258       Prev = Prev->getPreviousDecl()) {
259    if (Prev->Common) {
260      Common = Prev->Common;
261      break;
262    }
263
264    PrevDecls.push_back(Prev);
265  }
266
267  // If we never found a common pointer, allocate one now.
268  if (!Common) {
269    // FIXME: If any of the declarations is from an AST file, we probably
270    // need an update record to add the common data.
271
272    Common = newCommon(getASTContext());
273  }
274
275  // Update any previous declarations we saw with the common pointer.
276  for (const RedeclarableTemplateDecl *Prev : PrevDecls)
277    Prev->Common = Common;
278
279  return Common;
280}
281
282void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
283  // Grab the most recent declaration to ensure we've loaded any lazy
284  // redeclarations of this template.
285  CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
286  if (CommonBasePtr->LazySpecializations) {
287    ASTContext &Context = getASTContext();
288    uint32_t *Specs = CommonBasePtr->LazySpecializations;
289    CommonBasePtr->LazySpecializations = nullptr;
290    for (uint32_t I = 0, N = *Specs++; I != N; ++I)
291      (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
292  }
293}
294
295template<class EntryType, typename... ProfileArguments>
296typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
297RedeclarableTemplateDecl::findSpecializationImpl(
298    llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
299    ProfileArguments&&... ProfileArgs) {
300  using SETraits = SpecEntryTraits<EntryType>;
301
302  llvm::FoldingSetNodeID ID;
303  EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
304                     getASTContext());
305  EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
306  return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
307}
308
309template<class Derived, class EntryType>
310void RedeclarableTemplateDecl::addSpecializationImpl(
311    llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
312    void *InsertPos) {
313  using SETraits = SpecEntryTraits<EntryType>;
314
315  if (InsertPos) {
316#ifndef NDEBUG
317    void *CorrectInsertPos;
318    assert(!findSpecializationImpl(Specializations,
319                                   CorrectInsertPos,
320                                   SETraits::getTemplateArgs(Entry)) &&
321           InsertPos == CorrectInsertPos &&
322           "given incorrect InsertPos for specialization");
323#endif
324    Specializations.InsertNode(Entry, InsertPos);
325  } else {
326    EntryType *Existing = Specializations.GetOrInsertNode(Entry);
327    (void)Existing;
328    assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
329           "non-canonical specialization?");
330  }
331
332  if (ASTMutationListener *L = getASTMutationListener())
333    L->AddedCXXTemplateSpecialization(cast<Derived>(this),
334                                      SETraits::getDecl(Entry));
335}
336
337//===----------------------------------------------------------------------===//
338// FunctionTemplateDecl Implementation
339//===----------------------------------------------------------------------===//
340
341FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
342                                                   DeclContext *DC,
343                                                   SourceLocation L,
344                                                   DeclarationName Name,
345                                               TemplateParameterList *Params,
346                                                   NamedDecl *Decl) {
347  AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
348  return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
349}
350
351FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
352                                                               unsigned ID) {
353  return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
354                                          DeclarationName(), nullptr, nullptr);
355}
356
357RedeclarableTemplateDecl::CommonBase *
358FunctionTemplateDecl::newCommon(ASTContext &C) const {
359  auto *CommonPtr = new (C) Common;
360  C.addDestruction(CommonPtr);
361  return CommonPtr;
362}
363
364void FunctionTemplateDecl::LoadLazySpecializations() const {
365  loadLazySpecializationsImpl();
366}
367
368llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
369FunctionTemplateDecl::getSpecializations() const {
370  LoadLazySpecializations();
371  return getCommonPtr()->Specializations;
372}
373
374FunctionDecl *
375FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
376                                         void *&InsertPos) {
377  return findSpecializationImpl(getSpecializations(), InsertPos, Args);
378}
379
380void FunctionTemplateDecl::addSpecialization(
381      FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
382  addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
383                                              InsertPos);
384}
385
386ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
387  TemplateParameterList *Params = getTemplateParameters();
388  Common *CommonPtr = getCommonPtr();
389  if (!CommonPtr->InjectedArgs) {
390    auto &Context = getASTContext();
391    SmallVector<TemplateArgument, 16> TemplateArgs;
392    Context.getInjectedTemplateArgs(Params, TemplateArgs);
393    CommonPtr->InjectedArgs =
394        new (Context) TemplateArgument[TemplateArgs.size()];
395    std::copy(TemplateArgs.begin(), TemplateArgs.end(),
396              CommonPtr->InjectedArgs);
397  }
398
399  return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
400}
401
402void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
403  using Base = RedeclarableTemplateDecl;
404
405  // If we haven't created a common pointer yet, then it can just be created
406  // with the usual method.
407  if (!Base::Common)
408    return;
409
410  Common *ThisCommon = static_cast<Common *>(Base::Common);
411  Common *PrevCommon = nullptr;
412  SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
413  for (; Prev; Prev = Prev->getPreviousDecl()) {
414    if (Prev->Base::Common) {
415      PrevCommon = static_cast<Common *>(Prev->Base::Common);
416      break;
417    }
418    PreviousDecls.push_back(Prev);
419  }
420
421  // If the previous redecl chain hasn't created a common pointer yet, then just
422  // use this common pointer.
423  if (!PrevCommon) {
424    for (auto *D : PreviousDecls)
425      D->Base::Common = ThisCommon;
426    return;
427  }
428
429  // Ensure we don't leak any important state.
430  assert(ThisCommon->Specializations.size() == 0 &&
431         "Can't merge incompatible declarations!");
432
433  Base::Common = PrevCommon;
434}
435
436//===----------------------------------------------------------------------===//
437// ClassTemplateDecl Implementation
438//===----------------------------------------------------------------------===//
439
440ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
441                                             DeclContext *DC,
442                                             SourceLocation L,
443                                             DeclarationName Name,
444                                             TemplateParameterList *Params,
445                                             NamedDecl *Decl) {
446  AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
447
448  return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
449}
450
451ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
452                                                         unsigned ID) {
453  return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
454                                       DeclarationName(), nullptr, nullptr);
455}
456
457void ClassTemplateDecl::LoadLazySpecializations() const {
458  loadLazySpecializationsImpl();
459}
460
461llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
462ClassTemplateDecl::getSpecializations() const {
463  LoadLazySpecializations();
464  return getCommonPtr()->Specializations;
465}
466
467llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
468ClassTemplateDecl::getPartialSpecializations() const {
469  LoadLazySpecializations();
470  return getCommonPtr()->PartialSpecializations;
471}
472
473RedeclarableTemplateDecl::CommonBase *
474ClassTemplateDecl::newCommon(ASTContext &C) const {
475  auto *CommonPtr = new (C) Common;
476  C.addDestruction(CommonPtr);
477  return CommonPtr;
478}
479
480ClassTemplateSpecializationDecl *
481ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
482                                      void *&InsertPos) {
483  return findSpecializationImpl(getSpecializations(), InsertPos, Args);
484}
485
486void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
487                                          void *InsertPos) {
488  addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
489}
490
491ClassTemplatePartialSpecializationDecl *
492ClassTemplateDecl::findPartialSpecialization(
493    ArrayRef<TemplateArgument> Args,
494    TemplateParameterList *TPL, void *&InsertPos) {
495  return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
496                                TPL);
497}
498
499static void ProfileTemplateParameterList(ASTContext &C,
500    llvm::FoldingSetNodeID &ID, const TemplateParameterList *TPL) {
501  const Expr *RC = TPL->getRequiresClause();
502  ID.AddBoolean(RC != nullptr);
503  if (RC)
504    RC->Profile(ID, C, /*Canonical=*/true);
505  ID.AddInteger(TPL->size());
506  for (NamedDecl *D : *TPL) {
507    if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
508      ID.AddInteger(0);
509      ID.AddBoolean(NTTP->isParameterPack());
510      NTTP->getType().getCanonicalType().Profile(ID);
511      continue;
512    }
513    if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {
514      ID.AddInteger(1);
515      ID.AddBoolean(TTP->isParameterPack());
516      ID.AddBoolean(TTP->hasTypeConstraint());
517      if (const TypeConstraint *TC = TTP->getTypeConstraint())
518        TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,
519                                                        /*Canonical=*/true);
520      continue;
521    }
522    const auto *TTP = cast<TemplateTemplateParmDecl>(D);
523    ID.AddInteger(2);
524    ID.AddBoolean(TTP->isParameterPack());
525    ProfileTemplateParameterList(C, ID, TTP->getTemplateParameters());
526  }
527}
528
529void
530ClassTemplatePartialSpecializationDecl::Profile(llvm::FoldingSetNodeID &ID,
531    ArrayRef<TemplateArgument> TemplateArgs, TemplateParameterList *TPL,
532    ASTContext &Context) {
533  ID.AddInteger(TemplateArgs.size());
534  for (const TemplateArgument &TemplateArg : TemplateArgs)
535    TemplateArg.Profile(ID, Context);
536  ProfileTemplateParameterList(Context, ID, TPL);
537}
538
539void ClassTemplateDecl::AddPartialSpecialization(
540                                      ClassTemplatePartialSpecializationDecl *D,
541                                      void *InsertPos) {
542  if (InsertPos)
543    getPartialSpecializations().InsertNode(D, InsertPos);
544  else {
545    ClassTemplatePartialSpecializationDecl *Existing
546      = getPartialSpecializations().GetOrInsertNode(D);
547    (void)Existing;
548    assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
549  }
550
551  if (ASTMutationListener *L = getASTMutationListener())
552    L->AddedCXXTemplateSpecialization(this, D);
553}
554
555void ClassTemplateDecl::getPartialSpecializations(
556    SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) const {
557  llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
558    = getPartialSpecializations();
559  PS.clear();
560  PS.reserve(PartialSpecs.size());
561  for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
562    PS.push_back(P.getMostRecentDecl());
563}
564
565ClassTemplatePartialSpecializationDecl *
566ClassTemplateDecl::findPartialSpecialization(QualType T) {
567  ASTContext &Context = getASTContext();
568  for (ClassTemplatePartialSpecializationDecl &P :
569       getPartialSpecializations()) {
570    if (Context.hasSameType(P.getInjectedSpecializationType(), T))
571      return P.getMostRecentDecl();
572  }
573
574  return nullptr;
575}
576
577ClassTemplatePartialSpecializationDecl *
578ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
579                                    ClassTemplatePartialSpecializationDecl *D) {
580  Decl *DCanon = D->getCanonicalDecl();
581  for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
582    if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
583      return P.getMostRecentDecl();
584  }
585
586  return nullptr;
587}
588
589QualType
590ClassTemplateDecl::getInjectedClassNameSpecialization() {
591  Common *CommonPtr = getCommonPtr();
592  if (!CommonPtr->InjectedClassNameType.isNull())
593    return CommonPtr->InjectedClassNameType;
594
595  // C++0x [temp.dep.type]p2:
596  //  The template argument list of a primary template is a template argument
597  //  list in which the nth template argument has the value of the nth template
598  //  parameter of the class template. If the nth template parameter is a
599  //  template parameter pack (14.5.3), the nth template argument is a pack
600  //  expansion (14.5.3) whose pattern is the name of the template parameter
601  //  pack.
602  ASTContext &Context = getASTContext();
603  TemplateParameterList *Params = getTemplateParameters();
604  SmallVector<TemplateArgument, 16> TemplateArgs;
605  Context.getInjectedTemplateArgs(Params, TemplateArgs);
606  CommonPtr->InjectedClassNameType
607    = Context.getTemplateSpecializationType(TemplateName(this),
608                                            TemplateArgs);
609  return CommonPtr->InjectedClassNameType;
610}
611
612//===----------------------------------------------------------------------===//
613// TemplateTypeParm Allocation/Deallocation Method Implementations
614//===----------------------------------------------------------------------===//
615
616TemplateTypeParmDecl *
617TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
618                             SourceLocation KeyLoc, SourceLocation NameLoc,
619                             unsigned D, unsigned P, IdentifierInfo *Id,
620                             bool Typename, bool ParameterPack,
621                             bool HasTypeConstraint,
622                             Optional<unsigned> NumExpanded) {
623  auto *TTPDecl =
624      new (C, DC,
625           additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
626      TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
627                           HasTypeConstraint, NumExpanded);
628  QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
629  TTPDecl->setTypeForDecl(TTPType.getTypePtr());
630  return TTPDecl;
631}
632
633TemplateTypeParmDecl *
634TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
635  return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
636                                          SourceLocation(), nullptr, false,
637                                          false, None);
638}
639
640TemplateTypeParmDecl *
641TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID,
642                                         bool HasTypeConstraint) {
643  return new (C, ID,
644              additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
645         TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(),
646                              nullptr, false, HasTypeConstraint, None);
647}
648
649SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
650  return hasDefaultArgument()
651             ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
652             : SourceLocation();
653}
654
655SourceRange TemplateTypeParmDecl::getSourceRange() const {
656  if (hasDefaultArgument() && !defaultArgumentWasInherited())
657    return SourceRange(getBeginLoc(),
658                       getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
659  // TypeDecl::getSourceRange returns a range containing name location, which is
660  // wrong for unnamed template parameters. e.g:
661  // it will return <[[typename>]] instead of <[[typename]]>
662  else if (getDeclName().isEmpty())
663    return SourceRange(getBeginLoc());
664  return TypeDecl::getSourceRange();
665}
666
667unsigned TemplateTypeParmDecl::getDepth() const {
668  return getTypeForDecl()->castAs<TemplateTypeParmType>()->getDepth();
669}
670
671unsigned TemplateTypeParmDecl::getIndex() const {
672  return getTypeForDecl()->castAs<TemplateTypeParmType>()->getIndex();
673}
674
675bool TemplateTypeParmDecl::isParameterPack() const {
676  return getTypeForDecl()->castAs<TemplateTypeParmType>()->isParameterPack();
677}
678
679void TemplateTypeParmDecl::setTypeConstraint(NestedNameSpecifierLoc NNS,
680    DeclarationNameInfo NameInfo, NamedDecl *FoundDecl, ConceptDecl *CD,
681    const ASTTemplateArgumentListInfo *ArgsAsWritten,
682    Expr *ImmediatelyDeclaredConstraint) {
683  assert(HasTypeConstraint &&
684         "HasTypeConstraint=true must be passed at construction in order to "
685         "call setTypeConstraint");
686  assert(!TypeConstraintInitialized &&
687         "TypeConstraint was already initialized!");
688  new (getTrailingObjects<TypeConstraint>()) TypeConstraint(NNS, NameInfo,
689      FoundDecl, CD, ArgsAsWritten, ImmediatelyDeclaredConstraint);
690  TypeConstraintInitialized = true;
691}
692
693//===----------------------------------------------------------------------===//
694// NonTypeTemplateParmDecl Method Implementations
695//===----------------------------------------------------------------------===//
696
697NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
698    DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
699    unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
700    ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
701    : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
702      TemplateParmPosition(D, P), ParameterPack(true),
703      ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
704  if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
705    auto TypesAndInfos =
706        getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
707    for (unsigned I = 0; I != NumExpandedTypes; ++I) {
708      new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
709      TypesAndInfos[I].second = ExpandedTInfos[I];
710    }
711  }
712}
713
714NonTypeTemplateParmDecl *
715NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
716                                SourceLocation StartLoc, SourceLocation IdLoc,
717                                unsigned D, unsigned P, IdentifierInfo *Id,
718                                QualType T, bool ParameterPack,
719                                TypeSourceInfo *TInfo) {
720  AutoType *AT =
721      C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
722  return new (C, DC,
723              additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
724                                    Expr *>(0,
725                                            AT && AT->isConstrained() ? 1 : 0))
726      NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,
727                              TInfo);
728}
729
730NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
731    const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
732    SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
733    QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
734    ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
735  AutoType *AT = TInfo->getType()->getContainedAutoType();
736  return new (C, DC,
737              additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
738                                    Expr *>(
739                  ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))
740      NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
741                              ExpandedTypes, ExpandedTInfos);
742}
743
744NonTypeTemplateParmDecl *
745NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
746                                            bool HasTypeConstraint) {
747  return new (C, ID, additionalSizeToAlloc<std::pair<QualType,
748                                                     TypeSourceInfo *>,
749                                           Expr *>(0,
750                                                   HasTypeConstraint ? 1 : 0))
751          NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
752                                  0, 0, nullptr, QualType(), false, nullptr);
753}
754
755NonTypeTemplateParmDecl *
756NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
757                                            unsigned NumExpandedTypes,
758                                            bool HasTypeConstraint) {
759  auto *NTTP =
760      new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
761                                        Expr *>(
762                      NumExpandedTypes, HasTypeConstraint ? 1 : 0))
763          NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
764                                  0, 0, nullptr, QualType(), nullptr, None,
765                                  None);
766  NTTP->NumExpandedTypes = NumExpandedTypes;
767  return NTTP;
768}
769
770SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
771  if (hasDefaultArgument() && !defaultArgumentWasInherited())
772    return SourceRange(getOuterLocStart(),
773                       getDefaultArgument()->getSourceRange().getEnd());
774  return DeclaratorDecl::getSourceRange();
775}
776
777SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
778  return hasDefaultArgument()
779    ? getDefaultArgument()->getSourceRange().getBegin()
780    : SourceLocation();
781}
782
783//===----------------------------------------------------------------------===//
784// TemplateTemplateParmDecl Method Implementations
785//===----------------------------------------------------------------------===//
786
787void TemplateTemplateParmDecl::anchor() {}
788
789TemplateTemplateParmDecl::TemplateTemplateParmDecl(
790    DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
791    IdentifierInfo *Id, TemplateParameterList *Params,
792    ArrayRef<TemplateParameterList *> Expansions)
793    : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
794      TemplateParmPosition(D, P), ParameterPack(true),
795      ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
796  if (!Expansions.empty())
797    std::uninitialized_copy(Expansions.begin(), Expansions.end(),
798                            getTrailingObjects<TemplateParameterList *>());
799}
800
801TemplateTemplateParmDecl *
802TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
803                                 SourceLocation L, unsigned D, unsigned P,
804                                 bool ParameterPack, IdentifierInfo *Id,
805                                 TemplateParameterList *Params) {
806  return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
807                                              Params);
808}
809
810TemplateTemplateParmDecl *
811TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
812                                 SourceLocation L, unsigned D, unsigned P,
813                                 IdentifierInfo *Id,
814                                 TemplateParameterList *Params,
815                                 ArrayRef<TemplateParameterList *> Expansions) {
816  return new (C, DC,
817              additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
818      TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
819}
820
821TemplateTemplateParmDecl *
822TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
823  return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
824                                              false, nullptr, nullptr);
825}
826
827TemplateTemplateParmDecl *
828TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
829                                             unsigned NumExpansions) {
830  auto *TTP =
831      new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
832          TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
833                                   nullptr, None);
834  TTP->NumExpandedParams = NumExpansions;
835  return TTP;
836}
837
838SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
839  return hasDefaultArgument() ? getDefaultArgument().getLocation()
840                              : SourceLocation();
841}
842
843void TemplateTemplateParmDecl::setDefaultArgument(
844    const ASTContext &C, const TemplateArgumentLoc &DefArg) {
845  if (DefArg.getArgument().isNull())
846    DefaultArgument.set(nullptr);
847  else
848    DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
849}
850
851//===----------------------------------------------------------------------===//
852// TemplateArgumentList Implementation
853//===----------------------------------------------------------------------===//
854TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
855    : Arguments(getTrailingObjects<TemplateArgument>()),
856      NumArguments(Args.size()) {
857  std::uninitialized_copy(Args.begin(), Args.end(),
858                          getTrailingObjects<TemplateArgument>());
859}
860
861TemplateArgumentList *
862TemplateArgumentList::CreateCopy(ASTContext &Context,
863                                 ArrayRef<TemplateArgument> Args) {
864  void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
865  return new (Mem) TemplateArgumentList(Args);
866}
867
868FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
869    ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
870    TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
871    const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
872    MemberSpecializationInfo *MSInfo) {
873  const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
874  if (TemplateArgsAsWritten)
875    ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
876                                                        *TemplateArgsAsWritten);
877
878  void *Mem =
879      C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
880  return new (Mem) FunctionTemplateSpecializationInfo(
881      FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
882}
883
884//===----------------------------------------------------------------------===//
885// ClassTemplateSpecializationDecl Implementation
886//===----------------------------------------------------------------------===//
887
888ClassTemplateSpecializationDecl::
889ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
890                                DeclContext *DC, SourceLocation StartLoc,
891                                SourceLocation IdLoc,
892                                ClassTemplateDecl *SpecializedTemplate,
893                                ArrayRef<TemplateArgument> Args,
894                                ClassTemplateSpecializationDecl *PrevDecl)
895    : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
896                    SpecializedTemplate->getIdentifier(), PrevDecl),
897    SpecializedTemplate(SpecializedTemplate),
898    TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
899    SpecializationKind(TSK_Undeclared) {
900}
901
902ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
903                                                                 Kind DK)
904    : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
905                    SourceLocation(), nullptr, nullptr),
906      SpecializationKind(TSK_Undeclared) {}
907
908ClassTemplateSpecializationDecl *
909ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
910                                        DeclContext *DC,
911                                        SourceLocation StartLoc,
912                                        SourceLocation IdLoc,
913                                        ClassTemplateDecl *SpecializedTemplate,
914                                        ArrayRef<TemplateArgument> Args,
915                                   ClassTemplateSpecializationDecl *PrevDecl) {
916  auto *Result =
917      new (Context, DC) ClassTemplateSpecializationDecl(
918          Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
919          SpecializedTemplate, Args, PrevDecl);
920  Result->setMayHaveOutOfDateDef(false);
921
922  Context.getTypeDeclType(Result, PrevDecl);
923  return Result;
924}
925
926ClassTemplateSpecializationDecl *
927ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
928                                                    unsigned ID) {
929  auto *Result =
930    new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
931  Result->setMayHaveOutOfDateDef(false);
932  return Result;
933}
934
935void ClassTemplateSpecializationDecl::getNameForDiagnostic(
936    raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
937  NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
938
939  const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
940  if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
941          PS ? PS->getTemplateArgsAsWritten() : nullptr) {
942    printTemplateArgumentList(
943        OS, ArgsAsWritten->arguments(), Policy,
944        getSpecializedTemplate()->getTemplateParameters());
945  } else {
946    const TemplateArgumentList &TemplateArgs = getTemplateArgs();
947    printTemplateArgumentList(
948        OS, TemplateArgs.asArray(), Policy,
949        getSpecializedTemplate()->getTemplateParameters());
950  }
951}
952
953ClassTemplateDecl *
954ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
955  if (const auto *PartialSpec =
956          SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
957    return PartialSpec->PartialSpecialization->getSpecializedTemplate();
958  return SpecializedTemplate.get<ClassTemplateDecl*>();
959}
960
961SourceRange
962ClassTemplateSpecializationDecl::getSourceRange() const {
963  if (ExplicitInfo) {
964    SourceLocation Begin = getTemplateKeywordLoc();
965    if (Begin.isValid()) {
966      // Here we have an explicit (partial) specialization or instantiation.
967      assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
968             getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
969             getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
970      if (getExternLoc().isValid())
971        Begin = getExternLoc();
972      SourceLocation End = getBraceRange().getEnd();
973      if (End.isInvalid())
974        End = getTypeAsWritten()->getTypeLoc().getEndLoc();
975      return SourceRange(Begin, End);
976    }
977    // An implicit instantiation of a class template partial specialization
978    // uses ExplicitInfo to record the TypeAsWritten, but the source
979    // locations should be retrieved from the instantiation pattern.
980    using CTPSDecl = ClassTemplatePartialSpecializationDecl;
981    auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
982    CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
983    assert(inst_from != nullptr);
984    return inst_from->getSourceRange();
985  }
986  else {
987    // No explicit info available.
988    llvm::PointerUnion<ClassTemplateDecl *,
989                       ClassTemplatePartialSpecializationDecl *>
990      inst_from = getInstantiatedFrom();
991    if (inst_from.isNull())
992      return getSpecializedTemplate()->getSourceRange();
993    if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
994      return ctd->getSourceRange();
995    return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
996      ->getSourceRange();
997  }
998}
999
1000//===----------------------------------------------------------------------===//
1001// ConceptDecl Implementation
1002//===----------------------------------------------------------------------===//
1003ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
1004                                 SourceLocation L, DeclarationName Name,
1005                                 TemplateParameterList *Params,
1006                                 Expr *ConstraintExpr) {
1007  AdoptTemplateParameterList(Params, DC);
1008  return new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1009}
1010
1011ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C,
1012                                             unsigned ID) {
1013  ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1014                                                DeclarationName(),
1015                                                nullptr, nullptr);
1016
1017  return Result;
1018}
1019
1020//===----------------------------------------------------------------------===//
1021// ClassTemplatePartialSpecializationDecl Implementation
1022//===----------------------------------------------------------------------===//
1023void ClassTemplatePartialSpecializationDecl::anchor() {}
1024
1025ClassTemplatePartialSpecializationDecl::
1026ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
1027                                       DeclContext *DC,
1028                                       SourceLocation StartLoc,
1029                                       SourceLocation IdLoc,
1030                                       TemplateParameterList *Params,
1031                                       ClassTemplateDecl *SpecializedTemplate,
1032                                       ArrayRef<TemplateArgument> Args,
1033                               const ASTTemplateArgumentListInfo *ArgInfos,
1034                               ClassTemplatePartialSpecializationDecl *PrevDecl)
1035    : ClassTemplateSpecializationDecl(Context,
1036                                      ClassTemplatePartialSpecialization,
1037                                      TK, DC, StartLoc, IdLoc,
1038                                      SpecializedTemplate, Args, PrevDecl),
1039      TemplateParams(Params), ArgsAsWritten(ArgInfos),
1040      InstantiatedFromMember(nullptr, false) {
1041  AdoptTemplateParameterList(Params, this);
1042}
1043
1044ClassTemplatePartialSpecializationDecl *
1045ClassTemplatePartialSpecializationDecl::
1046Create(ASTContext &Context, TagKind TK,DeclContext *DC,
1047       SourceLocation StartLoc, SourceLocation IdLoc,
1048       TemplateParameterList *Params,
1049       ClassTemplateDecl *SpecializedTemplate,
1050       ArrayRef<TemplateArgument> Args,
1051       const TemplateArgumentListInfo &ArgInfos,
1052       QualType CanonInjectedType,
1053       ClassTemplatePartialSpecializationDecl *PrevDecl) {
1054  const ASTTemplateArgumentListInfo *ASTArgInfos =
1055    ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1056
1057  auto *Result = new (Context, DC)
1058      ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
1059                                             Params, SpecializedTemplate, Args,
1060                                             ASTArgInfos, PrevDecl);
1061  Result->setSpecializationKind(TSK_ExplicitSpecialization);
1062  Result->setMayHaveOutOfDateDef(false);
1063
1064  Context.getInjectedClassNameType(Result, CanonInjectedType);
1065  return Result;
1066}
1067
1068ClassTemplatePartialSpecializationDecl *
1069ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1070                                                           unsigned ID) {
1071  auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
1072  Result->setMayHaveOutOfDateDef(false);
1073  return Result;
1074}
1075
1076//===----------------------------------------------------------------------===//
1077// FriendTemplateDecl Implementation
1078//===----------------------------------------------------------------------===//
1079
1080void FriendTemplateDecl::anchor() {}
1081
1082FriendTemplateDecl *
1083FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
1084                           SourceLocation L,
1085                           MutableArrayRef<TemplateParameterList *> Params,
1086                           FriendUnion Friend, SourceLocation FLoc) {
1087  return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
1088}
1089
1090FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
1091                                                           unsigned ID) {
1092  return new (C, ID) FriendTemplateDecl(EmptyShell());
1093}
1094
1095//===----------------------------------------------------------------------===//
1096// TypeAliasTemplateDecl Implementation
1097//===----------------------------------------------------------------------===//
1098
1099TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
1100                                                     DeclContext *DC,
1101                                                     SourceLocation L,
1102                                                     DeclarationName Name,
1103                                                  TemplateParameterList *Params,
1104                                                     NamedDecl *Decl) {
1105  AdoptTemplateParameterList(Params, DC);
1106  return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1107}
1108
1109TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
1110                                                                 unsigned ID) {
1111  return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1112                                           DeclarationName(), nullptr, nullptr);
1113}
1114
1115RedeclarableTemplateDecl::CommonBase *
1116TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
1117  auto *CommonPtr = new (C) Common;
1118  C.addDestruction(CommonPtr);
1119  return CommonPtr;
1120}
1121
1122//===----------------------------------------------------------------------===//
1123// ClassScopeFunctionSpecializationDecl Implementation
1124//===----------------------------------------------------------------------===//
1125
1126void ClassScopeFunctionSpecializationDecl::anchor() {}
1127
1128ClassScopeFunctionSpecializationDecl *
1129ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
1130                                                         unsigned ID) {
1131  return new (C, ID) ClassScopeFunctionSpecializationDecl(
1132      nullptr, SourceLocation(), nullptr, nullptr);
1133}
1134
1135//===----------------------------------------------------------------------===//
1136// VarTemplateDecl Implementation
1137//===----------------------------------------------------------------------===//
1138
1139VarTemplateDecl *VarTemplateDecl::getDefinition() {
1140  VarTemplateDecl *CurD = this;
1141  while (CurD) {
1142    if (CurD->isThisDeclarationADefinition())
1143      return CurD;
1144    CurD = CurD->getPreviousDecl();
1145  }
1146  return nullptr;
1147}
1148
1149VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
1150                                         SourceLocation L, DeclarationName Name,
1151                                         TemplateParameterList *Params,
1152                                         VarDecl *Decl) {
1153  AdoptTemplateParameterList(Params, DC);
1154  return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1155}
1156
1157VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
1158                                                     unsigned ID) {
1159  return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1160                                     DeclarationName(), nullptr, nullptr);
1161}
1162
1163void VarTemplateDecl::LoadLazySpecializations() const {
1164  loadLazySpecializationsImpl();
1165}
1166
1167llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1168VarTemplateDecl::getSpecializations() const {
1169  LoadLazySpecializations();
1170  return getCommonPtr()->Specializations;
1171}
1172
1173llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1174VarTemplateDecl::getPartialSpecializations() const {
1175  LoadLazySpecializations();
1176  return getCommonPtr()->PartialSpecializations;
1177}
1178
1179RedeclarableTemplateDecl::CommonBase *
1180VarTemplateDecl::newCommon(ASTContext &C) const {
1181  auto *CommonPtr = new (C) Common;
1182  C.addDestruction(CommonPtr);
1183  return CommonPtr;
1184}
1185
1186VarTemplateSpecializationDecl *
1187VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1188                                    void *&InsertPos) {
1189  return findSpecializationImpl(getSpecializations(), InsertPos, Args);
1190}
1191
1192void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1193                                        void *InsertPos) {
1194  addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1195}
1196
1197VarTemplatePartialSpecializationDecl *
1198VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1199     TemplateParameterList *TPL, void *&InsertPos) {
1200  return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1201                                TPL);
1202}
1203
1204void
1205VarTemplatePartialSpecializationDecl::Profile(llvm::FoldingSetNodeID &ID,
1206    ArrayRef<TemplateArgument> TemplateArgs, TemplateParameterList *TPL,
1207    ASTContext &Context) {
1208  ID.AddInteger(TemplateArgs.size());
1209  for (const TemplateArgument &TemplateArg : TemplateArgs)
1210    TemplateArg.Profile(ID, Context);
1211  ProfileTemplateParameterList(Context, ID, TPL);
1212}
1213
1214void VarTemplateDecl::AddPartialSpecialization(
1215    VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1216  if (InsertPos)
1217    getPartialSpecializations().InsertNode(D, InsertPos);
1218  else {
1219    VarTemplatePartialSpecializationDecl *Existing =
1220        getPartialSpecializations().GetOrInsertNode(D);
1221    (void)Existing;
1222    assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1223  }
1224
1225  if (ASTMutationListener *L = getASTMutationListener())
1226    L->AddedCXXTemplateSpecialization(this, D);
1227}
1228
1229void VarTemplateDecl::getPartialSpecializations(
1230    SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const {
1231  llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1232      getPartialSpecializations();
1233  PS.clear();
1234  PS.reserve(PartialSpecs.size());
1235  for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1236    PS.push_back(P.getMostRecentDecl());
1237}
1238
1239VarTemplatePartialSpecializationDecl *
1240VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1241    VarTemplatePartialSpecializationDecl *D) {
1242  Decl *DCanon = D->getCanonicalDecl();
1243  for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1244    if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1245      return P.getMostRecentDecl();
1246  }
1247
1248  return nullptr;
1249}
1250
1251//===----------------------------------------------------------------------===//
1252// VarTemplateSpecializationDecl Implementation
1253//===----------------------------------------------------------------------===//
1254
1255VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1256    Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1257    SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1258    TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1259    : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1260              SpecializedTemplate->getIdentifier(), T, TInfo, S),
1261      SpecializedTemplate(SpecializedTemplate),
1262      TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1263      SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1264
1265VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1266                                                             ASTContext &C)
1267    : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1268              QualType(), nullptr, SC_None),
1269      SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1270
1271VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1272    ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1273    SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1274    TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1275  return new (Context, DC) VarTemplateSpecializationDecl(
1276      VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1277      SpecializedTemplate, T, TInfo, S, Args);
1278}
1279
1280VarTemplateSpecializationDecl *
1281VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1282  return new (C, ID)
1283      VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1284}
1285
1286void VarTemplateSpecializationDecl::getNameForDiagnostic(
1287    raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1288  NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1289
1290  const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1291  if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1292          PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1293    printTemplateArgumentList(
1294        OS, ArgsAsWritten->arguments(), Policy,
1295        getSpecializedTemplate()->getTemplateParameters());
1296  } else {
1297    const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1298    printTemplateArgumentList(
1299        OS, TemplateArgs.asArray(), Policy,
1300        getSpecializedTemplate()->getTemplateParameters());
1301  }
1302}
1303
1304VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1305  if (const auto *PartialSpec =
1306          SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1307    return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1308  return SpecializedTemplate.get<VarTemplateDecl *>();
1309}
1310
1311void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1312    const TemplateArgumentListInfo &ArgsInfo) {
1313  TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1314  TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1315  for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1316    TemplateArgsInfo.addArgument(Loc);
1317}
1318
1319//===----------------------------------------------------------------------===//
1320// VarTemplatePartialSpecializationDecl Implementation
1321//===----------------------------------------------------------------------===//
1322
1323void VarTemplatePartialSpecializationDecl::anchor() {}
1324
1325VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1326    ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1327    SourceLocation IdLoc, TemplateParameterList *Params,
1328    VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1329    StorageClass S, ArrayRef<TemplateArgument> Args,
1330    const ASTTemplateArgumentListInfo *ArgInfos)
1331    : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1332                                    DC, StartLoc, IdLoc, SpecializedTemplate, T,
1333                                    TInfo, S, Args),
1334      TemplateParams(Params), ArgsAsWritten(ArgInfos),
1335      InstantiatedFromMember(nullptr, false) {
1336  // TODO: The template parameters should be in DC by now. Verify.
1337  // AdoptTemplateParameterList(Params, DC);
1338}
1339
1340VarTemplatePartialSpecializationDecl *
1341VarTemplatePartialSpecializationDecl::Create(
1342    ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1343    SourceLocation IdLoc, TemplateParameterList *Params,
1344    VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1345    StorageClass S, ArrayRef<TemplateArgument> Args,
1346    const TemplateArgumentListInfo &ArgInfos) {
1347  const ASTTemplateArgumentListInfo *ASTArgInfos
1348    = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1349
1350  auto *Result =
1351      new (Context, DC) VarTemplatePartialSpecializationDecl(
1352          Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1353          S, Args, ASTArgInfos);
1354  Result->setSpecializationKind(TSK_ExplicitSpecialization);
1355  return Result;
1356}
1357
1358VarTemplatePartialSpecializationDecl *
1359VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1360                                                         unsigned ID) {
1361  return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1362}
1363
1364static TemplateParameterList *
1365createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1366  // typename T
1367  auto *T = TemplateTypeParmDecl::Create(
1368      C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1369      /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1370      /*HasTypeConstraint=*/false);
1371  T->setImplicit(true);
1372
1373  // T ...Ints
1374  TypeSourceInfo *TI =
1375      C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1376  auto *N = NonTypeTemplateParmDecl::Create(
1377      C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1378      /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1379  N->setImplicit(true);
1380
1381  // <typename T, T ...Ints>
1382  NamedDecl *P[2] = {T, N};
1383  auto *TPL = TemplateParameterList::Create(
1384      C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1385
1386  // template <typename T, ...Ints> class IntSeq
1387  auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1388      C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1389      /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1390  TemplateTemplateParm->setImplicit(true);
1391
1392  // typename T
1393  auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1394      C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1395      /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1396      /*HasTypeConstraint=*/false);
1397  TemplateTypeParm->setImplicit(true);
1398
1399  // T N
1400  TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1401      QualType(TemplateTypeParm->getTypeForDecl(), 0));
1402  auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1403      C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1404      /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1405  NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1406                         NonTypeTemplateParm};
1407
1408  // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1409  return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1410                                       Params, SourceLocation(), nullptr);
1411}
1412
1413static TemplateParameterList *
1414createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1415  // std::size_t Index
1416  TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1417  auto *Index = NonTypeTemplateParmDecl::Create(
1418      C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1419      /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1420
1421  // typename ...T
1422  auto *Ts = TemplateTypeParmDecl::Create(
1423      C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1424      /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
1425      /*HasTypeConstraint=*/false);
1426  Ts->setImplicit(true);
1427
1428  // template <std::size_t Index, typename ...T>
1429  NamedDecl *Params[] = {Index, Ts};
1430  return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1431                                       llvm::makeArrayRef(Params),
1432                                       SourceLocation(), nullptr);
1433}
1434
1435static TemplateParameterList *createBuiltinTemplateParameterList(
1436    const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1437  switch (BTK) {
1438  case BTK__make_integer_seq:
1439    return createMakeIntegerSeqParameterList(C, DC);
1440  case BTK__type_pack_element:
1441    return createTypePackElementParameterList(C, DC);
1442  }
1443
1444  llvm_unreachable("unhandled BuiltinTemplateKind!");
1445}
1446
1447void BuiltinTemplateDecl::anchor() {}
1448
1449BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1450                                         DeclarationName Name,
1451                                         BuiltinTemplateKind BTK)
1452    : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1453                   createBuiltinTemplateParameterList(C, DC, BTK)),
1454      BTK(BTK) {}
1455
1456void TypeConstraint::print(llvm::raw_ostream &OS, PrintingPolicy Policy) const {
1457  if (NestedNameSpec)
1458    NestedNameSpec.getNestedNameSpecifier()->print(OS, Policy);
1459  ConceptName.printName(OS, Policy);
1460  if (hasExplicitTemplateArgs()) {
1461    OS << "<";
1462    // FIXME: Find corresponding parameter for argument
1463    for (auto &ArgLoc : ArgsAsWritten->arguments())
1464      ArgLoc.getArgument().print(Policy, OS, /*IncludeType*/ false);
1465    OS << ">";
1466  }
1467}
1468
1469TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1470                                                         QualType T,
1471                                                         const APValue &V) {
1472  DeclContext *DC = C.getTranslationUnitDecl();
1473  auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1474  C.addDestruction(&TPOD->Value);
1475  return TPOD;
1476}
1477
1478TemplateParamObjectDecl *
1479TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1480  auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1481  C.addDestruction(&TPOD->Value);
1482  return TPOD;
1483}
1484
1485void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS) const {
1486  OS << "<template param ";
1487  printAsExpr(OS);
1488  OS << ">";
1489}
1490
1491void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1492  const ASTContext &Ctx = getASTContext();
1493  getType().getUnqualifiedType().print(OS, Ctx.getPrintingPolicy());
1494  printAsInit(OS);
1495}
1496
1497void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1498  const ASTContext &Ctx = getASTContext();
1499  getValue().printPretty(OS, Ctx, getType());
1500}
1501