Coverage Report

Created: 2024-01-17 10:31

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