clang 22.0.0git
DeclTemplate.cpp
Go to the documentation of this file.
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
16#include "clang/AST/DeclCXX.h"
18#include "clang/AST/Expr.h"
19#include "clang/AST/ExprCXX.h"
21#include "clang/AST/ODRHash.h"
24#include "clang/AST/Type.h"
25#include "clang/AST/TypeLoc.h"
27#include "clang/Basic/LLVM.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
48 return P.hasDefaultArgument() &&
49 P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
50}
51
52TemplateParameterList::TemplateParameterList(const ASTContext &C,
53 SourceLocation TemplateLoc,
54 SourceLocation LAngleLoc,
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>(P)) {
68 if (!IsPack && (NTTP->getType()->containsUnexpandedParameterPack() ||
70 ContainsUnexpandedParameterPack = true;
71 if (NTTP->hasPlaceholderTypeConstraint())
72 HasConstrainedParameters = true;
73 } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
74 if (!IsPack &&
75 (TTP->getTemplateParameters()->containsUnexpandedParameterPack() ||
77 ContainsUnexpandedParameterPack = true;
78 }
79 } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
81 ContainsUnexpandedParameterPack = true;
82 } else if (const TypeConstraint *TC = TTP->getTypeConstraint();
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(asArray())) {
111 if (!Param->isImplicit())
112 break;
113
114 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(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
127 SourceLocation LAngleLoc,
129 SourceLocation RAngleLoc, Expr *RequiresClause) {
130 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
131 Params.size(), RequiresClause ? 1u : 0u),
132 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(RC != nullptr);
141 if (RC)
142 RC->Profile(ID, C, /*Canonical=*/true);
143 ID.AddInteger(size());
144 for (NamedDecl *D : *this) {
145 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
146 ID.AddInteger(0);
147 ID.AddBoolean(NTTP->isParameterPack());
148 NTTP->getType().getCanonicalType().Profile(ID);
149 ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint());
150 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
151 E->Profile(ID, C, /*Canonical=*/true);
152 continue;
153 }
154 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {
155 ID.AddInteger(1);
156 ID.AddBoolean(TTP->isParameterPack());
157 ID.AddBoolean(TTP->hasTypeConstraint());
158 if (const TypeConstraint *TC = TTP->getTypeConstraint())
159 TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,
160 /*Canonical=*/true);
161 continue;
162 }
163 const auto *TTP = cast<TemplateTemplateParmDecl>(D);
164 ID.AddInteger(2);
165 ID.AddInteger(TTP->templateParameterKind());
166 ID.AddBoolean(TTP->isParameterPack());
167 TTP->getTemplateParameters()->Profile(ID, C);
168 }
169}
170
172 unsigned NumRequiredArgs = 0;
173 for (const NamedDecl *P : asArray()) {
174 if (P->isTemplateParameterPack()) {
175 if (UnsignedOrNone Expansions = getExpandedPackSize(P)) {
176 NumRequiredArgs += *Expansions;
177 continue;
178 }
179 break;
180 }
181
182 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
183 if (TTP->hasDefaultArgument())
184 break;
185 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
186 if (NTTP->hasDefaultArgument())
187 break;
188 } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(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(0);
203 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
204 return TTP->getDepth();
205 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
206 return NTTP->getDepth();
207 else
208 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
209}
210
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>(P))
218 if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner))
219 Invalid = true;
220
221 if (P->isInvalidDecl())
222 Invalid = true;
223 }
224 return Invalid;
225}
226
229 if (HasConstrainedParameters)
230 for (const NamedDecl *Param : *this) {
231 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
232 if (const auto *TC = TTP->getTypeConstraint())
233 ACs.emplace_back(TC->getImmediatelyDeclaredConstraint(),
234 TC->getArgPackSubstIndex());
235 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
236 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
237 ACs.emplace_back(E);
238 }
239 }
240 if (HasRequiresClause)
241 ACs.emplace_back(getRequiresClause());
242}
243
245 return HasRequiresClause || HasConstrainedParameters;
246}
247
250 if (!InjectedArgs) {
251 InjectedArgs = new (Context) TemplateArgument[size()];
252 llvm::transform(*this, InjectedArgs, [&](NamedDecl *ND) {
253 return Context.getInjectedTemplateArg(ND);
254 });
255 }
256 return {InjectedArgs, NumParams};
257}
258
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>(TemplParam))
267 if (ParamValueDecl->getType()->getContainedDeducedType())
268 return true;
269 return false;
270}
271
272namespace clang {
273
275 return new (C) char[sizeof(void*) * 2];
276}
277
278} // namespace clang
279
280//===----------------------------------------------------------------------===//
281// TemplateDecl Implementation
282//===----------------------------------------------------------------------===//
283
287 : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
288
289void TemplateDecl::anchor() {}
290
294 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
295 if (const AssociatedConstraint &TRC = FD->getTrailingRequiresClause())
296 ACs.emplace_back(TRC);
297}
298
301 return true;
302 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
303 return static_cast<bool>(FD->getTrailingRequiresClause());
304 return false;
305}
306
308 switch (getKind()) {
309 case TemplateDecl::TypeAliasTemplate:
310 return true;
311 case TemplateDecl::BuiltinTemplate:
312 return !cast<BuiltinTemplateDecl>(this)->isPackProducingBuiltinTemplate();
313 default:
314 return false;
315 };
316}
317
318//===----------------------------------------------------------------------===//
319// RedeclarableTemplateDecl Implementation
320//===----------------------------------------------------------------------===//
321
322void RedeclarableTemplateDecl::anchor() {}
323
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.
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(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
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
357 bool OnlyPartial /*=false*/) const {
359 if (!ExternalSource)
360 return;
361
363 OnlyPartial);
364}
365
369 if (!ExternalSource)
370 return false;
371
372 // If TPL is not null, it implies that we're loading specializations for
373 // partial templates. We need to load all specializations in such cases.
374 if (TPL)
376 /*OnlyPartial=*/false);
377
379 Args);
380}
381
382template <class EntryType, typename... ProfileArguments>
385 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
386 ProfileArguments... ProfileArgs) {
388
389 llvm::FoldingSetNodeID ID;
390 EntryType::Profile(ID, ProfileArgs..., getASTContext());
391 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
392 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
393}
394
395template <class EntryType, typename... ProfileArguments>
398 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
399 ProfileArguments... ProfileArgs) {
400
401 if (auto *Found = findSpecializationLocally(Specs, InsertPos, ProfileArgs...))
402 return Found;
403
404 if (!loadLazySpecializationsImpl(ProfileArgs...))
405 return nullptr;
406
407 return findSpecializationLocally(Specs, InsertPos, ProfileArgs...);
408}
409
410template<class Derived, class EntryType>
412 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
413 void *InsertPos) {
414 using SETraits = SpecEntryTraits<EntryType>;
415
416 if (InsertPos) {
417#ifndef NDEBUG
418 auto Args = SETraits::getTemplateArgs(Entry);
419 // Due to hash collisions, it can happen that we load another template
420 // specialization with the same hash. This is fine, as long as the next
421 // call to findSpecializationImpl does not find a matching Decl for the
422 // template arguments.
424 void *CorrectInsertPos;
425 assert(!findSpecializationImpl(Specializations, CorrectInsertPos, Args) &&
426 InsertPos == CorrectInsertPos &&
427 "given incorrect InsertPos for specialization");
428#endif
429 Specializations.InsertNode(Entry, InsertPos);
430 } else {
431 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
432 (void)Existing;
433 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
434 "non-canonical specialization?");
435 }
436
438 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
439 SETraits::getDecl(Entry));
440}
441
442//===----------------------------------------------------------------------===//
443// FunctionTemplateDecl Implementation
444//===----------------------------------------------------------------------===//
445
448 DeclarationName Name,
450 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
451 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
452 if (Invalid)
453 TD->setInvalidDecl();
454 return TD;
455}
456
459 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
460 DeclarationName(), nullptr, nullptr);
461}
462
465 auto *CommonPtr = new (C) Common;
466 C.addDestruction(CommonPtr);
467 return CommonPtr;
468}
469
472}
473
474llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
478}
479
482 void *&InsertPos) {
483 auto *Common = getCommonPtr();
484 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
485}
486
488 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
489 auto *Common = getCommonPtr();
490 addSpecializationImpl<FunctionTemplateDecl>(Common->Specializations, Info,
491 InsertPos);
492}
493
496
497 // If we haven't created a common pointer yet, then it can just be created
498 // with the usual method.
499 if (!Base::Common)
500 return;
501
502 Common *ThisCommon = static_cast<Common *>(Base::Common);
503 Common *PrevCommon = nullptr;
505 for (; Prev; Prev = Prev->getPreviousDecl()) {
506 if (Prev->Base::Common) {
507 PrevCommon = static_cast<Common *>(Prev->Base::Common);
508 break;
509 }
510 PreviousDecls.push_back(Prev);
511 }
512
513 // If the previous redecl chain hasn't created a common pointer yet, then just
514 // use this common pointer.
515 if (!PrevCommon) {
516 for (auto *D : PreviousDecls)
517 D->Base::Common = ThisCommon;
518 return;
519 }
520
521 // Ensure we don't leak any important state.
522 assert(ThisCommon->Specializations.size() == 0 &&
523 "Can't merge incompatible declarations!");
524
525 Base::Common = PrevCommon;
526}
527
528//===----------------------------------------------------------------------===//
529// ClassTemplateDecl Implementation
530//===----------------------------------------------------------------------===//
531
534 DeclarationName Name,
535 TemplateParameterList *Params,
536 NamedDecl *Decl) {
537 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
538 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
539 if (Invalid)
540 TD->setInvalidDecl();
541 return TD;
542}
543
545 GlobalDeclID ID) {
546 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
547 DeclarationName(), nullptr, nullptr);
548}
549
551 bool OnlyPartial /*=false*/) const {
552 loadLazySpecializationsImpl(OnlyPartial);
553}
554
555llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
559}
560
561llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
563 LoadLazySpecializations(/*PartialOnly = */ true);
565}
566
569 auto *CommonPtr = new (C) Common;
570 C.addDestruction(CommonPtr);
571 return CommonPtr;
572}
573
576 void *&InsertPos) {
577 auto *Common = getCommonPtr();
578 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
579}
580
582 void *InsertPos) {
583 auto *Common = getCommonPtr();
584 addSpecializationImpl<ClassTemplateDecl>(Common->Specializations, D,
585 InsertPos);
586}
587
591 TemplateParameterList *TPL, void *&InsertPos) {
592 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
593 TPL);
594}
595
597 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
598 TemplateParameterList *TPL, const ASTContext &Context) {
599 ID.AddInteger(TemplateArgs.size());
600 for (const TemplateArgument &TemplateArg : TemplateArgs)
601 TemplateArg.Profile(ID, Context);
602 TPL->Profile(ID, Context);
603}
604
607 void *InsertPos) {
608 if (InsertPos)
609 getPartialSpecializations().InsertNode(D, InsertPos);
610 else {
612 = getPartialSpecializations().GetOrInsertNode(D);
613 (void)Existing;
614 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
615 }
616
618 L->AddedCXXTemplateSpecialization(this, D);
619}
620
623 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
625 PS.clear();
626 PS.reserve(PartialSpecs.size());
627 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
628 PS.push_back(P.getMostRecentDecl());
629}
630
633 ASTContext &Context = getASTContext();
636 if (Context.hasSameType(P.getCanonicalInjectedSpecializationType(Context),
637 T))
638 return P.getMostRecentDecl();
639 }
640
641 return nullptr;
642}
643
647 Decl *DCanon = D->getCanonicalDecl();
649 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
650 return P.getMostRecentDecl();
651 }
652
653 return nullptr;
654}
655
657 const ASTContext &Ctx) const {
658 Common *CommonPtr = getCommonPtr();
659
660 if (CommonPtr->CanonInjectedTST.isNull()) {
661 SmallVector<TemplateArgument> CanonicalArgs(
663 Ctx.canonicalizeTemplateArguments(CanonicalArgs);
664 CommonPtr->CanonInjectedTST =
667 CanonicalArgs));
668 }
669 return CommonPtr->CanonInjectedTST;
670}
671
672//===----------------------------------------------------------------------===//
673// TemplateTypeParm Allocation/Deallocation Method Implementations
674//===----------------------------------------------------------------------===//
675
677 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
678 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
679 bool Typename, bool ParameterPack, bool HasTypeConstraint,
680 UnsignedOrNone NumExpanded) {
681 auto *TTPDecl =
682 new (C, DC,
683 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
684 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
685 HasTypeConstraint, NumExpanded);
686 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
687 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
688 return TTPDecl;
689}
690
693 return new (C, ID)
695 false, false, std::nullopt);
696}
697
700 bool HasTypeConstraint) {
701 return new (C, ID,
702 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
704 false, HasTypeConstraint, std::nullopt);
705}
706
709 : SourceLocation();
710}
711
714 return SourceRange(getBeginLoc(),
716 // TypeDecl::getSourceRange returns a range containing name location, which is
717 // wrong for unnamed template parameters. e.g:
718 // it will return <[[typename>]] instead of <[[typename]]>
719 if (getDeclName().isEmpty())
720 return SourceRange(getBeginLoc());
722}
723
725 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
726 if (DefArg.getArgument().isNull())
727 DefaultArgument.set(nullptr);
728 else
729 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
730}
731
733 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->getDepth();
734}
735
737 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->getIndex();
738}
739
741 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->isParameterPack();
742}
743
745 ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint,
746 UnsignedOrNone ArgPackSubstIndex) {
747 assert(HasTypeConstraint &&
748 "HasTypeConstraint=true must be passed at construction in order to "
749 "call setTypeConstraint");
750 assert(!TypeConstraintInitialized &&
751 "TypeConstraint was already initialized!");
752 new (getTrailingObjects())
753 TypeConstraint(Loc, ImmediatelyDeclaredConstraint, ArgPackSubstIndex);
754 TypeConstraintInitialized = true;
755}
756
757//===----------------------------------------------------------------------===//
758// NonTypeTemplateParmDecl Method Implementations
759//===----------------------------------------------------------------------===//
760
761NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
762 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
763 unsigned P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
764 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
765 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
766 TemplateParmPosition(D, P), ParameterPack(true),
767 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
768 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
769 auto TypesAndInfos =
770 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
771 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
772 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
773 TypesAndInfos[I].second = ExpandedTInfos[I];
774 }
775 }
776}
777
779 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
780 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
781 QualType T, bool ParameterPack, TypeSourceInfo *TInfo) {
782 AutoType *AT =
783 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
784 const bool HasConstraint = AT && AT->isConstrained();
785 auto *NTTP =
786 new (C, DC,
787 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
788 0, HasConstraint ? 1 : 0))
789 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T,
790 ParameterPack, TInfo);
791 if (HasConstraint)
792 NTTP->setPlaceholderTypeConstraint(nullptr);
793 return NTTP;
794}
795
797 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
798 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
799 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
800 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
801 AutoType *AT = TInfo->getType()->getContainedAutoType();
802 const bool HasConstraint = AT && AT->isConstrained();
803 auto *NTTP =
804 new (C, DC,
805 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
806 ExpandedTypes.size(), HasConstraint ? 1 : 0))
807 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
808 ExpandedTypes, ExpandedTInfos);
809 if (HasConstraint)
810 NTTP->setPlaceholderTypeConstraint(nullptr);
811 return NTTP;
812}
813
816 bool HasTypeConstraint) {
817 auto *NTTP =
818 new (C, ID,
819 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
820 0, HasTypeConstraint ? 1 : 0))
822 0, 0, nullptr, QualType(), false, nullptr);
823 if (HasTypeConstraint)
824 NTTP->setPlaceholderTypeConstraint(nullptr);
825 return NTTP;
826}
827
830 unsigned NumExpandedTypes,
831 bool HasTypeConstraint) {
832 auto *NTTP =
833 new (C, ID,
834 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
835 NumExpandedTypes, HasTypeConstraint ? 1 : 0))
837 0, 0, nullptr, QualType(), nullptr, {}, {});
838 NTTP->NumExpandedTypes = NumExpandedTypes;
839 if (HasTypeConstraint)
840 NTTP->setPlaceholderTypeConstraint(nullptr);
841 return NTTP;
842}
843
849}
850
853 : SourceLocation();
854}
855
857 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
858 if (DefArg.getArgument().isNull())
859 DefaultArgument.set(nullptr);
860 else
861 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
862}
863
864//===----------------------------------------------------------------------===//
865// TemplateTemplateParmDecl Method Implementations
866//===----------------------------------------------------------------------===//
867
868void TemplateTemplateParmDecl::anchor() {}
869
870TemplateTemplateParmDecl::TemplateTemplateParmDecl(
871 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
874 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
875 TemplateParmPosition(D, P), ParameterKind(Kind), Typename(Typename),
876 ParameterPack(true), ExpandedParameterPack(true),
877 NumExpandedParams(Expansions.size()) {
878 llvm::uninitialized_copy(Expansions, getTrailingObjects());
879}
880
882 const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
883 unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateNameKind Kind,
884 bool Typename, TemplateParameterList *Params) {
885 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
886 Kind, Typename, Params);
887}
888
891 SourceLocation L, unsigned D, unsigned P,
893 bool Typename, TemplateParameterList *Params,
895 return new (C, DC,
896 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
897 TemplateTemplateParmDecl(DC, L, D, P, Id, Kind, Typename, Params,
898 Expansions);
899}
900
903 return new (C, ID) TemplateTemplateParmDecl(
904 nullptr, SourceLocation(), 0, 0, false, nullptr,
906}
907
910 unsigned NumExpansions) {
911 auto *TTP =
912 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
913 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
915 nullptr, {});
916 TTP->NumExpandedParams = NumExpansions;
917 return TTP;
918}
919
922 : SourceLocation();
923}
924
926 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
927 if (DefArg.getArgument().isNull())
928 DefaultArgument.set(nullptr);
929 else
930 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
931}
932
933//===----------------------------------------------------------------------===//
934// TemplateArgumentList Implementation
935//===----------------------------------------------------------------------===//
936TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
937 : NumArguments(Args.size()) {
938 llvm::uninitialized_copy(Args, getTrailingObjects());
939}
940
944 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
945 return new (Mem) TemplateArgumentList(Args);
946}
947
951 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
952 MemberSpecializationInfo *MSInfo) {
953 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
954 if (TemplateArgsAsWritten)
956 *TemplateArgsAsWritten);
957
958 void *Mem =
959 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
960 return new (Mem) FunctionTemplateSpecializationInfo(
961 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
962}
963
964//===----------------------------------------------------------------------===//
965// ClassTemplateSpecializationDecl Implementation
966//===----------------------------------------------------------------------===//
967
969 ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC,
970 SourceLocation StartLoc, SourceLocation IdLoc,
971 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
972 bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)
973 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
974 SpecializedTemplate->getIdentifier(), PrevDecl),
975 SpecializedTemplate(SpecializedTemplate),
976 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
977 SpecializationKind(TSK_Undeclared), StrictPackMatch(StrictPackMatch) {
978 assert(DK == Kind::ClassTemplateSpecialization || StrictPackMatch == false);
979}
980
982 Kind DK)
983 : CXXRecordDecl(DK, TagTypeKind::Struct, C, nullptr, SourceLocation(),
984 SourceLocation(), nullptr, nullptr),
985 SpecializationKind(TSK_Undeclared) {}
986
988 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
989 SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate,
990 ArrayRef<TemplateArgument> Args, bool StrictPackMatch,
992 auto *Result = new (Context, DC) ClassTemplateSpecializationDecl(
993 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
994 SpecializedTemplate, Args, StrictPackMatch, PrevDecl);
995
996 // If the template decl is incomplete, copy the external lexical storage from
997 // the base template. This allows instantiations of incomplete types to
998 // complete using the external AST if the template's declaration came from an
999 // external AST.
1000 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
1001 Result->setHasExternalLexicalStorage(
1002 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
1003
1004 return Result;
1005}
1006
1009 GlobalDeclID ID) {
1010 return new (C, ID)
1011 ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
1012}
1013
1015 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1017
1018 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
1019 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1020 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1022 OS, ArgsAsWritten->arguments(), Policy,
1023 getSpecializedTemplate()->getTemplateParameters());
1024 } else {
1025 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1027 OS, TemplateArgs.asArray(), Policy,
1028 getSpecializedTemplate()->getTemplateParameters());
1029 }
1030}
1031
1034 if (const auto *PartialSpec =
1035 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
1036 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1037 return cast<ClassTemplateDecl *>(SpecializedTemplate);
1038}
1039
1042 switch (getSpecializationKind()) {
1043 case TSK_Undeclared:
1045 llvm::PointerUnion<ClassTemplateDecl *,
1048 assert(!Pattern.isNull() &&
1049 "Class template specialization without pattern?");
1050 if (const auto *CTPSD =
1051 dyn_cast<ClassTemplatePartialSpecializationDecl *>(Pattern))
1052 return CTPSD->getSourceRange();
1053 return cast<ClassTemplateDecl *>(Pattern)->getSourceRange();
1054 }
1059 Range.setEnd(Args->getRAngleLoc());
1060 return Range;
1061 }
1065 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1066 Range.setBegin(ExternKW);
1067 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1068 TemplateKW.isValid())
1069 Range.setBegin(TemplateKW);
1071 Range.setEnd(Args->getRAngleLoc());
1072 return Range;
1073 }
1074 }
1075 llvm_unreachable("unhandled template specialization kind");
1076}
1077
1079 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1080 if (!Info) {
1081 // Don't allocate if the location is invalid.
1082 if (Loc.isInvalid())
1083 return;
1086 ExplicitInfo = Info;
1087 }
1088 Info->ExternKeywordLoc = Loc;
1089}
1090
1093 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1094 if (!Info) {
1095 // Don't allocate if the location is invalid.
1096 if (Loc.isInvalid())
1097 return;
1100 ExplicitInfo = Info;
1101 }
1102 Info->TemplateKeywordLoc = Loc;
1103}
1104
1105//===----------------------------------------------------------------------===//
1106// ConceptDecl Implementation
1107//===----------------------------------------------------------------------===//
1110 TemplateParameterList *Params,
1111 Expr *ConstraintExpr) {
1112 bool Invalid = AdoptTemplateParameterList(Params, DC);
1113 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1114 if (Invalid)
1115 TD->setInvalidDecl();
1116 return TD;
1117}
1118
1120 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1122 nullptr, nullptr);
1123
1124 return Result;
1125}
1126
1127//===----------------------------------------------------------------------===//
1128// ImplicitConceptSpecializationDecl Implementation
1129//===----------------------------------------------------------------------===//
1130ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1132 ArrayRef<TemplateArgument> ConvertedArgs)
1133 : Decl(ImplicitConceptSpecialization, DC, SL),
1134 NumTemplateArgs(ConvertedArgs.size()) {
1135 setTemplateArguments(ConvertedArgs);
1136}
1137
1138ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1139 EmptyShell Empty, unsigned NumTemplateArgs)
1140 : Decl(ImplicitConceptSpecialization, Empty),
1141 NumTemplateArgs(NumTemplateArgs) {}
1142
1144 const ASTContext &C, DeclContext *DC, SourceLocation SL,
1145 ArrayRef<TemplateArgument> ConvertedArgs) {
1146 return new (C, DC,
1147 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1148 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1149}
1150
1153 const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) {
1154 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1156}
1157
1159 ArrayRef<TemplateArgument> Converted) {
1160 assert(Converted.size() == NumTemplateArgs);
1161 llvm::uninitialized_copy(Converted, getTrailingObjects());
1162}
1163
1164//===----------------------------------------------------------------------===//
1165// ClassTemplatePartialSpecializationDecl Implementation
1166//===----------------------------------------------------------------------===//
1167void ClassTemplatePartialSpecializationDecl::anchor() {}
1168
1169ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
1170 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1172 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1173 CanQualType CanonInjectedTST,
1176 Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
1177 // Tracking StrictPackMatch for Partial
1178 // Specializations is not needed.
1179 SpecializedTemplate, Args, /*StrictPackMatch=*/false, PrevDecl),
1180 TemplateParams(Params), InstantiatedFromMember(nullptr, false),
1181 CanonInjectedTST(CanonInjectedTST) {
1182 if (AdoptTemplateParameterList(Params, this))
1184}
1185
1188 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1190 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1191 CanQualType CanonInjectedTST,
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
1202 GlobalDeclID ID) {
1203 return new (C, ID) ClassTemplatePartialSpecializationDecl(C);
1204}
1205
1208 const ASTContext &Ctx) const {
1209 if (CanonInjectedTST.isNull()) {
1210 CanonInjectedTST =
1213 getTemplateArgs().asArray()));
1214 }
1215 return CanonInjectedTST;
1216}
1217
1221 MT && !isMemberSpecialization())
1222 return MT->getSourceRange();
1227 return Range;
1228}
1229
1230//===----------------------------------------------------------------------===//
1231// FriendTemplateDecl Implementation
1232//===----------------------------------------------------------------------===//
1233
1234void FriendTemplateDecl::anchor() {}
1235
1241 TemplateParameterList **TPL = nullptr;
1242 if (!Params.empty()) {
1243 TPL = new (Context) TemplateParameterList *[Params.size()];
1244 llvm::copy(Params, TPL);
1245 }
1246 return new (Context, DC)
1247 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
1248}
1249
1251 GlobalDeclID ID) {
1252 return new (C, ID) FriendTemplateDecl(EmptyShell());
1253}
1254
1255//===----------------------------------------------------------------------===//
1256// TypeAliasTemplateDecl Implementation
1257//===----------------------------------------------------------------------===//
1258
1261 DeclarationName Name,
1263 bool Invalid = AdoptTemplateParameterList(Params, DC);
1264 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1265 if (Invalid)
1266 TD->setInvalidDecl();
1267 return TD;
1268}
1269
1272 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1273 DeclarationName(), nullptr, nullptr);
1274}
1275
1278 auto *CommonPtr = new (C) Common;
1279 C.addDestruction(CommonPtr);
1280 return CommonPtr;
1281}
1282
1283//===----------------------------------------------------------------------===//
1284// VarTemplateDecl Implementation
1285//===----------------------------------------------------------------------===//
1286
1288 VarTemplateDecl *CurD = this;
1289 while (CurD) {
1290 if (CurD->isThisDeclarationADefinition())
1291 return CurD;
1292 CurD = CurD->getPreviousDecl();
1293 }
1294 return nullptr;
1295}
1296
1299 TemplateParameterList *Params,
1300 VarDecl *Decl) {
1301 bool Invalid = AdoptTemplateParameterList(Params, DC);
1302 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1303 if (Invalid)
1304 TD->setInvalidDecl();
1305 return TD;
1306}
1307
1309 GlobalDeclID ID) {
1310 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1311 DeclarationName(), nullptr, nullptr);
1312}
1313
1315 bool OnlyPartial /*=false*/) const {
1316 loadLazySpecializationsImpl(OnlyPartial);
1317}
1318
1319llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1322 return getCommonPtr()->Specializations;
1323}
1324
1325llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1327 LoadLazySpecializations(/*PartialOnly = */ true);
1329}
1330
1333 auto *CommonPtr = new (C) Common;
1334 C.addDestruction(CommonPtr);
1335 return CommonPtr;
1336}
1337
1340 void *&InsertPos) {
1341 auto *Common = getCommonPtr();
1342 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
1343}
1344
1346 void *InsertPos) {
1347 auto *Common = getCommonPtr();
1348 addSpecializationImpl<VarTemplateDecl>(Common->Specializations, D, InsertPos);
1349}
1350
1353 TemplateParameterList *TPL, void *&InsertPos) {
1354 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1355 TPL);
1356}
1357
1359 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1360 TemplateParameterList *TPL, const ASTContext &Context) {
1361 ID.AddInteger(TemplateArgs.size());
1362 for (const TemplateArgument &TemplateArg : TemplateArgs)
1363 TemplateArg.Profile(ID, Context);
1364 TPL->Profile(ID, Context);
1365}
1366
1368 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1369 if (InsertPos)
1370 getPartialSpecializations().InsertNode(D, InsertPos);
1371 else {
1373 getPartialSpecializations().GetOrInsertNode(D);
1374 (void)Existing;
1375 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1376 }
1377
1379 L->AddedCXXTemplateSpecialization(this, D);
1380}
1381
1384 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1386 PS.clear();
1387 PS.reserve(PartialSpecs.size());
1388 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1389 PS.push_back(P.getMostRecentDecl());
1390}
1391
1395 Decl *DCanon = D->getCanonicalDecl();
1397 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1398 return P.getMostRecentDecl();
1399 }
1400
1401 return nullptr;
1402}
1403
1404//===----------------------------------------------------------------------===//
1405// VarTemplateSpecializationDecl Implementation
1406//===----------------------------------------------------------------------===//
1407
1409 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1410 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1412 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1413 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1414 SpecializedTemplate(SpecializedTemplate),
1415 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1416 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1417
1419 ASTContext &C)
1420 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1421 QualType(), nullptr, SC_None),
1422 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1423
1425 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1426 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1428 return new (Context, DC) VarTemplateSpecializationDecl(
1429 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1430 SpecializedTemplate, T, TInfo, S, Args);
1431}
1432
1435 GlobalDeclID ID) {
1436 return new (C, ID)
1437 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1438}
1439
1441 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1443
1444 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1445 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1446 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1448 OS, ArgsAsWritten->arguments(), Policy,
1449 getSpecializedTemplate()->getTemplateParameters());
1450 } else {
1451 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1453 OS, TemplateArgs.asArray(), Policy,
1454 getSpecializedTemplate()->getTemplateParameters());
1455 }
1456}
1457
1459 if (const auto *PartialSpec =
1460 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1461 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1462 return cast<VarTemplateDecl *>(SpecializedTemplate);
1463}
1464
1466 switch (getSpecializationKind()) {
1467 case TSK_Undeclared:
1469 llvm::PointerUnion<VarTemplateDecl *,
1472 assert(!Pattern.isNull() &&
1473 "Variable template specialization without pattern?");
1474 if (const auto *VTPSD =
1475 dyn_cast<VarTemplatePartialSpecializationDecl *>(Pattern))
1476 return VTPSD->getSourceRange();
1477 VarTemplateDecl *VTD = cast<VarTemplateDecl *>(Pattern);
1478 if (hasInit()) {
1480 return Definition->getSourceRange();
1481 }
1482 return VTD->getCanonicalDecl()->getSourceRange();
1483 }
1487 !hasInit() && Args)
1488 Range.setEnd(Args->getRAngleLoc());
1489 return Range;
1490 }
1494 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1495 Range.setBegin(ExternKW);
1496 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1497 TemplateKW.isValid())
1498 Range.setBegin(TemplateKW);
1500 Range.setEnd(Args->getRAngleLoc());
1501 return Range;
1502 }
1503 }
1504 llvm_unreachable("unhandled template specialization kind");
1505}
1506
1508 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1509 if (!Info) {
1510 // Don't allocate if the location is invalid.
1511 if (Loc.isInvalid())
1512 return;
1515 ExplicitInfo = Info;
1516 }
1517 Info->ExternKeywordLoc = Loc;
1518}
1519
1521 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1522 if (!Info) {
1523 // Don't allocate if the location is invalid.
1524 if (Loc.isInvalid())
1525 return;
1528 ExplicitInfo = Info;
1529 }
1530 Info->TemplateKeywordLoc = Loc;
1531}
1532
1533//===----------------------------------------------------------------------===//
1534// VarTemplatePartialSpecializationDecl Implementation
1535//===----------------------------------------------------------------------===//
1536
1537void VarTemplatePartialSpecializationDecl::anchor() {}
1538
1539VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1540 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1542 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1544 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1545 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1546 TInfo, S, Args),
1547 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1548 if (AdoptTemplateParameterList(Params, DC))
1550}
1551
1554 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1556 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1558 auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(
1559 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,
1560 Args);
1561 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1562 return Result;
1563}
1564
1567 GlobalDeclID ID) {
1568 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1569}
1570
1574 MT && !isMemberSpecialization())
1575 return MT->getSourceRange();
1580 return Range;
1581}
1582
1584 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1585 switch (BTK) {
1586#define CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST
1587#include "clang/Basic/BuiltinTemplates.inc"
1588 }
1589
1590 llvm_unreachable("unhandled BuiltinTemplateKind!");
1591}
1592
1593void BuiltinTemplateDecl::anchor() {}
1594
1595BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1596 DeclarationName Name,
1600 BTK(BTK) {}
1601
1603 return getBuiltinTemplateKind() == clang::BTK__builtin_dedup_pack;
1604}
1605
1607 auto *T = dyn_cast_or_null<BuiltinTemplateDecl>(
1608 N.getAsTemplateDecl(/*IgnoreDeduced=*/true));
1609 return T && T->isPackProducingBuiltinTemplate();
1610}
1611
1612TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1613 QualType T,
1614 const APValue &V) {
1615 DeclContext *DC = C.getTranslationUnitDecl();
1616 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1617 C.addDestruction(&TPOD->Value);
1618 return TPOD;
1619}
1620
1622TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1623 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1624 C.addDestruction(&TPOD->Value);
1625 return TPOD;
1626}
1627
1628void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1629 const PrintingPolicy &Policy) const {
1630 OS << "<template param ";
1631 printAsExpr(OS, Policy);
1632 OS << ">";
1633}
1634
1635void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1636 printAsExpr(OS, getASTContext().getPrintingPolicy());
1637}
1638
1639void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1640 const PrintingPolicy &Policy) const {
1641 getType().getUnqualifiedType().print(OS, Policy);
1642 printAsInit(OS, Policy);
1643}
1644
1645void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1646 printAsInit(OS, getASTContext().getPrintingPolicy());
1647}
1648
1649void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1650 const PrintingPolicy &Policy) const {
1651 getValue().printPretty(OS, Policy, getType(), &getASTContext());
1652}
1653
1655 switch (D->getKind()) {
1656 case Decl::Kind::CXXRecord:
1657 return cast<CXXRecordDecl>(D)
1658 ->getDescribedTemplate()
1659 ->getTemplateParameters();
1660 case Decl::Kind::ClassTemplate:
1661 return cast<ClassTemplateDecl>(D)->getTemplateParameters();
1662 case Decl::Kind::ClassTemplateSpecialization: {
1663 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1664 auto P = CTSD->getSpecializedTemplateOrPartial();
1665 if (const auto *CTPSD =
1666 dyn_cast<ClassTemplatePartialSpecializationDecl *>(P))
1667 return CTPSD->getTemplateParameters();
1668 return cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1669 }
1670 case Decl::Kind::ClassTemplatePartialSpecialization:
1671 return cast<ClassTemplatePartialSpecializationDecl>(D)
1672 ->getTemplateParameters();
1673 case Decl::Kind::TypeAliasTemplate:
1674 return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
1675 case Decl::Kind::BuiltinTemplate:
1676 return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
1677 case Decl::Kind::CXXDeductionGuide:
1678 case Decl::Kind::CXXConversion:
1679 case Decl::Kind::CXXConstructor:
1680 case Decl::Kind::CXXDestructor:
1681 case Decl::Kind::CXXMethod:
1682 case Decl::Kind::Function:
1683 return cast<FunctionDecl>(D)
1684 ->getTemplateSpecializationInfo()
1685 ->getTemplate()
1686 ->getTemplateParameters();
1687 case Decl::Kind::FunctionTemplate:
1688 return cast<FunctionTemplateDecl>(D)->getTemplateParameters();
1689 case Decl::Kind::VarTemplate:
1690 return cast<VarTemplateDecl>(D)->getTemplateParameters();
1691 case Decl::Kind::VarTemplateSpecialization: {
1692 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1693 auto P = VTSD->getSpecializedTemplateOrPartial();
1694 if (const auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl *>(P))
1695 return VTPSD->getTemplateParameters();
1696 return cast<VarTemplateDecl *>(P)->getTemplateParameters();
1697 }
1698 case Decl::Kind::VarTemplatePartialSpecialization:
1699 return cast<VarTemplatePartialSpecializationDecl>(D)
1700 ->getTemplateParameters();
1701 case Decl::Kind::TemplateTemplateParm:
1702 return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();
1703 case Decl::Kind::Concept:
1704 return cast<ConceptDecl>(D)->getTemplateParameters();
1705 default:
1706 llvm_unreachable("Unhandled templated declaration kind");
1707 }
1708}
Defines the clang::ASTContext interface.
#define V(N, I)
Definition: ASTContext.h:3597
#define BuiltinTemplate(BTName)
Definition: ASTContext.h:2199
StringRef P
Defines enum values for all the target-independent builtin functions.
const Decl * D
Expr * E
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static bool DefaultTemplateArgumentContainsUnexpandedPack(const TemplateParam &P)
static bool AdoptTemplateParameterList(TemplateParameterList *Params, DeclContext *Owner)
static TemplateParameterList * createBuiltinTemplateParameterList(const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK)
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
This file contains the declaration of the ODRHash class, which calculates a hash based on AST nodes,...
static StringRef getIdentifier(const Token &Tok)
uint32_t Id
Definition: SemaARM.cpp:1179
SourceRange Range
Definition: SemaObjC.cpp:753
SourceLocation Loc
Definition: SemaObjC.cpp:754
Defines the clang::SourceLocation class and associated facilities.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
Definition: APValue.cpp:703
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2867
QualType getCanonicalTemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > CanonicalArgs) const
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl) const
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:814
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
Definition: ASTContext.h:1339
bool canonicalizeTemplateArguments(MutableArrayRef< TemplateArgument > Args) const
Canonicalize the given template argument list.
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: TypeBase.h:7180
bool isConstrained() const
Definition: TypeBase.h:7199
BuiltinTemplateKind getBuiltinTemplateKind() const
bool isPackProducingBuiltinTemplate() const
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclCXX.h:522
static CanQual< Type > CreateUnsafe(QualType Other)
Builds a canonical type from a QualType.
bool isNull() const
Definition: CanonicalType.h:98
Declaration of a class template.
void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this class template.
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
ClassTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
CommonBase * newCommon(ASTContext &C) const override
static ClassTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a class template node.
ClassTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
ClassTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *D)
Find a class template partial specialization which was instantiated from the given member partial spe...
void LoadLazySpecializations(bool OnlyPartial=false) const
Load any lazily-loaded specializations from the external source.
void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieve the canonical template specialization type of the injected-class-name for this class templat...
Common * getCommonPtr() const
ClassTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
static ClassTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty class template node.
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member class template partial specialization from which this particular class template p...
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieves the canonical injected specialization type for this partial specialization.
void Profile(llvm::FoldingSetNodeID &ID) const
bool isMemberSpecialization() const
Determines whether this class template partial specialization template was a specialization of a memb...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static ClassTemplatePartialSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, CanQualType CanonInjectedTST, ClassTemplatePartialSpecializationDecl *PrevDecl)
static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a class template specialization, which refers to a class template with a given set of temp...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
static ClassTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the class template or class template partial specialization which was specialized by this.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
static ClassTemplateSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
Declaration of a C++20 concept.
static ConceptDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
static ConceptDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr=nullptr)
A reference to a concept and its template args, as it appears in the code.
Definition: ASTConcept.h:126
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1449
bool hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
Definition: DeclBase.h:2688
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:524
ASTMutationListener * getASTMutationListener() const
Definition: DeclBase.cpp:534
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition: DeclBase.cpp:156
Kind
Lists the kind of concrete classes of Decl.
Definition: DeclBase.h:89
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
Definition: DeclBase.h:984
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:978
Kind getKind() const
Definition: DeclBase.h:442
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:779
SourceLocation getOuterLocStart() const
Return start of source range taking into account any outer template declarations.
Definition: Decl.cpp:2050
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2090
unsigned getNumTemplateParameterLists() const
Definition: Decl.h:861
void set(ArgType Arg)
Set the default argument.
Definition: DeclTemplate.h:357
This represents one expression.
Definition: Expr.h:112
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
Definition: Expr.h:241
virtual bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial)
Load all the external specializations for the Decl.
Declaration of a friend template.
static FriendTemplateDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc, MutableArrayRef< TemplateParameterList * > Params, FriendUnion Friend, SourceLocation FriendLoc)
llvm::PointerUnion< NamedDecl *, TypeSourceInfo * > FriendUnion
static FriendTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Represents a function declaration or definition.
Definition: Decl.h:1999
Declaration of a template function.
Definition: DeclTemplate.h:952
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
void addSpecialization(FunctionTemplateSpecializationInfo *Info, void *InsertPos)
Add a specialization of this function template.
CommonBase * newCommon(ASTContext &C) const override
Common * getCommonPtr() const
Definition: DeclTemplate.h:974
FunctionTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...
static FunctionTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty function template node.
static FunctionTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > & getSpecializations() const
Retrieve the set of function template specializations of this function template.
void mergePrevDecl(FunctionTemplateDecl *Prev)
Merge Prev with our RedeclarableTemplateDecl::Common.
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
Provides information about a function template specialization, which is a FunctionDecl that has been ...
Definition: DeclTemplate.h:470
static FunctionTemplateSpecializationInfo * Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs, const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI, MemberSpecializationInfo *MSInfo)
One of these records is kept for each identifier that is lexed.
void setTemplateArguments(ArrayRef< TemplateArgument > Converted)
static ImplicitConceptSpecializationDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef< TemplateArgument > ConvertedArgs)
static ImplicitConceptSpecializationDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs)
Provides information a specialization of a member of a class template, which may be a member function...
Definition: DeclTemplate.h:614
This represents a decl that may have a name.
Definition: Decl.h:273
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:339
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
Definition: Decl.cpp:1834
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
static NonTypeTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint)
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo)
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
A (possibly-)qualified type.
Definition: TypeBase.h:937
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: TypeBase.h:8343
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: TypeBase.h:8437
Declaration of a redeclarable template.
Definition: DeclTemplate.h:715
void loadLazySpecializationsImpl(bool OnlyPartial=false) const
CommonBase * getCommonPtr() const
Retrieves the "common" pointer shared by all (re-)declarations of the same template.
CommonBase * Common
Pointer to the common data shared by all declarations of this template.
Definition: DeclTemplate.h:805
SpecEntryTraits< EntryType >::DeclType * findSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments... ProfileArgs)
virtual CommonBase * newCommon(ASTContext &C) const =0
RedeclarableTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
Definition: DeclTemplate.h:827
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, void *InsertPos)
SpecEntryTraits< EntryType >::DeclType * findSpecializationLocally(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments... ProfileArgs)
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
Definition: DeclTemplate.h:915
RedeclarableTemplateDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Definition: Redeclarable.h:201
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getBegin() const
void setEnd(SourceLocation e)
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition: Decl.h:3800
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3805
unsigned getNumTemplateParameterLists() const
Definition: Decl.h:3965
A convenient class for passing around template argument information.
Definition: TemplateBase.h:634
A template argument list.
Definition: DeclTemplate.h:250
static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument list that copies the given set of template arguments.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Definition: DeclTemplate.h:280
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:528
SourceLocation getLocation() const
Definition: TemplateBase.h:563
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:574
SourceRange getSourceRange() const LLVM_READONLY
Represents a template argument.
Definition: TemplateBase.h:61
bool isNull() const
Determine whether this template argument has no value.
Definition: TemplateBase.h:299
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:396
TemplateParameterList * TemplateParams
Definition: DeclTemplate.h:448
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
bool isTypeAlias() const
bool hasAssociatedConstraints() const
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:429
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclTemplate.h:441
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:415
Represents a C++ template name within the type system.
Definition: TemplateName.h:222
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
A template parameter object.
void printAsExpr(llvm::raw_ostream &OS) const
Print this object as an equivalent expression.
const APValue & getValue() const
void printName(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const override
Print this template parameter object in a human-readable format.
void printAsInit(llvm::raw_ostream &OS) const
Print this object as an initializer suitable for a variable of the object's type.
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:74
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:146
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context)
Get the template argument list of the template parameter list.
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
bool hasAssociatedConstraints() const
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to form a template specialization.
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
Definition: DeclTemplate.h:182
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
All associated constraints derived from this template parameter list, including the requires clause a...
ArrayRef< NamedDecl * > asArray()
Definition: DeclTemplate.h:143
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
SourceLocation getTemplateLoc() const
Definition: DeclTemplate.h:205
Defines the position of a template parameter within a template parameter list.
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
static TemplateTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
static TemplateTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateNameKind ParameterKind, bool Typename, TemplateParameterList *Params)
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
Declaration of a template type parameter.
SourceLocation getDefaultArgumentLoc() const
Retrieves the location of the default argument declaration.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
unsigned getIndex() const
Retrieve the index of the template parameter.
void setTypeConstraint(ConceptReference *CR, Expr *ImmediatelyDeclaredConstraint, UnsignedOrNone ArgPackSubstIndex)
static TemplateTypeParmDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID)
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
bool isParameterPack() const
Returns whether this is a parameter pack.
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, UnsignedOrNone NumExpanded=std::nullopt)
unsigned getDepth() const
Retrieve the depth of the template parameter.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter.
Declaration of an alias template.
CommonBase * newCommon(ASTContext &C) const override
static TypeAliasTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty alias template node.
static TypeAliasTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition: ASTConcept.h:223
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Definition: ASTConcept.h:240
const Type * getTypeForDecl() const
Definition: Decl.h:3531
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.h:3542
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Decl.h:3540
A container of type source information.
Definition: TypeBase.h:8314
QualType getType() const
Return the type wrapped by this type source info.
Definition: TypeBase.h:8325
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition: TypeBase.h:2917
QualType getType() const
Definition: Decl.h:722
Represents a variable declaration or definition.
Definition: Decl.h:925
bool hasInit() const
Definition: Decl.cpp:2398
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2190
@ Definition
This declaration is definitely a definition.
Definition: Decl.h:1300
Declaration of a variable template.
VarTemplateDecl * getDefinition()
VarTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
Common * getCommonPtr() const
VarTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
VarTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this variable template, or nullptr if no such declaration exists...
CommonBase * newCommon(ASTContext &C) const override
void LoadLazySpecializations(bool OnlyPartial=false) const
Load any lazily-loaded specializations from the external source.
static VarTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty variable template node.
static VarTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, VarDecl *Decl)
Create a variable template node.
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this variable template.
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary variable pattern.
VarTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
VarTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl *D)
Find a variable template partial specialization which was instantiated from the given member partial ...
static VarTemplatePartialSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
VarTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member variable template partial specialization from which this particular variable temp...
bool isMemberSpecialization() const
Determines whether this variable template partial specialization was a specialization of a member par...
void Profile(llvm::FoldingSetNodeID &ID) const
static VarTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Represents a variable template specialization, which refers to a variable template with a given set o...
VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static VarTemplateSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the variable template or variable template partial specialization which was specialized by t...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
VarTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
static VarTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
The JSON file list parser is used to communicate input to InstallAPI.
bool isPackProducingBuiltinTemplateName(TemplateName N)
StorageClass
Storage classes.
Definition: Specifiers.h:248
@ SC_None
Definition: Specifiers.h:250
UnsignedOrNone getExpandedPackSize(const NamedDecl *Param)
Check whether the template parameter is a pack expansion, and if so, determine the number of paramete...
void * allocateDefaultArgStorageChain(const ASTContext &C)
@ Result
The result type of a method or function.
@ Template
We are parsing a template declaration.
TagTypeKind
The kind of a tag type.
Definition: TypeBase.h:5906
BuiltinTemplateKind
Kinds of BuiltinTemplateDecl.
Definition: Builtins.h:462
TemplateNameKind
Specifies the kind of template name that an identifier refers to.
Definition: TemplateKinds.h:20
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
Definition: TemplateKinds.h:30
TemplateParameterList * getReplacedTemplateParameterList(const Decl *D)
Internal helper used by Subst* nodes to retrieve the parameter list for their AssociatedDecl.
const FunctionProtoType * T
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
Definition: Specifiers.h:188
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition: Specifiers.h:206
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition: Specifiers.h:202
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition: Specifiers.h:198
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition: Specifiers.h:194
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:191
@ Struct
The "struct" keyword introduces the elaborated-type-specifier.
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
#define true
Definition: stdbool.h:25
#define false
Definition: stdbool.h:26
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:678
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
Data that is common to all of the declarations of a given class template.
CanQualType CanonInjectedTST
The Injected Template Specialization Type for this declaration.
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > PartialSpecializations
The class template partial specializations for this class template.
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > Specializations
The class template specializations for this class template, including explicit specializations and in...
A placeholder type used to construct an empty shell of a decl-derived type that will be filled in lat...
Definition: DeclBase.h:102
Provides information about an explicit instantiation of a variable or class template.
const ASTTemplateArgumentListInfo * TemplateArgsAsWritten
The template arguments as written..
Data that is common to all of the declarations of a given function template.
Definition: DeclTemplate.h:958
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > Specializations
The function template specializations for this function template, including explicit specializations ...
Definition: DeclTemplate.h:961
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
unsigned AlwaysIncludeTypeForTemplateArgument
Whether to use type suffixes (eg: 1U) on integral non-type template parameters.
Data that is common to all of the declarations of a given variable template.
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > PartialSpecializations
The variable template partial specializations for this variable template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > Specializations
The variable template specializations for this variable template, including explicit specializations ...