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,
380 llvm::FoldingSetInsertToken &InsertToken, ProfileArguments... ProfileArgs) {
382
383 llvm::FoldingSetNodeID ID;
384 EntryType::Profile(ID, ProfileArgs..., getASTContext());
385 EntryType *Entry = Specs.lookup(ID, InsertToken);
386 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
387}
388
389template <class EntryType, typename... ProfileArguments>
392 llvm::FoldingSetVector<EntryType> &Specs,
393 llvm::FoldingSetInsertToken &InsertToken, ProfileArguments... ProfileArgs) {
394
395 if (auto *Found =
396 findSpecializationLocally(Specs, InsertToken, ProfileArgs...))
397 return Found;
398
399 if (!loadLazySpecializationsImpl(ProfileArgs...))
400 return nullptr;
401
402 return findSpecializationLocally(Specs, InsertToken, ProfileArgs...);
403}
404
405template <class Derived, class EntryType>
407 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
408 llvm::FoldingSetInsertToken InsertToken) {
409 using SETraits = SpecEntryTraits<EntryType>;
410
411 if (InsertToken) {
412#ifndef NDEBUG
413 auto Args = SETraits::getTemplateArgs(Entry);
414 // Due to hash collisions, it can happen that we load another template
415 // specialization with the same hash. This is fine, as long as the next
416 // call to findSpecializationImpl does not find a matching Decl for the
417 // template arguments.
419 llvm::FoldingSetInsertToken CorrectToken;
420 assert(!findSpecializationImpl(Specializations, CorrectToken, Args) &&
421 InsertToken == CorrectToken &&
422 "given incorrect InsertToken for specialization");
423#endif
424 Specializations.insert(Entry, InsertToken);
425 } else {
426 EntryType *Existing = Specializations.getOrInsert(Entry);
427 (void)Existing;
428 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
429 "non-canonical specialization?");
430 }
431
433 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
434 SETraits::getDecl(Entry));
435}
436
437//===----------------------------------------------------------------------===//
438// FunctionTemplateDecl Implementation
439//===----------------------------------------------------------------------===//
440
443 DeclarationName Name,
445 assert(!Params->empty() && "template with no template parameters");
447 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
448 if (Invalid)
449 TD->setInvalidDecl();
450 return TD;
451}
452
455 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
456 DeclarationName(), nullptr, nullptr);
457}
458
461 auto *CommonPtr = new (C) Common;
462 C.addDestruction(CommonPtr);
463 return CommonPtr;
464}
465
469
470llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
475
477 ArrayRef<TemplateArgument> Args, llvm::FoldingSetInsertToken &InsertToken) {
478 auto *Common = getCommonPtr();
479 return findSpecializationImpl(Common->Specializations, InsertToken, Args);
480}
481
484 llvm::FoldingSetInsertToken InsertToken) {
485 auto *Common = getCommonPtr();
487 InsertToken);
488}
489
492
493 // If we haven't created a common pointer yet, then it can just be created
494 // with the usual method.
495 if (!Base::Common)
496 return;
497
498 Common *ThisCommon = static_cast<Common *>(Base::Common);
499 Common *PrevCommon = nullptr;
501 for (; Prev; Prev = Prev->getPreviousDecl()) {
502 if (Prev->Base::Common) {
503 PrevCommon = static_cast<Common *>(Prev->Base::Common);
504 break;
505 }
506 PreviousDecls.push_back(Prev);
507 }
508
509 // If the previous redecl chain hasn't created a common pointer yet, then just
510 // use this common pointer.
511 if (!PrevCommon) {
512 for (auto *D : PreviousDecls)
513 D->Base::Common = ThisCommon;
514 return;
515 }
516
517 // Ensure we don't leak any important state.
518 assert(ThisCommon->Specializations.size() == 0 &&
519 "Can't merge incompatible declarations!");
520
521 Base::Common = PrevCommon;
522}
523
524//===----------------------------------------------------------------------===//
525// ClassTemplateDecl Implementation
526//===----------------------------------------------------------------------===//
527
530 DeclarationName Name,
531 TemplateParameterList *Params,
532 NamedDecl *Decl) {
533 assert(!Params->empty() && "template with no template parameters");
535 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
536 if (Invalid)
537 TD->setInvalidDecl();
538 return TD;
539}
540
542 GlobalDeclID ID) {
543 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
544 DeclarationName(), nullptr, nullptr);
545}
546
551
552llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
557
558llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
563
566 auto *CommonPtr = new (C) Common;
567 C.addDestruction(CommonPtr);
568 return CommonPtr;
569}
570
572 ArrayRef<TemplateArgument> Args, llvm::FoldingSetInsertToken &InsertToken) {
573 auto *Common = getCommonPtr();
574 return findSpecializationImpl(Common->Specializations, InsertToken, Args);
575}
576
579 llvm::FoldingSetInsertToken InsertToken) {
580 auto *Common = getCommonPtr();
582 InsertToken);
583}
584
588 llvm::FoldingSetInsertToken &InsertToken) {
589 return findSpecializationImpl(getPartialSpecializations(), InsertToken, Args,
590 TPL);
591}
592
594 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
595 TemplateParameterList *TPL, const ASTContext &Context) {
596 ID.AddInteger(TemplateArgs.size());
597 for (const TemplateArgument &TemplateArg : TemplateArgs)
598 TemplateArg.Profile(ID, Context);
599 TPL->Profile(ID, Context);
600}
601
604 llvm::FoldingSetInsertToken InsertToken) {
605 if (InsertToken)
606 getPartialSpecializations().insert(D, InsertToken);
607 else {
609 getPartialSpecializations().getOrInsert(D);
610 (void)Existing;
611 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
612 }
613
615 L->AddedCXXTemplateSpecialization(this, D);
616}
617
620 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
622 PS.clear();
623 PS.reserve(PartialSpecs.size());
624 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
625 PS.push_back(P.getMostRecentDecl());
626}
627
630 ASTContext &Context = getASTContext();
633 if (Context.hasSameType(P.getCanonicalInjectedSpecializationType(Context),
634 T))
635 return P.getMostRecentDecl();
636 }
637
638 return nullptr;
639}
640
644 Decl *DCanon = D->getCanonicalDecl();
646 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
647 return P.getMostRecentDecl();
648 }
649
650 return nullptr;
651}
652
669
670//===----------------------------------------------------------------------===//
671// TemplateTypeParm Allocation/Deallocation Method Implementations
672//===----------------------------------------------------------------------===//
673
674TemplateTypeParmDecl *TemplateTypeParmDecl::Create(
675 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
676 SourceLocation NameLoc, int D, int P, IdentifierInfo *Id, bool Typename,
677 bool ParameterPack, bool HasTypeConstraint, UnsignedOrNone NumExpanded) {
678 auto *TTPDecl =
679 new (C, DC,
680 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
681 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
682 HasTypeConstraint, NumExpanded);
683 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
684 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
685 return TTPDecl;
686}
687
690 return new (C, ID)
691 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
692 false, false, std::nullopt);
693}
694
697 bool HasTypeConstraint) {
698 return new (C, ID,
699 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
700 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
701 false, HasTypeConstraint, std::nullopt);
702}
703
708
711 return SourceRange(getBeginLoc(),
713 // TypeDecl::getSourceRange returns a range containing name location, which is
714 // wrong for unnamed template parameters. e.g:
715 // it will return <[[typename>]] instead of <[[typename]]>
716 if (getDeclName().isEmpty())
717 return SourceRange(getBeginLoc());
719}
720
722 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
723 if (DefArg.getArgument().isNull())
724 DefaultArgument.set(nullptr);
725 else
726 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
727}
728
730 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->getDepth();
731}
732
734 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->getIndex();
735}
736
738 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->isParameterPack();
739}
740
742 ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint,
743 UnsignedOrNone ArgPackSubstIndex) {
744 assert(HasTypeConstraint &&
745 "HasTypeConstraint=true must be passed at construction in order to "
746 "call setTypeConstraint");
747 assert(!TypeConstraintInitialized &&
748 "TypeConstraint was already initialized!");
749 new (getTrailingObjects())
750 TypeConstraint(Loc, ImmediatelyDeclaredConstraint, ArgPackSubstIndex);
751 TypeConstraintInitialized = true;
752}
753
754//===----------------------------------------------------------------------===//
755// NonTypeTemplateParmDecl Method Implementations
756//===----------------------------------------------------------------------===//
757
758NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
759 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, int D,
760 int P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
761 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
762 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
763 TemplateParmPosition(D, P), ParameterPack(true),
764 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
765 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
766 auto TypesAndInfos =
767 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
768 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
769 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
770 TypesAndInfos[I].second = ExpandedTInfos[I];
771 }
772 }
773}
774
775NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
776 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
777 SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id, QualType T,
778 bool ParameterPack, TypeSourceInfo *TInfo) {
779 AutoType *AT =
780 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
781 const bool HasConstraint = AT && AT->isConstrained();
782 auto *NTTP =
783 new (C, DC,
784 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
785 0, HasConstraint ? 1 : 0))
786 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T,
787 ParameterPack, TInfo);
788 if (HasConstraint)
789 NTTP->setPlaceholderTypeConstraint(nullptr);
790 return NTTP;
791}
792
793NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
794 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
795 SourceLocation IdLoc, int D, int P, const IdentifierInfo *Id, QualType T,
796 TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
797 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
798 AutoType *AT = TInfo->getType()->getContainedAutoType();
799 const bool HasConstraint = AT && AT->isConstrained();
800 auto *NTTP =
801 new (C, DC,
802 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
803 ExpandedTypes.size(), HasConstraint ? 1 : 0))
804 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
805 ExpandedTypes, ExpandedTInfos);
806 if (HasConstraint)
807 NTTP->setPlaceholderTypeConstraint(nullptr);
808 return NTTP;
809}
810
813 bool HasTypeConstraint) {
814 auto *NTTP =
815 new (C, ID,
816 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
817 0, HasTypeConstraint ? 1 : 0))
818 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
819 0, 0, nullptr, QualType(), false, nullptr);
820 if (HasTypeConstraint)
821 NTTP->setPlaceholderTypeConstraint(nullptr);
822 return NTTP;
823}
824
827 unsigned NumExpandedTypes,
828 bool HasTypeConstraint) {
829 auto *NTTP =
830 new (C, ID,
831 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
832 NumExpandedTypes, HasTypeConstraint ? 1 : 0))
833 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
834 0, 0, nullptr, QualType(), nullptr, {}, {});
835 NTTP->NumExpandedTypes = NumExpandedTypes;
836 if (HasTypeConstraint)
837 NTTP->setPlaceholderTypeConstraint(nullptr);
838 return NTTP;
839}
840
847
852
854 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
855 if (DefArg.getArgument().isNull())
856 DefaultArgument.set(nullptr);
857 else
858 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
859}
860
861//===----------------------------------------------------------------------===//
862// TemplateTemplateParmDecl Method Implementations
863//===----------------------------------------------------------------------===//
864
865void TemplateTemplateParmDecl::anchor() {}
866
867TemplateTemplateParmDecl::TemplateTemplateParmDecl(
868 DeclContext *DC, SourceLocation L, int D, int P, IdentifierInfo *Id,
871 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
872 TemplateParmPosition(D, P), ParameterKind(Kind), Typename(Typename),
873 ParameterPack(true), ExpandedParameterPack(true),
874 NumExpandedParams(Expansions.size()) {
875 llvm::uninitialized_copy(Expansions, getTrailingObjects());
876}
877
878TemplateTemplateParmDecl *TemplateTemplateParmDecl::Create(
879 const ASTContext &C, DeclContext *DC, SourceLocation L, int D, int P,
880 bool ParameterPack, IdentifierInfo *Id, TemplateNameKind Kind,
881 bool Typename, TemplateParameterList *Params) {
882 assert(!Params->empty() && "template with no template parameters");
883 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
884 Kind, Typename, Params);
885}
886
889 SourceLocation L, int D, int P,
891 bool Typename, TemplateParameterList *Params,
893 assert(!Params->empty() && "template with no template parameters");
894 return new (C, DC,
895 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
896 TemplateTemplateParmDecl(DC, L, D, P, Id, Kind, Typename, Params,
897 Expansions);
898}
899
902 return new (C, ID) TemplateTemplateParmDecl(
903 nullptr, SourceLocation(), 0, 0, false, nullptr,
905}
906
909 unsigned NumExpansions) {
910 auto *TTP =
911 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
912 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
914 nullptr, {});
915 TTP->NumExpandedParams = NumExpansions;
916 return TTP;
917}
918
923
925 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
926 if (DefArg.getArgument().isNull())
927 DefaultArgument.set(nullptr);
928 else
929 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
930}
931
932//===----------------------------------------------------------------------===//
933// TemplateArgumentList Implementation
934//===----------------------------------------------------------------------===//
935TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
936 : NumArguments(Args.size()) {
937 llvm::uninitialized_copy(Args, getTrailingObjects());
938}
939
943 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
944 return new (Mem) TemplateArgumentList(Args);
945}
946
947FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
950 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
951 MemberSpecializationInfo *MSInfo) {
952 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
953 if (TemplateArgsAsWritten)
955 *TemplateArgsAsWritten);
956
957 void *Mem =
958 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
959 return new (Mem) FunctionTemplateSpecializationInfo(
960 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
961}
962
963//===----------------------------------------------------------------------===//
964// ClassTemplateSpecializationDecl Implementation
965//===----------------------------------------------------------------------===//
966
968 ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC,
969 SourceLocation StartLoc, SourceLocation IdLoc,
970 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
971 bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)
972 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
973 SpecializedTemplate->getIdentifier(), PrevDecl),
974 SpecializedTemplate(SpecializedTemplate),
975 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
976 SpecializationKind(TSK_Undeclared), StrictPackMatch(StrictPackMatch) {
977 assert(DK == Kind::ClassTemplateSpecialization || StrictPackMatch == false);
978}
979
985
987 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
988 SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate,
989 ArrayRef<TemplateArgument> Args, bool StrictPackMatch,
991 auto *Result = new (Context, DC) ClassTemplateSpecializationDecl(
992 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
993 SpecializedTemplate, Args, StrictPackMatch, PrevDecl);
994
995 return Result;
996}
997
1000 GlobalDeclID ID) {
1001 return new (C, ID)
1002 ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
1003}
1004
1006 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1008
1009 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
1010 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1011 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1012 printTemplateArgumentList(
1013 OS, ArgsAsWritten->arguments(), Policy,
1014 getSpecializedTemplate()->getTemplateParameters());
1015 } else {
1016 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1017 printTemplateArgumentList(
1018 OS, TemplateArgs.asArray(), Policy,
1019 getSpecializedTemplate()->getTemplateParameters());
1020 }
1021}
1022
1025 if (const auto *PartialSpec =
1026 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
1027 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1028 return cast<ClassTemplateDecl *>(SpecializedTemplate);
1029}
1030
1033 switch (getSpecializationKind()) {
1034 case TSK_Undeclared:
1036 llvm::PointerUnion<ClassTemplateDecl *,
1039 assert(!Pattern.isNull() &&
1040 "Class template specialization without pattern?");
1041 if (const auto *CTPSD =
1042 dyn_cast<ClassTemplatePartialSpecializationDecl *>(Pattern))
1043 return CTPSD->getSourceRange();
1044 return cast<ClassTemplateDecl *>(Pattern)->getSourceRange();
1045 }
1050 Range.setEnd(Args->getRAngleLoc());
1051 return Range;
1052 }
1056 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1057 Range.setBegin(ExternKW);
1058 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1059 TemplateKW.isValid())
1060 Range.setBegin(TemplateKW);
1062 Range.setEnd(Args->getRAngleLoc());
1063 return Range;
1064 }
1065 }
1066 llvm_unreachable("unhandled template specialization kind");
1067}
1068
1070 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1071 if (!Info) {
1072 // Don't allocate if the location is invalid.
1073 if (Loc.isInvalid())
1074 return;
1077 ExplicitInfo = Info;
1078 }
1079 Info->ExternKeywordLoc = Loc;
1080}
1081
1083 SourceLocation Loc) {
1084 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1085 if (!Info) {
1086 // Don't allocate if the location is invalid.
1087 if (Loc.isInvalid())
1088 return;
1091 ExplicitInfo = Info;
1092 }
1093 Info->TemplateKeywordLoc = Loc;
1094}
1095
1096//===----------------------------------------------------------------------===//
1097// ConceptDecl Implementation
1098//===----------------------------------------------------------------------===//
1101 TemplateParameterList *Params,
1103 assert(!Params->empty() && "template with no template parameters");
1104 bool Invalid = AdoptTemplateParameterList(Params, DC);
1105 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1106 if (Invalid)
1107 TD->setInvalidDecl();
1108 return TD;
1109}
1110
1112 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1114 nullptr, nullptr);
1115
1116 return Result;
1117}
1118
1119//===----------------------------------------------------------------------===//
1120// ImplicitConceptSpecializationDecl Implementation
1121//===----------------------------------------------------------------------===//
1122ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1124 ArrayRef<TemplateArgument> ConvertedArgs)
1125 : Decl(ImplicitConceptSpecialization, DC, SL),
1126 NumTemplateArgs(ConvertedArgs.size()) {
1127 setTemplateArguments(ConvertedArgs);
1128}
1129
1130ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1131 EmptyShell Empty, unsigned NumTemplateArgs)
1132 : Decl(ImplicitConceptSpecialization, Empty),
1133 NumTemplateArgs(NumTemplateArgs) {}
1134
1135ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create(
1136 const ASTContext &C, DeclContext *DC, SourceLocation SL,
1137 ArrayRef<TemplateArgument> ConvertedArgs) {
1138 return new (C, DC,
1139 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1140 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1141}
1142
1145 const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) {
1146 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1147 ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);
1148}
1149
1151 ArrayRef<TemplateArgument> Converted) {
1152 assert(Converted.size() == NumTemplateArgs);
1153 llvm::uninitialized_copy(Converted, getTrailingObjects());
1154}
1155
1156//===----------------------------------------------------------------------===//
1157// ClassTemplatePartialSpecializationDecl Implementation
1158//===----------------------------------------------------------------------===//
1159void ClassTemplatePartialSpecializationDecl::anchor() {}
1160
1161ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
1162 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1164 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1165 CanQualType CanonInjectedTST,
1168 Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
1169 // Tracking StrictPackMatch for Partial
1170 // Specializations is not needed.
1171 SpecializedTemplate, Args, /*StrictPackMatch=*/false, PrevDecl),
1172 TemplateParams(Params), InstantiatedFromMember(nullptr, false),
1173 CanonInjectedTST(CanonInjectedTST) {
1174 if (AdoptTemplateParameterList(Params, this))
1176}
1177
1180 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1182 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1183 CanQualType CanonInjectedTST,
1184 ClassTemplatePartialSpecializationDecl *PrevDecl) {
1185 assert(!Params->empty() && "template with no template parameters");
1186 auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl(
1187 Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args,
1188 CanonInjectedTST, PrevDecl);
1189 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1190 return Result;
1191}
1192
1195 GlobalDeclID ID) {
1196 return new (C, ID) ClassTemplatePartialSpecializationDecl(C);
1197}
1198
1201 const ASTContext &Ctx) const {
1202 if (CanonInjectedTST.isNull()) {
1203 CanonInjectedTST =
1207 getTemplateArgs().asArray()));
1208 }
1209 return CanonInjectedTST;
1210}
1211
1213 if (const ClassTemplatePartialSpecializationDecl *MT =
1215 MT && !isMemberSpecialization())
1216 return MT->getSourceRange();
1220 Range.setBegin(TPL->getTemplateLoc());
1221 return Range;
1222}
1223
1224//===----------------------------------------------------------------------===//
1225// FriendTemplateDecl Implementation
1226//===----------------------------------------------------------------------===//
1227
1228void FriendTemplateDecl::anchor() {}
1229
1233 SourceLocation FriendLoc,
1235 SourceLocation EllipsisLoc, TemplateName Template) {
1236 std::size_t Extra =
1237 FriendTemplateDecl::additionalSizeToAlloc<TemplateParameterList *>(
1238 FriendTPLists.size());
1239 auto *FTD = new (Context, DC, Extra) FriendTemplateDecl(
1240 DC, Loc, Friend, FriendLoc, EllipsisLoc, FriendTPLists, Template);
1241 cast<CXXRecordDecl>(DC)->pushFriendDecl(FTD);
1242 return FTD;
1243}
1244
1247 SourceLocation Loc, TemplateName Template,
1248 SourceLocation FriendLoc,
1250 SourceLocation EllipsisLoc) {
1251 auto *Friend = Template.getAsTemplateDecl();
1252 assert(Friend && "friend template name must be resolved");
1253 std::size_t Extra =
1254 FriendTemplateDecl::additionalSizeToAlloc<TemplateParameterList *>(
1255 FriendTPLists.size());
1256 auto *FTD = new (Context, DC, Extra) FriendTemplateDecl(
1257 DC, Loc, Friend, FriendLoc, EllipsisLoc, FriendTPLists, Template);
1258 cast<CXXRecordDecl>(DC)->pushFriendDecl(FTD);
1259 return FTD;
1260}
1261
1264 unsigned NumFriendTPLists) {
1265 std::size_t Extra =
1266 FriendTemplateDecl::additionalSizeToAlloc<TemplateParameterList *>(
1267 NumFriendTPLists);
1268 return new (C, ID, Extra) FriendTemplateDecl(EmptyShell(), NumFriendTPLists);
1269}
1270
1272 SourceLocation Begin = getTemplateParameterLists().front()->getTemplateLoc();
1273 SourceLocation End =
1274 !Template.isNull() && !getFriendType()
1277 return SourceRange(Begin, End);
1278}
1279
1280//===----------------------------------------------------------------------===//
1281// TypeAliasTemplateDecl Implementation
1282//===----------------------------------------------------------------------===//
1283
1286 DeclarationName Name,
1288 assert(!Params->empty() && "template with no template parameters");
1289 bool Invalid = AdoptTemplateParameterList(Params, DC);
1290 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1291 if (Invalid)
1292 TD->setInvalidDecl();
1293 return TD;
1294}
1295
1298 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1299 DeclarationName(), nullptr, nullptr);
1300}
1301
1304 auto *CommonPtr = new (C) Common;
1305 C.addDestruction(CommonPtr);
1306 return CommonPtr;
1307}
1308
1309//===----------------------------------------------------------------------===//
1310// VarTemplateDecl Implementation
1311//===----------------------------------------------------------------------===//
1312
1314 VarTemplateDecl *CurD = this;
1315 while (CurD) {
1316 if (CurD->isThisDeclarationADefinition())
1317 return CurD;
1318 CurD = CurD->getPreviousDecl();
1319 }
1320 return nullptr;
1321}
1322
1325 TemplateParameterList *Params,
1326 VarDecl *Decl) {
1327 assert(!Params->empty() && "template with no template parameters");
1328 bool Invalid = AdoptTemplateParameterList(Params, DC);
1329 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1330 if (Invalid)
1331 TD->setInvalidDecl();
1332 return TD;
1333}
1334
1336 GlobalDeclID ID) {
1337 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1338 DeclarationName(), nullptr, nullptr);
1339}
1340
1345
1346llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1351
1352llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1357
1360 auto *CommonPtr = new (C) Common;
1361 C.addDestruction(CommonPtr);
1362 return CommonPtr;
1363}
1364
1367 llvm::FoldingSetInsertToken &InsertToken) {
1368 auto *Common = getCommonPtr();
1369 return findSpecializationImpl(Common->Specializations, InsertToken, Args);
1370}
1371
1373 VarTemplateSpecializationDecl *D, llvm::FoldingSetInsertToken InsertToken) {
1374 auto *Common = getCommonPtr();
1376 InsertToken);
1377}
1378
1382 llvm::FoldingSetInsertToken &InsertToken) {
1383 return findSpecializationImpl(getPartialSpecializations(), InsertToken, Args,
1384 TPL);
1385}
1386
1388 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1389 TemplateParameterList *TPL, const ASTContext &Context) {
1390 ID.AddInteger(TemplateArgs.size());
1391 for (const TemplateArgument &TemplateArg : TemplateArgs)
1392 TemplateArg.Profile(ID, Context);
1393 TPL->Profile(ID, Context);
1394}
1395
1398 llvm::FoldingSetInsertToken InsertToken) {
1399 if (InsertToken)
1400 getPartialSpecializations().insert(D, InsertToken);
1401 else {
1403 getPartialSpecializations().getOrInsert(D);
1404 (void)Existing;
1405 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1406 }
1407
1409 L->AddedCXXTemplateSpecialization(this, D);
1410}
1411
1414 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1416 PS.clear();
1417 PS.reserve(PartialSpecs.size());
1418 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1419 PS.push_back(P.getMostRecentDecl());
1420}
1421
1425 Decl *DCanon = D->getCanonicalDecl();
1427 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1428 return P.getMostRecentDecl();
1429 }
1430
1431 return nullptr;
1432}
1433
1434//===----------------------------------------------------------------------===//
1435// VarTemplateSpecializationDecl Implementation
1436//===----------------------------------------------------------------------===//
1437
1439 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1440 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1442 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1443 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1444 SpecializedTemplate(SpecializedTemplate),
1445 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1446 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1447
1449 ASTContext &C)
1452 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1453
1455 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1456 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1458 return new (Context, DC) VarTemplateSpecializationDecl(
1459 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1460 SpecializedTemplate, T, TInfo, S, Args);
1461}
1462
1465 GlobalDeclID ID) {
1466 return new (C, ID)
1467 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1468}
1469
1471 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1473
1474 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1475 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1476 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1477 printTemplateArgumentList(
1478 OS, ArgsAsWritten->arguments(), Policy,
1479 getSpecializedTemplate()->getTemplateParameters());
1480 } else {
1481 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1482 printTemplateArgumentList(
1483 OS, TemplateArgs.asArray(), Policy,
1484 getSpecializedTemplate()->getTemplateParameters());
1485 }
1486}
1487
1489 if (const auto *PartialSpec =
1490 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1491 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1492 return cast<VarTemplateDecl *>(SpecializedTemplate);
1493}
1494
1496 switch (getSpecializationKind()) {
1497 case TSK_Undeclared:
1499 llvm::PointerUnion<VarTemplateDecl *,
1502 assert(!Pattern.isNull() &&
1503 "Variable template specialization without pattern?");
1504 if (const auto *VTPSD =
1505 dyn_cast<VarTemplatePartialSpecializationDecl *>(Pattern))
1506 return VTPSD->getSourceRange();
1508 if (hasInit()) {
1510 return Definition->getSourceRange();
1511 }
1512 return VTD->getCanonicalDecl()->getSourceRange();
1513 }
1517 !hasInit() && Args)
1518 Range.setEnd(Args->getRAngleLoc());
1519 return Range;
1520 }
1524 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1525 Range.setBegin(ExternKW);
1526 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1527 TemplateKW.isValid())
1528 Range.setBegin(TemplateKW);
1530 Range.setEnd(Args->getRAngleLoc());
1531 return Range;
1532 }
1533 }
1534 llvm_unreachable("unhandled template specialization kind");
1535}
1536
1538 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1539 if (!Info) {
1540 // Don't allocate if the location is invalid.
1541 if (Loc.isInvalid())
1542 return;
1545 ExplicitInfo = Info;
1546 }
1547 Info->ExternKeywordLoc = Loc;
1548}
1549
1551 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1552 if (!Info) {
1553 // Don't allocate if the location is invalid.
1554 if (Loc.isInvalid())
1555 return;
1558 ExplicitInfo = Info;
1559 }
1560 Info->TemplateKeywordLoc = Loc;
1561}
1562
1563//===----------------------------------------------------------------------===//
1564// VarTemplatePartialSpecializationDecl Implementation
1565//===----------------------------------------------------------------------===//
1566
1567void VarTemplatePartialSpecializationDecl::anchor() {}
1568
1569VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1570 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1572 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1574 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1575 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1576 TInfo, S, Args),
1577 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1578 if (AdoptTemplateParameterList(Params, DC))
1580}
1581
1584 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1586 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1588 assert(!Params->empty() && "template with no template parameters");
1589 auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(
1590 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,
1591 Args);
1592 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1593 return Result;
1594}
1595
1598 GlobalDeclID ID) {
1599 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1600}
1601
1603 if (const VarTemplatePartialSpecializationDecl *MT =
1605 MT && !isMemberSpecialization())
1606 return MT->getSourceRange();
1610 Range.setBegin(TPL->getTemplateLoc());
1611 return Range;
1612}
1613
1615 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1616 switch (BTK) {
1617#define CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST
1618#include "clang/Basic/BuiltinTemplates.inc"
1619 }
1620
1621 llvm_unreachable("unhandled BuiltinTemplateKind!");
1622}
1623
1624void BuiltinTemplateDecl::anchor() {}
1625
1626BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1627 DeclarationName Name,
1631 BTK(BTK) {}
1632
1634 return getBuiltinTemplateKind() == clang::BTK__builtin_dedup_pack;
1635}
1636
1638 auto *T = dyn_cast_or_null<BuiltinTemplateDecl>(
1639 N.getAsTemplateDecl(/*IgnoreDeduced=*/true));
1640 return T && T->isPackProducingBuiltinTemplate();
1641}
1642
1643TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1644 QualType T,
1645 const APValue &V) {
1646 DeclContext *DC = C.getTranslationUnitDecl();
1647 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1648 C.addDestruction(&TPOD->Value);
1649 return TPOD;
1650}
1651
1653TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1654 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1655 C.addDestruction(&TPOD->Value);
1656 return TPOD;
1657}
1658
1659void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1660 const PrintingPolicy &Policy) const {
1661 OS << "<template param ";
1662 printAsExpr(OS, Policy);
1663 OS << ">";
1664}
1665
1666void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1667 printAsExpr(OS, getASTContext().getPrintingPolicy());
1668}
1669
1670void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1671 const PrintingPolicy &Policy) const {
1672 getType().getUnqualifiedType().print(OS, Policy);
1673 printAsInit(OS, Policy);
1674}
1675
1676void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1677 printAsInit(OS, getASTContext().getPrintingPolicy());
1678}
1679
1680void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1681 const PrintingPolicy &Policy) const {
1682 getValue().printPretty(OS, Policy, getType(), &getASTContext());
1683}
1684
1685std::tuple<NamedDecl *, TemplateArgument>
1687 switch (D->getKind()) {
1688 case Decl::Kind::BuiltinTemplate:
1689 case Decl::Kind::ClassTemplate:
1690 case Decl::Kind::Concept:
1691 case Decl::Kind::FunctionTemplate:
1692 case Decl::Kind::TemplateTemplateParm:
1693 case Decl::Kind::TypeAliasTemplate:
1694 case Decl::Kind::VarTemplate:
1695 return {cast<TemplateDecl>(D)->getTemplateParameters()->getParam(Index),
1696 {}};
1697 case Decl::Kind::ClassTemplateSpecialization: {
1698 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1699 auto P = CTSD->getSpecializedTemplateOrPartial();
1700 if (const auto *CTPSD =
1701 dyn_cast<ClassTemplatePartialSpecializationDecl *>(P)) {
1702 TemplateParameterList *TPL = CTPSD->getTemplateParameters();
1703 return {TPL->getParam(Index),
1704 CTSD->getTemplateInstantiationArgs()[Index]};
1705 }
1707 cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1708 return {TPL->getParam(Index), CTSD->getTemplateArgs()[Index]};
1709 }
1710 case Decl::Kind::VarTemplateSpecialization: {
1711 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1712 auto P = VTSD->getSpecializedTemplateOrPartial();
1713 if (const auto *VTPSD =
1714 dyn_cast<VarTemplatePartialSpecializationDecl *>(P)) {
1715 TemplateParameterList *TPL = VTPSD->getTemplateParameters();
1716 return {TPL->getParam(Index),
1717 VTSD->getTemplateInstantiationArgs()[Index]};
1718 }
1720 cast<VarTemplateDecl *>(P)->getTemplateParameters();
1721 return {TPL->getParam(Index), VTSD->getTemplateArgs()[Index]};
1722 }
1723 case Decl::Kind::ClassTemplatePartialSpecialization:
1725 ->getTemplateParameters()
1726 ->getParam(Index),
1727 {}};
1728 case Decl::Kind::VarTemplatePartialSpecialization:
1730 ->getTemplateParameters()
1731 ->getParam(Index),
1732 {}};
1733 // This is used as the AssociatedDecl for placeholder type deduction.
1734 case Decl::TemplateTypeParm:
1735 return {cast<NamedDecl>(D), {}};
1736 // FIXME: Always use the template decl as the AssociatedDecl.
1737 case Decl::Kind::CXXRecord:
1739 cast<CXXRecordDecl>(D)->getDescribedClassTemplate(), Index);
1740 case Decl::Kind::CXXDeductionGuide:
1741 case Decl::Kind::CXXConversion:
1742 case Decl::Kind::CXXConstructor:
1743 case Decl::Kind::CXXDestructor:
1744 case Decl::Kind::CXXMethod:
1745 case Decl::Kind::Function: {
1747 cast<FunctionDecl>(D)->getTemplateSpecializationInfo();
1748 return {Info->getTemplate()->getTemplateParameters()->getParam(Index),
1749 Info->TemplateArguments->asArray()[Index]};
1750 }
1751 case Decl::Kind::CXXExpansionStmt:
1752 assert(Index == 0 && "expansion stmts only have a single template param");
1753 return {cast<CXXExpansionStmtDecl>(D)->getIndexTemplateParm(), {}};
1754 default:
1755 llvm_unreachable("Unhandled templated declaration kind");
1756 }
1757}
1758
1760 if (const auto *FD = dyn_cast<FunctionDecl>(&D)) {
1761 // Is this function declaration part of a function template?
1762 if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate())
1763 return *FTD;
1764
1765 // Nothing to do if function is not an implicit instantiation.
1766 if (FD->getTemplateSpecializationKind() != TSK_ImplicitInstantiation)
1767 return D;
1768
1769 // Function is an implicit instantiation of a function template?
1770 if (const FunctionTemplateDecl *FTD = FD->getPrimaryTemplate())
1771 return *FTD;
1772
1773 // Function is instantiated from a member definition of a class template?
1774 if (const FunctionDecl *MemberDecl =
1776 return *MemberDecl;
1777
1778 return D;
1779 }
1780 if (const auto *VD = dyn_cast<VarDecl>(&D)) {
1781 // Static data member is instantiated from a member definition of a class
1782 // template?
1783 if (VD->isStaticDataMember())
1784 if (const VarDecl *MemberDecl = VD->getInstantiatedFromStaticDataMember())
1785 return *MemberDecl;
1786
1787 return D;
1788 }
1789 if (const auto *CRD = dyn_cast<CXXRecordDecl>(&D)) {
1790 // Is this class declaration part of a class template?
1791 if (const ClassTemplateDecl *CTD = CRD->getDescribedClassTemplate())
1792 return *CTD;
1793
1794 // Class is an implicit instantiation of a class template or partial
1795 // specialization?
1796 if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(CRD)) {
1797 if (CTSD->getSpecializationKind() != TSK_ImplicitInstantiation)
1798 return D;
1799 llvm::PointerUnion<ClassTemplateDecl *,
1802 return isa<ClassTemplateDecl *>(PU)
1803 ? *static_cast<const Decl *>(cast<ClassTemplateDecl *>(PU))
1804 : *static_cast<const Decl *>(
1806 }
1807
1808 // Class is instantiated from a member definition of a class template?
1809 if (const MemberSpecializationInfo *Info =
1810 CRD->getMemberSpecializationInfo())
1811 return *Info->getInstantiatedFrom();
1812
1813 return D;
1814 }
1815 if (const auto *ED = dyn_cast<EnumDecl>(&D)) {
1816 // Enum is instantiated from a member definition of a class template?
1817 if (const EnumDecl *MemberDecl = ED->getInstantiatedFromMemberEnum())
1818 return *MemberDecl;
1819
1820 return D;
1821 }
1822 // FIXME: Adjust alias templates?
1823 return D;
1824}
1825
1826ExplicitInstantiationDecl::ExplicitInstantiationDecl(
1828 SourceLocation TemplateLoc, NestedNameSpecifierLoc QualifierLoc,
1829 const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc,
1830 TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK)
1831 : Decl(ExplicitInstantiation, DC, TemplateLoc),
1832 SpecAndTSK(Specialization, TSK), ExternLoc(ExternLoc), NameLoc(NameLoc) {
1833 unsigned Flags = 0;
1834 if (QualifierLoc)
1835 Flags |= HasQualifierFlag;
1836 if (ArgsAsWritten)
1837 Flags |= HasArgsAsWrittenFlag;
1838 // Set flags BEFORE writing trailing objects, because
1839 // numTrailingObjects reads TypeAndFlags.getInt() to compute offsets.
1840 TypeAndFlags.setPointerAndInt(TypeAsWritten, Flags);
1841 if (QualifierLoc)
1842 *getTrailingObjects<NestedNameSpecifierLoc>() = QualifierLoc;
1843 if (ArgsAsWritten)
1844 *getTrailingObjects<const ASTTemplateArgumentListInfo *>() = ArgsAsWritten;
1845}
1846
1847ExplicitInstantiationDecl *ExplicitInstantiationDecl::Create(
1849 SourceLocation ExternLoc, SourceLocation TemplateLoc,
1850 NestedNameSpecifierLoc QualifierLoc,
1851 const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc,
1852 TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK) {
1853 unsigned Extra = additionalSizeToAlloc<NestedNameSpecifierLoc,
1855 QualifierLoc ? 1 : 0, ArgsAsWritten ? 1 : 0);
1856 return new (C, DC, Extra) ExplicitInstantiationDecl(
1857 DC, Specialization, ExternLoc, TemplateLoc, QualifierLoc, ArgsAsWritten,
1858 NameLoc, TypeAsWritten, TSK);
1859}
1860
1863 unsigned TrailingFlags) {
1864 unsigned Extra = additionalSizeToAlloc<NestedNameSpecifierLoc,
1866 (TrailingFlags & HasQualifierFlag) ? 1 : 0,
1867 (TrailingFlags & HasArgsAsWrittenFlag) ? 1 : 0);
1868 auto *D = new (C, ID, Extra) ExplicitInstantiationDecl(EmptyShell());
1869 // Set the flags so the reader knows which trailing objects are present.
1870 D->TypeAndFlags.setInt(TrailingFlags);
1871 return D;
1872}
1873
1875 if (auto TL = getClassTypeLoc()) {
1876 if (auto TST = TL->getAs<TemplateSpecializationTypeLoc>())
1877 return TST.getElaboratedKeywordLoc();
1878 if (auto Tag = TL->getAs<TagTypeLoc>())
1879 return Tag.getElaboratedKeywordLoc();
1880 }
1881 return SourceLocation();
1882}
1883
1886 return *getTrailingObjects<NestedNameSpecifierLoc>();
1887 if (auto TL = getClassTypeLoc())
1888 return TL->getPrefix();
1889 return NestedNameSpecifierLoc();
1890}
1891
1893 // For class-like entities, TSI encodes the class itself, not a declared type.
1894 if (getClassTypeLoc())
1895 return nullptr;
1896 return getRawTypeSourceInfo();
1897}
1898
1899std::optional<unsigned> ExplicitInstantiationDecl::getNumTemplateArgs() const {
1900 if (const auto *Args = getTrailingArgsInfo())
1901 return Args->NumTemplateArgs;
1902 if (auto TL = getClassTypeLoc())
1903 if (auto TST = TL->getAs<TemplateSpecializationTypeLoc>())
1904 return TST.getNumArgs();
1905 return std::nullopt;
1906}
1907
1910 if (const auto *Args = getTrailingArgsInfo())
1911 return (*Args)[I];
1912 if (auto TL = getClassTypeLoc())
1913 if (auto TST = TL->getAs<TemplateSpecializationTypeLoc>())
1914 return TST.getArgLoc(I);
1915 llvm_unreachable("template arguments not found in trailing args or TypeLoc");
1916}
1917
1919 if (const auto *Args = getTrailingArgsInfo())
1920 return Args->getLAngleLoc();
1921 if (auto TL = getClassTypeLoc())
1922 if (auto TST = TL->getAs<TemplateSpecializationTypeLoc>())
1923 return TST.getLAngleLoc();
1924 llvm_unreachable("template arguments not found in trailing args or TypeLoc");
1925}
1926
1928 if (const auto *Args = getTrailingArgsInfo())
1929 return Args->getRAngleLoc();
1930 if (auto TL = getClassTypeLoc())
1931 if (auto TST = TL->getAs<TemplateSpecializationTypeLoc>())
1932 return TST.getRAngleLoc();
1933 llvm_unreachable("template arguments not found in trailing args or TypeLoc");
1934}
1935
1937 // For func/var templates with postfix type syntax (arrays, functions),
1938 // the type extends past the name, so use the type's end location.
1939 if (auto *TSI = getTypeAsWritten())
1940 if (TSI->getType().hasPostfixDeclaratorSyntax())
1941 return TSI->getTypeLoc().getEndLoc();
1942 // Otherwise, template args RAngleLoc or NameLoc.
1943 if (getNumTemplateArgs()) {
1945 if (RAngle.isValid())
1946 return RAngle;
1947 }
1948 return NameLoc;
1949}
1950
1952 SourceLocation Begin = ExternLoc.isValid() ? ExternLoc : getLocation();
1953 return SourceRange(Begin, getEndLoc());
1954}
1955
1956CXXExpansionStmtDecl::CXXExpansionStmtDecl(DeclContext *DC, SourceLocation Loc,
1958 : Decl(CXXExpansionStmt, DC, Loc), DeclContext(CXXExpansionStmt),
1959 IndexNTTP(NTTP) {}
1960
1964 return new (C, DC) CXXExpansionStmtDecl(DC, Loc, NTTP);
1965}
1968 return new (C, ID)
1969 CXXExpansionStmtDecl(/*DC=*/nullptr, SourceLocation(), /*NTTP=*/nullptr);
1970}
1971
1973 return Pattern ? Pattern->getSourceRange() : SourceRange();
1974}
Defines the clang::ASTContext interface.
#define V(N, I)
#define BuiltinTemplate(BTName)
Definition ASTContext.h:480
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:709
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.
ClassTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, llvm::FoldingSetInsertToken &InsertToken)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
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.
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.
ClassTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
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, llvm::FoldingSetInsertToken InsertToken)
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...
void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, llvm::FoldingSetInsertToken InsertToken)
Insert the specified partial specialization knowing that it is not already in.
Common * getCommonPtr() const
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:781
SourceLocation getOuterLocStart() const
Return start of source range taking into account any outer template declarations.
Definition Decl.cpp:2068
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2072
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
Definition Decl.h:863
Represents an enum.
Definition Decl.h:4146
EnumDecl * getInstantiatedFromMemberEnum() const
Returns the enumeration (declared within the template) from which this enumeration type was instantia...
Definition Decl.cpp:5218
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:113
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
Definition Expr.h:242
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:2059
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization,...
Definition Decl.cpp:4206
Declaration of a template function.
CommonBase * newCommon(ASTContext &C) const override
Common * getCommonPtr() const
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
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.
void addSpecialization(FunctionTemplateSpecializationInfo *Info, llvm::FoldingSetInsertToken InsertToken)
Add a specialization of this function template.
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:275
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:296
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
Definition Decl.h:287
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:341
NamedDecl * getMostRecentDecl()
Definition Decl.h:502
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:1850
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:8501
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:8595
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, llvm::FoldingSetInsertToken InsertToken)
SpecEntryTraits< EntryType >::DeclType * findSpecializationLocally(llvm::FoldingSetVector< EntryType > &Specs, llvm::FoldingSetInsertToken &InsertToken, ProfileArguments... ProfileArgs)
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
void loadLazySpecializationsImpl(bool OnlyPartial=false) const
SpecEntryTraits< EntryType >::DeclType * findSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, llvm::FoldingSetInsertToken &InsertToken, ProfileArguments... ProfileArgs)
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.
virtual CommonBase * newCommon(ASTContext &C) const =0
RedeclarableTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
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:3857
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition Decl.h:3948
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
Definition Decl.h:4113
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:3673
friend class ASTContext
Definition Decl.h:3649
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.h:3684
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:3682
A container of type source information.
Definition TypeBase.h:8472
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8483
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:724
Represents a variable declaration or definition.
Definition Decl.h:933
bool hasInit() const
Definition Decl.cpp:2380
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2172
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition Decl.cpp:2239
VarDecl * getInstantiatedFromStaticDataMember() const
If this variable is an instantiated static data member of a class template specialization,...
Definition Decl.cpp:2744
@ Definition
This declaration is definitely a definition.
Definition Decl.h:1325
Declaration of a variable template.
VarTemplateDecl * getDefinition()
VarTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D, llvm::FoldingSetInsertToken InsertToken)
Insert the specified partial specialization knowing that it is not already in.
Common * getCommonPtr() const
VarTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
VarTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this variable template, or nullptr if no such declaration exists...
CommonBase * newCommon(ASTContext &C) const override
VarTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, llvm::FoldingSetInsertToken &InsertToken)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
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.
void AddSpecialization(VarTemplateSpecializationDecl *D, llvm::FoldingSetInsertToken InsertToken)
Insert the specified specialization knowing that it is not already in.
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary variable pattern.
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:6044
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:6040
@ Struct
The "struct" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:6021
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
Definition TypeBase.h:6037
#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 ...