clang 24.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
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
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
288
289void TemplateDecl::anchor() {}
290
293 TemplateParams->getAssociatedConstraints(ACs);
294 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
295 if (const AssociatedConstraint &TRC = FD->getTrailingRequiresClause())
296 ACs.emplace_back(TRC);
297}
298
300 if (TemplateParams->hasAssociatedConstraints())
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
375
376template <class EntryType, typename... ProfileArguments>
379 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
380 ProfileArguments... ProfileArgs) {
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>
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>
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.
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
432 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
433 SETraits::getDecl(Entry));
434}
435
436//===----------------------------------------------------------------------===//
437// FunctionTemplateDecl Implementation
438//===----------------------------------------------------------------------===//
439
442 DeclarationName Name,
444 assert(!Params->empty() && "template with no template parameters");
446 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
447 if (Invalid)
448 TD->setInvalidDecl();
449 return TD;
450}
451
454 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
455 DeclarationName(), nullptr, nullptr);
456}
457
460 auto *CommonPtr = new (C) Common;
461 C.addDestruction(CommonPtr);
462 return CommonPtr;
463}
464
468
469llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
474
477 void *&InsertPos) {
478 auto *Common = getCommonPtr();
479 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
480}
481
488
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;
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(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
529 DeclarationName Name,
530 TemplateParameterList *Params,
531 NamedDecl *Decl) {
532 assert(!Params->empty() && "template with no template parameters");
534 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
535 if (Invalid)
536 TD->setInvalidDecl();
537 return TD;
538}
539
541 GlobalDeclID ID) {
542 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
543 DeclarationName(), nullptr, nullptr);
544}
545
550
551llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
556
557llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
562
565 auto *CommonPtr = new (C) Common;
566 C.addDestruction(CommonPtr);
567 return CommonPtr;
568}
569
572 void *&InsertPos) {
573 auto *Common = getCommonPtr();
574 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
575}
576
583
591
593 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
594 TemplateParameterList *TPL, const ASTContext &Context) {
595 ID.AddInteger(TemplateArgs.size());
596 for (const TemplateArgument &TemplateArg : TemplateArgs)
597 TemplateArg.Profile(ID, Context);
598 TPL->Profile(ID, Context);
599}
600
603 void *InsertPos) {
604 if (InsertPos)
605 getPartialSpecializations().InsertNode(D, InsertPos);
606 else {
608 = getPartialSpecializations().GetOrInsertNode(D);
609 (void)Existing;
610 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
611 }
612
614 L->AddedCXXTemplateSpecialization(this, D);
615}
616
619 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
621 PS.clear();
622 PS.reserve(PartialSpecs.size());
623 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
624 PS.push_back(P.getMostRecentDecl());
625}
626
629 ASTContext &Context = getASTContext();
632 if (Context.hasSameType(P.getCanonicalInjectedSpecializationType(Context),
633 T))
634 return P.getMostRecentDecl();
635 }
636
637 return nullptr;
638}
639
643 Decl *DCanon = D->getCanonicalDecl();
645 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
646 return P.getMostRecentDecl();
647 }
648
649 return nullptr;
650}
651
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>(HasTypeConstraint ? 1 : 0))
680 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
681 HasTypeConstraint, NumExpanded);
682 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
683 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
684 return TTPDecl;
685}
686
689 return new (C, ID)
690 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
691 false, false, std::nullopt);
692}
693
696 bool HasTypeConstraint) {
697 return new (C, ID,
698 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
699 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
700 false, HasTypeConstraint, std::nullopt);
701}
702
707
710 return SourceRange(getBeginLoc(),
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());
718}
719
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
729 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->getDepth();
730}
731
733 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->getIndex();
734}
735
737 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->isParameterPack();
738}
739
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 0, 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 ExpandedTypes.size(), 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
812 bool HasTypeConstraint) {
813 auto *NTTP =
814 new (C, ID,
815 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
816 0, 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
826 unsigned NumExpandedTypes,
827 bool HasTypeConstraint) {
828 auto *NTTP =
829 new (C, ID,
830 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
831 NumExpandedTypes, 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
846
851
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,
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(Expansions, 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
888 SourceLocation L, int D, int P,
890 bool Typename, TemplateParameterList *Params,
892 assert(!Params->empty() && "template with no template parameters");
893 return new (C, DC,
894 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
895 TemplateTemplateParmDecl(DC, L, D, P, Id, Kind, Typename, Params,
896 Expansions);
897}
898
901 return new (C, ID) TemplateTemplateParmDecl(
902 nullptr, SourceLocation(), 0, 0, false, nullptr,
904}
905
908 unsigned NumExpansions) {
909 auto *TTP =
910 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
911 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
913 nullptr, {});
914 TTP->NumExpandedParams = NumExpansions;
915 return TTP;
916}
917
922
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(Args, getTrailingObjects());
937}
938
942 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
943 return new (Mem) TemplateArgumentList(Args);
944}
945
946FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
949 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
950 MemberSpecializationInfo *MSInfo) {
951 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
952 if (TemplateArgsAsWritten)
954 *TemplateArgsAsWritten);
955
956 void *Mem =
957 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
958 return new (Mem) FunctionTemplateSpecializationInfo(
959 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
960}
961
962//===----------------------------------------------------------------------===//
963// ClassTemplateSpecializationDecl Implementation
964//===----------------------------------------------------------------------===//
965
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
984
986 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
987 SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate,
988 ArrayRef<TemplateArgument> Args, bool StrictPackMatch,
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
1007 GlobalDeclID ID) {
1008 return new (C, ID)
1009 ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
1010}
1011
1013 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1015
1016 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
1017 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1018 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1019 printTemplateArgumentList(
1020 OS, ArgsAsWritten->arguments(), Policy,
1021 getSpecializedTemplate()->getTemplateParameters());
1022 } else {
1023 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1024 printTemplateArgumentList(
1025 OS, TemplateArgs.asArray(), Policy,
1026 getSpecializedTemplate()->getTemplateParameters());
1027 }
1028}
1029
1032 if (const auto *PartialSpec =
1033 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
1034 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1035 return cast<ClassTemplateDecl *>(SpecializedTemplate);
1036}
1037
1040 switch (getSpecializationKind()) {
1041 case TSK_Undeclared:
1043 llvm::PointerUnion<ClassTemplateDecl *,
1046 assert(!Pattern.isNull() &&
1047 "Class template specialization without pattern?");
1048 if (const auto *CTPSD =
1049 dyn_cast<ClassTemplatePartialSpecializationDecl *>(Pattern))
1050 return CTPSD->getSourceRange();
1051 return cast<ClassTemplateDecl *>(Pattern)->getSourceRange();
1052 }
1057 Range.setEnd(Args->getRAngleLoc());
1058 return Range;
1059 }
1063 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1064 Range.setBegin(ExternKW);
1065 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1066 TemplateKW.isValid())
1067 Range.setBegin(TemplateKW);
1069 Range.setEnd(Args->getRAngleLoc());
1070 return Range;
1071 }
1072 }
1073 llvm_unreachable("unhandled template specialization kind");
1074}
1075
1077 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1078 if (!Info) {
1079 // Don't allocate if the location is invalid.
1080 if (Loc.isInvalid())
1081 return;
1084 ExplicitInfo = Info;
1085 }
1086 Info->ExternKeywordLoc = Loc;
1087}
1088
1090 SourceLocation Loc) {
1091 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1092 if (!Info) {
1093 // Don't allocate if the location is invalid.
1094 if (Loc.isInvalid())
1095 return;
1098 ExplicitInfo = Info;
1099 }
1100 Info->TemplateKeywordLoc = Loc;
1101}
1102
1103//===----------------------------------------------------------------------===//
1104// ConceptDecl Implementation
1105//===----------------------------------------------------------------------===//
1108 TemplateParameterList *Params,
1110 assert(!Params->empty() && "template with no template parameters");
1111 bool Invalid = AdoptTemplateParameterList(Params, DC);
1112 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1113 if (Invalid)
1114 TD->setInvalidDecl();
1115 return TD;
1116}
1117
1119 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1121 nullptr, nullptr);
1122
1123 return Result;
1124}
1125
1126//===----------------------------------------------------------------------===//
1127// ImplicitConceptSpecializationDecl Implementation
1128//===----------------------------------------------------------------------===//
1129ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
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>(ConvertedArgs.size()))
1147 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1148}
1149
1152 const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) {
1153 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1154 ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);
1155}
1156
1158 ArrayRef<TemplateArgument> Converted) {
1159 assert(Converted.size() == NumTemplateArgs);
1160 llvm::uninitialized_copy(Converted, getTrailingObjects());
1161}
1162
1163//===----------------------------------------------------------------------===//
1164// ClassTemplatePartialSpecializationDecl Implementation
1165//===----------------------------------------------------------------------===//
1166void ClassTemplatePartialSpecializationDecl::anchor() {}
1167
1168ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
1169 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1171 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1172 CanQualType CanonInjectedTST,
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, this))
1183}
1184
1187 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
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
1202 GlobalDeclID ID) {
1203 return new (C, ID) ClassTemplatePartialSpecializationDecl(C);
1204}
1205
1208 const ASTContext &Ctx) const {
1209 if (CanonInjectedTST.isNull()) {
1210 CanonInjectedTST =
1214 getTemplateArgs().asArray()));
1215 }
1216 return CanonInjectedTST;
1217}
1218
1220 if (const ClassTemplatePartialSpecializationDecl *MT =
1222 MT && !isMemberSpecialization())
1223 return MT->getSourceRange();
1227 Range.setBegin(TPL->getTemplateLoc());
1228 return Range;
1229}
1230
1231//===----------------------------------------------------------------------===//
1232// FriendTemplateDecl Implementation
1233//===----------------------------------------------------------------------===//
1234
1235void FriendTemplateDecl::anchor() {}
1236
1240 SourceLocation FriendLoc,
1242 SourceLocation EllipsisLoc, TemplateName Template) {
1243 std::size_t Extra =
1244 FriendTemplateDecl::additionalSizeToAlloc<TemplateParameterList *>(
1245 FriendTPLists.size());
1246 auto *FTD = new (Context, DC, Extra) FriendTemplateDecl(
1247 DC, Loc, Friend, FriendLoc, EllipsisLoc, FriendTPLists, Template);
1248 cast<CXXRecordDecl>(DC)->pushFriendDecl(FTD);
1249 return FTD;
1250}
1251
1254 SourceLocation Loc, TemplateName Template,
1255 SourceLocation FriendLoc,
1257 SourceLocation EllipsisLoc) {
1258 auto *Friend = Template.getAsTemplateDecl();
1259 assert(Friend && "friend template name must be resolved");
1260 std::size_t Extra =
1261 FriendTemplateDecl::additionalSizeToAlloc<TemplateParameterList *>(
1262 FriendTPLists.size());
1263 auto *FTD = new (Context, DC, Extra) FriendTemplateDecl(
1264 DC, Loc, Friend, FriendLoc, EllipsisLoc, FriendTPLists, Template);
1265 cast<CXXRecordDecl>(DC)->pushFriendDecl(FTD);
1266 return FTD;
1267}
1268
1271 unsigned NumFriendTPLists) {
1272 std::size_t Extra =
1273 FriendTemplateDecl::additionalSizeToAlloc<TemplateParameterList *>(
1274 NumFriendTPLists);
1275 return new (C, ID, Extra) FriendTemplateDecl(EmptyShell(), NumFriendTPLists);
1276}
1277
1279 SourceLocation Begin = getTemplateParameterLists().front()->getTemplateLoc();
1280 SourceLocation End =
1281 !Template.isNull() && !getFriendType()
1284 return SourceRange(Begin, End);
1285}
1286
1287//===----------------------------------------------------------------------===//
1288// TypeAliasTemplateDecl Implementation
1289//===----------------------------------------------------------------------===//
1290
1293 DeclarationName Name,
1295 assert(!Params->empty() && "template with no template parameters");
1296 bool Invalid = AdoptTemplateParameterList(Params, DC);
1297 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1298 if (Invalid)
1299 TD->setInvalidDecl();
1300 return TD;
1301}
1302
1305 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1306 DeclarationName(), nullptr, nullptr);
1307}
1308
1311 auto *CommonPtr = new (C) Common;
1312 C.addDestruction(CommonPtr);
1313 return CommonPtr;
1314}
1315
1316//===----------------------------------------------------------------------===//
1317// VarTemplateDecl Implementation
1318//===----------------------------------------------------------------------===//
1319
1321 VarTemplateDecl *CurD = this;
1322 while (CurD) {
1323 if (CurD->isThisDeclarationADefinition())
1324 return CurD;
1325 CurD = CurD->getPreviousDecl();
1326 }
1327 return nullptr;
1328}
1329
1332 TemplateParameterList *Params,
1333 VarDecl *Decl) {
1334 assert(!Params->empty() && "template with no template parameters");
1335 bool Invalid = AdoptTemplateParameterList(Params, DC);
1336 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1337 if (Invalid)
1338 TD->setInvalidDecl();
1339 return TD;
1340}
1341
1343 GlobalDeclID ID) {
1344 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1345 DeclarationName(), nullptr, nullptr);
1346}
1347
1352
1353llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1358
1359llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1364
1367 auto *CommonPtr = new (C) Common;
1368 C.addDestruction(CommonPtr);
1369 return CommonPtr;
1370}
1371
1374 void *&InsertPos) {
1375 auto *Common = getCommonPtr();
1376 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
1377}
1378
1384
1391
1393 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1394 TemplateParameterList *TPL, const ASTContext &Context) {
1395 ID.AddInteger(TemplateArgs.size());
1396 for (const TemplateArgument &TemplateArg : TemplateArgs)
1397 TemplateArg.Profile(ID, Context);
1398 TPL->Profile(ID, Context);
1399}
1400
1402 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1403 if (InsertPos)
1404 getPartialSpecializations().InsertNode(D, InsertPos);
1405 else {
1407 getPartialSpecializations().GetOrInsertNode(D);
1408 (void)Existing;
1409 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1410 }
1411
1413 L->AddedCXXTemplateSpecialization(this, D);
1414}
1415
1418 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1420 PS.clear();
1421 PS.reserve(PartialSpecs.size());
1422 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1423 PS.push_back(P.getMostRecentDecl());
1424}
1425
1429 Decl *DCanon = D->getCanonicalDecl();
1431 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1432 return P.getMostRecentDecl();
1433 }
1434
1435 return nullptr;
1436}
1437
1438//===----------------------------------------------------------------------===//
1439// VarTemplateSpecializationDecl Implementation
1440//===----------------------------------------------------------------------===//
1441
1443 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1444 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1446 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1447 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1448 SpecializedTemplate(SpecializedTemplate),
1449 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1450 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1451
1453 ASTContext &C)
1456 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1457
1459 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1460 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1462 return new (Context, DC) VarTemplateSpecializationDecl(
1463 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1464 SpecializedTemplate, T, TInfo, S, Args);
1465}
1466
1469 GlobalDeclID ID) {
1470 return new (C, ID)
1471 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1472}
1473
1475 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1477
1478 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1479 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1480 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1481 printTemplateArgumentList(
1482 OS, ArgsAsWritten->arguments(), Policy,
1483 getSpecializedTemplate()->getTemplateParameters());
1484 } else {
1485 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1486 printTemplateArgumentList(
1487 OS, TemplateArgs.asArray(), Policy,
1488 getSpecializedTemplate()->getTemplateParameters());
1489 }
1490}
1491
1493 if (const auto *PartialSpec =
1494 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1495 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1496 return cast<VarTemplateDecl *>(SpecializedTemplate);
1497}
1498
1500 switch (getSpecializationKind()) {
1501 case TSK_Undeclared:
1503 llvm::PointerUnion<VarTemplateDecl *,
1506 assert(!Pattern.isNull() &&
1507 "Variable template specialization without pattern?");
1508 if (const auto *VTPSD =
1509 dyn_cast<VarTemplatePartialSpecializationDecl *>(Pattern))
1510 return VTPSD->getSourceRange();
1512 if (hasInit()) {
1514 return Definition->getSourceRange();
1515 }
1516 return VTD->getCanonicalDecl()->getSourceRange();
1517 }
1521 !hasInit() && Args)
1522 Range.setEnd(Args->getRAngleLoc());
1523 return Range;
1524 }
1528 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1529 Range.setBegin(ExternKW);
1530 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1531 TemplateKW.isValid())
1532 Range.setBegin(TemplateKW);
1534 Range.setEnd(Args->getRAngleLoc());
1535 return Range;
1536 }
1537 }
1538 llvm_unreachable("unhandled template specialization kind");
1539}
1540
1542 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1543 if (!Info) {
1544 // Don't allocate if the location is invalid.
1545 if (Loc.isInvalid())
1546 return;
1549 ExplicitInfo = Info;
1550 }
1551 Info->ExternKeywordLoc = Loc;
1552}
1553
1555 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1556 if (!Info) {
1557 // Don't allocate if the location is invalid.
1558 if (Loc.isInvalid())
1559 return;
1562 ExplicitInfo = Info;
1563 }
1564 Info->TemplateKeywordLoc = Loc;
1565}
1566
1567//===----------------------------------------------------------------------===//
1568// VarTemplatePartialSpecializationDecl Implementation
1569//===----------------------------------------------------------------------===//
1570
1571void VarTemplatePartialSpecializationDecl::anchor() {}
1572
1573VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1574 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1576 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1578 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1579 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1580 TInfo, S, Args),
1581 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1582 if (AdoptTemplateParameterList(Params, DC))
1584}
1585
1588 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1590 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1592 assert(!Params->empty() && "template with no template parameters");
1593 auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(
1594 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,
1595 Args);
1596 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1597 return Result;
1598}
1599
1602 GlobalDeclID ID) {
1603 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1604}
1605
1607 if (const VarTemplatePartialSpecializationDecl *MT =
1609 MT && !isMemberSpecialization())
1610 return MT->getSourceRange();
1614 Range.setBegin(TPL->getTemplateLoc());
1615 return Range;
1616}
1617
1619 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1620 switch (BTK) {
1621#define CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST
1622#include "clang/Basic/BuiltinTemplates.inc"
1623 }
1624
1625 llvm_unreachable("unhandled BuiltinTemplateKind!");
1626}
1627
1628void BuiltinTemplateDecl::anchor() {}
1629
1630BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1631 DeclarationName Name,
1635 BTK(BTK) {}
1636
1638 return getBuiltinTemplateKind() == clang::BTK__builtin_dedup_pack;
1639}
1640
1642 auto *T = dyn_cast_or_null<BuiltinTemplateDecl>(
1643 N.getAsTemplateDecl(/*IgnoreDeduced=*/true));
1644 return T && T->isPackProducingBuiltinTemplate();
1645}
1646
1647TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1648 QualType T,
1649 const APValue &V) {
1650 DeclContext *DC = C.getTranslationUnitDecl();
1651 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1652 C.addDestruction(&TPOD->Value);
1653 return TPOD;
1654}
1655
1657TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1658 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1659 C.addDestruction(&TPOD->Value);
1660 return TPOD;
1661}
1662
1663void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1664 const PrintingPolicy &Policy) const {
1665 OS << "<template param ";
1666 printAsExpr(OS, Policy);
1667 OS << ">";
1668}
1669
1670void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1671 printAsExpr(OS, getASTContext().getPrintingPolicy());
1672}
1673
1674void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1675 const PrintingPolicy &Policy) const {
1676 getType().getUnqualifiedType().print(OS, Policy);
1677 printAsInit(OS, Policy);
1678}
1679
1680void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1681 printAsInit(OS, getASTContext().getPrintingPolicy());
1682}
1683
1684void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1685 const PrintingPolicy &Policy) const {
1686 getValue().printPretty(OS, Policy, getType(), &getASTContext());
1687}
1688
1689std::tuple<NamedDecl *, TemplateArgument>
1691 switch (D->getKind()) {
1692 case Decl::Kind::BuiltinTemplate:
1693 case Decl::Kind::ClassTemplate:
1694 case Decl::Kind::Concept:
1695 case Decl::Kind::FunctionTemplate:
1696 case Decl::Kind::TemplateTemplateParm:
1697 case Decl::Kind::TypeAliasTemplate:
1698 case Decl::Kind::VarTemplate:
1699 return {cast<TemplateDecl>(D)->getTemplateParameters()->getParam(Index),
1700 {}};
1701 case Decl::Kind::ClassTemplateSpecialization: {
1702 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1703 auto P = CTSD->getSpecializedTemplateOrPartial();
1704 if (const auto *CTPSD =
1705 dyn_cast<ClassTemplatePartialSpecializationDecl *>(P)) {
1706 TemplateParameterList *TPL = CTPSD->getTemplateParameters();
1707 return {TPL->getParam(Index),
1708 CTSD->getTemplateInstantiationArgs()[Index]};
1709 }
1711 cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1712 return {TPL->getParam(Index), CTSD->getTemplateArgs()[Index]};
1713 }
1714 case Decl::Kind::VarTemplateSpecialization: {
1715 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1716 auto P = VTSD->getSpecializedTemplateOrPartial();
1717 if (const auto *VTPSD =
1718 dyn_cast<VarTemplatePartialSpecializationDecl *>(P)) {
1719 TemplateParameterList *TPL = VTPSD->getTemplateParameters();
1720 return {TPL->getParam(Index),
1721 VTSD->getTemplateInstantiationArgs()[Index]};
1722 }
1724 cast<VarTemplateDecl *>(P)->getTemplateParameters();
1725 return {TPL->getParam(Index), VTSD->getTemplateArgs()[Index]};
1726 }
1727 case Decl::Kind::ClassTemplatePartialSpecialization:
1729 ->getTemplateParameters()
1730 ->getParam(Index),
1731 {}};
1732 case Decl::Kind::VarTemplatePartialSpecialization:
1734 ->getTemplateParameters()
1735 ->getParam(Index),
1736 {}};
1737 // This is used as the AssociatedDecl for placeholder type deduction.
1738 case Decl::TemplateTypeParm:
1739 return {cast<NamedDecl>(D), {}};
1740 // FIXME: Always use the template decl as the AssociatedDecl.
1741 case Decl::Kind::CXXRecord:
1743 cast<CXXRecordDecl>(D)->getDescribedClassTemplate(), Index);
1744 case Decl::Kind::CXXDeductionGuide:
1745 case Decl::Kind::CXXConversion:
1746 case Decl::Kind::CXXConstructor:
1747 case Decl::Kind::CXXDestructor:
1748 case Decl::Kind::CXXMethod:
1749 case Decl::Kind::Function: {
1751 cast<FunctionDecl>(D)->getTemplateSpecializationInfo();
1752 return {Info->getTemplate()->getTemplateParameters()->getParam(Index),
1753 Info->TemplateArguments->asArray()[Index]};
1754 }
1755 case Decl::Kind::CXXExpansionStmt:
1756 assert(Index == 0 && "expansion stmts only have a single template param");
1757 return {cast<CXXExpansionStmtDecl>(D)->getIndexTemplateParm(), {}};
1758 default:
1759 llvm_unreachable("Unhandled templated declaration kind");
1760 }
1761}
1762
1764 if (const auto *FD = dyn_cast<FunctionDecl>(&D)) {
1765 // Is this function declaration part of a function template?
1766 if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate())
1767 return *FTD;
1768
1769 // Nothing to do if function is not an implicit instantiation.
1770 if (FD->getTemplateSpecializationKind() != TSK_ImplicitInstantiation)
1771 return D;
1772
1773 // Function is an implicit instantiation of a function template?
1774 if (const FunctionTemplateDecl *FTD = FD->getPrimaryTemplate())
1775 return *FTD;
1776
1777 // Function is instantiated from a member definition of a class template?
1778 if (const FunctionDecl *MemberDecl =
1780 return *MemberDecl;
1781
1782 return D;
1783 }
1784 if (const auto *VD = dyn_cast<VarDecl>(&D)) {
1785 // Static data member is instantiated from a member definition of a class
1786 // template?
1787 if (VD->isStaticDataMember())
1788 if (const VarDecl *MemberDecl = VD->getInstantiatedFromStaticDataMember())
1789 return *MemberDecl;
1790
1791 return D;
1792 }
1793 if (const auto *CRD = dyn_cast<CXXRecordDecl>(&D)) {
1794 // Is this class declaration part of a class template?
1795 if (const ClassTemplateDecl *CTD = CRD->getDescribedClassTemplate())
1796 return *CTD;
1797
1798 // Class is an implicit instantiation of a class template or partial
1799 // specialization?
1800 if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(CRD)) {
1801 if (CTSD->getSpecializationKind() != TSK_ImplicitInstantiation)
1802 return D;
1803 llvm::PointerUnion<ClassTemplateDecl *,
1806 return isa<ClassTemplateDecl *>(PU)
1807 ? *static_cast<const Decl *>(cast<ClassTemplateDecl *>(PU))
1808 : *static_cast<const Decl *>(
1810 }
1811
1812 // Class is instantiated from a member definition of a class template?
1813 if (const MemberSpecializationInfo *Info =
1814 CRD->getMemberSpecializationInfo())
1815 return *Info->getInstantiatedFrom();
1816
1817 return D;
1818 }
1819 if (const auto *ED = dyn_cast<EnumDecl>(&D)) {
1820 // Enum is instantiated from a member definition of a class template?
1821 if (const EnumDecl *MemberDecl = ED->getInstantiatedFromMemberEnum())
1822 return *MemberDecl;
1823
1824 return D;
1825 }
1826 // FIXME: Adjust alias templates?
1827 return D;
1828}
1829
1830ExplicitInstantiationDecl::ExplicitInstantiationDecl(
1832 SourceLocation TemplateLoc, NestedNameSpecifierLoc QualifierLoc,
1833 const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc,
1834 TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK)
1835 : Decl(ExplicitInstantiation, DC, TemplateLoc),
1836 SpecAndTSK(Specialization, TSK), ExternLoc(ExternLoc), NameLoc(NameLoc) {
1837 unsigned Flags = 0;
1838 if (QualifierLoc)
1839 Flags |= HasQualifierFlag;
1840 if (ArgsAsWritten)
1841 Flags |= HasArgsAsWrittenFlag;
1842 // Set flags BEFORE writing trailing objects, because
1843 // numTrailingObjects reads TypeAndFlags.getInt() to compute offsets.
1844 TypeAndFlags.setPointerAndInt(TypeAsWritten, Flags);
1845 if (QualifierLoc)
1846 *getTrailingObjects<NestedNameSpecifierLoc>() = QualifierLoc;
1847 if (ArgsAsWritten)
1848 *getTrailingObjects<const ASTTemplateArgumentListInfo *>() = ArgsAsWritten;
1849}
1850
1851ExplicitInstantiationDecl *ExplicitInstantiationDecl::Create(
1853 SourceLocation ExternLoc, SourceLocation TemplateLoc,
1854 NestedNameSpecifierLoc QualifierLoc,
1855 const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc,
1856 TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK) {
1857 unsigned Extra = additionalSizeToAlloc<NestedNameSpecifierLoc,
1859 QualifierLoc ? 1 : 0, ArgsAsWritten ? 1 : 0);
1860 return new (C, DC, Extra) ExplicitInstantiationDecl(
1861 DC, Specialization, ExternLoc, TemplateLoc, QualifierLoc, ArgsAsWritten,
1862 NameLoc, TypeAsWritten, TSK);
1863}
1864
1867 unsigned TrailingFlags) {
1868 unsigned Extra = additionalSizeToAlloc<NestedNameSpecifierLoc,
1870 (TrailingFlags & HasQualifierFlag) ? 1 : 0,
1871 (TrailingFlags & HasArgsAsWrittenFlag) ? 1 : 0);
1872 auto *D = new (C, ID, Extra) ExplicitInstantiationDecl(EmptyShell());
1873 // Set the flags so the reader knows which trailing objects are present.
1874 D->TypeAndFlags.setInt(TrailingFlags);
1875 return D;
1876}
1877
1879 if (auto TL = getClassTypeLoc()) {
1880 if (auto TST = TL->getAs<TemplateSpecializationTypeLoc>())
1881 return TST.getElaboratedKeywordLoc();
1882 if (auto Tag = TL->getAs<TagTypeLoc>())
1883 return Tag.getElaboratedKeywordLoc();
1884 }
1885 return SourceLocation();
1886}
1887
1890 return *getTrailingObjects<NestedNameSpecifierLoc>();
1891 if (auto TL = getClassTypeLoc())
1892 return TL->getPrefix();
1893 return NestedNameSpecifierLoc();
1894}
1895
1897 // For class-like entities, TSI encodes the class itself, not a declared type.
1898 if (getClassTypeLoc())
1899 return nullptr;
1900 return getRawTypeSourceInfo();
1901}
1902
1903std::optional<unsigned> ExplicitInstantiationDecl::getNumTemplateArgs() const {
1904 if (const auto *Args = getTrailingArgsInfo())
1905 return Args->NumTemplateArgs;
1906 if (auto TL = getClassTypeLoc())
1907 if (auto TST = TL->getAs<TemplateSpecializationTypeLoc>())
1908 return TST.getNumArgs();
1909 return std::nullopt;
1910}
1911
1914 if (const auto *Args = getTrailingArgsInfo())
1915 return (*Args)[I];
1916 if (auto TL = getClassTypeLoc())
1917 if (auto TST = TL->getAs<TemplateSpecializationTypeLoc>())
1918 return TST.getArgLoc(I);
1919 llvm_unreachable("template arguments not found in trailing args or TypeLoc");
1920}
1921
1923 if (const auto *Args = getTrailingArgsInfo())
1924 return Args->getLAngleLoc();
1925 if (auto TL = getClassTypeLoc())
1926 if (auto TST = TL->getAs<TemplateSpecializationTypeLoc>())
1927 return TST.getLAngleLoc();
1928 llvm_unreachable("template arguments not found in trailing args or TypeLoc");
1929}
1930
1932 if (const auto *Args = getTrailingArgsInfo())
1933 return Args->getRAngleLoc();
1934 if (auto TL = getClassTypeLoc())
1935 if (auto TST = TL->getAs<TemplateSpecializationTypeLoc>())
1936 return TST.getRAngleLoc();
1937 llvm_unreachable("template arguments not found in trailing args or TypeLoc");
1938}
1939
1941 // For func/var templates with postfix type syntax (arrays, functions),
1942 // the type extends past the name, so use the type's end location.
1943 if (auto *TSI = getTypeAsWritten())
1944 if (TSI->getType().hasPostfixDeclaratorSyntax())
1945 return TSI->getTypeLoc().getEndLoc();
1946 // Otherwise, template args RAngleLoc or NameLoc.
1947 if (getNumTemplateArgs()) {
1949 if (RAngle.isValid())
1950 return RAngle;
1951 }
1952 return NameLoc;
1953}
1954
1956 SourceLocation Begin = ExternLoc.isValid() ? ExternLoc : getLocation();
1957 return SourceRange(Begin, getEndLoc());
1958}
1959
1960CXXExpansionStmtDecl::CXXExpansionStmtDecl(DeclContext *DC, SourceLocation Loc,
1962 : Decl(CXXExpansionStmt, DC, Loc), DeclContext(CXXExpansionStmt),
1963 IndexNTTP(NTTP) {}
1964
1968 return new (C, DC) CXXExpansionStmtDecl(DC, Loc, NTTP);
1969}
1972 return new (C, ID)
1973 CXXExpansionStmtDecl(/*DC=*/nullptr, SourceLocation(), /*NTTP=*/nullptr);
1974}
1975
1977 return Pattern ? Pattern->getSourceRange() : SourceRange();
1978}
Defines the clang::ASTContext interface.
#define V(N, I)
#define BuiltinTemplate(BTName)
Definition ASTContext.h:475
Defines enum values for all the target-independent builtin functions.
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)
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:711
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
QualType getCanonicalTemplateSpecializationType(ElaboratedTypeKeyword Keyword, TemplateName T, ArrayRef< TemplateArgument > CanonicalArgs) const
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl) const
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
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...
BuiltinTemplateKind getBuiltinTemplateKind() const
bool isPackProducingBuiltinTemplate() const
Represents a C++26 expansion statement declaration.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static CXXExpansionStmtDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
static CXXExpansionStmtDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, NonTypeTemplateParmDecl *NTTP)
CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl)
Definition DeclCXX.cpp:125
friend class DeclContext
Definition DeclCXX.h:266
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition DeclCXX.h:522
static CanQual< Type > CreateUnsafe(QualType Other)
bool isNull() const
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.
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...
ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
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 the given declaration.
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.
ConceptDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr)
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:130
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1466
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:550
ASTMutationListener * getASTMutationListener() const
Definition DeclBase.cpp:560
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition DeclBase.cpp:178
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:1001
bool isInvalidDecl() const
Definition DeclBase.h:596
SourceLocation getLocation() const
Definition DeclBase.h:447
bool isTemplateParameterPack() const
isTemplateParameter - Determines whether this declaration is a template parameter pack.
Definition DeclBase.cpp:256
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
Definition DeclBase.cpp:385
friend class DeclContext
Definition DeclBase.h:260
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition DeclBase.h:995
Kind getKind() const
Definition DeclBase.h:450
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
Definition Decl.h:780
SourceLocation getOuterLocStart() const
Return start of source range taking into account any outer template declarations.
Definition Decl.cpp:2067
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2071
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
Definition Decl.h:862
Represents an enum.
Definition Decl.h:4145
EnumDecl * getInstantiatedFromMemberEnum() const
Returns the enumeration (declared within the template) from which this enumeration type was instantia...
Definition Decl.cpp:5217
Represents an explicit instantiation of a template entity in source code.
SourceLocation getEndLoc() const LLVM_READONLY
static ExplicitInstantiationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned TrailingFlags)
TypeSourceInfo * getTypeAsWritten() const
The declared type (return type or variable type) for function / variable templates.
SourceLocation getTemplateArgsLAngleLoc() const
std::optional< unsigned > getNumTemplateArgs() const
Returns the number of explicit template arguments, or std::nullopt if this entity has no template arg...
TemplateArgumentLoc getTemplateArg(unsigned I) const
SourceLocation getTemplateArgsRAngleLoc() const
SourceLocation getTagKWLoc() const
The tag keyword (struct/class/union) location for class templates / nested classes; invalid for funct...
NestedNameSpecifierLoc getQualifierLoc() const
Returns the qualifier regardless of where it is stored.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static ExplicitInstantiationDecl * Create(ASTContext &C, DeclContext *DC, NamedDecl *Specialization, SourceLocation ExternLoc, SourceLocation TemplateLoc, NestedNameSpecifierLoc QualifierLoc, const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc, TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK)
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.
llvm::PointerUnion< NamedDecl *, TypeSourceInfo * > FriendUnion
Definition DeclFriend.h:50
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
FriendUnion Friend
Definition DeclFriend.h:63
SourceLocation getEllipsisLoc() const
Retrieves the location of the '...', if present.
Definition DeclFriend.h:107
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Definition DeclFriend.h:96
bool isPackExpansion() const
Definition DeclFriend.h:113
Declaration of a friend template.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static FriendTemplateDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc, FriendUnion Friend, SourceLocation FriendLoc, ArrayRef< TemplateParameterList * > FriendTPLists, SourceLocation EllipsisLoc={}, TemplateName Template={})
static FriendTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumFriendTPLists)
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
Represents a function declaration or definition.
Definition Decl.h:2058
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization,...
Definition Decl.cpp:4208
Declaration of a template function.
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
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.
FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
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 ...
TemplateArgumentList * TemplateArguments
The template arguments used to produce the function template specialization from the function templat...
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
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...
This represents a decl that may have a name.
Definition Decl.h:274
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:295
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
Definition Decl.h:286
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
NamedDecl * getMostRecentDecl()
Definition Decl.h:501
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:1849
A C++ nested-name-specifier augmented with source location information.
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.
static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo)
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.
void setPlaceholderTypeConstraint(Expr *E)
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:938
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8504
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:8598
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
void loadLazySpecializationsImpl(bool OnlyPartial=false) const
CommonBase * getCommonPtr() const
Retrieves the "common" pointer shared by all (re-)declarations of the same template.
RedeclarableTemplateDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
CommonBase * Common
Pointer to the common data shared by all declarations of this template.
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.
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...
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.
SourceLocation getEnd() const
SourceLocation getBegin() const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
TagTypeKind TagKind
Definition Decl.h:3856
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition Decl.h:3947
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
Definition Decl.h:4112
A convenient class for passing around template argument information.
A template argument list.
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.
Location wrapper for a TemplateArgument.
SourceLocation getLocation() const
const TemplateArgument & getArgument() const
SourceRange getSourceRange() const LLVM_READONLY
Represents a template argument.
bool isNull() const
Determine whether this template argument has no value.
The base class of all kinds of template declarations (e.g., class, function, etc.).
NamedDecl * TemplatedDecl
TemplateParameterList * TemplateParams
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.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
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.
NamedDecl * getParam(unsigned Idx)
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.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const
bool containsUnexpandedParameterPack() const
Determine whether this template parameter list contains an unexpanded parameter pack.
TemplateParameterList(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
All associated constraints derived from this template parameter list, including the requires clause a...
ArrayRef< NamedDecl * > asArray()
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
SourceLocation getTemplateLoc() const
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)
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
static TemplateTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P, bool ParameterPack, IdentifierInfo *Id, TemplateNameKind ParameterKind, bool Typename, TemplateParameterList *Params)
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)
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, int D, int P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, UnsignedOrNone NumExpanded=std::nullopt)
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.
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.
TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
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:227
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Definition ASTConcept.h:244
const Type * getTypeForDecl() const
Definition Decl.h:3672
friend class ASTContext
Definition Decl.h:3648
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.h:3683
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:3681
A container of type source information.
Definition TypeBase.h:8475
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8486
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition TypeBase.h:2976
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:932
bool hasInit() const
Definition Decl.cpp:2379
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2171
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition Decl.cpp:2238
VarDecl * getInstantiatedFromStaticDataMember() const
If this variable is an instantiated static data member of a class template specialization,...
Definition Decl.cpp:2743
@ Definition
This declaration is definitely a definition.
Definition Decl.h:1324
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.
VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
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.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ Specialization
We are substituting template parameters for template arguments in order to form a template specializa...
Definition Template.h:50
bool isPackProducingBuiltinTemplateName(TemplateName N)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
StorageClass
Storage classes.
Definition Specifiers.h:249
@ SC_None
Definition Specifiers.h:251
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.
Definition TypeBase.h:906
OptionalUnsigned< unsigned > UnsignedOrNone
const FunctionProtoType * T
@ ExplicitInstantiation
We are parsing an explicit instantiation.
Definition Parser.h:85
TagTypeKind
The kind of a tag type.
Definition TypeBase.h:6045
BuiltinTemplateKind
Kinds of BuiltinTemplateDecl.
Definition Builtins.h:491
std::tuple< NamedDecl *, TemplateArgument > getReplacedTemplateParameter(Decl *D, unsigned Index)
Internal helper used by Subst* nodes to retrieve a parameter from the AssociatedDecl,...
TemplateNameKind
Specifies the kind of template name that an identifier refers to.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
const Decl & adjustDeclToTemplate(const Decl &D)
If we have a 'templated' declaration for a template, adjust 'D' to refer to the actual template.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
Definition Specifiers.h:189
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition Specifiers.h:207
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition Specifiers.h:203
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition Specifiers.h:199
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition Specifiers.h:195
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition Specifiers.h:192
U cast(CodeGen::Address addr)
Definition Address.h:327
@ None
No keyword precedes the qualified type name.
Definition TypeBase.h:6041
@ Struct
The "struct" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:6022
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
Definition TypeBase.h:6038
#define false
Definition stdbool.h:26
#define true
Definition stdbool.h:25
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
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.
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > Specializations
The function template specializations for this function template, including explicit specializations ...
Describes how types, statements, expressions, and declarations should be printed.
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 ...