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
Profile(llvm::FoldingSetNodeID & ID,const ASTContext & C) const130 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;
146 }
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;
155 }
156 const auto *TTP = cast<TemplateTemplateParmDecl>(D);
157 ID.AddInteger(2);
158 ID.AddBoolean(TTP->isParameterPack());
159 TTP->getTemplateParameters()->Profile(ID, C);
160 }
161 }
162
getMinRequiredArguments() const163 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;
170 }
171 break;
172 }
173
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;
182
183 ++NumRequiredArgs;
184 }
185
186 return NumRequiredArgs;
187 }
188
getDepth() const189 unsigned TemplateParameterList::getDepth() const {
190 if (size() == 0)
191 return 0;
192
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();
200 }
201
AdoptTemplateParameterList(TemplateParameterList * Params,DeclContext * Owner)202 static bool AdoptTemplateParameterList(TemplateParameterList *Params,
203 DeclContext *Owner) {
204 bool Invalid = false;
205 for (NamedDecl *P : *Params) {
206 P->setDeclContext(Owner);
207
208 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
209 if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner))
210 Invalid = true;
211
212 if (P->isInvalidDecl())
213 Invalid = true;
214 }
215 return Invalid;
216 }
217
218 void TemplateParameterList::
getAssociatedConstraints(llvm::SmallVectorImpl<const Expr * > & AC) const219 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);
228 }
229 }
230 if (HasRequiresClause)
231 AC.push_back(getRequiresClause());
232 }
233
hasAssociatedConstraints() const234 bool TemplateParameterList::hasAssociatedConstraints() const {
235 return HasRequiresClause || HasConstrainedParameters;
236 }
237
shouldIncludeTypeForArgument(const PrintingPolicy & Policy,const TemplateParameterList * TPL,unsigned Idx)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;
249 }
250
251 namespace clang {
252
allocateDefaultArgStorageChain(const ASTContext & C)253 void *allocateDefaultArgStorageChain(const ASTContext &C) {
254 return new (C) char[sizeof(void*) * 2];
255 }
256
257 } // namespace clang
258
259 //===----------------------------------------------------------------------===//
260 // TemplateDecl Implementation
261 //===----------------------------------------------------------------------===//
262
TemplateDecl(Kind DK,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)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) {}
267
anchor()268 void TemplateDecl::anchor() {}
269
270 void TemplateDecl::
getAssociatedConstraints(llvm::SmallVectorImpl<const Expr * > & AC) const271 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);
276 }
277
hasAssociatedConstraints() const278 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;
284 }
285
isTypeAlias() const286 bool TemplateDecl::isTypeAlias() const {
287 switch (getKind()) {
288 case TemplateDecl::TypeAliasTemplate:
289 case TemplateDecl::BuiltinTemplate:
290 return true;
291 default:
292 return false;
293 };
294 }
295
296 //===----------------------------------------------------------------------===//
297 // RedeclarableTemplateDecl Implementation
298 //===----------------------------------------------------------------------===//
299
anchor()300 void RedeclarableTemplateDecl::anchor() {}
301
getCommonPtr() const302 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
303 if (Common)
304 return Common;
305
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;
314 }
315
316 PrevDecls.push_back(Prev);
317 }
318
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.
323
324 Common = newCommon(getASTContext());
325 }
326
327 // Update any previous declarations we saw with the common pointer.
328 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
329 Prev->Common = Common;
330
331 return Common;
332 }
333
loadLazySpecializationsImpl() const334 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 GlobalDeclID *Specs = CommonBasePtr->LazySpecializations;
341 CommonBasePtr->LazySpecializations = nullptr;
342 unsigned SpecSize = (*Specs++).getRawValue();
343 for (unsigned I = 0; I != SpecSize; ++I)
344 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
345 }
346 }
347
348 template<class EntryType, typename... ProfileArguments>
349 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
findSpecializationImpl(llvm::FoldingSetVector<EntryType> & Specs,void * & InsertPos,ProfileArguments &&...ProfileArgs)350 RedeclarableTemplateDecl::findSpecializationImpl(
351 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos,
352 ProfileArguments&&... ProfileArgs) {
353 using SETraits = SpecEntryTraits<EntryType>;
354
355 llvm::FoldingSetNodeID ID;
356 EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)...,
357 getASTContext());
358 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
359 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
360 }
361
362 template<class Derived, class EntryType>
addSpecializationImpl(llvm::FoldingSetVector<EntryType> & Specializations,EntryType * Entry,void * InsertPos)363 void RedeclarableTemplateDecl::addSpecializationImpl(
364 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
365 void *InsertPos) {
366 using SETraits = SpecEntryTraits<EntryType>;
367
368 if (InsertPos) {
369 #ifndef NDEBUG
370 void *CorrectInsertPos;
371 assert(!findSpecializationImpl(Specializations,
372 CorrectInsertPos,
373 SETraits::getTemplateArgs(Entry)) &&
374 InsertPos == CorrectInsertPos &&
375 "given incorrect InsertPos for specialization");
376 #endif
377 Specializations.InsertNode(Entry, InsertPos);
378 } else {
379 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
380 (void)Existing;
381 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
382 "non-canonical specialization?");
383 }
384
385 if (ASTMutationListener *L = getASTMutationListener())
386 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
387 SETraits::getDecl(Entry));
388 }
389
getInjectedTemplateArgs()390 ArrayRef<TemplateArgument> RedeclarableTemplateDecl::getInjectedTemplateArgs() {
391 TemplateParameterList *Params = getTemplateParameters();
392 auto *CommonPtr = getCommonPtr();
393 if (!CommonPtr->InjectedArgs) {
394 auto &Context = getASTContext();
395 SmallVector<TemplateArgument, 16> TemplateArgs;
396 Context.getInjectedTemplateArgs(Params, TemplateArgs);
397 CommonPtr->InjectedArgs =
398 new (Context) TemplateArgument[TemplateArgs.size()];
399 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
400 CommonPtr->InjectedArgs);
401 }
402
403 return llvm::ArrayRef(CommonPtr->InjectedArgs, Params->size());
404 }
405
406 //===----------------------------------------------------------------------===//
407 // FunctionTemplateDecl Implementation
408 //===----------------------------------------------------------------------===//
409
410 FunctionTemplateDecl *
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)411 FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
412 DeclarationName Name,
413 TemplateParameterList *Params, NamedDecl *Decl) {
414 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
415 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
416 if (Invalid)
417 TD->setInvalidDecl();
418 return TD;
419 }
420
421 FunctionTemplateDecl *
CreateDeserialized(ASTContext & C,GlobalDeclID ID)422 FunctionTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
423 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
424 DeclarationName(), nullptr, nullptr);
425 }
426
427 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const428 FunctionTemplateDecl::newCommon(ASTContext &C) const {
429 auto *CommonPtr = new (C) Common;
430 C.addDestruction(CommonPtr);
431 return CommonPtr;
432 }
433
LoadLazySpecializations() const434 void FunctionTemplateDecl::LoadLazySpecializations() const {
435 loadLazySpecializationsImpl();
436 }
437
438 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
getSpecializations() const439 FunctionTemplateDecl::getSpecializations() const {
440 LoadLazySpecializations();
441 return getCommonPtr()->Specializations;
442 }
443
444 FunctionDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)445 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
446 void *&InsertPos) {
447 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
448 }
449
addSpecialization(FunctionTemplateSpecializationInfo * Info,void * InsertPos)450 void FunctionTemplateDecl::addSpecialization(
451 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
452 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
453 InsertPos);
454 }
455
mergePrevDecl(FunctionTemplateDecl * Prev)456 void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
457 using Base = RedeclarableTemplateDecl;
458
459 // If we haven't created a common pointer yet, then it can just be created
460 // with the usual method.
461 if (!Base::Common)
462 return;
463
464 Common *ThisCommon = static_cast<Common *>(Base::Common);
465 Common *PrevCommon = nullptr;
466 SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
467 for (; Prev; Prev = Prev->getPreviousDecl()) {
468 if (Prev->Base::Common) {
469 PrevCommon = static_cast<Common *>(Prev->Base::Common);
470 break;
471 }
472 PreviousDecls.push_back(Prev);
473 }
474
475 // If the previous redecl chain hasn't created a common pointer yet, then just
476 // use this common pointer.
477 if (!PrevCommon) {
478 for (auto *D : PreviousDecls)
479 D->Base::Common = ThisCommon;
480 return;
481 }
482
483 // Ensure we don't leak any important state.
484 assert(ThisCommon->Specializations.size() == 0 &&
485 "Can't merge incompatible declarations!");
486
487 Base::Common = PrevCommon;
488 }
489
490 //===----------------------------------------------------------------------===//
491 // ClassTemplateDecl Implementation
492 //===----------------------------------------------------------------------===//
493
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)494 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC,
495 SourceLocation L,
496 DeclarationName Name,
497 TemplateParameterList *Params,
498 NamedDecl *Decl) {
499 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
500 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
501 if (Invalid)
502 TD->setInvalidDecl();
503 return TD;
504 }
505
CreateDeserialized(ASTContext & C,GlobalDeclID ID)506 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
507 GlobalDeclID ID) {
508 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
509 DeclarationName(), nullptr, nullptr);
510 }
511
LoadLazySpecializations() const512 void ClassTemplateDecl::LoadLazySpecializations() const {
513 loadLazySpecializationsImpl();
514 }
515
516 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
getSpecializations() const517 ClassTemplateDecl::getSpecializations() const {
518 LoadLazySpecializations();
519 return getCommonPtr()->Specializations;
520 }
521
522 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations() const523 ClassTemplateDecl::getPartialSpecializations() const {
524 LoadLazySpecializations();
525 return getCommonPtr()->PartialSpecializations;
526 }
527
528 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const529 ClassTemplateDecl::newCommon(ASTContext &C) const {
530 auto *CommonPtr = new (C) Common;
531 C.addDestruction(CommonPtr);
532 return CommonPtr;
533 }
534
535 ClassTemplateSpecializationDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)536 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
537 void *&InsertPos) {
538 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
539 }
540
AddSpecialization(ClassTemplateSpecializationDecl * D,void * InsertPos)541 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
542 void *InsertPos) {
543 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
544 }
545
546 ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args,TemplateParameterList * TPL,void * & InsertPos)547 ClassTemplateDecl::findPartialSpecialization(
548 ArrayRef<TemplateArgument> Args,
549 TemplateParameterList *TPL, void *&InsertPos) {
550 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
551 TPL);
552 }
553
Profile(llvm::FoldingSetNodeID & ID,ArrayRef<TemplateArgument> TemplateArgs,TemplateParameterList * TPL,const ASTContext & Context)554 void ClassTemplatePartialSpecializationDecl::Profile(
555 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
556 TemplateParameterList *TPL, const ASTContext &Context) {
557 ID.AddInteger(TemplateArgs.size());
558 for (const TemplateArgument &TemplateArg : TemplateArgs)
559 TemplateArg.Profile(ID, Context);
560 TPL->Profile(ID, Context);
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 TemplateName Name = Context.getQualifiedTemplateName(
631 /*NNS=*/nullptr, /*TemplateKeyword=*/false, TemplateName(this));
632 CommonPtr->InjectedClassNameType =
633 Context.getTemplateSpecializationType(Name, TemplateArgs);
634 return CommonPtr->InjectedClassNameType;
635 }
636
637 //===----------------------------------------------------------------------===//
638 // TemplateTypeParm Allocation/Deallocation Method Implementations
639 //===----------------------------------------------------------------------===//
640
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)641 TemplateTypeParmDecl *TemplateTypeParmDecl::Create(
642 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc,
643 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id,
644 bool Typename, bool ParameterPack, bool HasTypeConstraint,
645 std::optional<unsigned> NumExpanded) {
646 auto *TTPDecl =
647 new (C, DC,
648 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
649 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename,
650 HasTypeConstraint, NumExpanded);
651 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
652 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
653 return TTPDecl;
654 }
655
656 TemplateTypeParmDecl *
CreateDeserialized(const ASTContext & C,GlobalDeclID ID)657 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID) {
658 return new (C, ID)
659 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
660 false, false, std::nullopt);
661 }
662
663 TemplateTypeParmDecl *
CreateDeserialized(const ASTContext & C,GlobalDeclID ID,bool HasTypeConstraint)664 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID,
665 bool HasTypeConstraint) {
666 return new (C, ID,
667 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0))
668 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr,
669 false, HasTypeConstraint, std::nullopt);
670 }
671
getDefaultArgumentLoc() const672 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
673 return hasDefaultArgument() ? getDefaultArgument().getLocation()
674 : SourceLocation();
675 }
676
getSourceRange() const677 SourceRange TemplateTypeParmDecl::getSourceRange() const {
678 if (hasDefaultArgument() && !defaultArgumentWasInherited())
679 return SourceRange(getBeginLoc(),
680 getDefaultArgument().getSourceRange().getEnd());
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 if (getDeclName().isEmpty())
685 return SourceRange(getBeginLoc());
686 return TypeDecl::getSourceRange();
687 }
688
setDefaultArgument(const ASTContext & C,const TemplateArgumentLoc & DefArg)689 void TemplateTypeParmDecl::setDefaultArgument(
690 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
691 if (DefArg.getArgument().isNull())
692 DefaultArgument.set(nullptr);
693 else
694 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
695 }
696
getDepth() const697 unsigned TemplateTypeParmDecl::getDepth() const {
698 return getTypeForDecl()->castAs<TemplateTypeParmType>()->getDepth();
699 }
700
getIndex() const701 unsigned TemplateTypeParmDecl::getIndex() const {
702 return getTypeForDecl()->castAs<TemplateTypeParmType>()->getIndex();
703 }
704
isParameterPack() const705 bool TemplateTypeParmDecl::isParameterPack() const {
706 return getTypeForDecl()->castAs<TemplateTypeParmType>()->isParameterPack();
707 }
708
setTypeConstraint(ConceptReference * Loc,Expr * ImmediatelyDeclaredConstraint)709 void TemplateTypeParmDecl::setTypeConstraint(
710 ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint) {
711 assert(HasTypeConstraint &&
712 "HasTypeConstraint=true must be passed at construction in order to "
713 "call setTypeConstraint");
714 assert(!TypeConstraintInitialized &&
715 "TypeConstraint was already initialized!");
716 new (getTrailingObjects<TypeConstraint>())
717 TypeConstraint(Loc, ImmediatelyDeclaredConstraint);
718 TypeConstraintInitialized = true;
719 }
720
721 //===----------------------------------------------------------------------===//
722 // NonTypeTemplateParmDecl Method Implementations
723 //===----------------------------------------------------------------------===//
724
NonTypeTemplateParmDecl(DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,const IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,ArrayRef<QualType> ExpandedTypes,ArrayRef<TypeSourceInfo * > ExpandedTInfos)725 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
726 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
727 unsigned P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
728 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
729 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
730 TemplateParmPosition(D, P), ParameterPack(true),
731 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
732 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
733 auto TypesAndInfos =
734 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
735 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
736 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
737 TypesAndInfos[I].second = ExpandedTInfos[I];
738 }
739 }
740 }
741
Create(const ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,const IdentifierInfo * Id,QualType T,bool ParameterPack,TypeSourceInfo * TInfo)742 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
743 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
744 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
745 QualType T, bool ParameterPack, TypeSourceInfo *TInfo) {
746 AutoType *AT =
747 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr;
748 return new (C, DC,
749 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
750 Expr *>(0,
751 AT && AT->isConstrained() ? 1 : 0))
752 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack,
753 TInfo);
754 }
755
Create(const ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,const IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,ArrayRef<QualType> ExpandedTypes,ArrayRef<TypeSourceInfo * > ExpandedTInfos)756 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
757 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
758 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id,
759 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
760 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
761 AutoType *AT = TInfo->getType()->getContainedAutoType();
762 return new (C, DC,
763 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>,
764 Expr *>(
765 ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0))
766 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
767 ExpandedTypes, ExpandedTInfos);
768 }
769
770 NonTypeTemplateParmDecl *
CreateDeserialized(ASTContext & C,GlobalDeclID ID,bool HasTypeConstraint)771 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,
772 bool HasTypeConstraint) {
773 return new (C, ID, additionalSizeToAlloc<std::pair<QualType,
774 TypeSourceInfo *>,
775 Expr *>(0,
776 HasTypeConstraint ? 1 : 0))
777 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
778 0, 0, nullptr, QualType(), false, nullptr);
779 }
780
781 NonTypeTemplateParmDecl *
CreateDeserialized(ASTContext & C,GlobalDeclID ID,unsigned NumExpandedTypes,bool HasTypeConstraint)782 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,
783 unsigned NumExpandedTypes,
784 bool HasTypeConstraint) {
785 auto *NTTP =
786 new (C, ID,
787 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>(
788 NumExpandedTypes, HasTypeConstraint ? 1 : 0))
789 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
790 0, 0, nullptr, QualType(), nullptr,
791 std::nullopt, std::nullopt);
792 NTTP->NumExpandedTypes = NumExpandedTypes;
793 return NTTP;
794 }
795
getSourceRange() const796 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
797 if (hasDefaultArgument() && !defaultArgumentWasInherited())
798 return SourceRange(getOuterLocStart(),
799 getDefaultArgument().getSourceRange().getEnd());
800 return DeclaratorDecl::getSourceRange();
801 }
802
getDefaultArgumentLoc() const803 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
804 return hasDefaultArgument() ? getDefaultArgument().getSourceRange().getBegin()
805 : SourceLocation();
806 }
807
setDefaultArgument(const ASTContext & C,const TemplateArgumentLoc & DefArg)808 void NonTypeTemplateParmDecl::setDefaultArgument(
809 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
810 if (DefArg.getArgument().isNull())
811 DefaultArgument.set(nullptr);
812 else
813 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
814 }
815
816 //===----------------------------------------------------------------------===//
817 // TemplateTemplateParmDecl Method Implementations
818 //===----------------------------------------------------------------------===//
819
anchor()820 void TemplateTemplateParmDecl::anchor() {}
821
TemplateTemplateParmDecl(DeclContext * DC,SourceLocation L,unsigned D,unsigned P,IdentifierInfo * Id,bool Typename,TemplateParameterList * Params,ArrayRef<TemplateParameterList * > Expansions)822 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
823 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
824 IdentifierInfo *Id, bool Typename, TemplateParameterList *Params,
825 ArrayRef<TemplateParameterList *> Expansions)
826 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
827 TemplateParmPosition(D, P), Typename(Typename), ParameterPack(true),
828 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
829 if (!Expansions.empty())
830 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
831 getTrailingObjects<TemplateParameterList *>());
832 }
833
834 TemplateTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation L,unsigned D,unsigned P,bool ParameterPack,IdentifierInfo * Id,bool Typename,TemplateParameterList * Params)835 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
836 SourceLocation L, unsigned D, unsigned P,
837 bool ParameterPack, IdentifierInfo *Id,
838 bool Typename, TemplateParameterList *Params) {
839 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
840 Typename, Params);
841 }
842
843 TemplateTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation L,unsigned D,unsigned P,IdentifierInfo * Id,bool Typename,TemplateParameterList * Params,ArrayRef<TemplateParameterList * > Expansions)844 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
845 SourceLocation L, unsigned D, unsigned P,
846 IdentifierInfo *Id, bool Typename,
847 TemplateParameterList *Params,
848 ArrayRef<TemplateParameterList *> Expansions) {
849 return new (C, DC,
850 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
851 TemplateTemplateParmDecl(DC, L, D, P, Id, Typename, Params, Expansions);
852 }
853
854 TemplateTemplateParmDecl *
CreateDeserialized(ASTContext & C,GlobalDeclID ID)855 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
856 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
857 false, nullptr, false, nullptr);
858 }
859
860 TemplateTemplateParmDecl *
CreateDeserialized(ASTContext & C,GlobalDeclID ID,unsigned NumExpansions)861 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID,
862 unsigned NumExpansions) {
863 auto *TTP =
864 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
865 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
866 false, nullptr, std::nullopt);
867 TTP->NumExpandedParams = NumExpansions;
868 return TTP;
869 }
870
getDefaultArgumentLoc() const871 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
872 return hasDefaultArgument() ? getDefaultArgument().getLocation()
873 : SourceLocation();
874 }
875
setDefaultArgument(const ASTContext & C,const TemplateArgumentLoc & DefArg)876 void TemplateTemplateParmDecl::setDefaultArgument(
877 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
878 if (DefArg.getArgument().isNull())
879 DefaultArgument.set(nullptr);
880 else
881 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
882 }
883
884 //===----------------------------------------------------------------------===//
885 // TemplateArgumentList Implementation
886 //===----------------------------------------------------------------------===//
TemplateArgumentList(ArrayRef<TemplateArgument> Args)887 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
888 : NumArguments(Args.size()) {
889 std::uninitialized_copy(Args.begin(), Args.end(),
890 getTrailingObjects<TemplateArgument>());
891 }
892
893 TemplateArgumentList *
CreateCopy(ASTContext & Context,ArrayRef<TemplateArgument> Args)894 TemplateArgumentList::CreateCopy(ASTContext &Context,
895 ArrayRef<TemplateArgument> Args) {
896 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
897 return new (Mem) TemplateArgumentList(Args);
898 }
899
Create(ASTContext & C,FunctionDecl * FD,FunctionTemplateDecl * Template,TemplateSpecializationKind TSK,TemplateArgumentList * TemplateArgs,const TemplateArgumentListInfo * TemplateArgsAsWritten,SourceLocation POI,MemberSpecializationInfo * MSInfo)900 FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
901 ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
902 TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs,
903 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
904 MemberSpecializationInfo *MSInfo) {
905 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
906 if (TemplateArgsAsWritten)
907 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
908 *TemplateArgsAsWritten);
909
910 void *Mem =
911 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
912 return new (Mem) FunctionTemplateSpecializationInfo(
913 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
914 }
915
916 //===----------------------------------------------------------------------===//
917 // ClassTemplateSpecializationDecl Implementation
918 //===----------------------------------------------------------------------===//
919
920 ClassTemplateSpecializationDecl::
ClassTemplateSpecializationDecl(ASTContext & Context,Kind DK,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,ClassTemplateSpecializationDecl * PrevDecl)921 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
922 DeclContext *DC, SourceLocation StartLoc,
923 SourceLocation IdLoc,
924 ClassTemplateDecl *SpecializedTemplate,
925 ArrayRef<TemplateArgument> Args,
926 ClassTemplateSpecializationDecl *PrevDecl)
927 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
928 SpecializedTemplate->getIdentifier(), PrevDecl),
929 SpecializedTemplate(SpecializedTemplate),
930 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
931 SpecializationKind(TSK_Undeclared) {
932 }
933
ClassTemplateSpecializationDecl(ASTContext & C,Kind DK)934 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
935 Kind DK)
936 : CXXRecordDecl(DK, TagTypeKind::Struct, C, nullptr, SourceLocation(),
937 SourceLocation(), nullptr, nullptr),
938 SpecializationKind(TSK_Undeclared) {}
939
940 ClassTemplateSpecializationDecl *
Create(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,ClassTemplateSpecializationDecl * PrevDecl)941 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
942 DeclContext *DC,
943 SourceLocation StartLoc,
944 SourceLocation IdLoc,
945 ClassTemplateDecl *SpecializedTemplate,
946 ArrayRef<TemplateArgument> Args,
947 ClassTemplateSpecializationDecl *PrevDecl) {
948 auto *Result =
949 new (Context, DC) ClassTemplateSpecializationDecl(
950 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
951 SpecializedTemplate, Args, PrevDecl);
952 Result->setMayHaveOutOfDateDef(false);
953
954 // If the template decl is incomplete, copy the external lexical storage from
955 // the base template. This allows instantiations of incomplete types to
956 // complete using the external AST if the template's declaration came from an
957 // external AST.
958 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition())
959 Result->setHasExternalLexicalStorage(
960 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
961
962 Context.getTypeDeclType(Result, PrevDecl);
963 return Result;
964 }
965
966 ClassTemplateSpecializationDecl *
CreateDeserialized(ASTContext & C,GlobalDeclID ID)967 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
968 GlobalDeclID ID) {
969 auto *Result =
970 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
971 Result->setMayHaveOutOfDateDef(false);
972 return Result;
973 }
974
getNameForDiagnostic(raw_ostream & OS,const PrintingPolicy & Policy,bool Qualified) const975 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
976 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
977 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
978
979 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
980 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
981 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
982 printTemplateArgumentList(
983 OS, ArgsAsWritten->arguments(), Policy,
984 getSpecializedTemplate()->getTemplateParameters());
985 } else {
986 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
987 printTemplateArgumentList(
988 OS, TemplateArgs.asArray(), Policy,
989 getSpecializedTemplate()->getTemplateParameters());
990 }
991 }
992
993 ClassTemplateDecl *
getSpecializedTemplate() const994 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
995 if (const auto *PartialSpec =
996 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
997 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
998 return SpecializedTemplate.get<ClassTemplateDecl*>();
999 }
1000
1001 SourceRange
getSourceRange() const1002 ClassTemplateSpecializationDecl::getSourceRange() const {
1003 switch (getSpecializationKind()) {
1004 case TSK_Undeclared:
1005 case TSK_ImplicitInstantiation: {
1006 llvm::PointerUnion<ClassTemplateDecl *,
1007 ClassTemplatePartialSpecializationDecl *>
1008 Pattern = getSpecializedTemplateOrPartial();
1009 assert(!Pattern.isNull() &&
1010 "Class template specialization without pattern?");
1011 if (const auto *CTPSD =
1012 Pattern.dyn_cast<ClassTemplatePartialSpecializationDecl *>())
1013 return CTPSD->getSourceRange();
1014 return Pattern.get<ClassTemplateDecl *>()->getSourceRange();
1015 }
1016 case TSK_ExplicitSpecialization: {
1017 SourceRange Range = CXXRecordDecl::getSourceRange();
1018 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten();
1019 !isThisDeclarationADefinition() && Args)
1020 Range.setEnd(Args->getRAngleLoc());
1021 return Range;
1022 }
1023 case TSK_ExplicitInstantiationDeclaration:
1024 case TSK_ExplicitInstantiationDefinition: {
1025 SourceRange Range = CXXRecordDecl::getSourceRange();
1026 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1027 Range.setBegin(ExternKW);
1028 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1029 TemplateKW.isValid())
1030 Range.setBegin(TemplateKW);
1031 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten())
1032 Range.setEnd(Args->getRAngleLoc());
1033 return Range;
1034 }
1035 }
1036 llvm_unreachable("unhandled template specialization kind");
1037 }
1038
setExternKeywordLoc(SourceLocation Loc)1039 void ClassTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) {
1040 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1041 if (!Info) {
1042 // Don't allocate if the location is invalid.
1043 if (Loc.isInvalid())
1044 return;
1045 Info = new (getASTContext()) ExplicitInstantiationInfo;
1046 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
1047 ExplicitInfo = Info;
1048 }
1049 Info->ExternKeywordLoc = Loc;
1050 }
1051
setTemplateKeywordLoc(SourceLocation Loc)1052 void ClassTemplateSpecializationDecl::setTemplateKeywordLoc(
1053 SourceLocation Loc) {
1054 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1055 if (!Info) {
1056 // Don't allocate if the location is invalid.
1057 if (Loc.isInvalid())
1058 return;
1059 Info = new (getASTContext()) ExplicitInstantiationInfo;
1060 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
1061 ExplicitInfo = Info;
1062 }
1063 Info->TemplateKeywordLoc = Loc;
1064 }
1065
1066 //===----------------------------------------------------------------------===//
1067 // ConceptDecl Implementation
1068 //===----------------------------------------------------------------------===//
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,Expr * ConstraintExpr)1069 ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
1070 SourceLocation L, DeclarationName Name,
1071 TemplateParameterList *Params,
1072 Expr *ConstraintExpr) {
1073 bool Invalid = AdoptTemplateParameterList(Params, DC);
1074 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
1075 if (Invalid)
1076 TD->setInvalidDecl();
1077 return TD;
1078 }
1079
CreateDeserialized(ASTContext & C,GlobalDeclID ID)1080 ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1081 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
1082 DeclarationName(),
1083 nullptr, nullptr);
1084
1085 return Result;
1086 }
1087
1088 //===----------------------------------------------------------------------===//
1089 // ImplicitConceptSpecializationDecl Implementation
1090 //===----------------------------------------------------------------------===//
ImplicitConceptSpecializationDecl(DeclContext * DC,SourceLocation SL,ArrayRef<TemplateArgument> ConvertedArgs)1091 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1092 DeclContext *DC, SourceLocation SL,
1093 ArrayRef<TemplateArgument> ConvertedArgs)
1094 : Decl(ImplicitConceptSpecialization, DC, SL),
1095 NumTemplateArgs(ConvertedArgs.size()) {
1096 setTemplateArguments(ConvertedArgs);
1097 }
1098
ImplicitConceptSpecializationDecl(EmptyShell Empty,unsigned NumTemplateArgs)1099 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl(
1100 EmptyShell Empty, unsigned NumTemplateArgs)
1101 : Decl(ImplicitConceptSpecialization, Empty),
1102 NumTemplateArgs(NumTemplateArgs) {}
1103
Create(const ASTContext & C,DeclContext * DC,SourceLocation SL,ArrayRef<TemplateArgument> ConvertedArgs)1104 ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create(
1105 const ASTContext &C, DeclContext *DC, SourceLocation SL,
1106 ArrayRef<TemplateArgument> ConvertedArgs) {
1107 return new (C, DC,
1108 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size()))
1109 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs);
1110 }
1111
1112 ImplicitConceptSpecializationDecl *
CreateDeserialized(const ASTContext & C,GlobalDeclID ID,unsigned NumTemplateArgs)1113 ImplicitConceptSpecializationDecl::CreateDeserialized(
1114 const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) {
1115 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs))
1116 ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs);
1117 }
1118
setTemplateArguments(ArrayRef<TemplateArgument> Converted)1119 void ImplicitConceptSpecializationDecl::setTemplateArguments(
1120 ArrayRef<TemplateArgument> Converted) {
1121 assert(Converted.size() == NumTemplateArgs);
1122 std::uninitialized_copy(Converted.begin(), Converted.end(),
1123 getTrailingObjects<TemplateArgument>());
1124 }
1125
1126 //===----------------------------------------------------------------------===//
1127 // ClassTemplatePartialSpecializationDecl Implementation
1128 //===----------------------------------------------------------------------===//
anchor()1129 void ClassTemplatePartialSpecializationDecl::anchor() {}
1130
ClassTemplatePartialSpecializationDecl(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,ClassTemplatePartialSpecializationDecl * PrevDecl)1131 ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
1132 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1133 SourceLocation IdLoc, TemplateParameterList *Params,
1134 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1135 ClassTemplatePartialSpecializationDecl *PrevDecl)
1136 : ClassTemplateSpecializationDecl(
1137 Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
1138 SpecializedTemplate, Args, PrevDecl),
1139 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1140 if (AdoptTemplateParameterList(Params, this))
1141 setInvalidDecl();
1142 }
1143
1144 ClassTemplatePartialSpecializationDecl *
Create(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,QualType CanonInjectedType,ClassTemplatePartialSpecializationDecl * PrevDecl)1145 ClassTemplatePartialSpecializationDecl::Create(
1146 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
1147 SourceLocation IdLoc, TemplateParameterList *Params,
1148 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
1149 QualType CanonInjectedType,
1150 ClassTemplatePartialSpecializationDecl *PrevDecl) {
1151 auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl(
1152 Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args,
1153 PrevDecl);
1154 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1155 Result->setMayHaveOutOfDateDef(false);
1156
1157 Context.getInjectedClassNameType(Result, CanonInjectedType);
1158 return Result;
1159 }
1160
1161 ClassTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext & C,GlobalDeclID ID)1162 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1163 GlobalDeclID ID) {
1164 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
1165 Result->setMayHaveOutOfDateDef(false);
1166 return Result;
1167 }
1168
getSourceRange() const1169 SourceRange ClassTemplatePartialSpecializationDecl::getSourceRange() const {
1170 if (const ClassTemplatePartialSpecializationDecl *MT =
1171 getInstantiatedFromMember();
1172 MT && !isMemberSpecialization())
1173 return MT->getSourceRange();
1174 SourceRange Range = ClassTemplateSpecializationDecl::getSourceRange();
1175 if (const TemplateParameterList *TPL = getTemplateParameters();
1176 TPL && !getNumTemplateParameterLists())
1177 Range.setBegin(TPL->getTemplateLoc());
1178 return Range;
1179 }
1180
1181 //===----------------------------------------------------------------------===//
1182 // FriendTemplateDecl Implementation
1183 //===----------------------------------------------------------------------===//
1184
anchor()1185 void FriendTemplateDecl::anchor() {}
1186
1187 FriendTemplateDecl *
Create(ASTContext & Context,DeclContext * DC,SourceLocation L,MutableArrayRef<TemplateParameterList * > Params,FriendUnion Friend,SourceLocation FLoc)1188 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
1189 SourceLocation L,
1190 MutableArrayRef<TemplateParameterList *> Params,
1191 FriendUnion Friend, SourceLocation FLoc) {
1192 TemplateParameterList **TPL = nullptr;
1193 if (!Params.empty()) {
1194 TPL = new (Context) TemplateParameterList *[Params.size()];
1195 llvm::copy(Params, TPL);
1196 }
1197 return new (Context, DC)
1198 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc);
1199 }
1200
CreateDeserialized(ASTContext & C,GlobalDeclID ID)1201 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
1202 GlobalDeclID ID) {
1203 return new (C, ID) FriendTemplateDecl(EmptyShell());
1204 }
1205
1206 //===----------------------------------------------------------------------===//
1207 // TypeAliasTemplateDecl Implementation
1208 //===----------------------------------------------------------------------===//
1209
1210 TypeAliasTemplateDecl *
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)1211 TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
1212 DeclarationName Name,
1213 TemplateParameterList *Params, NamedDecl *Decl) {
1214 bool Invalid = AdoptTemplateParameterList(Params, DC);
1215 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
1216 if (Invalid)
1217 TD->setInvalidDecl();
1218 return TD;
1219 }
1220
1221 TypeAliasTemplateDecl *
CreateDeserialized(ASTContext & C,GlobalDeclID ID)1222 TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1223 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
1224 DeclarationName(), nullptr, nullptr);
1225 }
1226
1227 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const1228 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
1229 auto *CommonPtr = new (C) Common;
1230 C.addDestruction(CommonPtr);
1231 return CommonPtr;
1232 }
1233
1234 //===----------------------------------------------------------------------===//
1235 // VarTemplateDecl Implementation
1236 //===----------------------------------------------------------------------===//
1237
getDefinition()1238 VarTemplateDecl *VarTemplateDecl::getDefinition() {
1239 VarTemplateDecl *CurD = this;
1240 while (CurD) {
1241 if (CurD->isThisDeclarationADefinition())
1242 return CurD;
1243 CurD = CurD->getPreviousDecl();
1244 }
1245 return nullptr;
1246 }
1247
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,VarDecl * Decl)1248 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
1249 SourceLocation L, DeclarationName Name,
1250 TemplateParameterList *Params,
1251 VarDecl *Decl) {
1252 bool Invalid = AdoptTemplateParameterList(Params, DC);
1253 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1254 if (Invalid)
1255 TD->setInvalidDecl();
1256 return TD;
1257 }
1258
CreateDeserialized(ASTContext & C,GlobalDeclID ID)1259 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
1260 GlobalDeclID ID) {
1261 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1262 DeclarationName(), nullptr, nullptr);
1263 }
1264
LoadLazySpecializations() const1265 void VarTemplateDecl::LoadLazySpecializations() const {
1266 loadLazySpecializationsImpl();
1267 }
1268
1269 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
getSpecializations() const1270 VarTemplateDecl::getSpecializations() const {
1271 LoadLazySpecializations();
1272 return getCommonPtr()->Specializations;
1273 }
1274
1275 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
getPartialSpecializations() const1276 VarTemplateDecl::getPartialSpecializations() const {
1277 LoadLazySpecializations();
1278 return getCommonPtr()->PartialSpecializations;
1279 }
1280
1281 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const1282 VarTemplateDecl::newCommon(ASTContext &C) const {
1283 auto *CommonPtr = new (C) Common;
1284 C.addDestruction(CommonPtr);
1285 return CommonPtr;
1286 }
1287
1288 VarTemplateSpecializationDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)1289 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1290 void *&InsertPos) {
1291 return findSpecializationImpl(getSpecializations(), InsertPos, Args);
1292 }
1293
AddSpecialization(VarTemplateSpecializationDecl * D,void * InsertPos)1294 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1295 void *InsertPos) {
1296 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1297 }
1298
1299 VarTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args,TemplateParameterList * TPL,void * & InsertPos)1300 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1301 TemplateParameterList *TPL, void *&InsertPos) {
1302 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args,
1303 TPL);
1304 }
1305
Profile(llvm::FoldingSetNodeID & ID,ArrayRef<TemplateArgument> TemplateArgs,TemplateParameterList * TPL,const ASTContext & Context)1306 void VarTemplatePartialSpecializationDecl::Profile(
1307 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
1308 TemplateParameterList *TPL, const ASTContext &Context) {
1309 ID.AddInteger(TemplateArgs.size());
1310 for (const TemplateArgument &TemplateArg : TemplateArgs)
1311 TemplateArg.Profile(ID, Context);
1312 TPL->Profile(ID, Context);
1313 }
1314
AddPartialSpecialization(VarTemplatePartialSpecializationDecl * D,void * InsertPos)1315 void VarTemplateDecl::AddPartialSpecialization(
1316 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1317 if (InsertPos)
1318 getPartialSpecializations().InsertNode(D, InsertPos);
1319 else {
1320 VarTemplatePartialSpecializationDecl *Existing =
1321 getPartialSpecializations().GetOrInsertNode(D);
1322 (void)Existing;
1323 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1324 }
1325
1326 if (ASTMutationListener *L = getASTMutationListener())
1327 L->AddedCXXTemplateSpecialization(this, D);
1328 }
1329
getPartialSpecializations(SmallVectorImpl<VarTemplatePartialSpecializationDecl * > & PS) const1330 void VarTemplateDecl::getPartialSpecializations(
1331 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const {
1332 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1333 getPartialSpecializations();
1334 PS.clear();
1335 PS.reserve(PartialSpecs.size());
1336 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1337 PS.push_back(P.getMostRecentDecl());
1338 }
1339
1340 VarTemplatePartialSpecializationDecl *
findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl * D)1341 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1342 VarTemplatePartialSpecializationDecl *D) {
1343 Decl *DCanon = D->getCanonicalDecl();
1344 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1345 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1346 return P.getMostRecentDecl();
1347 }
1348
1349 return nullptr;
1350 }
1351
1352 //===----------------------------------------------------------------------===//
1353 // VarTemplateSpecializationDecl Implementation
1354 //===----------------------------------------------------------------------===//
1355
VarTemplateSpecializationDecl(Kind DK,ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args)1356 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1357 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1358 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1359 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1360 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1361 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1362 SpecializedTemplate(SpecializedTemplate),
1363 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1364 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1365
VarTemplateSpecializationDecl(Kind DK,ASTContext & C)1366 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1367 ASTContext &C)
1368 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1369 QualType(), nullptr, SC_None),
1370 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1371
Create(ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args)1372 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1373 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1374 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1375 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1376 return new (Context, DC) VarTemplateSpecializationDecl(
1377 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1378 SpecializedTemplate, T, TInfo, S, Args);
1379 }
1380
1381 VarTemplateSpecializationDecl *
CreateDeserialized(ASTContext & C,GlobalDeclID ID)1382 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
1383 GlobalDeclID ID) {
1384 return new (C, ID)
1385 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1386 }
1387
getNameForDiagnostic(raw_ostream & OS,const PrintingPolicy & Policy,bool Qualified) const1388 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1389 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1390 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1391
1392 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1393 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1394 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1395 printTemplateArgumentList(
1396 OS, ArgsAsWritten->arguments(), Policy,
1397 getSpecializedTemplate()->getTemplateParameters());
1398 } else {
1399 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1400 printTemplateArgumentList(
1401 OS, TemplateArgs.asArray(), Policy,
1402 getSpecializedTemplate()->getTemplateParameters());
1403 }
1404 }
1405
getSpecializedTemplate() const1406 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1407 if (const auto *PartialSpec =
1408 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1409 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1410 return SpecializedTemplate.get<VarTemplateDecl *>();
1411 }
1412
getSourceRange() const1413 SourceRange VarTemplateSpecializationDecl::getSourceRange() const {
1414 switch (getSpecializationKind()) {
1415 case TSK_Undeclared:
1416 case TSK_ImplicitInstantiation: {
1417 llvm::PointerUnion<VarTemplateDecl *,
1418 VarTemplatePartialSpecializationDecl *>
1419 Pattern = getSpecializedTemplateOrPartial();
1420 assert(!Pattern.isNull() &&
1421 "Variable template specialization without pattern?");
1422 if (const auto *VTPSD =
1423 Pattern.dyn_cast<VarTemplatePartialSpecializationDecl *>())
1424 return VTPSD->getSourceRange();
1425 VarTemplateDecl *VTD = Pattern.get<VarTemplateDecl *>();
1426 if (hasInit()) {
1427 if (VarTemplateDecl *Definition = VTD->getDefinition())
1428 return Definition->getSourceRange();
1429 }
1430 return VTD->getCanonicalDecl()->getSourceRange();
1431 }
1432 case TSK_ExplicitSpecialization: {
1433 SourceRange Range = VarDecl::getSourceRange();
1434 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten();
1435 !hasInit() && Args)
1436 Range.setEnd(Args->getRAngleLoc());
1437 return Range;
1438 }
1439 case TSK_ExplicitInstantiationDeclaration:
1440 case TSK_ExplicitInstantiationDefinition: {
1441 SourceRange Range = VarDecl::getSourceRange();
1442 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
1443 Range.setBegin(ExternKW);
1444 else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
1445 TemplateKW.isValid())
1446 Range.setBegin(TemplateKW);
1447 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten())
1448 Range.setEnd(Args->getRAngleLoc());
1449 return Range;
1450 }
1451 }
1452 llvm_unreachable("unhandled template specialization kind");
1453 }
1454
setExternKeywordLoc(SourceLocation Loc)1455 void VarTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) {
1456 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1457 if (!Info) {
1458 // Don't allocate if the location is invalid.
1459 if (Loc.isInvalid())
1460 return;
1461 Info = new (getASTContext()) ExplicitInstantiationInfo;
1462 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
1463 ExplicitInfo = Info;
1464 }
1465 Info->ExternKeywordLoc = Loc;
1466 }
1467
setTemplateKeywordLoc(SourceLocation Loc)1468 void VarTemplateSpecializationDecl::setTemplateKeywordLoc(SourceLocation Loc) {
1469 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
1470 if (!Info) {
1471 // Don't allocate if the location is invalid.
1472 if (Loc.isInvalid())
1473 return;
1474 Info = new (getASTContext()) ExplicitInstantiationInfo;
1475 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
1476 ExplicitInfo = Info;
1477 }
1478 Info->TemplateKeywordLoc = Loc;
1479 }
1480
1481 //===----------------------------------------------------------------------===//
1482 // VarTemplatePartialSpecializationDecl Implementation
1483 //===----------------------------------------------------------------------===//
1484
anchor()1485 void VarTemplatePartialSpecializationDecl::anchor() {}
1486
VarTemplatePartialSpecializationDecl(ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args)1487 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1488 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1489 SourceLocation IdLoc, TemplateParameterList *Params,
1490 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1491 StorageClass S, ArrayRef<TemplateArgument> Args)
1492 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1493 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1494 TInfo, S, Args),
1495 TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
1496 if (AdoptTemplateParameterList(Params, DC))
1497 setInvalidDecl();
1498 }
1499
1500 VarTemplatePartialSpecializationDecl *
Create(ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args)1501 VarTemplatePartialSpecializationDecl::Create(
1502 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1503 SourceLocation IdLoc, TemplateParameterList *Params,
1504 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1505 StorageClass S, ArrayRef<TemplateArgument> Args) {
1506 auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(
1507 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,
1508 Args);
1509 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1510 return Result;
1511 }
1512
1513 VarTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext & C,GlobalDeclID ID)1514 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1515 GlobalDeclID ID) {
1516 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1517 }
1518
getSourceRange() const1519 SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {
1520 if (const VarTemplatePartialSpecializationDecl *MT =
1521 getInstantiatedFromMember();
1522 MT && !isMemberSpecialization())
1523 return MT->getSourceRange();
1524 SourceRange Range = VarTemplateSpecializationDecl::getSourceRange();
1525 if (const TemplateParameterList *TPL = getTemplateParameters();
1526 TPL && !getNumTemplateParameterLists())
1527 Range.setBegin(TPL->getTemplateLoc());
1528 return Range;
1529 }
1530
1531 static TemplateParameterList *
createMakeIntegerSeqParameterList(const ASTContext & C,DeclContext * DC)1532 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1533 // typename T
1534 auto *T = TemplateTypeParmDecl::Create(
1535 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1536 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1537 /*HasTypeConstraint=*/false);
1538 T->setImplicit(true);
1539
1540 // T ...Ints
1541 TypeSourceInfo *TI =
1542 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1543 auto *N = NonTypeTemplateParmDecl::Create(
1544 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1545 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1546 N->setImplicit(true);
1547
1548 // <typename T, T ...Ints>
1549 NamedDecl *P[2] = {T, N};
1550 auto *TPL = TemplateParameterList::Create(
1551 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1552
1553 // template <typename T, ...Ints> class IntSeq
1554 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1555 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1556 /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, TPL);
1557 TemplateTemplateParm->setImplicit(true);
1558
1559 // typename T
1560 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1561 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1562 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false,
1563 /*HasTypeConstraint=*/false);
1564 TemplateTypeParm->setImplicit(true);
1565
1566 // T N
1567 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1568 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1569 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1570 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1571 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1572 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1573 NonTypeTemplateParm};
1574
1575 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1576 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1577 Params, SourceLocation(), nullptr);
1578 }
1579
1580 static TemplateParameterList *
createTypePackElementParameterList(const ASTContext & C,DeclContext * DC)1581 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1582 // std::size_t Index
1583 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1584 auto *Index = NonTypeTemplateParmDecl::Create(
1585 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1586 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1587
1588 // typename ...T
1589 auto *Ts = TemplateTypeParmDecl::Create(
1590 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1591 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true,
1592 /*HasTypeConstraint=*/false);
1593 Ts->setImplicit(true);
1594
1595 // template <std::size_t Index, typename ...T>
1596 NamedDecl *Params[] = {Index, Ts};
1597 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1598 llvm::ArrayRef(Params), SourceLocation(),
1599 nullptr);
1600 }
1601
createBuiltinTemplateParameterList(const ASTContext & C,DeclContext * DC,BuiltinTemplateKind BTK)1602 static TemplateParameterList *createBuiltinTemplateParameterList(
1603 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1604 switch (BTK) {
1605 case BTK__make_integer_seq:
1606 return createMakeIntegerSeqParameterList(C, DC);
1607 case BTK__type_pack_element:
1608 return createTypePackElementParameterList(C, DC);
1609 }
1610
1611 llvm_unreachable("unhandled BuiltinTemplateKind!");
1612 }
1613
anchor()1614 void BuiltinTemplateDecl::anchor() {}
1615
BuiltinTemplateDecl(const ASTContext & C,DeclContext * DC,DeclarationName Name,BuiltinTemplateKind BTK)1616 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1617 DeclarationName Name,
1618 BuiltinTemplateKind BTK)
1619 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1620 createBuiltinTemplateParameterList(C, DC, BTK)),
1621 BTK(BTK) {}
1622
Create(const ASTContext & C,QualType T,const APValue & V)1623 TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C,
1624 QualType T,
1625 const APValue &V) {
1626 DeclContext *DC = C.getTranslationUnitDecl();
1627 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V);
1628 C.addDestruction(&TPOD->Value);
1629 return TPOD;
1630 }
1631
1632 TemplateParamObjectDecl *
CreateDeserialized(ASTContext & C,GlobalDeclID ID)1633 TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
1634 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue());
1635 C.addDestruction(&TPOD->Value);
1636 return TPOD;
1637 }
1638
printName(llvm::raw_ostream & OS,const PrintingPolicy & Policy) const1639 void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
1640 const PrintingPolicy &Policy) const {
1641 OS << "<template param ";
1642 printAsExpr(OS, Policy);
1643 OS << ">";
1644 }
1645
printAsExpr(llvm::raw_ostream & OS) const1646 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const {
1647 printAsExpr(OS, getASTContext().getPrintingPolicy());
1648 }
1649
printAsExpr(llvm::raw_ostream & OS,const PrintingPolicy & Policy) const1650 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS,
1651 const PrintingPolicy &Policy) const {
1652 getType().getUnqualifiedType().print(OS, Policy);
1653 printAsInit(OS, Policy);
1654 }
1655
printAsInit(llvm::raw_ostream & OS) const1656 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const {
1657 printAsInit(OS, getASTContext().getPrintingPolicy());
1658 }
1659
printAsInit(llvm::raw_ostream & OS,const PrintingPolicy & Policy) const1660 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
1661 const PrintingPolicy &Policy) const {
1662 getValue().printPretty(OS, Policy, getType(), &getASTContext());
1663 }
1664
getReplacedTemplateParameterList(Decl * D)1665 TemplateParameterList *clang::getReplacedTemplateParameterList(Decl *D) {
1666 switch (D->getKind()) {
1667 case Decl::Kind::CXXRecord:
1668 return cast<CXXRecordDecl>(D)
1669 ->getDescribedTemplate()
1670 ->getTemplateParameters();
1671 case Decl::Kind::ClassTemplate:
1672 return cast<ClassTemplateDecl>(D)->getTemplateParameters();
1673 case Decl::Kind::ClassTemplateSpecialization: {
1674 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
1675 auto P = CTSD->getSpecializedTemplateOrPartial();
1676 if (const auto *CTPSD =
1677 P.dyn_cast<ClassTemplatePartialSpecializationDecl *>())
1678 return CTPSD->getTemplateParameters();
1679 return cast<ClassTemplateDecl *>(P)->getTemplateParameters();
1680 }
1681 case Decl::Kind::ClassTemplatePartialSpecialization:
1682 return cast<ClassTemplatePartialSpecializationDecl>(D)
1683 ->getTemplateParameters();
1684 case Decl::Kind::TypeAliasTemplate:
1685 return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
1686 case Decl::Kind::BuiltinTemplate:
1687 return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
1688 case Decl::Kind::CXXDeductionGuide:
1689 case Decl::Kind::CXXConversion:
1690 case Decl::Kind::CXXConstructor:
1691 case Decl::Kind::CXXDestructor:
1692 case Decl::Kind::CXXMethod:
1693 case Decl::Kind::Function:
1694 return cast<FunctionDecl>(D)
1695 ->getTemplateSpecializationInfo()
1696 ->getTemplate()
1697 ->getTemplateParameters();
1698 case Decl::Kind::FunctionTemplate:
1699 return cast<FunctionTemplateDecl>(D)->getTemplateParameters();
1700 case Decl::Kind::VarTemplate:
1701 return cast<VarTemplateDecl>(D)->getTemplateParameters();
1702 case Decl::Kind::VarTemplateSpecialization: {
1703 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
1704 auto P = VTSD->getSpecializedTemplateOrPartial();
1705 if (const auto *VTPSD =
1706 P.dyn_cast<VarTemplatePartialSpecializationDecl *>())
1707 return VTPSD->getTemplateParameters();
1708 return cast<VarTemplateDecl *>(P)->getTemplateParameters();
1709 }
1710 case Decl::Kind::VarTemplatePartialSpecialization:
1711 return cast<VarTemplatePartialSpecializationDecl>(D)
1712 ->getTemplateParameters();
1713 case Decl::Kind::TemplateTemplateParm:
1714 return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();
1715 case Decl::Kind::Concept:
1716 return cast<ConceptDecl>(D)->getTemplateParameters();
1717 default:
1718 llvm_unreachable("Unhandled templated declaration kind");
1719 }
1720 }
1721