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