clang 18.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 uint32_t *Specs = CommonBasePtr->LazySpecializations;
341 CommonBasePtr->LazySpecializations = nullptr;
342 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
343 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
344 }
345}
346
347template<class EntryType, typename... ProfileArguments>
350 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
351 ProfileArguments&&... ProfileArgs) {
352 using SETraits = SpecEntryTraits<EntryType>;
353
354 llvm::FoldingSetNodeID ID;
355 EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
356 getASTContext());
357 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
358 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
359}
360
361template<class Derived, class EntryType>
363 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
364 void *InsertPos) {
365 using SETraits = SpecEntryTraits<EntryType>;
366
367 if (InsertPos) {
368#ifndef NDEBUG
369 void *CorrectInsertPos;
370 assert(!findSpecializationImpl(Specializations,
371 CorrectInsertPos,
372 SETraits::getTemplateArgs(Entry)) &&
373 InsertPos == CorrectInsertPos &&
374 "given incorrect InsertPos for specialization");
375#endif
376 Specializations.InsertNode(Entry, InsertPos);
377 } else {
378 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
379 (void)Existing;
380 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
381 "non-canonical specialization?");
382 }
383
385 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
386 SETraits::getDecl(Entry));
387}
388
391 auto *CommonPtr = getCommonPtr();
392 if (!CommonPtr->InjectedArgs) {
393 auto &Context = getASTContext();
395 Context.getInjectedTemplateArgs(Params, TemplateArgs);
396 CommonPtr->InjectedArgs =
397 new (Context) TemplateArgument[TemplateArgs.size()];
398 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
399 CommonPtr->InjectedArgs);
400 }
401
402 return llvm::ArrayRef(CommonPtr->InjectedArgs, Params->size());
403}
404
405//===----------------------------------------------------------------------===//
406// FunctionTemplateDecl Implementation
407//===----------------------------------------------------------------------===//
408
411 DeclarationName Name,
413 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
414 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
415 if (Invalid)
416 TD->setInvalidDecl();
417 return TD;
418}
419
421 unsigned ID) {
422 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
423 DeclarationName(), nullptr, nullptr);
424}
425
428 auto *CommonPtr = new (C) Common;
429 C.addDestruction(CommonPtr);
430 return CommonPtr;
431}
432
435}
436
437llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
441}
442
445 void *&InsertPos) {
446 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
447}
448
450 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
451 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
452 InsertPos);
453}
454
457
458 // If we haven't created a common pointer yet, then it can just be created
459 // with the usual method.
460 if (!Base::Common)
461 return;
462
463 Common *ThisCommon = static_cast<Common *>(Base::Common);
464 Common *PrevCommon = nullptr;
466 for (; Prev; Prev = Prev->getPreviousDecl()) {
467 if (Prev->Base::Common) {
468 PrevCommon = static_cast<Common *>(Prev->Base::Common);
469 break;
470 }
471 PreviousDecls.push_back(Prev);
472 }
473
474 // If the previous redecl chain hasn't created a common pointer yet, then just
475 // use this common pointer.
476 if (!PrevCommon) {
477 for (auto *D : PreviousDecls)
478 D->Base::Common = ThisCommon;
479 return;
480 }
481
482 // Ensure we don't leak any important state.
483 assert(ThisCommon->Specializations.size() == 0 &&
484 "Can't merge incompatible declarations!");
485
486 Base::Common = PrevCommon;
487}
488
489//===----------------------------------------------------------------------===//
490// ClassTemplateDecl Implementation
491//===----------------------------------------------------------------------===//
492
495 DeclarationName Name,
496 TemplateParameterList *Params,
497 NamedDecl *Decl) {
498 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
499 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
500 if (Invalid)
501 TD->setInvalidDecl();
502 return TD;
503}
504
506 unsigned ID) {
507 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
508 DeclarationName(), nullptr, nullptr);
509}
510
513}
514
515llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
519}
520
521llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
525}
526
529 auto *CommonPtr = new (C) Common;
530 C.addDestruction(CommonPtr);
531 return CommonPtr;
532}
533
536 void *&InsertPos) {
537 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
538}
539
541 void *InsertPos) {
542 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
543}
544
548 TemplateParameterList *TPL, void *&InsertPos) {
549 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
550 TPL);
551}
552
554 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
555 TemplateParameterList *TPL, const ASTContext &Context) {
556 ID.AddInteger(TemplateArgs.size());
557 for (const TemplateArgument &TemplateArg : TemplateArgs)
558 TemplateArg.Profile(ID, Context);
559 TPL->Profile(ID, Context);
560}
561
564 void *InsertPos) {
565 if (InsertPos)
566 getPartialSpecializations().InsertNode(D, InsertPos);
567 else {
569 = getPartialSpecializations().GetOrInsertNode(D);
570 (void)Existing;
571 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
572 }
573
575 L->AddedCXXTemplateSpecialization(this, D);
576}
577
580 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
582 PS.clear();
583 PS.reserve(PartialSpecs.size());
584 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
585 PS.push_back(P.getMostRecentDecl());
586}
587
590 ASTContext &Context = getASTContext();
593 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
594 return P.getMostRecentDecl();
595 }
596
597 return nullptr;
598}
599
603 Decl *DCanon = D->getCanonicalDecl();
605 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
606 return P.getMostRecentDecl();
607 }
608
609 return nullptr;
610}
611
614 Common *CommonPtr = getCommonPtr();
615 if (!CommonPtr->InjectedClassNameType.isNull())
616 return CommonPtr->InjectedClassNameType;
617
618 // C++0x [temp.dep.type]p2:
619 // The template argument list of a primary template is a template argument
620 // list in which the nth template argument has the value of the nth template
621 // parameter of the class template. If the nth template parameter is a
622 // template parameter pack (14.5.3), the nth template argument is a pack
623 // expansion (14.5.3) whose pattern is the name of the template parameter
624 // pack.
625 ASTContext &Context = getASTContext();
628 Context.getInjectedTemplateArgs(Params, TemplateArgs);
629 CommonPtr->InjectedClassNameType
631 TemplateArgs);
632 return CommonPtr->InjectedClassNameType;
633}
634
635//===----------------------------------------------------------------------===//
636// TemplateTypeParm Allocation/Deallocation Method Implementations
637//===----------------------------------------------------------------------===//
638
640 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
641 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
642 bool Typename, bool ParameterPack, bool HasTypeConstraint,
643 std::optional<unsigned> NumExpanded) {
644 auto *TTPDecl =
645 new (C, DC,
646 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
647 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
648 HasTypeConstraint, NumExpanded);
649 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
650 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
651 return TTPDecl;
652}
653
656 return new (C, ID)
658 false, false, std::nullopt);
659}
660
663 bool HasTypeConstraint) {
664 return new (C, ID,
665 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
667 false, HasTypeConstraint, std::nullopt);
668}
669
671 return hasDefaultArgument()
673 : SourceLocation();
674}
675
678 return SourceRange(getBeginLoc(),
679 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
680 // TypeDecl::getSourceRange returns a range containing name location, which is
681 // wrong for unnamed template parameters. e.g:
682 // it will return <[[typename>]] instead of <[[typename]]>
683 else if (getDeclName().isEmpty())
684 return SourceRange(getBeginLoc());
686}
687
690}
691
694}
695
698}
699
701 ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint) {
702 assert(HasTypeConstraint &&
703 "HasTypeConstraint=true must be passed at construction in order to "
704 "call setTypeConstraint");
705 assert(!TypeConstraintInitialized &&
706 "TypeConstraint was already initialized!");
707 new (getTrailingObjects<TypeConstraint>())
708 TypeConstraint(Loc, ImmediatelyDeclaredConstraint);
709 TypeConstraintInitialized = true;
710}
711
712//===----------------------------------------------------------------------===//
713// NonTypeTemplateParmDecl Method Implementations
714//===----------------------------------------------------------------------===//
715
716NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
717 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
718 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
719 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
720 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
721 TemplateParmPosition(D, P), ParameterPack(true),
722 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
723 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
724 auto TypesAndInfos =
725 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
726 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
727 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
728 TypesAndInfos[I].second = ExpandedTInfos[I];
729 }
730 }
731}
732
735 SourceLocation StartLoc, SourceLocation IdLoc,
736 unsigned D, unsigned P, IdentifierInfo *Id,
737 QualType T, bool ParameterPack,
738 TypeSourceInfo *TInfo) {
739 AutoType *AT =
740 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
741 return new (C, DC,
742 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
743 Expr *>(0,
744 AT && AT->isConstrained() ? 1 : 0))
745 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,
746 TInfo);
747}
748
750 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
751 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
752 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
753 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
754 AutoType *AT = TInfo->getType()->getContainedAutoType();
755 return new (C, DC,
756 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
757 Expr *>(
758 ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))
759 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
760 ExpandedTypes, ExpandedTInfos);
761}
762
765 bool HasTypeConstraint) {
766 return new (C, ID, additionalSizeToAlloc<std::pair<QualType,
768 Expr *>(0,
769 HasTypeConstraint ? 1 : 0))
771 0, 0, nullptr, QualType(), false, nullptr);
772}
773
776 unsigned NumExpandedTypes,
777 bool HasTypeConstraint) {
778 auto *NTTP =
779 new (C, ID,
780 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
781 NumExpandedTypes, HasTypeConstraint ? 1 : 0))
783 0, 0, nullptr, QualType(), nullptr,
784 std::nullopt, std::nullopt);
785 NTTP->NumExpandedTypes = NumExpandedTypes;
786 return NTTP;
787}
788
792 getDefaultArgument()->getSourceRange().getEnd());
794}
795
797 return hasDefaultArgument()
799 : SourceLocation();
800}
801
802//===----------------------------------------------------------------------===//
803// TemplateTemplateParmDecl Method Implementations
804//===----------------------------------------------------------------------===//
805
806void TemplateTemplateParmDecl::anchor() {}
807
808TemplateTemplateParmDecl::TemplateTemplateParmDecl(
809 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
812 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
813 TemplateParmPosition(D, P), ParameterPack(true),
814 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
815 if (!Expansions.empty())
816 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
817 getTrailingObjects<TemplateParameterList *>());
818}
819
822 SourceLocation L, unsigned D, unsigned P,
823 bool ParameterPack, IdentifierInfo *Id,
824 TemplateParameterList *Params) {
825 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
826 Params);
827}
828
831 SourceLocation L, unsigned D, unsigned P,
833 TemplateParameterList *Params,
835 return new (C, DC,
836 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
837 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
838}
839
842 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
843 false, nullptr, nullptr);
844}
845
848 unsigned NumExpansions) {
849 auto *TTP =
850 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
851 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
852 nullptr, std::nullopt);
853 TTP->NumExpandedParams = NumExpansions;
854 return TTP;
855}
856
859 : SourceLocation();
860}
861
863 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
864 if (DefArg.getArgument().isNull())
865 DefaultArgument.set(nullptr);
866 else
867 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
868}
869
870//===----------------------------------------------------------------------===//
871// TemplateArgumentList Implementation
872//===----------------------------------------------------------------------===//
873TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
874 : Arguments(getTrailingObjects<TemplateArgument>()),
875 NumArguments(Args.size()) {
876 std::uninitialized_copy(Args.begin(), Args.end(),
877 getTrailingObjects<TemplateArgument>());
878}
879
883 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
884 return new (Mem) TemplateArgumentList(Args);
885}
886
889 TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
890 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
891 MemberSpecializationInfo *MSInfo) {
892 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
893 if (TemplateArgsAsWritten)
895 *TemplateArgsAsWritten);
896
897 void *Mem =
898 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
899 return new (Mem) FunctionTemplateSpecializationInfo(
900 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
901}
902
903//===----------------------------------------------------------------------===//
904// ClassTemplateSpecializationDecl Implementation
905//===----------------------------------------------------------------------===//
906
909 DeclContext *DC, SourceLocation StartLoc,
910 SourceLocation IdLoc,
911 ClassTemplateDecl *SpecializedTemplate,
914 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
915 SpecializedTemplate->getIdentifier(), PrevDecl),
916 SpecializedTemplate(SpecializedTemplate),
917 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
918 SpecializationKind(TSK_Undeclared) {
919}
920
922 Kind DK)
923 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
924 SourceLocation(), nullptr, nullptr),
925 SpecializationKind(TSK_Undeclared) {}
926
929 DeclContext *DC,
930 SourceLocation StartLoc,
931 SourceLocation IdLoc,
932 ClassTemplateDecl *SpecializedTemplate,
935 auto *Result =
936 new (Context, DC) ClassTemplateSpecializationDecl(
937 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
938 SpecializedTemplate, Args, PrevDecl);
939 Result->setMayHaveOutOfDateDef(false);
940
941 // If the template decl is incomplete, copy the external lexical storage from
942 // the base template. This allows instantiations of incomplete types to
943 // complete using the external AST if the template's declaration came from an
944 // external AST.
945 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
946 Result->setHasExternalLexicalStorage(
947 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
948
949 Context.getTypeDeclType(Result, PrevDecl);
950 return Result;
951}
952
955 unsigned ID) {
956 auto *Result =
957 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
958 Result->setMayHaveOutOfDateDef(false);
959 return Result;
960}
961
963 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
965
966 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
967 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
968 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
970 OS, ArgsAsWritten->arguments(), Policy,
971 getSpecializedTemplate()->getTemplateParameters());
972 } else {
973 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
975 OS, TemplateArgs.asArray(), Policy,
976 getSpecializedTemplate()->getTemplateParameters());
977 }
978}
979
982 if (const auto *PartialSpec =
983 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
984 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
985 return SpecializedTemplate.get<ClassTemplateDecl*>();
986}
987
990 if (ExplicitInfo) {
992 if (Begin.isValid()) {
993 // Here we have an explicit (partial) specialization or instantiation.
997 if (getExternLoc().isValid())
1000 if (End.isInvalid())
1002 return SourceRange(Begin, End);
1003 }
1004 // An implicit instantiation of a class template partial specialization
1005 // uses ExplicitInfo to record the TypeAsWritten, but the source
1006 // locations should be retrieved from the instantiation pattern.
1008 auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
1009 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
1010 assert(inst_from != nullptr);
1011 return inst_from->getSourceRange();
1012 }
1013 else {
1014 // No explicit info available.
1015 llvm::PointerUnion<ClassTemplateDecl *,
1017 inst_from = getInstantiatedFrom();
1018 if (inst_from.isNull())
1020 if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
1021 return ctd->getSourceRange();
1022 return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
1023 ->getSourceRange();
1024 }
1025}
1026
1027//===----------------------------------------------------------------------===//
1028// ConceptDecl Implementation
1029//===----------------------------------------------------------------------===//
1032 TemplateParameterList *Params,
1033 Expr *ConstraintExpr) {
1034 bool Invalid = AdoptTemplateParameterList(Params, DC);
1035 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1036 if (Invalid)
1037 TD->setInvalidDecl();
1038 return TD;
1039}
1040
1042 unsigned ID) {
1043 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1045 nullptr, nullptr);
1046
1047 return Result;
1048}
1049
1050//===----------------------------------------------------------------------===//
1051// ImplicitConceptSpecializationDecl Implementation
1052//===----------------------------------------------------------------------===//
1053ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1055 ArrayRef<TemplateArgument> ConvertedArgs)
1056 : Decl(ImplicitConceptSpecialization, DC, SL),
1057 NumTemplateArgs(ConvertedArgs.size()) {
1058 setTemplateArguments(ConvertedArgs);
1059}
1060
1061ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1062 EmptyShell Empty, unsigned NumTemplateArgs)
1063 : Decl(ImplicitConceptSpecialization, Empty),
1064 NumTemplateArgs(NumTemplateArgs) {}
1065
1067 const ASTContext &C, DeclContext *DC, SourceLocation SL,
1068 ArrayRef<TemplateArgument> ConvertedArgs) {
1069 return new (C, DC,
1070 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1071 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1072}
1073
1076 const ASTContext &C, unsigned ID, unsigned NumTemplateArgs) {
1077 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1079}
1080
1082 ArrayRef<TemplateArgument> Converted) {
1083 assert(Converted.size() == NumTemplateArgs);
1084 std::uninitialized_copy(Converted.begin(), Converted.end(),
1085 getTrailingObjects<TemplateArgument>());
1086}
1087
1088//===----------------------------------------------------------------------===//
1089// ClassTemplatePartialSpecializationDecl Implementation
1090//===----------------------------------------------------------------------===//
1091void ClassTemplatePartialSpecializationDecl::anchor() {}
1092
1093ClassTemplatePartialSpecializationDecl::
1094ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
1095 DeclContext *DC,
1096 SourceLocation StartLoc,
1097 SourceLocation IdLoc,
1098 TemplateParameterList *Params,
1099 ClassTemplateDecl *SpecializedTemplate,
1101 const ASTTemplateArgumentListInfo *ArgInfos,
1104 ClassTemplatePartialSpecialization,
1105 TK, DC, StartLoc, IdLoc,
1106 SpecializedTemplate, Args, PrevDecl),
1107 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1108 InstantiatedFromMember(nullptr, false) {
1109 if (AdoptTemplateParameterList(Params, this))
1111}
1112
1115Create(ASTContext &Context, TagKind TK,DeclContext *DC,
1116 SourceLocation StartLoc, SourceLocation IdLoc,
1117 TemplateParameterList *Params,
1118 ClassTemplateDecl *SpecializedTemplate,
1120 const TemplateArgumentListInfo &ArgInfos,
1121 QualType CanonInjectedType,
1123 const ASTTemplateArgumentListInfo *ASTArgInfos =
1124 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1125
1126 auto *Result = new (Context, DC)
1127 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
1128 Params, SpecializedTemplate, Args,
1129 ASTArgInfos, PrevDecl);
1130 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1131 Result->setMayHaveOutOfDateDef(false);
1132
1133 Context.getInjectedClassNameType(Result, CanonInjectedType);
1134 return Result;
1135}
1136
1139 unsigned ID) {
1141 Result->setMayHaveOutOfDateDef(false);
1142 return Result;
1143}
1144
1145//===----------------------------------------------------------------------===//
1146// FriendTemplateDecl Implementation
1147//===----------------------------------------------------------------------===//
1148
1149void FriendTemplateDecl::anchor() {}
1150
1155 FriendUnion Friend, SourceLocation FLoc) {
1156 TemplateParameterList **TPL = nullptr;
1157 if (!Params.empty()) {
1158 TPL = new (Context) TemplateParameterList *[Params.size()];
1159 llvm::copy(Params, TPL);
1160 }
1161 return new (Context, DC)
1162 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
1163}
1164
1166 unsigned ID) {
1167 return new (C, ID) FriendTemplateDecl(EmptyShell());
1168}
1169
1170//===----------------------------------------------------------------------===//
1171// TypeAliasTemplateDecl Implementation
1172//===----------------------------------------------------------------------===//
1173
1176 DeclarationName Name,
1178 bool Invalid = AdoptTemplateParameterList(Params, DC);
1179 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1180 if (Invalid)
1181 TD->setInvalidDecl();
1182 return TD;
1183}
1184
1186 unsigned ID) {
1187 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1188 DeclarationName(), nullptr, nullptr);
1189}
1190
1193 auto *CommonPtr = new (C) Common;
1194 C.addDestruction(CommonPtr);
1195 return CommonPtr;
1196}
1197
1198//===----------------------------------------------------------------------===//
1199// ClassScopeFunctionSpecializationDecl Implementation
1200//===----------------------------------------------------------------------===//
1201
1202void ClassScopeFunctionSpecializationDecl::anchor() {}
1203
1206 unsigned ID) {
1207 return new (C, ID) ClassScopeFunctionSpecializationDecl(
1208 nullptr, SourceLocation(), nullptr, nullptr);
1209}
1210
1211//===----------------------------------------------------------------------===//
1212// VarTemplateDecl Implementation
1213//===----------------------------------------------------------------------===//
1214
1216 VarTemplateDecl *CurD = this;
1217 while (CurD) {
1218 if (CurD->isThisDeclarationADefinition())
1219 return CurD;
1220 CurD = CurD->getPreviousDecl();
1221 }
1222 return nullptr;
1223}
1224
1227 TemplateParameterList *Params,
1228 VarDecl *Decl) {
1229 bool Invalid = AdoptTemplateParameterList(Params, DC);
1230 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1231 if (Invalid)
1232 TD->setInvalidDecl();
1233 return TD;
1234}
1235
1237 unsigned ID) {
1238 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1239 DeclarationName(), nullptr, nullptr);
1240}
1241
1244}
1245
1246llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1249 return getCommonPtr()->Specializations;
1250}
1251
1252llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1256}
1257
1260 auto *CommonPtr = new (C) Common;
1261 C.addDestruction(CommonPtr);
1262 return CommonPtr;
1263}
1264
1267 void *&InsertPos) {
1268 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
1269}
1270
1272 void *InsertPos) {
1273 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1274}
1275
1278 TemplateParameterList *TPL, void *&InsertPos) {
1279 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1280 TPL);
1281}
1282
1284 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1285 TemplateParameterList *TPL, const ASTContext &Context) {
1286 ID.AddInteger(TemplateArgs.size());
1287 for (const TemplateArgument &TemplateArg : TemplateArgs)
1288 TemplateArg.Profile(ID, Context);
1289 TPL->Profile(ID, Context);
1290}
1291
1293 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1294 if (InsertPos)
1295 getPartialSpecializations().InsertNode(D, InsertPos);
1296 else {
1298 getPartialSpecializations().GetOrInsertNode(D);
1299 (void)Existing;
1300 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1301 }
1302
1304 L->AddedCXXTemplateSpecialization(this, D);
1305}
1306
1309 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1311 PS.clear();
1312 PS.reserve(PartialSpecs.size());
1313 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1314 PS.push_back(P.getMostRecentDecl());
1315}
1316
1320 Decl *DCanon = D->getCanonicalDecl();
1322 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1323 return P.getMostRecentDecl();
1324 }
1325
1326 return nullptr;
1327}
1328
1329//===----------------------------------------------------------------------===//
1330// VarTemplateSpecializationDecl Implementation
1331//===----------------------------------------------------------------------===//
1332
1334 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1335 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1337 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1338 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1339 SpecializedTemplate(SpecializedTemplate),
1340 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1341 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1342
1344 ASTContext &C)
1345 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1346 QualType(), nullptr, SC_None),
1347 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1348
1350 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1351 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1353 return new (Context, DC) VarTemplateSpecializationDecl(
1354 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1355 SpecializedTemplate, T, TInfo, S, Args);
1356}
1357
1360 return new (C, ID)
1361 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1362}
1363
1365 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1367
1368 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1369 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1370 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1372 OS, ArgsAsWritten->arguments(), Policy,
1373 getSpecializedTemplate()->getTemplateParameters());
1374 } else {
1375 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1377 OS, TemplateArgs.asArray(), Policy,
1378 getSpecializedTemplate()->getTemplateParameters());
1379 }
1380}
1381
1383 if (const auto *PartialSpec =
1384 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1385 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1386 return SpecializedTemplate.get<VarTemplateDecl *>();
1387}
1388
1390 const TemplateArgumentListInfo &ArgsInfo) {
1391 TemplateArgsInfo =
1393}
1394
1396 const ASTTemplateArgumentListInfo *ArgsInfo) {
1397 TemplateArgsInfo =
1399}
1400
1402 if (isExplicitSpecialization() && !hasInit()) {
1404 return SourceRange(getOuterLocStart(), Info->getRAngleLoc());
1405 }
1406 return VarDecl::getSourceRange();
1407}
1408
1409
1410//===----------------------------------------------------------------------===//
1411// VarTemplatePartialSpecializationDecl Implementation
1412//===----------------------------------------------------------------------===//
1413
1414void VarTemplatePartialSpecializationDecl::anchor() {}
1415
1416VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1417 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1419 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1421 const ASTTemplateArgumentListInfo *ArgInfos)
1422 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1423 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1424 TInfo, S, Args),
1425 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1426 InstantiatedFromMember(nullptr, false) {
1427 if (AdoptTemplateParameterList(Params, DC))
1429}
1430
1433 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1435 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1437 const TemplateArgumentListInfo &ArgInfos) {
1438 const ASTTemplateArgumentListInfo *ASTArgInfos
1439 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1440
1441 auto *Result =
1442 new (Context, DC) VarTemplatePartialSpecializationDecl(
1443 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1444 S, Args, ASTArgInfos);
1445 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1446 return Result;
1447}
1448
1451 unsigned ID) {
1452 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1453}
1454
1456 if (isExplicitSpecialization() && !hasInit()) {
1458 return SourceRange(getOuterLocStart(), Info->getRAngleLoc());
1459 }
1460 return VarDecl::getSourceRange();
1461}
1462
1463static TemplateParameterList *
1465 // typename T
1467 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1468 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1469 /*HasTypeConstraint=*/false);
1470 T->setImplicit(true);
1471
1472 // T ...Ints
1473 TypeSourceInfo *TI =
1474 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1476 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1477 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1478 N->setImplicit(true);
1479
1480 // <typename T, T ...Ints>
1481 NamedDecl *P[2] = {T, N};
1483 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1484
1485 // template <typename T, ...Ints> class IntSeq
1486 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1487 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1488 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1489 TemplateTemplateParm->setImplicit(true);
1490
1491 // typename T
1492 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1493 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1494 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1495 /*HasTypeConstraint=*/false);
1496 TemplateTypeParm->setImplicit(true);
1497
1498 // T N
1499 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1500 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1501 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1502 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1503 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1504 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1505 NonTypeTemplateParm};
1506
1507 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1509 Params, SourceLocation(), nullptr);
1510}
1511
1512static TemplateParameterList *
1514 // std::size_t Index
1515 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1516 auto *Index = NonTypeTemplateParmDecl::Create(
1517 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1518 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1519
1520 // typename ...T
1522 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1523 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
1524 /*HasTypeConstraint=*/false);
1525 Ts->setImplicit(true);
1526
1527 // template <std::size_t Index, typename ...T>
1528 NamedDecl *Params[] = {Index, Ts};
1530 llvm::ArrayRef(Params), SourceLocation(),
1531 nullptr);
1532}
1533
1535 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1536 switch (BTK) {
1541 }
1542
1543 llvm_unreachable("unhandled BuiltinTemplateKind!");
1544}
1545
1546void BuiltinTemplateDecl::anchor() {}
1547
1548BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1549 DeclarationName Name,
1551 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1553 BTK(BTK) {}
1554
1555TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1556 QualType T,
1557 const APValue &V) {
1558 DeclContext *DC = C.getTranslationUnitDecl();
1559 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1560 C.addDestruction(&TPOD->Value);
1561 return TPOD;
1562}
1563
1565TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1566 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1567 C.addDestruction(&TPOD->Value);
1568 return TPOD;
1569}
1570
1571void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1572 const PrintingPolicy &Policy) const {
1573 OS << "<template param ";
1574 printAsExpr(OS, Policy);
1575 OS << ">";
1576}
1577
1578void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1579 printAsExpr(OS, getASTContext().getPrintingPolicy());
1580}
1581
1582void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1583 const PrintingPolicy &Policy) const {
1584 getType().getUnqualifiedType().print(OS, Policy);
1585 printAsInit(OS, Policy);
1586}
1587
1588void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1589 printAsInit(OS, getASTContext().getPrintingPolicy());
1590}
1591
1592void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1593 const PrintingPolicy &Policy) const {
1594 getValue().printPretty(OS, Policy, getType(), &getASTContext());
1595}
1596
1598 switch (D->getKind()) {
1599 case Decl::Kind::ClassTemplate:
1600 return cast<ClassTemplateDecl>(D)->getTemplateParameters();
1601 case Decl::Kind::ClassTemplateSpecialization: {
1602 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1603 auto P = CTSD->getSpecializedTemplateOrPartial();
1604 if (const auto *CTPSD =
1606 return CTPSD->getTemplateParameters();
1607 return cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1608 }
1609 case Decl::Kind::ClassTemplatePartialSpecialization:
1610 return cast<ClassTemplatePartialSpecializationDecl>(D)
1611 ->getTemplateParameters();
1612 case Decl::Kind::TypeAliasTemplate:
1613 return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
1614 case Decl::Kind::BuiltinTemplate:
1615 return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
1616 case Decl::Kind::CXXDeductionGuide:
1617 case Decl::Kind::CXXConversion:
1618 case Decl::Kind::CXXConstructor:
1619 case Decl::Kind::CXXDestructor:
1620 case Decl::Kind::CXXMethod:
1621 case Decl::Kind::Function:
1622 return cast<FunctionDecl>(D)
1623 ->getTemplateSpecializationInfo()
1624 ->getTemplate()
1625 ->getTemplateParameters();
1626 case Decl::Kind::FunctionTemplate:
1627 return cast<FunctionTemplateDecl>(D)->getTemplateParameters();
1628 case Decl::Kind::VarTemplate:
1629 return cast<VarTemplateDecl>(D)->getTemplateParameters();
1630 case Decl::Kind::VarTemplateSpecialization: {
1631 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1632 auto P = VTSD->getSpecializedTemplateOrPartial();
1633 if (const auto *VTPSD =
1635 return VTPSD->getTemplateParameters();
1636 return cast<VarTemplateDecl *>(P)->getTemplateParameters();
1637 }
1638 case Decl::Kind::VarTemplatePartialSpecialization:
1639 return cast<VarTemplatePartialSpecializationDecl>(D)
1640 ->getTemplateParameters();
1641 case Decl::Kind::TemplateTemplateParm:
1642 return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();
1643 case Decl::Kind::Concept:
1644 return cast<ConceptDecl>(D)->getTemplateParameters();
1645 default:
1646 llvm_unreachable("Unhandled templated declaration kind");
1647 }
1648}
Defines the clang::ASTContext interface.
#define V(N, I)
Definition: ASTContext.h:3233
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)
Defines the clang::SourceLocation class and associated facilities.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
SourceLocation Begin
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:2543
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:1564
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:704
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
Definition: ASTContext.h:1169
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:5365
bool isConstrained() const
Definition: Type.h:5384
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclCXX.h:511
Declaration of a function specialization at template class scope.
static ClassScopeFunctionSpecializationDecl * CreateDeserialized(ASTContext &Context, unsigned ID)
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.
static ClassTemplateDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Create an empty class template node.
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...
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member class template partial specialization from which this particular class template p...
void Profile(llvm::FoldingSetNodeID &ID) const
static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, unsigned ID)
static ClassTemplatePartialSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, const TemplateArgumentListInfo &ArgInfos, QualType CanonInjectedType, ClassTemplatePartialSpecializationDecl *PrevDecl)
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.
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, unsigned ID)
SourceLocation getExternLoc() const
Gets the location of the extern keyword, if present.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
TypeSourceInfo * getTypeAsWritten() const
Gets the type of this specialization as it was written by the user, if it was so written.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getInstantiatedFrom() const
If this class template specialization is an instantiation of a template (rather than an explicit spec...
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, unsigned 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:1409
bool hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
Definition: DeclBase.h:2521
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
SourceLocation getEndLoc() const LLVM_READONLY
Definition: DeclBase.h:428
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:429
ASTMutationListener * getASTMutationListener() const
Definition: DeclBase.cpp:439
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition: DeclBase.cpp:133
Kind
Lists the kind of concrete classes of Decl.
Definition: DeclBase.h:86
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
Definition: DeclBase.h:952
Kind getKind() const
Definition: DeclBase.h:435
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:767
SourceLocation getOuterLocStart() const
Return start of source range taking into account any outer template declarations.
Definition: Decl.cpp:2029
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2069
void set(ArgType Arg)
Set the default argument.
Definition: DeclTemplate.h:370
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:233
virtual Decl * GetExternalDecl(uint32_t 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)
static FriendTemplateDecl * CreateDeserialized(ASTContext &C, unsigned ID)
llvm::PointerUnion< NamedDecl *, TypeSourceInfo * > FriendUnion
Represents a function declaration or definition.
Definition: Decl.h:1919
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
void addSpecialization(FunctionTemplateSpecializationInfo *Info, void *InsertPos)
Add a specialization of this function template.
CommonBase * newCommon(ASTContext &C) const override
static FunctionTemplateDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Create an empty function template node.
Common * getCommonPtr() const
FunctionTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...
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:483
static FunctionTemplateSpecializationInfo * Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, TemplateSpecializationKind TSK, const 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 * CreateDeserialized(const ASTContext &C, unsigned ID, unsigned NumTemplateArgs)
static ImplicitConceptSpecializationDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef< TemplateArgument > ConvertedArgs)
Provides information a specialization of a member of a class template, which may be a member function...
Definition: DeclTemplate.h:632
This represents a decl that may have a name.
Definition: Decl.h:247
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:313
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:1823
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, 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.
Expr * getDefaultArgument() const
Retrieve the default argument, if any.
static NonTypeTemplateParmDecl * CreateDeserialized(ASTContext &C, unsigned ID, bool HasTypeConstraint)
A (possibly-)qualified type.
Definition: Type.h:736
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:803
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6747
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:6840
Declaration of a redeclarable template.
Definition: DeclTemplate.h:767
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:864
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.
SourceLocation getEnd() const
SourceLocation getBegin() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:325
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
SourceRange getBraceRange() const
Definition: Decl.h:3556
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3580
A convenient class for passing around template argument information.
Definition: TemplateBase.h:590
A template argument list.
Definition: DeclTemplate.h:240
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:292
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:484
SourceLocation getLocation() const
Definition: TemplateBase.h:522
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:533
Represents a template argument.
Definition: TemplateBase.h:60
bool isNull() const
Determine whether this template argument has no value.
Definition: TemplateBase.h:266
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:410
TemplateParameterList * TemplateParams
Definition: DeclTemplate.h:461
bool isTypeAlias() const
bool hasAssociatedConstraints() const
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:442
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclTemplate.h:454
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:429
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:140
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:176
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:135
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
Defines the position of a template parameter within a template parameter list.
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
static TemplateTemplateParmDecl * CreateDeserialized(ASTContext &C, unsigned ID)
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
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, 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.
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.
static TemplateTypeParmDecl * CreateDeserialized(const ASTContext &C, unsigned ID)
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, unsigned 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:3309
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.h:3314
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Decl.h:3312
SourceLocation getEndLoc() const
Get the end source location.
Definition: TypeLoc.cpp:235
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:192
A container of type source information.
Definition: Type.h:6718
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:250
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6729
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7590
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition: Type.h:2470
QualType getType() const
Definition: Decl.h:714
Represents a variable declaration or definition.
Definition: Decl.h:915
bool hasInit() const
Definition: Decl.cpp:2378
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2169
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:2237
Declaration of a variable template.
VarTemplateDecl * getDefinition()
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 * 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 VarTemplateDecl * CreateDeserialized(ASTContext &C, unsigned ID)
Create an empty variable template node.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Get the template arguments as written.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static VarTemplatePartialSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args, const TemplateArgumentListInfo &ArgInfos)
void Profile(llvm::FoldingSetNodeID &ID) const
static VarTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, unsigned 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)
void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo)
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
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)
VarTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
const ASTTemplateArgumentListInfo * getTemplateArgsInfo() const
static VarTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, unsigned ID)
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
StorageClass
Storage classes.
Definition: Specifiers.h:239
@ SC_None
Definition: Specifiers.h:241
void * allocateDefaultArgStorageChain(const ASTContext &C)
@ C
Languages that the frontend can parse and compile.
@ 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:5659
@ TTK_Struct
The "struct" keyword.
Definition: Type.h:5661
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...
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:179
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition: Specifiers.h:197
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition: Specifiers.h:193
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition: Specifiers.h:189
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:182
#define true
Definition: stdbool.h:21
#define false
Definition: stdbool.h:22
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:641
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:99
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.
Definition: PrettyPrinter.h:57
unsigned AlwaysIncludeTypeForTemplateArgument
Whether to use type suffixes (eg: 1U) on integral non-type template parameters.
uint32_t * LazySpecializations
If non-null, points to an array of specializations (including partial specializations) known only by ...
Definition: DeclTemplate.h:850
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 ...