clang 22.0.0git
DeclTemplate.cpp
Go to the documentation of this file.
1//===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the C++ related Decl classes for templates.
10//
11//===----------------------------------------------------------------------===//
12
16#include "clang/AST/DeclCXX.h"
18#include "clang/AST/Expr.h"
19#include "clang/AST/ExprCXX.h"
21#include "clang/AST/ODRHash.h"
24#include "clang/AST/Type.h"
25#include "clang/AST/TypeLoc.h"
27#include "clang/Basic/LLVM.h"
29#include "llvm/ADT/ArrayRef.h"
30#include "llvm/ADT/FoldingSet.h"
31#include "llvm/ADT/PointerUnion.h"
32#include "llvm/ADT/STLExtras.h"
33#include "llvm/ADT/SmallVector.h"
34#include "llvm/Support/ErrorHandling.h"
35#include <cassert>
36#include <optional>
37#include <utility>
38
39using namespace clang;
40
41//===----------------------------------------------------------------------===//
42// TemplateParameterList Implementation
43//===----------------------------------------------------------------------===//
44
45template <class TemplateParam>
46static bool
48 return P.hasDefaultArgument() &&
49 P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
50}
51
53 SourceLocation TemplateLoc,
54 SourceLocation LAngleLoc,
56 SourceLocation RAngleLoc,
57 Expr *RequiresClause)
58 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
59 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
60 HasRequiresClause(RequiresClause != nullptr),
61 HasConstrainedParameters(false) {
62 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
63 NamedDecl *P = Params[Idx];
64 begin()[Idx] = P;
65
66 bool IsPack = P->isTemplateParameterPack();
67 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
68 if (!IsPack && (NTTP->getType()->containsUnexpandedParameterPack() ||
70 ContainsUnexpandedParameterPack = true;
71 if (NTTP->hasPlaceholderTypeConstraint())
72 HasConstrainedParameters = true;
73 } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
74 if (!IsPack &&
75 (TTP->getTemplateParameters()->containsUnexpandedParameterPack() ||
77 ContainsUnexpandedParameterPack = true;
78 }
79 } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
81 ContainsUnexpandedParameterPack = true;
82 } else if (const TypeConstraint *TC = TTP->getTypeConstraint();
85 ContainsUnexpandedParameterPack = true;
86 }
87 if (TTP->hasTypeConstraint())
88 HasConstrainedParameters = true;
89 } else {
90 llvm_unreachable("unexpected template parameter type");
91 }
92 }
93
94 if (HasRequiresClause) {
95 if (RequiresClause->containsUnexpandedParameterPack())
96 ContainsUnexpandedParameterPack = true;
97 *getTrailingObjects<Expr *>() = RequiresClause;
98 }
99}
100
102 if (ContainsUnexpandedParameterPack)
103 return true;
104 if (!HasConstrainedParameters)
105 return false;
106
107 // An implicit constrained parameter might have had a use of an unexpanded
108 // pack added to it after the template parameter list was created. All
109 // implicit parameters are at the end of the parameter list.
110 for (const NamedDecl *Param : llvm::reverse(asArray())) {
111 if (!Param->isImplicit())
112 break;
113
114 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
115 const auto *TC = TTP->getTypeConstraint();
116 if (TC && TC->getImmediatelyDeclaredConstraint()
117 ->containsUnexpandedParameterPack())
118 return true;
119 }
120 }
121
122 return false;
123}
124
127 SourceLocation LAngleLoc,
129 SourceLocation RAngleLoc, Expr *RequiresClause) {
130 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
131 Params.size(), RequiresClause ? 1u : 0u),
132 alignof(TemplateParameterList));
133 return new (Mem) TemplateParameterList(C, TemplateLoc, LAngleLoc, Params,
134 RAngleLoc, RequiresClause);
135}
136
137void TemplateParameterList::Profile(llvm::FoldingSetNodeID &ID,
138 const ASTContext &C) const {
139 const Expr *RC = getRequiresClause();
140 ID.AddBoolean(RC != nullptr);
141 if (RC)
142 RC->Profile(ID, C, /*Canonical=*/true);
143 ID.AddInteger(size());
144 for (NamedDecl *D : *this) {
145 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
146 ID.AddInteger(0);
147 ID.AddBoolean(NTTP->isParameterPack());
148 NTTP->getType().getCanonicalType().Profile(ID);
149 ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint());
150 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
151 E->Profile(ID, C, /*Canonical=*/true);
152 continue;
153 }
154 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {
155 ID.AddInteger(1);
156 ID.AddBoolean(TTP->isParameterPack());
157 ID.AddBoolean(TTP->hasTypeConstraint());
158 if (const TypeConstraint *TC = TTP->getTypeConstraint())
159 TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,
160 /*Canonical=*/true);
161 continue;
162 }
163 const auto *TTP = cast<TemplateTemplateParmDecl>(D);
164 ID.AddInteger(2);
165 ID.AddInteger(TTP->templateParameterKind());
166 ID.AddBoolean(TTP->isParameterPack());
167 TTP->getTemplateParameters()->Profile(ID, C);
168 }
169}
170
172 unsigned NumRequiredArgs = 0;
173 for (const NamedDecl *P : asArray()) {
174 if (P->isTemplateParameterPack()) {
175 if (UnsignedOrNone Expansions = getExpandedPackSize(P)) {
176 NumRequiredArgs += *Expansions;
177 continue;
178 }
179 break;
180 }
181
182 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
183 if (TTP->hasDefaultArgument())
184 break;
185 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
186 if (NTTP->hasDefaultArgument())
187 break;
188 } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P);
189 TTP && TTP->hasDefaultArgument())
190 break;
191
192 ++NumRequiredArgs;
193 }
194
195 return NumRequiredArgs;
196}
197
198unsigned TemplateParameterList::getDepth() const {
199 if (size() == 0)
200 return 0;
201
202 const NamedDecl *FirstParm = getParam(0);
203 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
204 return TTP->getDepth();
205 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
206 return NTTP->getDepth();
207 else
208 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
209}
210
212 DeclContext *Owner) {
213 bool Invalid = false;
214 for (NamedDecl *P : *Params) {
215 P->setDeclContext(Owner);
216
217 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
218 if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner))
219 Invalid = true;
220
221 if (P->isInvalidDecl())
222 Invalid = true;
223 }
224 return Invalid;
225}
226
229 if (HasConstrainedParameters)
230 for (const NamedDecl *Param : *this) {
231 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
232 if (const auto *TC = TTP->getTypeConstraint())
233 ACs.emplace_back(TC->getImmediatelyDeclaredConstraint(),
234 TC->getArgPackSubstIndex());
235 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
236 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
237 ACs.emplace_back(E);
238 }
239 }
240 if (HasRequiresClause)
241 ACs.emplace_back(getRequiresClause());
242}
243
245 return HasRequiresClause || HasConstrainedParameters;
246}
247
250 if (!InjectedArgs) {
251 InjectedArgs = new (Context) TemplateArgument[size()];
252 llvm::transform(*this, InjectedArgs, [&](NamedDecl *ND) {
253 return Context.getInjectedTemplateArg(ND);
254 });
255 }
256 return {InjectedArgs, NumParams};
257}
258
260 const PrintingPolicy &Policy, const TemplateParameterList *TPL,
261 unsigned Idx) {
262 if (!TPL || Idx >= TPL->size() || Policy.AlwaysIncludeTypeForTemplateArgument)
263 return true;
264 const NamedDecl *TemplParam = TPL->getParam(Idx);
265 if (const auto *ParamValueDecl =
266 dyn_cast<NonTypeTemplateParmDecl>(TemplParam))
267 if (ParamValueDecl->getType()->getContainedDeducedType())
268 return true;
269 return false;
270}
271
272namespace clang {
273
275 return new (C) char[sizeof(void*) * 2];
276}
277
278} // namespace clang
279
280//===----------------------------------------------------------------------===//
281// TemplateDecl Implementation
282//===----------------------------------------------------------------------===//
283
288
289void TemplateDecl::anchor() {}
290
293 TemplateParams->getAssociatedConstraints(ACs);
294 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
295 if (const AssociatedConstraint &TRC = FD->getTrailingRequiresClause())
296 ACs.emplace_back(TRC);
297}
298
300 if (TemplateParams->hasAssociatedConstraints())
301 return true;
302 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
303 return static_cast<bool>(FD->getTrailingRequiresClause());
304 return false;
305}
306
308 switch (getKind()) {
309 case TemplateDecl::TypeAliasTemplate:
310 return true;
311 case TemplateDecl::BuiltinTemplate:
312 return !cast<BuiltinTemplateDecl>(this)->isPackProducingBuiltinTemplate();
313 default:
314 return false;
315 };
316}
317
318//===----------------------------------------------------------------------===//
319// RedeclarableTemplateDecl Implementation
320//===----------------------------------------------------------------------===//
321
322void RedeclarableTemplateDecl::anchor() {}
323
325 if (Common)
326 return Common;
327
328 // Walk the previous-declaration chain until we either find a declaration
329 // with a common pointer or we run out of previous declarations.
331 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
332 Prev = Prev->getPreviousDecl()) {
333 if (Prev->Common) {
334 Common = Prev->Common;
335 break;
336 }
337
338 PrevDecls.push_back(Prev);
339 }
340
341 // If we never found a common pointer, allocate one now.
342 if (!Common) {
343 // FIXME: If any of the declarations is from an AST file, we probably
344 // need an update record to add the common data.
345
347 }
348
349 // Update any previous declarations we saw with the common pointer.
350 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
351 Prev->Common = Common;
352
353 return Common;
354}
355
357 bool OnlyPartial /*=false*/) const {
359 if (!ExternalSource)
360 return;
361
363 OnlyPartial);
364}
365
369 if (!ExternalSource)
370 return false;
371
372 // If TPL is not null, it implies that we're loading specializations for
373 // partial templates. We need to load all specializations in such cases.
374 if (TPL)
376 /*OnlyPartial=*/false);
377
379 Args);
380}
381
382template <class EntryType, typename... ProfileArguments>
385 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
386 ProfileArguments... ProfileArgs) {
388
389 llvm::FoldingSetNodeID ID;
390 EntryType::Profile(ID, ProfileArgs..., getASTContext());
391 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
392 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
393}
394
395template <class EntryType, typename... ProfileArguments>
398 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
399 ProfileArguments... ProfileArgs) {
400
401 if (auto *Found = findSpecializationLocally(Specs, InsertPos, ProfileArgs...))
402 return Found;
403
404 if (!loadLazySpecializationsImpl(ProfileArgs...))
405 return nullptr;
406
407 return findSpecializationLocally(Specs, InsertPos, ProfileArgs...);
408}
409
410template<class Derived, class EntryType>
412 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
413 void *InsertPos) {
414 using SETraits = SpecEntryTraits<EntryType>;
415
416 if (InsertPos) {
417#ifndef NDEBUG
418 auto Args = SETraits::getTemplateArgs(Entry);
419 // Due to hash collisions, it can happen that we load another template
420 // specialization with the same hash. This is fine, as long as the next
421 // call to findSpecializationImpl does not find a matching Decl for the
422 // template arguments.
424 void *CorrectInsertPos;
425 assert(!findSpecializationImpl(Specializations, CorrectInsertPos, Args) &&
426 InsertPos == CorrectInsertPos &&
427 "given incorrect InsertPos for specialization");
428#endif
429 Specializations.InsertNode(Entry, InsertPos);
430 } else {
431 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
432 (void)Existing;
433 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
434 "non-canonical specialization?");
435 }
436
438 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
439 SETraits::getDecl(Entry));
440}
441
442//===----------------------------------------------------------------------===//
443// FunctionTemplateDecl Implementation
444//===----------------------------------------------------------------------===//
445
448 DeclarationName Name,
451 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
452 if (Invalid)
453 TD->setInvalidDecl();
454 return TD;
455}
456
459 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
460 DeclarationName(), nullptr, nullptr);
461}
462
465 auto *CommonPtr = new (C) Common;
466 C.addDestruction(CommonPtr);
467 return CommonPtr;
468}
469
473
474llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
479
482 void *&InsertPos) {
483 auto *Common = getCommonPtr();
484 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
485}
486
493
496
497 // If we haven't created a common pointer yet, then it can just be created
498 // with the usual method.
499 if (!Base::Common)
500 return;
501
502 Common *ThisCommon = static_cast<Common *>(Base::Common);
503 Common *PrevCommon = nullptr;
505 for (; Prev; Prev = Prev->getPreviousDecl()) {
506 if (Prev->Base::Common) {
507 PrevCommon = static_cast<Common *>(Prev->Base::Common);
508 break;
509 }
510 PreviousDecls.push_back(Prev);
511 }
512
513 // If the previous redecl chain hasn't created a common pointer yet, then just
514 // use this common pointer.
515 if (!PrevCommon) {
516 for (auto *D : PreviousDecls)
517 D->Base::Common = ThisCommon;
518 return;
519 }
520
521 // Ensure we don't leak any important state.
522 assert(ThisCommon->Specializations.size() == 0 &&
523 "Can't merge incompatible declarations!");
524
525 Base::Common = PrevCommon;
526}
527
528//===----------------------------------------------------------------------===//
529// ClassTemplateDecl Implementation
530//===----------------------------------------------------------------------===//
531
534 DeclarationName Name,
535 TemplateParameterList *Params,
536 NamedDecl *Decl) {
538 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
539 if (Invalid)
540 TD->setInvalidDecl();
541 return TD;
542}
543
545 GlobalDeclID ID) {
546 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
547 DeclarationName(), nullptr, nullptr);
548}
549
551 bool OnlyPartial /*=false*/) const {
552 loadLazySpecializationsImpl(OnlyPartial);
553}
554
555llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
560
561llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
566
569 auto *CommonPtr = new (C) Common;
570 C.addDestruction(CommonPtr);
571 return CommonPtr;
572}
573
576 void *&InsertPos) {
577 auto *Common = getCommonPtr();
578 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
579}
580
587
595
597 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
598 TemplateParameterList *TPL, const ASTContext &Context) {
599 ID.AddInteger(TemplateArgs.size());
600 for (const TemplateArgument &TemplateArg : TemplateArgs)
601 TemplateArg.Profile(ID, Context);
602 TPL->Profile(ID, Context);
603}
604
607 void *InsertPos) {
608 if (InsertPos)
609 getPartialSpecializations().InsertNode(D, InsertPos);
610 else {
612 = getPartialSpecializations().GetOrInsertNode(D);
613 (void)Existing;
614 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
615 }
616
618 L->AddedCXXTemplateSpecialization(this, D);
619}
620
623 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
625 PS.clear();
626 PS.reserve(PartialSpecs.size());
627 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
628 PS.push_back(P.getMostRecentDecl());
629}
630
633 ASTContext &Context = getASTContext();
636 if (Context.hasSameType(P.getCanonicalInjectedSpecializationType(Context),
637 T))
638 return P.getMostRecentDecl();
639 }
640
641 return nullptr;
642}
643
647 Decl *DCanon = D->getCanonicalDecl();
649 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
650 return P.getMostRecentDecl();
651 }
652
653 return nullptr;
654}
655
672
673//===----------------------------------------------------------------------===//
674// TemplateTypeParm Allocation/Deallocation Method Implementations
675//===----------------------------------------------------------------------===//
676
677TemplateTypeParmDecl *TemplateTypeParmDecl::Create(
678 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
679 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
680 bool Typename, bool ParameterPack, bool HasTypeConstraint,
681 UnsignedOrNone NumExpanded) {
682 auto *TTPDecl =
683 new (C, DC,
684 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
685 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
686 HasTypeConstraint, NumExpanded);
687 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
688 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
689 return TTPDecl;
690}
691
694 return new (C, ID)
695 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
696 false, false, std::nullopt);
697}
698
701 bool HasTypeConstraint) {
702 return new (C, ID,
703 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
704 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
705 false, HasTypeConstraint, std::nullopt);
706}
707
712
715 return SourceRange(getBeginLoc(),
717 // TypeDecl::getSourceRange returns a range containing name location, which is
718 // wrong for unnamed template parameters. e.g:
719 // it will return <[[typename>]] instead of <[[typename]]>
720 if (getDeclName().isEmpty())
721 return SourceRange(getBeginLoc());
723}
724
726 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
727 if (DefArg.getArgument().isNull())
728 DefaultArgument.set(nullptr);
729 else
730 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
731}
732
734 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->getDepth();
735}
736
738 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->getIndex();
739}
740
742 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->isParameterPack();
743}
744
746 ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint,
747 UnsignedOrNone ArgPackSubstIndex) {
748 assert(HasTypeConstraint &&
749 "HasTypeConstraint=true must be passed at construction in order to "
750 "call setTypeConstraint");
751 assert(!TypeConstraintInitialized &&
752 "TypeConstraint was already initialized!");
753 new (getTrailingObjects())
754 TypeConstraint(Loc, ImmediatelyDeclaredConstraint, ArgPackSubstIndex);
755 TypeConstraintInitialized = true;
756}
757
758//===----------------------------------------------------------------------===//
759// NonTypeTemplateParmDecl Method Implementations
760//===----------------------------------------------------------------------===//
761
762NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
763 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
764 unsigned P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
765 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
766 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
767 TemplateParmPosition(D, P), ParameterPack(true),
768 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
769 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
770 auto TypesAndInfos =
771 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
772 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
773 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
774 TypesAndInfos[I].second = ExpandedTInfos[I];
775 }
776 }
777}
778
779NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
780 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
781 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
782 QualType T, bool ParameterPack, TypeSourceInfo *TInfo) {
783 AutoType *AT =
784 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
785 const bool HasConstraint = AT && AT->isConstrained();
786 auto *NTTP =
787 new (C, DC,
788 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
789 0, HasConstraint ? 1 : 0))
790 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T,
791 ParameterPack, TInfo);
792 if (HasConstraint)
793 NTTP->setPlaceholderTypeConstraint(nullptr);
794 return NTTP;
795}
796
797NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
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 const bool HasConstraint = AT && AT->isConstrained();
804 auto *NTTP =
805 new (C, DC,
806 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
807 ExpandedTypes.size(), HasConstraint ? 1 : 0))
808 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
809 ExpandedTypes, ExpandedTInfos);
810 if (HasConstraint)
811 NTTP->setPlaceholderTypeConstraint(nullptr);
812 return NTTP;
813}
814
817 bool HasTypeConstraint) {
818 auto *NTTP =
819 new (C, ID,
820 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
821 0, HasTypeConstraint ? 1 : 0))
822 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
823 0, 0, nullptr, QualType(), false, nullptr);
824 if (HasTypeConstraint)
825 NTTP->setPlaceholderTypeConstraint(nullptr);
826 return NTTP;
827}
828
831 unsigned NumExpandedTypes,
832 bool HasTypeConstraint) {
833 auto *NTTP =
834 new (C, ID,
835 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
836 NumExpandedTypes, HasTypeConstraint ? 1 : 0))
837 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
838 0, 0, nullptr, QualType(), nullptr, {}, {});
839 NTTP->NumExpandedTypes = NumExpandedTypes;
840 if (HasTypeConstraint)
841 NTTP->setPlaceholderTypeConstraint(nullptr);
842 return NTTP;
843}
844
851
856
858 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
859 if (DefArg.getArgument().isNull())
860 DefaultArgument.set(nullptr);
861 else
862 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
863}
864
865//===----------------------------------------------------------------------===//
866// TemplateTemplateParmDecl Method Implementations
867//===----------------------------------------------------------------------===//
868
869void TemplateTemplateParmDecl::anchor() {}
870
871TemplateTemplateParmDecl::TemplateTemplateParmDecl(
872 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
875 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
876 TemplateParmPosition(D, P), ParameterKind(Kind), Typename(Typename),
877 ParameterPack(true), ExpandedParameterPack(true),
878 NumExpandedParams(Expansions.size()) {
879 llvm::uninitialized_copy(Expansions, getTrailingObjects());
880}
881
882TemplateTemplateParmDecl *TemplateTemplateParmDecl::Create(
883 const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
884 unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateNameKind Kind,
885 bool Typename, TemplateParameterList *Params) {
886 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
887 Kind, Typename, Params);
888}
889
892 SourceLocation L, unsigned D, unsigned P,
894 bool Typename, TemplateParameterList *Params,
896 return new (C, DC,
897 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
898 TemplateTemplateParmDecl(DC, L, D, P, Id, Kind, Typename, Params,
899 Expansions);
900}
901
904 return new (C, ID) TemplateTemplateParmDecl(
905 nullptr, SourceLocation(), 0, 0, false, nullptr,
907}
908
911 unsigned NumExpansions) {
912 auto *TTP =
913 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
914 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
916 nullptr, {});
917 TTP->NumExpandedParams = NumExpansions;
918 return TTP;
919}
920
925
927 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
928 if (DefArg.getArgument().isNull())
929 DefaultArgument.set(nullptr);
930 else
931 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
932}
933
934//===----------------------------------------------------------------------===//
935// TemplateArgumentList Implementation
936//===----------------------------------------------------------------------===//
937TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
938 : NumArguments(Args.size()) {
939 llvm::uninitialized_copy(Args, getTrailingObjects());
940}
941
945 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
946 return new (Mem) TemplateArgumentList(Args);
947}
948
949FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
952 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
953 MemberSpecializationInfo *MSInfo) {
954 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
955 if (TemplateArgsAsWritten)
957 *TemplateArgsAsWritten);
958
959 void *Mem =
960 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
961 return new (Mem) FunctionTemplateSpecializationInfo(
962 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
963}
964
965//===----------------------------------------------------------------------===//
966// ClassTemplateSpecializationDecl Implementation
967//===----------------------------------------------------------------------===//
968
970 ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC,
971 SourceLocation StartLoc, SourceLocation IdLoc,
972 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
973 bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)
974 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
975 SpecializedTemplate->getIdentifier(), PrevDecl),
976 SpecializedTemplate(SpecializedTemplate),
977 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
978 SpecializationKind(TSK_Undeclared), StrictPackMatch(StrictPackMatch) {
979 assert(DK == Kind::ClassTemplateSpecialization || StrictPackMatch == false);
980}
981
987
989 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
990 SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate,
991 ArrayRef<TemplateArgument> Args, bool StrictPackMatch,
993 auto *Result = new (Context, DC) ClassTemplateSpecializationDecl(
994 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
995 SpecializedTemplate, Args, StrictPackMatch, PrevDecl);
996
997 // If the template decl is incomplete, copy the external lexical storage from
998 // the base template. This allows instantiations of incomplete types to
999 // complete using the external AST if the template's declaration came from an
1000 // external AST.
1001 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
1002 Result->setHasExternalLexicalStorage(
1003 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
1004
1005 return Result;
1006}
1007
1010 GlobalDeclID ID) {
1011 return new (C, ID)
1012 ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
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) {
1022 printTemplateArgumentList(
1023 OS, ArgsAsWritten->arguments(), Policy,
1024 getSpecializedTemplate()->getTemplateParameters());
1025 } else {
1026 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1027 printTemplateArgumentList(
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 dyn_cast<ClassTemplatePartialSpecializationDecl *>(Pattern))
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 = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
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
1093 SourceLocation Loc) {
1094 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
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,
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
1144ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create(
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))
1156 ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);
1157}
1158
1160 ArrayRef<TemplateArgument> Converted) {
1161 assert(Converted.size() == NumTemplateArgs);
1162 llvm::uninitialized_copy(Converted, getTrailingObjects());
1163}
1164
1165//===----------------------------------------------------------------------===//
1166// ClassTemplatePartialSpecializationDecl Implementation
1167//===----------------------------------------------------------------------===//
1168void ClassTemplatePartialSpecializationDecl::anchor() {}
1169
1170ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
1171 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1173 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1174 CanQualType CanonInjectedTST,
1177 Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
1178 // Tracking StrictPackMatch for Partial
1179 // Specializations is not needed.
1180 SpecializedTemplate, Args, /*StrictPackMatch=*/false, PrevDecl),
1181 TemplateParams(Params), InstantiatedFromMember(nullptr, false),
1182 CanonInjectedTST(CanonInjectedTST) {
1183 if (AdoptTemplateParameterList(Params, this))
1185}
1186
1189 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1191 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1192 CanQualType CanonInjectedTST,
1193 ClassTemplatePartialSpecializationDecl *PrevDecl) {
1194 auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl(
1195 Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args,
1196 CanonInjectedTST, PrevDecl);
1197 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1198 return Result;
1199}
1200
1203 GlobalDeclID ID) {
1204 return new (C, ID) ClassTemplatePartialSpecializationDecl(C);
1205}
1206
1209 const ASTContext &Ctx) const {
1210 if (CanonInjectedTST.isNull()) {
1211 CanonInjectedTST =
1215 getTemplateArgs().asArray()));
1216 }
1217 return CanonInjectedTST;
1218}
1219
1221 if (const ClassTemplatePartialSpecializationDecl *MT =
1223 MT && !isMemberSpecialization())
1224 return MT->getSourceRange();
1228 Range.setBegin(TPL->getTemplateLoc());
1229 return Range;
1230}
1231
1232//===----------------------------------------------------------------------===//
1233// FriendTemplateDecl Implementation
1234//===----------------------------------------------------------------------===//
1235
1236void FriendTemplateDecl::anchor() {}
1237
1242 FriendUnion Friend, SourceLocation FLoc) {
1243 TemplateParameterList **TPL = nullptr;
1244 if (!Params.empty()) {
1245 TPL = new (Context) TemplateParameterList *[Params.size()];
1246 llvm::copy(Params, TPL);
1247 }
1248 return new (Context, DC)
1249 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
1250}
1251
1253 GlobalDeclID ID) {
1254 return new (C, ID) FriendTemplateDecl(EmptyShell());
1255}
1256
1257//===----------------------------------------------------------------------===//
1258// TypeAliasTemplateDecl Implementation
1259//===----------------------------------------------------------------------===//
1260
1263 DeclarationName Name,
1265 bool Invalid = AdoptTemplateParameterList(Params, DC);
1266 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1267 if (Invalid)
1268 TD->setInvalidDecl();
1269 return TD;
1270}
1271
1274 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1275 DeclarationName(), nullptr, nullptr);
1276}
1277
1280 auto *CommonPtr = new (C) Common;
1281 C.addDestruction(CommonPtr);
1282 return CommonPtr;
1283}
1284
1285//===----------------------------------------------------------------------===//
1286// VarTemplateDecl Implementation
1287//===----------------------------------------------------------------------===//
1288
1290 VarTemplateDecl *CurD = this;
1291 while (CurD) {
1292 if (CurD->isThisDeclarationADefinition())
1293 return CurD;
1294 CurD = CurD->getPreviousDecl();
1295 }
1296 return nullptr;
1297}
1298
1301 TemplateParameterList *Params,
1302 VarDecl *Decl) {
1303 bool Invalid = AdoptTemplateParameterList(Params, DC);
1304 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1305 if (Invalid)
1306 TD->setInvalidDecl();
1307 return TD;
1308}
1309
1311 GlobalDeclID ID) {
1312 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1313 DeclarationName(), nullptr, nullptr);
1314}
1315
1317 bool OnlyPartial /*=false*/) const {
1318 loadLazySpecializationsImpl(OnlyPartial);
1319}
1320
1321llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1326
1327llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1332
1335 auto *CommonPtr = new (C) Common;
1336 C.addDestruction(CommonPtr);
1337 return CommonPtr;
1338}
1339
1342 void *&InsertPos) {
1343 auto *Common = getCommonPtr();
1344 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
1345}
1346
1352
1359
1361 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1362 TemplateParameterList *TPL, const ASTContext &Context) {
1363 ID.AddInteger(TemplateArgs.size());
1364 for (const TemplateArgument &TemplateArg : TemplateArgs)
1365 TemplateArg.Profile(ID, Context);
1366 TPL->Profile(ID, Context);
1367}
1368
1370 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1371 if (InsertPos)
1372 getPartialSpecializations().InsertNode(D, InsertPos);
1373 else {
1375 getPartialSpecializations().GetOrInsertNode(D);
1376 (void)Existing;
1377 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1378 }
1379
1381 L->AddedCXXTemplateSpecialization(this, D);
1382}
1383
1386 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1388 PS.clear();
1389 PS.reserve(PartialSpecs.size());
1390 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1391 PS.push_back(P.getMostRecentDecl());
1392}
1393
1397 Decl *DCanon = D->getCanonicalDecl();
1399 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1400 return P.getMostRecentDecl();
1401 }
1402
1403 return nullptr;
1404}
1405
1406//===----------------------------------------------------------------------===//
1407// VarTemplateSpecializationDecl Implementation
1408//===----------------------------------------------------------------------===//
1409
1411 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1412 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1414 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1415 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1416 SpecializedTemplate(SpecializedTemplate),
1417 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1418 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1419
1421 ASTContext &C)
1424 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1425
1427 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1428 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1430 return new (Context, DC) VarTemplateSpecializationDecl(
1431 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1432 SpecializedTemplate, T, TInfo, S, Args);
1433}
1434
1437 GlobalDeclID ID) {
1438 return new (C, ID)
1439 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1440}
1441
1443 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1445
1446 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1447 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1448 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1449 printTemplateArgumentList(
1450 OS, ArgsAsWritten->arguments(), Policy,
1451 getSpecializedTemplate()->getTemplateParameters());
1452 } else {
1453 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1454 printTemplateArgumentList(
1455 OS, TemplateArgs.asArray(), Policy,
1456 getSpecializedTemplate()->getTemplateParameters());
1457 }
1458}
1459
1461 if (const auto *PartialSpec =
1462 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1463 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1464 return cast<VarTemplateDecl *>(SpecializedTemplate);
1465}
1466
1468 switch (getSpecializationKind()) {
1469 case TSK_Undeclared:
1471 llvm::PointerUnion<VarTemplateDecl *,
1474 assert(!Pattern.isNull() &&
1475 "Variable template specialization without pattern?");
1476 if (const auto *VTPSD =
1477 dyn_cast<VarTemplatePartialSpecializationDecl *>(Pattern))
1478 return VTPSD->getSourceRange();
1480 if (hasInit()) {
1482 return Definition->getSourceRange();
1483 }
1484 return VTD->getCanonicalDecl()->getSourceRange();
1485 }
1489 !hasInit() && Args)
1490 Range.setEnd(Args->getRAngleLoc());
1491 return Range;
1492 }
1496 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1497 Range.setBegin(ExternKW);
1498 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1499 TemplateKW.isValid())
1500 Range.setBegin(TemplateKW);
1502 Range.setEnd(Args->getRAngleLoc());
1503 return Range;
1504 }
1505 }
1506 llvm_unreachable("unhandled template specialization kind");
1507}
1508
1510 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1511 if (!Info) {
1512 // Don't allocate if the location is invalid.
1513 if (Loc.isInvalid())
1514 return;
1517 ExplicitInfo = Info;
1518 }
1519 Info->ExternKeywordLoc = Loc;
1520}
1521
1523 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1524 if (!Info) {
1525 // Don't allocate if the location is invalid.
1526 if (Loc.isInvalid())
1527 return;
1530 ExplicitInfo = Info;
1531 }
1532 Info->TemplateKeywordLoc = Loc;
1533}
1534
1535//===----------------------------------------------------------------------===//
1536// VarTemplatePartialSpecializationDecl Implementation
1537//===----------------------------------------------------------------------===//
1538
1539void VarTemplatePartialSpecializationDecl::anchor() {}
1540
1541VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1542 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1544 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1546 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1547 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1548 TInfo, S, Args),
1549 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1550 if (AdoptTemplateParameterList(Params, DC))
1552}
1553
1556 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1558 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1560 auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(
1561 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,
1562 Args);
1563 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1564 return Result;
1565}
1566
1569 GlobalDeclID ID) {
1570 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1571}
1572
1574 if (const VarTemplatePartialSpecializationDecl *MT =
1576 MT && !isMemberSpecialization())
1577 return MT->getSourceRange();
1581 Range.setBegin(TPL->getTemplateLoc());
1582 return Range;
1583}
1584
1586 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1587 switch (BTK) {
1588#define CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST
1589#include "clang/Basic/BuiltinTemplates.inc"
1590 }
1591
1592 llvm_unreachable("unhandled BuiltinTemplateKind!");
1593}
1594
1595void BuiltinTemplateDecl::anchor() {}
1596
1597BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1598 DeclarationName Name,
1602 BTK(BTK) {}
1603
1605 return getBuiltinTemplateKind() == clang::BTK__builtin_dedup_pack;
1606}
1607
1609 auto *T = dyn_cast_or_null<BuiltinTemplateDecl>(
1610 N.getAsTemplateDecl(/*IgnoreDeduced=*/true));
1611 return T && T->isPackProducingBuiltinTemplate();
1612}
1613
1614TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1615 QualType T,
1616 const APValue &V) {
1617 DeclContext *DC = C.getTranslationUnitDecl();
1618 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1619 C.addDestruction(&TPOD->Value);
1620 return TPOD;
1621}
1622
1624TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1625 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1626 C.addDestruction(&TPOD->Value);
1627 return TPOD;
1628}
1629
1630void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1631 const PrintingPolicy &Policy) const {
1632 OS << "<template param ";
1633 printAsExpr(OS, Policy);
1634 OS << ">";
1635}
1636
1637void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1638 printAsExpr(OS, getASTContext().getPrintingPolicy());
1639}
1640
1641void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1642 const PrintingPolicy &Policy) const {
1643 getType().getUnqualifiedType().print(OS, Policy);
1644 printAsInit(OS, Policy);
1645}
1646
1647void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1648 printAsInit(OS, getASTContext().getPrintingPolicy());
1649}
1650
1651void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1652 const PrintingPolicy &Policy) const {
1653 getValue().printPretty(OS, Policy, getType(), &getASTContext());
1654}
1655
1657 switch (D->getKind()) {
1658 case Decl::Kind::CXXRecord:
1659 return cast<CXXRecordDecl>(D)
1660 ->getDescribedTemplate()
1661 ->getTemplateParameters();
1662 case Decl::Kind::ClassTemplate:
1663 return cast<ClassTemplateDecl>(D)->getTemplateParameters();
1664 case Decl::Kind::ClassTemplateSpecialization: {
1665 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1666 auto P = CTSD->getSpecializedTemplateOrPartial();
1667 if (const auto *CTPSD =
1668 dyn_cast<ClassTemplatePartialSpecializationDecl *>(P))
1669 return CTPSD->getTemplateParameters();
1670 return cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1671 }
1672 case Decl::Kind::ClassTemplatePartialSpecialization:
1674 ->getTemplateParameters();
1675 case Decl::Kind::TypeAliasTemplate:
1676 return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
1677 case Decl::Kind::BuiltinTemplate:
1678 return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
1679 case Decl::Kind::CXXDeductionGuide:
1680 case Decl::Kind::CXXConversion:
1681 case Decl::Kind::CXXConstructor:
1682 case Decl::Kind::CXXDestructor:
1683 case Decl::Kind::CXXMethod:
1684 case Decl::Kind::Function:
1685 return cast<FunctionDecl>(D)
1686 ->getTemplateSpecializationInfo()
1687 ->getTemplate()
1688 ->getTemplateParameters();
1689 case Decl::Kind::FunctionTemplate:
1690 return cast<FunctionTemplateDecl>(D)->getTemplateParameters();
1691 case Decl::Kind::VarTemplate:
1692 return cast<VarTemplateDecl>(D)->getTemplateParameters();
1693 case Decl::Kind::VarTemplateSpecialization: {
1694 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1695 auto P = VTSD->getSpecializedTemplateOrPartial();
1696 if (const auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl *>(P))
1697 return VTPSD->getTemplateParameters();
1698 return cast<VarTemplateDecl *>(P)->getTemplateParameters();
1699 }
1700 case Decl::Kind::VarTemplatePartialSpecialization:
1702 ->getTemplateParameters();
1703 case Decl::Kind::TemplateTemplateParm:
1704 return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();
1705 case Decl::Kind::Concept:
1706 return cast<ConceptDecl>(D)->getTemplateParameters();
1707 default:
1708 llvm_unreachable("Unhandled templated declaration kind");
1709 }
1710}
Defines the clang::ASTContext interface.
#define V(N, I)
#define BuiltinTemplate(BTName)
Definition ASTContext.h:419
Defines enum values for all the target-independent builtin functions.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static bool DefaultTemplateArgumentContainsUnexpandedPack(const TemplateParam &P)
static bool AdoptTemplateParameterList(TemplateParameterList *Params, DeclContext *Owner)
static TemplateParameterList * createBuiltinTemplateParameterList(const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK)
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
This file contains the declaration of the ODRHash class, which calculates a hash based on AST nodes,...
static StringRef getIdentifier(const Token &Tok)
Defines the clang::SourceLocation class and associated facilities.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
Definition APValue.cpp:703
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:188
QualType getCanonicalTemplateSpecializationType(ElaboratedTypeKeyword Keyword, TemplateName T, ArrayRef< TemplateArgument > CanonicalArgs) const
TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl) const
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
bool canonicalizeTemplateArguments(MutableArrayRef< TemplateArgument > Args) const
Canonicalize the given template argument list.
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
BuiltinTemplateKind getBuiltinTemplateKind() const
bool isPackProducingBuiltinTemplate() const
CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl)
Definition DeclCXX.cpp:124
friend class DeclContext
Definition DeclCXX.h:266
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition DeclCXX.h:522
static CanQual< Type > CreateUnsafe(QualType Other)
bool isNull() const
Declaration of a class template.
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.
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...
ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
CommonBase * newCommon(ASTContext &C) const override
static ClassTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a class template node.
ClassTemplateDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
ClassTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *D)
Find a class template partial specialization which was instantiated from the given member partial spe...
void LoadLazySpecializations(bool OnlyPartial=false) const
Load any lazily-loaded specializations from the external source.
void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieve the canonical template specialization type of the injected-class-name for this class templat...
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...
CanQualType getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const
Retrieves the canonical injected specialization type for this partial specialization.
void Profile(llvm::FoldingSetNodeID &ID) const
bool isMemberSpecialization() const
Determines whether this class template partial specialization template was a specialization of a memb...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static ClassTemplatePartialSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, CanQualType CanonInjectedTST, ClassTemplatePartialSpecializationDecl *PrevDecl)
static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a class template specialization, which refers to a class template with a given set of temp...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
static ClassTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the class template or class template partial specialization which was specialized by this.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
static ClassTemplateSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
ConceptDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr)
static ConceptDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
static ConceptDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr=nullptr)
A reference to a concept and its template args, as it appears in the code.
Definition ASTConcept.h:126
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1449
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:524
ASTMutationListener * getASTMutationListener() const
Definition DeclBase.cpp:534
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition DeclBase.cpp:156
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:984
bool isInvalidDecl() const
Definition DeclBase.h:588
bool isTemplateParameterPack() const
isTemplateParameter - Determines whether this declaration is a template parameter pack.
Definition DeclBase.cpp:234
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
Definition DeclBase.cpp:360
friend class DeclContext
Definition DeclBase.h:252
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition DeclBase.h:978
Kind getKind() const
Definition DeclBase.h:442
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
Definition Decl.h:779
SourceLocation getOuterLocStart() const
Return start of source range taking into account any outer template declarations.
Definition Decl.cpp:2050
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2090
unsigned getNumTemplateParameterLists() const
Definition Decl.h:861
This represents one expression.
Definition Expr.h:112
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
Definition Expr.h:241
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:1999
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
Common * getCommonPtr() const
FunctionTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...
static FunctionTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty function template node.
FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
static FunctionTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
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 ...
static FunctionTemplateSpecializationInfo * Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs, const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI, MemberSpecializationInfo *MSInfo)
One of these records is kept for each identifier that is lexed.
void setTemplateArguments(ArrayRef< TemplateArgument > Converted)
static ImplicitConceptSpecializationDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef< TemplateArgument > ConvertedArgs)
static ImplicitConceptSpecializationDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs)
Provides information a specialization of a member of a class template, which may be a member function...
This represents a decl that may have a name.
Definition Decl.h:273
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:294
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
Definition Decl.h:285
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:339
NamedDecl * getMostRecentDecl()
Definition Decl.h:500
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:1834
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 setPlaceholderTypeConstraint(Expr *E)
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
A (possibly-)qualified type.
Definition TypeBase.h:937
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8285
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition TypeBase.h:8379
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
void loadLazySpecializationsImpl(bool OnlyPartial=false) const
CommonBase * getCommonPtr() const
Retrieves the "common" pointer shared by all (re-)declarations of the same template.
RedeclarableTemplateDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
CommonBase * Common
Pointer to the common data shared by all declarations of this template.
SpecEntryTraits< EntryType >::DeclType * findSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments... ProfileArgs)
virtual CommonBase * newCommon(ASTContext &C) const =0
RedeclarableTemplateDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this template.
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, void *InsertPos)
SpecEntryTraits< EntryType >::DeclType * findSpecializationLocally(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments... ProfileArgs)
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context) const
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
TagTypeKind TagKind
Definition Decl.h:3719
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition Decl.h:3804
unsigned getNumTemplateParameterLists() const
Definition Decl.h:3969
A convenient class for passing around template argument information.
A template argument list.
static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument list that copies the given set of template arguments.
Location wrapper for a TemplateArgument.
SourceLocation getLocation() const
const TemplateArgument & getArgument() const
SourceRange getSourceRange() const LLVM_READONLY
Represents a template argument.
bool isNull() const
Determine whether this template argument has no value.
The base class of all kinds of template declarations (e.g., class, function, etc.).
NamedDecl * TemplatedDecl
TemplateParameterList * TemplateParams
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
bool isTypeAlias() const
bool hasAssociatedConstraints() const
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
A template parameter object.
void printAsExpr(llvm::raw_ostream &OS) const
Print this object as an equivalent expression.
const APValue & getValue() const
void printName(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const override
Print this template parameter object in a human-readable format.
void printAsInit(llvm::raw_ostream &OS) const
Print this object as an initializer suitable for a variable of the object's type.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context)
Get the template argument list of the template parameter list.
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
bool hasAssociatedConstraints() const
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to form a template specialization.
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const
bool containsUnexpandedParameterPack() const
Determine whether this template parameter list contains an unexpanded parameter pack.
TemplateParameterList(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
void getAssociatedConstraints(llvm::SmallVectorImpl< AssociatedConstraint > &AC) const
All associated constraints derived from this template parameter list, including the requires clause a...
ArrayRef< NamedDecl * > asArray()
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
SourceLocation getTemplateLoc() const
Defines the position of a template parameter within a template parameter list.
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
static TemplateTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
static TemplateTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateNameKind ParameterKind, bool Typename, TemplateParameterList *Params)
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...
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
Declaration of a template type parameter.
SourceLocation getDefaultArgumentLoc() const
Retrieves the location of the default argument declaration.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
unsigned getIndex() const
Retrieve the index of the template parameter.
void setTypeConstraint(ConceptReference *CR, Expr *ImmediatelyDeclaredConstraint, UnsignedOrNone ArgPackSubstIndex)
static TemplateTypeParmDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID)
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.
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, UnsignedOrNone NumExpanded=std::nullopt)
unsigned getDepth() const
Retrieve the depth of the template parameter.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter.
Declaration of an alias template.
CommonBase * newCommon(ASTContext &C) const override
static TypeAliasTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty alias template node.
TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
static TypeAliasTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition ASTConcept.h:223
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Definition ASTConcept.h:240
const Type * getTypeForDecl() const
Definition Decl.h:3535
friend class ASTContext
Definition Decl.h:3511
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.h:3546
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:3544
A container of type source information.
Definition TypeBase.h:8256
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8267
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition TypeBase.h:2899
QualType getType() const
Definition Decl.h:722
Represents a variable declaration or definition.
Definition Decl.h:925
bool hasInit() const
Definition Decl.cpp:2398
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2190
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition Decl.cpp:2257
@ Definition
This declaration is definitely a definition.
Definition Decl.h:1300
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.
VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
static VarTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty variable template node.
static VarTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, VarDecl *Decl)
Create a variable template node.
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this variable template.
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.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isPackProducingBuiltinTemplateName(TemplateName N)
nullptr
This class represents a compute construct, representing a 'Kind' of β€˜parallel’, 'serial',...
StorageClass
Storage classes.
Definition Specifiers.h:248
@ SC_None
Definition Specifiers.h:250
UnsignedOrNone getExpandedPackSize(const NamedDecl *Param)
Check whether the template parameter is a pack expansion, and if so, determine the number of paramete...
void * allocateDefaultArgStorageChain(const ASTContext &C)
@ Result
The result type of a method or function.
Definition TypeBase.h:905
const FunctionProtoType * T
TagTypeKind
The kind of a tag type.
Definition TypeBase.h:5888
BuiltinTemplateKind
Kinds of BuiltinTemplateDecl.
Definition Builtins.h:462
TemplateNameKind
Specifies the kind of template name that an identifier refers to.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
TemplateParameterList * getReplacedTemplateParameterList(const Decl *D)
Internal helper used by Subst* nodes to retrieve the parameter list for their AssociatedDecl.
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
U cast(CodeGen::Address addr)
Definition Address.h:327
@ None
No keyword precedes the qualified type name.
Definition TypeBase.h:5884
@ Struct
The "struct" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5865
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
Definition TypeBase.h:5881
#define false
Definition stdbool.h:26
#define true
Definition stdbool.h:25
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
Data that is common to all of the declarations of a given class template.
CanQualType CanonInjectedTST
The Injected Template Specialization Type for this declaration.
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > PartialSpecializations
The class template partial specializations for this class template.
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > Specializations
The class template specializations for this class template, including explicit specializations and in...
A placeholder type used to construct an empty shell of a decl-derived type that will be filled in lat...
Definition DeclBase.h:102
Provides information about an explicit instantiation of a variable or class template.
const ASTTemplateArgumentListInfo * TemplateArgsAsWritten
The template arguments as written..
Data that is common to all of the declarations of a given function template.
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > Specializations
The function template specializations for this function template, including explicit specializations ...
Describes how types, statements, expressions, and declarations should be printed.
unsigned AlwaysIncludeTypeForTemplateArgument
Whether to use type suffixes (eg: 1U) on integral non-type template parameters.
Data that is common to all of the declarations of a given variable template.
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > PartialSpecializations
The variable template partial specializations for this variable template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > Specializations
The variable template specializations for this variable template, including explicit specializations ...