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