clang 20.0.0git
DeclTemplate.cpp
Go to the documentation of this file.
1//===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the C++ related Decl classes for templates.
10//
11//===----------------------------------------------------------------------===//
12
16#include "clang/AST/DeclCXX.h"
18#include "clang/AST/Expr.h"
19#include "clang/AST/ExprCXX.h"
21#include "clang/AST/ODRHash.h"
24#include "clang/AST/Type.h"
25#include "clang/AST/TypeLoc.h"
27#include "clang/Basic/LLVM.h"
29#include "llvm/ADT/ArrayRef.h"
30#include "llvm/ADT/FoldingSet.h"
31#include "llvm/ADT/PointerUnion.h"
32#include "llvm/ADT/STLExtras.h"
33#include "llvm/ADT/SmallVector.h"
34#include "llvm/Support/ErrorHandling.h"
35#include <cassert>
36#include <memory>
37#include <optional>
38#include <utility>
39
40using namespace clang;
41
42//===----------------------------------------------------------------------===//
43// TemplateParameterList Implementation
44//===----------------------------------------------------------------------===//
45
46template <class TemplateParam>
47static bool
49 return P.hasDefaultArgument() &&
50 P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
51}
52
53TemplateParameterList::TemplateParameterList(const ASTContext &C,
54 SourceLocation TemplateLoc,
55 SourceLocation LAngleLoc,
57 SourceLocation RAngleLoc,
58 Expr *RequiresClause)
59 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
60 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
61 HasRequiresClause(RequiresClause != nullptr),
62 HasConstrainedParameters(false) {
63 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
64 NamedDecl *P = Params[Idx];
65 begin()[Idx] = P;
66
67 bool IsPack = P->isTemplateParameterPack();
68 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
69 if (!IsPack && (NTTP->getType()->containsUnexpandedParameterPack() ||
71 ContainsUnexpandedParameterPack = true;
72 if (NTTP->hasPlaceholderTypeConstraint())
73 HasConstrainedParameters = true;
74 } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
75 if (!IsPack &&
76 (TTP->getTemplateParameters()->containsUnexpandedParameterPack() ||
78 ContainsUnexpandedParameterPack = true;
79 }
80 } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
82 ContainsUnexpandedParameterPack = true;
83 } else if (const TypeConstraint *TC = TTP->getTypeConstraint();
86 ContainsUnexpandedParameterPack = true;
87 }
88 if (TTP->hasTypeConstraint())
89 HasConstrainedParameters = true;
90 } else {
91 llvm_unreachable("unexpected template parameter type");
92 }
93 }
94
95 if (HasRequiresClause) {
96 if (RequiresClause->containsUnexpandedParameterPack())
97 ContainsUnexpandedParameterPack = true;
98 *getTrailingObjects<Expr *>() = RequiresClause;
99 }
100}
101
102bool TemplateParameterList::containsUnexpandedParameterPack() const {
103 if (ContainsUnexpandedParameterPack)
104 return true;
105 if (!HasConstrainedParameters)
106 return false;
107
108 // An implicit constrained parameter might have had a use of an unexpanded
109 // pack added to it after the template parameter list was created. All
110 // implicit parameters are at the end of the parameter list.
111 for (const NamedDecl *Param : llvm::reverse(asArray())) {
112 if (!Param->isImplicit())
113 break;
114
115 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
116 const auto *TC = TTP->getTypeConstraint();
117 if (TC && TC->getImmediatelyDeclaredConstraint()
118 ->containsUnexpandedParameterPack())
119 return true;
120 }
121 }
122
123 return false;
124}
125
128 SourceLocation LAngleLoc,
130 SourceLocation RAngleLoc, Expr *RequiresClause) {
131 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
132 Params.size(), RequiresClause ? 1u : 0u),
133 alignof(TemplateParameterList));
134 return new (Mem) TemplateParameterList(C, TemplateLoc, LAngleLoc, Params,
135 RAngleLoc, RequiresClause);
136}
137
138void TemplateParameterList::Profile(llvm::FoldingSetNodeID &ID,
139 const ASTContext &C) const {
140 const Expr *RC = getRequiresClause();
141 ID.AddBoolean(RC != nullptr);
142 if (RC)
143 RC->Profile(ID, C, /*Canonical=*/true);
144 ID.AddInteger(size());
145 for (NamedDecl *D : *this) {
146 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
147 ID.AddInteger(0);
148 ID.AddBoolean(NTTP->isParameterPack());
149 NTTP->getType().getCanonicalType().Profile(ID);
150 ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint());
151 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
152 E->Profile(ID, C, /*Canonical=*/true);
153 continue;
154 }
155 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {
156 ID.AddInteger(1);
157 ID.AddBoolean(TTP->isParameterPack());
158 ID.AddBoolean(TTP->hasTypeConstraint());
159 if (const TypeConstraint *TC = TTP->getTypeConstraint())
160 TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,
161 /*Canonical=*/true);
162 continue;
163 }
164 const auto *TTP = cast<TemplateTemplateParmDecl>(D);
165 ID.AddInteger(2);
166 ID.AddBoolean(TTP->isParameterPack());
167 TTP->getTemplateParameters()->Profile(ID, C);
168 }
169}
170
172 unsigned NumRequiredArgs = 0;
173 for (const NamedDecl *P : asArray()) {
174 if (P->isTemplateParameterPack()) {
175 if (std::optional<unsigned> Expansions = getExpandedPackSize(P)) {
176 NumRequiredArgs += *Expansions;
177 continue;
178 }
179 break;
180 }
181
182 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
183 if (TTP->hasDefaultArgument())
184 break;
185 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
186 if (NTTP->hasDefaultArgument())
187 break;
188 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
189 break;
190
191 ++NumRequiredArgs;
192 }
193
194 return NumRequiredArgs;
195}
196
197unsigned TemplateParameterList::getDepth() const {
198 if (size() == 0)
199 return 0;
200
201 const NamedDecl *FirstParm = getParam(0);
202 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
203 return TTP->getDepth();
204 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
205 return NTTP->getDepth();
206 else
207 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
208}
209
211 DeclContext *Owner) {
212 bool Invalid = false;
213 for (NamedDecl *P : *Params) {
214 P->setDeclContext(Owner);
215
216 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
217 if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner))
218 Invalid = true;
219
220 if (P->isInvalidDecl())
221 Invalid = true;
222 }
223 return Invalid;
224}
225
228 if (HasConstrainedParameters)
229 for (const NamedDecl *Param : *this) {
230 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
231 if (const auto *TC = TTP->getTypeConstraint())
232 AC.push_back(TC->getImmediatelyDeclaredConstraint());
233 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
234 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
235 AC.push_back(E);
236 }
237 }
238 if (HasRequiresClause)
239 AC.push_back(getRequiresClause());
240}
241
243 return HasRequiresClause || HasConstrainedParameters;
244}
245
248 if (!InjectedArgs) {
249 InjectedArgs = new (Context) TemplateArgument[size()];
250 llvm::transform(*this, InjectedArgs, [&](NamedDecl *ND) {
251 return Context.getInjectedTemplateArg(ND);
252 });
253 }
254 return {InjectedArgs, NumParams};
255}
256
258 const PrintingPolicy &Policy, const TemplateParameterList *TPL,
259 unsigned Idx) {
260 if (!TPL || Idx >= TPL->size() || Policy.AlwaysIncludeTypeForTemplateArgument)
261 return true;
262 const NamedDecl *TemplParam = TPL->getParam(Idx);
263 if (const auto *ParamValueDecl =
264 dyn_cast<NonTypeTemplateParmDecl>(TemplParam))
265 if (ParamValueDecl->getType()->getContainedDeducedType())
266 return true;
267 return false;
268}
269
270namespace clang {
271
273 return new (C) char[sizeof(void*) * 2];
274}
275
276} // namespace clang
277
278//===----------------------------------------------------------------------===//
279// TemplateDecl Implementation
280//===----------------------------------------------------------------------===//
281
285 : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
286
287void TemplateDecl::anchor() {}
288
292 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
293 if (const Expr *TRC = FD->getTrailingRequiresClause())
294 AC.push_back(TRC);
295}
296
299 return true;
300 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
301 return FD->getTrailingRequiresClause();
302 return false;
303}
304
306 switch (getKind()) {
307 case TemplateDecl::TypeAliasTemplate:
308 case TemplateDecl::BuiltinTemplate:
309 return true;
310 default:
311 return false;
312 };
313}
314
315//===----------------------------------------------------------------------===//
316// RedeclarableTemplateDecl Implementation
317//===----------------------------------------------------------------------===//
318
319void RedeclarableTemplateDecl::anchor() {}
320
322 if (Common)
323 return Common;
324
325 // Walk the previous-declaration chain until we either find a declaration
326 // with a common pointer or we run out of previous declarations.
328 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
329 Prev = Prev->getPreviousDecl()) {
330 if (Prev->Common) {
331 Common = Prev->Common;
332 break;
333 }
334
335 PrevDecls.push_back(Prev);
336 }
337
338 // If we never found a common pointer, allocate one now.
339 if (!Common) {
340 // FIXME: If any of the declarations is from an AST file, we probably
341 // need an update record to add the common data.
342
344 }
345
346 // Update any previous declarations we saw with the common pointer.
347 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
348 Prev->Common = Common;
349
350 return Common;
351}
352
354 bool OnlyPartial /*=false*/) const {
356 if (!ExternalSource)
357 return;
358
360 OnlyPartial);
361 return;
362}
363
367 if (!ExternalSource)
368 return false;
369
370 // If TPL is not null, it implies that we're loading specializations for
371 // partial templates. We need to load all specializations in such cases.
372 if (TPL)
374 /*OnlyPartial=*/false);
375
377 Args);
378}
379
380template <class EntryType, typename... ProfileArguments>
383 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
384 ProfileArguments &&...ProfileArgs) {
386
387 llvm::FoldingSetNodeID ID;
388 EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
389 getASTContext());
390 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
391 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
392}
393
394template <class EntryType, typename... ProfileArguments>
397 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
398 ProfileArguments &&...ProfileArgs) {
399
401 Specs, InsertPos, std::forward<ProfileArguments>(ProfileArgs)...))
402 return Found;
403
405 std::forward<ProfileArguments>(ProfileArgs)...))
406 return nullptr;
407
409 Specs, InsertPos, std::forward<ProfileArguments>(ProfileArgs)...);
410}
411
412template<class Derived, class EntryType>
414 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
415 void *InsertPos) {
416 using SETraits = SpecEntryTraits<EntryType>;
417
418 if (InsertPos) {
419#ifndef NDEBUG
420 auto Args = SETraits::getTemplateArgs(Entry);
421 // Due to hash collisions, it can happen that we load another template
422 // specialization with the same hash. This is fine, as long as the next
423 // call to findSpecializationImpl does not find a matching Decl for the
424 // template arguments.
426 void *CorrectInsertPos;
427 assert(!findSpecializationImpl(Specializations, CorrectInsertPos, Args) &&
428 InsertPos == CorrectInsertPos &&
429 "given incorrect InsertPos for specialization");
430#endif
431 Specializations.InsertNode(Entry, InsertPos);
432 } else {
433 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
434 (void)Existing;
435 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
436 "non-canonical specialization?");
437 }
438
440 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
441 SETraits::getDecl(Entry));
442}
443
444//===----------------------------------------------------------------------===//
445// FunctionTemplateDecl Implementation
446//===----------------------------------------------------------------------===//
447
450 DeclarationName Name,
452 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
453 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
454 if (Invalid)
455 TD->setInvalidDecl();
456 return TD;
457}
458
461 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
462 DeclarationName(), nullptr, nullptr);
463}
464
467 auto *CommonPtr = new (C) Common;
468 C.addDestruction(CommonPtr);
469 return CommonPtr;
470}
471
474}
475
476llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
480}
481
484 void *&InsertPos) {
485 auto *Common = getCommonPtr();
486 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
487}
488
490 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
491 auto *Common = getCommonPtr();
492 addSpecializationImpl<FunctionTemplateDecl>(Common->Specializations, Info,
493 InsertPos);
494}
495
498
499 // If we haven't created a common pointer yet, then it can just be created
500 // with the usual method.
501 if (!Base::Common)
502 return;
503
504 Common *ThisCommon = static_cast<Common *>(Base::Common);
505 Common *PrevCommon = nullptr;
507 for (; Prev; Prev = Prev->getPreviousDecl()) {
508 if (Prev->Base::Common) {
509 PrevCommon = static_cast<Common *>(Prev->Base::Common);
510 break;
511 }
512 PreviousDecls.push_back(Prev);
513 }
514
515 // If the previous redecl chain hasn't created a common pointer yet, then just
516 // use this common pointer.
517 if (!PrevCommon) {
518 for (auto *D : PreviousDecls)
519 D->Base::Common = ThisCommon;
520 return;
521 }
522
523 // Ensure we don't leak any important state.
524 assert(ThisCommon->Specializations.size() == 0 &&
525 "Can't merge incompatible declarations!");
526
527 Base::Common = PrevCommon;
528}
529
530//===----------------------------------------------------------------------===//
531// ClassTemplateDecl Implementation
532//===----------------------------------------------------------------------===//
533
536 DeclarationName Name,
537 TemplateParameterList *Params,
538 NamedDecl *Decl) {
539 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
540 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
541 if (Invalid)
542 TD->setInvalidDecl();
543 return TD;
544}
545
547 GlobalDeclID ID) {
548 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
549 DeclarationName(), nullptr, nullptr);
550}
551
553 bool OnlyPartial /*=false*/) const {
554 loadLazySpecializationsImpl(OnlyPartial);
555}
556
557llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
561}
562
563llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
565 LoadLazySpecializations(/*PartialOnly = */ true);
567}
568
571 auto *CommonPtr = new (C) Common;
572 C.addDestruction(CommonPtr);
573 return CommonPtr;
574}
575
578 void *&InsertPos) {
579 auto *Common = getCommonPtr();
580 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
581}
582
584 void *InsertPos) {
585 auto *Common = getCommonPtr();
586 addSpecializationImpl<ClassTemplateDecl>(Common->Specializations, D,
587 InsertPos);
588}
589
593 TemplateParameterList *TPL, void *&InsertPos) {
594 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
595 TPL);
596}
597
599 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
600 TemplateParameterList *TPL, const ASTContext &Context) {
601 ID.AddInteger(TemplateArgs.size());
602 for (const TemplateArgument &TemplateArg : TemplateArgs)
603 TemplateArg.Profile(ID, Context);
604 TPL->Profile(ID, Context);
605}
606
609 void *InsertPos) {
610 if (InsertPos)
611 getPartialSpecializations().InsertNode(D, InsertPos);
612 else {
614 = getPartialSpecializations().GetOrInsertNode(D);
615 (void)Existing;
616 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
617 }
618
620 L->AddedCXXTemplateSpecialization(this, D);
621}
622
625 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
627 PS.clear();
628 PS.reserve(PartialSpecs.size());
629 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
630 PS.push_back(P.getMostRecentDecl());
631}
632
635 ASTContext &Context = getASTContext();
638 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
639 return P.getMostRecentDecl();
640 }
641
642 return nullptr;
643}
644
648 Decl *DCanon = D->getCanonicalDecl();
650 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
651 return P.getMostRecentDecl();
652 }
653
654 return nullptr;
655}
656
659 Common *CommonPtr = getCommonPtr();
660 if (!CommonPtr->InjectedClassNameType.isNull())
661 return CommonPtr->InjectedClassNameType;
662
663 // C++0x [temp.dep.type]p2:
664 // The template argument list of a primary template is a template argument
665 // list in which the nth template argument has the value of the nth template
666 // parameter of the class template. If the nth template parameter is a
667 // template parameter pack (14.5.3), the nth template argument is a pack
668 // expansion (14.5.3) whose pattern is the name of the template parameter
669 // pack.
670 ASTContext &Context = getASTContext();
672 /*NNS=*/nullptr, /*TemplateKeyword=*/false, TemplateName(this));
675 return CommonPtr->InjectedClassNameType;
676}
677
678//===----------------------------------------------------------------------===//
679// TemplateTypeParm Allocation/Deallocation Method Implementations
680//===----------------------------------------------------------------------===//
681
683 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
684 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
685 bool Typename, bool ParameterPack, bool HasTypeConstraint,
686 std::optional<unsigned> NumExpanded) {
687 auto *TTPDecl =
688 new (C, DC,
689 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
690 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
691 HasTypeConstraint, NumExpanded);
692 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
693 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
694 return TTPDecl;
695}
696
699 return new (C, ID)
701 false, false, std::nullopt);
702}
703
706 bool HasTypeConstraint) {
707 return new (C, ID,
708 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
710 false, HasTypeConstraint, std::nullopt);
711}
712
715 : SourceLocation();
716}
717
720 return SourceRange(getBeginLoc(),
722 // TypeDecl::getSourceRange returns a range containing name location, which is
723 // wrong for unnamed template parameters. e.g:
724 // it will return <[[typename>]] instead of <[[typename]]>
725 if (getDeclName().isEmpty())
726 return SourceRange(getBeginLoc());
728}
729
731 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
732 if (DefArg.getArgument().isNull())
733 DefaultArgument.set(nullptr);
734 else
735 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
736}
737
740}
741
744}
745
748}
749
751 ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint) {
752 assert(HasTypeConstraint &&
753 "HasTypeConstraint=true must be passed at construction in order to "
754 "call setTypeConstraint");
755 assert(!TypeConstraintInitialized &&
756 "TypeConstraint was already initialized!");
757 new (getTrailingObjects<TypeConstraint>())
758 TypeConstraint(Loc, ImmediatelyDeclaredConstraint);
759 TypeConstraintInitialized = true;
760}
761
762//===----------------------------------------------------------------------===//
763// NonTypeTemplateParmDecl Method Implementations
764//===----------------------------------------------------------------------===//
765
766NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
767 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
768 unsigned P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
769 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
770 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
771 TemplateParmPosition(D, P), ParameterPack(true),
772 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
773 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
774 auto TypesAndInfos =
775 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
776 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
777 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
778 TypesAndInfos[I].second = ExpandedTInfos[I];
779 }
780 }
781}
782
784 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
785 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
786 QualType T, bool ParameterPack, TypeSourceInfo *TInfo) {
787 AutoType *AT =
788 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
789 return new (C, DC,
790 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
791 Expr *>(0,
792 AT && AT->isConstrained() ? 1 : 0))
793 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,
794 TInfo);
795}
796
798 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
799 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
800 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
801 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
802 AutoType *AT = TInfo->getType()->getContainedAutoType();
803 return new (C, DC,
804 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
805 Expr *>(
806 ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))
807 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
808 ExpandedTypes, ExpandedTInfos);
809}
810
813 bool HasTypeConstraint) {
814 return new (C, ID, additionalSizeToAlloc<std::pair<QualType,
816 Expr *>(0,
817 HasTypeConstraint ? 1 : 0))
819 0, 0, nullptr, QualType(), false, nullptr);
820}
821
824 unsigned NumExpandedTypes,
825 bool HasTypeConstraint) {
826 auto *NTTP =
827 new (C, ID,
828 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
829 NumExpandedTypes, HasTypeConstraint ? 1 : 0))
831 0, 0, nullptr, QualType(), nullptr, {}, {});
832 NTTP->NumExpandedTypes = NumExpandedTypes;
833 return NTTP;
834}
835
841}
842
845 : SourceLocation();
846}
847
849 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
850 if (DefArg.getArgument().isNull())
851 DefaultArgument.set(nullptr);
852 else
853 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
854}
855
856//===----------------------------------------------------------------------===//
857// TemplateTemplateParmDecl Method Implementations
858//===----------------------------------------------------------------------===//
859
860void TemplateTemplateParmDecl::anchor() {}
861
862TemplateTemplateParmDecl::TemplateTemplateParmDecl(
863 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
866 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
867 TemplateParmPosition(D, P), Typename(Typename), ParameterPack(true),
868 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
869 if (!Expansions.empty())
870 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
871 getTrailingObjects<TemplateParameterList *>());
872}
873
876 SourceLocation L, unsigned D, unsigned P,
877 bool ParameterPack, IdentifierInfo *Id,
878 bool Typename, TemplateParameterList *Params) {
879 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
880 Typename, Params);
881}
882
885 SourceLocation L, unsigned D, unsigned P,
887 TemplateParameterList *Params,
889 return new (C, DC,
890 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
891 TemplateTemplateParmDecl(DC, L, D, P, Id, Typename, Params, Expansions);
892}
893
896 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
897 false, nullptr, false, nullptr);
898}
899
902 unsigned NumExpansions) {
903 auto *TTP =
904 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
905 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
906 false, nullptr, {});
907 TTP->NumExpandedParams = NumExpansions;
908 return TTP;
909}
910
913 : SourceLocation();
914}
915
917 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
918 if (DefArg.getArgument().isNull())
919 DefaultArgument.set(nullptr);
920 else
921 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
922}
923
924//===----------------------------------------------------------------------===//
925// TemplateArgumentList Implementation
926//===----------------------------------------------------------------------===//
927TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
928 : NumArguments(Args.size()) {
929 std::uninitialized_copy(Args.begin(), Args.end(),
930 getTrailingObjects<TemplateArgument>());
931}
932
936 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
937 return new (Mem) TemplateArgumentList(Args);
938}
939
943 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
944 MemberSpecializationInfo *MSInfo) {
945 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
946 if (TemplateArgsAsWritten)
948 *TemplateArgsAsWritten);
949
950 void *Mem =
951 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
952 return new (Mem) FunctionTemplateSpecializationInfo(
953 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
954}
955
956//===----------------------------------------------------------------------===//
957// ClassTemplateSpecializationDecl Implementation
958//===----------------------------------------------------------------------===//
959
962 DeclContext *DC, SourceLocation StartLoc,
963 SourceLocation IdLoc,
964 ClassTemplateDecl *SpecializedTemplate,
967 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
968 SpecializedTemplate->getIdentifier(), PrevDecl),
969 SpecializedTemplate(SpecializedTemplate),
970 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
971 SpecializationKind(TSK_Undeclared) {
972}
973
975 Kind DK)
976 : CXXRecordDecl(DK, TagTypeKind::Struct, C, nullptr, SourceLocation(),
977 SourceLocation(), nullptr, nullptr),
978 SpecializationKind(TSK_Undeclared) {}
979
982 DeclContext *DC,
983 SourceLocation StartLoc,
984 SourceLocation IdLoc,
985 ClassTemplateDecl *SpecializedTemplate,
988 auto *Result =
989 new (Context, DC) ClassTemplateSpecializationDecl(
990 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
991 SpecializedTemplate, Args, PrevDecl);
992 Result->setMayHaveOutOfDateDef(false);
993
994 // If the template decl is incomplete, copy the external lexical storage from
995 // the base template. This allows instantiations of incomplete types to
996 // complete using the external AST if the template's declaration came from an
997 // external AST.
998 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
999 Result->setHasExternalLexicalStorage(
1000 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
1001
1002 Context.getTypeDeclType(Result, PrevDecl);
1003 return Result;
1004}
1005
1008 GlobalDeclID ID) {
1009 auto *Result =
1010 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
1011 Result->setMayHaveOutOfDateDef(false);
1012 return Result;
1013}
1014
1016 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1018
1019 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
1020 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1021 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1023 OS, ArgsAsWritten->arguments(), Policy,
1024 getSpecializedTemplate()->getTemplateParameters());
1025 } else {
1026 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1028 OS, TemplateArgs.asArray(), Policy,
1029 getSpecializedTemplate()->getTemplateParameters());
1030 }
1031}
1032
1035 if (const auto *PartialSpec =
1036 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
1037 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1038 return cast<ClassTemplateDecl *>(SpecializedTemplate);
1039}
1040
1043 switch (getSpecializationKind()) {
1044 case TSK_Undeclared:
1046 llvm::PointerUnion<ClassTemplateDecl *,
1049 assert(!Pattern.isNull() &&
1050 "Class template specialization without pattern?");
1051 if (const auto *CTPSD =
1052 Pattern.dyn_cast<ClassTemplatePartialSpecializationDecl *>())
1053 return CTPSD->getSourceRange();
1054 return cast<ClassTemplateDecl *>(Pattern)->getSourceRange();
1055 }
1060 Range.setEnd(Args->getRAngleLoc());
1061 return Range;
1062 }
1066 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1067 Range.setBegin(ExternKW);
1068 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1069 TemplateKW.isValid())
1070 Range.setBegin(TemplateKW);
1072 Range.setEnd(Args->getRAngleLoc());
1073 return Range;
1074 }
1075 }
1076 llvm_unreachable("unhandled template specialization kind");
1077}
1078
1080 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1081 if (!Info) {
1082 // Don't allocate if the location is invalid.
1083 if (Loc.isInvalid())
1084 return;
1087 ExplicitInfo = Info;
1088 }
1089 Info->ExternKeywordLoc = Loc;
1090}
1091
1094 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1095 if (!Info) {
1096 // Don't allocate if the location is invalid.
1097 if (Loc.isInvalid())
1098 return;
1101 ExplicitInfo = Info;
1102 }
1103 Info->TemplateKeywordLoc = Loc;
1104}
1105
1106//===----------------------------------------------------------------------===//
1107// ConceptDecl Implementation
1108//===----------------------------------------------------------------------===//
1111 TemplateParameterList *Params,
1112 Expr *ConstraintExpr) {
1113 bool Invalid = AdoptTemplateParameterList(Params, DC);
1114 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1115 if (Invalid)
1116 TD->setInvalidDecl();
1117 return TD;
1118}
1119
1121 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1123 nullptr, nullptr);
1124
1125 return Result;
1126}
1127
1128//===----------------------------------------------------------------------===//
1129// ImplicitConceptSpecializationDecl Implementation
1130//===----------------------------------------------------------------------===//
1131ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1133 ArrayRef<TemplateArgument> ConvertedArgs)
1134 : Decl(ImplicitConceptSpecialization, DC, SL),
1135 NumTemplateArgs(ConvertedArgs.size()) {
1136 setTemplateArguments(ConvertedArgs);
1137}
1138
1139ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1140 EmptyShell Empty, unsigned NumTemplateArgs)
1141 : Decl(ImplicitConceptSpecialization, Empty),
1142 NumTemplateArgs(NumTemplateArgs) {}
1143
1145 const ASTContext &C, DeclContext *DC, SourceLocation SL,
1146 ArrayRef<TemplateArgument> ConvertedArgs) {
1147 return new (C, DC,
1148 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1149 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1150}
1151
1154 const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) {
1155 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1157}
1158
1160 ArrayRef<TemplateArgument> Converted) {
1161 assert(Converted.size() == NumTemplateArgs);
1162 std::uninitialized_copy(Converted.begin(), Converted.end(),
1163 getTrailingObjects<TemplateArgument>());
1164}
1165
1166//===----------------------------------------------------------------------===//
1167// ClassTemplatePartialSpecializationDecl Implementation
1168//===----------------------------------------------------------------------===//
1169void ClassTemplatePartialSpecializationDecl::anchor() {}
1170
1171ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
1172 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1174 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1177 Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
1178 SpecializedTemplate, Args, PrevDecl),
1179 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1180 if (AdoptTemplateParameterList(Params, this))
1182}
1183
1186 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1188 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1189 QualType CanonInjectedType,
1191 auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl(
1192 Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args,
1193 PrevDecl);
1194 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1195 Result->setMayHaveOutOfDateDef(false);
1196
1197 Context.getInjectedClassNameType(Result, CanonInjectedType);
1198 return Result;
1199}
1200
1203 GlobalDeclID ID) {
1205 Result->setMayHaveOutOfDateDef(false);
1206 return Result;
1207}
1208
1212 MT && !isMemberSpecialization())
1213 return MT->getSourceRange();
1218 return Range;
1219}
1220
1221//===----------------------------------------------------------------------===//
1222// FriendTemplateDecl Implementation
1223//===----------------------------------------------------------------------===//
1224
1225void FriendTemplateDecl::anchor() {}
1226
1232 TemplateParameterList **TPL = nullptr;
1233 if (!Params.empty()) {
1234 TPL = new (Context) TemplateParameterList *[Params.size()];
1235 llvm::copy(Params, TPL);
1236 }
1237 return new (Context, DC)
1238 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
1239}
1240
1242 GlobalDeclID ID) {
1243 return new (C, ID) FriendTemplateDecl(EmptyShell());
1244}
1245
1246//===----------------------------------------------------------------------===//
1247// TypeAliasTemplateDecl Implementation
1248//===----------------------------------------------------------------------===//
1249
1252 DeclarationName Name,
1254 bool Invalid = AdoptTemplateParameterList(Params, DC);
1255 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1256 if (Invalid)
1257 TD->setInvalidDecl();
1258 return TD;
1259}
1260
1263 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1264 DeclarationName(), nullptr, nullptr);
1265}
1266
1269 auto *CommonPtr = new (C) Common;
1270 C.addDestruction(CommonPtr);
1271 return CommonPtr;
1272}
1273
1274//===----------------------------------------------------------------------===//
1275// VarTemplateDecl Implementation
1276//===----------------------------------------------------------------------===//
1277
1279 VarTemplateDecl *CurD = this;
1280 while (CurD) {
1281 if (CurD->isThisDeclarationADefinition())
1282 return CurD;
1283 CurD = CurD->getPreviousDecl();
1284 }
1285 return nullptr;
1286}
1287
1290 TemplateParameterList *Params,
1291 VarDecl *Decl) {
1292 bool Invalid = AdoptTemplateParameterList(Params, DC);
1293 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1294 if (Invalid)
1295 TD->setInvalidDecl();
1296 return TD;
1297}
1298
1300 GlobalDeclID ID) {
1301 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1302 DeclarationName(), nullptr, nullptr);
1303}
1304
1306 bool OnlyPartial /*=false*/) const {
1307 loadLazySpecializationsImpl(OnlyPartial);
1308}
1309
1310llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1313 return getCommonPtr()->Specializations;
1314}
1315
1316llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1318 LoadLazySpecializations(/*PartialOnly = */ true);
1320}
1321
1324 auto *CommonPtr = new (C) Common;
1325 C.addDestruction(CommonPtr);
1326 return CommonPtr;
1327}
1328
1331 void *&InsertPos) {
1332 auto *Common = getCommonPtr();
1333 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
1334}
1335
1337 void *InsertPos) {
1338 auto *Common = getCommonPtr();
1339 addSpecializationImpl<VarTemplateDecl>(Common->Specializations, D, InsertPos);
1340}
1341
1344 TemplateParameterList *TPL, void *&InsertPos) {
1345 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1346 TPL);
1347}
1348
1350 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1351 TemplateParameterList *TPL, const ASTContext &Context) {
1352 ID.AddInteger(TemplateArgs.size());
1353 for (const TemplateArgument &TemplateArg : TemplateArgs)
1354 TemplateArg.Profile(ID, Context);
1355 TPL->Profile(ID, Context);
1356}
1357
1359 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1360 if (InsertPos)
1361 getPartialSpecializations().InsertNode(D, InsertPos);
1362 else {
1364 getPartialSpecializations().GetOrInsertNode(D);
1365 (void)Existing;
1366 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1367 }
1368
1370 L->AddedCXXTemplateSpecialization(this, D);
1371}
1372
1375 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1377 PS.clear();
1378 PS.reserve(PartialSpecs.size());
1379 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1380 PS.push_back(P.getMostRecentDecl());
1381}
1382
1386 Decl *DCanon = D->getCanonicalDecl();
1388 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1389 return P.getMostRecentDecl();
1390 }
1391
1392 return nullptr;
1393}
1394
1395//===----------------------------------------------------------------------===//
1396// VarTemplateSpecializationDecl Implementation
1397//===----------------------------------------------------------------------===//
1398
1400 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1401 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1403 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1404 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1405 SpecializedTemplate(SpecializedTemplate),
1406 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1407 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1408
1410 ASTContext &C)
1411 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1412 QualType(), nullptr, SC_None),
1413 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1414
1416 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1417 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1419 return new (Context, DC) VarTemplateSpecializationDecl(
1420 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1421 SpecializedTemplate, T, TInfo, S, Args);
1422}
1423
1426 GlobalDeclID ID) {
1427 return new (C, ID)
1428 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1429}
1430
1432 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1434
1435 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1436 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1437 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1439 OS, ArgsAsWritten->arguments(), Policy,
1440 getSpecializedTemplate()->getTemplateParameters());
1441 } else {
1442 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1444 OS, TemplateArgs.asArray(), Policy,
1445 getSpecializedTemplate()->getTemplateParameters());
1446 }
1447}
1448
1450 if (const auto *PartialSpec =
1451 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1452 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1453 return cast<VarTemplateDecl *>(SpecializedTemplate);
1454}
1455
1457 switch (getSpecializationKind()) {
1458 case TSK_Undeclared:
1460 llvm::PointerUnion<VarTemplateDecl *,
1463 assert(!Pattern.isNull() &&
1464 "Variable template specialization without pattern?");
1465 if (const auto *VTPSD =
1466 Pattern.dyn_cast<VarTemplatePartialSpecializationDecl *>())
1467 return VTPSD->getSourceRange();
1468 VarTemplateDecl *VTD = cast<VarTemplateDecl *>(Pattern);
1469 if (hasInit()) {
1471 return Definition->getSourceRange();
1472 }
1473 return VTD->getCanonicalDecl()->getSourceRange();
1474 }
1478 !hasInit() && Args)
1479 Range.setEnd(Args->getRAngleLoc());
1480 return Range;
1481 }
1485 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1486 Range.setBegin(ExternKW);
1487 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1488 TemplateKW.isValid())
1489 Range.setBegin(TemplateKW);
1491 Range.setEnd(Args->getRAngleLoc());
1492 return Range;
1493 }
1494 }
1495 llvm_unreachable("unhandled template specialization kind");
1496}
1497
1499 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1500 if (!Info) {
1501 // Don't allocate if the location is invalid.
1502 if (Loc.isInvalid())
1503 return;
1506 ExplicitInfo = Info;
1507 }
1508 Info->ExternKeywordLoc = Loc;
1509}
1510
1512 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1513 if (!Info) {
1514 // Don't allocate if the location is invalid.
1515 if (Loc.isInvalid())
1516 return;
1519 ExplicitInfo = Info;
1520 }
1521 Info->TemplateKeywordLoc = Loc;
1522}
1523
1524//===----------------------------------------------------------------------===//
1525// VarTemplatePartialSpecializationDecl Implementation
1526//===----------------------------------------------------------------------===//
1527
1528void VarTemplatePartialSpecializationDecl::anchor() {}
1529
1530VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1531 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1533 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1535 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1536 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1537 TInfo, S, Args),
1538 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1539 if (AdoptTemplateParameterList(Params, DC))
1541}
1542
1545 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1547 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1549 auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(
1550 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,
1551 Args);
1552 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1553 return Result;
1554}
1555
1558 GlobalDeclID ID) {
1559 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1560}
1561
1565 MT && !isMemberSpecialization())
1566 return MT->getSourceRange();
1571 return Range;
1572}
1573
1574static TemplateParameterList *
1576 // typename T
1578 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1579 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1580 /*HasTypeConstraint=*/false);
1581 T->setImplicit(true);
1582
1583 // T ...Ints
1584 TypeSourceInfo *TI =
1585 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1587 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1588 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1589 N->setImplicit(true);
1590
1591 // <typename T, T ...Ints>
1592 NamedDecl *P[2] = {T, N};
1594 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1595
1596 // template <typename T, ...Ints> class IntSeq
1597 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1598 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1599 /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, TPL);
1600 TemplateTemplateParm->setImplicit(true);
1601
1602 // typename T
1603 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1604 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1605 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1606 /*HasTypeConstraint=*/false);
1607 TemplateTypeParm->setImplicit(true);
1608
1609 // T N
1610 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1611 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1612 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1613 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1614 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1615 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1616 NonTypeTemplateParm};
1617
1618 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1620 Params, SourceLocation(), nullptr);
1621}
1622
1623static TemplateParameterList *
1625 // std::size_t Index
1626 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1627 auto *Index = NonTypeTemplateParmDecl::Create(
1628 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1629 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1630
1631 // typename ...T
1633 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1634 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
1635 /*HasTypeConstraint=*/false);
1636 Ts->setImplicit(true);
1637
1638 // template <std::size_t Index, typename ...T>
1639 NamedDecl *Params[] = {Index, Ts};
1641 llvm::ArrayRef(Params), SourceLocation(),
1642 nullptr);
1643}
1644
1646 DeclContext *DC) {
1647 // class... Args
1648 auto *Args =
1650 /*Depth=*/1, /*Position=*/0, /*Id=*/nullptr,
1651 /*Typename=*/false, /*ParameterPack=*/true);
1652
1653 // <class... Args>
1654 auto *BaseTemplateList = TemplateParameterList::Create(
1655 C, SourceLocation(), SourceLocation(), Args, SourceLocation(), nullptr);
1656
1657 // template <class... Args> class BaseTemplate
1658 auto *BaseTemplate = TemplateTemplateParmDecl::Create(
1659 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1660 /*ParameterPack=*/false, /*Id=*/nullptr,
1661 /*Typename=*/false, BaseTemplateList);
1662
1663 // class TypeMember
1664 auto *TypeMember =
1666 /*Depth=*/1, /*Position=*/0, /*Id=*/nullptr,
1667 /*Typename=*/false, /*ParameterPack=*/false);
1668
1669 // <class TypeMember>
1670 auto *HasTypeMemberList =
1672 TypeMember, SourceLocation(), nullptr);
1673
1674 // template <class TypeMember> class HasTypeMember
1675 auto *HasTypeMember = TemplateTemplateParmDecl::Create(
1676 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/1,
1677 /*ParameterPack=*/false, /*Id=*/nullptr,
1678 /*Typename=*/false, HasTypeMemberList);
1679
1680 // class HasNoTypeMember
1681 auto *HasNoTypeMember = TemplateTypeParmDecl::Create(
1682 C, DC, {}, {}, /*Depth=*/0, /*Position=*/2, /*Id=*/nullptr,
1683 /*Typename=*/false, /*ParameterPack=*/false);
1684
1685 // class... Ts
1687 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/3,
1688 /*Id=*/nullptr, /*Typename=*/false, /*ParameterPack=*/true);
1689
1690 // template <template <class... Args> class BaseTemplate,
1691 // template <class TypeMember> class HasTypeMember, class HasNoTypeMember,
1692 // class... Ts>
1695 {BaseTemplate, HasTypeMember, HasNoTypeMember, Ts}, SourceLocation(),
1696 nullptr);
1697}
1698
1700 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1701 switch (BTK) {
1707 return createBuiltinCommonTypeList(C, DC);
1708 }
1709
1710 llvm_unreachable("unhandled BuiltinTemplateKind!");
1711}
1712
1713void BuiltinTemplateDecl::anchor() {}
1714
1715BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1716 DeclarationName Name,
1718 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1720 BTK(BTK) {}
1721
1722TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1723 QualType T,
1724 const APValue &V) {
1725 DeclContext *DC = C.getTranslationUnitDecl();
1726 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1727 C.addDestruction(&TPOD->Value);
1728 return TPOD;
1729}
1730
1732TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1733 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1734 C.addDestruction(&TPOD->Value);
1735 return TPOD;
1736}
1737
1738void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1739 const PrintingPolicy &Policy) const {
1740 OS << "<template param ";
1741 printAsExpr(OS, Policy);
1742 OS << ">";
1743}
1744
1745void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1746 printAsExpr(OS, getASTContext().getPrintingPolicy());
1747}
1748
1749void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1750 const PrintingPolicy &Policy) const {
1751 getType().getUnqualifiedType().print(OS, Policy);
1752 printAsInit(OS, Policy);
1753}
1754
1755void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1756 printAsInit(OS, getASTContext().getPrintingPolicy());
1757}
1758
1759void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1760 const PrintingPolicy &Policy) const {
1761 getValue().printPretty(OS, Policy, getType(), &getASTContext());
1762}
1763
1765 switch (D->getKind()) {
1766 case Decl::Kind::CXXRecord:
1767 return cast<CXXRecordDecl>(D)
1768 ->getDescribedTemplate()
1769 ->getTemplateParameters();
1770 case Decl::Kind::ClassTemplate:
1771 return cast<ClassTemplateDecl>(D)->getTemplateParameters();
1772 case Decl::Kind::ClassTemplateSpecialization: {
1773 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1774 auto P = CTSD->getSpecializedTemplateOrPartial();
1775 if (const auto *CTPSD =
1777 return CTPSD->getTemplateParameters();
1778 return cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1779 }
1780 case Decl::Kind::ClassTemplatePartialSpecialization:
1781 return cast<ClassTemplatePartialSpecializationDecl>(D)
1782 ->getTemplateParameters();
1783 case Decl::Kind::TypeAliasTemplate:
1784 return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
1785 case Decl::Kind::BuiltinTemplate:
1786 return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
1787 case Decl::Kind::CXXDeductionGuide:
1788 case Decl::Kind::CXXConversion:
1789 case Decl::Kind::CXXConstructor:
1790 case Decl::Kind::CXXDestructor:
1791 case Decl::Kind::CXXMethod:
1792 case Decl::Kind::Function:
1793 return cast<FunctionDecl>(D)
1794 ->getTemplateSpecializationInfo()
1795 ->getTemplate()
1796 ->getTemplateParameters();
1797 case Decl::Kind::FunctionTemplate:
1798 return cast<FunctionTemplateDecl>(D)->getTemplateParameters();
1799 case Decl::Kind::VarTemplate:
1800 return cast<VarTemplateDecl>(D)->getTemplateParameters();
1801 case Decl::Kind::VarTemplateSpecialization: {
1802 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1803 auto P = VTSD->getSpecializedTemplateOrPartial();
1804 if (const auto *VTPSD =
1806 return VTPSD->getTemplateParameters();
1807 return cast<VarTemplateDecl *>(P)->getTemplateParameters();
1808 }
1809 case Decl::Kind::VarTemplatePartialSpecialization:
1810 return cast<VarTemplatePartialSpecializationDecl>(D)
1811 ->getTemplateParameters();
1812 case Decl::Kind::TemplateTemplateParm:
1813 return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();
1814 case Decl::Kind::Concept:
1815 return cast<ConceptDecl>(D)->getTemplateParameters();
1816 default:
1817 llvm_unreachable("Unhandled templated declaration kind");
1818 }
1819}
Defines the clang::ASTContext interface.
#define V(N, I)
Definition: ASTContext.h:3443
StringRef P
Defines enum values for all the target-independent builtin functions.
const Decl * D
Expr * E
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static TemplateParameterList * createTypePackElementParameterList(const ASTContext &C, DeclContext *DC)
static bool DefaultTemplateArgumentContainsUnexpandedPack(const TemplateParam &P)
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)
static TemplateParameterList * createBuiltinCommonTypeList(const ASTContext &C, DeclContext *DC)
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
This file contains the declaration of the ODRHash class, which calculates a hash based on AST nodes,...
static StringRef getIdentifier(const Token &Tok)
uint32_t Id
Definition: SemaARM.cpp:1134
SourceRange Range
Definition: SemaObjC.cpp:758
SourceLocation Loc
Definition: SemaObjC.cpp:759
Defines the clang::SourceLocation class and associated facilities.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
Definition: APValue.cpp:693
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
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:2732
TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, TemplateName Template) const
Retrieve the template name that represents a qualified template name such as std::vector.
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:1703
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl) const
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:754
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
Definition: ASTContext.h:1274
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:6556
bool isConstrained() const
Definition: Type.h:6575
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
Declaration of a class template.
void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this class template.
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
ClassTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
CommonBase * newCommon(ASTContext &C) const override
static ClassTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a class template node.
ClassTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *D)
Find a class template partial specialization which was instantiated from the given member partial spe...
void LoadLazySpecializations(bool OnlyPartial=false) const
Load any lazily-loaded specializations from the external source.
void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
QualType getInjectedClassNameSpecialization()
Retrieve the template specialization type of the injected-class-name for this class template.
Common * getCommonPtr() const
ClassTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
static ClassTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty class template node.
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member class template partial specialization from which this particular class template p...
static ClassTemplatePartialSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, QualType CanonInjectedType, ClassTemplatePartialSpecializationDecl *PrevDecl)
void Profile(llvm::FoldingSetNodeID &ID) const
bool isMemberSpecialization() const
Determines whether this class template partial specialization template was a specialization of a memb...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a class template specialization, which refers to a class template with a given set of temp...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, ClassTemplateSpecializationDecl *PrevDecl)
static ClassTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the class template or class template partial specialization which was specialized by this.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
static ClassTemplateSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, ClassTemplateSpecializationDecl *PrevDecl)
Declaration of a C++20 concept.
static ConceptDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
static ConceptDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr=nullptr)
A reference to a concept and its template args, as it appears in the code.
Definition: ASTConcept.h:124
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1435
bool hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
Definition: DeclBase.h:2664
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:520
ASTMutationListener * getASTMutationListener() const
Definition: DeclBase.cpp:530
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition: DeclBase.cpp:151
Kind
Lists the kind of concrete classes of Decl.
Definition: DeclBase.h:89
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
Definition: DeclBase.h:973
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:967
Kind getKind() const
Definition: DeclBase.h:445
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:735
SourceLocation getOuterLocStart() const
Return start of source range taking into account any outer template declarations.
Definition: Decl.cpp:2039
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2079
unsigned getNumTemplateParameterLists() const
Definition: Decl.h:822
void set(ArgType Arg)
Set the default argument.
Definition: DeclTemplate.h:359
This represents one expression.
Definition: Expr.h:110
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
Definition: Expr.h:239
virtual bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial)
Load all the external specializations for the Decl.
Declaration of a friend template.
static FriendTemplateDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc, MutableArrayRef< TemplateParameterList * > Params, FriendUnion Friend, SourceLocation FriendLoc)
llvm::PointerUnion< NamedDecl *, TypeSourceInfo * > FriendUnion
static FriendTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Represents a function declaration or definition.
Definition: Decl.h:1935
Declaration of a template function.
Definition: DeclTemplate.h:959
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
void addSpecialization(FunctionTemplateSpecializationInfo *Info, void *InsertPos)
Add a specialization of this function template.
CommonBase * newCommon(ASTContext &C) const override
Common * getCommonPtr() const
Definition: DeclTemplate.h:981
FunctionTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...
static FunctionTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty function template node.
static FunctionTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > & getSpecializations() const
Retrieve the set of function template specializations of this function template.
void mergePrevDecl(FunctionTemplateDecl *Prev)
Merge Prev with our RedeclarableTemplateDecl::Common.
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
Provides information about a function template specialization, which is a FunctionDecl that has been ...
Definition: DeclTemplate.h:472
static FunctionTemplateSpecializationInfo * Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs, const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI, MemberSpecializationInfo *MSInfo)
One of these records is kept for each identifier that is lexed.
void setTemplateArguments(ArrayRef< TemplateArgument > Converted)
static ImplicitConceptSpecializationDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef< TemplateArgument > ConvertedArgs)
static ImplicitConceptSpecializationDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs)
Provides information a specialization of a member of a class template, which may be a member function...
Definition: DeclTemplate.h:620
This represents a decl that may have a name.
Definition: Decl.h:253
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:319
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:1818
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
static NonTypeTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint)
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo)
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
A (possibly-)qualified type.
Definition: Type.h:929
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:996
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:7931
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:8025
Declaration of a redeclarable template.
Definition: DeclTemplate.h:721
SpecEntryTraits< EntryType >::DeclType * findSpecializationLocally(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments &&...ProfileArgs)
void loadLazySpecializationsImpl(bool OnlyPartial=false) const
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:812
virtual CommonBase * newCommon(ASTContext &C) const =0
RedeclarableTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
Definition: DeclTemplate.h:834
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, void *InsertPos)
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
Definition: DeclTemplate.h:922
RedeclarableTemplateDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Definition: Redeclarable.h:203
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getBegin() const
void setEnd(SourceLocation e)
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition: Decl.h:3662
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3667
unsigned getNumTemplateParameterLists() const
Definition: Decl.h:3816
A convenient class for passing around template argument information.
Definition: TemplateBase.h:632
A template argument list.
Definition: DeclTemplate.h:250
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:280
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
SourceLocation getLocation() const
Definition: TemplateBase.h:563
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:574
SourceRange getSourceRange() const LLVM_READONLY
Represents a template argument.
Definition: TemplateBase.h:61
bool isNull() const
Determine whether this template argument has no value.
Definition: TemplateBase.h:298
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:399
TemplateParameterList * TemplateParams
Definition: DeclTemplate.h:450
bool isTypeAlias() const
bool hasAssociatedConstraints() const
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:431
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclTemplate.h:443
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:418
Represents a C++ template name within the type system.
Definition: TemplateName.h:220
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:147
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context)
Get the template argument list of the template parameter list.
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
bool hasAssociatedConstraints() const
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to form a template specialization.
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
Definition: DeclTemplate.h:183
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:142
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
SourceLocation getTemplateLoc() const
Definition: DeclTemplate.h:205
Defines the position of a template parameter within a template parameter list.
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
static TemplateTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
static TemplateTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, bool Typename, TemplateParameterList *Params)
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
Declaration of a template type parameter.
SourceLocation getDefaultArgumentLoc() const
Retrieves the location of the default argument declaration.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
unsigned getIndex() const
Retrieve the index of the template parameter.
static TemplateTypeParmDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID)
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, std::optional< unsigned > NumExpanded=std::nullopt)
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
bool isParameterPack() const
Returns whether this is a parameter pack.
unsigned getDepth() const
Retrieve the depth of the template parameter.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void setTypeConstraint(ConceptReference *CR, Expr *ImmediatelyDeclaredConstraint)
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter.
Declaration of an alias template.
CommonBase * newCommon(ASTContext &C) const override
static TypeAliasTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty alias template node.
static TypeAliasTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition: ASTConcept.h:227
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Definition: ASTConcept.h:242
const Type * getTypeForDecl() const
Definition: Decl.h:3395
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.h:3400
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Decl.h:3398
A container of type source information.
Definition: Type.h:7902
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:7913
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8800
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition: Type.h:2811
QualType getType() const
Definition: Decl.h:682
Represents a variable declaration or definition.
Definition: Decl.h:882
bool hasInit() const
Definition: Decl.cpp:2387
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2179
@ Definition
This declaration is definitely a definition.
Definition: Decl.h:1252
Declaration of a variable template.
VarTemplateDecl * getDefinition()
VarTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
Common * getCommonPtr() const
VarTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
VarTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this variable template, or nullptr if no such declaration exists...
CommonBase * newCommon(ASTContext &C) const override
void LoadLazySpecializations(bool OnlyPartial=false) const
Load any lazily-loaded specializations from the external source.
static VarTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty variable template node.
static VarTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, VarDecl *Decl)
Create a variable template node.
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this variable template.
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary variable pattern.
VarTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
VarTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl *D)
Find a variable template partial specialization which was instantiated from the given member partial ...
static VarTemplatePartialSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
VarTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member variable template partial specialization from which this particular variable temp...
bool isMemberSpecialization() const
Determines whether this variable template partial specialization was a specialization of a member par...
void Profile(llvm::FoldingSetNodeID &ID) const
static VarTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Represents a variable template specialization, which refers to a variable template with a given set o...
VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static VarTemplateSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the variable template or variable template partial specialization which was specialized by t...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
VarTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
static VarTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
The JSON file list parser is used to communicate input to InstallAPI.
StorageClass
Storage classes.
Definition: Specifiers.h:248
@ SC_None
Definition: Specifiers.h:250
void * allocateDefaultArgStorageChain(const ASTContext &C)
@ Result
The result type of a method or function.
TemplateParameterList * getReplacedTemplateParameterList(Decl *D)
Internal helper used by Subst* nodes to retrieve the parameter list for their AssociatedDecl.
TagTypeKind
The kind of a tag type.
Definition: Type.h:6871
BuiltinTemplateKind
Kinds of BuiltinTemplateDecl.
Definition: Builtins.h:305
@ BTK__type_pack_element
This names the __type_pack_element BuiltinTemplateDecl.
Definition: Builtins.h:310
@ BTK__builtin_common_type
This names the __builtin_common_type BuiltinTemplateDecl.
Definition: Builtins.h:313
@ BTK__make_integer_seq
This names the __make_integer_seq BuiltinTemplateDecl.
Definition: Builtins.h:307
std::optional< unsigned > getExpandedPackSize(const NamedDecl *Param)
Check whether the template parameter is a pack expansion, and if so, determine the number of paramete...
const FunctionProtoType * T
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
Definition: Specifiers.h:188
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition: Specifiers.h:206
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition: Specifiers.h:202
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition: Specifiers.h:198
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition: Specifiers.h:194
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:191
@ Struct
The "struct" keyword introduces the elaborated-type-specifier.
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
#define true
Definition: stdbool.h:25
#define false
Definition: stdbool.h:26
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:676
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
Data that is common to all of the declarations of a given class template.
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > PartialSpecializations
The class template partial specializations for this class template.
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > Specializations
The class template specializations for this class template, including explicit specializations and in...
QualType InjectedClassNameType
The injected-class-name type for this class template.
A placeholder type used to construct an empty shell of a decl-derived type that will be filled in lat...
Definition: DeclBase.h:102
Provides information about an explicit instantiation of a variable or class template.
const ASTTemplateArgumentListInfo * TemplateArgsAsWritten
The template arguments as written..
Data that is common to all of the declarations of a given function template.
Definition: DeclTemplate.h:965
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > Specializations
The function template specializations for this function template, including explicit specializations ...
Definition: DeclTemplate.h:968
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.
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 ...