[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang / lib / AST / DeclTemplate.cpp
blobbe385ca1152546e14fd474ccf9b48f5d8388bbe2
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.
11 //===----------------------------------------------------------------------===//
13 #include "clang/AST/DeclTemplate.h"
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/ASTMutationListener.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclarationName.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/ExternalASTSource.h"
20 #include "clang/AST/TemplateBase.h"
21 #include "clang/AST/TemplateName.h"
22 #include "clang/AST/Type.h"
23 #include "clang/AST/TypeLoc.h"
24 #include "clang/Basic/Builtins.h"
25 #include "clang/Basic/LLVM.h"
26 #include "clang/Basic/SourceLocation.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>
41 using namespace clang;
43 //===----------------------------------------------------------------------===//
44 // TemplateParameterList Implementation
45 //===----------------------------------------------------------------------===//
48 TemplateParameterList::TemplateParameterList(const ASTContext& C,
49 SourceLocation TemplateLoc,
50 SourceLocation LAngleLoc,
51 ArrayRef<NamedDecl *> Params,
52 SourceLocation RAngleLoc,
53 Expr *RequiresClause)
54 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
55 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
56 HasRequiresClause(RequiresClause != nullptr),
57 HasConstrainedParameters(false) {
58 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
59 NamedDecl *P = Params[Idx];
60 begin()[Idx] = P;
62 bool IsPack = P->isTemplateParameterPack();
63 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
64 if (!IsPack && NTTP->getType()->containsUnexpandedParameterPack())
65 ContainsUnexpandedParameterPack = true;
66 if (NTTP->hasPlaceholderTypeConstraint())
67 HasConstrainedParameters = true;
68 } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) {
69 if (!IsPack &&
70 TTP->getTemplateParameters()->containsUnexpandedParameterPack())
71 ContainsUnexpandedParameterPack = true;
72 } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
73 if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
74 if (TC->getImmediatelyDeclaredConstraint()
75 ->containsUnexpandedParameterPack())
76 ContainsUnexpandedParameterPack = true;
78 if (TTP->hasTypeConstraint())
79 HasConstrainedParameters = true;
80 } else {
81 llvm_unreachable("unexpected template parameter type");
83 // FIXME: If a default argument contains an unexpanded parameter pack, the
84 // template parameter list does too.
87 if (HasRequiresClause) {
88 if (RequiresClause->containsUnexpandedParameterPack())
89 ContainsUnexpandedParameterPack = true;
90 *getTrailingObjects<Expr *>() = RequiresClause;
94 bool TemplateParameterList::containsUnexpandedParameterPack() const {
95 if (ContainsUnexpandedParameterPack)
96 return true;
97 if (!HasConstrainedParameters)
98 return false;
100 // An implicit constrained parameter might have had a use of an unexpanded
101 // pack added to it after the template parameter list was created. All
102 // implicit parameters are at the end of the parameter list.
103 for (const NamedDecl *Param : llvm::reverse(asArray())) {
104 if (!Param->isImplicit())
105 break;
107 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
108 const auto *TC = TTP->getTypeConstraint();
109 if (TC && TC->getImmediatelyDeclaredConstraint()
110 ->containsUnexpandedParameterPack())
111 return true;
115 return false;
118 TemplateParameterList *
119 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
120 SourceLocation LAngleLoc,
121 ArrayRef<NamedDecl *> Params,
122 SourceLocation RAngleLoc, Expr *RequiresClause) {
123 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
124 Params.size(), RequiresClause ? 1u : 0u),
125 alignof(TemplateParameterList));
126 return new (Mem) TemplateParameterList(C, TemplateLoc, LAngleLoc, Params,
127 RAngleLoc, RequiresClause);
130 void TemplateParameterList::Profile(llvm::FoldingSetNodeID &ID,
131 const ASTContext &C) const {
132 const Expr *RC = getRequiresClause();
133 ID.AddBoolean(RC != nullptr);
134 if (RC)
135 RC->Profile(ID, C, /*Canonical=*/true);
136 ID.AddInteger(size());
137 for (NamedDecl *D : *this) {
138 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
139 ID.AddInteger(0);
140 ID.AddBoolean(NTTP->isParameterPack());
141 NTTP->getType().getCanonicalType().Profile(ID);
142 ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint());
143 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
144 E->Profile(ID, C, /*Canonical=*/true);
145 continue;
147 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {
148 ID.AddInteger(1);
149 ID.AddBoolean(TTP->isParameterPack());
150 ID.AddBoolean(TTP->hasTypeConstraint());
151 if (const TypeConstraint *TC = TTP->getTypeConstraint())
152 TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,
153 /*Canonical=*/true);
154 continue;
156 const auto *TTP = cast<TemplateTemplateParmDecl>(D);
157 ID.AddInteger(2);
158 ID.AddBoolean(TTP->isParameterPack());
159 TTP->getTemplateParameters()->Profile(ID, C);
163 unsigned TemplateParameterList::getMinRequiredArguments() const {
164 unsigned NumRequiredArgs = 0;
165 for (const NamedDecl *P : asArray()) {
166 if (P->isTemplateParameterPack()) {
167 if (std::optional<unsigned> Expansions = getExpandedPackSize(P)) {
168 NumRequiredArgs += *Expansions;
169 continue;
171 break;
174 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
175 if (TTP->hasDefaultArgument())
176 break;
177 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
178 if (NTTP->hasDefaultArgument())
179 break;
180 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
181 break;
183 ++NumRequiredArgs;
186 return NumRequiredArgs;
189 unsigned TemplateParameterList::getDepth() const {
190 if (size() == 0)
191 return 0;
193 const NamedDecl *FirstParm = getParam(0);
194 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
195 return TTP->getDepth();
196 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
197 return NTTP->getDepth();
198 else
199 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
202 static bool AdoptTemplateParameterList(TemplateParameterList *Params,
203 DeclContext *Owner) {
204 bool Invalid = false;
205 for (NamedDecl *P : *Params) {
206 P->setDeclContext(Owner);
208 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
209 if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner))
210 Invalid = true;
212 if (P->isInvalidDecl())
213 Invalid = true;
215 return Invalid;
218 void TemplateParameterList::
219 getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
220 if (HasConstrainedParameters)
221 for (const NamedDecl *Param : *this) {
222 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
223 if (const auto *TC = TTP->getTypeConstraint())
224 AC.push_back(TC->getImmediatelyDeclaredConstraint());
225 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
226 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
227 AC.push_back(E);
230 if (HasRequiresClause)
231 AC.push_back(getRequiresClause());
234 bool TemplateParameterList::hasAssociatedConstraints() const {
235 return HasRequiresClause || HasConstrainedParameters;
238 bool TemplateParameterList::shouldIncludeTypeForArgument(
239 const PrintingPolicy &Policy, const TemplateParameterList *TPL,
240 unsigned Idx) {
241 if (!TPL || Idx >= TPL->size() || Policy.AlwaysIncludeTypeForTemplateArgument)
242 return true;
243 const NamedDecl *TemplParam = TPL->getParam(Idx);
244 if (const auto *ParamValueDecl =
245 dyn_cast<NonTypeTemplateParmDecl>(TemplParam))
246 if (ParamValueDecl->getType()->getContainedDeducedType())
247 return true;
248 return false;
251 namespace clang {
253 void *allocateDefaultArgStorageChain(const ASTContext &C) {
254 return new (C) char[sizeof(void*) * 2];
257 } // namespace clang
259 //===----------------------------------------------------------------------===//
260 // TemplateDecl Implementation
261 //===----------------------------------------------------------------------===//
263 TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
264 DeclarationName Name, TemplateParameterList *Params,
265 NamedDecl *Decl)
266 : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
268 void TemplateDecl::anchor() {}
270 void TemplateDecl::
271 getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
272 TemplateParams->getAssociatedConstraints(AC);
273 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
274 if (const Expr *TRC = FD->getTrailingRequiresClause())
275 AC.push_back(TRC);
278 bool TemplateDecl::hasAssociatedConstraints() const {
279 if (TemplateParams->hasAssociatedConstraints())
280 return true;
281 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
282 return FD->getTrailingRequiresClause();
283 return false;
286 bool TemplateDecl::isTypeAlias() const {
287 switch (getKind()) {
288 case TemplateDecl::TypeAliasTemplate:
289 case TemplateDecl::BuiltinTemplate:
290 return true;
291 default:
292 return false;
296 //===----------------------------------------------------------------------===//
297 // RedeclarableTemplateDecl Implementation
298 //===----------------------------------------------------------------------===//
300 void RedeclarableTemplateDecl::anchor() {}
302 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
303 if (Common)
304 return Common;
306 // Walk the previous-declaration chain until we either find a declaration
307 // with a common pointer or we run out of previous declarations.
308 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
309 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
310 Prev = Prev->getPreviousDecl()) {
311 if (Prev->Common) {
312 Common = Prev->Common;
313 break;
316 PrevDecls.push_back(Prev);
319 // If we never found a common pointer, allocate one now.
320 if (!Common) {
321 // FIXME: If any of the declarations is from an AST file, we probably
322 // need an update record to add the common data.
324 Common = newCommon(getASTContext());
327 // Update any previous declarations we saw with the common pointer.
328 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
329 Prev->Common = Common;
331 return Common;
334 void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
335 // Grab the most recent declaration to ensure we've loaded any lazy
336 // redeclarations of this template.
337 CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
338 if (CommonBasePtr->LazySpecializations) {
339 ASTContext &Context = getASTContext();
340 uint32_t *Specs = CommonBasePtr->LazySpecializations;
341 CommonBasePtr->LazySpecializations = nullptr;
342 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
343 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
347 template<class EntryType, typename... ProfileArguments>
348 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
349 RedeclarableTemplateDecl::findSpecializationImpl(
350 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
351 ProfileArguments&&... ProfileArgs) {
352 using SETraits = SpecEntryTraits<EntryType>;
354 llvm::FoldingSetNodeID ID;
355 EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
356 getASTContext());
357 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
358 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
361 template<class Derived, class EntryType>
362 void RedeclarableTemplateDecl::addSpecializationImpl(
363 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
364 void *InsertPos) {
365 using SETraits = SpecEntryTraits<EntryType>;
367 if (InsertPos) {
368 #ifndef NDEBUG
369 void *CorrectInsertPos;
370 assert(!findSpecializationImpl(Specializations,
371 CorrectInsertPos,
372 SETraits::getTemplateArgs(Entry)) &&
373 InsertPos == CorrectInsertPos &&
374 "given incorrect InsertPos for specialization");
375 #endif
376 Specializations.InsertNode(Entry, InsertPos);
377 } else {
378 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
379 (void)Existing;
380 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
381 "non-canonical specialization?");
384 if (ASTMutationListener *L = getASTMutationListener())
385 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
386 SETraits::getDecl(Entry));
389 ArrayRef<TemplateArgument> RedeclarableTemplateDecl::getInjectedTemplateArgs() {
390 TemplateParameterList *Params = getTemplateParameters();
391 auto *CommonPtr = getCommonPtr();
392 if (!CommonPtr->InjectedArgs) {
393 auto &Context = getASTContext();
394 SmallVector<TemplateArgument, 16> TemplateArgs;
395 Context.getInjectedTemplateArgs(Params, TemplateArgs);
396 CommonPtr->InjectedArgs =
397 new (Context) TemplateArgument[TemplateArgs.size()];
398 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
399 CommonPtr->InjectedArgs);
402 return llvm::ArrayRef(CommonPtr->InjectedArgs, Params->size());
405 //===----------------------------------------------------------------------===//
406 // FunctionTemplateDecl Implementation
407 //===----------------------------------------------------------------------===//
409 FunctionTemplateDecl *
410 FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
411 DeclarationName Name,
412 TemplateParameterList *Params, NamedDecl *Decl) {
413 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
414 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
415 if (Invalid)
416 TD->setInvalidDecl();
417 return TD;
420 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
421 unsigned ID) {
422 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
423 DeclarationName(), nullptr, nullptr);
426 RedeclarableTemplateDecl::CommonBase *
427 FunctionTemplateDecl::newCommon(ASTContext &C) const {
428 auto *CommonPtr = new (C) Common;
429 C.addDestruction(CommonPtr);
430 return CommonPtr;
433 void FunctionTemplateDecl::LoadLazySpecializations() const {
434 loadLazySpecializationsImpl();
437 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
438 FunctionTemplateDecl::getSpecializations() const {
439 LoadLazySpecializations();
440 return getCommonPtr()->Specializations;
443 FunctionDecl *
444 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
445 void *&InsertPos) {
446 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
449 void FunctionTemplateDecl::addSpecialization(
450 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
451 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
452 InsertPos);
455 void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
456 using Base = RedeclarableTemplateDecl;
458 // If we haven't created a common pointer yet, then it can just be created
459 // with the usual method.
460 if (!Base::Common)
461 return;
463 Common *ThisCommon = static_cast<Common *>(Base::Common);
464 Common *PrevCommon = nullptr;
465 SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
466 for (; Prev; Prev = Prev->getPreviousDecl()) {
467 if (Prev->Base::Common) {
468 PrevCommon = static_cast<Common *>(Prev->Base::Common);
469 break;
471 PreviousDecls.push_back(Prev);
474 // If the previous redecl chain hasn't created a common pointer yet, then just
475 // use this common pointer.
476 if (!PrevCommon) {
477 for (auto *D : PreviousDecls)
478 D->Base::Common = ThisCommon;
479 return;
482 // Ensure we don't leak any important state.
483 assert(ThisCommon->Specializations.size() == 0 &&
484 "Can't merge incompatible declarations!");
486 Base::Common = PrevCommon;
489 //===----------------------------------------------------------------------===//
490 // ClassTemplateDecl Implementation
491 //===----------------------------------------------------------------------===//
493 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC,
494 SourceLocation L,
495 DeclarationName Name,
496 TemplateParameterList *Params,
497 NamedDecl *Decl) {
498 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
499 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
500 if (Invalid)
501 TD->setInvalidDecl();
502 return TD;
505 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
506 unsigned ID) {
507 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
508 DeclarationName(), nullptr, nullptr);
511 void ClassTemplateDecl::LoadLazySpecializations() const {
512 loadLazySpecializationsImpl();
515 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
516 ClassTemplateDecl::getSpecializations() const {
517 LoadLazySpecializations();
518 return getCommonPtr()->Specializations;
521 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
522 ClassTemplateDecl::getPartialSpecializations() const {
523 LoadLazySpecializations();
524 return getCommonPtr()->PartialSpecializations;
527 RedeclarableTemplateDecl::CommonBase *
528 ClassTemplateDecl::newCommon(ASTContext &C) const {
529 auto *CommonPtr = new (C) Common;
530 C.addDestruction(CommonPtr);
531 return CommonPtr;
534 ClassTemplateSpecializationDecl *
535 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
536 void *&InsertPos) {
537 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
540 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
541 void *InsertPos) {
542 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
545 ClassTemplatePartialSpecializationDecl *
546 ClassTemplateDecl::findPartialSpecialization(
547 ArrayRef<TemplateArgument> Args,
548 TemplateParameterList *TPL, void *&InsertPos) {
549 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
550 TPL);
553 void ClassTemplatePartialSpecializationDecl::Profile(
554 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
555 TemplateParameterList *TPL, const ASTContext &Context) {
556 ID.AddInteger(TemplateArgs.size());
557 for (const TemplateArgument &TemplateArg : TemplateArgs)
558 TemplateArg.Profile(ID, Context);
559 TPL->Profile(ID, Context);
562 void ClassTemplateDecl::AddPartialSpecialization(
563 ClassTemplatePartialSpecializationDecl *D,
564 void *InsertPos) {
565 if (InsertPos)
566 getPartialSpecializations().InsertNode(D, InsertPos);
567 else {
568 ClassTemplatePartialSpecializationDecl *Existing
569 = getPartialSpecializations().GetOrInsertNode(D);
570 (void)Existing;
571 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
574 if (ASTMutationListener *L = getASTMutationListener())
575 L->AddedCXXTemplateSpecialization(this, D);
578 void ClassTemplateDecl::getPartialSpecializations(
579 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) const {
580 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
581 = getPartialSpecializations();
582 PS.clear();
583 PS.reserve(PartialSpecs.size());
584 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
585 PS.push_back(P.getMostRecentDecl());
588 ClassTemplatePartialSpecializationDecl *
589 ClassTemplateDecl::findPartialSpecialization(QualType T) {
590 ASTContext &Context = getASTContext();
591 for (ClassTemplatePartialSpecializationDecl &P :
592 getPartialSpecializations()) {
593 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
594 return P.getMostRecentDecl();
597 return nullptr;
600 ClassTemplatePartialSpecializationDecl *
601 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
602 ClassTemplatePartialSpecializationDecl *D) {
603 Decl *DCanon = D->getCanonicalDecl();
604 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
605 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
606 return P.getMostRecentDecl();
609 return nullptr;
612 QualType
613 ClassTemplateDecl::getInjectedClassNameSpecialization() {
614 Common *CommonPtr = getCommonPtr();
615 if (!CommonPtr->InjectedClassNameType.isNull())
616 return CommonPtr->InjectedClassNameType;
618 // C++0x [temp.dep.type]p2:
619 // The template argument list of a primary template is a template argument
620 // list in which the nth template argument has the value of the nth template
621 // parameter of the class template. If the nth template parameter is a
622 // template parameter pack (14.5.3), the nth template argument is a pack
623 // expansion (14.5.3) whose pattern is the name of the template parameter
624 // pack.
625 ASTContext &Context = getASTContext();
626 TemplateParameterList *Params = getTemplateParameters();
627 SmallVector<TemplateArgument, 16> TemplateArgs;
628 Context.getInjectedTemplateArgs(Params, TemplateArgs);
629 CommonPtr->InjectedClassNameType
630 = Context.getTemplateSpecializationType(TemplateName(this),
631 TemplateArgs);
632 return CommonPtr->InjectedClassNameType;
635 //===----------------------------------------------------------------------===//
636 // TemplateTypeParm Allocation/Deallocation Method Implementations
637 //===----------------------------------------------------------------------===//
639 TemplateTypeParmDecl *TemplateTypeParmDecl::Create(
640 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
641 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
642 bool Typename, bool ParameterPack, bool HasTypeConstraint,
643 std::optional<unsigned> NumExpanded) {
644 auto *TTPDecl =
645 new (C, DC,
646 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
647 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
648 HasTypeConstraint, NumExpanded);
649 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
650 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
651 return TTPDecl;
654 TemplateTypeParmDecl *
655 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
656 return new (C, ID)
657 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
658 false, false, std::nullopt);
661 TemplateTypeParmDecl *
662 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID,
663 bool HasTypeConstraint) {
664 return new (C, ID,
665 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
666 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
667 false, HasTypeConstraint, std::nullopt);
670 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
671 return hasDefaultArgument()
672 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
673 : SourceLocation();
676 SourceRange TemplateTypeParmDecl::getSourceRange() const {
677 if (hasDefaultArgument() && !defaultArgumentWasInherited())
678 return SourceRange(getBeginLoc(),
679 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
680 // TypeDecl::getSourceRange returns a range containing name location, which is
681 // wrong for unnamed template parameters. e.g:
682 // it will return <[[typename>]] instead of <[[typename]]>
683 else if (getDeclName().isEmpty())
684 return SourceRange(getBeginLoc());
685 return TypeDecl::getSourceRange();
688 unsigned TemplateTypeParmDecl::getDepth() const {
689 return getTypeForDecl()->castAs<TemplateTypeParmType>()->getDepth();
692 unsigned TemplateTypeParmDecl::getIndex() const {
693 return getTypeForDecl()->castAs<TemplateTypeParmType>()->getIndex();
696 bool TemplateTypeParmDecl::isParameterPack() const {
697 return getTypeForDecl()->castAs<TemplateTypeParmType>()->isParameterPack();
700 void TemplateTypeParmDecl::setTypeConstraint(
701 ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint) {
702 assert(HasTypeConstraint &&
703 "HasTypeConstraint=true must be passed at construction in order to "
704 "call setTypeConstraint");
705 assert(!TypeConstraintInitialized &&
706 "TypeConstraint was already initialized!");
707 new (getTrailingObjects<TypeConstraint>())
708 TypeConstraint(Loc, ImmediatelyDeclaredConstraint);
709 TypeConstraintInitialized = true;
712 //===----------------------------------------------------------------------===//
713 // NonTypeTemplateParmDecl Method Implementations
714 //===----------------------------------------------------------------------===//
716 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
717 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
718 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
719 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
720 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
721 TemplateParmPosition(D, P), ParameterPack(true),
722 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
723 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
724 auto TypesAndInfos =
725 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
726 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
727 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
728 TypesAndInfos[I].second = ExpandedTInfos[I];
733 NonTypeTemplateParmDecl *
734 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
735 SourceLocation StartLoc, SourceLocation IdLoc,
736 unsigned D, unsigned P, IdentifierInfo *Id,
737 QualType T, bool ParameterPack,
738 TypeSourceInfo *TInfo) {
739 AutoType *AT =
740 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
741 return new (C, DC,
742 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
743 Expr *>(0,
744 AT && AT->isConstrained() ? 1 : 0))
745 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,
746 TInfo);
749 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
750 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
751 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
752 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
753 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
754 AutoType *AT = TInfo->getType()->getContainedAutoType();
755 return new (C, DC,
756 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
757 Expr *>(
758 ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))
759 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
760 ExpandedTypes, ExpandedTInfos);
763 NonTypeTemplateParmDecl *
764 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
765 bool HasTypeConstraint) {
766 return new (C, ID, additionalSizeToAlloc<std::pair<QualType,
767 TypeSourceInfo *>,
768 Expr *>(0,
769 HasTypeConstraint ? 1 : 0))
770 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
771 0, 0, nullptr, QualType(), false, nullptr);
774 NonTypeTemplateParmDecl *
775 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
776 unsigned NumExpandedTypes,
777 bool HasTypeConstraint) {
778 auto *NTTP =
779 new (C, ID,
780 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
781 NumExpandedTypes, HasTypeConstraint ? 1 : 0))
782 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
783 0, 0, nullptr, QualType(), nullptr,
784 std::nullopt, std::nullopt);
785 NTTP->NumExpandedTypes = NumExpandedTypes;
786 return NTTP;
789 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
790 if (hasDefaultArgument() && !defaultArgumentWasInherited())
791 return SourceRange(getOuterLocStart(),
792 getDefaultArgument()->getSourceRange().getEnd());
793 return DeclaratorDecl::getSourceRange();
796 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
797 return hasDefaultArgument()
798 ? getDefaultArgument()->getSourceRange().getBegin()
799 : SourceLocation();
802 //===----------------------------------------------------------------------===//
803 // TemplateTemplateParmDecl Method Implementations
804 //===----------------------------------------------------------------------===//
806 void TemplateTemplateParmDecl::anchor() {}
808 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
809 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
810 IdentifierInfo *Id, TemplateParameterList *Params,
811 ArrayRef<TemplateParameterList *> Expansions)
812 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
813 TemplateParmPosition(D, P), ParameterPack(true),
814 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
815 if (!Expansions.empty())
816 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
817 getTrailingObjects<TemplateParameterList *>());
820 TemplateTemplateParmDecl *
821 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
822 SourceLocation L, unsigned D, unsigned P,
823 bool ParameterPack, IdentifierInfo *Id,
824 TemplateParameterList *Params) {
825 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
826 Params);
829 TemplateTemplateParmDecl *
830 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
831 SourceLocation L, unsigned D, unsigned P,
832 IdentifierInfo *Id,
833 TemplateParameterList *Params,
834 ArrayRef<TemplateParameterList *> Expansions) {
835 return new (C, DC,
836 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
837 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
840 TemplateTemplateParmDecl *
841 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
842 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
843 false, nullptr, nullptr);
846 TemplateTemplateParmDecl *
847 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
848 unsigned NumExpansions) {
849 auto *TTP =
850 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
851 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
852 nullptr, std::nullopt);
853 TTP->NumExpandedParams = NumExpansions;
854 return TTP;
857 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
858 return hasDefaultArgument() ? getDefaultArgument().getLocation()
859 : SourceLocation();
862 void TemplateTemplateParmDecl::setDefaultArgument(
863 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
864 if (DefArg.getArgument().isNull())
865 DefaultArgument.set(nullptr);
866 else
867 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
870 //===----------------------------------------------------------------------===//
871 // TemplateArgumentList Implementation
872 //===----------------------------------------------------------------------===//
873 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
874 : Arguments(getTrailingObjects<TemplateArgument>()),
875 NumArguments(Args.size()) {
876 std::uninitialized_copy(Args.begin(), Args.end(),
877 getTrailingObjects<TemplateArgument>());
880 TemplateArgumentList *
881 TemplateArgumentList::CreateCopy(ASTContext &Context,
882 ArrayRef<TemplateArgument> Args) {
883 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
884 return new (Mem) TemplateArgumentList(Args);
887 FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
888 ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
889 TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
890 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
891 MemberSpecializationInfo *MSInfo) {
892 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
893 if (TemplateArgsAsWritten)
894 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
895 *TemplateArgsAsWritten);
897 void *Mem =
898 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
899 return new (Mem) FunctionTemplateSpecializationInfo(
900 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
903 //===----------------------------------------------------------------------===//
904 // ClassTemplateSpecializationDecl Implementation
905 //===----------------------------------------------------------------------===//
907 ClassTemplateSpecializationDecl::
908 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
909 DeclContext *DC, SourceLocation StartLoc,
910 SourceLocation IdLoc,
911 ClassTemplateDecl *SpecializedTemplate,
912 ArrayRef<TemplateArgument> Args,
913 ClassTemplateSpecializationDecl *PrevDecl)
914 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
915 SpecializedTemplate->getIdentifier(), PrevDecl),
916 SpecializedTemplate(SpecializedTemplate),
917 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
918 SpecializationKind(TSK_Undeclared) {
921 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
922 Kind DK)
923 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
924 SourceLocation(), nullptr, nullptr),
925 SpecializationKind(TSK_Undeclared) {}
927 ClassTemplateSpecializationDecl *
928 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
929 DeclContext *DC,
930 SourceLocation StartLoc,
931 SourceLocation IdLoc,
932 ClassTemplateDecl *SpecializedTemplate,
933 ArrayRef<TemplateArgument> Args,
934 ClassTemplateSpecializationDecl *PrevDecl) {
935 auto *Result =
936 new (Context, DC) ClassTemplateSpecializationDecl(
937 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
938 SpecializedTemplate, Args, PrevDecl);
939 Result->setMayHaveOutOfDateDef(false);
941 // If the template decl is incomplete, copy the external lexical storage from
942 // the base template. This allows instantiations of incomplete types to
943 // complete using the external AST if the template's declaration came from an
944 // external AST.
945 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
946 Result->setHasExternalLexicalStorage(
947 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
949 Context.getTypeDeclType(Result, PrevDecl);
950 return Result;
953 ClassTemplateSpecializationDecl *
954 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
955 unsigned ID) {
956 auto *Result =
957 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
958 Result->setMayHaveOutOfDateDef(false);
959 return Result;
962 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
963 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
964 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
966 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
967 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
968 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
969 printTemplateArgumentList(
970 OS, ArgsAsWritten->arguments(), Policy,
971 getSpecializedTemplate()->getTemplateParameters());
972 } else {
973 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
974 printTemplateArgumentList(
975 OS, TemplateArgs.asArray(), Policy,
976 getSpecializedTemplate()->getTemplateParameters());
980 ClassTemplateDecl *
981 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
982 if (const auto *PartialSpec =
983 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
984 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
985 return SpecializedTemplate.get<ClassTemplateDecl*>();
988 SourceRange
989 ClassTemplateSpecializationDecl::getSourceRange() const {
990 if (ExplicitInfo) {
991 SourceLocation Begin = getTemplateKeywordLoc();
992 if (Begin.isValid()) {
993 // Here we have an explicit (partial) specialization or instantiation.
994 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
995 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
996 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
997 if (getExternLoc().isValid())
998 Begin = getExternLoc();
999 SourceLocation End = getBraceRange().getEnd();
1000 if (End.isInvalid())
1001 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
1002 return SourceRange(Begin, End);
1004 // An implicit instantiation of a class template partial specialization
1005 // uses ExplicitInfo to record the TypeAsWritten, but the source
1006 // locations should be retrieved from the instantiation pattern.
1007 using CTPSDecl = ClassTemplatePartialSpecializationDecl;
1008 auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
1009 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
1010 assert(inst_from != nullptr);
1011 return inst_from->getSourceRange();
1013 else {
1014 // No explicit info available.
1015 llvm::PointerUnion<ClassTemplateDecl *,
1016 ClassTemplatePartialSpecializationDecl *>
1017 inst_from = getInstantiatedFrom();
1018 if (inst_from.isNull())
1019 return getSpecializedTemplate()->getSourceRange();
1020 if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
1021 return ctd->getSourceRange();
1022 return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
1023 ->getSourceRange();
1027 //===----------------------------------------------------------------------===//
1028 // ConceptDecl Implementation
1029 //===----------------------------------------------------------------------===//
1030 ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
1031 SourceLocation L, DeclarationName Name,
1032 TemplateParameterList *Params,
1033 Expr *ConstraintExpr) {
1034 bool Invalid = AdoptTemplateParameterList(Params, DC);
1035 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1036 if (Invalid)
1037 TD->setInvalidDecl();
1038 return TD;
1041 ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C,
1042 unsigned ID) {
1043 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1044 DeclarationName(),
1045 nullptr, nullptr);
1047 return Result;
1050 //===----------------------------------------------------------------------===//
1051 // ImplicitConceptSpecializationDecl Implementation
1052 //===----------------------------------------------------------------------===//
1053 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1054 DeclContext *DC, SourceLocation SL,
1055 ArrayRef<TemplateArgument> ConvertedArgs)
1056 : Decl(ImplicitConceptSpecialization, DC, SL),
1057 NumTemplateArgs(ConvertedArgs.size()) {
1058 setTemplateArguments(ConvertedArgs);
1061 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1062 EmptyShell Empty, unsigned NumTemplateArgs)
1063 : Decl(ImplicitConceptSpecialization, Empty),
1064 NumTemplateArgs(NumTemplateArgs) {}
1066 ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create(
1067 const ASTContext &C, DeclContext *DC, SourceLocation SL,
1068 ArrayRef<TemplateArgument> ConvertedArgs) {
1069 return new (C, DC,
1070 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1071 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1074 ImplicitConceptSpecializationDecl *
1075 ImplicitConceptSpecializationDecl::CreateDeserialized(
1076 const ASTContext &C, unsigned ID, unsigned NumTemplateArgs) {
1077 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1078 ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);
1081 void ImplicitConceptSpecializationDecl::setTemplateArguments(
1082 ArrayRef<TemplateArgument> Converted) {
1083 assert(Converted.size() == NumTemplateArgs);
1084 std::uninitialized_copy(Converted.begin(), Converted.end(),
1085 getTrailingObjects<TemplateArgument>());
1088 //===----------------------------------------------------------------------===//
1089 // ClassTemplatePartialSpecializationDecl Implementation
1090 //===----------------------------------------------------------------------===//
1091 void ClassTemplatePartialSpecializationDecl::anchor() {}
1093 ClassTemplatePartialSpecializationDecl::
1094 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
1095 DeclContext *DC,
1096 SourceLocation StartLoc,
1097 SourceLocation IdLoc,
1098 TemplateParameterList *Params,
1099 ClassTemplateDecl *SpecializedTemplate,
1100 ArrayRef<TemplateArgument> Args,
1101 const ASTTemplateArgumentListInfo *ArgInfos,
1102 ClassTemplatePartialSpecializationDecl *PrevDecl)
1103 : ClassTemplateSpecializationDecl(Context,
1104 ClassTemplatePartialSpecialization,
1105 TK, DC, StartLoc, IdLoc,
1106 SpecializedTemplate, Args, PrevDecl),
1107 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1108 InstantiatedFromMember(nullptr, false) {
1109 if (AdoptTemplateParameterList(Params, this))
1110 setInvalidDecl();
1113 ClassTemplatePartialSpecializationDecl *
1114 ClassTemplatePartialSpecializationDecl::
1115 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
1116 SourceLocation StartLoc, SourceLocation IdLoc,
1117 TemplateParameterList *Params,
1118 ClassTemplateDecl *SpecializedTemplate,
1119 ArrayRef<TemplateArgument> Args,
1120 const TemplateArgumentListInfo &ArgInfos,
1121 QualType CanonInjectedType,
1122 ClassTemplatePartialSpecializationDecl *PrevDecl) {
1123 const ASTTemplateArgumentListInfo *ASTArgInfos =
1124 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1126 auto *Result = new (Context, DC)
1127 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
1128 Params, SpecializedTemplate, Args,
1129 ASTArgInfos, PrevDecl);
1130 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1131 Result->setMayHaveOutOfDateDef(false);
1133 Context.getInjectedClassNameType(Result, CanonInjectedType);
1134 return Result;
1137 ClassTemplatePartialSpecializationDecl *
1138 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1139 unsigned ID) {
1140 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
1141 Result->setMayHaveOutOfDateDef(false);
1142 return Result;
1145 //===----------------------------------------------------------------------===//
1146 // FriendTemplateDecl Implementation
1147 //===----------------------------------------------------------------------===//
1149 void FriendTemplateDecl::anchor() {}
1151 FriendTemplateDecl *
1152 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
1153 SourceLocation L,
1154 MutableArrayRef<TemplateParameterList *> Params,
1155 FriendUnion Friend, SourceLocation FLoc) {
1156 TemplateParameterList **TPL = nullptr;
1157 if (!Params.empty()) {
1158 TPL = new (Context) TemplateParameterList *[Params.size()];
1159 llvm::copy(Params, TPL);
1161 return new (Context, DC)
1162 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
1165 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
1166 unsigned ID) {
1167 return new (C, ID) FriendTemplateDecl(EmptyShell());
1170 //===----------------------------------------------------------------------===//
1171 // TypeAliasTemplateDecl Implementation
1172 //===----------------------------------------------------------------------===//
1174 TypeAliasTemplateDecl *
1175 TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
1176 DeclarationName Name,
1177 TemplateParameterList *Params, NamedDecl *Decl) {
1178 bool Invalid = AdoptTemplateParameterList(Params, DC);
1179 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1180 if (Invalid)
1181 TD->setInvalidDecl();
1182 return TD;
1185 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
1186 unsigned ID) {
1187 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1188 DeclarationName(), nullptr, nullptr);
1191 RedeclarableTemplateDecl::CommonBase *
1192 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
1193 auto *CommonPtr = new (C) Common;
1194 C.addDestruction(CommonPtr);
1195 return CommonPtr;
1198 //===----------------------------------------------------------------------===//
1199 // VarTemplateDecl Implementation
1200 //===----------------------------------------------------------------------===//
1202 VarTemplateDecl *VarTemplateDecl::getDefinition() {
1203 VarTemplateDecl *CurD = this;
1204 while (CurD) {
1205 if (CurD->isThisDeclarationADefinition())
1206 return CurD;
1207 CurD = CurD->getPreviousDecl();
1209 return nullptr;
1212 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
1213 SourceLocation L, DeclarationName Name,
1214 TemplateParameterList *Params,
1215 VarDecl *Decl) {
1216 bool Invalid = AdoptTemplateParameterList(Params, DC);
1217 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1218 if (Invalid)
1219 TD->setInvalidDecl();
1220 return TD;
1223 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
1224 unsigned ID) {
1225 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1226 DeclarationName(), nullptr, nullptr);
1229 void VarTemplateDecl::LoadLazySpecializations() const {
1230 loadLazySpecializationsImpl();
1233 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1234 VarTemplateDecl::getSpecializations() const {
1235 LoadLazySpecializations();
1236 return getCommonPtr()->Specializations;
1239 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1240 VarTemplateDecl::getPartialSpecializations() const {
1241 LoadLazySpecializations();
1242 return getCommonPtr()->PartialSpecializations;
1245 RedeclarableTemplateDecl::CommonBase *
1246 VarTemplateDecl::newCommon(ASTContext &C) const {
1247 auto *CommonPtr = new (C) Common;
1248 C.addDestruction(CommonPtr);
1249 return CommonPtr;
1252 VarTemplateSpecializationDecl *
1253 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1254 void *&InsertPos) {
1255 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
1258 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1259 void *InsertPos) {
1260 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1263 VarTemplatePartialSpecializationDecl *
1264 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1265 TemplateParameterList *TPL, void *&InsertPos) {
1266 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1267 TPL);
1270 void VarTemplatePartialSpecializationDecl::Profile(
1271 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1272 TemplateParameterList *TPL, const ASTContext &Context) {
1273 ID.AddInteger(TemplateArgs.size());
1274 for (const TemplateArgument &TemplateArg : TemplateArgs)
1275 TemplateArg.Profile(ID, Context);
1276 TPL->Profile(ID, Context);
1279 void VarTemplateDecl::AddPartialSpecialization(
1280 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1281 if (InsertPos)
1282 getPartialSpecializations().InsertNode(D, InsertPos);
1283 else {
1284 VarTemplatePartialSpecializationDecl *Existing =
1285 getPartialSpecializations().GetOrInsertNode(D);
1286 (void)Existing;
1287 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1290 if (ASTMutationListener *L = getASTMutationListener())
1291 L->AddedCXXTemplateSpecialization(this, D);
1294 void VarTemplateDecl::getPartialSpecializations(
1295 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const {
1296 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1297 getPartialSpecializations();
1298 PS.clear();
1299 PS.reserve(PartialSpecs.size());
1300 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1301 PS.push_back(P.getMostRecentDecl());
1304 VarTemplatePartialSpecializationDecl *
1305 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1306 VarTemplatePartialSpecializationDecl *D) {
1307 Decl *DCanon = D->getCanonicalDecl();
1308 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1309 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1310 return P.getMostRecentDecl();
1313 return nullptr;
1316 //===----------------------------------------------------------------------===//
1317 // VarTemplateSpecializationDecl Implementation
1318 //===----------------------------------------------------------------------===//
1320 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1321 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1322 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1323 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1324 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1325 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1326 SpecializedTemplate(SpecializedTemplate),
1327 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1328 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1330 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1331 ASTContext &C)
1332 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1333 QualType(), nullptr, SC_None),
1334 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1336 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1337 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1338 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1339 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1340 return new (Context, DC) VarTemplateSpecializationDecl(
1341 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1342 SpecializedTemplate, T, TInfo, S, Args);
1345 VarTemplateSpecializationDecl *
1346 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1347 return new (C, ID)
1348 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1351 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1352 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1353 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1355 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1356 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1357 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1358 printTemplateArgumentList(
1359 OS, ArgsAsWritten->arguments(), Policy,
1360 getSpecializedTemplate()->getTemplateParameters());
1361 } else {
1362 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1363 printTemplateArgumentList(
1364 OS, TemplateArgs.asArray(), Policy,
1365 getSpecializedTemplate()->getTemplateParameters());
1369 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1370 if (const auto *PartialSpec =
1371 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1372 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1373 return SpecializedTemplate.get<VarTemplateDecl *>();
1376 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1377 const TemplateArgumentListInfo &ArgsInfo) {
1378 TemplateArgsInfo =
1379 ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo);
1382 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1383 const ASTTemplateArgumentListInfo *ArgsInfo) {
1384 TemplateArgsInfo =
1385 ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo);
1388 SourceRange VarTemplateSpecializationDecl::getSourceRange() const {
1389 if (isExplicitSpecialization() && !hasInit()) {
1390 if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsInfo())
1391 return SourceRange(getOuterLocStart(), Info->getRAngleLoc());
1393 return VarDecl::getSourceRange();
1397 //===----------------------------------------------------------------------===//
1398 // VarTemplatePartialSpecializationDecl Implementation
1399 //===----------------------------------------------------------------------===//
1401 void VarTemplatePartialSpecializationDecl::anchor() {}
1403 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1404 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1405 SourceLocation IdLoc, TemplateParameterList *Params,
1406 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1407 StorageClass S, ArrayRef<TemplateArgument> Args,
1408 const ASTTemplateArgumentListInfo *ArgInfos)
1409 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1410 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1411 TInfo, S, Args),
1412 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1413 InstantiatedFromMember(nullptr, false) {
1414 if (AdoptTemplateParameterList(Params, DC))
1415 setInvalidDecl();
1418 VarTemplatePartialSpecializationDecl *
1419 VarTemplatePartialSpecializationDecl::Create(
1420 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1421 SourceLocation IdLoc, TemplateParameterList *Params,
1422 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1423 StorageClass S, ArrayRef<TemplateArgument> Args,
1424 const TemplateArgumentListInfo &ArgInfos) {
1425 const ASTTemplateArgumentListInfo *ASTArgInfos
1426 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1428 auto *Result =
1429 new (Context, DC) VarTemplatePartialSpecializationDecl(
1430 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1431 S, Args, ASTArgInfos);
1432 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1433 return Result;
1436 VarTemplatePartialSpecializationDecl *
1437 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1438 unsigned ID) {
1439 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1442 SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {
1443 if (isExplicitSpecialization() && !hasInit()) {
1444 if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsAsWritten())
1445 return SourceRange(getOuterLocStart(), Info->getRAngleLoc());
1447 return VarDecl::getSourceRange();
1450 static TemplateParameterList *
1451 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1452 // typename T
1453 auto *T = TemplateTypeParmDecl::Create(
1454 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1455 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1456 /*HasTypeConstraint=*/false);
1457 T->setImplicit(true);
1459 // T ...Ints
1460 TypeSourceInfo *TI =
1461 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1462 auto *N = NonTypeTemplateParmDecl::Create(
1463 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1464 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1465 N->setImplicit(true);
1467 // <typename T, T ...Ints>
1468 NamedDecl *P[2] = {T, N};
1469 auto *TPL = TemplateParameterList::Create(
1470 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1472 // template <typename T, ...Ints> class IntSeq
1473 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1474 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1475 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1476 TemplateTemplateParm->setImplicit(true);
1478 // typename T
1479 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1480 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1481 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1482 /*HasTypeConstraint=*/false);
1483 TemplateTypeParm->setImplicit(true);
1485 // T N
1486 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1487 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1488 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1489 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1490 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1491 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1492 NonTypeTemplateParm};
1494 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1495 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1496 Params, SourceLocation(), nullptr);
1499 static TemplateParameterList *
1500 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1501 // std::size_t Index
1502 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1503 auto *Index = NonTypeTemplateParmDecl::Create(
1504 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1505 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1507 // typename ...T
1508 auto *Ts = TemplateTypeParmDecl::Create(
1509 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1510 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
1511 /*HasTypeConstraint=*/false);
1512 Ts->setImplicit(true);
1514 // template <std::size_t Index, typename ...T>
1515 NamedDecl *Params[] = {Index, Ts};
1516 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1517 llvm::ArrayRef(Params), SourceLocation(),
1518 nullptr);
1521 static TemplateParameterList *createBuiltinTemplateParameterList(
1522 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1523 switch (BTK) {
1524 case BTK__make_integer_seq:
1525 return createMakeIntegerSeqParameterList(C, DC);
1526 case BTK__type_pack_element:
1527 return createTypePackElementParameterList(C, DC);
1530 llvm_unreachable("unhandled BuiltinTemplateKind!");
1533 void BuiltinTemplateDecl::anchor() {}
1535 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1536 DeclarationName Name,
1537 BuiltinTemplateKind BTK)
1538 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1539 createBuiltinTemplateParameterList(C, DC, BTK)),
1540 BTK(BTK) {}
1542 TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1543 QualType T,
1544 const APValue &V) {
1545 DeclContext *DC = C.getTranslationUnitDecl();
1546 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1547 C.addDestruction(&TPOD->Value);
1548 return TPOD;
1551 TemplateParamObjectDecl *
1552 TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1553 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1554 C.addDestruction(&TPOD->Value);
1555 return TPOD;
1558 void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1559 const PrintingPolicy &Policy) const {
1560 OS << "<template param ";
1561 printAsExpr(OS, Policy);
1562 OS << ">";
1565 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1566 printAsExpr(OS, getASTContext().getPrintingPolicy());
1569 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1570 const PrintingPolicy &Policy) const {
1571 getType().getUnqualifiedType().print(OS, Policy);
1572 printAsInit(OS, Policy);
1575 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1576 printAsInit(OS, getASTContext().getPrintingPolicy());
1579 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1580 const PrintingPolicy &Policy) const {
1581 getValue().printPretty(OS, Policy, getType(), &getASTContext());
1584 TemplateParameterList *clang::getReplacedTemplateParameterList(Decl *D) {
1585 switch (D->getKind()) {
1586 case Decl::Kind::ClassTemplate:
1587 return cast<ClassTemplateDecl>(D)->getTemplateParameters();
1588 case Decl::Kind::ClassTemplateSpecialization: {
1589 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1590 auto P = CTSD->getSpecializedTemplateOrPartial();
1591 if (const auto *CTPSD =
1592 P.dyn_cast<ClassTemplatePartialSpecializationDecl *>())
1593 return CTPSD->getTemplateParameters();
1594 return cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1596 case Decl::Kind::ClassTemplatePartialSpecialization:
1597 return cast<ClassTemplatePartialSpecializationDecl>(D)
1598 ->getTemplateParameters();
1599 case Decl::Kind::TypeAliasTemplate:
1600 return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
1601 case Decl::Kind::BuiltinTemplate:
1602 return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
1603 case Decl::Kind::CXXDeductionGuide:
1604 case Decl::Kind::CXXConversion:
1605 case Decl::Kind::CXXConstructor:
1606 case Decl::Kind::CXXDestructor:
1607 case Decl::Kind::CXXMethod:
1608 case Decl::Kind::Function:
1609 return cast<FunctionDecl>(D)
1610 ->getTemplateSpecializationInfo()
1611 ->getTemplate()
1612 ->getTemplateParameters();
1613 case Decl::Kind::FunctionTemplate:
1614 return cast<FunctionTemplateDecl>(D)->getTemplateParameters();
1615 case Decl::Kind::VarTemplate:
1616 return cast<VarTemplateDecl>(D)->getTemplateParameters();
1617 case Decl::Kind::VarTemplateSpecialization: {
1618 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1619 auto P = VTSD->getSpecializedTemplateOrPartial();
1620 if (const auto *VTPSD =
1621 P.dyn_cast<VarTemplatePartialSpecializationDecl *>())
1622 return VTPSD->getTemplateParameters();
1623 return cast<VarTemplateDecl *>(P)->getTemplateParameters();
1625 case Decl::Kind::VarTemplatePartialSpecialization:
1626 return cast<VarTemplatePartialSpecializationDecl>(D)
1627 ->getTemplateParameters();
1628 case Decl::Kind::TemplateTemplateParm:
1629 return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();
1630 case Decl::Kind::Concept:
1631 return cast<ConceptDecl>(D)->getTemplateParameters();
1632 default:
1633 llvm_unreachable("Unhandled templated declaration kind");