clang 20.0.0git
DeclTemplate.cpp
Go to the documentation of this file.
1//===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the C++ related Decl classes for templates.
10//
11//===----------------------------------------------------------------------===//
12
16#include "clang/AST/DeclCXX.h"
18#include "clang/AST/Expr.h"
22#include "clang/AST/Type.h"
23#include "clang/AST/TypeLoc.h"
25#include "clang/Basic/LLVM.h"
27#include "llvm/ADT/ArrayRef.h"
28#include "llvm/ADT/FoldingSet.h"
29#include "llvm/ADT/PointerUnion.h"
30#include "llvm/ADT/STLExtras.h"
31#include "llvm/ADT/SmallVector.h"
32#include "llvm/Support/Casting.h"
33#include "llvm/Support/ErrorHandling.h"
34#include <algorithm>
35#include <cassert>
36#include <cstdint>
37#include <memory>
38#include <optional>
39#include <utility>
40
41using namespace clang;
42
43//===----------------------------------------------------------------------===//
44// TemplateParameterList Implementation
45//===----------------------------------------------------------------------===//
46
47template <class TemplateParam>
48static bool
50 return P.hasDefaultArgument() &&
51 P.getDefaultArgument().getArgument().containsUnexpandedParameterPack();
52}
53
54TemplateParameterList::TemplateParameterList(const ASTContext& C,
55 SourceLocation TemplateLoc,
56 SourceLocation LAngleLoc,
58 SourceLocation RAngleLoc,
59 Expr *RequiresClause)
60 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
61 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
62 HasRequiresClause(RequiresClause != nullptr),
63 HasConstrainedParameters(false) {
64 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
65 NamedDecl *P = Params[Idx];
66 begin()[Idx] = P;
67
68 bool IsPack = P->isTemplateParameterPack();
69 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
70 if (!IsPack && (NTTP->getType()->containsUnexpandedParameterPack() ||
72 ContainsUnexpandedParameterPack = true;
73 if (NTTP->hasPlaceholderTypeConstraint())
74 HasConstrainedParameters = true;
75 } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
76 if (!IsPack &&
77 (TTP->getTemplateParameters()->containsUnexpandedParameterPack() ||
79 ContainsUnexpandedParameterPack = true;
80 }
81 } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
83 ContainsUnexpandedParameterPack = true;
84 } else if (const TypeConstraint *TC = TTP->getTypeConstraint();
87 ContainsUnexpandedParameterPack = true;
88 }
89 if (TTP->hasTypeConstraint())
90 HasConstrainedParameters = true;
91 } else {
92 llvm_unreachable("unexpected template parameter type");
93 }
94 }
95
96 if (HasRequiresClause) {
97 if (RequiresClause->containsUnexpandedParameterPack())
98 ContainsUnexpandedParameterPack = true;
99 *getTrailingObjects<Expr *>() = RequiresClause;
100 }
101}
102
103bool TemplateParameterList::containsUnexpandedParameterPack() const {
104 if (ContainsUnexpandedParameterPack)
105 return true;
106 if (!HasConstrainedParameters)
107 return false;
108
109 // An implicit constrained parameter might have had a use of an unexpanded
110 // pack added to it after the template parameter list was created. All
111 // implicit parameters are at the end of the parameter list.
112 for (const NamedDecl *Param : llvm::reverse(asArray())) {
113 if (!Param->isImplicit())
114 break;
115
116 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
117 const auto *TC = TTP->getTypeConstraint();
118 if (TC && TC->getImmediatelyDeclaredConstraint()
119 ->containsUnexpandedParameterPack())
120 return true;
121 }
122 }
123
124 return false;
125}
126
129 SourceLocation LAngleLoc,
131 SourceLocation RAngleLoc, Expr *RequiresClause) {
132 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
133 Params.size(), RequiresClause ? 1u : 0u),
134 alignof(TemplateParameterList));
135 return new (Mem) TemplateParameterList(C, TemplateLoc, LAngleLoc, Params,
136 RAngleLoc, RequiresClause);
137}
138
139void TemplateParameterList::Profile(llvm::FoldingSetNodeID &ID,
140 const ASTContext &C) const {
141 const Expr *RC = getRequiresClause();
142 ID.AddBoolean(RC != nullptr);
143 if (RC)
144 RC->Profile(ID, C, /*Canonical=*/true);
145 ID.AddInteger(size());
146 for (NamedDecl *D : *this) {
147 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
148 ID.AddInteger(0);
149 ID.AddBoolean(NTTP->isParameterPack());
150 NTTP->getType().getCanonicalType().Profile(ID);
151 ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint());
152 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
153 E->Profile(ID, C, /*Canonical=*/true);
154 continue;
155 }
156 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {
157 ID.AddInteger(1);
158 ID.AddBoolean(TTP->isParameterPack());
159 ID.AddBoolean(TTP->hasTypeConstraint());
160 if (const TypeConstraint *TC = TTP->getTypeConstraint())
161 TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,
162 /*Canonical=*/true);
163 continue;
164 }
165 const auto *TTP = cast<TemplateTemplateParmDecl>(D);
166 ID.AddInteger(2);
167 ID.AddBoolean(TTP->isParameterPack());
168 TTP->getTemplateParameters()->Profile(ID, C);
169 }
170}
171
173 unsigned NumRequiredArgs = 0;
174 for (const NamedDecl *P : asArray()) {
175 if (P->isTemplateParameterPack()) {
176 if (std::optional<unsigned> Expansions = getExpandedPackSize(P)) {
177 NumRequiredArgs += *Expansions;
178 continue;
179 }
180 break;
181 }
182
183 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
184 if (TTP->hasDefaultArgument())
185 break;
186 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
187 if (NTTP->hasDefaultArgument())
188 break;
189 } else if (cast<TemplateTemplateParmDecl>(P)->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 AC.push_back(TC->getImmediatelyDeclaredConstraint());
234 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
235 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
236 AC.push_back(E);
237 }
238 }
239 if (HasRequiresClause)
240 AC.push_back(getRequiresClause());
241}
242
244 return HasRequiresClause || HasConstrainedParameters;
245}
246
248 const PrintingPolicy &Policy, const TemplateParameterList *TPL,
249 unsigned Idx) {
250 if (!TPL || Idx >= TPL->size() || Policy.AlwaysIncludeTypeForTemplateArgument)
251 return true;
252 const NamedDecl *TemplParam = TPL->getParam(Idx);
253 if (const auto *ParamValueDecl =
254 dyn_cast<NonTypeTemplateParmDecl>(TemplParam))
255 if (ParamValueDecl->getType()->getContainedDeducedType())
256 return true;
257 return false;
258}
259
260namespace clang {
261
263 return new (C) char[sizeof(void*) * 2];
264}
265
266} // namespace clang
267
268//===----------------------------------------------------------------------===//
269// TemplateDecl Implementation
270//===----------------------------------------------------------------------===//
271
275 : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
276
277void TemplateDecl::anchor() {}
278
282 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
283 if (const Expr *TRC = FD->getTrailingRequiresClause())
284 AC.push_back(TRC);
285}
286
289 return true;
290 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
291 return FD->getTrailingRequiresClause();
292 return false;
293}
294
296 switch (getKind()) {
297 case TemplateDecl::TypeAliasTemplate:
298 case TemplateDecl::BuiltinTemplate:
299 return true;
300 default:
301 return false;
302 };
303}
304
305//===----------------------------------------------------------------------===//
306// RedeclarableTemplateDecl Implementation
307//===----------------------------------------------------------------------===//
308
309void RedeclarableTemplateDecl::anchor() {}
310
312 if (Common)
313 return Common;
314
315 // Walk the previous-declaration chain until we either find a declaration
316 // with a common pointer or we run out of previous declarations.
318 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
319 Prev = Prev->getPreviousDecl()) {
320 if (Prev->Common) {
321 Common = Prev->Common;
322 break;
323 }
324
325 PrevDecls.push_back(Prev);
326 }
327
328 // If we never found a common pointer, allocate one now.
329 if (!Common) {
330 // FIXME: If any of the declarations is from an AST file, we probably
331 // need an update record to add the common data.
332
334 }
335
336 // Update any previous declarations we saw with the common pointer.
337 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
338 Prev->Common = Common;
339
340 return Common;
341}
342
344 // Grab the most recent declaration to ensure we've loaded any lazy
345 // redeclarations of this template.
346 CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
347 if (CommonBasePtr->LazySpecializations) {
348 ASTContext &Context = getASTContext();
349 GlobalDeclID *Specs = CommonBasePtr->LazySpecializations;
350 CommonBasePtr->LazySpecializations = nullptr;
351 unsigned SpecSize = (*Specs++).getRawValue();
352 for (unsigned I = 0; I != SpecSize; ++I)
353 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
354 }
355}
356
357template<class EntryType, typename... ProfileArguments>
360 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
361 ProfileArguments&&... ProfileArgs) {
362 using SETraits = SpecEntryTraits<EntryType>;
363
364 llvm::FoldingSetNodeID ID;
365 EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
366 getASTContext());
367 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
368 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
369}
370
371template<class Derived, class EntryType>
373 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
374 void *InsertPos) {
375 using SETraits = SpecEntryTraits<EntryType>;
376
377 if (InsertPos) {
378#ifndef NDEBUG
379 void *CorrectInsertPos;
380 assert(!findSpecializationImpl(Specializations,
381 CorrectInsertPos,
382 SETraits::getTemplateArgs(Entry)) &&
383 InsertPos == CorrectInsertPos &&
384 "given incorrect InsertPos for specialization");
385#endif
386 Specializations.InsertNode(Entry, InsertPos);
387 } else {
388 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
389 (void)Existing;
390 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
391 "non-canonical specialization?");
392 }
393
395 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
396 SETraits::getDecl(Entry));
397}
398
401 auto *CommonPtr = getCommonPtr();
402 if (!CommonPtr->InjectedArgs) {
403 auto &Context = getASTContext();
405 Context.getInjectedTemplateArgs(Params, TemplateArgs);
406 CommonPtr->InjectedArgs =
407 new (Context) TemplateArgument[TemplateArgs.size()];
408 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
409 CommonPtr->InjectedArgs);
410 }
411
412 return llvm::ArrayRef(CommonPtr->InjectedArgs, Params->size());
413}
414
415//===----------------------------------------------------------------------===//
416// FunctionTemplateDecl Implementation
417//===----------------------------------------------------------------------===//
418
421 DeclarationName Name,
423 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
424 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
425 if (Invalid)
426 TD->setInvalidDecl();
427 return TD;
428}
429
432 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
433 DeclarationName(), nullptr, nullptr);
434}
435
438 auto *CommonPtr = new (C) Common;
439 C.addDestruction(CommonPtr);
440 return CommonPtr;
441}
442
445}
446
447llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
451}
452
455 void *&InsertPos) {
456 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
457}
458
460 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
461 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
462 InsertPos);
463}
464
467
468 // If we haven't created a common pointer yet, then it can just be created
469 // with the usual method.
470 if (!Base::Common)
471 return;
472
473 Common *ThisCommon = static_cast<Common *>(Base::Common);
474 Common *PrevCommon = nullptr;
476 for (; Prev; Prev = Prev->getPreviousDecl()) {
477 if (Prev->Base::Common) {
478 PrevCommon = static_cast<Common *>(Prev->Base::Common);
479 break;
480 }
481 PreviousDecls.push_back(Prev);
482 }
483
484 // If the previous redecl chain hasn't created a common pointer yet, then just
485 // use this common pointer.
486 if (!PrevCommon) {
487 for (auto *D : PreviousDecls)
488 D->Base::Common = ThisCommon;
489 return;
490 }
491
492 // Ensure we don't leak any important state.
493 assert(ThisCommon->Specializations.size() == 0 &&
494 "Can't merge incompatible declarations!");
495
496 Base::Common = PrevCommon;
497}
498
499//===----------------------------------------------------------------------===//
500// ClassTemplateDecl Implementation
501//===----------------------------------------------------------------------===//
502
505 DeclarationName Name,
506 TemplateParameterList *Params,
507 NamedDecl *Decl) {
508 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
509 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
510 if (Invalid)
511 TD->setInvalidDecl();
512 return TD;
513}
514
516 GlobalDeclID ID) {
517 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
518 DeclarationName(), nullptr, nullptr);
519}
520
523}
524
525llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
529}
530
531llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
535}
536
539 auto *CommonPtr = new (C) Common;
540 C.addDestruction(CommonPtr);
541 return CommonPtr;
542}
543
546 void *&InsertPos) {
547 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
548}
549
551 void *InsertPos) {
552 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
553}
554
558 TemplateParameterList *TPL, void *&InsertPos) {
559 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
560 TPL);
561}
562
564 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
565 TemplateParameterList *TPL, const ASTContext &Context) {
566 ID.AddInteger(TemplateArgs.size());
567 for (const TemplateArgument &TemplateArg : TemplateArgs)
568 TemplateArg.Profile(ID, Context);
569 TPL->Profile(ID, Context);
570}
571
574 void *InsertPos) {
575 if (InsertPos)
576 getPartialSpecializations().InsertNode(D, InsertPos);
577 else {
579 = getPartialSpecializations().GetOrInsertNode(D);
580 (void)Existing;
581 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
582 }
583
585 L->AddedCXXTemplateSpecialization(this, D);
586}
587
590 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
592 PS.clear();
593 PS.reserve(PartialSpecs.size());
594 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
595 PS.push_back(P.getMostRecentDecl());
596}
597
600 ASTContext &Context = getASTContext();
603 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
604 return P.getMostRecentDecl();
605 }
606
607 return nullptr;
608}
609
613 Decl *DCanon = D->getCanonicalDecl();
615 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
616 return P.getMostRecentDecl();
617 }
618
619 return nullptr;
620}
621
624 Common *CommonPtr = getCommonPtr();
625 if (!CommonPtr->InjectedClassNameType.isNull())
626 return CommonPtr->InjectedClassNameType;
627
628 // C++0x [temp.dep.type]p2:
629 // The template argument list of a primary template is a template argument
630 // list in which the nth template argument has the value of the nth template
631 // parameter of the class template. If the nth template parameter is a
632 // template parameter pack (14.5.3), the nth template argument is a pack
633 // expansion (14.5.3) whose pattern is the name of the template parameter
634 // pack.
635 ASTContext &Context = getASTContext();
638 Context.getInjectedTemplateArgs(Params, TemplateArgs);
640 /*NNS=*/nullptr, /*TemplateKeyword=*/false, TemplateName(this));
641 CommonPtr->InjectedClassNameType =
642 Context.getTemplateSpecializationType(Name, TemplateArgs);
643 return CommonPtr->InjectedClassNameType;
644}
645
646//===----------------------------------------------------------------------===//
647// TemplateTypeParm Allocation/Deallocation Method Implementations
648//===----------------------------------------------------------------------===//
649
651 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
652 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
653 bool Typename, bool ParameterPack, bool HasTypeConstraint,
654 std::optional<unsigned> NumExpanded) {
655 auto *TTPDecl =
656 new (C, DC,
657 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
658 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
659 HasTypeConstraint, NumExpanded);
660 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
661 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
662 return TTPDecl;
663}
664
667 return new (C, ID)
669 false, false, std::nullopt);
670}
671
674 bool HasTypeConstraint) {
675 return new (C, ID,
676 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
678 false, HasTypeConstraint, std::nullopt);
679}
680
683 : SourceLocation();
684}
685
688 return SourceRange(getBeginLoc(),
690 // TypeDecl::getSourceRange returns a range containing name location, which is
691 // wrong for unnamed template parameters. e.g:
692 // it will return <[[typename>]] instead of <[[typename]]>
693 if (getDeclName().isEmpty())
694 return SourceRange(getBeginLoc());
696}
697
699 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
700 if (DefArg.getArgument().isNull())
701 DefaultArgument.set(nullptr);
702 else
703 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
704}
705
708}
709
712}
713
716}
717
719 ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint) {
720 assert(HasTypeConstraint &&
721 "HasTypeConstraint=true must be passed at construction in order to "
722 "call setTypeConstraint");
723 assert(!TypeConstraintInitialized &&
724 "TypeConstraint was already initialized!");
725 new (getTrailingObjects<TypeConstraint>())
726 TypeConstraint(Loc, ImmediatelyDeclaredConstraint);
727 TypeConstraintInitialized = true;
728}
729
730//===----------------------------------------------------------------------===//
731// NonTypeTemplateParmDecl Method Implementations
732//===----------------------------------------------------------------------===//
733
734NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
735 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
736 unsigned P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
737 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
738 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
739 TemplateParmPosition(D, P), ParameterPack(true),
740 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
741 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
742 auto TypesAndInfos =
743 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
744 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
745 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
746 TypesAndInfos[I].second = ExpandedTInfos[I];
747 }
748 }
749}
750
752 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
753 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
754 QualType T, bool ParameterPack, TypeSourceInfo *TInfo) {
755 AutoType *AT =
756 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
757 return new (C, DC,
758 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
759 Expr *>(0,
760 AT && AT->isConstrained() ? 1 : 0))
761 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,
762 TInfo);
763}
764
766 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
767 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
768 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
769 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
770 AutoType *AT = TInfo->getType()->getContainedAutoType();
771 return new (C, DC,
772 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
773 Expr *>(
774 ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))
775 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
776 ExpandedTypes, ExpandedTInfos);
777}
778
781 bool HasTypeConstraint) {
782 return new (C, ID, additionalSizeToAlloc<std::pair<QualType,
784 Expr *>(0,
785 HasTypeConstraint ? 1 : 0))
787 0, 0, nullptr, QualType(), false, nullptr);
788}
789
792 unsigned NumExpandedTypes,
793 bool HasTypeConstraint) {
794 auto *NTTP =
795 new (C, ID,
796 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
797 NumExpandedTypes, HasTypeConstraint ? 1 : 0))
799 0, 0, nullptr, QualType(), nullptr,
800 std::nullopt, std::nullopt);
801 NTTP->NumExpandedTypes = NumExpandedTypes;
802 return NTTP;
803}
804
810}
811
814 : SourceLocation();
815}
816
818 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
819 if (DefArg.getArgument().isNull())
820 DefaultArgument.set(nullptr);
821 else
822 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
823}
824
825//===----------------------------------------------------------------------===//
826// TemplateTemplateParmDecl Method Implementations
827//===----------------------------------------------------------------------===//
828
829void TemplateTemplateParmDecl::anchor() {}
830
831TemplateTemplateParmDecl::TemplateTemplateParmDecl(
832 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
835 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
836 TemplateParmPosition(D, P), Typename(Typename), ParameterPack(true),
837 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
838 if (!Expansions.empty())
839 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
840 getTrailingObjects<TemplateParameterList *>());
841}
842
845 SourceLocation L, unsigned D, unsigned P,
846 bool ParameterPack, IdentifierInfo *Id,
847 bool Typename, TemplateParameterList *Params) {
848 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
849 Typename, Params);
850}
851
854 SourceLocation L, unsigned D, unsigned P,
856 TemplateParameterList *Params,
858 return new (C, DC,
859 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
860 TemplateTemplateParmDecl(DC, L, D, P, Id, Typename, Params, Expansions);
861}
862
865 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
866 false, nullptr, false, nullptr);
867}
868
871 unsigned NumExpansions) {
872 auto *TTP =
873 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
874 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
875 false, nullptr, std::nullopt);
876 TTP->NumExpandedParams = NumExpansions;
877 return TTP;
878}
879
882 : SourceLocation();
883}
884
886 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
887 if (DefArg.getArgument().isNull())
888 DefaultArgument.set(nullptr);
889 else
890 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
891}
892
893//===----------------------------------------------------------------------===//
894// TemplateArgumentList Implementation
895//===----------------------------------------------------------------------===//
896TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
897 : NumArguments(Args.size()) {
898 std::uninitialized_copy(Args.begin(), Args.end(),
899 getTrailingObjects<TemplateArgument>());
900}
901
905 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
906 return new (Mem) TemplateArgumentList(Args);
907}
908
912 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
913 MemberSpecializationInfo *MSInfo) {
914 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
915 if (TemplateArgsAsWritten)
917 *TemplateArgsAsWritten);
918
919 void *Mem =
920 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
921 return new (Mem) FunctionTemplateSpecializationInfo(
922 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
923}
924
925//===----------------------------------------------------------------------===//
926// ClassTemplateSpecializationDecl Implementation
927//===----------------------------------------------------------------------===//
928
931 DeclContext *DC, SourceLocation StartLoc,
932 SourceLocation IdLoc,
933 ClassTemplateDecl *SpecializedTemplate,
936 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
937 SpecializedTemplate->getIdentifier(), PrevDecl),
938 SpecializedTemplate(SpecializedTemplate),
939 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
940 SpecializationKind(TSK_Undeclared) {
941}
942
944 Kind DK)
945 : CXXRecordDecl(DK, TagTypeKind::Struct, C, nullptr, SourceLocation(),
946 SourceLocation(), nullptr, nullptr),
947 SpecializationKind(TSK_Undeclared) {}
948
951 DeclContext *DC,
952 SourceLocation StartLoc,
953 SourceLocation IdLoc,
954 ClassTemplateDecl *SpecializedTemplate,
957 auto *Result =
958 new (Context, DC) ClassTemplateSpecializationDecl(
959 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
960 SpecializedTemplate, Args, PrevDecl);
961 Result->setMayHaveOutOfDateDef(false);
962
963 // If the template decl is incomplete, copy the external lexical storage from
964 // the base template. This allows instantiations of incomplete types to
965 // complete using the external AST if the template's declaration came from an
966 // external AST.
967 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
968 Result->setHasExternalLexicalStorage(
969 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
970
971 Context.getTypeDeclType(Result, PrevDecl);
972 return Result;
973}
974
977 GlobalDeclID ID) {
978 auto *Result =
979 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
980 Result->setMayHaveOutOfDateDef(false);
981 return Result;
982}
983
985 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
987
988 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
989 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
990 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
992 OS, ArgsAsWritten->arguments(), Policy,
993 getSpecializedTemplate()->getTemplateParameters());
994 } else {
995 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
997 OS, TemplateArgs.asArray(), Policy,
998 getSpecializedTemplate()->getTemplateParameters());
999 }
1000}
1001
1004 if (const auto *PartialSpec =
1005 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
1006 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1007 return SpecializedTemplate.get<ClassTemplateDecl*>();
1008}
1009
1012 switch (getSpecializationKind()) {
1013 case TSK_Undeclared:
1015 llvm::PointerUnion<ClassTemplateDecl *,
1018 assert(!Pattern.isNull() &&
1019 "Class template specialization without pattern?");
1020 if (const auto *CTPSD =
1021 Pattern.dyn_cast<ClassTemplatePartialSpecializationDecl *>())
1022 return CTPSD->getSourceRange();
1023 return Pattern.get<ClassTemplateDecl *>()->getSourceRange();
1024 }
1029 Range.setEnd(Args->getRAngleLoc());
1030 return Range;
1031 }
1035 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1036 Range.setBegin(ExternKW);
1037 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1038 TemplateKW.isValid())
1039 Range.setBegin(TemplateKW);
1041 Range.setEnd(Args->getRAngleLoc());
1042 return Range;
1043 }
1044 }
1045 llvm_unreachable("unhandled template specialization kind");
1046}
1047
1049 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1050 if (!Info) {
1051 // Don't allocate if the location is invalid.
1052 if (Loc.isInvalid())
1053 return;
1056 ExplicitInfo = Info;
1057 }
1058 Info->ExternKeywordLoc = Loc;
1059}
1060
1063 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1064 if (!Info) {
1065 // Don't allocate if the location is invalid.
1066 if (Loc.isInvalid())
1067 return;
1070 ExplicitInfo = Info;
1071 }
1072 Info->TemplateKeywordLoc = Loc;
1073}
1074
1075//===----------------------------------------------------------------------===//
1076// ConceptDecl Implementation
1077//===----------------------------------------------------------------------===//
1080 TemplateParameterList *Params,
1081 Expr *ConstraintExpr) {
1082 bool Invalid = AdoptTemplateParameterList(Params, DC);
1083 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1084 if (Invalid)
1085 TD->setInvalidDecl();
1086 return TD;
1087}
1088
1090 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1092 nullptr, nullptr);
1093
1094 return Result;
1095}
1096
1097//===----------------------------------------------------------------------===//
1098// ImplicitConceptSpecializationDecl Implementation
1099//===----------------------------------------------------------------------===//
1100ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1102 ArrayRef<TemplateArgument> ConvertedArgs)
1103 : Decl(ImplicitConceptSpecialization, DC, SL),
1104 NumTemplateArgs(ConvertedArgs.size()) {
1105 setTemplateArguments(ConvertedArgs);
1106}
1107
1108ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1109 EmptyShell Empty, unsigned NumTemplateArgs)
1110 : Decl(ImplicitConceptSpecialization, Empty),
1111 NumTemplateArgs(NumTemplateArgs) {}
1112
1114 const ASTContext &C, DeclContext *DC, SourceLocation SL,
1115 ArrayRef<TemplateArgument> ConvertedArgs) {
1116 return new (C, DC,
1117 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1118 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1119}
1120
1123 const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) {
1124 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1126}
1127
1129 ArrayRef<TemplateArgument> Converted) {
1130 assert(Converted.size() == NumTemplateArgs);
1131 std::uninitialized_copy(Converted.begin(), Converted.end(),
1132 getTrailingObjects<TemplateArgument>());
1133}
1134
1135//===----------------------------------------------------------------------===//
1136// ClassTemplatePartialSpecializationDecl Implementation
1137//===----------------------------------------------------------------------===//
1138void ClassTemplatePartialSpecializationDecl::anchor() {}
1139
1140ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
1141 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1143 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1146 Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
1147 SpecializedTemplate, Args, PrevDecl),
1148 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1149 if (AdoptTemplateParameterList(Params, this))
1151}
1152
1155 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1157 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1158 QualType CanonInjectedType,
1160 auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl(
1161 Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args,
1162 PrevDecl);
1163 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1164 Result->setMayHaveOutOfDateDef(false);
1165
1166 Context.getInjectedClassNameType(Result, CanonInjectedType);
1167 return Result;
1168}
1169
1172 GlobalDeclID ID) {
1174 Result->setMayHaveOutOfDateDef(false);
1175 return Result;
1176}
1177
1181 MT && !isMemberSpecialization())
1182 return MT->getSourceRange();
1187 return Range;
1188}
1189
1190//===----------------------------------------------------------------------===//
1191// FriendTemplateDecl Implementation
1192//===----------------------------------------------------------------------===//
1193
1194void FriendTemplateDecl::anchor() {}
1195
1201 TemplateParameterList **TPL = nullptr;
1202 if (!Params.empty()) {
1203 TPL = new (Context) TemplateParameterList *[Params.size()];
1204 llvm::copy(Params, TPL);
1205 }
1206 return new (Context, DC)
1207 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
1208}
1209
1211 GlobalDeclID ID) {
1212 return new (C, ID) FriendTemplateDecl(EmptyShell());
1213}
1214
1215//===----------------------------------------------------------------------===//
1216// TypeAliasTemplateDecl Implementation
1217//===----------------------------------------------------------------------===//
1218
1221 DeclarationName Name,
1223 bool Invalid = AdoptTemplateParameterList(Params, DC);
1224 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1225 if (Invalid)
1226 TD->setInvalidDecl();
1227 return TD;
1228}
1229
1232 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1233 DeclarationName(), nullptr, nullptr);
1234}
1235
1238 auto *CommonPtr = new (C) Common;
1239 C.addDestruction(CommonPtr);
1240 return CommonPtr;
1241}
1242
1243//===----------------------------------------------------------------------===//
1244// VarTemplateDecl Implementation
1245//===----------------------------------------------------------------------===//
1246
1248 VarTemplateDecl *CurD = this;
1249 while (CurD) {
1250 if (CurD->isThisDeclarationADefinition())
1251 return CurD;
1252 CurD = CurD->getPreviousDecl();
1253 }
1254 return nullptr;
1255}
1256
1259 TemplateParameterList *Params,
1260 VarDecl *Decl) {
1261 bool Invalid = AdoptTemplateParameterList(Params, DC);
1262 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1263 if (Invalid)
1264 TD->setInvalidDecl();
1265 return TD;
1266}
1267
1269 GlobalDeclID ID) {
1270 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1271 DeclarationName(), nullptr, nullptr);
1272}
1273
1276}
1277
1278llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1281 return getCommonPtr()->Specializations;
1282}
1283
1284llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1288}
1289
1292 auto *CommonPtr = new (C) Common;
1293 C.addDestruction(CommonPtr);
1294 return CommonPtr;
1295}
1296
1299 void *&InsertPos) {
1300 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
1301}
1302
1304 void *InsertPos) {
1305 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1306}
1307
1310 TemplateParameterList *TPL, void *&InsertPos) {
1311 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1312 TPL);
1313}
1314
1316 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1317 TemplateParameterList *TPL, const ASTContext &Context) {
1318 ID.AddInteger(TemplateArgs.size());
1319 for (const TemplateArgument &TemplateArg : TemplateArgs)
1320 TemplateArg.Profile(ID, Context);
1321 TPL->Profile(ID, Context);
1322}
1323
1325 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1326 if (InsertPos)
1327 getPartialSpecializations().InsertNode(D, InsertPos);
1328 else {
1330 getPartialSpecializations().GetOrInsertNode(D);
1331 (void)Existing;
1332 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1333 }
1334
1336 L->AddedCXXTemplateSpecialization(this, D);
1337}
1338
1341 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1343 PS.clear();
1344 PS.reserve(PartialSpecs.size());
1345 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1346 PS.push_back(P.getMostRecentDecl());
1347}
1348
1352 Decl *DCanon = D->getCanonicalDecl();
1354 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1355 return P.getMostRecentDecl();
1356 }
1357
1358 return nullptr;
1359}
1360
1361//===----------------------------------------------------------------------===//
1362// VarTemplateSpecializationDecl Implementation
1363//===----------------------------------------------------------------------===//
1364
1366 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1367 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1369 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1370 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1371 SpecializedTemplate(SpecializedTemplate),
1372 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1373 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1374
1376 ASTContext &C)
1377 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1378 QualType(), nullptr, SC_None),
1379 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1380
1382 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1383 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1385 return new (Context, DC) VarTemplateSpecializationDecl(
1386 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1387 SpecializedTemplate, T, TInfo, S, Args);
1388}
1389
1392 GlobalDeclID ID) {
1393 return new (C, ID)
1394 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1395}
1396
1398 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1400
1401 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1402 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1403 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1405 OS, ArgsAsWritten->arguments(), Policy,
1406 getSpecializedTemplate()->getTemplateParameters());
1407 } else {
1408 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1410 OS, TemplateArgs.asArray(), Policy,
1411 getSpecializedTemplate()->getTemplateParameters());
1412 }
1413}
1414
1416 if (const auto *PartialSpec =
1417 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1418 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1419 return SpecializedTemplate.get<VarTemplateDecl *>();
1420}
1421
1423 switch (getSpecializationKind()) {
1424 case TSK_Undeclared:
1426 llvm::PointerUnion<VarTemplateDecl *,
1429 assert(!Pattern.isNull() &&
1430 "Variable template specialization without pattern?");
1431 if (const auto *VTPSD =
1432 Pattern.dyn_cast<VarTemplatePartialSpecializationDecl *>())
1433 return VTPSD->getSourceRange();
1434 VarTemplateDecl *VTD = Pattern.get<VarTemplateDecl *>();
1435 if (hasInit()) {
1437 return Definition->getSourceRange();
1438 }
1439 return VTD->getCanonicalDecl()->getSourceRange();
1440 }
1444 !hasInit() && Args)
1445 Range.setEnd(Args->getRAngleLoc());
1446 return Range;
1447 }
1451 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1452 Range.setBegin(ExternKW);
1453 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1454 TemplateKW.isValid())
1455 Range.setBegin(TemplateKW);
1457 Range.setEnd(Args->getRAngleLoc());
1458 return Range;
1459 }
1460 }
1461 llvm_unreachable("unhandled template specialization kind");
1462}
1463
1465 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1466 if (!Info) {
1467 // Don't allocate if the location is invalid.
1468 if (Loc.isInvalid())
1469 return;
1472 ExplicitInfo = Info;
1473 }
1474 Info->ExternKeywordLoc = Loc;
1475}
1476
1478 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1479 if (!Info) {
1480 // Don't allocate if the location is invalid.
1481 if (Loc.isInvalid())
1482 return;
1485 ExplicitInfo = Info;
1486 }
1487 Info->TemplateKeywordLoc = Loc;
1488}
1489
1490//===----------------------------------------------------------------------===//
1491// VarTemplatePartialSpecializationDecl Implementation
1492//===----------------------------------------------------------------------===//
1493
1494void VarTemplatePartialSpecializationDecl::anchor() {}
1495
1496VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1497 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1499 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1501 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1502 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1503 TInfo, S, Args),
1504 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1505 if (AdoptTemplateParameterList(Params, DC))
1507}
1508
1511 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1513 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1515 auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(
1516 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,
1517 Args);
1518 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1519 return Result;
1520}
1521
1524 GlobalDeclID ID) {
1525 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1526}
1527
1531 MT && !isMemberSpecialization())
1532 return MT->getSourceRange();
1537 return Range;
1538}
1539
1540static TemplateParameterList *
1542 // typename T
1544 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1545 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1546 /*HasTypeConstraint=*/false);
1547 T->setImplicit(true);
1548
1549 // T ...Ints
1550 TypeSourceInfo *TI =
1551 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1553 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1554 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1555 N->setImplicit(true);
1556
1557 // <typename T, T ...Ints>
1558 NamedDecl *P[2] = {T, N};
1560 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1561
1562 // template <typename T, ...Ints> class IntSeq
1563 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1564 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1565 /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, TPL);
1566 TemplateTemplateParm->setImplicit(true);
1567
1568 // typename T
1569 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1570 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1571 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1572 /*HasTypeConstraint=*/false);
1573 TemplateTypeParm->setImplicit(true);
1574
1575 // T N
1576 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1577 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1578 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1579 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1580 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1581 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1582 NonTypeTemplateParm};
1583
1584 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1586 Params, SourceLocation(), nullptr);
1587}
1588
1589static TemplateParameterList *
1591 // std::size_t Index
1592 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1593 auto *Index = NonTypeTemplateParmDecl::Create(
1594 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1595 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1596
1597 // typename ...T
1599 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1600 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
1601 /*HasTypeConstraint=*/false);
1602 Ts->setImplicit(true);
1603
1604 // template <std::size_t Index, typename ...T>
1605 NamedDecl *Params[] = {Index, Ts};
1607 llvm::ArrayRef(Params), SourceLocation(),
1608 nullptr);
1609}
1610
1612 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1613 switch (BTK) {
1618 }
1619
1620 llvm_unreachable("unhandled BuiltinTemplateKind!");
1621}
1622
1623void BuiltinTemplateDecl::anchor() {}
1624
1625BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1626 DeclarationName Name,
1628 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1630 BTK(BTK) {}
1631
1632TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1633 QualType T,
1634 const APValue &V) {
1635 DeclContext *DC = C.getTranslationUnitDecl();
1636 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1637 C.addDestruction(&TPOD->Value);
1638 return TPOD;
1639}
1640
1642TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1643 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1644 C.addDestruction(&TPOD->Value);
1645 return TPOD;
1646}
1647
1648void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1649 const PrintingPolicy &Policy) const {
1650 OS << "<template param ";
1651 printAsExpr(OS, Policy);
1652 OS << ">";
1653}
1654
1655void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1656 printAsExpr(OS, getASTContext().getPrintingPolicy());
1657}
1658
1659void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1660 const PrintingPolicy &Policy) const {
1661 getType().getUnqualifiedType().print(OS, Policy);
1662 printAsInit(OS, Policy);
1663}
1664
1665void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1666 printAsInit(OS, getASTContext().getPrintingPolicy());
1667}
1668
1669void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1670 const PrintingPolicy &Policy) const {
1671 getValue().printPretty(OS, Policy, getType(), &getASTContext());
1672}
1673
1675 switch (D->getKind()) {
1676 case Decl::Kind::CXXRecord:
1677 return cast<CXXRecordDecl>(D)
1678 ->getDescribedTemplate()
1679 ->getTemplateParameters();
1680 case Decl::Kind::ClassTemplate:
1681 return cast<ClassTemplateDecl>(D)->getTemplateParameters();
1682 case Decl::Kind::ClassTemplateSpecialization: {
1683 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1684 auto P = CTSD->getSpecializedTemplateOrPartial();
1685 if (const auto *CTPSD =
1687 return CTPSD->getTemplateParameters();
1688 return cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1689 }
1690 case Decl::Kind::ClassTemplatePartialSpecialization:
1691 return cast<ClassTemplatePartialSpecializationDecl>(D)
1692 ->getTemplateParameters();
1693 case Decl::Kind::TypeAliasTemplate:
1694 return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
1695 case Decl::Kind::BuiltinTemplate:
1696 return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
1697 case Decl::Kind::CXXDeductionGuide:
1698 case Decl::Kind::CXXConversion:
1699 case Decl::Kind::CXXConstructor:
1700 case Decl::Kind::CXXDestructor:
1701 case Decl::Kind::CXXMethod:
1702 case Decl::Kind::Function:
1703 return cast<FunctionDecl>(D)
1704 ->getTemplateSpecializationInfo()
1705 ->getTemplate()
1706 ->getTemplateParameters();
1707 case Decl::Kind::FunctionTemplate:
1708 return cast<FunctionTemplateDecl>(D)->getTemplateParameters();
1709 case Decl::Kind::VarTemplate:
1710 return cast<VarTemplateDecl>(D)->getTemplateParameters();
1711 case Decl::Kind::VarTemplateSpecialization: {
1712 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1713 auto P = VTSD->getSpecializedTemplateOrPartial();
1714 if (const auto *VTPSD =
1716 return VTPSD->getTemplateParameters();
1717 return cast<VarTemplateDecl *>(P)->getTemplateParameters();
1718 }
1719 case Decl::Kind::VarTemplatePartialSpecialization:
1720 return cast<VarTemplatePartialSpecializationDecl>(D)
1721 ->getTemplateParameters();
1722 case Decl::Kind::TemplateTemplateParm:
1723 return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();
1724 case Decl::Kind::Concept:
1725 return cast<ConceptDecl>(D)->getTemplateParameters();
1726 default:
1727 llvm_unreachable("Unhandled templated declaration kind");
1728 }
1729}
Defines the clang::ASTContext interface.
#define V(N, I)
Definition: ASTContext.h:3338
StringRef P
Defines enum values for all the target-independent builtin functions.
const Decl * D
Expr * E
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static TemplateParameterList * createTypePackElementParameterList(const ASTContext &C, DeclContext *DC)
static bool DefaultTemplateArgumentContainsUnexpandedPack(const TemplateParam &P)
static TemplateParameterList * createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC)
static bool AdoptTemplateParameterList(TemplateParameterList *Params, DeclContext *Owner)
static TemplateParameterList * createBuiltinTemplateParameterList(const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK)
Defines the C++ template declaration subclasses.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static StringRef getIdentifier(const Token &Tok)
uint32_t Id
Definition: SemaARM.cpp:1143
SourceRange Range
Definition: SemaObjC.cpp:757
SourceLocation Loc
Definition: SemaObjC.cpp:758
Defines the clang::SourceLocation class and associated facilities.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
Definition: APValue.cpp:693
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:186
QualType getTemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > Args, QualType Canon=QualType()) const
QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const
getInjectedClassNameType - Return the unique reference to the injected class name type for the specif...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2641
TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, TemplateName Template) const
Retrieve the template name that represents a qualified template name such as std::vector.
void getInjectedTemplateArgs(const TemplateParameterList *Params, SmallVectorImpl< TemplateArgument > &Args)
Get a template argument list with one argument per template parameter in a template parameter list,...
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
Definition: ASTContext.h:1634
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:733
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
Definition: ASTContext.h:1224
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:6368
bool isConstrained() const
Definition: Type.h:6387
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
Declaration of a class template.
void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D, void *InsertPos)
Insert the specified partial specialization knowing that it is not already in.
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this class template.
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
ClassTemplatePartialSpecializationDecl * findPartialSpecialization(ArrayRef< TemplateArgument > Args, TemplateParameterList *TPL, void *&InsertPos)
Return the partial specialization with the provided arguments if it exists, otherwise return the inse...
CommonBase * newCommon(ASTContext &C) const override
static ClassTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a class template node.
ClassTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl *D)
Find a class template partial specialization which was instantiated from the given member partial spe...
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
QualType getInjectedClassNameSpecialization()
Retrieve the template specialization type of the injected-class-name for this class template.
Common * getCommonPtr() const
ClassTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
static ClassTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty class template node.
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member class template partial specialization from which this particular class template p...
static ClassTemplatePartialSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, QualType CanonInjectedType, ClassTemplatePartialSpecializationDecl *PrevDecl)
void Profile(llvm::FoldingSetNodeID &ID) const
bool isMemberSpecialization() const
Determines whether this class template partial specialization template was a specialization of a memb...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a class template specialization, which refers to a class template with a given set of temp...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, ClassTemplateSpecializationDecl *PrevDecl)
static ClassTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the class template or class template partial specialization which was specialized by this.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the class template specialization.
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
static ClassTemplateSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef< TemplateArgument > Args, ClassTemplateSpecializationDecl *PrevDecl)
Declaration of a C++20 concept.
static ConceptDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
static ConceptDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr)
A reference to a concept and its template args, as it appears in the code.
Definition: ASTConcept.h:125
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1425
bool hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
Definition: DeclBase.h:2654
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:523
ASTMutationListener * getASTMutationListener() const
Definition: DeclBase.cpp:533
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition: DeclBase.cpp:154
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:963
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:957
Kind getKind() const
Definition: DeclBase.h:448
The name of a declaration.
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:731
SourceLocation getOuterLocStart() const
Return start of source range taking into account any outer template declarations.
Definition: Decl.cpp:2032
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2072
unsigned getNumTemplateParameterLists() const
Definition: Decl.h:819
void set(ArgType Arg)
Set the default argument.
Definition: DeclTemplate.h:354
This represents one expression.
Definition: Expr.h:110
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
Definition: Expr.h:239
virtual Decl * GetExternalDecl(GlobalDeclID ID)
Resolve a declaration ID into a declaration, potentially building a new declaration.
Declaration of a friend template.
static FriendTemplateDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc, MutableArrayRef< TemplateParameterList * > Params, FriendUnion Friend, SourceLocation FriendLoc)
llvm::PointerUnion< NamedDecl *, TypeSourceInfo * > FriendUnion
static FriendTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Represents a function declaration or definition.
Definition: Decl.h:1932
Declaration of a template function.
Definition: DeclTemplate.h:957
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
void addSpecialization(FunctionTemplateSpecializationInfo *Info, void *InsertPos)
Add a specialization of this function template.
CommonBase * newCommon(ASTContext &C) const override
Common * getCommonPtr() const
Definition: DeclTemplate.h:979
FunctionTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this function template, or nullptr if no such declaration exists...
static FunctionTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty function template node.
static FunctionTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > & getSpecializations() const
Retrieve the set of function template specializations of this function template.
void mergePrevDecl(FunctionTemplateDecl *Prev)
Merge Prev with our RedeclarableTemplateDecl::Common.
void LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
Provides information about a function template specialization, which is a FunctionDecl that has been ...
Definition: DeclTemplate.h:467
static FunctionTemplateSpecializationInfo * Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs, const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI, MemberSpecializationInfo *MSInfo)
One of these records is kept for each identifier that is lexed.
void setTemplateArguments(ArrayRef< TemplateArgument > Converted)
static ImplicitConceptSpecializationDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef< TemplateArgument > ConvertedArgs)
static ImplicitConceptSpecializationDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs)
Provides information a specialization of a member of a class template, which may be a member function...
Definition: DeclTemplate.h:615
This represents a decl that may have a name.
Definition: Decl.h:249
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:315
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:1811
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
static NonTypeTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint)
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo)
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
A (possibly-)qualified type.
Definition: Type.h:941
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1008
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:7743
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:7837
Declaration of a redeclarable template.
Definition: DeclTemplate.h:716
CommonBase * getCommonPtr() const
Retrieves the "common" pointer shared by all (re-)declarations of the same template.
SpecEntryTraits< EntryType >::DeclType * findSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, void *&InsertPos, ProfileArguments &&...ProfileArgs)
CommonBase * Common
Pointer to the common data shared by all declarations of this template.
Definition: DeclTemplate.h:813
virtual CommonBase * newCommon(ASTContext &C) const =0
void addSpecializationImpl(llvm::FoldingSetVector< EntryType > &Specs, EntryType *Entry, void *InsertPos)
ArrayRef< TemplateArgument > getInjectedTemplateArgs()
Retrieve the "injected" template arguments that correspond to the template parameters of this templat...
RedeclarableTemplateDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Definition: Redeclarable.h:204
RedeclarableTemplateDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:226
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
void setBegin(SourceLocation b)
SourceLocation getBegin() const
void setEnd(SourceLocation e)
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition: Decl.h:3655
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3660
unsigned getNumTemplateParameterLists() const
Definition: Decl.h:3809
A convenient class for passing around template argument information.
Definition: TemplateBase.h:632
A template argument list.
Definition: DeclTemplate.h:244
static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument list that copies the given set of template arguments.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Definition: DeclTemplate.h:274
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
SourceLocation getLocation() const
Definition: TemplateBase.h:563
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:574
SourceRange getSourceRange() const LLVM_READONLY
Represents a template argument.
Definition: TemplateBase.h:61
bool isNull() const
Determine whether this template argument has no value.
Definition: TemplateBase.h:298
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
TemplateParameterList * TemplateParams
Definition: DeclTemplate.h:445
bool isTypeAlias() const
bool hasAssociatedConstraints() const
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:426
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: DeclTemplate.h:438
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
Get the total constraint-expression associated with this template, including constraint-expressions d...
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:413
Represents a C++ template name within the type system.
Definition: TemplateName.h:203
A template parameter object.
void printAsExpr(llvm::raw_ostream &OS) const
Print this object as an equivalent expression.
const APValue & getValue() const
void printName(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const override
Print this template parameter object in a human-readable format.
void printAsInit(llvm::raw_ostream &OS) const
Print this object as an initializer suitable for a variable of the object's type.
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:144
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
bool hasAssociatedConstraints() const
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to form a template specialization.
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
Definition: DeclTemplate.h:180
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const
void getAssociatedConstraints(llvm::SmallVectorImpl< const Expr * > &AC) const
All associated constraints derived from this template parameter list, including the requires clause a...
ArrayRef< NamedDecl * > asArray()
Definition: DeclTemplate.h:139
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
SourceLocation getTemplateLoc() const
Definition: DeclTemplate.h:199
Defines the position of a template parameter within a template parameter list.
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
static TemplateTemplateParmDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
SourceLocation getDefaultArgumentLoc() const
Retrieve the location of the default argument, if any.
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter, and whether that default argument was inherited...
static TemplateTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, bool Typename, TemplateParameterList *Params)
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
Declaration of a template type parameter.
SourceLocation getDefaultArgumentLoc() const
Retrieves the location of the default argument declaration.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
unsigned getIndex() const
Retrieve the index of the template parameter.
static TemplateTypeParmDecl * CreateDeserialized(const ASTContext &C, GlobalDeclID ID)
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, std::optional< unsigned > NumExpanded=std::nullopt)
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
bool isParameterPack() const
Returns whether this is a parameter pack.
unsigned getDepth() const
Retrieve the depth of the template parameter.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
void setTypeConstraint(ConceptReference *CR, Expr *ImmediatelyDeclaredConstraint)
void setDefaultArgument(const ASTContext &C, const TemplateArgumentLoc &DefArg)
Set the default argument for this template parameter.
Declaration of an alias template.
CommonBase * newCommon(ASTContext &C) const override
static TypeAliasTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty alias template node.
static TypeAliasTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition: ASTConcept.h:228
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Definition: ASTConcept.h:243
const Type * getTypeForDecl() const
Definition: Decl.h:3387
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.h:3392
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Decl.h:3390
A container of type source information.
Definition: Type.h:7714
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:7725
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8583
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition: Type.h:2777
QualType getType() const
Definition: Decl.h:678
Represents a variable declaration or definition.
Definition: Decl.h:879
bool hasInit() const
Definition: Decl.cpp:2380
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition: Decl.cpp:2172
@ Definition
This declaration is definitely a definition.
Definition: Decl.h:1249
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 LoadLazySpecializations() const
Load any lazily-loaded specializations from the external source.
void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos)
Insert the specified specialization knowing that it is not already in.
VarTemplateDecl * getPreviousDecl()
Retrieve the previous declaration of this variable template, or nullptr if no such declaration exists...
CommonBase * newCommon(ASTContext &C) const override
static VarTemplateDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Create an empty variable template node.
static VarTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, VarDecl *Decl)
Create a variable template node.
llvm::FoldingSetVector< VarTemplatePartialSpecializationDecl > & getPartialSpecializations() const
Retrieve the set of partial specializations of this class template.
llvm::FoldingSetVector< VarTemplateSpecializationDecl > & getSpecializations() const
Retrieve the set of specializations of this variable template.
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary variable pattern.
VarTemplateSpecializationDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
VarTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl *D)
Find a variable template partial specialization which was instantiated from the given member partial ...
static VarTemplatePartialSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
VarTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member variable template partial specialization from which this particular variable temp...
bool isMemberSpecialization() const
Determines whether this variable template partial specialization was a specialization of a member par...
void Profile(llvm::FoldingSetNodeID &ID) const
static VarTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
Represents a variable template specialization, which refers to a variable template with a given set o...
VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
void setTemplateKeywordLoc(SourceLocation Loc)
Sets the location of the template keyword.
const TemplateArgumentList & getTemplateArgs() const
Retrieve the template arguments of the variable template specialization.
SourceLocation getTemplateKeywordLoc() const
Gets the location of the template keyword, if present.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
static VarTemplateSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef< TemplateArgument > Args)
llvm::PointerUnion< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the variable template or variable template partial specialization which was specialized by t...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
VarTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
SourceLocation getExternKeywordLoc() const
Gets the location of the extern keyword, if present.
static VarTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID)
void setExternKeywordLoc(SourceLocation Loc)
Sets the location of the extern keyword.
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
The JSON file list parser is used to communicate input to InstallAPI.
StorageClass
Storage classes.
Definition: Specifiers.h:245
@ SC_None
Definition: Specifiers.h:247
void * allocateDefaultArgStorageChain(const ASTContext &C)
@ Result
The result type of a method or function.
TemplateParameterList * getReplacedTemplateParameterList(Decl *D)
Internal helper used by Subst* nodes to retrieve the parameter list for their AssociatedDecl.
TagTypeKind
The kind of a tag type.
Definition: Type.h:6683
BuiltinTemplateKind
Kinds of BuiltinTemplateDecl.
Definition: Builtins.h:307
@ BTK__type_pack_element
This names the __type_pack_element BuiltinTemplateDecl.
Definition: Builtins.h:312
@ BTK__make_integer_seq
This names the __make_integer_seq BuiltinTemplateDecl.
Definition: Builtins.h:309
std::optional< unsigned > getExpandedPackSize(const NamedDecl *Param)
Check whether the template parameter is a pack expansion, and if so, determine the number of paramete...
const FunctionProtoType * T
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
Definition: Specifiers.h:185
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition: Specifiers.h:203
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition: Specifiers.h:199
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition: Specifiers.h:195
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition: Specifiers.h:191
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:188
@ Struct
The "struct" keyword introduces the elaborated-type-specifier.
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
#define true
Definition: stdbool.h:25
#define false
Definition: stdbool.h:26
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:676
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
Data that is common to all of the declarations of a given class template.
llvm::FoldingSetVector< ClassTemplatePartialSpecializationDecl > PartialSpecializations
The class template partial specializations for this class template.
llvm::FoldingSetVector< ClassTemplateSpecializationDecl > Specializations
The class template specializations for this class template, including explicit specializations and in...
QualType InjectedClassNameType
The injected-class-name type for this class template.
A placeholder type used to construct an empty shell of a decl-derived type that will be filled in lat...
Definition: DeclBase.h:102
Provides information about an explicit instantiation of a variable or class template.
const ASTTemplateArgumentListInfo * TemplateArgsAsWritten
The template arguments as written..
Data that is common to all of the declarations of a given function template.
Definition: DeclTemplate.h:963
llvm::FoldingSetVector< FunctionTemplateSpecializationInfo > Specializations
The function template specializations for this function template, including explicit specializations ...
Definition: DeclTemplate.h:966
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
unsigned AlwaysIncludeTypeForTemplateArgument
Whether to use type suffixes (eg: 1U) on integral non-type template parameters.
GlobalDeclID * LazySpecializations
If non-null, points to an array of specializations (including partial specializations) known only by ...
Definition: DeclTemplate.h:799
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 ...