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
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>
40
41 using namespace clang;
42
43 //===----------------------------------------------------------------------===//
44 // TemplateParameterList Implementation
45 //===----------------------------------------------------------------------===//
46
47
TemplateParameterList(const ASTContext & C,SourceLocation TemplateLoc,SourceLocation LAngleLoc,ArrayRef<NamedDecl * > Params,SourceLocation RAngleLoc,Expr * RequiresClause)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;
61
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;
77 }
78 if (TTP->hasTypeConstraint())
79 HasConstrainedParameters = true;
80 } else {
81 llvm_unreachable("unexpected template parameter type");
82 }
83 // FIXME: If a default argument contains an unexpanded parameter pack, the
84 // template parameter list does too.
85 }
86
87 if (HasRequiresClause) {
88 if (RequiresClause->containsUnexpandedParameterPack())
89 ContainsUnexpandedParameterPack = true;
90 *getTrailingObjects<Expr *>() = RequiresClause;
91 }
92 }
93
containsUnexpandedParameterPack() const94 bool TemplateParameterList::containsUnexpandedParameterPack() const {
95 if (ContainsUnexpandedParameterPack)
96 return true;
97 if (!HasConstrainedParameters)
98 return false;
99
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;
106
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;
112 }
113 }
114
115 return false;
116 }
117
118 TemplateParameterList *
Create(const ASTContext & C,SourceLocation TemplateLoc,SourceLocation LAngleLoc,ArrayRef<NamedDecl * > Params,SourceLocation RAngleLoc,Expr * RequiresClause)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);
128 }
129
getMinRequiredArguments() const130 unsigned TemplateParameterList::getMinRequiredArguments() const {
131 unsigned NumRequiredArgs = 0;
132 for (const NamedDecl *P : asArray()) {
133 if (P->isTemplateParameterPack()) {
134 if (std::optional<unsigned> Expansions = getExpandedPackSize(P)) {
135 NumRequiredArgs += *Expansions;
136 continue;
137 }
138 break;
139 }
140
141 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
142 if (TTP->hasDefaultArgument())
143 break;
144 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
145 if (NTTP->hasDefaultArgument())
146 break;
147 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
148 break;
149
150 ++NumRequiredArgs;
151 }
152
153 return NumRequiredArgs;
154 }
155
getDepth() const156 unsigned TemplateParameterList::getDepth() const {
157 if (size() == 0)
158 return 0;
159
160 const NamedDecl *FirstParm = getParam(0);
161 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
162 return TTP->getDepth();
163 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
164 return NTTP->getDepth();
165 else
166 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
167 }
168
AdoptTemplateParameterList(TemplateParameterList * Params,DeclContext * Owner)169 static bool AdoptTemplateParameterList(TemplateParameterList *Params,
170 DeclContext *Owner) {
171 bool Invalid = false;
172 for (NamedDecl *P : *Params) {
173 P->setDeclContext(Owner);
174
175 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
176 if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner))
177 Invalid = true;
178
179 if (P->isInvalidDecl())
180 Invalid = true;
181 }
182 return Invalid;
183 }
184
185 void TemplateParameterList::
getAssociatedConstraints(llvm::SmallVectorImpl<const Expr * > & AC) const186 getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
187 if (HasConstrainedParameters)
188 for (const NamedDecl *Param : *this) {
189 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
190 if (const auto *TC = TTP->getTypeConstraint())
191 AC.push_back(TC->getImmediatelyDeclaredConstraint());
192 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
193 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
194 AC.push_back(E);
195 }
196 }
197 if (HasRequiresClause)
198 AC.push_back(getRequiresClause());
199 }
200
hasAssociatedConstraints() const201 bool TemplateParameterList::hasAssociatedConstraints() const {
202 return HasRequiresClause || HasConstrainedParameters;
203 }
204
shouldIncludeTypeForArgument(const PrintingPolicy & Policy,const TemplateParameterList * TPL,unsigned Idx)205 bool TemplateParameterList::shouldIncludeTypeForArgument(
206 const PrintingPolicy &Policy, const TemplateParameterList *TPL,
207 unsigned Idx) {
208 if (!TPL || Idx >= TPL->size() || Policy.AlwaysIncludeTypeForTemplateArgument)
209 return true;
210 const NamedDecl *TemplParam = TPL->getParam(Idx);
211 if (const auto *ParamValueDecl =
212 dyn_cast<NonTypeTemplateParmDecl>(TemplParam))
213 if (ParamValueDecl->getType()->getContainedDeducedType())
214 return true;
215 return false;
216 }
217
218 namespace clang {
219
allocateDefaultArgStorageChain(const ASTContext & C)220 void *allocateDefaultArgStorageChain(const ASTContext &C) {
221 return new (C) char[sizeof(void*) * 2];
222 }
223
224 } // namespace clang
225
226 //===----------------------------------------------------------------------===//
227 // TemplateDecl Implementation
228 //===----------------------------------------------------------------------===//
229
TemplateDecl(Kind DK,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)230 TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
231 DeclarationName Name, TemplateParameterList *Params,
232 NamedDecl *Decl)
233 : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
234
anchor()235 void TemplateDecl::anchor() {}
236
237 void TemplateDecl::
getAssociatedConstraints(llvm::SmallVectorImpl<const Expr * > & AC) const238 getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
239 TemplateParams->getAssociatedConstraints(AC);
240 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
241 if (const Expr *TRC = FD->getTrailingRequiresClause())
242 AC.push_back(TRC);
243 }
244
hasAssociatedConstraints() const245 bool TemplateDecl::hasAssociatedConstraints() const {
246 if (TemplateParams->hasAssociatedConstraints())
247 return true;
248 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl()))
249 return FD->getTrailingRequiresClause();
250 return false;
251 }
252
isTypeAlias() const253 bool TemplateDecl::isTypeAlias() const {
254 switch (getKind()) {
255 case TemplateDecl::TypeAliasTemplate:
256 case TemplateDecl::BuiltinTemplate:
257 return true;
258 default:
259 return false;
260 };
261 }
262
263 //===----------------------------------------------------------------------===//
264 // RedeclarableTemplateDecl Implementation
265 //===----------------------------------------------------------------------===//
266
anchor()267 void RedeclarableTemplateDecl::anchor() {}
268
getCommonPtr() const269 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
270 if (Common)
271 return Common;
272
273 // Walk the previous-declaration chain until we either find a declaration
274 // with a common pointer or we run out of previous declarations.
275 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
276 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
277 Prev = Prev->getPreviousDecl()) {
278 if (Prev->Common) {
279 Common = Prev->Common;
280 break;
281 }
282
283 PrevDecls.push_back(Prev);
284 }
285
286 // If we never found a common pointer, allocate one now.
287 if (!Common) {
288 // FIXME: If any of the declarations is from an AST file, we probably
289 // need an update record to add the common data.
290
291 Common = newCommon(getASTContext());
292 }
293
294 // Update any previous declarations we saw with the common pointer.
295 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
296 Prev->Common = Common;
297
298 return Common;
299 }
300
loadLazySpecializationsImpl() const301 void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
302 // Grab the most recent declaration to ensure we've loaded any lazy
303 // redeclarations of this template.
304 CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
305 if (CommonBasePtr->LazySpecializations) {
306 ASTContext &Context = getASTContext();
307 uint32_t *Specs = CommonBasePtr->LazySpecializations;
308 CommonBasePtr->LazySpecializations = nullptr;
309 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
310 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
311 }
312 }
313
314 template<class EntryType, typename... ProfileArguments>
315 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
findSpecializationImpl(llvm::FoldingSetVector<EntryType> & Specs,void * & InsertPos,ProfileArguments &&...ProfileArgs)316 RedeclarableTemplateDecl::findSpecializationImpl(
317 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
318 ProfileArguments&&... ProfileArgs) {
319 using SETraits = SpecEntryTraits<EntryType>;
320
321 llvm::FoldingSetNodeID ID;
322 EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
323 getASTContext());
324 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
325 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
326 }
327
328 template<class Derived, class EntryType>
addSpecializationImpl(llvm::FoldingSetVector<EntryType> & Specializations,EntryType * Entry,void * InsertPos)329 void RedeclarableTemplateDecl::addSpecializationImpl(
330 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
331 void *InsertPos) {
332 using SETraits = SpecEntryTraits<EntryType>;
333
334 if (InsertPos) {
335 #ifndef NDEBUG
336 void *CorrectInsertPos;
337 assert(!findSpecializationImpl(Specializations,
338 CorrectInsertPos,
339 SETraits::getTemplateArgs(Entry)) &&
340 InsertPos == CorrectInsertPos &&
341 "given incorrect InsertPos for specialization");
342 #endif
343 Specializations.InsertNode(Entry, InsertPos);
344 } else {
345 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
346 (void)Existing;
347 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
348 "non-canonical specialization?");
349 }
350
351 if (ASTMutationListener *L = getASTMutationListener())
352 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
353 SETraits::getDecl(Entry));
354 }
355
getInjectedTemplateArgs()356 ArrayRef<TemplateArgument> RedeclarableTemplateDecl::getInjectedTemplateArgs() {
357 TemplateParameterList *Params = getTemplateParameters();
358 auto *CommonPtr = getCommonPtr();
359 if (!CommonPtr->InjectedArgs) {
360 auto &Context = getASTContext();
361 SmallVector<TemplateArgument, 16> TemplateArgs;
362 Context.getInjectedTemplateArgs(Params, TemplateArgs);
363 CommonPtr->InjectedArgs =
364 new (Context) TemplateArgument[TemplateArgs.size()];
365 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
366 CommonPtr->InjectedArgs);
367 }
368
369 return llvm::ArrayRef(CommonPtr->InjectedArgs, Params->size());
370 }
371
372 //===----------------------------------------------------------------------===//
373 // FunctionTemplateDecl Implementation
374 //===----------------------------------------------------------------------===//
375
376 FunctionTemplateDecl *
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)377 FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
378 DeclarationName Name,
379 TemplateParameterList *Params, NamedDecl *Decl) {
380 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
381 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
382 if (Invalid)
383 TD->setInvalidDecl();
384 return TD;
385 }
386
CreateDeserialized(ASTContext & C,unsigned ID)387 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
388 unsigned ID) {
389 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
390 DeclarationName(), nullptr, nullptr);
391 }
392
393 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const394 FunctionTemplateDecl::newCommon(ASTContext &C) const {
395 auto *CommonPtr = new (C) Common;
396 C.addDestruction(CommonPtr);
397 return CommonPtr;
398 }
399
LoadLazySpecializations() const400 void FunctionTemplateDecl::LoadLazySpecializations() const {
401 loadLazySpecializationsImpl();
402 }
403
404 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
getSpecializations() const405 FunctionTemplateDecl::getSpecializations() const {
406 LoadLazySpecializations();
407 return getCommonPtr()->Specializations;
408 }
409
410 FunctionDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)411 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
412 void *&InsertPos) {
413 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
414 }
415
addSpecialization(FunctionTemplateSpecializationInfo * Info,void * InsertPos)416 void FunctionTemplateDecl::addSpecialization(
417 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
418 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
419 InsertPos);
420 }
421
mergePrevDecl(FunctionTemplateDecl * Prev)422 void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
423 using Base = RedeclarableTemplateDecl;
424
425 // If we haven't created a common pointer yet, then it can just be created
426 // with the usual method.
427 if (!Base::Common)
428 return;
429
430 Common *ThisCommon = static_cast<Common *>(Base::Common);
431 Common *PrevCommon = nullptr;
432 SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
433 for (; Prev; Prev = Prev->getPreviousDecl()) {
434 if (Prev->Base::Common) {
435 PrevCommon = static_cast<Common *>(Prev->Base::Common);
436 break;
437 }
438 PreviousDecls.push_back(Prev);
439 }
440
441 // If the previous redecl chain hasn't created a common pointer yet, then just
442 // use this common pointer.
443 if (!PrevCommon) {
444 for (auto *D : PreviousDecls)
445 D->Base::Common = ThisCommon;
446 return;
447 }
448
449 // Ensure we don't leak any important state.
450 assert(ThisCommon->Specializations.size() == 0 &&
451 "Can't merge incompatible declarations!");
452
453 Base::Common = PrevCommon;
454 }
455
456 //===----------------------------------------------------------------------===//
457 // ClassTemplateDecl Implementation
458 //===----------------------------------------------------------------------===//
459
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)460 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC,
461 SourceLocation L,
462 DeclarationName Name,
463 TemplateParameterList *Params,
464 NamedDecl *Decl) {
465 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
466 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
467 if (Invalid)
468 TD->setInvalidDecl();
469 return TD;
470 }
471
CreateDeserialized(ASTContext & C,unsigned ID)472 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
473 unsigned ID) {
474 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
475 DeclarationName(), nullptr, nullptr);
476 }
477
LoadLazySpecializations() const478 void ClassTemplateDecl::LoadLazySpecializations() const {
479 loadLazySpecializationsImpl();
480 }
481
482 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
getSpecializations() const483 ClassTemplateDecl::getSpecializations() const {
484 LoadLazySpecializations();
485 return getCommonPtr()->Specializations;
486 }
487
488 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations() const489 ClassTemplateDecl::getPartialSpecializations() const {
490 LoadLazySpecializations();
491 return getCommonPtr()->PartialSpecializations;
492 }
493
494 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const495 ClassTemplateDecl::newCommon(ASTContext &C) const {
496 auto *CommonPtr = new (C) Common;
497 C.addDestruction(CommonPtr);
498 return CommonPtr;
499 }
500
501 ClassTemplateSpecializationDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)502 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
503 void *&InsertPos) {
504 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
505 }
506
AddSpecialization(ClassTemplateSpecializationDecl * D,void * InsertPos)507 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
508 void *InsertPos) {
509 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
510 }
511
512 ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args,TemplateParameterList * TPL,void * & InsertPos)513 ClassTemplateDecl::findPartialSpecialization(
514 ArrayRef<TemplateArgument> Args,
515 TemplateParameterList *TPL, void *&InsertPos) {
516 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
517 TPL);
518 }
519
ProfileTemplateParameterList(ASTContext & C,llvm::FoldingSetNodeID & ID,const TemplateParameterList * TPL)520 static void ProfileTemplateParameterList(ASTContext &C,
521 llvm::FoldingSetNodeID &ID, const TemplateParameterList *TPL) {
522 const Expr *RC = TPL->getRequiresClause();
523 ID.AddBoolean(RC != nullptr);
524 if (RC)
525 RC->Profile(ID, C, /*Canonical=*/true);
526 ID.AddInteger(TPL->size());
527 for (NamedDecl *D : *TPL) {
528 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
529 ID.AddInteger(0);
530 ID.AddBoolean(NTTP->isParameterPack());
531 NTTP->getType().getCanonicalType().Profile(ID);
532 ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint());
533 if (const Expr *E = NTTP->getPlaceholderTypeConstraint())
534 E->Profile(ID, C, /*Canonical=*/true);
535 continue;
536 }
537 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) {
538 ID.AddInteger(1);
539 ID.AddBoolean(TTP->isParameterPack());
540 ID.AddBoolean(TTP->hasTypeConstraint());
541 if (const TypeConstraint *TC = TTP->getTypeConstraint())
542 TC->getImmediatelyDeclaredConstraint()->Profile(ID, C,
543 /*Canonical=*/true);
544 continue;
545 }
546 const auto *TTP = cast<TemplateTemplateParmDecl>(D);
547 ID.AddInteger(2);
548 ID.AddBoolean(TTP->isParameterPack());
549 ProfileTemplateParameterList(C, ID, TTP->getTemplateParameters());
550 }
551 }
552
553 void
Profile(llvm::FoldingSetNodeID & ID,ArrayRef<TemplateArgument> TemplateArgs,TemplateParameterList * TPL,ASTContext & Context)554 ClassTemplatePartialSpecializationDecl::Profile(llvm::FoldingSetNodeID &ID,
555 ArrayRef<TemplateArgument> TemplateArgs, TemplateParameterList *TPL,
556 ASTContext &Context) {
557 ID.AddInteger(TemplateArgs.size());
558 for (const TemplateArgument &TemplateArg : TemplateArgs)
559 TemplateArg.Profile(ID, Context);
560 ProfileTemplateParameterList(Context, ID, TPL);
561 }
562
AddPartialSpecialization(ClassTemplatePartialSpecializationDecl * D,void * InsertPos)563 void ClassTemplateDecl::AddPartialSpecialization(
564 ClassTemplatePartialSpecializationDecl *D,
565 void *InsertPos) {
566 if (InsertPos)
567 getPartialSpecializations().InsertNode(D, InsertPos);
568 else {
569 ClassTemplatePartialSpecializationDecl *Existing
570 = getPartialSpecializations().GetOrInsertNode(D);
571 (void)Existing;
572 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
573 }
574
575 if (ASTMutationListener *L = getASTMutationListener())
576 L->AddedCXXTemplateSpecialization(this, D);
577 }
578
getPartialSpecializations(SmallVectorImpl<ClassTemplatePartialSpecializationDecl * > & PS) const579 void ClassTemplateDecl::getPartialSpecializations(
580 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) const {
581 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
582 = getPartialSpecializations();
583 PS.clear();
584 PS.reserve(PartialSpecs.size());
585 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
586 PS.push_back(P.getMostRecentDecl());
587 }
588
589 ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(QualType T)590 ClassTemplateDecl::findPartialSpecialization(QualType T) {
591 ASTContext &Context = getASTContext();
592 for (ClassTemplatePartialSpecializationDecl &P :
593 getPartialSpecializations()) {
594 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
595 return P.getMostRecentDecl();
596 }
597
598 return nullptr;
599 }
600
601 ClassTemplatePartialSpecializationDecl *
findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl * D)602 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
603 ClassTemplatePartialSpecializationDecl *D) {
604 Decl *DCanon = D->getCanonicalDecl();
605 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
606 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
607 return P.getMostRecentDecl();
608 }
609
610 return nullptr;
611 }
612
613 QualType
getInjectedClassNameSpecialization()614 ClassTemplateDecl::getInjectedClassNameSpecialization() {
615 Common *CommonPtr = getCommonPtr();
616 if (!CommonPtr->InjectedClassNameType.isNull())
617 return CommonPtr->InjectedClassNameType;
618
619 // C++0x [temp.dep.type]p2:
620 // The template argument list of a primary template is a template argument
621 // list in which the nth template argument has the value of the nth template
622 // parameter of the class template. If the nth template parameter is a
623 // template parameter pack (14.5.3), the nth template argument is a pack
624 // expansion (14.5.3) whose pattern is the name of the template parameter
625 // pack.
626 ASTContext &Context = getASTContext();
627 TemplateParameterList *Params = getTemplateParameters();
628 SmallVector<TemplateArgument, 16> TemplateArgs;
629 Context.getInjectedTemplateArgs(Params, TemplateArgs);
630 CommonPtr->InjectedClassNameType
631 = Context.getTemplateSpecializationType(TemplateName(this),
632 TemplateArgs);
633 return CommonPtr->InjectedClassNameType;
634 }
635
636 //===----------------------------------------------------------------------===//
637 // TemplateTypeParm Allocation/Deallocation Method Implementations
638 //===----------------------------------------------------------------------===//
639
Create(const ASTContext & C,DeclContext * DC,SourceLocation KeyLoc,SourceLocation NameLoc,unsigned D,unsigned P,IdentifierInfo * Id,bool Typename,bool ParameterPack,bool HasTypeConstraint,std::optional<unsigned> NumExpanded)640 TemplateTypeParmDecl *TemplateTypeParmDecl::Create(
641 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
642 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
643 bool Typename, bool ParameterPack, bool HasTypeConstraint,
644 std::optional<unsigned> NumExpanded) {
645 auto *TTPDecl =
646 new (C, DC,
647 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
648 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
649 HasTypeConstraint, NumExpanded);
650 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
651 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
652 return TTPDecl;
653 }
654
655 TemplateTypeParmDecl *
CreateDeserialized(const ASTContext & C,unsigned ID)656 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
657 return new (C, ID)
658 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
659 false, false, std::nullopt);
660 }
661
662 TemplateTypeParmDecl *
CreateDeserialized(const ASTContext & C,unsigned ID,bool HasTypeConstraint)663 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID,
664 bool HasTypeConstraint) {
665 return new (C, ID,
666 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
667 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
668 false, HasTypeConstraint, std::nullopt);
669 }
670
getDefaultArgumentLoc() const671 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
672 return hasDefaultArgument()
673 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
674 : SourceLocation();
675 }
676
getSourceRange() const677 SourceRange TemplateTypeParmDecl::getSourceRange() const {
678 if (hasDefaultArgument() && !defaultArgumentWasInherited())
679 return SourceRange(getBeginLoc(),
680 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
681 // TypeDecl::getSourceRange returns a range containing name location, which is
682 // wrong for unnamed template parameters. e.g:
683 // it will return <[[typename>]] instead of <[[typename]]>
684 else if (getDeclName().isEmpty())
685 return SourceRange(getBeginLoc());
686 return TypeDecl::getSourceRange();
687 }
688
getDepth() const689 unsigned TemplateTypeParmDecl::getDepth() const {
690 return getTypeForDecl()->castAs<TemplateTypeParmType>()->getDepth();
691 }
692
getIndex() const693 unsigned TemplateTypeParmDecl::getIndex() const {
694 return getTypeForDecl()->castAs<TemplateTypeParmType>()->getIndex();
695 }
696
isParameterPack() const697 bool TemplateTypeParmDecl::isParameterPack() const {
698 return getTypeForDecl()->castAs<TemplateTypeParmType>()->isParameterPack();
699 }
700
setTypeConstraint(NestedNameSpecifierLoc NNS,DeclarationNameInfo NameInfo,NamedDecl * FoundDecl,ConceptDecl * CD,const ASTTemplateArgumentListInfo * ArgsAsWritten,Expr * ImmediatelyDeclaredConstraint)701 void TemplateTypeParmDecl::setTypeConstraint(NestedNameSpecifierLoc NNS,
702 DeclarationNameInfo NameInfo, NamedDecl *FoundDecl, ConceptDecl *CD,
703 const ASTTemplateArgumentListInfo *ArgsAsWritten,
704 Expr *ImmediatelyDeclaredConstraint) {
705 assert(HasTypeConstraint &&
706 "HasTypeConstraint=true must be passed at construction in order to "
707 "call setTypeConstraint");
708 assert(!TypeConstraintInitialized &&
709 "TypeConstraint was already initialized!");
710 new (getTrailingObjects<TypeConstraint>()) TypeConstraint(NNS, NameInfo,
711 FoundDecl, CD, ArgsAsWritten, ImmediatelyDeclaredConstraint);
712 TypeConstraintInitialized = true;
713 }
714
715 //===----------------------------------------------------------------------===//
716 // NonTypeTemplateParmDecl Method Implementations
717 //===----------------------------------------------------------------------===//
718
NonTypeTemplateParmDecl(DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,ArrayRef<QualType> ExpandedTypes,ArrayRef<TypeSourceInfo * > ExpandedTInfos)719 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
720 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
721 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
722 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
723 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
724 TemplateParmPosition(D, P), ParameterPack(true),
725 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
726 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
727 auto TypesAndInfos =
728 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
729 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
730 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
731 TypesAndInfos[I].second = ExpandedTInfos[I];
732 }
733 }
734 }
735
736 NonTypeTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,bool ParameterPack,TypeSourceInfo * TInfo)737 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
738 SourceLocation StartLoc, SourceLocation IdLoc,
739 unsigned D, unsigned P, IdentifierInfo *Id,
740 QualType T, bool ParameterPack,
741 TypeSourceInfo *TInfo) {
742 AutoType *AT =
743 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
744 return new (C, DC,
745 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
746 Expr *>(0,
747 AT && AT->isConstrained() ? 1 : 0))
748 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,
749 TInfo);
750 }
751
Create(const ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,ArrayRef<QualType> ExpandedTypes,ArrayRef<TypeSourceInfo * > ExpandedTInfos)752 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
753 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
754 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
755 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
756 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
757 AutoType *AT = TInfo->getType()->getContainedAutoType();
758 return new (C, DC,
759 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
760 Expr *>(
761 ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))
762 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
763 ExpandedTypes, ExpandedTInfos);
764 }
765
766 NonTypeTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID,bool HasTypeConstraint)767 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
768 bool HasTypeConstraint) {
769 return new (C, ID, additionalSizeToAlloc<std::pair<QualType,
770 TypeSourceInfo *>,
771 Expr *>(0,
772 HasTypeConstraint ? 1 : 0))
773 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
774 0, 0, nullptr, QualType(), false, nullptr);
775 }
776
777 NonTypeTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID,unsigned NumExpandedTypes,bool HasTypeConstraint)778 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
779 unsigned NumExpandedTypes,
780 bool HasTypeConstraint) {
781 auto *NTTP =
782 new (C, ID,
783 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
784 NumExpandedTypes, HasTypeConstraint ? 1 : 0))
785 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
786 0, 0, nullptr, QualType(), nullptr,
787 std::nullopt, std::nullopt);
788 NTTP->NumExpandedTypes = NumExpandedTypes;
789 return NTTP;
790 }
791
getSourceRange() const792 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
793 if (hasDefaultArgument() && !defaultArgumentWasInherited())
794 return SourceRange(getOuterLocStart(),
795 getDefaultArgument()->getSourceRange().getEnd());
796 return DeclaratorDecl::getSourceRange();
797 }
798
getDefaultArgumentLoc() const799 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
800 return hasDefaultArgument()
801 ? getDefaultArgument()->getSourceRange().getBegin()
802 : SourceLocation();
803 }
804
805 //===----------------------------------------------------------------------===//
806 // TemplateTemplateParmDecl Method Implementations
807 //===----------------------------------------------------------------------===//
808
anchor()809 void TemplateTemplateParmDecl::anchor() {}
810
TemplateTemplateParmDecl(DeclContext * DC,SourceLocation L,unsigned D,unsigned P,IdentifierInfo * Id,TemplateParameterList * Params,ArrayRef<TemplateParameterList * > Expansions)811 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
812 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
813 IdentifierInfo *Id, TemplateParameterList *Params,
814 ArrayRef<TemplateParameterList *> Expansions)
815 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
816 TemplateParmPosition(D, P), ParameterPack(true),
817 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
818 if (!Expansions.empty())
819 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
820 getTrailingObjects<TemplateParameterList *>());
821 }
822
823 TemplateTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation L,unsigned D,unsigned P,bool ParameterPack,IdentifierInfo * Id,TemplateParameterList * Params)824 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
825 SourceLocation L, unsigned D, unsigned P,
826 bool ParameterPack, IdentifierInfo *Id,
827 TemplateParameterList *Params) {
828 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
829 Params);
830 }
831
832 TemplateTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation L,unsigned D,unsigned P,IdentifierInfo * Id,TemplateParameterList * Params,ArrayRef<TemplateParameterList * > Expansions)833 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
834 SourceLocation L, unsigned D, unsigned P,
835 IdentifierInfo *Id,
836 TemplateParameterList *Params,
837 ArrayRef<TemplateParameterList *> Expansions) {
838 return new (C, DC,
839 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
840 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
841 }
842
843 TemplateTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID)844 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
845 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
846 false, nullptr, nullptr);
847 }
848
849 TemplateTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID,unsigned NumExpansions)850 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
851 unsigned NumExpansions) {
852 auto *TTP =
853 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
854 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
855 nullptr, std::nullopt);
856 TTP->NumExpandedParams = NumExpansions;
857 return TTP;
858 }
859
getDefaultArgumentLoc() const860 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
861 return hasDefaultArgument() ? getDefaultArgument().getLocation()
862 : SourceLocation();
863 }
864
setDefaultArgument(const ASTContext & C,const TemplateArgumentLoc & DefArg)865 void TemplateTemplateParmDecl::setDefaultArgument(
866 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
867 if (DefArg.getArgument().isNull())
868 DefaultArgument.set(nullptr);
869 else
870 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
871 }
872
873 //===----------------------------------------------------------------------===//
874 // TemplateArgumentList Implementation
875 //===----------------------------------------------------------------------===//
TemplateArgumentList(ArrayRef<TemplateArgument> Args)876 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
877 : Arguments(getTrailingObjects<TemplateArgument>()),
878 NumArguments(Args.size()) {
879 std::uninitialized_copy(Args.begin(), Args.end(),
880 getTrailingObjects<TemplateArgument>());
881 }
882
883 TemplateArgumentList *
CreateCopy(ASTContext & Context,ArrayRef<TemplateArgument> Args)884 TemplateArgumentList::CreateCopy(ASTContext &Context,
885 ArrayRef<TemplateArgument> Args) {
886 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
887 return new (Mem) TemplateArgumentList(Args);
888 }
889
Create(ASTContext & C,FunctionDecl * FD,FunctionTemplateDecl * Template,TemplateSpecializationKind TSK,const TemplateArgumentList * TemplateArgs,const TemplateArgumentListInfo * TemplateArgsAsWritten,SourceLocation POI,MemberSpecializationInfo * MSInfo)890 FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
891 ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
892 TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
893 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
894 MemberSpecializationInfo *MSInfo) {
895 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
896 if (TemplateArgsAsWritten)
897 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
898 *TemplateArgsAsWritten);
899
900 void *Mem =
901 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
902 return new (Mem) FunctionTemplateSpecializationInfo(
903 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
904 }
905
906 //===----------------------------------------------------------------------===//
907 // ClassTemplateSpecializationDecl Implementation
908 //===----------------------------------------------------------------------===//
909
910 ClassTemplateSpecializationDecl::
ClassTemplateSpecializationDecl(ASTContext & Context,Kind DK,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,ClassTemplateSpecializationDecl * PrevDecl)911 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
912 DeclContext *DC, SourceLocation StartLoc,
913 SourceLocation IdLoc,
914 ClassTemplateDecl *SpecializedTemplate,
915 ArrayRef<TemplateArgument> Args,
916 ClassTemplateSpecializationDecl *PrevDecl)
917 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
918 SpecializedTemplate->getIdentifier(), PrevDecl),
919 SpecializedTemplate(SpecializedTemplate),
920 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
921 SpecializationKind(TSK_Undeclared) {
922 }
923
ClassTemplateSpecializationDecl(ASTContext & C,Kind DK)924 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
925 Kind DK)
926 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
927 SourceLocation(), nullptr, nullptr),
928 SpecializationKind(TSK_Undeclared) {}
929
930 ClassTemplateSpecializationDecl *
Create(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,ClassTemplateSpecializationDecl * PrevDecl)931 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
932 DeclContext *DC,
933 SourceLocation StartLoc,
934 SourceLocation IdLoc,
935 ClassTemplateDecl *SpecializedTemplate,
936 ArrayRef<TemplateArgument> Args,
937 ClassTemplateSpecializationDecl *PrevDecl) {
938 auto *Result =
939 new (Context, DC) ClassTemplateSpecializationDecl(
940 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
941 SpecializedTemplate, Args, PrevDecl);
942 Result->setMayHaveOutOfDateDef(false);
943
944 // If the template decl is incomplete, copy the external lexical storage from
945 // the base template. This allows instantiations of incomplete types to
946 // complete using the external AST if the template's declaration came from an
947 // external AST.
948 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
949 Result->setHasExternalLexicalStorage(
950 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
951
952 Context.getTypeDeclType(Result, PrevDecl);
953 return Result;
954 }
955
956 ClassTemplateSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)957 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
958 unsigned ID) {
959 auto *Result =
960 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
961 Result->setMayHaveOutOfDateDef(false);
962 return Result;
963 }
964
getNameForDiagnostic(raw_ostream & OS,const PrintingPolicy & Policy,bool Qualified) const965 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
966 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
967 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
968
969 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
970 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
971 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
972 printTemplateArgumentList(
973 OS, ArgsAsWritten->arguments(), Policy,
974 getSpecializedTemplate()->getTemplateParameters());
975 } else {
976 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
977 printTemplateArgumentList(
978 OS, TemplateArgs.asArray(), Policy,
979 getSpecializedTemplate()->getTemplateParameters());
980 }
981 }
982
983 ClassTemplateDecl *
getSpecializedTemplate() const984 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
985 if (const auto *PartialSpec =
986 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
987 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
988 return SpecializedTemplate.get<ClassTemplateDecl*>();
989 }
990
991 SourceRange
getSourceRange() const992 ClassTemplateSpecializationDecl::getSourceRange() const {
993 if (ExplicitInfo) {
994 SourceLocation Begin = getTemplateKeywordLoc();
995 if (Begin.isValid()) {
996 // Here we have an explicit (partial) specialization or instantiation.
997 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
998 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
999 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
1000 if (getExternLoc().isValid())
1001 Begin = getExternLoc();
1002 SourceLocation End = getBraceRange().getEnd();
1003 if (End.isInvalid())
1004 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
1005 return SourceRange(Begin, End);
1006 }
1007 // An implicit instantiation of a class template partial specialization
1008 // uses ExplicitInfo to record the TypeAsWritten, but the source
1009 // locations should be retrieved from the instantiation pattern.
1010 using CTPSDecl = ClassTemplatePartialSpecializationDecl;
1011 auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
1012 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
1013 assert(inst_from != nullptr);
1014 return inst_from->getSourceRange();
1015 }
1016 else {
1017 // No explicit info available.
1018 llvm::PointerUnion<ClassTemplateDecl *,
1019 ClassTemplatePartialSpecializationDecl *>
1020 inst_from = getInstantiatedFrom();
1021 if (inst_from.isNull())
1022 return getSpecializedTemplate()->getSourceRange();
1023 if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
1024 return ctd->getSourceRange();
1025 return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
1026 ->getSourceRange();
1027 }
1028 }
1029
1030 //===----------------------------------------------------------------------===//
1031 // ConceptDecl Implementation
1032 //===----------------------------------------------------------------------===//
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,Expr * ConstraintExpr)1033 ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
1034 SourceLocation L, DeclarationName Name,
1035 TemplateParameterList *Params,
1036 Expr *ConstraintExpr) {
1037 bool Invalid = AdoptTemplateParameterList(Params, DC);
1038 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1039 if (Invalid)
1040 TD->setInvalidDecl();
1041 return TD;
1042 }
1043
CreateDeserialized(ASTContext & C,unsigned ID)1044 ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C,
1045 unsigned ID) {
1046 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1047 DeclarationName(),
1048 nullptr, nullptr);
1049
1050 return Result;
1051 }
1052
1053 //===----------------------------------------------------------------------===//
1054 // ImplicitConceptSpecializationDecl Implementation
1055 //===----------------------------------------------------------------------===//
ImplicitConceptSpecializationDecl(DeclContext * DC,SourceLocation SL,ArrayRef<TemplateArgument> ConvertedArgs)1056 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1057 DeclContext *DC, SourceLocation SL,
1058 ArrayRef<TemplateArgument> ConvertedArgs)
1059 : Decl(ImplicitConceptSpecialization, DC, SL),
1060 NumTemplateArgs(ConvertedArgs.size()) {
1061 setTemplateArguments(ConvertedArgs);
1062 }
1063
ImplicitConceptSpecializationDecl(EmptyShell Empty,unsigned NumTemplateArgs)1064 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1065 EmptyShell Empty, unsigned NumTemplateArgs)
1066 : Decl(ImplicitConceptSpecialization, Empty),
1067 NumTemplateArgs(NumTemplateArgs) {}
1068
Create(const ASTContext & C,DeclContext * DC,SourceLocation SL,ArrayRef<TemplateArgument> ConvertedArgs)1069 ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create(
1070 const ASTContext &C, DeclContext *DC, SourceLocation SL,
1071 ArrayRef<TemplateArgument> ConvertedArgs) {
1072 return new (C, DC,
1073 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1074 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1075 }
1076
1077 ImplicitConceptSpecializationDecl *
CreateDeserialized(const ASTContext & C,unsigned ID,unsigned NumTemplateArgs)1078 ImplicitConceptSpecializationDecl::CreateDeserialized(
1079 const ASTContext &C, unsigned ID, unsigned NumTemplateArgs) {
1080 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1081 ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);
1082 }
1083
setTemplateArguments(ArrayRef<TemplateArgument> Converted)1084 void ImplicitConceptSpecializationDecl::setTemplateArguments(
1085 ArrayRef<TemplateArgument> Converted) {
1086 assert(Converted.size() == NumTemplateArgs);
1087 std::uninitialized_copy(Converted.begin(), Converted.end(),
1088 getTrailingObjects<TemplateArgument>());
1089 }
1090
1091 //===----------------------------------------------------------------------===//
1092 // ClassTemplatePartialSpecializationDecl Implementation
1093 //===----------------------------------------------------------------------===//
anchor()1094 void ClassTemplatePartialSpecializationDecl::anchor() {}
1095
1096 ClassTemplatePartialSpecializationDecl::
ClassTemplatePartialSpecializationDecl(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,const ASTTemplateArgumentListInfo * ArgInfos,ClassTemplatePartialSpecializationDecl * PrevDecl)1097 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
1098 DeclContext *DC,
1099 SourceLocation StartLoc,
1100 SourceLocation IdLoc,
1101 TemplateParameterList *Params,
1102 ClassTemplateDecl *SpecializedTemplate,
1103 ArrayRef<TemplateArgument> Args,
1104 const ASTTemplateArgumentListInfo *ArgInfos,
1105 ClassTemplatePartialSpecializationDecl *PrevDecl)
1106 : ClassTemplateSpecializationDecl(Context,
1107 ClassTemplatePartialSpecialization,
1108 TK, DC, StartLoc, IdLoc,
1109 SpecializedTemplate, Args, PrevDecl),
1110 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1111 InstantiatedFromMember(nullptr, false) {
1112 if (AdoptTemplateParameterList(Params, this))
1113 setInvalidDecl();
1114 }
1115
1116 ClassTemplatePartialSpecializationDecl *
1117 ClassTemplatePartialSpecializationDecl::
Create(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,const TemplateArgumentListInfo & ArgInfos,QualType CanonInjectedType,ClassTemplatePartialSpecializationDecl * PrevDecl)1118 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
1119 SourceLocation StartLoc, SourceLocation IdLoc,
1120 TemplateParameterList *Params,
1121 ClassTemplateDecl *SpecializedTemplate,
1122 ArrayRef<TemplateArgument> Args,
1123 const TemplateArgumentListInfo &ArgInfos,
1124 QualType CanonInjectedType,
1125 ClassTemplatePartialSpecializationDecl *PrevDecl) {
1126 const ASTTemplateArgumentListInfo *ASTArgInfos =
1127 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1128
1129 auto *Result = new (Context, DC)
1130 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
1131 Params, SpecializedTemplate, Args,
1132 ASTArgInfos, PrevDecl);
1133 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1134 Result->setMayHaveOutOfDateDef(false);
1135
1136 Context.getInjectedClassNameType(Result, CanonInjectedType);
1137 return Result;
1138 }
1139
1140 ClassTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1141 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1142 unsigned ID) {
1143 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
1144 Result->setMayHaveOutOfDateDef(false);
1145 return Result;
1146 }
1147
1148 //===----------------------------------------------------------------------===//
1149 // FriendTemplateDecl Implementation
1150 //===----------------------------------------------------------------------===//
1151
anchor()1152 void FriendTemplateDecl::anchor() {}
1153
1154 FriendTemplateDecl *
Create(ASTContext & Context,DeclContext * DC,SourceLocation L,MutableArrayRef<TemplateParameterList * > Params,FriendUnion Friend,SourceLocation FLoc)1155 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
1156 SourceLocation L,
1157 MutableArrayRef<TemplateParameterList *> Params,
1158 FriendUnion Friend, SourceLocation FLoc) {
1159 TemplateParameterList **TPL = nullptr;
1160 if (!Params.empty()) {
1161 TPL = new (Context) TemplateParameterList *[Params.size()];
1162 llvm::copy(Params, TPL);
1163 }
1164 return new (Context, DC)
1165 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
1166 }
1167
CreateDeserialized(ASTContext & C,unsigned ID)1168 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
1169 unsigned ID) {
1170 return new (C, ID) FriendTemplateDecl(EmptyShell());
1171 }
1172
1173 //===----------------------------------------------------------------------===//
1174 // TypeAliasTemplateDecl Implementation
1175 //===----------------------------------------------------------------------===//
1176
1177 TypeAliasTemplateDecl *
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)1178 TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
1179 DeclarationName Name,
1180 TemplateParameterList *Params, NamedDecl *Decl) {
1181 bool Invalid = AdoptTemplateParameterList(Params, DC);
1182 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1183 if (Invalid)
1184 TD->setInvalidDecl();
1185 return TD;
1186 }
1187
CreateDeserialized(ASTContext & C,unsigned ID)1188 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
1189 unsigned ID) {
1190 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1191 DeclarationName(), nullptr, nullptr);
1192 }
1193
1194 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const1195 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
1196 auto *CommonPtr = new (C) Common;
1197 C.addDestruction(CommonPtr);
1198 return CommonPtr;
1199 }
1200
1201 //===----------------------------------------------------------------------===//
1202 // ClassScopeFunctionSpecializationDecl Implementation
1203 //===----------------------------------------------------------------------===//
1204
anchor()1205 void ClassScopeFunctionSpecializationDecl::anchor() {}
1206
1207 ClassScopeFunctionSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1208 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
1209 unsigned ID) {
1210 return new (C, ID) ClassScopeFunctionSpecializationDecl(
1211 nullptr, SourceLocation(), nullptr, nullptr);
1212 }
1213
1214 //===----------------------------------------------------------------------===//
1215 // VarTemplateDecl Implementation
1216 //===----------------------------------------------------------------------===//
1217
getDefinition()1218 VarTemplateDecl *VarTemplateDecl::getDefinition() {
1219 VarTemplateDecl *CurD = this;
1220 while (CurD) {
1221 if (CurD->isThisDeclarationADefinition())
1222 return CurD;
1223 CurD = CurD->getPreviousDecl();
1224 }
1225 return nullptr;
1226 }
1227
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,VarDecl * Decl)1228 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
1229 SourceLocation L, DeclarationName Name,
1230 TemplateParameterList *Params,
1231 VarDecl *Decl) {
1232 bool Invalid = AdoptTemplateParameterList(Params, DC);
1233 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1234 if (Invalid)
1235 TD->setInvalidDecl();
1236 return TD;
1237 }
1238
CreateDeserialized(ASTContext & C,unsigned ID)1239 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
1240 unsigned ID) {
1241 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1242 DeclarationName(), nullptr, nullptr);
1243 }
1244
LoadLazySpecializations() const1245 void VarTemplateDecl::LoadLazySpecializations() const {
1246 loadLazySpecializationsImpl();
1247 }
1248
1249 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
getSpecializations() const1250 VarTemplateDecl::getSpecializations() const {
1251 LoadLazySpecializations();
1252 return getCommonPtr()->Specializations;
1253 }
1254
1255 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
getPartialSpecializations() const1256 VarTemplateDecl::getPartialSpecializations() const {
1257 LoadLazySpecializations();
1258 return getCommonPtr()->PartialSpecializations;
1259 }
1260
1261 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const1262 VarTemplateDecl::newCommon(ASTContext &C) const {
1263 auto *CommonPtr = new (C) Common;
1264 C.addDestruction(CommonPtr);
1265 return CommonPtr;
1266 }
1267
1268 VarTemplateSpecializationDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)1269 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1270 void *&InsertPos) {
1271 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
1272 }
1273
AddSpecialization(VarTemplateSpecializationDecl * D,void * InsertPos)1274 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1275 void *InsertPos) {
1276 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1277 }
1278
1279 VarTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args,TemplateParameterList * TPL,void * & InsertPos)1280 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1281 TemplateParameterList *TPL, void *&InsertPos) {
1282 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1283 TPL);
1284 }
1285
1286 void
Profile(llvm::FoldingSetNodeID & ID,ArrayRef<TemplateArgument> TemplateArgs,TemplateParameterList * TPL,ASTContext & Context)1287 VarTemplatePartialSpecializationDecl::Profile(llvm::FoldingSetNodeID &ID,
1288 ArrayRef<TemplateArgument> TemplateArgs, TemplateParameterList *TPL,
1289 ASTContext &Context) {
1290 ID.AddInteger(TemplateArgs.size());
1291 for (const TemplateArgument &TemplateArg : TemplateArgs)
1292 TemplateArg.Profile(ID, Context);
1293 ProfileTemplateParameterList(Context, ID, TPL);
1294 }
1295
AddPartialSpecialization(VarTemplatePartialSpecializationDecl * D,void * InsertPos)1296 void VarTemplateDecl::AddPartialSpecialization(
1297 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1298 if (InsertPos)
1299 getPartialSpecializations().InsertNode(D, InsertPos);
1300 else {
1301 VarTemplatePartialSpecializationDecl *Existing =
1302 getPartialSpecializations().GetOrInsertNode(D);
1303 (void)Existing;
1304 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1305 }
1306
1307 if (ASTMutationListener *L = getASTMutationListener())
1308 L->AddedCXXTemplateSpecialization(this, D);
1309 }
1310
getPartialSpecializations(SmallVectorImpl<VarTemplatePartialSpecializationDecl * > & PS) const1311 void VarTemplateDecl::getPartialSpecializations(
1312 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const {
1313 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1314 getPartialSpecializations();
1315 PS.clear();
1316 PS.reserve(PartialSpecs.size());
1317 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1318 PS.push_back(P.getMostRecentDecl());
1319 }
1320
1321 VarTemplatePartialSpecializationDecl *
findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl * D)1322 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1323 VarTemplatePartialSpecializationDecl *D) {
1324 Decl *DCanon = D->getCanonicalDecl();
1325 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1326 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1327 return P.getMostRecentDecl();
1328 }
1329
1330 return nullptr;
1331 }
1332
1333 //===----------------------------------------------------------------------===//
1334 // VarTemplateSpecializationDecl Implementation
1335 //===----------------------------------------------------------------------===//
1336
VarTemplateSpecializationDecl(Kind DK,ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args)1337 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1338 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1339 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1340 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1341 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1342 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1343 SpecializedTemplate(SpecializedTemplate),
1344 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1345 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1346
VarTemplateSpecializationDecl(Kind DK,ASTContext & C)1347 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1348 ASTContext &C)
1349 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1350 QualType(), nullptr, SC_None),
1351 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1352
Create(ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args)1353 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1354 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1355 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1356 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1357 return new (Context, DC) VarTemplateSpecializationDecl(
1358 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1359 SpecializedTemplate, T, TInfo, S, Args);
1360 }
1361
1362 VarTemplateSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1363 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1364 return new (C, ID)
1365 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1366 }
1367
getNameForDiagnostic(raw_ostream & OS,const PrintingPolicy & Policy,bool Qualified) const1368 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1369 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1370 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1371
1372 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1373 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1374 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1375 printTemplateArgumentList(
1376 OS, ArgsAsWritten->arguments(), Policy,
1377 getSpecializedTemplate()->getTemplateParameters());
1378 } else {
1379 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1380 printTemplateArgumentList(
1381 OS, TemplateArgs.asArray(), Policy,
1382 getSpecializedTemplate()->getTemplateParameters());
1383 }
1384 }
1385
getSpecializedTemplate() const1386 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1387 if (const auto *PartialSpec =
1388 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1389 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1390 return SpecializedTemplate.get<VarTemplateDecl *>();
1391 }
1392
setTemplateArgsInfo(const TemplateArgumentListInfo & ArgsInfo)1393 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1394 const TemplateArgumentListInfo &ArgsInfo) {
1395 TemplateArgsInfo =
1396 ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo);
1397 }
1398
setTemplateArgsInfo(const ASTTemplateArgumentListInfo * ArgsInfo)1399 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1400 const ASTTemplateArgumentListInfo *ArgsInfo) {
1401 TemplateArgsInfo =
1402 ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo);
1403 }
1404
1405 //===----------------------------------------------------------------------===//
1406 // VarTemplatePartialSpecializationDecl Implementation
1407 //===----------------------------------------------------------------------===//
1408
anchor()1409 void VarTemplatePartialSpecializationDecl::anchor() {}
1410
VarTemplatePartialSpecializationDecl(ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args,const ASTTemplateArgumentListInfo * ArgInfos)1411 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1412 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1413 SourceLocation IdLoc, TemplateParameterList *Params,
1414 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1415 StorageClass S, ArrayRef<TemplateArgument> Args,
1416 const ASTTemplateArgumentListInfo *ArgInfos)
1417 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1418 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1419 TInfo, S, Args),
1420 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1421 InstantiatedFromMember(nullptr, false) {
1422 if (AdoptTemplateParameterList(Params, DC))
1423 setInvalidDecl();
1424 }
1425
1426 VarTemplatePartialSpecializationDecl *
Create(ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args,const TemplateArgumentListInfo & ArgInfos)1427 VarTemplatePartialSpecializationDecl::Create(
1428 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1429 SourceLocation IdLoc, TemplateParameterList *Params,
1430 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1431 StorageClass S, ArrayRef<TemplateArgument> Args,
1432 const TemplateArgumentListInfo &ArgInfos) {
1433 const ASTTemplateArgumentListInfo *ASTArgInfos
1434 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1435
1436 auto *Result =
1437 new (Context, DC) VarTemplatePartialSpecializationDecl(
1438 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1439 S, Args, ASTArgInfos);
1440 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1441 return Result;
1442 }
1443
1444 VarTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1445 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1446 unsigned ID) {
1447 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1448 }
1449
1450 static TemplateParameterList *
createMakeIntegerSeqParameterList(const ASTContext & C,DeclContext * DC)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);
1458
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);
1466
1467 // <typename T, T ...Ints>
1468 NamedDecl *P[2] = {T, N};
1469 auto *TPL = TemplateParameterList::Create(
1470 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1471
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);
1477
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);
1484
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};
1493
1494 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1495 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1496 Params, SourceLocation(), nullptr);
1497 }
1498
1499 static TemplateParameterList *
createTypePackElementParameterList(const ASTContext & C,DeclContext * DC)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);
1506
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);
1513
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);
1519 }
1520
createBuiltinTemplateParameterList(const ASTContext & C,DeclContext * DC,BuiltinTemplateKind BTK)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);
1528 }
1529
1530 llvm_unreachable("unhandled BuiltinTemplateKind!");
1531 }
1532
anchor()1533 void BuiltinTemplateDecl::anchor() {}
1534
BuiltinTemplateDecl(const ASTContext & C,DeclContext * DC,DeclarationName Name,BuiltinTemplateKind BTK)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) {}
1541
print(llvm::raw_ostream & OS,PrintingPolicy Policy) const1542 void TypeConstraint::print(llvm::raw_ostream &OS, PrintingPolicy Policy) const {
1543 if (NestedNameSpec)
1544 NestedNameSpec.getNestedNameSpecifier()->print(OS, Policy);
1545 ConceptName.printName(OS, Policy);
1546 if (hasExplicitTemplateArgs()) {
1547 OS << "<";
1548 // FIXME: Find corresponding parameter for argument
1549 for (auto &ArgLoc : ArgsAsWritten->arguments())
1550 ArgLoc.getArgument().print(Policy, OS, /*IncludeType*/ false);
1551 OS << ">";
1552 }
1553 }
1554
Create(const ASTContext & C,QualType T,const APValue & V)1555 TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1556 QualType T,
1557 const APValue &V) {
1558 DeclContext *DC = C.getTranslationUnitDecl();
1559 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1560 C.addDestruction(&TPOD->Value);
1561 return TPOD;
1562 }
1563
1564 TemplateParamObjectDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1565 TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1566 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1567 C.addDestruction(&TPOD->Value);
1568 return TPOD;
1569 }
1570
printName(llvm::raw_ostream & OS,const PrintingPolicy & Policy) const1571 void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1572 const PrintingPolicy &Policy) const {
1573 OS << "<template param ";
1574 printAsExpr(OS, Policy);
1575 OS << ">";
1576 }
1577
printAsExpr(llvm::raw_ostream & OS) const1578 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1579 printAsExpr(OS, getASTContext().getPrintingPolicy());
1580 }
1581
printAsExpr(llvm::raw_ostream & OS,const PrintingPolicy & Policy) const1582 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1583 const PrintingPolicy &Policy) const {
1584 getType().getUnqualifiedType().print(OS, Policy);
1585 printAsInit(OS, Policy);
1586 }
1587
printAsInit(llvm::raw_ostream & OS) const1588 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1589 printAsInit(OS, getASTContext().getPrintingPolicy());
1590 }
1591
printAsInit(llvm::raw_ostream & OS,const PrintingPolicy & Policy) const1592 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1593 const PrintingPolicy &Policy) const {
1594 getValue().printPretty(OS, Policy, getType(), &getASTContext());
1595 }
1596
getReplacedTemplateParameterList(Decl * D)1597 TemplateParameterList *clang::getReplacedTemplateParameterList(Decl *D) {
1598 switch (D->getKind()) {
1599 case Decl::Kind::ClassTemplate:
1600 return cast<ClassTemplateDecl>(D)->getTemplateParameters();
1601 case Decl::Kind::ClassTemplateSpecialization: {
1602 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1603 auto P = CTSD->getSpecializedTemplateOrPartial();
1604 if (const auto *CTPSD =
1605 P.dyn_cast<ClassTemplatePartialSpecializationDecl *>())
1606 return CTPSD->getTemplateParameters();
1607 return cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1608 }
1609 case Decl::Kind::ClassTemplatePartialSpecialization:
1610 return cast<ClassTemplatePartialSpecializationDecl>(D)
1611 ->getTemplateParameters();
1612 case Decl::Kind::TypeAliasTemplate:
1613 return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
1614 case Decl::Kind::BuiltinTemplate:
1615 return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
1616 case Decl::Kind::CXXDeductionGuide:
1617 case Decl::Kind::CXXConversion:
1618 case Decl::Kind::CXXConstructor:
1619 case Decl::Kind::CXXDestructor:
1620 case Decl::Kind::CXXMethod:
1621 case Decl::Kind::Function:
1622 return cast<FunctionDecl>(D)
1623 ->getTemplateSpecializationInfo()
1624 ->getTemplate()
1625 ->getTemplateParameters();
1626 case Decl::Kind::FunctionTemplate:
1627 return cast<FunctionTemplateDecl>(D)->getTemplateParameters();
1628 case Decl::Kind::VarTemplate:
1629 return cast<VarTemplateDecl>(D)->getTemplateParameters();
1630 case Decl::Kind::VarTemplateSpecialization: {
1631 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1632 auto P = VTSD->getSpecializedTemplateOrPartial();
1633 if (const auto *VTPSD =
1634 P.dyn_cast<VarTemplatePartialSpecializationDecl *>())
1635 return VTPSD->getTemplateParameters();
1636 return cast<VarTemplateDecl *>(P)->getTemplateParameters();
1637 }
1638 case Decl::Kind::VarTemplatePartialSpecialization:
1639 return cast<VarTemplatePartialSpecializationDecl>(D)
1640 ->getTemplateParameters();
1641 case Decl::Kind::TemplateTemplateParm:
1642 return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();
1643 case Decl::Kind::Concept:
1644 return cast<ConceptDecl>(D)->getTemplateParameters();
1645 default:
1646 llvm_unreachable("Unhandled templated declaration kind");
1647 }
1648 }
1649