clang 23.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
375
376template <class EntryType, typename... ProfileArguments>
379 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
380 ProfileArguments... ProfileArgs) {
382
383 llvm::FoldingSetNodeID ID;
384 EntryType::Profile(ID, ProfileArgs..., getASTContext());
385 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
386 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
387}
388
389template <class EntryType, typename... ProfileArguments>
392 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
393 ProfileArguments... ProfileArgs) {
394
395 if (auto *Found = findSpecializationLocally(Specs, InsertPos, ProfileArgs...))
396 return Found;
397
398 if (!loadLazySpecializationsImpl(ProfileArgs...))
399 return nullptr;
400
401 return findSpecializationLocally(Specs, InsertPos, ProfileArgs...);
402}
403
404template<class Derived, class EntryType>
406 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
407 void *InsertPos) {
408 using SETraits = SpecEntryTraits<EntryType>;
409
410 if (InsertPos) {
411#ifndef NDEBUG
412 auto Args = SETraits::getTemplateArgs(Entry);
413 // Due to hash collisions, it can happen that we load another template
414 // specialization with the same hash. This is fine, as long as the next
415 // call to findSpecializationImpl does not find a matching Decl for the
416 // template arguments.
418 void *CorrectInsertPos;
419 assert(!findSpecializationImpl(Specializations, CorrectInsertPos, Args) &&
420 InsertPos == CorrectInsertPos &&
421 "given incorrect InsertPos for specialization");
422#endif
423 Specializations.InsertNode(Entry, InsertPos);
424 } else {
425 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
426 (void)Existing;
427 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
428 "non-canonical specialization?");
429 }
430
432 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
433 SETraits::getDecl(Entry));
434}
435
436//===----------------------------------------------------------------------===//
437// FunctionTemplateDecl Implementation
438//===----------------------------------------------------------------------===//
439
442 DeclarationName Name,
445 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
446 if (Invalid)
447 TD->setInvalidDecl();
448 return TD;
449}
450
453 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
454 DeclarationName(), nullptr, nullptr);
455}
456
459 auto *CommonPtr = new (C) Common;
460 C.addDestruction(CommonPtr);
461 return CommonPtr;
462}
463
467
468llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
473
476 void *&InsertPos) {
477 auto *Common = getCommonPtr();
478 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
479}
480
487
490
491 // If we haven't created a common pointer yet, then it can just be created
492 // with the usual method.
493 if (!Base::Common)
494 return;
495
496 Common *ThisCommon = static_cast<Common *>(Base::Common);
497 Common *PrevCommon = nullptr;
499 for (; Prev; Prev = Prev->getPreviousDecl()) {
500 if (Prev->Base::Common) {
501 PrevCommon = static_cast<Common *>(Prev->Base::Common);
502 break;
503 }
504 PreviousDecls.push_back(Prev);
505 }
506
507 // If the previous redecl chain hasn't created a common pointer yet, then just
508 // use this common pointer.
509 if (!PrevCommon) {
510 for (auto *D : PreviousDecls)
511 D->Base::Common = ThisCommon;
512 return;
513 }
514
515 // Ensure we don't leak any important state.
516 assert(ThisCommon->Specializations.size() == 0 &&
517 "Can't merge incompatible declarations!");
518
519 Base::Common = PrevCommon;
520}
521
522//===----------------------------------------------------------------------===//
523// ClassTemplateDecl Implementation
524//===----------------------------------------------------------------------===//
525
528 DeclarationName Name,
529 TemplateParameterList *Params,
530 NamedDecl *Decl) {
532 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
533 if (Invalid)
534 TD->setInvalidDecl();
535 return TD;
536}
537
539 GlobalDeclID ID) {
540 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
541 DeclarationName(), nullptr, nullptr);
542}
543
545 bool OnlyPartial /*=false*/) const {
546 loadLazySpecializationsImpl(OnlyPartial);
547}
548
549llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
554
555llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
560
563 auto *CommonPtr = new (C) Common;
564 C.addDestruction(CommonPtr);
565 return CommonPtr;
566}
567
570 void *&InsertPos) {
571 auto *Common = getCommonPtr();
572 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
573}
574
581
589
591 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
592 TemplateParameterList *TPL, const ASTContext &Context) {
593 ID.AddInteger(TemplateArgs.size());
594 for (const TemplateArgument &TemplateArg : TemplateArgs)
595 TemplateArg.Profile(ID, Context);
596 TPL->Profile(ID, Context);
597}
598
601 void *InsertPos) {
602 if (InsertPos)
603 getPartialSpecializations().InsertNode(D, InsertPos);
604 else {
606 = getPartialSpecializations().GetOrInsertNode(D);
607 (void)Existing;
608 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
609 }
610
612 L->AddedCXXTemplateSpecialization(this, D);
613}
614
617 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
619 PS.clear();
620 PS.reserve(PartialSpecs.size());
621 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
622 PS.push_back(P.getMostRecentDecl());
623}
624
627 ASTContext &Context = getASTContext();
630 if (Context.hasSameType(P.getCanonicalInjectedSpecializationType(Context),
631 T))
632 return P.getMostRecentDecl();
633 }
634
635 return nullptr;
636}
637
641 Decl *DCanon = D->getCanonicalDecl();
643 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
644 return P.getMostRecentDecl();
645 }
646
647 return nullptr;
648}
649
666
667//===----------------------------------------------------------------------===//
668// TemplateTypeParm Allocation/Deallocation Method Implementations
669//===----------------------------------------------------------------------===//
670
671TemplateTypeParmDecl *TemplateTypeParmDecl::Create(
672 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
673 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
674 bool Typename, bool ParameterPack, bool HasTypeConstraint,
675 UnsignedOrNone NumExpanded) {
676 auto *TTPDecl =
677 new (C, DC,
678 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
679 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
680 HasTypeConstraint, NumExpanded);
681 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
682 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
683 return TTPDecl;
684}
685
688 return new (C, ID)
689 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
690 false, false, std::nullopt);
691}
692
695 bool HasTypeConstraint) {
696 return new (C, ID,
697 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
698 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
699 false, HasTypeConstraint, std::nullopt);
700}
701
706
709 return SourceRange(getBeginLoc(),
711 // TypeDecl::getSourceRange returns a range containing name location, which is
712 // wrong for unnamed template parameters. e.g:
713 // it will return <[[typename>]] instead of <[[typename]]>
714 if (getDeclName().isEmpty())
715 return SourceRange(getBeginLoc());
717}
718
720 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
721 if (DefArg.getArgument().isNull())
722 DefaultArgument.set(nullptr);
723 else
724 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
725}
726
728 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->getDepth();
729}
730
732 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->getIndex();
733}
734
736 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->isParameterPack();
737}
738
740 ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint,
741 UnsignedOrNone ArgPackSubstIndex) {
742 assert(HasTypeConstraint &&
743 "HasTypeConstraint=true must be passed at construction in order to "
744 "call setTypeConstraint");
745 assert(!TypeConstraintInitialized &&
746 "TypeConstraint was already initialized!");
747 new (getTrailingObjects())
748 TypeConstraint(Loc, ImmediatelyDeclaredConstraint, ArgPackSubstIndex);
749 TypeConstraintInitialized = true;
750}
751
752//===----------------------------------------------------------------------===//
753// NonTypeTemplateParmDecl Method Implementations
754//===----------------------------------------------------------------------===//
755
756NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
757 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
758 unsigned P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
759 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
760 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
761 TemplateParmPosition(D, P), ParameterPack(true),
762 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
763 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
764 auto TypesAndInfos =
765 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
766 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
767 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
768 TypesAndInfos[I].second = ExpandedTInfos[I];
769 }
770 }
771}
772
773NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
774 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
775 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
776 QualType T, bool ParameterPack, TypeSourceInfo *TInfo) {
777 AutoType *AT =
778 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
779 const bool HasConstraint = AT && AT->isConstrained();
780 auto *NTTP =
781 new (C, DC,
782 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
783 0, HasConstraint ? 1 : 0))
784 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T,
785 ParameterPack, TInfo);
786 if (HasConstraint)
787 NTTP->setPlaceholderTypeConstraint(nullptr);
788 return NTTP;
789}
790
791NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
792 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
793 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
794 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
795 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
796 AutoType *AT = TInfo->getType()->getContainedAutoType();
797 const bool HasConstraint = AT && AT->isConstrained();
798 auto *NTTP =
799 new (C, DC,
800 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
801 ExpandedTypes.size(), HasConstraint ? 1 : 0))
802 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
803 ExpandedTypes, ExpandedTInfos);
804 if (HasConstraint)
805 NTTP->setPlaceholderTypeConstraint(nullptr);
806 return NTTP;
807}
808
811 bool HasTypeConstraint) {
812 auto *NTTP =
813 new (C, ID,
814 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
815 0, HasTypeConstraint ? 1 : 0))
816 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
817 0, 0, nullptr, QualType(), false, nullptr);
818 if (HasTypeConstraint)
819 NTTP->setPlaceholderTypeConstraint(nullptr);
820 return NTTP;
821}
822
825 unsigned NumExpandedTypes,
826 bool HasTypeConstraint) {
827 auto *NTTP =
828 new (C, ID,
829 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
830 NumExpandedTypes, HasTypeConstraint ? 1 : 0))
831 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
832 0, 0, nullptr, QualType(), nullptr, {}, {});
833 NTTP->NumExpandedTypes = NumExpandedTypes;
834 if (HasTypeConstraint)
835 NTTP->setPlaceholderTypeConstraint(nullptr);
836 return NTTP;
837}
838
845
850
852 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
853 if (DefArg.getArgument().isNull())
854 DefaultArgument.set(nullptr);
855 else
856 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
857}
858
859//===----------------------------------------------------------------------===//
860// TemplateTemplateParmDecl Method Implementations
861//===----------------------------------------------------------------------===//
862
863void TemplateTemplateParmDecl::anchor() {}
864
865TemplateTemplateParmDecl::TemplateTemplateParmDecl(
866 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
869 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
870 TemplateParmPosition(D, P), ParameterKind(Kind), Typename(Typename),
871 ParameterPack(true), ExpandedParameterPack(true),
872 NumExpandedParams(Expansions.size()) {
873 llvm::uninitialized_copy(Expansions, getTrailingObjects());
874}
875
876TemplateTemplateParmDecl *TemplateTemplateParmDecl::Create(
877 const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
878 unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateNameKind Kind,
879 bool Typename, TemplateParameterList *Params) {
880 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
881 Kind, Typename, Params);
882}
883
886 SourceLocation L, unsigned D, unsigned P,
888 bool Typename, TemplateParameterList *Params,
890 return new (C, DC,
891 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
892 TemplateTemplateParmDecl(DC, L, D, P, Id, Kind, Typename, Params,
893 Expansions);
894}
895
898 return new (C, ID) TemplateTemplateParmDecl(
899 nullptr, SourceLocation(), 0, 0, false, nullptr,
901}
902
905 unsigned NumExpansions) {
906 auto *TTP =
907 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
908 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
910 nullptr, {});
911 TTP->NumExpandedParams = NumExpansions;
912 return TTP;
913}
914
919
921 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
922 if (DefArg.getArgument().isNull())
923 DefaultArgument.set(nullptr);
924 else
925 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
926}
927
928//===----------------------------------------------------------------------===//
929// TemplateArgumentList Implementation
930//===----------------------------------------------------------------------===//
931TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
932 : NumArguments(Args.size()) {
933 llvm::uninitialized_copy(Args, getTrailingObjects());
934}
935
939 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
940 return new (Mem) TemplateArgumentList(Args);
941}
942
943FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
946 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
947 MemberSpecializationInfo *MSInfo) {
948 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
949 if (TemplateArgsAsWritten)
951 *TemplateArgsAsWritten);
952
953 void *Mem =
954 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
955 return new (Mem) FunctionTemplateSpecializationInfo(
956 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
957}
958
959//===----------------------------------------------------------------------===//
960// ClassTemplateSpecializationDecl Implementation
961//===----------------------------------------------------------------------===//
962
964 ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC,
965 SourceLocation StartLoc, SourceLocation IdLoc,
966 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
967 bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)
968 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
969 SpecializedTemplate->getIdentifier(), PrevDecl),
970 SpecializedTemplate(SpecializedTemplate),
971 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
972 SpecializationKind(TSK_Undeclared), StrictPackMatch(StrictPackMatch) {
973 assert(DK == Kind::ClassTemplateSpecialization || StrictPackMatch == false);
974}
975
981
983 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
984 SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate,
985 ArrayRef<TemplateArgument> Args, bool StrictPackMatch,
987 auto *Result = new (Context, DC) ClassTemplateSpecializationDecl(
988 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
989 SpecializedTemplate, Args, StrictPackMatch, PrevDecl);
990
991 // If the template decl is incomplete, copy the external lexical storage from
992 // the base template. This allows instantiations of incomplete types to
993 // complete using the external AST if the template's declaration came from an
994 // external AST.
995 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
996 Result->setHasExternalLexicalStorage(
997 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
998
999 return Result;
1000}
1001
1004 GlobalDeclID ID) {
1005 return new (C, ID)
1006 ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
1007}
1008
1010 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1012
1013 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
1014 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1015 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1016 printTemplateArgumentList(
1017 OS, ArgsAsWritten->arguments(), Policy,
1018 getSpecializedTemplate()->getTemplateParameters());
1019 } else {
1020 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1021 printTemplateArgumentList(
1022 OS, TemplateArgs.asArray(), Policy,
1023 getSpecializedTemplate()->getTemplateParameters());
1024 }
1025}
1026
1029 if (const auto *PartialSpec =
1030 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
1031 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1032 return cast<ClassTemplateDecl *>(SpecializedTemplate);
1033}
1034
1037 switch (getSpecializationKind()) {
1038 case TSK_Undeclared:
1040 llvm::PointerUnion<ClassTemplateDecl *,
1043 assert(!Pattern.isNull() &&
1044 "Class template specialization without pattern?");
1045 if (const auto *CTPSD =
1046 dyn_cast<ClassTemplatePartialSpecializationDecl *>(Pattern))
1047 return CTPSD->getSourceRange();
1048 return cast<ClassTemplateDecl *>(Pattern)->getSourceRange();
1049 }
1054 Range.setEnd(Args->getRAngleLoc());
1055 return Range;
1056 }
1060 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1061 Range.setBegin(ExternKW);
1062 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1063 TemplateKW.isValid())
1064 Range.setBegin(TemplateKW);
1066 Range.setEnd(Args->getRAngleLoc());
1067 return Range;
1068 }
1069 }
1070 llvm_unreachable("unhandled template specialization kind");
1071}
1072
1074 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1075 if (!Info) {
1076 // Don't allocate if the location is invalid.
1077 if (Loc.isInvalid())
1078 return;
1081 ExplicitInfo = Info;
1082 }
1083 Info->ExternKeywordLoc = Loc;
1084}
1085
1087 SourceLocation Loc) {
1088 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1089 if (!Info) {
1090 // Don't allocate if the location is invalid.
1091 if (Loc.isInvalid())
1092 return;
1095 ExplicitInfo = Info;
1096 }
1097 Info->TemplateKeywordLoc = Loc;
1098}
1099
1100//===----------------------------------------------------------------------===//
1101// ConceptDecl Implementation
1102//===----------------------------------------------------------------------===//
1105 TemplateParameterList *Params,
1107 bool Invalid = AdoptTemplateParameterList(Params, DC);
1108 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1109 if (Invalid)
1110 TD->setInvalidDecl();
1111 return TD;
1112}
1113
1115 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1117 nullptr, nullptr);
1118
1119 return Result;
1120}
1121
1122//===----------------------------------------------------------------------===//
1123// ImplicitConceptSpecializationDecl Implementation
1124//===----------------------------------------------------------------------===//
1125ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1127 ArrayRef<TemplateArgument> ConvertedArgs)
1128 : Decl(ImplicitConceptSpecialization, DC, SL),
1129 NumTemplateArgs(ConvertedArgs.size()) {
1130 setTemplateArguments(ConvertedArgs);
1131}
1132
1133ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1134 EmptyShell Empty, unsigned NumTemplateArgs)
1135 : Decl(ImplicitConceptSpecialization, Empty),
1136 NumTemplateArgs(NumTemplateArgs) {}
1137
1138ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create(
1139 const ASTContext &C, DeclContext *DC, SourceLocation SL,
1140 ArrayRef<TemplateArgument> ConvertedArgs) {
1141 return new (C, DC,
1142 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1143 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1144}
1145
1148 const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) {
1149 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1150 ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);
1151}
1152
1154 ArrayRef<TemplateArgument> Converted) {
1155 assert(Converted.size() == NumTemplateArgs);
1156 llvm::uninitialized_copy(Converted, getTrailingObjects());
1157}
1158
1159//===----------------------------------------------------------------------===//
1160// ClassTemplatePartialSpecializationDecl Implementation
1161//===----------------------------------------------------------------------===//
1162void ClassTemplatePartialSpecializationDecl::anchor() {}
1163
1164ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
1165 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1167 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1168 CanQualType CanonInjectedTST,
1171 Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
1172 // Tracking StrictPackMatch for Partial
1173 // Specializations is not needed.
1174 SpecializedTemplate, Args, /*StrictPackMatch=*/false, PrevDecl),
1175 TemplateParams(Params), InstantiatedFromMember(nullptr, false),
1176 CanonInjectedTST(CanonInjectedTST) {
1177 if (AdoptTemplateParameterList(Params, this))
1179}
1180
1183 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1185 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1186 CanQualType CanonInjectedTST,
1187 ClassTemplatePartialSpecializationDecl *PrevDecl) {
1188 auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl(
1189 Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args,
1190 CanonInjectedTST, PrevDecl);
1191 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1192 return Result;
1193}
1194
1197 GlobalDeclID ID) {
1198 return new (C, ID) ClassTemplatePartialSpecializationDecl(C);
1199}
1200
1203 const ASTContext &Ctx) const {
1204 if (CanonInjectedTST.isNull()) {
1205 CanonInjectedTST =
1209 getTemplateArgs().asArray()));
1210 }
1211 return CanonInjectedTST;
1212}
1213
1215 if (const ClassTemplatePartialSpecializationDecl *MT =
1217 MT && !isMemberSpecialization())
1218 return MT->getSourceRange();
1222 Range.setBegin(TPL->getTemplateLoc());
1223 return Range;
1224}
1225
1226//===----------------------------------------------------------------------===//
1227// FriendTemplateDecl Implementation
1228//===----------------------------------------------------------------------===//
1229
1230void FriendTemplateDecl::anchor() {}
1231
1236 FriendUnion Friend, SourceLocation FLoc) {
1237 TemplateParameterList **TPL = nullptr;
1238 if (!Params.empty()) {
1239 TPL = new (Context) TemplateParameterList *[Params.size()];
1240 llvm::copy(Params, TPL);
1241 }
1242 return new (Context, DC)
1243 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
1244}
1245
1247 GlobalDeclID ID) {
1248 return new (C, ID) FriendTemplateDecl(EmptyShell());
1249}
1250
1251//===----------------------------------------------------------------------===//
1252// TypeAliasTemplateDecl Implementation
1253//===----------------------------------------------------------------------===//
1254
1257 DeclarationName Name,
1259 bool Invalid = AdoptTemplateParameterList(Params, DC);
1260 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1261 if (Invalid)
1262 TD->setInvalidDecl();
1263 return TD;
1264}
1265
1268 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1269 DeclarationName(), nullptr, nullptr);
1270}
1271
1274 auto *CommonPtr = new (C) Common;
1275 C.addDestruction(CommonPtr);
1276 return CommonPtr;
1277}
1278
1279//===----------------------------------------------------------------------===//
1280// VarTemplateDecl Implementation
1281//===----------------------------------------------------------------------===//
1282
1284 VarTemplateDecl *CurD = this;
1285 while (CurD) {
1286 if (CurD->isThisDeclarationADefinition())
1287 return CurD;
1288 CurD = CurD->getPreviousDecl();
1289 }
1290 return nullptr;
1291}
1292
1295 TemplateParameterList *Params,
1296 VarDecl *Decl) {
1297 bool Invalid = AdoptTemplateParameterList(Params, DC);
1298 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1299 if (Invalid)
1300 TD->setInvalidDecl();
1301 return TD;
1302}
1303
1305 GlobalDeclID ID) {
1306 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1307 DeclarationName(), nullptr, nullptr);
1308}
1309
1311 bool OnlyPartial /*=false*/) const {
1312 loadLazySpecializationsImpl(OnlyPartial);
1313}
1314
1315llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1320
1321llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1326
1329 auto *CommonPtr = new (C) Common;
1330 C.addDestruction(CommonPtr);
1331 return CommonPtr;
1332}
1333
1336 void *&InsertPos) {
1337 auto *Common = getCommonPtr();
1338 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
1339}
1340
1346
1353
1355 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1356 TemplateParameterList *TPL, const ASTContext &Context) {
1357 ID.AddInteger(TemplateArgs.size());
1358 for (const TemplateArgument &TemplateArg : TemplateArgs)
1359 TemplateArg.Profile(ID, Context);
1360 TPL->Profile(ID, Context);
1361}
1362
1364 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1365 if (InsertPos)
1366 getPartialSpecializations().InsertNode(D, InsertPos);
1367 else {
1369 getPartialSpecializations().GetOrInsertNode(D);
1370 (void)Existing;
1371 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1372 }
1373
1375 L->AddedCXXTemplateSpecialization(this, D);
1376}
1377
1380 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1382 PS.clear();
1383 PS.reserve(PartialSpecs.size());
1384 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1385 PS.push_back(P.getMostRecentDecl());
1386}
1387
1391 Decl *DCanon = D->getCanonicalDecl();
1393 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1394 return P.getMostRecentDecl();
1395 }
1396
1397 return nullptr;
1398}
1399
1400//===----------------------------------------------------------------------===//
1401// VarTemplateSpecializationDecl Implementation
1402//===----------------------------------------------------------------------===//
1403
1405 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1406 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1408 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1409 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1410 SpecializedTemplate(SpecializedTemplate),
1411 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1412 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1413
1415 ASTContext &C)
1418 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1419
1421 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1422 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1424 return new (Context, DC) VarTemplateSpecializationDecl(
1425 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1426 SpecializedTemplate, T, TInfo, S, Args);
1427}
1428
1431 GlobalDeclID ID) {
1432 return new (C, ID)
1433 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1434}
1435
1437 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1439
1440 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1441 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1442 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1443 printTemplateArgumentList(
1444 OS, ArgsAsWritten->arguments(), Policy,
1445 getSpecializedTemplate()->getTemplateParameters());
1446 } else {
1447 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1448 printTemplateArgumentList(
1449 OS, TemplateArgs.asArray(), Policy,
1450 getSpecializedTemplate()->getTemplateParameters());
1451 }
1452}
1453
1455 if (const auto *PartialSpec =
1456 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1457 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1458 return cast<VarTemplateDecl *>(SpecializedTemplate);
1459}
1460
1462 switch (getSpecializationKind()) {
1463 case TSK_Undeclared:
1465 llvm::PointerUnion<VarTemplateDecl *,
1468 assert(!Pattern.isNull() &&
1469 "Variable template specialization without pattern?");
1470 if (const auto *VTPSD =
1471 dyn_cast<VarTemplatePartialSpecializationDecl *>(Pattern))
1472 return VTPSD->getSourceRange();
1474 if (hasInit()) {
1476 return Definition->getSourceRange();
1477 }
1478 return VTD->getCanonicalDecl()->getSourceRange();
1479 }
1483 !hasInit() && Args)
1484 Range.setEnd(Args->getRAngleLoc());
1485 return Range;
1486 }
1490 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1491 Range.setBegin(ExternKW);
1492 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1493 TemplateKW.isValid())
1494 Range.setBegin(TemplateKW);
1496 Range.setEnd(Args->getRAngleLoc());
1497 return Range;
1498 }
1499 }
1500 llvm_unreachable("unhandled template specialization kind");
1501}
1502
1504 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1505 if (!Info) {
1506 // Don't allocate if the location is invalid.
1507 if (Loc.isInvalid())
1508 return;
1511 ExplicitInfo = Info;
1512 }
1513 Info->ExternKeywordLoc = Loc;
1514}
1515
1517 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1518 if (!Info) {
1519 // Don't allocate if the location is invalid.
1520 if (Loc.isInvalid())
1521 return;
1524 ExplicitInfo = Info;
1525 }
1526 Info->TemplateKeywordLoc = Loc;
1527}
1528
1529//===----------------------------------------------------------------------===//
1530// VarTemplatePartialSpecializationDecl Implementation
1531//===----------------------------------------------------------------------===//
1532
1533void VarTemplatePartialSpecializationDecl::anchor() {}
1534
1535VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1536 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1538 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1540 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1541 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1542 TInfo, S, Args),
1543 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1544 if (AdoptTemplateParameterList(Params, DC))
1546}
1547
1550 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1552 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1554 auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(
1555 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,
1556 Args);
1557 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1558 return Result;
1559}
1560
1563 GlobalDeclID ID) {
1564 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1565}
1566
1568 if (const VarTemplatePartialSpecializationDecl *MT =
1570 MT && !isMemberSpecialization())
1571 return MT->getSourceRange();
1575 Range.setBegin(TPL->getTemplateLoc());
1576 return Range;
1577}
1578
1580 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1581 switch (BTK) {
1582#define CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST
1583#include "clang/Basic/BuiltinTemplates.inc"
1584 }
1585
1586 llvm_unreachable("unhandled BuiltinTemplateKind!");
1587}
1588
1589void BuiltinTemplateDecl::anchor() {}
1590
1591BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1592 DeclarationName Name,
1596 BTK(BTK) {}
1597
1599 return getBuiltinTemplateKind() == clang::BTK__builtin_dedup_pack;
1600}
1601
1603 auto *T = dyn_cast_or_null<BuiltinTemplateDecl>(
1604 N.getAsTemplateDecl(/*IgnoreDeduced=*/true));
1605 return T && T->isPackProducingBuiltinTemplate();
1606}
1607
1608TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1609 QualType T,
1610 const APValue &V) {
1611 DeclContext *DC = C.getTranslationUnitDecl();
1612 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1613 C.addDestruction(&TPOD->Value);
1614 return TPOD;
1615}
1616
1618TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1619 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1620 C.addDestruction(&TPOD->Value);
1621 return TPOD;
1622}
1623
1624void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1625 const PrintingPolicy &Policy) const {
1626 OS << "<template param ";
1627 printAsExpr(OS, Policy);
1628 OS << ">";
1629}
1630
1631void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1632 printAsExpr(OS, getASTContext().getPrintingPolicy());
1633}
1634
1635void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1636 const PrintingPolicy &Policy) const {
1637 getType().getUnqualifiedType().print(OS, Policy);
1638 printAsInit(OS, Policy);
1639}
1640
1641void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1642 printAsInit(OS, getASTContext().getPrintingPolicy());
1643}
1644
1645void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1646 const PrintingPolicy &Policy) const {
1647 getValue().printPretty(OS, Policy, getType(), &getASTContext());
1648}
1649
1650std::tuple<NamedDecl *, TemplateArgument>
1652 switch (D->getKind()) {
1653 case Decl::Kind::BuiltinTemplate:
1654 case Decl::Kind::ClassTemplate:
1655 case Decl::Kind::Concept:
1656 case Decl::Kind::FunctionTemplate:
1657 case Decl::Kind::TemplateTemplateParm:
1658 case Decl::Kind::TypeAliasTemplate:
1659 case Decl::Kind::VarTemplate:
1660 return {cast<TemplateDecl>(D)->getTemplateParameters()->getParam(Index),
1661 {}};
1662 case Decl::Kind::ClassTemplateSpecialization: {
1663 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1664 auto P = CTSD->getSpecializedTemplateOrPartial();
1666 if (const auto *CTPSD =
1667 dyn_cast<ClassTemplatePartialSpecializationDecl *>(P)) {
1668 TPL = CTPSD->getTemplateParameters();
1669 // FIXME: Obtain Args deduced for the partial specialization.
1670 return {TPL->getParam(Index), {}};
1671 }
1672 TPL = cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1673 return {TPL->getParam(Index), CTSD->getTemplateArgs()[Index]};
1674 }
1675 case Decl::Kind::VarTemplateSpecialization: {
1676 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1677 auto P = VTSD->getSpecializedTemplateOrPartial();
1679 if (const auto *VTPSD =
1680 dyn_cast<VarTemplatePartialSpecializationDecl *>(P)) {
1681 TPL = VTPSD->getTemplateParameters();
1682 // FIXME: Obtain Args deduced for the partial specialization.
1683 return {TPL->getParam(Index), {}};
1684 }
1685 TPL = cast<VarTemplateDecl *>(P)->getTemplateParameters();
1686 return {TPL->getParam(Index), VTSD->getTemplateArgs()[Index]};
1687 }
1688 case Decl::Kind::ClassTemplatePartialSpecialization:
1690 ->getTemplateParameters()
1691 ->getParam(Index),
1692 {}};
1693 case Decl::Kind::VarTemplatePartialSpecialization:
1695 ->getTemplateParameters()
1696 ->getParam(Index),
1697 {}};
1698 // This is used as the AssociatedDecl for placeholder type deduction.
1699 case Decl::TemplateTypeParm:
1700 return {cast<NamedDecl>(D), {}};
1701 // FIXME: Always use the template decl as the AssociatedDecl.
1702 case Decl::Kind::CXXRecord:
1704 cast<CXXRecordDecl>(D)->getDescribedClassTemplate(), Index);
1705 case Decl::Kind::CXXDeductionGuide:
1706 case Decl::Kind::CXXConversion:
1707 case Decl::Kind::CXXConstructor:
1708 case Decl::Kind::CXXDestructor:
1709 case Decl::Kind::CXXMethod:
1710 case Decl::Kind::Function:
1712 cast<FunctionDecl>(D)->getTemplateSpecializationInfo()->getTemplate(),
1713 Index);
1714 default:
1715 llvm_unreachable("Unhandled templated declaration kind");
1716 }
1717}
1718
1720 if (const auto *FD = dyn_cast<FunctionDecl>(&D)) {
1721 // Is this function declaration part of a function template?
1722 if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate())
1723 return *FTD;
1724
1725 // Nothing to do if function is not an implicit instantiation.
1726 if (FD->getTemplateSpecializationKind() != TSK_ImplicitInstantiation)
1727 return D;
1728
1729 // Function is an implicit instantiation of a function template?
1730 if (const FunctionTemplateDecl *FTD = FD->getPrimaryTemplate())
1731 return *FTD;
1732
1733 // Function is instantiated from a member definition of a class template?
1734 if (const FunctionDecl *MemberDecl =
1736 return *MemberDecl;
1737
1738 return D;
1739 }
1740 if (const auto *VD = dyn_cast<VarDecl>(&D)) {
1741 // Static data member is instantiated from a member definition of a class
1742 // template?
1743 if (VD->isStaticDataMember())
1744 if (const VarDecl *MemberDecl = VD->getInstantiatedFromStaticDataMember())
1745 return *MemberDecl;
1746
1747 return D;
1748 }
1749 if (const auto *CRD = dyn_cast<CXXRecordDecl>(&D)) {
1750 // Is this class declaration part of a class template?
1751 if (const ClassTemplateDecl *CTD = CRD->getDescribedClassTemplate())
1752 return *CTD;
1753
1754 // Class is an implicit instantiation of a class template or partial
1755 // specialization?
1756 if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(CRD)) {
1757 if (CTSD->getSpecializationKind() != TSK_ImplicitInstantiation)
1758 return D;
1759 llvm::PointerUnion<ClassTemplateDecl *,
1762 return isa<ClassTemplateDecl *>(PU)
1763 ? *static_cast<const Decl *>(cast<ClassTemplateDecl *>(PU))
1764 : *static_cast<const Decl *>(
1766 }
1767
1768 // Class is instantiated from a member definition of a class template?
1769 if (const MemberSpecializationInfo *Info =
1770 CRD->getMemberSpecializationInfo())
1771 return *Info->getInstantiatedFrom();
1772
1773 return D;
1774 }
1775 if (const auto *ED = dyn_cast<EnumDecl>(&D)) {
1776 // Enum is instantiated from a member definition of a class template?
1777 if (const EnumDecl *MemberDecl = ED->getInstantiatedFromMemberEnum())
1778 return *MemberDecl;
1779
1780 return D;
1781 }
1782 // FIXME: Adjust alias templates?
1783 return D;
1784}
Defines the clang::ASTContext interface.
#define V(N, I)
#define BuiltinTemplate(BTName)
Definition ASTContext.h:466
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:220
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:130
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:546
ASTMutationListener * getASTMutationListener() const
Definition DeclBase.cpp:556
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition DeclBase.cpp:178
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:256
void setDeclContext(DeclContext *DC)
setDeclContext - Set both the semantic and lexical DeclContext to DC.
Definition DeclBase.cpp:382
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:780
SourceLocation getOuterLocStart() const
Return start of source range taking into account any outer template declarations.
Definition Decl.cpp:2061
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2101
unsigned getNumTemplateParameterLists() const
Definition Decl.h:862
Represents an enum.
Definition Decl.h:4010
EnumDecl * getInstantiatedFromMemberEnum() const
Returns the enumeration (declared within the template) from which this enumeration type was instantia...
Definition Decl.cpp:5149
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:2000
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization,...
Definition Decl.cpp:4165
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:274
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:295
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
Definition Decl.h:286
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
NamedDecl * getMostRecentDecl()
Definition Decl.h:501
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:1845
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:8292
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:8386
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:3722
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition Decl.h:3810
unsigned getNumTemplateParameterLists() const
Definition Decl.h:3975
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:227
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Definition ASTConcept.h:244
const Type * getTypeForDecl() const
Definition Decl.h:3538
friend class ASTContext
Definition Decl.h:3514
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.h:3549
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:3547
A container of type source information.
Definition TypeBase.h:8263
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8274
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition TypeBase.h:2900
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:926
bool hasInit() const
Definition Decl.cpp:2409
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2201
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition Decl.cpp:2268
VarDecl * getInstantiatedFromStaticDataMember() const
If this variable is an instantiated static data member of a class template specialization,...
Definition Decl.cpp:2783
@ Definition
This declaration is definitely a definition.
Definition Decl.h:1301
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 isa(CodeGen::Address addr)
Definition Address.h:330
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:5893
BuiltinTemplateKind
Kinds of BuiltinTemplateDecl.
Definition Builtins.h:490
std::tuple< NamedDecl *, TemplateArgument > getReplacedTemplateParameter(Decl *D, unsigned Index)
Internal helper used by Subst* nodes to retrieve a parameter from the AssociatedDecl,...
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.
const Decl & adjustDeclToTemplate(const Decl &D)
If we have a 'templated' declaration for a template, adjust 'D' to refer to the actual template.
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:5889
@ Struct
The "struct" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5870
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
Definition TypeBase.h:5886
#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 ...