clang 17.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
131 unsigned NumRequiredArgs = 0;
132 for (const NamedDecl *P : asArray()) {
133 if (P->isTemplateParameterPack()) {
134 if (std::optional<unsigned> Expansions = getExpandedPackSize(P)) {
135 NumRequiredArgs += *Expansions;
136 continue;
137 }
138 break;
139 }
140
141 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
142 if (TTP->hasDefaultArgument())
143 break;
144 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
145 if (NTTP->hasDefaultArgument())
146 break;
147 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
148 break;
149
150 ++NumRequiredArgs;
151 }
152
153 return NumRequiredArgs;
154}
155
156unsigned TemplateParameterList::getDepth() const {
157 if (size() == 0)
158 return 0;
159
160 const NamedDecl *FirstParm = getParam(0);
161 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
162 return TTP->getDepth();
163 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
164 return NTTP->getDepth();
165 else
166 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
167}
168
170 DeclContext *Owner) {
171 bool Invalid = false;
172 for (NamedDecl *P : *Params) {
173 P->setDeclContext(Owner);
174
175 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
176 if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner))
177 Invalid = true;
178
179 if (P->isInvalidDecl())
180 Invalid = true;
181 }
182 return Invalid;
183}
184
187 if (HasConstrainedParameters)
188 for (const NamedDecl *Param : *this) {
189 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
190 if (const auto *TC = TTP->getTypeConstraint())
191 AC.push_back(TC->getImmediatelyDeclaredConstraint());
192 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
193 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
194 AC.push_back(E);
195 }
196 }
197 if (HasRequiresClause)
198 AC.push_back(getRequiresClause());
199}
200
202 return HasRequiresClause || HasConstrainedParameters;
203}
204
206 const PrintingPolicy &Policy, const TemplateParameterList *TPL,
207 unsigned Idx) {
208 if (!TPL || Idx >= TPL->size() || Policy.AlwaysIncludeTypeForTemplateArgument)
209 return true;
210 const NamedDecl *TemplParam = TPL->getParam(Idx);
211 if (const auto *ParamValueDecl =
212 dyn_cast<NonTypeTemplateParmDecl>(TemplParam))
213 if (ParamValueDecl->getType()->getContainedDeducedType())
214 return true;
215 return false;
216}
217
218namespace clang {
219
221 return new (C) char[sizeof(void*) * 2];
222}
223
224} // namespace clang
225
226//===----------------------------------------------------------------------===//
227// TemplateDecl Implementation
228//===----------------------------------------------------------------------===//
229
233 : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
234
235void TemplateDecl::anchor() {}
236
240 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
241 if (const Expr *TRC = FD->getTrailingRequiresClause())
242 AC.push_back(TRC);
243}
244
247 return true;
248 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
249 return FD->getTrailingRequiresClause();
250 return false;
251}
252
254 switch (getKind()) {
255 case TemplateDecl::TypeAliasTemplate:
256 case TemplateDecl::BuiltinTemplate:
257 return true;
258 default:
259 return false;
260 };
261}
262
263//===----------------------------------------------------------------------===//
264// RedeclarableTemplateDecl Implementation
265//===----------------------------------------------------------------------===//
266
267void RedeclarableTemplateDecl::anchor() {}
268
270 if (Common)
271 return Common;
272
273 // Walk the previous-declaration chain until we either find a declaration
274 // with a common pointer or we run out of previous declarations.
276 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
277 Prev = Prev->getPreviousDecl()) {
278 if (Prev->Common) {
279 Common = Prev->Common;
280 break;
281 }
282
283 PrevDecls.push_back(Prev);
284 }
285
286 // If we never found a common pointer, allocate one now.
287 if (!Common) {
288 // FIXME: If any of the declarations is from an AST file, we probably
289 // need an update record to add the common data.
290
292 }
293
294 // Update any previous declarations we saw with the common pointer.
295 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
296 Prev->Common = Common;
297
298 return Common;
299}
300
302 // Grab the most recent declaration to ensure we've loaded any lazy
303 // redeclarations of this template.
304 CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
305 if (CommonBasePtr->LazySpecializations) {
306 ASTContext &Context = getASTContext();
307 uint32_t *Specs = CommonBasePtr->LazySpecializations;
308 CommonBasePtr->LazySpecializations = nullptr;
309 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
310 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
311 }
312}
313
314template<class EntryType, typename... ProfileArguments>
317 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
318 ProfileArguments&&... ProfileArgs) {
319 using SETraits = SpecEntryTraits<EntryType>;
320
321 llvm::FoldingSetNodeID ID;
322 EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
323 getASTContext());
324 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
325 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
326}
327
328template<class Derived, class EntryType>
330 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
331 void *InsertPos) {
332 using SETraits = SpecEntryTraits<EntryType>;
333
334 if (InsertPos) {
335#ifndef NDEBUG
336 void *CorrectInsertPos;
337 assert(!findSpecializationImpl(Specializations,
338 CorrectInsertPos,
339 SETraits::getTemplateArgs(Entry)) &&
340 InsertPos == CorrectInsertPos &&
341 "given incorrect InsertPos for specialization");
342#endif
343 Specializations.InsertNode(Entry, InsertPos);
344 } else {
345 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
346 (void)Existing;
347 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
348 "non-canonical specialization?");
349 }
350
352 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
353 SETraits::getDecl(Entry));
354}
355
358 auto *CommonPtr = getCommonPtr();
359 if (!CommonPtr->InjectedArgs) {
360 auto &Context = getASTContext();
362 Context.getInjectedTemplateArgs(Params, TemplateArgs);
363 CommonPtr->InjectedArgs =
364 new (Context) TemplateArgument[TemplateArgs.size()];
365 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
366 CommonPtr->InjectedArgs);
367 }
368
369 return llvm::ArrayRef(CommonPtr->InjectedArgs, Params->size());
370}
371
372//===----------------------------------------------------------------------===//
373// FunctionTemplateDecl Implementation
374//===----------------------------------------------------------------------===//
375
378 DeclarationName Name,
380 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
381 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
382 if (Invalid)
383 TD->setInvalidDecl();
384 return TD;
385}
386
388 unsigned ID) {
389 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
390 DeclarationName(), nullptr, nullptr);
391}
392
395 auto *CommonPtr = new (C) Common;
396 C.addDestruction(CommonPtr);
397 return CommonPtr;
398}
399
402}
403
404llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
408}
409
412 void *&InsertPos) {
413 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
414}
415
417 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
418 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
419 InsertPos);
420}
421
424
425 // If we haven't created a common pointer yet, then it can just be created
426 // with the usual method.
427 if (!Base::Common)
428 return;
429
430 Common *ThisCommon = static_cast<Common *>(Base::Common);
431 Common *PrevCommon = nullptr;
433 for (; Prev; Prev = Prev->getPreviousDecl()) {
434 if (Prev->Base::Common) {
435 PrevCommon = static_cast<Common *>(Prev->Base::Common);
436 break;
437 }
438 PreviousDecls.push_back(Prev);
439 }
440
441 // If the previous redecl chain hasn't created a common pointer yet, then just
442 // use this common pointer.
443 if (!PrevCommon) {
444 for (auto *D : PreviousDecls)
445 D->Base::Common = ThisCommon;
446 return;
447 }
448
449 // Ensure we don't leak any important state.
450 assert(ThisCommon->Specializations.size() == 0 &&
451 "Can't merge incompatible declarations!");
452
453 Base::Common = PrevCommon;
454}
455
456//===----------------------------------------------------------------------===//
457// ClassTemplateDecl Implementation
458//===----------------------------------------------------------------------===//
459
462 DeclarationName Name,
463 TemplateParameterList *Params,
464 NamedDecl *Decl) {
465 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
466 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
467 if (Invalid)
468 TD->setInvalidDecl();
469 return TD;
470}
471
473 unsigned ID) {
474 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
475 DeclarationName(), nullptr, nullptr);
476}
477
480}
481
482llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
486}
487
488llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
492}
493
496 auto *CommonPtr = new (C) Common;
497 C.addDestruction(CommonPtr);
498 return CommonPtr;
499}
500
503 void *&InsertPos) {
504 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
505}
506
508 void *InsertPos) {
509 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
510}
511
515 TemplateParameterList *TPL, void *&InsertPos) {
516 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
517 TPL);
518}
519
521 llvm::FoldingSetNodeID &ID, const TemplateParameterList *TPL) {
522 const Expr *RC = TPL->getRequiresClause();
523 ID.AddBoolean(RC != nullptr);
524 if (RC)
525 RC->Profile(ID, C, /*Canonical=*/true);
526 ID.AddInteger(TPL->size());
527 for (NamedDecl *D : *TPL) {
528 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
529 ID.AddInteger(0);
530 ID.AddBoolean(NTTP->isParameterPack());
531 NTTP->getType().getCanonicalType().Profile(ID);
532 ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint());
533 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
534 E->Profile(ID, C, /*Canonical=*/true);
535 continue;
536 }
537 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {
538 ID.AddInteger(1);
539 ID.AddBoolean(TTP->isParameterPack());
540 ID.AddBoolean(TTP->hasTypeConstraint());
541 if (const TypeConstraint *TC = TTP->getTypeConstraint())
542 TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,
543 /*Canonical=*/true);
544 continue;
545 }
546 const auto *TTP = cast<TemplateTemplateParmDecl>(D);
547 ID.AddInteger(2);
548 ID.AddBoolean(TTP->isParameterPack());
549 ProfileTemplateParameterList(C, ID, TTP->getTemplateParameters());
550 }
551}
552
553void
556 ASTContext &Context) {
557 ID.AddInteger(TemplateArgs.size());
558 for (const TemplateArgument &TemplateArg : TemplateArgs)
559 TemplateArg.Profile(ID, Context);
560 ProfileTemplateParameterList(Context, ID, TPL);
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 DeclarationNameInfo NameInfo, NamedDecl *FoundDecl, ConceptDecl *CD,
703 const ASTTemplateArgumentListInfo *ArgsAsWritten,
704 Expr *ImmediatelyDeclaredConstraint) {
705 assert(HasTypeConstraint &&
706 "HasTypeConstraint=true must be passed at construction in order to "
707 "call setTypeConstraint");
708 assert(!TypeConstraintInitialized &&
709 "TypeConstraint was already initialized!");
710 new (getTrailingObjects<TypeConstraint>()) TypeConstraint(NNS, NameInfo,
711 FoundDecl, CD, ArgsAsWritten, ImmediatelyDeclaredConstraint);
712 TypeConstraintInitialized = true;
713}
714
715//===----------------------------------------------------------------------===//
716// NonTypeTemplateParmDecl Method Implementations
717//===----------------------------------------------------------------------===//
718
719NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
720 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
721 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
722 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
723 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
724 TemplateParmPosition(D, P), ParameterPack(true),
725 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
726 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
727 auto TypesAndInfos =
728 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
729 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
730 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
731 TypesAndInfos[I].second = ExpandedTInfos[I];
732 }
733 }
734}
735
738 SourceLocation StartLoc, SourceLocation IdLoc,
739 unsigned D, unsigned P, IdentifierInfo *Id,
740 QualType T, bool ParameterPack,
741 TypeSourceInfo *TInfo) {
742 AutoType *AT =
743 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
744 return new (C, DC,
745 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
746 Expr *>(0,
747 AT && AT->isConstrained() ? 1 : 0))
748 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,
749 TInfo);
750}
751
753 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
754 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
755 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
756 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
757 AutoType *AT = TInfo->getType()->getContainedAutoType();
758 return new (C, DC,
759 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
760 Expr *>(
761 ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))
762 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
763 ExpandedTypes, ExpandedTInfos);
764}
765
768 bool HasTypeConstraint) {
769 return new (C, ID, additionalSizeToAlloc<std::pair<QualType,
771 Expr *>(0,
772 HasTypeConstraint ? 1 : 0))
774 0, 0, nullptr, QualType(), false, nullptr);
775}
776
779 unsigned NumExpandedTypes,
780 bool HasTypeConstraint) {
781 auto *NTTP =
782 new (C, ID,
783 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
784 NumExpandedTypes, HasTypeConstraint ? 1 : 0))
786 0, 0, nullptr, QualType(), nullptr,
787 std::nullopt, std::nullopt);
788 NTTP->NumExpandedTypes = NumExpandedTypes;
789 return NTTP;
790}
791
795 getDefaultArgument()->getSourceRange().getEnd());
797}
798
800 return hasDefaultArgument()
802 : SourceLocation();
803}
804
805//===----------------------------------------------------------------------===//
806// TemplateTemplateParmDecl Method Implementations
807//===----------------------------------------------------------------------===//
808
809void TemplateTemplateParmDecl::anchor() {}
810
811TemplateTemplateParmDecl::TemplateTemplateParmDecl(
812 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
815 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
816 TemplateParmPosition(D, P), ParameterPack(true),
817 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
818 if (!Expansions.empty())
819 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
820 getTrailingObjects<TemplateParameterList *>());
821}
822
825 SourceLocation L, unsigned D, unsigned P,
826 bool ParameterPack, IdentifierInfo *Id,
827 TemplateParameterList *Params) {
828 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
829 Params);
830}
831
834 SourceLocation L, unsigned D, unsigned P,
836 TemplateParameterList *Params,
838 return new (C, DC,
839 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
840 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
841}
842
845 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
846 false, nullptr, nullptr);
847}
848
851 unsigned NumExpansions) {
852 auto *TTP =
853 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
854 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
855 nullptr, std::nullopt);
856 TTP->NumExpandedParams = NumExpansions;
857 return TTP;
858}
859
862 : SourceLocation();
863}
864
866 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
867 if (DefArg.getArgument().isNull())
868 DefaultArgument.set(nullptr);
869 else
870 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
871}
872
873//===----------------------------------------------------------------------===//
874// TemplateArgumentList Implementation
875//===----------------------------------------------------------------------===//
876TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
877 : Arguments(getTrailingObjects<TemplateArgument>()),
878 NumArguments(Args.size()) {
879 std::uninitialized_copy(Args.begin(), Args.end(),
880 getTrailingObjects<TemplateArgument>());
881}
882
886 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
887 return new (Mem) TemplateArgumentList(Args);
888}
889
892 TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
893 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
894 MemberSpecializationInfo *MSInfo) {
895 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
896 if (TemplateArgsAsWritten)
898 *TemplateArgsAsWritten);
899
900 void *Mem =
901 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
902 return new (Mem) FunctionTemplateSpecializationInfo(
903 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
904}
905
906//===----------------------------------------------------------------------===//
907// ClassTemplateSpecializationDecl Implementation
908//===----------------------------------------------------------------------===//
909
912 DeclContext *DC, SourceLocation StartLoc,
913 SourceLocation IdLoc,
914 ClassTemplateDecl *SpecializedTemplate,
917 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
918 SpecializedTemplate->getIdentifier(), PrevDecl),
919 SpecializedTemplate(SpecializedTemplate),
920 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
921 SpecializationKind(TSK_Undeclared) {
922}
923
925 Kind DK)
926 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
927 SourceLocation(), nullptr, nullptr),
928 SpecializationKind(TSK_Undeclared) {}
929
932 DeclContext *DC,
933 SourceLocation StartLoc,
934 SourceLocation IdLoc,
935 ClassTemplateDecl *SpecializedTemplate,
938 auto *Result =
939 new (Context, DC) ClassTemplateSpecializationDecl(
940 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
941 SpecializedTemplate, Args, PrevDecl);
942 Result->setMayHaveOutOfDateDef(false);
943
944 // If the template decl is incomplete, copy the external lexical storage from
945 // the base template. This allows instantiations of incomplete types to
946 // complete using the external AST if the template's declaration came from an
947 // external AST.
948 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
949 Result->setHasExternalLexicalStorage(
950 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
951
952 Context.getTypeDeclType(Result, PrevDecl);
953 return Result;
954}
955
958 unsigned ID) {
959 auto *Result =
960 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
961 Result->setMayHaveOutOfDateDef(false);
962 return Result;
963}
964
966 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
968
969 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
970 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
971 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
973 OS, ArgsAsWritten->arguments(), Policy,
974 getSpecializedTemplate()->getTemplateParameters());
975 } else {
976 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
978 OS, TemplateArgs.asArray(), Policy,
979 getSpecializedTemplate()->getTemplateParameters());
980 }
981}
982
985 if (const auto *PartialSpec =
986 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
987 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
988 return SpecializedTemplate.get<ClassTemplateDecl*>();
989}
990
993 if (ExplicitInfo) {
995 if (Begin.isValid()) {
996 // Here we have an explicit (partial) specialization or instantiation.
1000 if (getExternLoc().isValid())
1001 Begin = getExternLoc();
1003 if (End.isInvalid())
1005 return SourceRange(Begin, End);
1006 }
1007 // An implicit instantiation of a class template partial specialization
1008 // uses ExplicitInfo to record the TypeAsWritten, but the source
1009 // locations should be retrieved from the instantiation pattern.
1011 auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
1012 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
1013 assert(inst_from != nullptr);
1014 return inst_from->getSourceRange();
1015 }
1016 else {
1017 // No explicit info available.
1018 llvm::PointerUnion<ClassTemplateDecl *,
1020 inst_from = getInstantiatedFrom();
1021 if (inst_from.isNull())
1023 if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
1024 return ctd->getSourceRange();
1025 return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
1026 ->getSourceRange();
1027 }
1028}
1029
1030//===----------------------------------------------------------------------===//
1031// ConceptDecl Implementation
1032//===----------------------------------------------------------------------===//
1035 TemplateParameterList *Params,
1036 Expr *ConstraintExpr) {
1037 bool Invalid = AdoptTemplateParameterList(Params, DC);
1038 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1039 if (Invalid)
1040 TD->setInvalidDecl();
1041 return TD;
1042}
1043
1045 unsigned ID) {
1046 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1048 nullptr, nullptr);
1049
1050 return Result;
1051}
1052
1053//===----------------------------------------------------------------------===//
1054// ImplicitConceptSpecializationDecl Implementation
1055//===----------------------------------------------------------------------===//
1056ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1058 ArrayRef<TemplateArgument> ConvertedArgs)
1059 : Decl(ImplicitConceptSpecialization, DC, SL),
1060 NumTemplateArgs(ConvertedArgs.size()) {
1061 setTemplateArguments(ConvertedArgs);
1062}
1063
1064ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1065 EmptyShell Empty, unsigned NumTemplateArgs)
1066 : Decl(ImplicitConceptSpecialization, Empty),
1067 NumTemplateArgs(NumTemplateArgs) {}
1068
1070 const ASTContext &C, DeclContext *DC, SourceLocation SL,
1071 ArrayRef<TemplateArgument> ConvertedArgs) {
1072 return new (C, DC,
1073 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1074 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1075}
1076
1079 const ASTContext &C, unsigned ID, unsigned NumTemplateArgs) {
1080 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1082}
1083
1085 ArrayRef<TemplateArgument> Converted) {
1086 assert(Converted.size() == NumTemplateArgs);
1087 std::uninitialized_copy(Converted.begin(), Converted.end(),
1088 getTrailingObjects<TemplateArgument>());
1089}
1090
1091//===----------------------------------------------------------------------===//
1092// ClassTemplatePartialSpecializationDecl Implementation
1093//===----------------------------------------------------------------------===//
1094void ClassTemplatePartialSpecializationDecl::anchor() {}
1095
1096ClassTemplatePartialSpecializationDecl::
1097ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
1098 DeclContext *DC,
1099 SourceLocation StartLoc,
1100 SourceLocation IdLoc,
1101 TemplateParameterList *Params,
1102 ClassTemplateDecl *SpecializedTemplate,
1104 const ASTTemplateArgumentListInfo *ArgInfos,
1107 ClassTemplatePartialSpecialization,
1108 TK, DC, StartLoc, IdLoc,
1109 SpecializedTemplate, Args, PrevDecl),
1110 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1111 InstantiatedFromMember(nullptr, false) {
1112 if (AdoptTemplateParameterList(Params, this))
1114}
1115
1118Create(ASTContext &Context, TagKind TK,DeclContext *DC,
1119 SourceLocation StartLoc, SourceLocation IdLoc,
1120 TemplateParameterList *Params,
1121 ClassTemplateDecl *SpecializedTemplate,
1123 const TemplateArgumentListInfo &ArgInfos,
1124 QualType CanonInjectedType,
1126 const ASTTemplateArgumentListInfo *ASTArgInfos =
1127 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1128
1129 auto *Result = new (Context, DC)
1130 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
1131 Params, SpecializedTemplate, Args,
1132 ASTArgInfos, PrevDecl);
1133 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1134 Result->setMayHaveOutOfDateDef(false);
1135
1136 Context.getInjectedClassNameType(Result, CanonInjectedType);
1137 return Result;
1138}
1139
1142 unsigned ID) {
1144 Result->setMayHaveOutOfDateDef(false);
1145 return Result;
1146}
1147
1148//===----------------------------------------------------------------------===//
1149// FriendTemplateDecl Implementation
1150//===----------------------------------------------------------------------===//
1151
1152void FriendTemplateDecl::anchor() {}
1153
1158 FriendUnion Friend, SourceLocation FLoc) {
1159 TemplateParameterList **TPL = nullptr;
1160 if (!Params.empty()) {
1161 TPL = new (Context) TemplateParameterList *[Params.size()];
1162 llvm::copy(Params, TPL);
1163 }
1164 return new (Context, DC)
1165 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
1166}
1167
1169 unsigned ID) {
1170 return new (C, ID) FriendTemplateDecl(EmptyShell());
1171}
1172
1173//===----------------------------------------------------------------------===//
1174// TypeAliasTemplateDecl Implementation
1175//===----------------------------------------------------------------------===//
1176
1179 DeclarationName Name,
1181 bool Invalid = AdoptTemplateParameterList(Params, DC);
1182 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1183 if (Invalid)
1184 TD->setInvalidDecl();
1185 return TD;
1186}
1187
1189 unsigned ID) {
1190 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1191 DeclarationName(), nullptr, nullptr);
1192}
1193
1196 auto *CommonPtr = new (C) Common;
1197 C.addDestruction(CommonPtr);
1198 return CommonPtr;
1199}
1200
1201//===----------------------------------------------------------------------===//
1202// ClassScopeFunctionSpecializationDecl Implementation
1203//===----------------------------------------------------------------------===//
1204
1205void ClassScopeFunctionSpecializationDecl::anchor() {}
1206
1209 unsigned ID) {
1210 return new (C, ID) ClassScopeFunctionSpecializationDecl(
1211 nullptr, SourceLocation(), nullptr, nullptr);
1212}
1213
1214//===----------------------------------------------------------------------===//
1215// VarTemplateDecl Implementation
1216//===----------------------------------------------------------------------===//
1217
1219 VarTemplateDecl *CurD = this;
1220 while (CurD) {
1221 if (CurD->isThisDeclarationADefinition())
1222 return CurD;
1223 CurD = CurD->getPreviousDecl();
1224 }
1225 return nullptr;
1226}
1227
1230 TemplateParameterList *Params,
1231 VarDecl *Decl) {
1232 bool Invalid = AdoptTemplateParameterList(Params, DC);
1233 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1234 if (Invalid)
1235 TD->setInvalidDecl();
1236 return TD;
1237}
1238
1240 unsigned ID) {
1241 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1242 DeclarationName(), nullptr, nullptr);
1243}
1244
1247}
1248
1249llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1252 return getCommonPtr()->Specializations;
1253}
1254
1255llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1259}
1260
1263 auto *CommonPtr = new (C) Common;
1264 C.addDestruction(CommonPtr);
1265 return CommonPtr;
1266}
1267
1270 void *&InsertPos) {
1271 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
1272}
1273
1275 void *InsertPos) {
1276 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1277}
1278
1281 TemplateParameterList *TPL, void *&InsertPos) {
1282 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1283 TPL);
1284}
1285
1286void
1289 ASTContext &Context) {
1290 ID.AddInteger(TemplateArgs.size());
1291 for (const TemplateArgument &TemplateArg : TemplateArgs)
1292 TemplateArg.Profile(ID, Context);
1293 ProfileTemplateParameterList(Context, ID, TPL);
1294}
1295
1297 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1298 if (InsertPos)
1299 getPartialSpecializations().InsertNode(D, InsertPos);
1300 else {
1302 getPartialSpecializations().GetOrInsertNode(D);
1303 (void)Existing;
1304 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1305 }
1306
1308 L->AddedCXXTemplateSpecialization(this, D);
1309}
1310
1313 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1315 PS.clear();
1316 PS.reserve(PartialSpecs.size());
1317 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1318 PS.push_back(P.getMostRecentDecl());
1319}
1320
1324 Decl *DCanon = D->getCanonicalDecl();
1326 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1327 return P.getMostRecentDecl();
1328 }
1329
1330 return nullptr;
1331}
1332
1333//===----------------------------------------------------------------------===//
1334// VarTemplateSpecializationDecl Implementation
1335//===----------------------------------------------------------------------===//
1336
1338 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1339 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1341 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1342 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1343 SpecializedTemplate(SpecializedTemplate),
1344 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1345 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1346
1348 ASTContext &C)
1349 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1350 QualType(), nullptr, SC_None),
1351 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1352
1354 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1355 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1357 return new (Context, DC) VarTemplateSpecializationDecl(
1358 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1359 SpecializedTemplate, T, TInfo, S, Args);
1360}
1361
1364 return new (C, ID)
1365 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1366}
1367
1369 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1371
1372 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1373 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1374 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1376 OS, ArgsAsWritten->arguments(), Policy,
1377 getSpecializedTemplate()->getTemplateParameters());
1378 } else {
1379 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1381 OS, TemplateArgs.asArray(), Policy,
1382 getSpecializedTemplate()->getTemplateParameters());
1383 }
1384}
1385
1387 if (const auto *PartialSpec =
1388 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1389 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1390 return SpecializedTemplate.get<VarTemplateDecl *>();
1391}
1392
1394 const TemplateArgumentListInfo &ArgsInfo) {
1395 TemplateArgsInfo =
1397}
1398
1400 const ASTTemplateArgumentListInfo *ArgsInfo) {
1401 TemplateArgsInfo =
1403}
1404
1405//===----------------------------------------------------------------------===//
1406// VarTemplatePartialSpecializationDecl Implementation
1407//===----------------------------------------------------------------------===//
1408
1409void VarTemplatePartialSpecializationDecl::anchor() {}
1410
1411VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1412 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1414 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1416 const ASTTemplateArgumentListInfo *ArgInfos)
1417 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1418 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1419 TInfo, S, Args),
1420 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1421 InstantiatedFromMember(nullptr, false) {
1422 if (AdoptTemplateParameterList(Params, DC))
1424}
1425
1428 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1430 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1432 const TemplateArgumentListInfo &ArgInfos) {
1433 const ASTTemplateArgumentListInfo *ASTArgInfos
1434 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1435
1436 auto *Result =
1437 new (Context, DC) VarTemplatePartialSpecializationDecl(
1438 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1439 S, Args, ASTArgInfos);
1440 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1441 return Result;
1442}
1443
1446 unsigned ID) {
1447 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1448}
1449
1450static TemplateParameterList *
1452 // typename T
1454 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1455 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1456 /*HasTypeConstraint=*/false);
1457 T->setImplicit(true);
1458
1459 // T ...Ints
1460 TypeSourceInfo *TI =
1461 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1463 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1464 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1465 N->setImplicit(true);
1466
1467 // <typename T, T ...Ints>
1468 NamedDecl *P[2] = {T, N};
1470 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1471
1472 // template <typename T, ...Ints> class IntSeq
1473 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1474 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1475 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1476 TemplateTemplateParm->setImplicit(true);
1477
1478 // typename T
1479 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1480 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1481 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1482 /*HasTypeConstraint=*/false);
1483 TemplateTypeParm->setImplicit(true);
1484
1485 // T N
1486 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1487 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1488 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1489 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1490 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1491 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1492 NonTypeTemplateParm};
1493
1494 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1496 Params, SourceLocation(), nullptr);
1497}
1498
1499static TemplateParameterList *
1501 // std::size_t Index
1502 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1503 auto *Index = NonTypeTemplateParmDecl::Create(
1504 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1505 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1506
1507 // typename ...T
1509 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1510 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
1511 /*HasTypeConstraint=*/false);
1512 Ts->setImplicit(true);
1513
1514 // template <std::size_t Index, typename ...T>
1515 NamedDecl *Params[] = {Index, Ts};
1517 llvm::ArrayRef(Params), SourceLocation(),
1518 nullptr);
1519}
1520
1522 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1523 switch (BTK) {
1528 }
1529
1530 llvm_unreachable("unhandled BuiltinTemplateKind!");
1531}
1532
1533void BuiltinTemplateDecl::anchor() {}
1534
1535BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1536 DeclarationName Name,
1538 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1540 BTK(BTK) {}
1541
1542void TypeConstraint::print(llvm::raw_ostream &OS, PrintingPolicy Policy) const {
1543 if (NestedNameSpec)
1545 ConceptName.printName(OS, Policy);
1547 OS << "<";
1548 // FIXME: Find corresponding parameter for argument
1549 for (auto &ArgLoc : ArgsAsWritten->arguments())
1550 ArgLoc.getArgument().print(Policy, OS, /*IncludeType*/ false);
1551 OS << ">";
1552 }
1553}
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:3217
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 void ProfileTemplateParameterList(ASTContext &C, llvm::FoldingSetNodeID &ID, const TemplateParameterList *TPL)
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:691
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:2521
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:1559
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:705
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
Definition: ASTContext.h:1167
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:5267
bool isConstrained() const
Definition: Type.h:5286
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclCXX.h:507
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)
NestedNameSpecifierLoc NestedNameSpec
Definition: ASTConcept.h:115
bool hasExplicitTemplateArgs() const
Whether or not template arguments were explicitly specified in the concept reference (they might not ...
Definition: ASTConcept.h:175
DeclarationNameInfo ConceptName
The concept name used.
Definition: ASTConcept.h:122
const ASTTemplateArgumentListInfo * ArgsAsWritten
The template argument list source info used to specialize the concept.
Definition: ASTConcept.h:135
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1393
bool hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
Definition: DeclBase.h:2503
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:428
ASTMutationListener * getASTMutationListener() const
Definition: DeclBase.cpp:438
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:86
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
Definition: DeclBase.h:949
Kind getKind() const
Definition: DeclBase.h:435
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:765
SourceLocation getOuterLocStart() const
Return start of source range taking into account any outer template declarations.
Definition: Decl.cpp:1994
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2034
void set(ArgType Arg)
Set the default argument.
Definition: DeclTemplate.h:368
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:1917
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:480
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:629
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:1788
A C++ nested-name-specifier augmented with source location information.
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false) const
Print this nested name specifier to the given output stream.
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:6649
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:6742
Declaration of a redeclarable template.
Definition: DeclTemplate.h:764
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:861
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) const
Produce a unique representation of the given statement.
SourceRange getBraceRange() const
Definition: Decl.h:3519
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3543
A convenient class for passing around template argument information.
Definition: TemplateBase.h:590
A template argument list.
Definition: DeclTemplate.h:238
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:290
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:407
TemplateParameterList * TemplateParams
Definition: DeclTemplate.h:458
bool isTypeAlias() const
bool hasAssociatedConstraints() const
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:439
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclTemplate.h:451
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:426
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:138
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:174
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:133
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(NestedNameSpecifierLoc NNS, DeclarationNameInfo NameInfo, NamedDecl *FoundDecl, ConceptDecl *CD, const ASTTemplateArgumentListInfo *ArgsAsWritten, 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.
void print(llvm::raw_ostream &OS, PrintingPolicy Policy) const
const Type * getTypeForDecl() const
Definition: Decl.h:3272
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.h:3277
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Decl.h:3275
SourceLocation getEndLoc() const
Get the end source location.
Definition: TypeLoc.cpp:234
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:191
A container of type source information.
Definition: Type.h:6620
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:244
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6631
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7491
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition: Type.h:2422
QualType getType() const
Definition: Decl.h:712
Represents a variable declaration or definition.
Definition: Decl.h:913
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:2202
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.
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.
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.
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:236
@ SC_None
Definition: Specifiers.h:238
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:5561
@ TTK_Struct
The "struct" keyword.
Definition: Type.h:5563
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:176
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition: Specifiers.h:194
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition: Specifiers.h:190
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition: Specifiers.h:186
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:179
#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)
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:670
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
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
void printName(raw_ostream &OS, PrintingPolicy Policy) const
printName - Print the human-readable name to a stream.
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:847
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 ...