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,
444 assert(!Params->empty() && "template with no template parameters");
446 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
447 if (Invalid)
448 TD->setInvalidDecl();
449 return TD;
450}
451
454 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
455 DeclarationName(), nullptr, nullptr);
456}
457
460 auto *CommonPtr = new (C) Common;
461 C.addDestruction(CommonPtr);
462 return CommonPtr;
463}
464
468
469llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
474
477 void *&InsertPos) {
478 auto *Common = getCommonPtr();
479 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
480}
481
488
491
492 // If we haven't created a common pointer yet, then it can just be created
493 // with the usual method.
494 if (!Base::Common)
495 return;
496
497 Common *ThisCommon = static_cast<Common *>(Base::Common);
498 Common *PrevCommon = nullptr;
500 for (; Prev; Prev = Prev->getPreviousDecl()) {
501 if (Prev->Base::Common) {
502 PrevCommon = static_cast<Common *>(Prev->Base::Common);
503 break;
504 }
505 PreviousDecls.push_back(Prev);
506 }
507
508 // If the previous redecl chain hasn't created a common pointer yet, then just
509 // use this common pointer.
510 if (!PrevCommon) {
511 for (auto *D : PreviousDecls)
512 D->Base::Common = ThisCommon;
513 return;
514 }
515
516 // Ensure we don't leak any important state.
517 assert(ThisCommon->Specializations.size() == 0 &&
518 "Can't merge incompatible declarations!");
519
520 Base::Common = PrevCommon;
521}
522
523//===----------------------------------------------------------------------===//
524// ClassTemplateDecl Implementation
525//===----------------------------------------------------------------------===//
526
529 DeclarationName Name,
530 TemplateParameterList *Params,
531 NamedDecl *Decl) {
532 assert(!Params->empty() && "template with no template parameters");
534 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
535 if (Invalid)
536 TD->setInvalidDecl();
537 return TD;
538}
539
541 GlobalDeclID ID) {
542 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
543 DeclarationName(), nullptr, nullptr);
544}
545
550
551llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
556
557llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
562
565 auto *CommonPtr = new (C) Common;
566 C.addDestruction(CommonPtr);
567 return CommonPtr;
568}
569
572 void *&InsertPos) {
573 auto *Common = getCommonPtr();
574 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
575}
576
583
591
593 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
594 TemplateParameterList *TPL, const ASTContext &Context) {
595 ID.AddInteger(TemplateArgs.size());
596 for (const TemplateArgument &TemplateArg : TemplateArgs)
597 TemplateArg.Profile(ID, Context);
598 TPL->Profile(ID, Context);
599}
600
603 void *InsertPos) {
604 if (InsertPos)
605 getPartialSpecializations().InsertNode(D, InsertPos);
606 else {
608 = getPartialSpecializations().GetOrInsertNode(D);
609 (void)Existing;
610 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
611 }
612
614 L->AddedCXXTemplateSpecialization(this, D);
615}
616
619 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
621 PS.clear();
622 PS.reserve(PartialSpecs.size());
623 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
624 PS.push_back(P.getMostRecentDecl());
625}
626
629 ASTContext &Context = getASTContext();
632 if (Context.hasSameType(P.getCanonicalInjectedSpecializationType(Context),
633 T))
634 return P.getMostRecentDecl();
635 }
636
637 return nullptr;
638}
639
643 Decl *DCanon = D->getCanonicalDecl();
645 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
646 return P.getMostRecentDecl();
647 }
648
649 return nullptr;
650}
651
668
669//===----------------------------------------------------------------------===//
670// TemplateTypeParm Allocation/Deallocation Method Implementations
671//===----------------------------------------------------------------------===//
672
673TemplateTypeParmDecl *TemplateTypeParmDecl::Create(
674 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
675 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
676 bool Typename, bool ParameterPack, bool HasTypeConstraint,
677 UnsignedOrNone NumExpanded) {
678 auto *TTPDecl =
679 new (C, DC,
680 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
681 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
682 HasTypeConstraint, NumExpanded);
683 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
684 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
685 return TTPDecl;
686}
687
690 return new (C, ID)
691 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
692 false, false, std::nullopt);
693}
694
697 bool HasTypeConstraint) {
698 return new (C, ID,
699 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
700 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
701 false, HasTypeConstraint, std::nullopt);
702}
703
708
711 return SourceRange(getBeginLoc(),
713 // TypeDecl::getSourceRange returns a range containing name location, which is
714 // wrong for unnamed template parameters. e.g:
715 // it will return <[[typename>]] instead of <[[typename]]>
716 if (getDeclName().isEmpty())
717 return SourceRange(getBeginLoc());
719}
720
722 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
723 if (DefArg.getArgument().isNull())
724 DefaultArgument.set(nullptr);
725 else
726 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
727}
728
730 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->getDepth();
731}
732
734 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->getIndex();
735}
736
738 return dyn_cast<TemplateTypeParmType>(getTypeForDecl())->isParameterPack();
739}
740
742 ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint,
743 UnsignedOrNone ArgPackSubstIndex) {
744 assert(HasTypeConstraint &&
745 "HasTypeConstraint=true must be passed at construction in order to "
746 "call setTypeConstraint");
747 assert(!TypeConstraintInitialized &&
748 "TypeConstraint was already initialized!");
749 new (getTrailingObjects())
750 TypeConstraint(Loc, ImmediatelyDeclaredConstraint, ArgPackSubstIndex);
751 TypeConstraintInitialized = true;
752}
753
754//===----------------------------------------------------------------------===//
755// NonTypeTemplateParmDecl Method Implementations
756//===----------------------------------------------------------------------===//
757
758NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
759 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
760 unsigned P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
761 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
762 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
763 TemplateParmPosition(D, P), ParameterPack(true),
764 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
765 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
766 auto TypesAndInfos =
767 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
768 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
769 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
770 TypesAndInfos[I].second = ExpandedTInfos[I];
771 }
772 }
773}
774
775NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
776 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
777 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
778 QualType T, bool ParameterPack, TypeSourceInfo *TInfo) {
779 AutoType *AT =
780 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
781 const bool HasConstraint = AT && AT->isConstrained();
782 auto *NTTP =
783 new (C, DC,
784 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
785 0, HasConstraint ? 1 : 0))
786 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T,
787 ParameterPack, TInfo);
788 if (HasConstraint)
789 NTTP->setPlaceholderTypeConstraint(nullptr);
790 return NTTP;
791}
792
793NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
794 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
795 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
796 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
797 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
798 AutoType *AT = TInfo->getType()->getContainedAutoType();
799 const bool HasConstraint = AT && AT->isConstrained();
800 auto *NTTP =
801 new (C, DC,
802 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
803 ExpandedTypes.size(), HasConstraint ? 1 : 0))
804 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
805 ExpandedTypes, ExpandedTInfos);
806 if (HasConstraint)
807 NTTP->setPlaceholderTypeConstraint(nullptr);
808 return NTTP;
809}
810
813 bool HasTypeConstraint) {
814 auto *NTTP =
815 new (C, ID,
816 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
817 0, HasTypeConstraint ? 1 : 0))
818 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
819 0, 0, nullptr, QualType(), false, nullptr);
820 if (HasTypeConstraint)
821 NTTP->setPlaceholderTypeConstraint(nullptr);
822 return NTTP;
823}
824
827 unsigned NumExpandedTypes,
828 bool HasTypeConstraint) {
829 auto *NTTP =
830 new (C, ID,
831 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
832 NumExpandedTypes, HasTypeConstraint ? 1 : 0))
833 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
834 0, 0, nullptr, QualType(), nullptr, {}, {});
835 NTTP->NumExpandedTypes = NumExpandedTypes;
836 if (HasTypeConstraint)
837 NTTP->setPlaceholderTypeConstraint(nullptr);
838 return NTTP;
839}
840
847
852
854 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
855 if (DefArg.getArgument().isNull())
856 DefaultArgument.set(nullptr);
857 else
858 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
859}
860
861//===----------------------------------------------------------------------===//
862// TemplateTemplateParmDecl Method Implementations
863//===----------------------------------------------------------------------===//
864
865void TemplateTemplateParmDecl::anchor() {}
866
867TemplateTemplateParmDecl::TemplateTemplateParmDecl(
868 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
871 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
872 TemplateParmPosition(D, P), ParameterKind(Kind), Typename(Typename),
873 ParameterPack(true), ExpandedParameterPack(true),
874 NumExpandedParams(Expansions.size()) {
875 llvm::uninitialized_copy(Expansions, getTrailingObjects());
876}
877
878TemplateTemplateParmDecl *TemplateTemplateParmDecl::Create(
879 const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
880 unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateNameKind Kind,
881 bool Typename, TemplateParameterList *Params) {
882 assert(!Params->empty() && "template with no template parameters");
883 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
884 Kind, Typename, Params);
885}
886
889 SourceLocation L, unsigned D, unsigned P,
891 bool Typename, TemplateParameterList *Params,
893 assert(!Params->empty() && "template with no template parameters");
894 return new (C, DC,
895 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
896 TemplateTemplateParmDecl(DC, L, D, P, Id, Kind, Typename, Params,
897 Expansions);
898}
899
902 return new (C, ID) TemplateTemplateParmDecl(
903 nullptr, SourceLocation(), 0, 0, false, nullptr,
905}
906
909 unsigned NumExpansions) {
910 auto *TTP =
911 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
912 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
914 nullptr, {});
915 TTP->NumExpandedParams = NumExpansions;
916 return TTP;
917}
918
923
925 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
926 if (DefArg.getArgument().isNull())
927 DefaultArgument.set(nullptr);
928 else
929 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
930}
931
932//===----------------------------------------------------------------------===//
933// TemplateArgumentList Implementation
934//===----------------------------------------------------------------------===//
935TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
936 : NumArguments(Args.size()) {
937 llvm::uninitialized_copy(Args, getTrailingObjects());
938}
939
943 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
944 return new (Mem) TemplateArgumentList(Args);
945}
946
947FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
950 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
951 MemberSpecializationInfo *MSInfo) {
952 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
953 if (TemplateArgsAsWritten)
955 *TemplateArgsAsWritten);
956
957 void *Mem =
958 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
959 return new (Mem) FunctionTemplateSpecializationInfo(
960 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
961}
962
963//===----------------------------------------------------------------------===//
964// ClassTemplateSpecializationDecl Implementation
965//===----------------------------------------------------------------------===//
966
968 ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC,
969 SourceLocation StartLoc, SourceLocation IdLoc,
970 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
971 bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl)
972 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
973 SpecializedTemplate->getIdentifier(), PrevDecl),
974 SpecializedTemplate(SpecializedTemplate),
975 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
976 SpecializationKind(TSK_Undeclared), StrictPackMatch(StrictPackMatch) {
977 assert(DK == Kind::ClassTemplateSpecialization || StrictPackMatch == false);
978}
979
985
987 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
988 SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate,
989 ArrayRef<TemplateArgument> Args, bool StrictPackMatch,
991 auto *Result = new (Context, DC) ClassTemplateSpecializationDecl(
992 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
993 SpecializedTemplate, Args, StrictPackMatch, PrevDecl);
994
995 // If the template decl is incomplete, copy the external lexical storage from
996 // the base template. This allows instantiations of incomplete types to
997 // complete using the external AST if the template's declaration came from an
998 // external AST.
999 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
1000 Result->setHasExternalLexicalStorage(
1001 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
1002
1003 return Result;
1004}
1005
1008 GlobalDeclID ID) {
1009 return new (C, ID)
1010 ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
1011}
1012
1014 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1016
1017 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
1018 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1019 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1020 printTemplateArgumentList(
1021 OS, ArgsAsWritten->arguments(), Policy,
1022 getSpecializedTemplate()->getTemplateParameters());
1023 } else {
1024 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1025 printTemplateArgumentList(
1026 OS, TemplateArgs.asArray(), Policy,
1027 getSpecializedTemplate()->getTemplateParameters());
1028 }
1029}
1030
1033 if (const auto *PartialSpec =
1034 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
1035 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1036 return cast<ClassTemplateDecl *>(SpecializedTemplate);
1037}
1038
1041 switch (getSpecializationKind()) {
1042 case TSK_Undeclared:
1044 llvm::PointerUnion<ClassTemplateDecl *,
1047 assert(!Pattern.isNull() &&
1048 "Class template specialization without pattern?");
1049 if (const auto *CTPSD =
1050 dyn_cast<ClassTemplatePartialSpecializationDecl *>(Pattern))
1051 return CTPSD->getSourceRange();
1052 return cast<ClassTemplateDecl *>(Pattern)->getSourceRange();
1053 }
1058 Range.setEnd(Args->getRAngleLoc());
1059 return Range;
1060 }
1064 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1065 Range.setBegin(ExternKW);
1066 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1067 TemplateKW.isValid())
1068 Range.setBegin(TemplateKW);
1070 Range.setEnd(Args->getRAngleLoc());
1071 return Range;
1072 }
1073 }
1074 llvm_unreachable("unhandled template specialization kind");
1075}
1076
1078 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1079 if (!Info) {
1080 // Don't allocate if the location is invalid.
1081 if (Loc.isInvalid())
1082 return;
1085 ExplicitInfo = Info;
1086 }
1087 Info->ExternKeywordLoc = Loc;
1088}
1089
1091 SourceLocation Loc) {
1092 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1093 if (!Info) {
1094 // Don't allocate if the location is invalid.
1095 if (Loc.isInvalid())
1096 return;
1099 ExplicitInfo = Info;
1100 }
1101 Info->TemplateKeywordLoc = Loc;
1102}
1103
1104//===----------------------------------------------------------------------===//
1105// ConceptDecl Implementation
1106//===----------------------------------------------------------------------===//
1109 TemplateParameterList *Params,
1111 assert(!Params->empty() && "template with no template parameters");
1112 bool Invalid = AdoptTemplateParameterList(Params, DC);
1113 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1114 if (Invalid)
1115 TD->setInvalidDecl();
1116 return TD;
1117}
1118
1120 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1122 nullptr, nullptr);
1123
1124 return Result;
1125}
1126
1127//===----------------------------------------------------------------------===//
1128// ImplicitConceptSpecializationDecl Implementation
1129//===----------------------------------------------------------------------===//
1130ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1132 ArrayRef<TemplateArgument> ConvertedArgs)
1133 : Decl(ImplicitConceptSpecialization, DC, SL),
1134 NumTemplateArgs(ConvertedArgs.size()) {
1135 setTemplateArguments(ConvertedArgs);
1136}
1137
1138ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1139 EmptyShell Empty, unsigned NumTemplateArgs)
1140 : Decl(ImplicitConceptSpecialization, Empty),
1141 NumTemplateArgs(NumTemplateArgs) {}
1142
1143ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create(
1144 const ASTContext &C, DeclContext *DC, SourceLocation SL,
1145 ArrayRef<TemplateArgument> ConvertedArgs) {
1146 return new (C, DC,
1147 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1148 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1149}
1150
1153 const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) {
1154 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1155 ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);
1156}
1157
1159 ArrayRef<TemplateArgument> Converted) {
1160 assert(Converted.size() == NumTemplateArgs);
1161 llvm::uninitialized_copy(Converted, getTrailingObjects());
1162}
1163
1164//===----------------------------------------------------------------------===//
1165// ClassTemplatePartialSpecializationDecl Implementation
1166//===----------------------------------------------------------------------===//
1167void ClassTemplatePartialSpecializationDecl::anchor() {}
1168
1169ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
1170 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1172 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1173 CanQualType CanonInjectedTST,
1176 Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
1177 // Tracking StrictPackMatch for Partial
1178 // Specializations is not needed.
1179 SpecializedTemplate, Args, /*StrictPackMatch=*/false, PrevDecl),
1180 TemplateParams(Params), InstantiatedFromMember(nullptr, false),
1181 CanonInjectedTST(CanonInjectedTST) {
1182 if (AdoptTemplateParameterList(Params, this))
1184}
1185
1188 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1190 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1191 CanQualType CanonInjectedTST,
1192 ClassTemplatePartialSpecializationDecl *PrevDecl) {
1193 assert(!Params->empty() && "template with no template parameters");
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 assert(!Params->empty() && "template with no template parameters");
1266 bool Invalid = AdoptTemplateParameterList(Params, DC);
1267 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1268 if (Invalid)
1269 TD->setInvalidDecl();
1270 return TD;
1271}
1272
1275 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1276 DeclarationName(), nullptr, nullptr);
1277}
1278
1281 auto *CommonPtr = new (C) Common;
1282 C.addDestruction(CommonPtr);
1283 return CommonPtr;
1284}
1285
1286//===----------------------------------------------------------------------===//
1287// VarTemplateDecl Implementation
1288//===----------------------------------------------------------------------===//
1289
1291 VarTemplateDecl *CurD = this;
1292 while (CurD) {
1293 if (CurD->isThisDeclarationADefinition())
1294 return CurD;
1295 CurD = CurD->getPreviousDecl();
1296 }
1297 return nullptr;
1298}
1299
1302 TemplateParameterList *Params,
1303 VarDecl *Decl) {
1304 assert(!Params->empty() && "template with no template parameters");
1305 bool Invalid = AdoptTemplateParameterList(Params, DC);
1306 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1307 if (Invalid)
1308 TD->setInvalidDecl();
1309 return TD;
1310}
1311
1313 GlobalDeclID ID) {
1314 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1315 DeclarationName(), nullptr, nullptr);
1316}
1317
1322
1323llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1328
1329llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1334
1337 auto *CommonPtr = new (C) Common;
1338 C.addDestruction(CommonPtr);
1339 return CommonPtr;
1340}
1341
1344 void *&InsertPos) {
1345 auto *Common = getCommonPtr();
1346 return findSpecializationImpl(Common->Specializations, InsertPos, Args);
1347}
1348
1354
1361
1363 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1364 TemplateParameterList *TPL, const ASTContext &Context) {
1365 ID.AddInteger(TemplateArgs.size());
1366 for (const TemplateArgument &TemplateArg : TemplateArgs)
1367 TemplateArg.Profile(ID, Context);
1368 TPL->Profile(ID, Context);
1369}
1370
1372 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1373 if (InsertPos)
1374 getPartialSpecializations().InsertNode(D, InsertPos);
1375 else {
1377 getPartialSpecializations().GetOrInsertNode(D);
1378 (void)Existing;
1379 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1380 }
1381
1383 L->AddedCXXTemplateSpecialization(this, D);
1384}
1385
1388 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1390 PS.clear();
1391 PS.reserve(PartialSpecs.size());
1392 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1393 PS.push_back(P.getMostRecentDecl());
1394}
1395
1399 Decl *DCanon = D->getCanonicalDecl();
1401 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1402 return P.getMostRecentDecl();
1403 }
1404
1405 return nullptr;
1406}
1407
1408//===----------------------------------------------------------------------===//
1409// VarTemplateSpecializationDecl Implementation
1410//===----------------------------------------------------------------------===//
1411
1413 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1414 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1416 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1417 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1418 SpecializedTemplate(SpecializedTemplate),
1419 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1420 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1421
1423 ASTContext &C)
1426 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1427
1429 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1430 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1432 return new (Context, DC) VarTemplateSpecializationDecl(
1433 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1434 SpecializedTemplate, T, TInfo, S, Args);
1435}
1436
1439 GlobalDeclID ID) {
1440 return new (C, ID)
1441 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1442}
1443
1445 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1447
1448 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1449 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1450 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1451 printTemplateArgumentList(
1452 OS, ArgsAsWritten->arguments(), Policy,
1453 getSpecializedTemplate()->getTemplateParameters());
1454 } else {
1455 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1456 printTemplateArgumentList(
1457 OS, TemplateArgs.asArray(), Policy,
1458 getSpecializedTemplate()->getTemplateParameters());
1459 }
1460}
1461
1463 if (const auto *PartialSpec =
1464 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1465 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1466 return cast<VarTemplateDecl *>(SpecializedTemplate);
1467}
1468
1470 switch (getSpecializationKind()) {
1471 case TSK_Undeclared:
1473 llvm::PointerUnion<VarTemplateDecl *,
1476 assert(!Pattern.isNull() &&
1477 "Variable template specialization without pattern?");
1478 if (const auto *VTPSD =
1479 dyn_cast<VarTemplatePartialSpecializationDecl *>(Pattern))
1480 return VTPSD->getSourceRange();
1482 if (hasInit()) {
1484 return Definition->getSourceRange();
1485 }
1486 return VTD->getCanonicalDecl()->getSourceRange();
1487 }
1491 !hasInit() && Args)
1492 Range.setEnd(Args->getRAngleLoc());
1493 return Range;
1494 }
1498 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1499 Range.setBegin(ExternKW);
1500 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1501 TemplateKW.isValid())
1502 Range.setBegin(TemplateKW);
1504 Range.setEnd(Args->getRAngleLoc());
1505 return Range;
1506 }
1507 }
1508 llvm_unreachable("unhandled template specialization kind");
1509}
1510
1512 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1513 if (!Info) {
1514 // Don't allocate if the location is invalid.
1515 if (Loc.isInvalid())
1516 return;
1519 ExplicitInfo = Info;
1520 }
1521 Info->ExternKeywordLoc = Loc;
1522}
1523
1525 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo);
1526 if (!Info) {
1527 // Don't allocate if the location is invalid.
1528 if (Loc.isInvalid())
1529 return;
1532 ExplicitInfo = Info;
1533 }
1534 Info->TemplateKeywordLoc = Loc;
1535}
1536
1537//===----------------------------------------------------------------------===//
1538// VarTemplatePartialSpecializationDecl Implementation
1539//===----------------------------------------------------------------------===//
1540
1541void VarTemplatePartialSpecializationDecl::anchor() {}
1542
1543VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1544 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1546 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1548 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1549 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1550 TInfo, S, Args),
1551 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1552 if (AdoptTemplateParameterList(Params, DC))
1554}
1555
1558 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1560 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1562 assert(!Params->empty() && "template with no template parameters");
1563 auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(
1564 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,
1565 Args);
1566 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1567 return Result;
1568}
1569
1572 GlobalDeclID ID) {
1573 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1574}
1575
1577 if (const VarTemplatePartialSpecializationDecl *MT =
1579 MT && !isMemberSpecialization())
1580 return MT->getSourceRange();
1584 Range.setBegin(TPL->getTemplateLoc());
1585 return Range;
1586}
1587
1589 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1590 switch (BTK) {
1591#define CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST
1592#include "clang/Basic/BuiltinTemplates.inc"
1593 }
1594
1595 llvm_unreachable("unhandled BuiltinTemplateKind!");
1596}
1597
1598void BuiltinTemplateDecl::anchor() {}
1599
1600BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1601 DeclarationName Name,
1605 BTK(BTK) {}
1606
1608 return getBuiltinTemplateKind() == clang::BTK__builtin_dedup_pack;
1609}
1610
1612 auto *T = dyn_cast_or_null<BuiltinTemplateDecl>(
1613 N.getAsTemplateDecl(/*IgnoreDeduced=*/true));
1614 return T && T->isPackProducingBuiltinTemplate();
1615}
1616
1617TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1618 QualType T,
1619 const APValue &V) {
1620 DeclContext *DC = C.getTranslationUnitDecl();
1621 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1622 C.addDestruction(&TPOD->Value);
1623 return TPOD;
1624}
1625
1627TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1628 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1629 C.addDestruction(&TPOD->Value);
1630 return TPOD;
1631}
1632
1633void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1634 const PrintingPolicy &Policy) const {
1635 OS << "<template param ";
1636 printAsExpr(OS, Policy);
1637 OS << ">";
1638}
1639
1640void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1641 printAsExpr(OS, getASTContext().getPrintingPolicy());
1642}
1643
1644void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1645 const PrintingPolicy &Policy) const {
1646 getType().getUnqualifiedType().print(OS, Policy);
1647 printAsInit(OS, Policy);
1648}
1649
1650void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1651 printAsInit(OS, getASTContext().getPrintingPolicy());
1652}
1653
1654void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1655 const PrintingPolicy &Policy) const {
1656 getValue().printPretty(OS, Policy, getType(), &getASTContext());
1657}
1658
1659std::tuple<NamedDecl *, TemplateArgument>
1661 switch (D->getKind()) {
1662 case Decl::Kind::BuiltinTemplate:
1663 case Decl::Kind::ClassTemplate:
1664 case Decl::Kind::Concept:
1665 case Decl::Kind::FunctionTemplate:
1666 case Decl::Kind::TemplateTemplateParm:
1667 case Decl::Kind::TypeAliasTemplate:
1668 case Decl::Kind::VarTemplate:
1669 return {cast<TemplateDecl>(D)->getTemplateParameters()->getParam(Index),
1670 {}};
1671 case Decl::Kind::ClassTemplateSpecialization: {
1672 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1673 auto P = CTSD->getSpecializedTemplateOrPartial();
1674 if (const auto *CTPSD =
1675 dyn_cast<ClassTemplatePartialSpecializationDecl *>(P)) {
1676 TemplateParameterList *TPL = CTPSD->getTemplateParameters();
1677 return {TPL->getParam(Index),
1678 CTSD->getTemplateInstantiationArgs()[Index]};
1679 }
1681 cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1682 return {TPL->getParam(Index), CTSD->getTemplateArgs()[Index]};
1683 }
1684 case Decl::Kind::VarTemplateSpecialization: {
1685 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1686 auto P = VTSD->getSpecializedTemplateOrPartial();
1687 if (const auto *VTPSD =
1688 dyn_cast<VarTemplatePartialSpecializationDecl *>(P)) {
1689 TemplateParameterList *TPL = VTPSD->getTemplateParameters();
1690 return {TPL->getParam(Index),
1691 VTSD->getTemplateInstantiationArgs()[Index]};
1692 }
1694 cast<VarTemplateDecl *>(P)->getTemplateParameters();
1695 return {TPL->getParam(Index), VTSD->getTemplateArgs()[Index]};
1696 }
1697 case Decl::Kind::ClassTemplatePartialSpecialization:
1699 ->getTemplateParameters()
1700 ->getParam(Index),
1701 {}};
1702 case Decl::Kind::VarTemplatePartialSpecialization:
1704 ->getTemplateParameters()
1705 ->getParam(Index),
1706 {}};
1707 // This is used as the AssociatedDecl for placeholder type deduction.
1708 case Decl::TemplateTypeParm:
1709 return {cast<NamedDecl>(D), {}};
1710 // FIXME: Always use the template decl as the AssociatedDecl.
1711 case Decl::Kind::CXXRecord:
1713 cast<CXXRecordDecl>(D)->getDescribedClassTemplate(), Index);
1714 case Decl::Kind::CXXDeductionGuide:
1715 case Decl::Kind::CXXConversion:
1716 case Decl::Kind::CXXConstructor:
1717 case Decl::Kind::CXXDestructor:
1718 case Decl::Kind::CXXMethod:
1719 case Decl::Kind::Function: {
1721 cast<FunctionDecl>(D)->getTemplateSpecializationInfo();
1722 return {Info->getTemplate()->getTemplateParameters()->getParam(Index),
1723 Info->TemplateArguments->asArray()[Index]};
1724 }
1725 default:
1726 llvm_unreachable("Unhandled templated declaration kind");
1727 }
1728}
1729
1731 if (const auto *FD = dyn_cast<FunctionDecl>(&D)) {
1732 // Is this function declaration part of a function template?
1733 if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate())
1734 return *FTD;
1735
1736 // Nothing to do if function is not an implicit instantiation.
1737 if (FD->getTemplateSpecializationKind() != TSK_ImplicitInstantiation)
1738 return D;
1739
1740 // Function is an implicit instantiation of a function template?
1741 if (const FunctionTemplateDecl *FTD = FD->getPrimaryTemplate())
1742 return *FTD;
1743
1744 // Function is instantiated from a member definition of a class template?
1745 if (const FunctionDecl *MemberDecl =
1747 return *MemberDecl;
1748
1749 return D;
1750 }
1751 if (const auto *VD = dyn_cast<VarDecl>(&D)) {
1752 // Static data member is instantiated from a member definition of a class
1753 // template?
1754 if (VD->isStaticDataMember())
1755 if (const VarDecl *MemberDecl = VD->getInstantiatedFromStaticDataMember())
1756 return *MemberDecl;
1757
1758 return D;
1759 }
1760 if (const auto *CRD = dyn_cast<CXXRecordDecl>(&D)) {
1761 // Is this class declaration part of a class template?
1762 if (const ClassTemplateDecl *CTD = CRD->getDescribedClassTemplate())
1763 return *CTD;
1764
1765 // Class is an implicit instantiation of a class template or partial
1766 // specialization?
1767 if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(CRD)) {
1768 if (CTSD->getSpecializationKind() != TSK_ImplicitInstantiation)
1769 return D;
1770 llvm::PointerUnion<ClassTemplateDecl *,
1773 return isa<ClassTemplateDecl *>(PU)
1774 ? *static_cast<const Decl *>(cast<ClassTemplateDecl *>(PU))
1775 : *static_cast<const Decl *>(
1777 }
1778
1779 // Class is instantiated from a member definition of a class template?
1780 if (const MemberSpecializationInfo *Info =
1781 CRD->getMemberSpecializationInfo())
1782 return *Info->getInstantiatedFrom();
1783
1784 return D;
1785 }
1786 if (const auto *ED = dyn_cast<EnumDecl>(&D)) {
1787 // Enum is instantiated from a member definition of a class template?
1788 if (const EnumDecl *MemberDecl = ED->getInstantiatedFromMemberEnum())
1789 return *MemberDecl;
1790
1791 return D;
1792 }
1793 // FIXME: Adjust alias templates?
1794 return D;
1795}
1796
1797ExplicitInstantiationDecl::ExplicitInstantiationDecl(
1799 SourceLocation TemplateLoc, NestedNameSpecifierLoc QualifierLoc,
1800 const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc,
1801 TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK)
1802 : Decl(ExplicitInstantiation, DC, TemplateLoc),
1803 SpecAndTSK(Specialization, TSK), ExternLoc(ExternLoc), NameLoc(NameLoc) {
1804 unsigned Flags = 0;
1805 if (QualifierLoc)
1806 Flags |= HasQualifierFlag;
1807 if (ArgsAsWritten)
1808 Flags |= HasArgsAsWrittenFlag;
1809 // Set flags BEFORE writing trailing objects, because
1810 // numTrailingObjects reads TypeAndFlags.getInt() to compute offsets.
1811 TypeAndFlags.setPointerAndInt(TypeAsWritten, Flags);
1812 if (QualifierLoc)
1813 *getTrailingObjects<NestedNameSpecifierLoc>() = QualifierLoc;
1814 if (ArgsAsWritten)
1815 *getTrailingObjects<const ASTTemplateArgumentListInfo *>() = ArgsAsWritten;
1816}
1817
1818ExplicitInstantiationDecl *ExplicitInstantiationDecl::Create(
1820 SourceLocation ExternLoc, SourceLocation TemplateLoc,
1821 NestedNameSpecifierLoc QualifierLoc,
1822 const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc,
1823 TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK) {
1824 unsigned Extra = additionalSizeToAlloc<NestedNameSpecifierLoc,
1826 QualifierLoc ? 1 : 0, ArgsAsWritten ? 1 : 0);
1827 return new (C, DC, Extra) ExplicitInstantiationDecl(
1828 DC, Specialization, ExternLoc, TemplateLoc, QualifierLoc, ArgsAsWritten,
1829 NameLoc, TypeAsWritten, TSK);
1830}
1831
1834 unsigned TrailingFlags) {
1835 unsigned Extra = additionalSizeToAlloc<NestedNameSpecifierLoc,
1837 (TrailingFlags & HasQualifierFlag) ? 1 : 0,
1838 (TrailingFlags & HasArgsAsWrittenFlag) ? 1 : 0);
1839 auto *D = new (C, ID, Extra) ExplicitInstantiationDecl(EmptyShell());
1840 // Set the flags so the reader knows which trailing objects are present.
1841 D->TypeAndFlags.setInt(TrailingFlags);
1842 return D;
1843}
1844
1846 if (auto *TSI = getRawTypeSourceInfo()) {
1847 if (auto TL = TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>())
1848 return TL.getElaboratedKeywordLoc();
1849 if (auto TL = TSI->getTypeLoc().getAs<TagTypeLoc>())
1850 return TL.getElaboratedKeywordLoc();
1851 }
1852 return SourceLocation();
1853}
1854
1857 return *getTrailingObjects<NestedNameSpecifierLoc>();
1858 if (auto *TSI = getRawTypeSourceInfo())
1859 return TSI->getTypeLoc().getPrefix();
1860 return NestedNameSpecifierLoc();
1861}
1862
1864 auto *TSI = getRawTypeSourceInfo();
1865 if (!TSI)
1866 return nullptr;
1867 TypeLoc TL = TSI->getTypeLoc();
1868 // For class templates and nested classes, the "type" is fully described by
1869 // the unified accessors (getQualifierLoc, getTemplateArg, getTagKWLoc).
1871 return nullptr;
1872 return TSI;
1873}
1874
1876 if (const auto *Args = getTrailingArgsInfo())
1877 return Args->NumTemplateArgs;
1878 if (auto *TSI = getRawTypeSourceInfo())
1879 if (auto TL = TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>())
1880 return TL.getNumArgs();
1881 return 0;
1882}
1883
1886 if (const auto *Args = getTrailingArgsInfo())
1887 return (*Args)[I];
1888 auto *TSI = getRawTypeSourceInfo();
1889 return TSI->getTypeLoc().castAs<TemplateSpecializationTypeLoc>().getArgLoc(I);
1890}
1891
1893 if (const auto *Args = getTrailingArgsInfo())
1894 return Args->getLAngleLoc();
1895 if (auto *TSI = getRawTypeSourceInfo())
1896 if (auto TL = TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>())
1897 return TL.getLAngleLoc();
1898 return SourceLocation();
1899}
1900
1902 if (const auto *Args = getTrailingArgsInfo())
1903 return Args->getRAngleLoc();
1904 if (auto *TSI = getRawTypeSourceInfo())
1905 if (auto TL = TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>())
1906 return TL.getRAngleLoc();
1907 return SourceLocation();
1908}
1909
1911 // For func/var templates with postfix type syntax (arrays, functions),
1912 // the type extends past the name, so use the type's end location.
1913 if (auto *TSI = getTypeAsWritten())
1914 if (TSI->getType().hasPostfixDeclaratorSyntax())
1915 return TSI->getTypeLoc().getEndLoc();
1916 // Otherwise, template args RAngleLoc or NameLoc.
1918 return RAngle.isValid() ? RAngle : NameLoc;
1919}
1920
1922 SourceLocation Begin = ExternLoc.isValid() ? ExternLoc : getLocation();
1923 return SourceRange(Begin, getEndLoc());
1924}
Defines the clang::ASTContext interface.
#define V(N, I)
#define BuiltinTemplate(BTName)
Definition ASTContext.h:475
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:717
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:227
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:1462
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:547
ASTMutationListener * getASTMutationListener() const
Definition DeclBase.cpp:557
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:997
bool isInvalidDecl() const
Definition DeclBase.h:596
SourceLocation getLocation() const
Definition DeclBase.h:447
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:260
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition DeclBase.h:991
Kind getKind() const
Definition DeclBase.h:450
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:2065
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2069
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
Definition Decl.h:862
Represents an enum.
Definition Decl.h:4029
EnumDecl * getInstantiatedFromMemberEnum() const
Returns the enumeration (declared within the template) from which this enumeration type was instantia...
Definition Decl.cpp:5149
Represents an explicit instantiation of a template entity in source code.
SourceLocation getEndLoc() const LLVM_READONLY
static ExplicitInstantiationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned TrailingFlags)
TypeSourceInfo * getTypeAsWritten() const
For function / variable templates, returns the declared type (return type or variable type).
SourceLocation getTemplateArgsLAngleLoc() const
TemplateArgumentLoc getTemplateArg(unsigned I) const
unsigned getNumTemplateArgs() const
Number of explicit template arguments, regardless of storage.
bool hasTrailingQualifier() const
Whether the qualifier is stored as a trailing object (function / variable templates) rather than insi...
SourceLocation getTemplateArgsRAngleLoc() const
SourceLocation getTagKWLoc() const
For class templates / nested classes, the tag keyword location is stored inside TypeSourceInfo; other...
NestedNameSpecifierLoc getQualifierLoc() const
Returns the qualifier regardless of where it is stored.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static ExplicitInstantiationDecl * Create(ASTContext &C, DeclContext *DC, NamedDecl *Specialization, SourceLocation ExternLoc, SourceLocation TemplateLoc, NestedNameSpecifierLoc QualifierLoc, const ASTTemplateArgumentListInfo *ArgsAsWritten, SourceLocation NameLoc, TypeSourceInfo *TypeAsWritten, TemplateSpecializationKind TSK)
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:2018
FunctionDecl * getInstantiatedFromMemberFunction() const
If this function is an instantiation of a member function of a class template specialization,...
Definition Decl.cpp:4160
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 ...
TemplateArgumentList * TemplateArguments
The template arguments used to produce the function template specialization from the function templat...
FunctionTemplateDecl * getTemplate() const
Retrieve the template from which this function was specialized.
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:1847
A C++ nested-name-specifier augmented with source location information.
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:8436
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:8530
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:3740
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition Decl.h:3831
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
Definition Decl.h:3996
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.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
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:3556
friend class ASTContext
Definition Decl.h:3532
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.h:3567
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:3565
Base wrapper for a particular "section" of type source info.
Definition TypeLoc.h:59
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition TypeLoc.h:89
A container of type source information.
Definition TypeBase.h:8407
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8418
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition TypeBase.h:2954
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:924
bool hasInit() const
Definition Decl.cpp:2377
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2169
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition Decl.cpp:2236
VarDecl * getInstantiatedFromStaticDataMember() const
If this variable is an instantiated static data member of a class template specialization,...
Definition Decl.cpp:2751
@ Definition
This declaration is definitely a definition.
Definition Decl.h:1314
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
@ Specialization
We are substituting template parameters for template arguments in order to form a template specializa...
Definition Template.h:50
bool isPackProducingBuiltinTemplateName(TemplateName N)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
StorageClass
Storage classes.
Definition Specifiers.h:249
@ SC_None
Definition Specifiers.h:251
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
OptionalUnsigned< unsigned > UnsignedOrNone
@ ExplicitInstantiation
We are parsing an explicit instantiation.
Definition Parser.h:85
TagTypeKind
The kind of a tag type.
Definition TypeBase.h:5986
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:189
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition Specifiers.h:207
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition Specifiers.h:203
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition Specifiers.h:199
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition Specifiers.h:195
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition Specifiers.h:192
U cast(CodeGen::Address addr)
Definition Address.h:327
@ None
No keyword precedes the qualified type name.
Definition TypeBase.h:5982
@ Struct
The "struct" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5963
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
Definition TypeBase.h:5979
#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 ...