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