clang 19.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"
22#include "clang/AST/Type.h"
23#include "clang/AST/TypeLoc.h"
25#include "clang/Basic/LLVM.h"
27#include "llvm/ADT/ArrayRef.h"
28#include "llvm/ADT/FoldingSet.h"
29#include "llvm/ADT/PointerUnion.h"
30#include "llvm/ADT/STLExtras.h"
31#include "llvm/ADT/SmallVector.h"
32#include "llvm/Support/Casting.h"
33#include "llvm/Support/ErrorHandling.h"
34#include <algorithm>
35#include <cassert>
36#include <cstdint>
37#include <memory>
38#include <optional>
39#include <utility>
40
41using namespace clang;
42
43//===----------------------------------------------------------------------===//
44// TemplateParameterList Implementation
45//===----------------------------------------------------------------------===//
46
47
48TemplateParameterList::TemplateParameterList(const ASTContext& C,
49 SourceLocation TemplateLoc,
50 SourceLocation LAngleLoc,
52 SourceLocation RAngleLoc,
53 Expr *RequiresClause)
54 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
55 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
56 HasRequiresClause(RequiresClause != nullptr),
57 HasConstrainedParameters(false) {
58 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
59 NamedDecl *P = Params[Idx];
60 begin()[Idx] = P;
61
62 bool IsPack = P->isTemplateParameterPack();
63 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
64 if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())
65 ContainsUnexpandedParameterPack = true;
66 if (NTTP->hasPlaceholderTypeConstraint())
67 HasConstrainedParameters = true;
68 } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
69 if (!IsPack &&
70 TTP->getTemplateParameters()->containsUnexpandedParameterPack())
71 ContainsUnexpandedParameterPack = true;
72 } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
73 if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
74 if (TC->getImmediatelyDeclaredConstraint()
75 ->containsUnexpandedParameterPack())
76 ContainsUnexpandedParameterPack = true;
77 }
78 if (TTP->hasTypeConstraint())
79 HasConstrainedParameters = true;
80 } else {
81 llvm_unreachable("unexpected template parameter type");
82 }
83 // FIXME: If a default argument contains an unexpanded parameter pack, the
84 // template parameter list does too.
85 }
86
87 if (HasRequiresClause) {
88 if (RequiresClause->containsUnexpandedParameterPack())
89 ContainsUnexpandedParameterPack = true;
90 *getTrailingObjects<Expr *>() = RequiresClause;
91 }
92}
93
94bool TemplateParameterList::containsUnexpandedParameterPack() const {
95 if (ContainsUnexpandedParameterPack)
96 return true;
97 if (!HasConstrainedParameters)
98 return false;
99
100 // An implicit constrained parameter might have had a use of an unexpanded
101 // pack added to it after the template parameter list was created. All
102 // implicit parameters are at the end of the parameter list.
103 for (const NamedDecl *Param : llvm::reverse(asArray())) {
104 if (!Param->isImplicit())
105 break;
106
107 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
108 const auto *TC = TTP->getTypeConstraint();
109 if (TC && TC->getImmediatelyDeclaredConstraint()
110 ->containsUnexpandedParameterPack())
111 return true;
112 }
113 }
114
115 return false;
116}
117
120 SourceLocation LAngleLoc,
122 SourceLocation RAngleLoc, Expr *RequiresClause) {
123 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
124 Params.size(), RequiresClause ? 1u : 0u),
125 alignof(TemplateParameterList));
126 return new (Mem) TemplateParameterList(C, TemplateLoc, LAngleLoc, Params,
127 RAngleLoc, RequiresClause);
128}
129
130void TemplateParameterList::Profile(llvm::FoldingSetNodeID &ID,
131 const ASTContext &C) const {
132 const Expr *RC = getRequiresClause();
133 ID.AddBoolean(RC != nullptr);
134 if (RC)
135 RC->Profile(ID, C, /*Canonical=*/true);
136 ID.AddInteger(size());
137 for (NamedDecl *D : *this) {
138 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
139 ID.AddInteger(0);
140 ID.AddBoolean(NTTP->isParameterPack());
141 NTTP->getType().getCanonicalType().Profile(ID);
142 ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint());
143 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
144 E->Profile(ID, C, /*Canonical=*/true);
145 continue;
146 }
147 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {
148 ID.AddInteger(1);
149 ID.AddBoolean(TTP->isParameterPack());
150 ID.AddBoolean(TTP->hasTypeConstraint());
151 if (const TypeConstraint *TC = TTP->getTypeConstraint())
152 TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,
153 /*Canonical=*/true);
154 continue;
155 }
156 const auto *TTP = cast<TemplateTemplateParmDecl>(D);
157 ID.AddInteger(2);
158 ID.AddBoolean(TTP->isParameterPack());
159 TTP->getTemplateParameters()->Profile(ID, C);
160 }
161}
162
164 unsigned NumRequiredArgs = 0;
165 for (const NamedDecl *P : asArray()) {
166 if (P->isTemplateParameterPack()) {
167 if (std::optional<unsigned> Expansions = getExpandedPackSize(P)) {
168 NumRequiredArgs += *Expansions;
169 continue;
170 }
171 break;
172 }
173
174 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
175 if (TTP->hasDefaultArgument())
176 break;
177 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
178 if (NTTP->hasDefaultArgument())
179 break;
180 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
181 break;
182
183 ++NumRequiredArgs;
184 }
185
186 return NumRequiredArgs;
187}
188
189unsigned TemplateParameterList::getDepth() const {
190 if (size() == 0)
191 return 0;
192
193 const NamedDecl *FirstParm = getParam(0);
194 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
195 return TTP->getDepth();
196 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
197 return NTTP->getDepth();
198 else
199 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
200}
201
203 DeclContext *Owner) {
204 bool Invalid = false;
205 for (NamedDecl *P : *Params) {
206 P->setDeclContext(Owner);
207
208 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
209 if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner))
210 Invalid = true;
211
212 if (P->isInvalidDecl())
213 Invalid = true;
214 }
215 return Invalid;
216}
217
220 if (HasConstrainedParameters)
221 for (const NamedDecl *Param : *this) {
222 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
223 if (const auto *TC = TTP->getTypeConstraint())
224 AC.push_back(TC->getImmediatelyDeclaredConstraint());
225 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
226 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
227 AC.push_back(E);
228 }
229 }
230 if (HasRequiresClause)
231 AC.push_back(getRequiresClause());
232}
233
235 return HasRequiresClause || HasConstrainedParameters;
236}
237
239 const PrintingPolicy &Policy, const TemplateParameterList *TPL,
240 unsigned Idx) {
241 if (!TPL || Idx >= TPL->size() || Policy.AlwaysIncludeTypeForTemplateArgument)
242 return true;
243 const NamedDecl *TemplParam = TPL->getParam(Idx);
244 if (const auto *ParamValueDecl =
245 dyn_cast<NonTypeTemplateParmDecl>(TemplParam))
246 if (ParamValueDecl->getType()->getContainedDeducedType())
247 return true;
248 return false;
249}
250
251namespace clang {
252
254 return new (C) char[sizeof(void*) * 2];
255}
256
257} // namespace clang
258
259//===----------------------------------------------------------------------===//
260// TemplateDecl Implementation
261//===----------------------------------------------------------------------===//
262
266 : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
267
268void TemplateDecl::anchor() {}
269
273 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
274 if (const Expr *TRC = FD->getTrailingRequiresClause())
275 AC.push_back(TRC);
276}
277
280 return true;
281 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
282 return FD->getTrailingRequiresClause();
283 return false;
284}
285
287 switch (getKind()) {
288 case TemplateDecl::TypeAliasTemplate:
289 case TemplateDecl::BuiltinTemplate:
290 return true;
291 default:
292 return false;
293 };
294}
295
296//===----------------------------------------------------------------------===//
297// RedeclarableTemplateDecl Implementation
298//===----------------------------------------------------------------------===//
299
300void RedeclarableTemplateDecl::anchor() {}
301
303 if (Common)
304 return Common;
305
306 // Walk the previous-declaration chain until we either find a declaration
307 // with a common pointer or we run out of previous declarations.
309 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
310 Prev = Prev->getPreviousDecl()) {
311 if (Prev->Common) {
312 Common = Prev->Common;
313 break;
314 }
315
316 PrevDecls.push_back(Prev);
317 }
318
319 // If we never found a common pointer, allocate one now.
320 if (!Common) {
321 // FIXME: If any of the declarations is from an AST file, we probably
322 // need an update record to add the common data.
323
325 }
326
327 // Update any previous declarations we saw with the common pointer.
328 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
329 Prev->Common = Common;
330
331 return Common;
332}
333
335 // Grab the most recent declaration to ensure we've loaded any lazy
336 // redeclarations of this template.
337 CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
338 if (CommonBasePtr->LazySpecializations) {
339 ASTContext &Context = getASTContext();
340 GlobalDeclID *Specs = CommonBasePtr->LazySpecializations;
341 CommonBasePtr->LazySpecializations = nullptr;
342 unsigned SpecSize = (*Specs++).get();
343 for (unsigned I = 0; I != SpecSize; ++I)
344 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
345 }
346}
347
348template<class EntryType, typename... ProfileArguments>
351 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
352 ProfileArguments&&... ProfileArgs) {
353 using SETraits = SpecEntryTraits<EntryType>;
354
355 llvm::FoldingSetNodeID ID;
356 EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
357 getASTContext());
358 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
359 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
360}
361
362template<class Derived, class EntryType>
364 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
365 void *InsertPos) {
366 using SETraits = SpecEntryTraits<EntryType>;
367
368 if (InsertPos) {
369#ifndef NDEBUG
370 void *CorrectInsertPos;
371 assert(!findSpecializationImpl(Specializations,
372 CorrectInsertPos,
373 SETraits::getTemplateArgs(Entry)) &&
374 InsertPos == CorrectInsertPos &&
375 "given incorrect InsertPos for specialization");
376#endif
377 Specializations.InsertNode(Entry, InsertPos);
378 } else {
379 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
380 (void)Existing;
381 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
382 "non-canonical specialization?");
383 }
384
386 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
387 SETraits::getDecl(Entry));
388}
389
392 auto *CommonPtr = getCommonPtr();
393 if (!CommonPtr->InjectedArgs) {
394 auto &Context = getASTContext();
396 Context.getInjectedTemplateArgs(Params, TemplateArgs);
397 CommonPtr->InjectedArgs =
398 new (Context) TemplateArgument[TemplateArgs.size()];
399 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
400 CommonPtr->InjectedArgs);
401 }
402
403 return llvm::ArrayRef(CommonPtr->InjectedArgs, Params->size());
404}
405
406//===----------------------------------------------------------------------===//
407// FunctionTemplateDecl Implementation
408//===----------------------------------------------------------------------===//
409
412 DeclarationName Name,
414 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
415 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
416 if (Invalid)
417 TD->setInvalidDecl();
418 return TD;
419}
420
423 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
424 DeclarationName(), nullptr, nullptr);
425}
426
429 auto *CommonPtr = new (C) Common;
430 C.addDestruction(CommonPtr);
431 return CommonPtr;
432}
433
436}
437
438llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
442}
443
446 void *&InsertPos) {
447 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
448}
449
451 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
452 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
453 InsertPos);
454}
455
458
459 // If we haven't created a common pointer yet, then it can just be created
460 // with the usual method.
461 if (!Base::Common)
462 return;
463
464 Common *ThisCommon = static_cast<Common *>(Base::Common);
465 Common *PrevCommon = nullptr;
467 for (; Prev; Prev = Prev->getPreviousDecl()) {
468 if (Prev->Base::Common) {
469 PrevCommon = static_cast<Common *>(Prev->Base::Common);
470 break;
471 }
472 PreviousDecls.push_back(Prev);
473 }
474
475 // If the previous redecl chain hasn't created a common pointer yet, then just
476 // use this common pointer.
477 if (!PrevCommon) {
478 for (auto *D : PreviousDecls)
479 D->Base::Common = ThisCommon;
480 return;
481 }
482
483 // Ensure we don't leak any important state.
484 assert(ThisCommon->Specializations.size() == 0 &&
485 "Can't merge incompatible declarations!");
486
487 Base::Common = PrevCommon;
488}
489
490//===----------------------------------------------------------------------===//
491// ClassTemplateDecl Implementation
492//===----------------------------------------------------------------------===//
493
496 DeclarationName Name,
497 TemplateParameterList *Params,
498 NamedDecl *Decl) {
499 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
500 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
501 if (Invalid)
502 TD->setInvalidDecl();
503 return TD;
504}
505
507 GlobalDeclID ID) {
508 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
509 DeclarationName(), nullptr, nullptr);
510}
511
514}
515
516llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
520}
521
522llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
526}
527
530 auto *CommonPtr = new (C) Common;
531 C.addDestruction(CommonPtr);
532 return CommonPtr;
533}
534
537 void *&InsertPos) {
538 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
539}
540
542 void *InsertPos) {
543 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
544}
545
549 TemplateParameterList *TPL, void *&InsertPos) {
550 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
551 TPL);
552}
553
555 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
556 TemplateParameterList *TPL, const ASTContext &Context) {
557 ID.AddInteger(TemplateArgs.size());
558 for (const TemplateArgument &TemplateArg : TemplateArgs)
559 TemplateArg.Profile(ID, Context);
560 TPL->Profile(ID, Context);
561}
562
565 void *InsertPos) {
566 if (InsertPos)
567 getPartialSpecializations().InsertNode(D, InsertPos);
568 else {
570 = getPartialSpecializations().GetOrInsertNode(D);
571 (void)Existing;
572 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
573 }
574
576 L->AddedCXXTemplateSpecialization(this, D);
577}
578
581 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
583 PS.clear();
584 PS.reserve(PartialSpecs.size());
585 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
586 PS.push_back(P.getMostRecentDecl());
587}
588
591 ASTContext &Context = getASTContext();
594 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
595 return P.getMostRecentDecl();
596 }
597
598 return nullptr;
599}
600
604 Decl *DCanon = D->getCanonicalDecl();
606 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
607 return P.getMostRecentDecl();
608 }
609
610 return nullptr;
611}
612
615 Common *CommonPtr = getCommonPtr();
616 if (!CommonPtr->InjectedClassNameType.isNull())
617 return CommonPtr->InjectedClassNameType;
618
619 // C++0x [temp.dep.type]p2:
620 // The template argument list of a primary template is a template argument
621 // list in which the nth template argument has the value of the nth template
622 // parameter of the class template. If the nth template parameter is a
623 // template parameter pack (14.5.3), the nth template argument is a pack
624 // expansion (14.5.3) whose pattern is the name of the template parameter
625 // pack.
626 ASTContext &Context = getASTContext();
629 Context.getInjectedTemplateArgs(Params, TemplateArgs);
630 CommonPtr->InjectedClassNameType
632 TemplateArgs);
633 return CommonPtr->InjectedClassNameType;
634}
635
636//===----------------------------------------------------------------------===//
637// TemplateTypeParm Allocation/Deallocation Method Implementations
638//===----------------------------------------------------------------------===//
639
641 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
642 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
643 bool Typename, bool ParameterPack, bool HasTypeConstraint,
644 std::optional<unsigned> NumExpanded) {
645 auto *TTPDecl =
646 new (C, DC,
647 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
648 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
649 HasTypeConstraint, NumExpanded);
650 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
651 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
652 return TTPDecl;
653}
654
657 return new (C, ID)
659 false, false, std::nullopt);
660}
661
664 bool HasTypeConstraint) {
665 return new (C, ID,
666 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
668 false, HasTypeConstraint, std::nullopt);
669}
670
672 return hasDefaultArgument()
674 : SourceLocation();
675}
676
679 return SourceRange(getBeginLoc(),
680 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
681 // TypeDecl::getSourceRange returns a range containing name location, which is
682 // wrong for unnamed template parameters. e.g:
683 // it will return <[[typename>]] instead of <[[typename]]>
684 else if (getDeclName().isEmpty())
685 return SourceRange(getBeginLoc());
687}
688
691}
692
695}
696
699}
700
702 ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint) {
703 assert(HasTypeConstraint &&
704 "HasTypeConstraint=true must be passed at construction in order to "
705 "call setTypeConstraint");
706 assert(!TypeConstraintInitialized &&
707 "TypeConstraint was already initialized!");
708 new (getTrailingObjects<TypeConstraint>())
709 TypeConstraint(Loc, ImmediatelyDeclaredConstraint);
710 TypeConstraintInitialized = true;
711}
712
713//===----------------------------------------------------------------------===//
714// NonTypeTemplateParmDecl Method Implementations
715//===----------------------------------------------------------------------===//
716
717NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
718 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
719 unsigned P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
720 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
721 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
722 TemplateParmPosition(D, P), ParameterPack(true),
723 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
724 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
725 auto TypesAndInfos =
726 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
727 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
728 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
729 TypesAndInfos[I].second = ExpandedTInfos[I];
730 }
731 }
732}
733
735 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
736 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
737 QualType T, bool ParameterPack, TypeSourceInfo *TInfo) {
738 AutoType *AT =
739 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
740 return new (C, DC,
741 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
742 Expr *>(0,
743 AT && AT->isConstrained() ? 1 : 0))
744 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,
745 TInfo);
746}
747
749 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
750 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
751 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
752 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
753 AutoType *AT = TInfo->getType()->getContainedAutoType();
754 return new (C, DC,
755 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
756 Expr *>(
757 ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))
758 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
759 ExpandedTypes, ExpandedTInfos);
760}
761
764 bool HasTypeConstraint) {
765 return new (C, ID, additionalSizeToAlloc<std::pair<QualType,
767 Expr *>(0,
768 HasTypeConstraint ? 1 : 0))
770 0, 0, nullptr, QualType(), false, nullptr);
771}
772
775 unsigned NumExpandedTypes,
776 bool HasTypeConstraint) {
777 auto *NTTP =
778 new (C, ID,
779 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
780 NumExpandedTypes, HasTypeConstraint ? 1 : 0))
782 0, 0, nullptr, QualType(), nullptr,
783 std::nullopt, std::nullopt);
784 NTTP->NumExpandedTypes = NumExpandedTypes;
785 return NTTP;
786}
787
791 getDefaultArgument()->getSourceRange().getEnd());
793}
794
796 return hasDefaultArgument()
798 : SourceLocation();
799}
800
801//===----------------------------------------------------------------------===//
802// TemplateTemplateParmDecl Method Implementations
803//===----------------------------------------------------------------------===//
804
805void TemplateTemplateParmDecl::anchor() {}
806
807TemplateTemplateParmDecl::TemplateTemplateParmDecl(
808 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
811 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
812 TemplateParmPosition(D, P), Typename(Typename), ParameterPack(true),
813 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
814 if (!Expansions.empty())
815 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
816 getTrailingObjects<TemplateParameterList *>());
817}
818
821 SourceLocation L, unsigned D, unsigned P,
822 bool ParameterPack, IdentifierInfo *Id,
823 bool Typename, TemplateParameterList *Params) {
824 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
825 Typename, Params);
826}
827
830 SourceLocation L, unsigned D, unsigned P,
832 TemplateParameterList *Params,
834 return new (C, DC,
835 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
836 TemplateTemplateParmDecl(DC, L, D, P, Id, Typename, Params, Expansions);
837}
838
841 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
842 false, nullptr, false, nullptr);
843}
844
847 unsigned NumExpansions) {
848 auto *TTP =
849 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
850 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
851 false, nullptr, std::nullopt);
852 TTP->NumExpandedParams = NumExpansions;
853 return TTP;
854}
855
858 : SourceLocation();
859}
860
862 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
863 if (DefArg.getArgument().isNull())
864 DefaultArgument.set(nullptr);
865 else
866 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
867}
868
869//===----------------------------------------------------------------------===//
870// TemplateArgumentList Implementation
871//===----------------------------------------------------------------------===//
872TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
873 : NumArguments(Args.size()) {
874 std::uninitialized_copy(Args.begin(), Args.end(),
875 getTrailingObjects<TemplateArgument>());
876}
877
881 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
882 return new (Mem) TemplateArgumentList(Args);
883}
884
888 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
889 MemberSpecializationInfo *MSInfo) {
890 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
891 if (TemplateArgsAsWritten)
893 *TemplateArgsAsWritten);
894
895 void *Mem =
896 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
897 return new (Mem) FunctionTemplateSpecializationInfo(
898 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
899}
900
901//===----------------------------------------------------------------------===//
902// ClassTemplateSpecializationDecl Implementation
903//===----------------------------------------------------------------------===//
904
907 DeclContext *DC, SourceLocation StartLoc,
908 SourceLocation IdLoc,
909 ClassTemplateDecl *SpecializedTemplate,
912 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
913 SpecializedTemplate->getIdentifier(), PrevDecl),
914 SpecializedTemplate(SpecializedTemplate),
915 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
916 SpecializationKind(TSK_Undeclared) {
917}
918
920 Kind DK)
921 : CXXRecordDecl(DK, TagTypeKind::Struct, C, nullptr, SourceLocation(),
922 SourceLocation(), nullptr, nullptr),
923 SpecializationKind(TSK_Undeclared) {}
924
927 DeclContext *DC,
928 SourceLocation StartLoc,
929 SourceLocation IdLoc,
930 ClassTemplateDecl *SpecializedTemplate,
933 auto *Result =
934 new (Context, DC) ClassTemplateSpecializationDecl(
935 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
936 SpecializedTemplate, Args, PrevDecl);
937 Result->setMayHaveOutOfDateDef(false);
938
939 // If the template decl is incomplete, copy the external lexical storage from
940 // the base template. This allows instantiations of incomplete types to
941 // complete using the external AST if the template's declaration came from an
942 // external AST.
943 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
944 Result->setHasExternalLexicalStorage(
945 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
946
947 Context.getTypeDeclType(Result, PrevDecl);
948 return Result;
949}
950
953 GlobalDeclID ID) {
954 auto *Result =
955 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
956 Result->setMayHaveOutOfDateDef(false);
957 return Result;
958}
959
961 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
963
964 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
965 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
966 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
968 OS, ArgsAsWritten->arguments(), Policy,
969 getSpecializedTemplate()->getTemplateParameters());
970 } else {
971 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
973 OS, TemplateArgs.asArray(), Policy,
974 getSpecializedTemplate()->getTemplateParameters());
975 }
976}
977
980 if (const auto *PartialSpec =
981 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
982 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
983 return SpecializedTemplate.get<ClassTemplateDecl*>();
984}
985
988 switch (getSpecializationKind()) {
989 case TSK_Undeclared:
991 llvm::PointerUnion<ClassTemplateDecl *,
994 assert(!Pattern.isNull() &&
995 "Class template specialization without pattern?");
996 if (const auto *CTPSD =
997 Pattern.dyn_cast<ClassTemplatePartialSpecializationDecl *>())
998 return CTPSD->getSourceRange();
999 return Pattern.get<ClassTemplateDecl *>()->getSourceRange();
1000 }
1005 Range.setEnd(Args->getRAngleLoc());
1006 return Range;
1007 }
1011 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1012 Range.setBegin(ExternKW);
1013 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1014 TemplateKW.isValid())
1015 Range.setBegin(TemplateKW);
1017 Range.setEnd(Args->getRAngleLoc());
1018 return Range;
1019 }
1020 }
1021 llvm_unreachable("unhandled template specialization kind");
1022}
1023
1025 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1026 if (!Info) {
1027 // Don't allocate if the location is invalid.
1028 if (Loc.isInvalid())
1029 return;
1032 ExplicitInfo = Info;
1033 }
1034 Info->ExternKeywordLoc = Loc;
1035}
1036
1039 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1040 if (!Info) {
1041 // Don't allocate if the location is invalid.
1042 if (Loc.isInvalid())
1043 return;
1046 ExplicitInfo = Info;
1047 }
1048 Info->TemplateKeywordLoc = Loc;
1049}
1050
1051//===----------------------------------------------------------------------===//
1052// ConceptDecl Implementation
1053//===----------------------------------------------------------------------===//
1056 TemplateParameterList *Params,
1057 Expr *ConstraintExpr) {
1058 bool Invalid = AdoptTemplateParameterList(Params, DC);
1059 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1060 if (Invalid)
1061 TD->setInvalidDecl();
1062 return TD;
1063}
1064
1066 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1068 nullptr, nullptr);
1069
1070 return Result;
1071}
1072
1073//===----------------------------------------------------------------------===//
1074// ImplicitConceptSpecializationDecl Implementation
1075//===----------------------------------------------------------------------===//
1076ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1078 ArrayRef<TemplateArgument> ConvertedArgs)
1079 : Decl(ImplicitConceptSpecialization, DC, SL),
1080 NumTemplateArgs(ConvertedArgs.size()) {
1081 setTemplateArguments(ConvertedArgs);
1082}
1083
1084ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1085 EmptyShell Empty, unsigned NumTemplateArgs)
1086 : Decl(ImplicitConceptSpecialization, Empty),
1087 NumTemplateArgs(NumTemplateArgs) {}
1088
1090 const ASTContext &C, DeclContext *DC, SourceLocation SL,
1091 ArrayRef<TemplateArgument> ConvertedArgs) {
1092 return new (C, DC,
1093 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1094 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1095}
1096
1099 const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) {
1100 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1102}
1103
1105 ArrayRef<TemplateArgument> Converted) {
1106 assert(Converted.size() == NumTemplateArgs);
1107 std::uninitialized_copy(Converted.begin(), Converted.end(),
1108 getTrailingObjects<TemplateArgument>());
1109}
1110
1111//===----------------------------------------------------------------------===//
1112// ClassTemplatePartialSpecializationDecl Implementation
1113//===----------------------------------------------------------------------===//
1114void ClassTemplatePartialSpecializationDecl::anchor() {}
1115
1116ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
1117 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1119 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1122 Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
1123 SpecializedTemplate, Args, PrevDecl),
1124 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1125 if (AdoptTemplateParameterList(Params, this))
1127}
1128
1131 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1133 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1134 QualType CanonInjectedType,
1136 auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl(
1137 Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args,
1138 PrevDecl);
1139 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1140 Result->setMayHaveOutOfDateDef(false);
1141
1142 Context.getInjectedClassNameType(Result, CanonInjectedType);
1143 return Result;
1144}
1145
1148 GlobalDeclID ID) {
1150 Result->setMayHaveOutOfDateDef(false);
1151 return Result;
1152}
1153
1157 MT && !isMemberSpecialization())
1158 return MT->getSourceRange();
1163 return Range;
1164}
1165
1166//===----------------------------------------------------------------------===//
1167// FriendTemplateDecl Implementation
1168//===----------------------------------------------------------------------===//
1169
1170void FriendTemplateDecl::anchor() {}
1171
1176 FriendUnion Friend, SourceLocation FLoc) {
1177 TemplateParameterList **TPL = nullptr;
1178 if (!Params.empty()) {
1179 TPL = new (Context) TemplateParameterList *[Params.size()];
1180 llvm::copy(Params, TPL);
1181 }
1182 return new (Context, DC)
1183 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
1184}
1185
1187 GlobalDeclID ID) {
1188 return new (C, ID) FriendTemplateDecl(EmptyShell());
1189}
1190
1191//===----------------------------------------------------------------------===//
1192// TypeAliasTemplateDecl Implementation
1193//===----------------------------------------------------------------------===//
1194
1197 DeclarationName Name,
1199 bool Invalid = AdoptTemplateParameterList(Params, DC);
1200 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1201 if (Invalid)
1202 TD->setInvalidDecl();
1203 return TD;
1204}
1205
1208 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1209 DeclarationName(), nullptr, nullptr);
1210}
1211
1214 auto *CommonPtr = new (C) Common;
1215 C.addDestruction(CommonPtr);
1216 return CommonPtr;
1217}
1218
1219//===----------------------------------------------------------------------===//
1220// VarTemplateDecl Implementation
1221//===----------------------------------------------------------------------===//
1222
1224 VarTemplateDecl *CurD = this;
1225 while (CurD) {
1226 if (CurD->isThisDeclarationADefinition())
1227 return CurD;
1228 CurD = CurD->getPreviousDecl();
1229 }
1230 return nullptr;
1231}
1232
1235 TemplateParameterList *Params,
1236 VarDecl *Decl) {
1237 bool Invalid = AdoptTemplateParameterList(Params, DC);
1238 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1239 if (Invalid)
1240 TD->setInvalidDecl();
1241 return TD;
1242}
1243
1245 GlobalDeclID ID) {
1246 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1247 DeclarationName(), nullptr, nullptr);
1248}
1249
1252}
1253
1254llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1257 return getCommonPtr()->Specializations;
1258}
1259
1260llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1264}
1265
1268 auto *CommonPtr = new (C) Common;
1269 C.addDestruction(CommonPtr);
1270 return CommonPtr;
1271}
1272
1275 void *&InsertPos) {
1276 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
1277}
1278
1280 void *InsertPos) {
1281 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1282}
1283
1286 TemplateParameterList *TPL, void *&InsertPos) {
1287 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1288 TPL);
1289}
1290
1292 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1293 TemplateParameterList *TPL, const ASTContext &Context) {
1294 ID.AddInteger(TemplateArgs.size());
1295 for (const TemplateArgument &TemplateArg : TemplateArgs)
1296 TemplateArg.Profile(ID, Context);
1297 TPL->Profile(ID, Context);
1298}
1299
1301 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1302 if (InsertPos)
1303 getPartialSpecializations().InsertNode(D, InsertPos);
1304 else {
1306 getPartialSpecializations().GetOrInsertNode(D);
1307 (void)Existing;
1308 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1309 }
1310
1312 L->AddedCXXTemplateSpecialization(this, D);
1313}
1314
1317 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1319 PS.clear();
1320 PS.reserve(PartialSpecs.size());
1321 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1322 PS.push_back(P.getMostRecentDecl());
1323}
1324
1328 Decl *DCanon = D->getCanonicalDecl();
1330 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1331 return P.getMostRecentDecl();
1332 }
1333
1334 return nullptr;
1335}
1336
1337//===----------------------------------------------------------------------===//
1338// VarTemplateSpecializationDecl Implementation
1339//===----------------------------------------------------------------------===//
1340
1342 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1343 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1345 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1346 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1347 SpecializedTemplate(SpecializedTemplate),
1348 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1349 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1350
1352 ASTContext &C)
1353 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1354 QualType(), nullptr, SC_None),
1355 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1356
1358 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1359 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1361 return new (Context, DC) VarTemplateSpecializationDecl(
1362 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1363 SpecializedTemplate, T, TInfo, S, Args);
1364}
1365
1368 GlobalDeclID ID) {
1369 return new (C, ID)
1370 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1371}
1372
1374 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1376
1377 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1378 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1379 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1381 OS, ArgsAsWritten->arguments(), Policy,
1382 getSpecializedTemplate()->getTemplateParameters());
1383 } else {
1384 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1386 OS, TemplateArgs.asArray(), Policy,
1387 getSpecializedTemplate()->getTemplateParameters());
1388 }
1389}
1390
1392 if (const auto *PartialSpec =
1393 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1394 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1395 return SpecializedTemplate.get<VarTemplateDecl *>();
1396}
1397
1399 switch (getSpecializationKind()) {
1400 case TSK_Undeclared:
1402 llvm::PointerUnion<VarTemplateDecl *,
1405 assert(!Pattern.isNull() &&
1406 "Variable template specialization without pattern?");
1407 if (const auto *VTPSD =
1408 Pattern.dyn_cast<VarTemplatePartialSpecializationDecl *>())
1409 return VTPSD->getSourceRange();
1410 VarTemplateDecl *VTD = Pattern.get<VarTemplateDecl *>();
1411 if (hasInit()) {
1413 return Definition->getSourceRange();
1414 }
1415 return VTD->getCanonicalDecl()->getSourceRange();
1416 }
1420 !hasInit() && Args)
1421 Range.setEnd(Args->getRAngleLoc());
1422 return Range;
1423 }
1427 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1428 Range.setBegin(ExternKW);
1429 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1430 TemplateKW.isValid())
1431 Range.setBegin(TemplateKW);
1433 Range.setEnd(Args->getRAngleLoc());
1434 return Range;
1435 }
1436 }
1437 llvm_unreachable("unhandled template specialization kind");
1438}
1439
1441 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1442 if (!Info) {
1443 // Don't allocate if the location is invalid.
1444 if (Loc.isInvalid())
1445 return;
1448 ExplicitInfo = Info;
1449 }
1450 Info->ExternKeywordLoc = Loc;
1451}
1452
1454 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1455 if (!Info) {
1456 // Don't allocate if the location is invalid.
1457 if (Loc.isInvalid())
1458 return;
1461 ExplicitInfo = Info;
1462 }
1463 Info->TemplateKeywordLoc = Loc;
1464}
1465
1466//===----------------------------------------------------------------------===//
1467// VarTemplatePartialSpecializationDecl Implementation
1468//===----------------------------------------------------------------------===//
1469
1470void VarTemplatePartialSpecializationDecl::anchor() {}
1471
1472VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1473 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1475 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1477 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1478 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1479 TInfo, S, Args),
1480 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1481 if (AdoptTemplateParameterList(Params, DC))
1483}
1484
1487 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1489 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1491 auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(
1492 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,
1493 Args);
1494 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1495 return Result;
1496}
1497
1500 GlobalDeclID ID) {
1501 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1502}
1503
1507 MT && !isMemberSpecialization())
1508 return MT->getSourceRange();
1513 return Range;
1514}
1515
1516static TemplateParameterList *
1518 // typename T
1520 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1521 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1522 /*HasTypeConstraint=*/false);
1523 T->setImplicit(true);
1524
1525 // T ...Ints
1526 TypeSourceInfo *TI =
1527 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1529 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1530 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1531 N->setImplicit(true);
1532
1533 // <typename T, T ...Ints>
1534 NamedDecl *P[2] = {T, N};
1536 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1537
1538 // template <typename T, ...Ints> class IntSeq
1539 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1540 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1541 /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, TPL);
1542 TemplateTemplateParm->setImplicit(true);
1543
1544 // typename T
1545 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1546 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1547 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1548 /*HasTypeConstraint=*/false);
1549 TemplateTypeParm->setImplicit(true);
1550
1551 // T N
1552 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1553 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1554 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1555 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1556 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1557 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1558 NonTypeTemplateParm};
1559
1560 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1562 Params, SourceLocation(), nullptr);
1563}
1564
1565static TemplateParameterList *
1567 // std::size_t Index
1568 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1569 auto *Index = NonTypeTemplateParmDecl::Create(
1570 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1571 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1572
1573 // typename ...T
1575 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1576 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
1577 /*HasTypeConstraint=*/false);
1578 Ts->setImplicit(true);
1579
1580 // template <std::size_t Index, typename ...T>
1581 NamedDecl *Params[] = {Index, Ts};
1583 llvm::ArrayRef(Params), SourceLocation(),
1584 nullptr);
1585}
1586
1588 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1589 switch (BTK) {
1594 }
1595
1596 llvm_unreachable("unhandled BuiltinTemplateKind!");
1597}
1598
1599void BuiltinTemplateDecl::anchor() {}
1600
1601BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1602 DeclarationName Name,
1604 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1606 BTK(BTK) {}
1607
1608TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1609 QualType T,
1610 const APValue &V) {
1611 DeclContext *DC = C.getTranslationUnitDecl();
1612 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1613 C.addDestruction(&TPOD->Value);
1614 return TPOD;
1615}
1616
1618TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1619 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1620 C.addDestruction(&TPOD->Value);
1621 return TPOD;
1622}
1623
1624void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1625 const PrintingPolicy &Policy) const {
1626 OS << "<template param ";
1627 printAsExpr(OS, Policy);
1628 OS << ">";
1629}
1630
1631void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1632 printAsExpr(OS, getASTContext().getPrintingPolicy());
1633}
1634
1635void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1636 const PrintingPolicy &Policy) const {
1637 getType().getUnqualifiedType().print(OS, Policy);
1638 printAsInit(OS, Policy);
1639}
1640
1641void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1642 printAsInit(OS, getASTContext().getPrintingPolicy());
1643}
1644
1645void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1646 const PrintingPolicy &Policy) const {
1647 getValue().printPretty(OS, Policy, getType(), &getASTContext());
1648}
1649
1651 switch (D->getKind()) {
1652 case Decl::Kind::CXXRecord:
1653 return cast<CXXRecordDecl>(D)
1654 ->getDescribedTemplate()
1655 ->getTemplateParameters();
1656 case Decl::Kind::ClassTemplate:
1657 return cast<ClassTemplateDecl>(D)->getTemplateParameters();
1658 case Decl::Kind::ClassTemplateSpecialization: {
1659 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1660 auto P = CTSD->getSpecializedTemplateOrPartial();
1661 if (const auto *CTPSD =
1663 return CTPSD->getTemplateParameters();
1664 return cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1665 }
1666 case Decl::Kind::ClassTemplatePartialSpecialization:
1667 return cast<ClassTemplatePartialSpecializationDecl>(D)
1668 ->getTemplateParameters();
1669 case Decl::Kind::TypeAliasTemplate:
1670 return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
1671 case Decl::Kind::BuiltinTemplate:
1672 return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
1673 case Decl::Kind::CXXDeductionGuide:
1674 case Decl::Kind::CXXConversion:
1675 case Decl::Kind::CXXConstructor:
1676 case Decl::Kind::CXXDestructor:
1677 case Decl::Kind::CXXMethod:
1678 case Decl::Kind::Function:
1679 return cast<FunctionDecl>(D)
1680 ->getTemplateSpecializationInfo()
1681 ->getTemplate()
1682 ->getTemplateParameters();
1683 case Decl::Kind::FunctionTemplate:
1684 return cast<FunctionTemplateDecl>(D)->getTemplateParameters();
1685 case Decl::Kind::VarTemplate:
1686 return cast<VarTemplateDecl>(D)->getTemplateParameters();
1687 case Decl::Kind::VarTemplateSpecialization: {
1688 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1689 auto P = VTSD->getSpecializedTemplateOrPartial();
1690 if (const auto *VTPSD =
1692 return VTPSD->getTemplateParameters();
1693 return cast<VarTemplateDecl *>(P)->getTemplateParameters();
1694 }
1695 case Decl::Kind::VarTemplatePartialSpecialization:
1696 return cast<VarTemplatePartialSpecializationDecl>(D)
1697 ->getTemplateParameters();
1698 case Decl::Kind::TemplateTemplateParm:
1699 return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();
1700 case Decl::Kind::Concept:
1701 return cast<ConceptDecl>(D)->getTemplateParameters();
1702 default:
1703 llvm_unreachable("Unhandled templated declaration kind");
1704 }
1705}
Defines the clang::ASTContext interface.
#define V(N, I)
Definition: ASTContext.h:3285
int Id
Definition: ASTDiff.cpp:190
StringRef P
Defines enum values for all the target-independent builtin functions.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static TemplateParameterList * createTypePackElementParameterList(const ASTContext &C, DeclContext *DC)
static TemplateParameterList * createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC)
static bool AdoptTemplateParameterList(TemplateParameterList *Params, DeclContext *Owner)
static TemplateParameterList * createBuiltinTemplateParameterList(const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK)
Defines the C++ template declaration subclasses.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static StringRef getIdentifier(const Token &Tok)
SourceRange Range
Definition: SemaObjC.cpp:754
SourceLocation Loc
Definition: SemaObjC.cpp:755
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:693
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
QualType getTemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > Args, QualType Canon=QualType()) const
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const
getInjectedClassNameType - Return the unique reference to the injected class name type for the specif...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2591
void getInjectedTemplateArgs(const TemplateParameterList *Params, SmallVectorImpl< TemplateArgument > &Args)
Get a template argument list with one argument per template parameter in a template parameter list,...
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
Definition: ASTContext.h:1591
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:718
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
Definition: ASTContext.h:1189
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:5981
bool isConstrained() const
Definition: Type.h:6000
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclCXX.h:523
Declaration of a class template.
void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this class template.
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
ClassTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
CommonBase * newCommon(ASTContext &C) const override
static ClassTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a class template node.
ClassTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *D)
Find a class template partial specialization which was instantiated from the given member partial spe...
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
QualType getInjectedClassNameSpecialization()
Retrieve the template specialization type of the injected-class-name for this class template.
Common * getCommonPtr() const
ClassTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
static ClassTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty class template node.
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member class template partial specialization from which this particular class template p...
static ClassTemplatePartialSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, QualType CanonInjectedType, ClassTemplatePartialSpecializationDecl *PrevDecl)
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 * 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.
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, ClassTemplateSpecializationDecl *PrevDecl)
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.
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.
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
static ClassTemplateSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, ClassTemplateSpecializationDecl *PrevDecl)
Declaration of a C++20 concept.
static ConceptDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
static ConceptDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr)
A reference to a concept and its template args, as it appears in the code.
Definition: ASTConcept.h:128
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
bool hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
Definition: DeclBase.h:2637
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
SourceLocation getEndLoc() const LLVM_READONLY
Definition: DeclBase.h:441
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:501
ASTMutationListener * getASTMutationListener() const
Definition: DeclBase.cpp:511
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition: DeclBase.cpp:132
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:974
Kind getKind() const
Definition: DeclBase.h:448
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:770
SourceLocation getOuterLocStart() const
Return start of source range taking into account any outer template declarations.
Definition: Decl.cpp:2047
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2087
unsigned getNumTemplateParameterLists() const
Definition: Decl.h:858
void set(ArgType Arg)
Set the default argument.
Definition: DeclTemplate.h:354
This represents one expression.
Definition: Expr.h:110
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
Definition: Expr.h:239
virtual Decl * GetExternalDecl(GlobalDeclID ID)
Resolve a declaration ID into a declaration, potentially building a new declaration.
Declaration of a friend template.
static FriendTemplateDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc, MutableArrayRef< TemplateParameterList * > Params, FriendUnion Friend, SourceLocation FriendLoc)
llvm::PointerUnion< NamedDecl *, TypeSourceInfo * > FriendUnion
static FriendTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Represents a function declaration or definition.
Definition: Decl.h:1971
Declaration of a template function.
Definition: DeclTemplate.h:957
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
void addSpecialization(FunctionTemplateSpecializationInfo *Info, void *InsertPos)
Add a specialization of this function template.
CommonBase * newCommon(ASTContext &C) const override
Common * getCommonPtr() const
Definition: DeclTemplate.h:979
FunctionTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...
static FunctionTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty function template node.
static FunctionTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > & getSpecializations() const
Retrieve the set of function template specializations of this function template.
void mergePrevDecl(FunctionTemplateDecl *Prev)
Merge Prev with our RedeclarableTemplateDecl::Common.
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
Provides information about a function template specialization, which is a FunctionDecl that has been ...
Definition: DeclTemplate.h:467
static FunctionTemplateSpecializationInfo * Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs, const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI, MemberSpecializationInfo *MSInfo)
One of these records is kept for each identifier that is lexed.
void setTemplateArguments(ArrayRef< TemplateArgument > Converted)
static ImplicitConceptSpecializationDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef< TemplateArgument > ConvertedArgs)
static ImplicitConceptSpecializationDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs)
Provides information a specialization of a member of a class template, which may be a member function...
Definition: DeclTemplate.h:615
This represents a decl that may have a name.
Definition: Decl.h:249
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:315
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:1826
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
static NonTypeTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint)
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo)
Expr * getDefaultArgument() const
Retrieve the default argument, if any.
A (possibly-)qualified type.
Definition: Type.h:940
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1007
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:7359
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: Type.h:7453
Declaration of a redeclarable template.
Definition: DeclTemplate.h:716
CommonBase * getCommonPtr() const
Retrieves the "common" pointer shared by all (re-)declarations of the same template.
SpecEntryTraits< EntryType >::DeclType * findSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments &&...ProfileArgs)
CommonBase * Common
Pointer to the common data shared by all declarations of this template.
Definition: DeclTemplate.h:813
virtual CommonBase * newCommon(ASTContext &C) const =0
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, void *InsertPos)
ArrayRef< TemplateArgument > getInjectedTemplateArgs()
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
RedeclarableTemplateDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Definition: Redeclarable.h:204
RedeclarableTemplateDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:226
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getBegin() const
void setEnd(SourceLocation e)
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:326
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition: Decl.h:3682
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3687
unsigned getNumTemplateParameterLists() const
Definition: Decl.h:3836
A convenient class for passing around template argument information.
Definition: TemplateBase.h:632
A template argument list.
Definition: DeclTemplate.h:244
static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument list that copies the given set of template arguments.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Definition: DeclTemplate.h:274
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
SourceLocation getLocation() const
Definition: TemplateBase.h:563
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:574
Represents a template argument.
Definition: TemplateBase.h:61
bool isNull() const
Determine whether this template argument has no value.
Definition: TemplateBase.h:298
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
TemplateParameterList * TemplateParams
Definition: DeclTemplate.h:445
bool isTypeAlias() const
bool hasAssociatedConstraints() const
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:426
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclTemplate.h:438
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:413
Represents a C++ template name within the type system.
Definition: TemplateName.h:202
A template parameter object.
void printAsExpr(llvm::raw_ostream &OS) const
Print this object as an equivalent expression.
const APValue & getValue() const
void printName(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const override
Print this template parameter object in a human-readable format.
void printAsInit(llvm::raw_ostream &OS) const
Print this object as an initializer suitable for a variable of the object's type.
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:144
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
bool hasAssociatedConstraints() const
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to form a template specialization.
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
Definition: DeclTemplate.h:180
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
All associated constraints derived from this template parameter list, including the requires clause a...
ArrayRef< NamedDecl * > asArray()
Definition: DeclTemplate.h:139
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
SourceLocation getTemplateLoc() const
Definition: DeclTemplate.h:199
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.
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
static TemplateTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, bool Typename, TemplateParameterList *Params)
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.
unsigned getIndex() const
Retrieve the index of the template parameter.
static TemplateTypeParmDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID)
TypeSourceInfo * getDefaultArgumentInfo() const
Retrieves the default argument's source information, if any.
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, std::optional< unsigned > 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 setTypeConstraint(ConceptReference *CR, Expr *ImmediatelyDeclaredConstraint)
Declaration of an alias template.
CommonBase * newCommon(ASTContext &C) const override
static TypeAliasTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty alias template node.
static TypeAliasTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition: ASTConcept.h:231
const Type * getTypeForDecl() const
Definition: Decl.h:3414
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.h:3419
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Decl.h:3417
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:192
A container of type source information.
Definition: Type.h:7330
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:256
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:7341
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8193
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition: Type.h:2758
QualType getType() const
Definition: Decl.h:717
Represents a variable declaration or definition.
Definition: Decl.h:918
bool hasInit() const
Definition: Decl.cpp:2395
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2187
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:2254
@ Definition
This declaration is definitely a definition.
Definition: Decl.h:1288
Declaration of a variable template.
VarTemplateDecl * getDefinition()
VarTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
Common * getCommonPtr() const
VarTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
VarTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this variable template, or nullptr if no such declaration exists...
CommonBase * newCommon(ASTContext &C) const override
static VarTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty variable template node.
static VarTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, VarDecl *Decl)
Create a variable template node.
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this variable template.
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary variable pattern.
VarTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
VarTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl *D)
Find a variable template partial specialization which was instantiated from the given member partial ...
static VarTemplatePartialSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
VarTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member variable template partial specialization from which this particular variable temp...
bool isMemberSpecialization() const
Determines whether this variable template partial specialization was a specialization of a member par...
void Profile(llvm::FoldingSetNodeID &ID) const
static VarTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Represents a variable template specialization, which refers to a variable template with a given set o...
VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static VarTemplateSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the variable template or variable template partial specialization which was specialized by t...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
VarTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
static VarTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
The JSON file list parser is used to communicate input to InstallAPI.
StorageClass
Storage classes.
Definition: Specifiers.h:245
@ SC_None
Definition: Specifiers.h:247
void * allocateDefaultArgStorageChain(const ASTContext &C)
@ Result
The result type of a method or function.
TemplateParameterList * getReplacedTemplateParameterList(Decl *D)
Internal helper used by Subst* nodes to retrieve the parameter list for their AssociatedDecl.
TagTypeKind
The kind of a tag type.
Definition: Type.h:6299
BuiltinTemplateKind
Kinds of BuiltinTemplateDecl.
Definition: Builtins.h:302
@ BTK__type_pack_element
This names the __type_pack_element BuiltinTemplateDecl.
Definition: Builtins.h:307
@ BTK__make_integer_seq
This names the __make_integer_seq BuiltinTemplateDecl.
Definition: Builtins.h:304
std::optional< unsigned > getExpandedPackSize(const NamedDecl *Param)
Check whether the template parameter is a pack expansion, and if so, determine the number of paramete...
const FunctionProtoType * T
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
Definition: Specifiers.h:185
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition: Specifiers.h:203
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition: Specifiers.h:199
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition: Specifiers.h:195
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition: Specifiers.h:191
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:188
@ Struct
The "struct" keyword introduces the elaborated-type-specifier.
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
#define true
Definition: stdbool.h:25
#define false
Definition: stdbool.h:26
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:676
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
Data that is common to all of the declarations of a given class template.
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...
QualType InjectedClassNameType
The injected-class-name type for this class template.
A placeholder type used to construct an empty shell of a decl-derived type that will be filled in lat...
Definition: DeclBase.h:102
Provides information about an explicit instantiation of a variable or class template.
const ASTTemplateArgumentListInfo * TemplateArgsAsWritten
The template arguments as written..
Data that is common to all of the declarations of a given function template.
Definition: DeclTemplate.h:963
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > Specializations
The function template specializations for this function template, including explicit specializations ...
Definition: DeclTemplate.h:966
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
unsigned AlwaysIncludeTypeForTemplateArgument
Whether to use type suffixes (eg: 1U) on integral non-type template parameters.
GlobalDeclID * LazySpecializations
If non-null, points to an array of specializations (including partial specializations) known only by ...
Definition: DeclTemplate.h:799
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 ...