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/ExprCXX.h"
20#include "clang/AST/ExternalASTSource.h"
21#include "clang/AST/ODRHash.h"
22#include "clang/AST/TemplateBase.h"
23#include "clang/AST/TemplateName.h"
24#include "clang/AST/Type.h"
25#include "clang/AST/TypeLoc.h"
26#include "clang/Basic/Builtins.h"
27#include "clang/Basic/LLVM.h"
28#include "clang/Basic/SourceLocation.h"
29#include "llvm/ADT/ArrayRef.h"
30#include "llvm/ADT/FoldingSet.h"
31#include "llvm/ADT/PointerUnion.h"
32#include "llvm/ADT/STLExtras.h"
33#include "llvm/ADT/SmallVector.h"
34#include "llvm/Support/ErrorHandling.h"
35#include <cassert>
36#include <optional>
37#include <utility>
38
39using namespace clang;
40
41//===----------------------------------------------------------------------===//
42// TemplateParameterList Implementation
43//===----------------------------------------------------------------------===//
44
45template <class TemplateParam>
46static bool
47DefaultTemplateArgumentContainsUnexpandedPack(const TemplateParam &P) {
48 return P.hasDefaultArgument() &&
49 P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
50}
51
52TemplateParameterList::TemplateParameterList(const ASTContext &C,
53 SourceLocation TemplateLoc,
54 SourceLocation LAngleLoc,
55 ArrayRef<NamedDecl *> Params,
56 SourceLocation RAngleLoc,
57 Expr *RequiresClause)
58 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
59 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
60 HasRequiresClause(RequiresClause != nullptr),
61 HasConstrainedParameters(false) {
62 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
63 NamedDecl *P = Params[Idx];
64 begin()[Idx] = P;
65
66 bool IsPack = P->isTemplateParameterPack();
67 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Val: P)) {
68 if (!IsPack && (NTTP->getType()->containsUnexpandedParameterPack() ||
69 DefaultTemplateArgumentContainsUnexpandedPack(P: *NTTP)))
70 ContainsUnexpandedParameterPack = true;
71 if (NTTP->hasPlaceholderTypeConstraint())
72 HasConstrainedParameters = true;
73 } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Val: P)) {
74 if (!IsPack &&
75 (TTP->getTemplateParameters()->containsUnexpandedParameterPack() ||
76 DefaultTemplateArgumentContainsUnexpandedPack(P: *TTP))) {
77 ContainsUnexpandedParameterPack = true;
78 }
79 } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Val: P)) {
80 if (!IsPack && DefaultTemplateArgumentContainsUnexpandedPack(P: *TTP)) {
81 ContainsUnexpandedParameterPack = true;
82 } else if (const TypeConstraint *TC = TTP->getTypeConstraint();
83 TC && TC->getImmediatelyDeclaredConstraint()
84 ->containsUnexpandedParameterPack()) {
85 ContainsUnexpandedParameterPack = true;
86 }
87 if (TTP->hasTypeConstraint())
88 HasConstrainedParameters = true;
89 } else {
90 llvm_unreachable("unexpected template parameter type");
91 }
92 }
93
94 if (HasRequiresClause) {
95 if (RequiresClause->containsUnexpandedParameterPack())
96 ContainsUnexpandedParameterPack = true;
97 *getTrailingObjects<Expr *>() = RequiresClause;
98 }
99}
100
101bool TemplateParameterList::containsUnexpandedParameterPack() const {
102 if (ContainsUnexpandedParameterPack)
103 return true;
104 if (!HasConstrainedParameters)
105 return false;
106
107 // An implicit constrained parameter might have had a use of an unexpanded
108 // pack added to it after the template parameter list was created. All
109 // implicit parameters are at the end of the parameter list.
110 for (const NamedDecl *Param : llvm::reverse(C: asArray())) {
111 if (!Param->isImplicit())
112 break;
113
114 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Val: Param)) {
115 const auto *TC = TTP->getTypeConstraint();
116 if (TC && TC->getImmediatelyDeclaredConstraint()
117 ->containsUnexpandedParameterPack())
118 return true;
119 }
120 }
121
122 return false;
123}
124
125TemplateParameterList *
126TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
127 SourceLocation LAngleLoc,
128 ArrayRef<NamedDecl *> Params,
129 SourceLocation RAngleLoc, Expr *RequiresClause) {
130 void *Mem = C.Allocate(Size: totalSizeToAlloc<NamedDecl *, Expr *>(
131 Counts: Params.size(), Counts: RequiresClause ? 1u : 0u),
132 Align: alignof(TemplateParameterList));
133 return new (Mem) TemplateParameterList(C, TemplateLoc, LAngleLoc, Params,
134 RAngleLoc, RequiresClause);
135}
136
137void TemplateParameterList::Profile(llvm::FoldingSetNodeID &ID,
138 const ASTContext &C) const {
139 const Expr *RC = getRequiresClause();
140 ID.AddBoolean(B: RC != nullptr);
141 if (RC)
142 RC->Profile(ID, Context: C, /*Canonical=*/true);
143 ID.AddInteger(I: size());
144 for (NamedDecl *D : *this) {
145 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Val: D)) {
146 ID.AddInteger(I: 0);
147 ID.AddBoolean(B: NTTP->isParameterPack());
148 NTTP->getType().getCanonicalType().Profile(ID);
149 ID.AddBoolean(B: NTTP->hasPlaceholderTypeConstraint());
150 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
151 E->Profile(ID, Context: C, /*Canonical=*/true);
152 continue;
153 }
154 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Val: D)) {
155 ID.AddInteger(I: 1);
156 ID.AddBoolean(B: TTP->isParameterPack());
157 ID.AddBoolean(B: TTP->hasTypeConstraint());
158 if (const TypeConstraint *TC = TTP->getTypeConstraint())
159 TC->getImmediatelyDeclaredConstraint()->Profile(ID, Context: C,
160 /*Canonical=*/true);
161 continue;
162 }
163 const auto *TTP = cast<TemplateTemplateParmDecl>(Val: D);
164 ID.AddInteger(I: 2);
165 ID.AddInteger(I: TTP->templateParameterKind());
166 ID.AddBoolean(B: TTP->isParameterPack());
167 TTP->getTemplateParameters()->Profile(ID, C);
168 }
169}
170
171unsigned TemplateParameterList::getMinRequiredArguments() const {
172 unsigned NumRequiredArgs = 0;
173 for (const NamedDecl *P : asArray()) {
174 if (P->isTemplateParameterPack()) {
175 if (UnsignedOrNone Expansions = getExpandedPackSize(Param: P)) {
176 NumRequiredArgs += *Expansions;
177 continue;
178 }
179 break;
180 }
181
182 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Val: P)) {
183 if (TTP->hasDefaultArgument())
184 break;
185 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Val: P)) {
186 if (NTTP->hasDefaultArgument())
187 break;
188 } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Val: P);
189 TTP && TTP->hasDefaultArgument())
190 break;
191
192 ++NumRequiredArgs;
193 }
194
195 return NumRequiredArgs;
196}
197
198unsigned TemplateParameterList::getDepth() const {
199 if (size() == 0)
200 return 0;
201
202 const NamedDecl *FirstParm = getParam(Idx: 0);
203 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Val: FirstParm))
204 return TTP->getDepth();
205 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Val: FirstParm))
206 return NTTP->getDepth();
207 else
208 return cast<TemplateTemplateParmDecl>(Val: FirstParm)->getDepth();
209}
210
211static bool AdoptTemplateParameterList(TemplateParameterList *Params,
212 DeclContext *Owner) {
213 bool Invalid = false;
214 for (NamedDecl *P : *Params) {
215 P->setDeclContext(Owner);
216
217 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Val: P))
218 if (AdoptTemplateParameterList(Params: TTP->getTemplateParameters(), Owner))
219 Invalid = true;
220
221 if (P->isInvalidDecl())
222 Invalid = true;
223 }
224 return Invalid;
225}
226
227void TemplateParameterList::getAssociatedConstraints(
228 llvm::SmallVectorImpl<AssociatedConstraint> &ACs) const {
229 if (HasConstrainedParameters)
230 for (const NamedDecl *Param : *this) {
231 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Val: Param)) {
232 if (const auto *TC = TTP->getTypeConstraint())
233 ACs.emplace_back(Args: TC->getImmediatelyDeclaredConstraint(),
234 Args: TC->getArgPackSubstIndex());
235 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Val: Param)) {
236 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
237 ACs.emplace_back(Args&: E);
238 }
239 }
240 if (HasRequiresClause)
241 ACs.emplace_back(Args: getRequiresClause());
242}
243
244bool TemplateParameterList::hasAssociatedConstraints() const {
245 return HasRequiresClause || HasConstrainedParameters;
246}
247
248ArrayRef<TemplateArgument>
249TemplateParameterList::getInjectedTemplateArgs(const ASTContext &Context) {
250 if (!InjectedArgs) {
251 InjectedArgs = new (Context) TemplateArgument[size()];
252 llvm::transform(Range&: *this, d_first: InjectedArgs, F: [&](NamedDecl *ND) {
253 return Context.getInjectedTemplateArg(ParamDecl: ND);
254 });
255 }
256 return {InjectedArgs, NumParams};
257}
258
259bool TemplateParameterList::shouldIncludeTypeForArgument(
260 const PrintingPolicy &Policy, const TemplateParameterList *TPL,
261 unsigned Idx) {
262 if (!TPL || Idx >= TPL->size() || Policy.AlwaysIncludeTypeForTemplateArgument)
263 return true;
264 const NamedDecl *TemplParam = TPL->getParam(Idx);
265 if (const auto *ParamValueDecl =
266 dyn_cast<NonTypeTemplateParmDecl>(Val: TemplParam))
267 if (ParamValueDecl->getType()->getContainedDeducedType())
268 return true;
269 return false;
270}
271
272namespace clang {
273
274void *allocateDefaultArgStorageChain(const ASTContext &C) {
275 return new (C) char[sizeof(void*) * 2];
276}
277
278} // namespace clang
279
280//===----------------------------------------------------------------------===//
281// TemplateDecl Implementation
282//===----------------------------------------------------------------------===//
283
284TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
285 DeclarationName Name, TemplateParameterList *Params,
286 NamedDecl *Decl)
287 : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
288
289void TemplateDecl::anchor() {}
290
291void TemplateDecl::getAssociatedConstraints(
292 llvm::SmallVectorImpl<AssociatedConstraint> &ACs) const {
293 TemplateParams->getAssociatedConstraints(ACs);
294 if (auto *FD = dyn_cast_or_null<FunctionDecl>(Val: getTemplatedDecl()))
295 if (const AssociatedConstraint &TRC = FD->getTrailingRequiresClause())
296 ACs.emplace_back(Args: TRC);
297}
298
299bool TemplateDecl::hasAssociatedConstraints() const {
300 if (TemplateParams->hasAssociatedConstraints())
301 return true;
302 if (auto *FD = dyn_cast_or_null<FunctionDecl>(Val: getTemplatedDecl()))
303 return static_cast<bool>(FD->getTrailingRequiresClause());
304 return false;
305}
306
307bool TemplateDecl::isTypeAlias() const {
308 switch (getKind()) {
309 case TemplateDecl::TypeAliasTemplate:
310 return true;
311 case TemplateDecl::BuiltinTemplate:
312 return !cast<BuiltinTemplateDecl>(Val: this)->isPackProducingBuiltinTemplate();
313 default:
314 return false;
315 };
316}
317
318//===----------------------------------------------------------------------===//
319// RedeclarableTemplateDecl Implementation
320//===----------------------------------------------------------------------===//
321
322void RedeclarableTemplateDecl::anchor() {}
323
324RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
325 if (Common)
326 return Common;
327
328 // Walk the previous-declaration chain until we either find a declaration
329 // with a common pointer or we run out of previous declarations.
330 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
331 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
332 Prev = Prev->getPreviousDecl()) {
333 if (Prev->Common) {
334 Common = Prev->Common;
335 break;
336 }
337
338 PrevDecls.push_back(Elt: Prev);
339 }
340
341 // If we never found a common pointer, allocate one now.
342 if (!Common) {
343 // FIXME: If any of the declarations is from an AST file, we probably
344 // need an update record to add the common data.
345
346 Common = newCommon(C&: getASTContext());
347 }
348
349 // Update any previous declarations we saw with the common pointer.
350 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
351 Prev->Common = Common;
352
353 return Common;
354}
355
356void RedeclarableTemplateDecl::loadLazySpecializationsImpl(
357 bool OnlyPartial /*=false*/) const {
358 auto *ExternalSource = getASTContext().getExternalSource();
359 if (!ExternalSource)
360 return;
361
362 ExternalSource->LoadExternalSpecializations(D: this->getCanonicalDecl(),
363 OnlyPartial);
364}
365
366bool RedeclarableTemplateDecl::loadLazySpecializationsImpl(
367 ArrayRef<TemplateArgument> Args, TemplateParameterList *TPL) const {
368 auto *ExternalSource = getASTContext().getExternalSource();
369 if (!ExternalSource)
370 return false;
371
372 return ExternalSource->LoadExternalSpecializations(D: this->getCanonicalDecl(),
373 TemplateArgs: Args);
374}
375
376template <class EntryType, typename... ProfileArguments>
377typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
378RedeclarableTemplateDecl::findSpecializationLocally(
379 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
380 ProfileArguments... ProfileArgs) {
381 using SETraits = RedeclarableTemplateDecl::SpecEntryTraits<EntryType>;
382
383 llvm::FoldingSetNodeID ID;
384 EntryType::Profile(ID, ProfileArgs..., getASTContext());
385 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
386 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
387}
388
389template <class EntryType, typename... ProfileArguments>
390typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
391RedeclarableTemplateDecl::findSpecializationImpl(
392 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
393 ProfileArguments... ProfileArgs) {
394
395 if (auto *Found = findSpecializationLocally(Specs, InsertPos, ProfileArgs...))
396 return Found;
397
398 if (!loadLazySpecializationsImpl(ProfileArgs...))
399 return nullptr;
400
401 return findSpecializationLocally(Specs, InsertPos, ProfileArgs...);
402}
403
404template<class Derived, class EntryType>
405void RedeclarableTemplateDecl::addSpecializationImpl(
406 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
407 void *InsertPos) {
408 using SETraits = SpecEntryTraits<EntryType>;
409
410 if (InsertPos) {
411#ifndef NDEBUG
412 auto Args = SETraits::getTemplateArgs(Entry);
413 // Due to hash collisions, it can happen that we load another template
414 // specialization with the same hash. This is fine, as long as the next
415 // call to findSpecializationImpl does not find a matching Decl for the
416 // template arguments.
417 loadLazySpecializationsImpl(Args);
418 void *CorrectInsertPos;
419 assert(!findSpecializationImpl(Specializations, CorrectInsertPos, Args) &&
420 InsertPos == CorrectInsertPos &&
421 "given incorrect InsertPos for specialization");
422#endif
423 Specializations.InsertNode(Entry, InsertPos);
424 } else {
425 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
426 (void)Existing;
427 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
428 "non-canonical specialization?");
429 }
430
431 if (ASTMutationListener *L = getASTMutationListener())
432 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
433 SETraits::getDecl(Entry));
434}
435
436//===----------------------------------------------------------------------===//
437// FunctionTemplateDecl Implementation
438//===----------------------------------------------------------------------===//
439
440FunctionTemplateDecl *
441FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
442 DeclarationName Name,
443 TemplateParameterList *Params, NamedDecl *Decl) {
444 assert(!Params->empty() && "template with no template parameters");
445 bool Invalid = AdoptTemplateParameterList(Params, Owner: cast<DeclContext>(Val: Decl));
446 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
447 if (Invalid)
448 TD->setInvalidDecl();
449 return TD;
450}
451
452FunctionTemplateDecl *
453FunctionTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
454 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
455 DeclarationName(), nullptr, nullptr);
456}
457
458RedeclarableTemplateDecl::CommonBase *
459FunctionTemplateDecl::newCommon(ASTContext &C) const {
460 auto *CommonPtr = new (C) Common;
461 C.addDestruction(Ptr: CommonPtr);
462 return CommonPtr;
463}
464
465void FunctionTemplateDecl::LoadLazySpecializations() const {
466 loadLazySpecializationsImpl();
467}
468
469llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
470FunctionTemplateDecl::getSpecializations() const {
471 LoadLazySpecializations();
472 return getCommonPtr()->Specializations;
473}
474
475FunctionDecl *
476FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
477 void *&InsertPos) {
478 auto *Common = getCommonPtr();
479 return findSpecializationImpl(Specs&: Common->Specializations, InsertPos, ProfileArgs: Args);
480}
481
482void FunctionTemplateDecl::addSpecialization(
483 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
484 auto *Common = getCommonPtr();
485 addSpecializationImpl<FunctionTemplateDecl>(Specializations&: Common->Specializations, Entry: Info,
486 InsertPos);
487}
488
489void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
490 using Base = RedeclarableTemplateDecl;
491
492 // If we haven't created a common pointer yet, then it can just be created
493 // with the usual method.
494 if (!Base::Common)
495 return;
496
497 Common *ThisCommon = static_cast<Common *>(Base::Common);
498 Common *PrevCommon = nullptr;
499 SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
500 for (; Prev; Prev = Prev->getPreviousDecl()) {
501 if (Prev->Base::Common) {
502 PrevCommon = static_cast<Common *>(Prev->Base::Common);
503 break;
504 }
505 PreviousDecls.push_back(Elt: Prev);
506 }
507
508 // If the previous redecl chain hasn't created a common pointer yet, then just
509 // use this common pointer.
510 if (!PrevCommon) {
511 for (auto *D : PreviousDecls)
512 D->Base::Common = ThisCommon;
513 return;
514 }
515
516 // Ensure we don't leak any important state.
517 assert(ThisCommon->Specializations.size() == 0 &&
518 "Can't merge incompatible declarations!");
519
520 Base::Common = PrevCommon;
521}
522
523//===----------------------------------------------------------------------===//
524// ClassTemplateDecl Implementation
525//===----------------------------------------------------------------------===//
526
527ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC,
528 SourceLocation L,
529 DeclarationName Name,
530 TemplateParameterList *Params,
531 NamedDecl *Decl) {
532 assert(!Params->empty() && "template with no template parameters");
533 bool Invalid = AdoptTemplateParameterList(Params, Owner: cast<DeclContext>(Val: Decl));
534 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
535 if (Invalid)
536 TD->setInvalidDecl();
537 return TD;
538}
539
540ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
541 GlobalDeclID ID) {
542 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
543 DeclarationName(), nullptr, nullptr);
544}
545
546void ClassTemplateDecl::LoadLazySpecializations(
547 bool OnlyPartial /*=false*/) const {
548 loadLazySpecializationsImpl(OnlyPartial);
549}
550
551llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
552ClassTemplateDecl::getSpecializations() const {
553 LoadLazySpecializations();
554 return getCommonPtr()->Specializations;
555}
556
557llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
558ClassTemplateDecl::getPartialSpecializations() const {
559 LoadLazySpecializations(/*PartialOnly = */ OnlyPartial: true);
560 return getCommonPtr()->PartialSpecializations;
561}
562
563RedeclarableTemplateDecl::CommonBase *
564ClassTemplateDecl::newCommon(ASTContext &C) const {
565 auto *CommonPtr = new (C) Common;
566 C.addDestruction(Ptr: CommonPtr);
567 return CommonPtr;
568}
569
570ClassTemplateSpecializationDecl *
571ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
572 void *&InsertPos) {
573 auto *Common = getCommonPtr();
574 return findSpecializationImpl(Specs&: Common->Specializations, InsertPos, ProfileArgs: Args);
575}
576
577void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
578 void *InsertPos) {
579 auto *Common = getCommonPtr();
580 addSpecializationImpl<ClassTemplateDecl>(Specializations&: Common->Specializations, Entry: D,
581 InsertPos);
582}
583
584ClassTemplatePartialSpecializationDecl *
585ClassTemplateDecl::findPartialSpecialization(
586 ArrayRef<TemplateArgument> Args,
587 TemplateParameterList *TPL, void *&InsertPos) {
588 return findSpecializationImpl(Specs&: getPartialSpecializations(), InsertPos, ProfileArgs: Args,
589 ProfileArgs: TPL);
590}
591
592void ClassTemplatePartialSpecializationDecl::Profile(
593 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
594 TemplateParameterList *TPL, const ASTContext &Context) {
595 ID.AddInteger(I: TemplateArgs.size());
596 for (const TemplateArgument &TemplateArg : TemplateArgs)
597 TemplateArg.Profile(ID, Context);
598 TPL->Profile(ID, C: Context);
599}
600
601void ClassTemplateDecl::AddPartialSpecialization(
602 ClassTemplatePartialSpecializationDecl *D,
603 void *InsertPos) {
604 if (InsertPos)
605 getPartialSpecializations().InsertNode(N: D, InsertPos);
606 else {
607 ClassTemplatePartialSpecializationDecl *Existing
608 = getPartialSpecializations().GetOrInsertNode(N: D);
609 (void)Existing;
610 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
611 }
612
613 if (ASTMutationListener *L = getASTMutationListener())
614 L->AddedCXXTemplateSpecialization(TD: this, D);
615}
616
617void ClassTemplateDecl::getPartialSpecializations(
618 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) const {
619 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
620 = getPartialSpecializations();
621 PS.clear();
622 PS.reserve(N: PartialSpecs.size());
623 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
624 PS.push_back(Elt: P.getMostRecentDecl());
625}
626
627ClassTemplatePartialSpecializationDecl *
628ClassTemplateDecl::findPartialSpecialization(QualType T) {
629 ASTContext &Context = getASTContext();
630 for (ClassTemplatePartialSpecializationDecl &P :
631 getPartialSpecializations()) {
632 if (Context.hasSameType(T1: P.getCanonicalInjectedSpecializationType(Ctx: Context),
633 T2: T))
634 return P.getMostRecentDecl();
635 }
636
637 return nullptr;
638}
639
640ClassTemplatePartialSpecializationDecl *
641ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
642 ClassTemplatePartialSpecializationDecl *D) {
643 Decl *DCanon = D->getCanonicalDecl();
644 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
645 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
646 return P.getMostRecentDecl();
647 }
648
649 return nullptr;
650}
651
652CanQualType ClassTemplateDecl::getCanonicalInjectedSpecializationType(
653 const ASTContext &Ctx) const {
654 Common *CommonPtr = getCommonPtr();
655
656 if (CommonPtr->CanonInjectedTST.isNull()) {
657 SmallVector<TemplateArgument> CanonicalArgs(
658 getTemplateParameters()->getInjectedTemplateArgs(Context: Ctx));
659 Ctx.canonicalizeTemplateArguments(Args: CanonicalArgs);
660 CommonPtr->CanonInjectedTST =
661 CanQualType::CreateUnsafe(Other: Ctx.getCanonicalTemplateSpecializationType(
662 Keyword: ElaboratedTypeKeyword::None,
663 T: TemplateName(const_cast<ClassTemplateDecl *>(getCanonicalDecl())),
664 CanonicalArgs));
665 }
666 return CommonPtr->CanonInjectedTST;
667}
668
669//===----------------------------------------------------------------------===//
670// TemplateTypeParm Allocation/Deallocation Method Implementations
671//===----------------------------------------------------------------------===//
672
673TemplateTypeParmDecl *TemplateTypeParmDecl::Create(
674 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
675 SourceLocation NameLoc, int D, int P, IdentifierInfo *Id, bool Typename,
676 bool ParameterPack, bool HasTypeConstraint, UnsignedOrNone NumExpanded) {
677 auto *TTPDecl =
678 new (C, DC,
679 additionalSizeToAlloc<TypeConstraint>(Counts: HasTypeConstraint ? 1 : 0))
680 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
681 HasTypeConstraint, NumExpanded);
682 QualType TTPType = C.getTemplateTypeParmType(Depth: D, Index: P, ParameterPack, ParmDecl: TTPDecl);
683 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
684 return TTPDecl;
685}
686
687TemplateTypeParmDecl *
688TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID) {
689 return new (C, ID)
690 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
691 false, false, std::nullopt);
692}
693
694TemplateTypeParmDecl *
695TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID,
696 bool HasTypeConstraint) {
697 return new (C, ID,
698 additionalSizeToAlloc<TypeConstraint>(Counts: HasTypeConstraint ? 1 : 0))
699 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
700 false, HasTypeConstraint, std::nullopt);
701}
702
703SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
704 return hasDefaultArgument() ? getDefaultArgument().getLocation()
705 : SourceLocation();
706}
707
708SourceRange TemplateTypeParmDecl::getSourceRange() const {
709 if (hasDefaultArgument() && !defaultArgumentWasInherited())
710 return SourceRange(getBeginLoc(),
711 getDefaultArgument().getSourceRange().getEnd());
712 // TypeDecl::getSourceRange returns a range containing name location, which is
713 // wrong for unnamed template parameters. e.g:
714 // it will return <[[typename>]] instead of <[[typename]]>
715 if (getDeclName().isEmpty())
716 return SourceRange(getBeginLoc());
717 return TypeDecl::getSourceRange();
718}
719
720void TemplateTypeParmDecl::setDefaultArgument(
721 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
722 if (DefArg.getArgument().isNull())
723 DefaultArgument.set(nullptr);
724 else
725 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
726}
727
728unsigned TemplateTypeParmDecl::getDepth() const {
729 return dyn_cast<TemplateTypeParmType>(Val: getTypeForDecl())->getDepth();
730}
731
732unsigned TemplateTypeParmDecl::getIndex() const {
733 return dyn_cast<TemplateTypeParmType>(Val: getTypeForDecl())->getIndex();
734}
735
736bool TemplateTypeParmDecl::isParameterPack() const {
737 return dyn_cast<TemplateTypeParmType>(Val: getTypeForDecl())->isParameterPack();
738}
739
740void TemplateTypeParmDecl::setTypeConstraint(
741 ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint,
742 UnsignedOrNone ArgPackSubstIndex) {
743 assert(HasTypeConstraint &&
744 "HasTypeConstraint=true must be passed at construction in order to "
745 "call setTypeConstraint");
746 assert(!TypeConstraintInitialized &&
747 "TypeConstraint was already initialized!");
748 new (getTrailingObjects())
749 TypeConstraint(Loc, ImmediatelyDeclaredConstraint, ArgPackSubstIndex);
750 TypeConstraintInitialized = true;
751}
752
753//===----------------------------------------------------------------------===//
754// NonTypeTemplateParmDecl Method Implementations
755//===----------------------------------------------------------------------===//
756
757NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
758 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, int D,
759 int P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
760 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
761 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
762 TemplateParmPosition(D, P), ParameterPack(true),
763 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
764 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
765 auto TypesAndInfos =
766 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
767 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
768 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
769 TypesAndInfos[I].second = ExpandedTInfos[I];
770 }
771 }
772}
773
774NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
775 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
776 SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id, QualType T,
777 bool ParameterPack, TypeSourceInfo *TInfo) {
778 AutoType *AT =
779 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
780 const bool HasConstraint = AT && AT->isConstrained();
781 auto *NTTP =
782 new (C, DC,
783 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
784 Counts: 0, Counts: HasConstraint ? 1 : 0))
785 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T,
786 ParameterPack, TInfo);
787 if (HasConstraint)
788 NTTP->setPlaceholderTypeConstraint(nullptr);
789 return NTTP;
790}
791
792NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
793 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
794 SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id, QualType T,
795 TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
796 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
797 AutoType *AT = TInfo->getType()->getContainedAutoType();
798 const bool HasConstraint = AT && AT->isConstrained();
799 auto *NTTP =
800 new (C, DC,
801 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
802 Counts: ExpandedTypes.size(), Counts: HasConstraint ? 1 : 0))
803 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
804 ExpandedTypes, ExpandedTInfos);
805 if (HasConstraint)
806 NTTP->setPlaceholderTypeConstraint(nullptr);
807 return NTTP;
808}
809
810NonTypeTemplateParmDecl *
811NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,
812 bool HasTypeConstraint) {
813 auto *NTTP =
814 new (C, ID,
815 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
816 Counts: 0, Counts: HasTypeConstraint ? 1 : 0))
817 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
818 0, 0, nullptr, QualType(), false, nullptr);
819 if (HasTypeConstraint)
820 NTTP->setPlaceholderTypeConstraint(nullptr);
821 return NTTP;
822}
823
824NonTypeTemplateParmDecl *
825NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,
826 unsigned NumExpandedTypes,
827 bool HasTypeConstraint) {
828 auto *NTTP =
829 new (C, ID,
830 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
831 Counts: NumExpandedTypes, Counts: HasTypeConstraint ? 1 : 0))
832 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
833 0, 0, nullptr, QualType(), nullptr, {}, {});
834 NTTP->NumExpandedTypes = NumExpandedTypes;
835 if (HasTypeConstraint)
836 NTTP->setPlaceholderTypeConstraint(nullptr);
837 return NTTP;
838}
839
840SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
841 if (hasDefaultArgument() && !defaultArgumentWasInherited())
842 return SourceRange(getOuterLocStart(),
843 getDefaultArgument().getSourceRange().getEnd());
844 return DeclaratorDecl::getSourceRange();
845}
846
847SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
848 return hasDefaultArgument() ? getDefaultArgument().getSourceRange().getBegin()
849 : SourceLocation();
850}
851
852void NonTypeTemplateParmDecl::setDefaultArgument(
853 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
854 if (DefArg.getArgument().isNull())
855 DefaultArgument.set(nullptr);
856 else
857 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
858}
859
860//===----------------------------------------------------------------------===//
861// TemplateTemplateParmDecl Method Implementations
862//===----------------------------------------------------------------------===//
863
864void TemplateTemplateParmDecl::anchor() {}
865
866TemplateTemplateParmDecl::TemplateTemplateParmDecl(
867 DeclContext *DC, SourceLocation L, int D, int P, IdentifierInfo *Id,
868 TemplateNameKind Kind, bool Typename, TemplateParameterList *Params,
869 ArrayRef<TemplateParameterList *> Expansions)
870 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
871 TemplateParmPosition(D, P), ParameterKind(Kind), Typename(Typename),
872 ParameterPack(true), ExpandedParameterPack(true),
873 NumExpandedParams(Expansions.size()) {
874 llvm::uninitialized_copy(Src&: Expansions, Dst: getTrailingObjects());
875}
876
877TemplateTemplateParmDecl *TemplateTemplateParmDecl::Create(
878 const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P,
879 bool ParameterPack, IdentifierInfo *Id, TemplateNameKind Kind,
880 bool Typename, TemplateParameterList *Params) {
881 assert(!Params->empty() && "template with no template parameters");
882 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
883 Kind, Typename, Params);
884}
885
886TemplateTemplateParmDecl *
887TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
888 SourceLocation L, int D, int P,
889 IdentifierInfo *Id, TemplateNameKind Kind,
890 bool Typename, TemplateParameterList *Params,
891 ArrayRef<TemplateParameterList *> Expansions) {
892 assert(!Params->empty() && "template with no template parameters");
893 return new (C, DC,
894 additionalSizeToAlloc<TemplateParameterList *>(Counts: Expansions.size()))
895 TemplateTemplateParmDecl(DC, L, D, P, Id, Kind, Typename, Params,
896 Expansions);
897}
898
899TemplateTemplateParmDecl *
900TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
901 return new (C, ID) TemplateTemplateParmDecl(
902 nullptr, SourceLocation(), 0, 0, false, nullptr,
903 TemplateNameKind::TNK_Type_template, false, nullptr);
904}
905
906TemplateTemplateParmDecl *
907TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,
908 unsigned NumExpansions) {
909 auto *TTP =
910 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(Counts: NumExpansions))
911 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
912 TemplateNameKind::TNK_Type_template, false,
913 nullptr, {});
914 TTP->NumExpandedParams = NumExpansions;
915 return TTP;
916}
917
918SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
919 return hasDefaultArgument() ? getDefaultArgument().getLocation()
920 : SourceLocation();
921}
922
923void TemplateTemplateParmDecl::setDefaultArgument(
924 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
925 if (DefArg.getArgument().isNull())
926 DefaultArgument.set(nullptr);
927 else
928 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
929}
930
931//===----------------------------------------------------------------------===//
932// TemplateArgumentList Implementation
933//===----------------------------------------------------------------------===//
934TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
935 : NumArguments(Args.size()) {
936 llvm::uninitialized_copy(Src&: Args, Dst: getTrailingObjects());
937}
938
939TemplateArgumentList *
940TemplateArgumentList::CreateCopy(ASTContext &Context,
941 ArrayRef<TemplateArgument> Args) {
942 void *Mem = Context.Allocate(Size: totalSizeToAlloc<TemplateArgument>(Counts: Args.size()));
943 return new (Mem) TemplateArgumentList(Args);
944}
945
946FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
947 ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
948 TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs,
949 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
950 MemberSpecializationInfo *MSInfo) {
951 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
952 if (TemplateArgsAsWritten)
953 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
954 List: *TemplateArgsAsWritten);
955
956 void *Mem =
957 C.Allocate(Size: totalSizeToAlloc<MemberSpecializationInfo *>(Counts: MSInfo ? 1 : 0));
958 return new (Mem) FunctionTemplateSpecializationInfo(
959 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
960}
961
962//===----------------------------------------------------------------------===//
963// ClassTemplateSpecializationDecl Implementation
964//===----------------------------------------------------------------------===//
965
966ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(
967 ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC,
968 SourceLocation StartLoc, SourceLocation IdLoc,
969 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
970 bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)
971 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
972 SpecializedTemplate->getIdentifier(), PrevDecl),
973 SpecializedTemplate(SpecializedTemplate),
974 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
975 SpecializationKind(TSK_Undeclared), StrictPackMatch(StrictPackMatch) {
976 assert(DK == Kind::ClassTemplateSpecialization || StrictPackMatch == false);
977}
978
979ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
980 Kind DK)
981 : CXXRecordDecl(DK, TagTypeKind::Struct, C, nullptr, SourceLocation(),
982 SourceLocation(), nullptr, nullptr),
983 SpecializationKind(TSK_Undeclared) {}
984
985ClassTemplateSpecializationDecl *ClassTemplateSpecializationDecl::Create(
986 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
987 SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate,
988 ArrayRef<TemplateArgument> Args, bool StrictPackMatch,
989 ClassTemplateSpecializationDecl *PrevDecl) {
990 auto *Result = new (Context, DC) ClassTemplateSpecializationDecl(
991 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
992 SpecializedTemplate, Args, StrictPackMatch, PrevDecl);
993
994 // If the template decl is incomplete, copy the external lexical storage from
995 // the base template. This allows instantiations of incomplete types to
996 // complete using the external AST if the template's declaration came from an
997 // external AST.
998 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
999 Result->setHasExternalLexicalStorage(
1000 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
1001
1002 return Result;
1003}
1004
1005ClassTemplateSpecializationDecl *
1006ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
1007 GlobalDeclID ID) {
1008 return new (C, ID)
1009 ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
1010}
1011
1012void ClassTemplateSpecializationDecl::getNameForDiagnostic(
1013 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1014 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1015
1016 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(Val: this);
1017 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1018 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1019 printTemplateArgumentList(
1020 OS, Args: ArgsAsWritten->arguments(), Policy,
1021 TPL: getSpecializedTemplate()->getTemplateParameters());
1022 } else {
1023 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1024 printTemplateArgumentList(
1025 OS, Args: TemplateArgs.asArray(), Policy,
1026 TPL: getSpecializedTemplate()->getTemplateParameters());
1027 }
1028}
1029
1030ClassTemplateDecl *
1031ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
1032 if (const auto *PartialSpec =
1033 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
1034 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1035 return cast<ClassTemplateDecl *>(Val: SpecializedTemplate);
1036}
1037
1038SourceRange
1039ClassTemplateSpecializationDecl::getSourceRange() const {
1040 switch (getSpecializationKind()) {
1041 case TSK_Undeclared:
1042 case TSK_ImplicitInstantiation: {
1043 llvm::PointerUnion<ClassTemplateDecl *,
1044 ClassTemplatePartialSpecializationDecl *>
1045 Pattern = getSpecializedTemplateOrPartial();
1046 assert(!Pattern.isNull() &&
1047 "Class template specialization without pattern?");
1048 if (const auto *CTPSD =
1049 dyn_cast<ClassTemplatePartialSpecializationDecl *>(Val&: Pattern))
1050 return CTPSD->getSourceRange();
1051 return cast<ClassTemplateDecl *>(Val&: Pattern)->getSourceRange();
1052 }
1053 case TSK_ExplicitSpecialization: {
1054 SourceRange Range = CXXRecordDecl::getSourceRange();
1055 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten();
1056 !isThisDeclarationADefinition() && Args)
1057 Range.setEnd(Args->getRAngleLoc());
1058 return Range;
1059 }
1060 case TSK_ExplicitInstantiationDeclaration:
1061 case TSK_ExplicitInstantiationDefinition: {
1062 SourceRange Range = CXXRecordDecl::getSourceRange();
1063 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1064 Range.setBegin(ExternKW);
1065 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1066 TemplateKW.isValid())
1067 Range.setBegin(TemplateKW);
1068 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten())
1069 Range.setEnd(Args->getRAngleLoc());
1070 return Range;
1071 }
1072 }
1073 llvm_unreachable("unhandled template specialization kind");
1074}
1075
1076void ClassTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) {
1077 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(Val&: ExplicitInfo);
1078 if (!Info) {
1079 // Don't allocate if the location is invalid.
1080 if (Loc.isInvalid())
1081 return;
1082 Info = new (getASTContext()) ExplicitInstantiationInfo;
1083 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
1084 ExplicitInfo = Info;
1085 }
1086 Info->ExternKeywordLoc = Loc;
1087}
1088
1089void ClassTemplateSpecializationDecl::setTemplateKeywordLoc(
1090 SourceLocation Loc) {
1091 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(Val&: ExplicitInfo);
1092 if (!Info) {
1093 // Don't allocate if the location is invalid.
1094 if (Loc.isInvalid())
1095 return;
1096 Info = new (getASTContext()) ExplicitInstantiationInfo;
1097 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
1098 ExplicitInfo = Info;
1099 }
1100 Info->TemplateKeywordLoc = Loc;
1101}
1102
1103//===----------------------------------------------------------------------===//
1104// ConceptDecl Implementation
1105//===----------------------------------------------------------------------===//
1106ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
1107 SourceLocation L, DeclarationName Name,
1108 TemplateParameterList *Params,
1109 Expr *ConstraintExpr) {
1110 assert(!Params->empty() && "template with no template parameters");
1111 bool Invalid = AdoptTemplateParameterList(Params, Owner: DC);
1112 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1113 if (Invalid)
1114 TD->setInvalidDecl();
1115 return TD;
1116}
1117
1118ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1119 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1120 DeclarationName(),
1121 nullptr, nullptr);
1122
1123 return Result;
1124}
1125
1126//===----------------------------------------------------------------------===//
1127// ImplicitConceptSpecializationDecl Implementation
1128//===----------------------------------------------------------------------===//
1129ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1130 DeclContext *DC, SourceLocation SL,
1131 ArrayRef<TemplateArgument> ConvertedArgs)
1132 : Decl(ImplicitConceptSpecialization, DC, SL),
1133 NumTemplateArgs(ConvertedArgs.size()) {
1134 setTemplateArguments(ConvertedArgs);
1135}
1136
1137ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1138 EmptyShell Empty, unsigned NumTemplateArgs)
1139 : Decl(ImplicitConceptSpecialization, Empty),
1140 NumTemplateArgs(NumTemplateArgs) {}
1141
1142ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create(
1143 const ASTContext &C, DeclContext *DC, SourceLocation SL,
1144 ArrayRef<TemplateArgument> ConvertedArgs) {
1145 return new (C, DC,
1146 additionalSizeToAlloc<TemplateArgument>(Counts: ConvertedArgs.size()))
1147 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1148}
1149
1150ImplicitConceptSpecializationDecl *
1151ImplicitConceptSpecializationDecl::CreateDeserialized(
1152 const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) {
1153 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(Counts: NumTemplateArgs))
1154 ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);
1155}
1156
1157void ImplicitConceptSpecializationDecl::setTemplateArguments(
1158 ArrayRef<TemplateArgument> Converted) {
1159 assert(Converted.size() == NumTemplateArgs);
1160 llvm::uninitialized_copy(Src&: Converted, Dst: getTrailingObjects());
1161}
1162
1163//===----------------------------------------------------------------------===//
1164// ClassTemplatePartialSpecializationDecl Implementation
1165//===----------------------------------------------------------------------===//
1166void ClassTemplatePartialSpecializationDecl::anchor() {}
1167
1168ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
1169 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1170 SourceLocation IdLoc, TemplateParameterList *Params,
1171 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1172 CanQualType CanonInjectedTST,
1173 ClassTemplatePartialSpecializationDecl *PrevDecl)
1174 : ClassTemplateSpecializationDecl(
1175 Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
1176 // Tracking StrictPackMatch for Partial
1177 // Specializations is not needed.
1178 SpecializedTemplate, Args, /*StrictPackMatch=*/false, PrevDecl),
1179 TemplateParams(Params), InstantiatedFromMember(nullptr, false),
1180 CanonInjectedTST(CanonInjectedTST) {
1181 if (AdoptTemplateParameterList(Params, Owner: this))
1182 setInvalidDecl();
1183}
1184
1185ClassTemplatePartialSpecializationDecl *
1186ClassTemplatePartialSpecializationDecl::Create(
1187 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1188 SourceLocation IdLoc, TemplateParameterList *Params,
1189 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1190 CanQualType CanonInjectedTST,
1191 ClassTemplatePartialSpecializationDecl *PrevDecl) {
1192 assert(!Params->empty() && "template with no template parameters");
1193 auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl(
1194 Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args,
1195 CanonInjectedTST, PrevDecl);
1196 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1197 return Result;
1198}
1199
1200ClassTemplatePartialSpecializationDecl *
1201ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1202 GlobalDeclID ID) {
1203 return new (C, ID) ClassTemplatePartialSpecializationDecl(C);
1204}
1205
1206CanQualType
1207ClassTemplatePartialSpecializationDecl::getCanonicalInjectedSpecializationType(
1208 const ASTContext &Ctx) const {
1209 if (CanonInjectedTST.isNull()) {
1210 CanonInjectedTST =
1211 CanQualType::CreateUnsafe(Other: Ctx.getCanonicalTemplateSpecializationType(
1212 Keyword: ElaboratedTypeKeyword::None,
1213 T: TemplateName(getSpecializedTemplate()->getCanonicalDecl()),
1214 CanonicalArgs: getTemplateArgs().asArray()));
1215 }
1216 return CanonInjectedTST;
1217}
1218
1219SourceRange ClassTemplatePartialSpecializationDecl::getSourceRange() const {
1220 if (const ClassTemplatePartialSpecializationDecl *MT =
1221 getInstantiatedFromMember();
1222 MT && !isMemberSpecialization())
1223 return MT->getSourceRange();
1224 SourceRange Range = ClassTemplateSpecializationDecl::getSourceRange();
1225 if (const TemplateParameterList *TPL = getTemplateParameters();
1226 TPL && getTemplateParameterLists().empty())
1227 Range.setBegin(TPL->getTemplateLoc());
1228 return Range;
1229}
1230
1231//===----------------------------------------------------------------------===//
1232// FriendTemplateDecl Implementation
1233//===----------------------------------------------------------------------===//
1234
1235void FriendTemplateDecl::anchor() {}
1236
1237FriendTemplateDecl *
1238FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
1239 SourceLocation L,
1240 MutableArrayRef<TemplateParameterList *> Params,
1241 FriendUnion Friend, SourceLocation FLoc) {
1242 TemplateParameterList **TPL = nullptr;
1243 if (!Params.empty()) {
1244 TPL = new (Context) TemplateParameterList *[Params.size()];
1245 llvm::copy(Range&: Params, Out: TPL);
1246 }
1247 return new (Context, DC)
1248 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
1249}
1250
1251FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
1252 GlobalDeclID ID) {
1253 return new (C, ID) FriendTemplateDecl(EmptyShell());
1254}
1255
1256//===----------------------------------------------------------------------===//
1257// TypeAliasTemplateDecl Implementation
1258//===----------------------------------------------------------------------===//
1259
1260TypeAliasTemplateDecl *
1261TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
1262 DeclarationName Name,
1263 TemplateParameterList *Params, NamedDecl *Decl) {
1264 assert(!Params->empty() && "template with no template parameters");
1265 bool Invalid = AdoptTemplateParameterList(Params, Owner: DC);
1266 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1267 if (Invalid)
1268 TD->setInvalidDecl();
1269 return TD;
1270}
1271
1272TypeAliasTemplateDecl *
1273TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1274 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1275 DeclarationName(), nullptr, nullptr);
1276}
1277
1278RedeclarableTemplateDecl::CommonBase *
1279TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
1280 auto *CommonPtr = new (C) Common;
1281 C.addDestruction(Ptr: CommonPtr);
1282 return CommonPtr;
1283}
1284
1285//===----------------------------------------------------------------------===//
1286// VarTemplateDecl Implementation
1287//===----------------------------------------------------------------------===//
1288
1289VarTemplateDecl *VarTemplateDecl::getDefinition() {
1290 VarTemplateDecl *CurD = this;
1291 while (CurD) {
1292 if (CurD->isThisDeclarationADefinition())
1293 return CurD;
1294 CurD = CurD->getPreviousDecl();
1295 }
1296 return nullptr;
1297}
1298
1299VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
1300 SourceLocation L, DeclarationName Name,
1301 TemplateParameterList *Params,
1302 VarDecl *Decl) {
1303 assert(!Params->empty() && "template with no template parameters");
1304 bool Invalid = AdoptTemplateParameterList(Params, Owner: DC);
1305 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1306 if (Invalid)
1307 TD->setInvalidDecl();
1308 return TD;
1309}
1310
1311VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
1312 GlobalDeclID ID) {
1313 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1314 DeclarationName(), nullptr, nullptr);
1315}
1316
1317void VarTemplateDecl::LoadLazySpecializations(
1318 bool OnlyPartial /*=false*/) const {
1319 loadLazySpecializationsImpl(OnlyPartial);
1320}
1321
1322llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1323VarTemplateDecl::getSpecializations() const {
1324 LoadLazySpecializations();
1325 return getCommonPtr()->Specializations;
1326}
1327
1328llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1329VarTemplateDecl::getPartialSpecializations() const {
1330 LoadLazySpecializations(/*PartialOnly = */ OnlyPartial: true);
1331 return getCommonPtr()->PartialSpecializations;
1332}
1333
1334RedeclarableTemplateDecl::CommonBase *
1335VarTemplateDecl::newCommon(ASTContext &C) const {
1336 auto *CommonPtr = new (C) Common;
1337 C.addDestruction(Ptr: CommonPtr);
1338 return CommonPtr;
1339}
1340
1341VarTemplateSpecializationDecl *
1342VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1343 void *&InsertPos) {
1344 auto *Common = getCommonPtr();
1345 return findSpecializationImpl(Specs&: Common->Specializations, InsertPos, ProfileArgs: Args);
1346}
1347
1348void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1349 void *InsertPos) {
1350 auto *Common = getCommonPtr();
1351 addSpecializationImpl<VarTemplateDecl>(Specializations&: Common->Specializations, Entry: D, InsertPos);
1352}
1353
1354VarTemplatePartialSpecializationDecl *
1355VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1356 TemplateParameterList *TPL, void *&InsertPos) {
1357 return findSpecializationImpl(Specs&: getPartialSpecializations(), InsertPos, ProfileArgs: Args,
1358 ProfileArgs: TPL);
1359}
1360
1361void VarTemplatePartialSpecializationDecl::Profile(
1362 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1363 TemplateParameterList *TPL, const ASTContext &Context) {
1364 ID.AddInteger(I: TemplateArgs.size());
1365 for (const TemplateArgument &TemplateArg : TemplateArgs)
1366 TemplateArg.Profile(ID, Context);
1367 TPL->Profile(ID, C: Context);
1368}
1369
1370void VarTemplateDecl::AddPartialSpecialization(
1371 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1372 if (InsertPos)
1373 getPartialSpecializations().InsertNode(N: D, InsertPos);
1374 else {
1375 VarTemplatePartialSpecializationDecl *Existing =
1376 getPartialSpecializations().GetOrInsertNode(N: D);
1377 (void)Existing;
1378 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1379 }
1380
1381 if (ASTMutationListener *L = getASTMutationListener())
1382 L->AddedCXXTemplateSpecialization(TD: this, D);
1383}
1384
1385void VarTemplateDecl::getPartialSpecializations(
1386 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const {
1387 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1388 getPartialSpecializations();
1389 PS.clear();
1390 PS.reserve(N: PartialSpecs.size());
1391 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1392 PS.push_back(Elt: P.getMostRecentDecl());
1393}
1394
1395VarTemplatePartialSpecializationDecl *
1396VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1397 VarTemplatePartialSpecializationDecl *D) {
1398 Decl *DCanon = D->getCanonicalDecl();
1399 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1400 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1401 return P.getMostRecentDecl();
1402 }
1403
1404 return nullptr;
1405}
1406
1407//===----------------------------------------------------------------------===//
1408// VarTemplateSpecializationDecl Implementation
1409//===----------------------------------------------------------------------===//
1410
1411VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1412 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1413 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1414 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1415 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1416 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1417 SpecializedTemplate(SpecializedTemplate),
1418 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1419 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1420
1421VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1422 ASTContext &C)
1423 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1424 QualType(), nullptr, SC_None),
1425 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1426
1427VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1428 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1429 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1430 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1431 return new (Context, DC) VarTemplateSpecializationDecl(
1432 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1433 SpecializedTemplate, T, TInfo, S, Args);
1434}
1435
1436VarTemplateSpecializationDecl *
1437VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
1438 GlobalDeclID ID) {
1439 return new (C, ID)
1440 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1441}
1442
1443void VarTemplateSpecializationDecl::getNameForDiagnostic(
1444 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1445 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1446
1447 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(Val: this);
1448 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1449 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1450 printTemplateArgumentList(
1451 OS, Args: ArgsAsWritten->arguments(), Policy,
1452 TPL: getSpecializedTemplate()->getTemplateParameters());
1453 } else {
1454 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1455 printTemplateArgumentList(
1456 OS, Args: TemplateArgs.asArray(), Policy,
1457 TPL: getSpecializedTemplate()->getTemplateParameters());
1458 }
1459}
1460
1461VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1462 if (const auto *PartialSpec =
1463 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1464 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1465 return cast<VarTemplateDecl *>(Val: SpecializedTemplate);
1466}
1467
1468SourceRange VarTemplateSpecializationDecl::getSourceRange() const {
1469 switch (getSpecializationKind()) {
1470 case TSK_Undeclared:
1471 case TSK_ImplicitInstantiation: {
1472 llvm::PointerUnion<VarTemplateDecl *,
1473 VarTemplatePartialSpecializationDecl *>
1474 Pattern = getSpecializedTemplateOrPartial();
1475 assert(!Pattern.isNull() &&
1476 "Variable template specialization without pattern?");
1477 if (const auto *VTPSD =
1478 dyn_cast<VarTemplatePartialSpecializationDecl *>(Val&: Pattern))
1479 return VTPSD->getSourceRange();
1480 VarTemplateDecl *VTD = cast<VarTemplateDecl *>(Val&: Pattern);
1481 if (hasInit()) {
1482 if (VarTemplateDecl *Definition = VTD->getDefinition())
1483 return Definition->getSourceRange();
1484 }
1485 return VTD->getCanonicalDecl()->getSourceRange();
1486 }
1487 case TSK_ExplicitSpecialization: {
1488 SourceRange Range = VarDecl::getSourceRange();
1489 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten();
1490 !hasInit() && Args)
1491 Range.setEnd(Args->getRAngleLoc());
1492 return Range;
1493 }
1494 case TSK_ExplicitInstantiationDeclaration:
1495 case TSK_ExplicitInstantiationDefinition: {
1496 SourceRange Range = VarDecl::getSourceRange();
1497 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1498 Range.setBegin(ExternKW);
1499 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1500 TemplateKW.isValid())
1501 Range.setBegin(TemplateKW);
1502 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten())
1503 Range.setEnd(Args->getRAngleLoc());
1504 return Range;
1505 }
1506 }
1507 llvm_unreachable("unhandled template specialization kind");
1508}
1509
1510void VarTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) {
1511 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(Val&: ExplicitInfo);
1512 if (!Info) {
1513 // Don't allocate if the location is invalid.
1514 if (Loc.isInvalid())
1515 return;
1516 Info = new (getASTContext()) ExplicitInstantiationInfo;
1517 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
1518 ExplicitInfo = Info;
1519 }
1520 Info->ExternKeywordLoc = Loc;
1521}
1522
1523void VarTemplateSpecializationDecl::setTemplateKeywordLoc(SourceLocation Loc) {
1524 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(Val&: ExplicitInfo);
1525 if (!Info) {
1526 // Don't allocate if the location is invalid.
1527 if (Loc.isInvalid())
1528 return;
1529 Info = new (getASTContext()) ExplicitInstantiationInfo;
1530 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
1531 ExplicitInfo = Info;
1532 }
1533 Info->TemplateKeywordLoc = Loc;
1534}
1535
1536//===----------------------------------------------------------------------===//
1537// VarTemplatePartialSpecializationDecl Implementation
1538//===----------------------------------------------------------------------===//
1539
1540void VarTemplatePartialSpecializationDecl::anchor() {}
1541
1542VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1543 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1544 SourceLocation IdLoc, TemplateParameterList *Params,
1545 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1546 StorageClass S, ArrayRef<TemplateArgument> Args)
1547 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1548 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1549 TInfo, S, Args),
1550 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1551 if (AdoptTemplateParameterList(Params, Owner: DC))
1552 setInvalidDecl();
1553}
1554
1555VarTemplatePartialSpecializationDecl *
1556VarTemplatePartialSpecializationDecl::Create(
1557 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1558 SourceLocation IdLoc, TemplateParameterList *Params,
1559 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1560 StorageClass S, ArrayRef<TemplateArgument> Args) {
1561 assert(!Params->empty() && "template with no template parameters");
1562 auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(
1563 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,
1564 Args);
1565 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1566 return Result;
1567}
1568
1569VarTemplatePartialSpecializationDecl *
1570VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1571 GlobalDeclID ID) {
1572 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1573}
1574
1575SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {
1576 if (const VarTemplatePartialSpecializationDecl *MT =
1577 getInstantiatedFromMember();
1578 MT && !isMemberSpecialization())
1579 return MT->getSourceRange();
1580 SourceRange Range = VarTemplateSpecializationDecl::getSourceRange();
1581 if (const TemplateParameterList *TPL = getTemplateParameters();
1582 TPL && getTemplateParameterLists().empty())
1583 Range.setBegin(TPL->getTemplateLoc());
1584 return Range;
1585}
1586
1587static TemplateParameterList *createBuiltinTemplateParameterList(
1588 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1589 switch (BTK) {
1590#define CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST
1591#include "clang/Basic/BuiltinTemplates.inc"
1592 }
1593
1594 llvm_unreachable("unhandled BuiltinTemplateKind!");
1595}
1596
1597void BuiltinTemplateDecl::anchor() {}
1598
1599BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1600 DeclarationName Name,
1601 BuiltinTemplateKind BTK)
1602 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1603 createBuiltinTemplateParameterList(C, DC, BTK)),
1604 BTK(BTK) {}
1605
1606bool BuiltinTemplateDecl::isPackProducingBuiltinTemplate() const {
1607 return getBuiltinTemplateKind() == clang::BTK__builtin_dedup_pack;
1608}
1609
1610bool clang::isPackProducingBuiltinTemplateName(TemplateName N) {
1611 auto *T = dyn_cast_or_null<BuiltinTemplateDecl>(
1612 Val: N.getAsTemplateDecl(/*IgnoreDeduced=*/true));
1613 return T && T->isPackProducingBuiltinTemplate();
1614}
1615
1616TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1617 QualType T,
1618 const APValue &V) {
1619 DeclContext *DC = C.getTranslationUnitDecl();
1620 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1621 C.addDestruction(Ptr: &TPOD->Value);
1622 return TPOD;
1623}
1624
1625TemplateParamObjectDecl *
1626TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1627 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1628 C.addDestruction(Ptr: &TPOD->Value);
1629 return TPOD;
1630}
1631
1632void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1633 const PrintingPolicy &Policy) const {
1634 OS << "<template param ";
1635 printAsExpr(OS, Policy);
1636 OS << ">";
1637}
1638
1639void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1640 printAsExpr(OS, Policy: getASTContext().getPrintingPolicy());
1641}
1642
1643void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1644 const PrintingPolicy &Policy) const {
1645 getType().getUnqualifiedType().print(OS, Policy);
1646 printAsInit(OS, Policy);
1647}
1648
1649void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1650 printAsInit(OS, Policy: getASTContext().getPrintingPolicy());
1651}
1652
1653void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1654 const PrintingPolicy &Policy) const {
1655 getValue().printPretty(OS, Policy, Ty: getType(), Ctx: &getASTContext());
1656}
1657
1658std::tuple<NamedDecl *, TemplateArgument>
1659clang::getReplacedTemplateParameter(Decl *D, unsigned Index) {
1660 switch (D->getKind()) {
1661 case Decl::Kind::BuiltinTemplate:
1662 case Decl::Kind::ClassTemplate:
1663 case Decl::Kind::Concept:
1664 case Decl::Kind::FunctionTemplate:
1665 case Decl::Kind::TemplateTemplateParm:
1666 case Decl::Kind::TypeAliasTemplate:
1667 case Decl::Kind::VarTemplate:
1668 return {cast<TemplateDecl>(Val: D)->getTemplateParameters()->getParam(Idx: Index),
1669 {}};
1670 case Decl::Kind::ClassTemplateSpecialization: {
1671 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(Val: D);
1672 auto P = CTSD->getSpecializedTemplateOrPartial();
1673 if (const auto *CTPSD =
1674 dyn_cast<ClassTemplatePartialSpecializationDecl *>(Val&: P)) {
1675 TemplateParameterList *TPL = CTPSD->getTemplateParameters();
1676 return {TPL->getParam(Idx: Index),
1677 CTSD->getTemplateInstantiationArgs()[Index]};
1678 }
1679 TemplateParameterList *TPL =
1680 cast<ClassTemplateDecl *>(Val&: P)->getTemplateParameters();
1681 return {TPL->getParam(Idx: Index), CTSD->getTemplateArgs()[Index]};
1682 }
1683 case Decl::Kind::VarTemplateSpecialization: {
1684 const auto *VTSD = cast<VarTemplateSpecializationDecl>(Val: D);
1685 auto P = VTSD->getSpecializedTemplateOrPartial();
1686 if (const auto *VTPSD =
1687 dyn_cast<VarTemplatePartialSpecializationDecl *>(Val&: P)) {
1688 TemplateParameterList *TPL = VTPSD->getTemplateParameters();
1689 return {TPL->getParam(Idx: Index),
1690 VTSD->getTemplateInstantiationArgs()[Index]};
1691 }
1692 TemplateParameterList *TPL =
1693 cast<VarTemplateDecl *>(Val&: P)->getTemplateParameters();
1694 return {TPL->getParam(Idx: Index), VTSD->getTemplateArgs()[Index]};
1695 }
1696 case Decl::Kind::ClassTemplatePartialSpecialization:
1697 return {cast<ClassTemplatePartialSpecializationDecl>(Val: D)
1698 ->getTemplateParameters()
1699 ->getParam(Idx: Index),
1700 {}};
1701 case Decl::Kind::VarTemplatePartialSpecialization:
1702 return {cast<VarTemplatePartialSpecializationDecl>(Val: D)
1703 ->getTemplateParameters()
1704 ->getParam(Idx: Index),
1705 {}};
1706 // This is used as the AssociatedDecl for placeholder type deduction.
1707 case Decl::TemplateTypeParm:
1708 return {cast<NamedDecl>(Val: D), {}};
1709 // FIXME: Always use the template decl as the AssociatedDecl.
1710 case Decl::Kind::CXXRecord:
1711 return getReplacedTemplateParameter(
1712 D: cast<CXXRecordDecl>(Val: D)->getDescribedClassTemplate(), Index);
1713 case Decl::Kind::CXXDeductionGuide:
1714 case Decl::Kind::CXXConversion:
1715 case Decl::Kind::CXXConstructor:
1716 case Decl::Kind::CXXDestructor:
1717 case Decl::Kind::CXXMethod:
1718 case Decl::Kind::Function: {
1719 const FunctionTemplateSpecializationInfo *Info =
1720 cast<FunctionDecl>(Val: D)->getTemplateSpecializationInfo();
1721 return {Info->getTemplate()->getTemplateParameters()->getParam(Idx: Index),
1722 Info->TemplateArguments->asArray()[Index]};
1723 }
1724 default:
1725 llvm_unreachable("Unhandled templated declaration kind");
1726 }
1727}
1728
1729const Decl &clang::adjustDeclToTemplate(const Decl &D) {
1730 if (const auto *FD = dyn_cast<FunctionDecl>(Val: &D)) {
1731 // Is this function declaration part of a function template?
1732 if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate())
1733 return *FTD;
1734
1735 // Nothing to do if function is not an implicit instantiation.
1736 if (FD->getTemplateSpecializationKind() != TSK_ImplicitInstantiation)
1737 return D;
1738
1739 // Function is an implicit instantiation of a function template?
1740 if (const FunctionTemplateDecl *FTD = FD->getPrimaryTemplate())
1741 return *FTD;
1742
1743 // Function is instantiated from a member definition of a class template?
1744 if (const FunctionDecl *MemberDecl =
1745 FD->getInstantiatedFromMemberFunction())
1746 return *MemberDecl;
1747
1748 return D;
1749 }
1750 if (const auto *VD = dyn_cast<VarDecl>(Val: &D)) {
1751 // Static data member is instantiated from a member definition of a class
1752 // template?
1753 if (VD->isStaticDataMember())
1754 if (const VarDecl *MemberDecl = VD->getInstantiatedFromStaticDataMember())
1755 return *MemberDecl;
1756
1757 return D;
1758 }
1759 if (const auto *CRD = dyn_cast<CXXRecordDecl>(Val: &D)) {
1760 // Is this class declaration part of a class template?
1761 if (const ClassTemplateDecl *CTD = CRD->getDescribedClassTemplate())
1762 return *CTD;
1763
1764 // Class is an implicit instantiation of a class template or partial
1765 // specialization?
1766 if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Val: CRD)) {
1767 if (CTSD->getSpecializationKind() != TSK_ImplicitInstantiation)
1768 return D;
1769 llvm::PointerUnion<ClassTemplateDecl *,
1770 ClassTemplatePartialSpecializationDecl *>
1771 PU = CTSD->getSpecializedTemplateOrPartial();
1772 return isa<ClassTemplateDecl *>(Val: PU)
1773 ? *static_cast<const Decl *>(cast<ClassTemplateDecl *>(Val&: PU))
1774 : *static_cast<const Decl *>(
1775 cast<ClassTemplatePartialSpecializationDecl *>(Val&: PU));
1776 }
1777
1778 // Class is instantiated from a member definition of a class template?
1779 if (const MemberSpecializationInfo *Info =
1780 CRD->getMemberSpecializationInfo())
1781 return *Info->getInstantiatedFrom();
1782
1783 return D;
1784 }
1785 if (const auto *ED = dyn_cast<EnumDecl>(Val: &D)) {
1786 // Enum is instantiated from a member definition of a class template?
1787 if (const EnumDecl *MemberDecl = ED->getInstantiatedFromMemberEnum())
1788 return *MemberDecl;
1789
1790 return D;
1791 }
1792 // FIXME: Adjust alias templates?
1793 return D;
1794}
1795
1796ExplicitInstantiationDecl::ExplicitInstantiationDecl(
1797 DeclContext *DC, NamedDecl *Specialization, SourceLocation ExternLoc,
1798 SourceLocation TemplateLoc, NestedNameSpecifierLoc QualifierLoc,
1799 const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc,
1800 TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK)
1801 : Decl(ExplicitInstantiation, DC, TemplateLoc),
1802 SpecAndTSK(Specialization, TSK), ExternLoc(ExternLoc), NameLoc(NameLoc) {
1803 unsigned Flags = 0;
1804 if (QualifierLoc)
1805 Flags |= HasQualifierFlag;
1806 if (ArgsAsWritten)
1807 Flags |= HasArgsAsWrittenFlag;
1808 // Set flags BEFORE writing trailing objects, because
1809 // numTrailingObjects reads TypeAndFlags.getInt() to compute offsets.
1810 TypeAndFlags.setPointerAndInt(PtrVal: TypeAsWritten, IntVal: Flags);
1811 if (QualifierLoc)
1812 *getTrailingObjects<NestedNameSpecifierLoc>() = QualifierLoc;
1813 if (ArgsAsWritten)
1814 *getTrailingObjects<const ASTTemplateArgumentListInfo *>() = ArgsAsWritten;
1815}
1816
1817ExplicitInstantiationDecl *ExplicitInstantiationDecl::Create(
1818 ASTContext &C, DeclContext *DC, NamedDecl *Specialization,
1819 SourceLocation ExternLoc, SourceLocation TemplateLoc,
1820 NestedNameSpecifierLoc QualifierLoc,
1821 const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc,
1822 TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK) {
1823 unsigned Extra = additionalSizeToAlloc<NestedNameSpecifierLoc,
1824 const ASTTemplateArgumentListInfo *>(
1825 Counts: QualifierLoc ? 1 : 0, Counts: ArgsAsWritten ? 1 : 0);
1826 return new (C, DC, Extra) ExplicitInstantiationDecl(
1827 DC, Specialization, ExternLoc, TemplateLoc, QualifierLoc, ArgsAsWritten,
1828 NameLoc, TypeAsWritten, TSK);
1829}
1830
1831ExplicitInstantiationDecl *
1832ExplicitInstantiationDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,
1833 unsigned TrailingFlags) {
1834 unsigned Extra = additionalSizeToAlloc<NestedNameSpecifierLoc,
1835 const ASTTemplateArgumentListInfo *>(
1836 Counts: (TrailingFlags & HasQualifierFlag) ? 1 : 0,
1837 Counts: (TrailingFlags & HasArgsAsWrittenFlag) ? 1 : 0);
1838 auto *D = new (C, ID, Extra) ExplicitInstantiationDecl(EmptyShell());
1839 // Set the flags so the reader knows which trailing objects are present.
1840 D->TypeAndFlags.setInt(TrailingFlags);
1841 return D;
1842}
1843
1844SourceLocation ExplicitInstantiationDecl::getTagKWLoc() const {
1845 if (auto TL = getClassTypeLoc()) {
1846 if (auto TST = TL->getAs<TemplateSpecializationTypeLoc>())
1847 return TST.getElaboratedKeywordLoc();
1848 if (auto Tag = TL->getAs<TagTypeLoc>())
1849 return Tag.getElaboratedKeywordLoc();
1850 }
1851 return SourceLocation();
1852}
1853
1854NestedNameSpecifierLoc ExplicitInstantiationDecl::getQualifierLoc() const {
1855 if (hasTrailingQualifier())
1856 return *getTrailingObjects<NestedNameSpecifierLoc>();
1857 if (auto TL = getClassTypeLoc())
1858 return TL->getPrefix();
1859 return NestedNameSpecifierLoc();
1860}
1861
1862TypeSourceInfo *ExplicitInstantiationDecl::getTypeAsWritten() const {
1863 // For class-like entities, TSI encodes the class itself, not a declared type.
1864 if (getClassTypeLoc())
1865 return nullptr;
1866 return getRawTypeSourceInfo();
1867}
1868
1869std::optional<unsigned> ExplicitInstantiationDecl::getNumTemplateArgs() const {
1870 if (const auto *Args = getTrailingArgsInfo())
1871 return Args->NumTemplateArgs;
1872 if (auto TL = getClassTypeLoc())
1873 if (auto TST = TL->getAs<TemplateSpecializationTypeLoc>())
1874 return TST.getNumArgs();
1875 return std::nullopt;
1876}
1877
1878TemplateArgumentLoc
1879ExplicitInstantiationDecl::getTemplateArg(unsigned I) const {
1880 if (const auto *Args = getTrailingArgsInfo())
1881 return (*Args)[I];
1882 if (auto TL = getClassTypeLoc())
1883 if (auto TST = TL->getAs<TemplateSpecializationTypeLoc>())
1884 return TST.getArgLoc(i: I);
1885 llvm_unreachable("template arguments not found in trailing args or TypeLoc");
1886}
1887
1888SourceLocation ExplicitInstantiationDecl::getTemplateArgsLAngleLoc() const {
1889 if (const auto *Args = getTrailingArgsInfo())
1890 return Args->getLAngleLoc();
1891 if (auto TL = getClassTypeLoc())
1892 if (auto TST = TL->getAs<TemplateSpecializationTypeLoc>())
1893 return TST.getLAngleLoc();
1894 llvm_unreachable("template arguments not found in trailing args or TypeLoc");
1895}
1896
1897SourceLocation ExplicitInstantiationDecl::getTemplateArgsRAngleLoc() const {
1898 if (const auto *Args = getTrailingArgsInfo())
1899 return Args->getRAngleLoc();
1900 if (auto TL = getClassTypeLoc())
1901 if (auto TST = TL->getAs<TemplateSpecializationTypeLoc>())
1902 return TST.getRAngleLoc();
1903 llvm_unreachable("template arguments not found in trailing args or TypeLoc");
1904}
1905
1906SourceLocation ExplicitInstantiationDecl::getEndLoc() const {
1907 // For func/var templates with postfix type syntax (arrays, functions),
1908 // the type extends past the name, so use the type's end location.
1909 if (auto *TSI = getTypeAsWritten())
1910 if (TSI->getType().hasPostfixDeclaratorSyntax())
1911 return TSI->getTypeLoc().getEndLoc();
1912 // Otherwise, template args RAngleLoc or NameLoc.
1913 if (getNumTemplateArgs()) {
1914 SourceLocation RAngle = getTemplateArgsRAngleLoc();
1915 if (RAngle.isValid())
1916 return RAngle;
1917 }
1918 return NameLoc;
1919}
1920
1921SourceRange ExplicitInstantiationDecl::getSourceRange() const {
1922 SourceLocation Begin = ExternLoc.isValid() ? ExternLoc : getLocation();
1923 return SourceRange(Begin, getEndLoc());
1924}
1925