1 //===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the C++ related Decl classes for templates.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "clang/AST/DeclTemplate.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/ASTMutationListener.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclarationName.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/AST/ExternalASTSource.h"
21 #include "clang/AST/TemplateBase.h"
22 #include "clang/AST/TemplateName.h"
23 #include "clang/AST/Type.h"
24 #include "clang/AST/TypeLoc.h"
25 #include "clang/Basic/Builtins.h"
26 #include "clang/Basic/LLVM.h"
27 #include "clang/Basic/SourceLocation.h"
28 #include "llvm/ADT/ArrayRef.h"
29 #include "llvm/ADT/FoldingSet.h"
30 #include "llvm/ADT/None.h"
31 #include "llvm/ADT/PointerUnion.h"
32 #include "llvm/ADT/SmallVector.h"
33 #include "llvm/Support/Casting.h"
34 #include "llvm/Support/ErrorHandling.h"
35 #include <algorithm>
36 #include <cassert>
37 #include <cstdint>
38 #include <memory>
39 #include <utility>
40
41 using namespace clang;
42
43 //===----------------------------------------------------------------------===//
44 // TemplateParameterList Implementation
45 //===----------------------------------------------------------------------===//
46
TemplateParameterList(SourceLocation TemplateLoc,SourceLocation LAngleLoc,ArrayRef<NamedDecl * > Params,SourceLocation RAngleLoc,Expr * RequiresClause)47 TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
48 SourceLocation LAngleLoc,
49 ArrayRef<NamedDecl *> Params,
50 SourceLocation RAngleLoc,
51 Expr *RequiresClause)
52 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
53 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
54 HasRequiresClause(static_cast<bool>(RequiresClause)) {
55 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
56 NamedDecl *P = Params[Idx];
57 begin()[Idx] = P;
58
59 if (!P->isTemplateParameterPack()) {
60 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
61 if (NTTP->getType()->containsUnexpandedParameterPack())
62 ContainsUnexpandedParameterPack = true;
63
64 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
65 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
66 ContainsUnexpandedParameterPack = true;
67
68 // FIXME: If a default argument contains an unexpanded parameter pack, the
69 // template parameter list does too.
70 }
71 }
72 if (RequiresClause) {
73 *getTrailingObjects<Expr *>() = RequiresClause;
74 }
75 }
76
77 TemplateParameterList *
Create(const ASTContext & C,SourceLocation TemplateLoc,SourceLocation LAngleLoc,ArrayRef<NamedDecl * > Params,SourceLocation RAngleLoc,Expr * RequiresClause)78 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
79 SourceLocation LAngleLoc,
80 ArrayRef<NamedDecl *> Params,
81 SourceLocation RAngleLoc, Expr *RequiresClause) {
82 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
83 Params.size(), RequiresClause ? 1u : 0u),
84 alignof(TemplateParameterList));
85 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
86 RAngleLoc, RequiresClause);
87 }
88
getMinRequiredArguments() const89 unsigned TemplateParameterList::getMinRequiredArguments() const {
90 unsigned NumRequiredArgs = 0;
91 for (const NamedDecl *P : asArray()) {
92 if (P->isTemplateParameterPack()) {
93 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
94 if (NTTP->isExpandedParameterPack()) {
95 NumRequiredArgs += NTTP->getNumExpansionTypes();
96 continue;
97 }
98
99 break;
100 }
101
102 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
103 if (TTP->hasDefaultArgument())
104 break;
105 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
106 if (NTTP->hasDefaultArgument())
107 break;
108 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
109 break;
110
111 ++NumRequiredArgs;
112 }
113
114 return NumRequiredArgs;
115 }
116
getDepth() const117 unsigned TemplateParameterList::getDepth() const {
118 if (size() == 0)
119 return 0;
120
121 const NamedDecl *FirstParm = getParam(0);
122 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
123 return TTP->getDepth();
124 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
125 return NTTP->getDepth();
126 else
127 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
128 }
129
AdoptTemplateParameterList(TemplateParameterList * Params,DeclContext * Owner)130 static void AdoptTemplateParameterList(TemplateParameterList *Params,
131 DeclContext *Owner) {
132 for (NamedDecl *P : *Params) {
133 P->setDeclContext(Owner);
134
135 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
136 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
137 }
138 }
139
140 namespace clang {
141
allocateDefaultArgStorageChain(const ASTContext & C)142 void *allocateDefaultArgStorageChain(const ASTContext &C) {
143 return new (C) char[sizeof(void*) * 2];
144 }
145
146 } // namespace clang
147
148 //===----------------------------------------------------------------------===//
149 // RedeclarableTemplateDecl Implementation
150 //===----------------------------------------------------------------------===//
151
anchor()152 void RedeclarableTemplateDecl::anchor() {}
153
getCommonPtr() const154 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
155 if (Common)
156 return Common;
157
158 // Walk the previous-declaration chain until we either find a declaration
159 // with a common pointer or we run out of previous declarations.
160 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
161 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
162 Prev = Prev->getPreviousDecl()) {
163 if (Prev->Common) {
164 Common = Prev->Common;
165 break;
166 }
167
168 PrevDecls.push_back(Prev);
169 }
170
171 // If we never found a common pointer, allocate one now.
172 if (!Common) {
173 // FIXME: If any of the declarations is from an AST file, we probably
174 // need an update record to add the common data.
175
176 Common = newCommon(getASTContext());
177 }
178
179 // Update any previous declarations we saw with the common pointer.
180 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
181 Prev->Common = Common;
182
183 return Common;
184 }
185
loadLazySpecializationsImpl() const186 void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
187 // Grab the most recent declaration to ensure we've loaded any lazy
188 // redeclarations of this template.
189 CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
190 if (CommonBasePtr->LazySpecializations) {
191 ASTContext &Context = getASTContext();
192 uint32_t *Specs = CommonBasePtr->LazySpecializations;
193 CommonBasePtr->LazySpecializations = nullptr;
194 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
195 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
196 }
197 }
198
199 template<class EntryType>
200 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
findSpecializationImpl(llvm::FoldingSetVector<EntryType> & Specs,ArrayRef<TemplateArgument> Args,void * & InsertPos)201 RedeclarableTemplateDecl::findSpecializationImpl(
202 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
203 void *&InsertPos) {
204 using SETraits = SpecEntryTraits<EntryType>;
205
206 llvm::FoldingSetNodeID ID;
207 EntryType::Profile(ID, Args, getASTContext());
208 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
209 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
210 }
211
212 template<class Derived, class EntryType>
addSpecializationImpl(llvm::FoldingSetVector<EntryType> & Specializations,EntryType * Entry,void * InsertPos)213 void RedeclarableTemplateDecl::addSpecializationImpl(
214 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
215 void *InsertPos) {
216 using SETraits = SpecEntryTraits<EntryType>;
217
218 if (InsertPos) {
219 #ifndef NDEBUG
220 void *CorrectInsertPos;
221 assert(!findSpecializationImpl(Specializations,
222 SETraits::getTemplateArgs(Entry),
223 CorrectInsertPos) &&
224 InsertPos == CorrectInsertPos &&
225 "given incorrect InsertPos for specialization");
226 #endif
227 Specializations.InsertNode(Entry, InsertPos);
228 } else {
229 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
230 (void)Existing;
231 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
232 "non-canonical specialization?");
233 }
234
235 if (ASTMutationListener *L = getASTMutationListener())
236 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
237 SETraits::getDecl(Entry));
238 }
239
240 //===----------------------------------------------------------------------===//
241 // FunctionTemplateDecl Implementation
242 //===----------------------------------------------------------------------===//
243
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)244 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
245 DeclContext *DC,
246 SourceLocation L,
247 DeclarationName Name,
248 TemplateParameterList *Params,
249 NamedDecl *Decl) {
250 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
251 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
252 }
253
CreateDeserialized(ASTContext & C,unsigned ID)254 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
255 unsigned ID) {
256 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
257 DeclarationName(), nullptr, nullptr);
258 }
259
260 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const261 FunctionTemplateDecl::newCommon(ASTContext &C) const {
262 auto *CommonPtr = new (C) Common;
263 C.addDestruction(CommonPtr);
264 return CommonPtr;
265 }
266
LoadLazySpecializations() const267 void FunctionTemplateDecl::LoadLazySpecializations() const {
268 loadLazySpecializationsImpl();
269 }
270
271 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
getSpecializations() const272 FunctionTemplateDecl::getSpecializations() const {
273 LoadLazySpecializations();
274 return getCommonPtr()->Specializations;
275 }
276
277 FunctionDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)278 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
279 void *&InsertPos) {
280 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
281 }
282
addSpecialization(FunctionTemplateSpecializationInfo * Info,void * InsertPos)283 void FunctionTemplateDecl::addSpecialization(
284 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
285 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
286 InsertPos);
287 }
288
getInjectedTemplateArgs()289 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
290 TemplateParameterList *Params = getTemplateParameters();
291 Common *CommonPtr = getCommonPtr();
292 if (!CommonPtr->InjectedArgs) {
293 auto &Context = getASTContext();
294 SmallVector<TemplateArgument, 16> TemplateArgs;
295 Context.getInjectedTemplateArgs(Params, TemplateArgs);
296 CommonPtr->InjectedArgs =
297 new (Context) TemplateArgument[TemplateArgs.size()];
298 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
299 CommonPtr->InjectedArgs);
300 }
301
302 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
303 }
304
mergePrevDecl(FunctionTemplateDecl * Prev)305 void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
306 using Base = RedeclarableTemplateDecl;
307
308 // If we haven't created a common pointer yet, then it can just be created
309 // with the usual method.
310 if (!Base::Common)
311 return;
312
313 Common *ThisCommon = static_cast<Common *>(Base::Common);
314 Common *PrevCommon = nullptr;
315 SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
316 for (; Prev; Prev = Prev->getPreviousDecl()) {
317 if (Prev->Base::Common) {
318 PrevCommon = static_cast<Common *>(Prev->Base::Common);
319 break;
320 }
321 PreviousDecls.push_back(Prev);
322 }
323
324 // If the previous redecl chain hasn't created a common pointer yet, then just
325 // use this common pointer.
326 if (!PrevCommon) {
327 for (auto *D : PreviousDecls)
328 D->Base::Common = ThisCommon;
329 return;
330 }
331
332 // Ensure we don't leak any important state.
333 assert(ThisCommon->Specializations.size() == 0 &&
334 "Can't merge incompatible declarations!");
335
336 Base::Common = PrevCommon;
337 }
338
339 //===----------------------------------------------------------------------===//
340 // ClassTemplateDecl Implementation
341 //===----------------------------------------------------------------------===//
342
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl,Expr * AssociatedConstraints)343 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
344 DeclContext *DC,
345 SourceLocation L,
346 DeclarationName Name,
347 TemplateParameterList *Params,
348 NamedDecl *Decl,
349 Expr *AssociatedConstraints) {
350 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
351
352 if (!AssociatedConstraints) {
353 return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
354 }
355
356 auto *const CTDI = new (C) ConstrainedTemplateDeclInfo;
357 auto *const New =
358 new (C, DC) ClassTemplateDecl(CTDI, C, DC, L, Name, Params, Decl);
359 New->setAssociatedConstraints(AssociatedConstraints);
360 return New;
361 }
362
CreateDeserialized(ASTContext & C,unsigned ID)363 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
364 unsigned ID) {
365 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
366 DeclarationName(), nullptr, nullptr);
367 }
368
LoadLazySpecializations() const369 void ClassTemplateDecl::LoadLazySpecializations() const {
370 loadLazySpecializationsImpl();
371 }
372
373 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
getSpecializations() const374 ClassTemplateDecl::getSpecializations() const {
375 LoadLazySpecializations();
376 return getCommonPtr()->Specializations;
377 }
378
379 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations()380 ClassTemplateDecl::getPartialSpecializations() {
381 LoadLazySpecializations();
382 return getCommonPtr()->PartialSpecializations;
383 }
384
385 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const386 ClassTemplateDecl::newCommon(ASTContext &C) const {
387 auto *CommonPtr = new (C) Common;
388 C.addDestruction(CommonPtr);
389 return CommonPtr;
390 }
391
392 ClassTemplateSpecializationDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)393 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
394 void *&InsertPos) {
395 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
396 }
397
AddSpecialization(ClassTemplateSpecializationDecl * D,void * InsertPos)398 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
399 void *InsertPos) {
400 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
401 }
402
403 ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)404 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
405 void *&InsertPos) {
406 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
407 }
408
AddPartialSpecialization(ClassTemplatePartialSpecializationDecl * D,void * InsertPos)409 void ClassTemplateDecl::AddPartialSpecialization(
410 ClassTemplatePartialSpecializationDecl *D,
411 void *InsertPos) {
412 if (InsertPos)
413 getPartialSpecializations().InsertNode(D, InsertPos);
414 else {
415 ClassTemplatePartialSpecializationDecl *Existing
416 = getPartialSpecializations().GetOrInsertNode(D);
417 (void)Existing;
418 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
419 }
420
421 if (ASTMutationListener *L = getASTMutationListener())
422 L->AddedCXXTemplateSpecialization(this, D);
423 }
424
getPartialSpecializations(SmallVectorImpl<ClassTemplatePartialSpecializationDecl * > & PS)425 void ClassTemplateDecl::getPartialSpecializations(
426 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
427 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
428 = getPartialSpecializations();
429 PS.clear();
430 PS.reserve(PartialSpecs.size());
431 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
432 PS.push_back(P.getMostRecentDecl());
433 }
434
435 ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(QualType T)436 ClassTemplateDecl::findPartialSpecialization(QualType T) {
437 ASTContext &Context = getASTContext();
438 for (ClassTemplatePartialSpecializationDecl &P :
439 getPartialSpecializations()) {
440 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
441 return P.getMostRecentDecl();
442 }
443
444 return nullptr;
445 }
446
447 ClassTemplatePartialSpecializationDecl *
findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl * D)448 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
449 ClassTemplatePartialSpecializationDecl *D) {
450 Decl *DCanon = D->getCanonicalDecl();
451 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
452 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
453 return P.getMostRecentDecl();
454 }
455
456 return nullptr;
457 }
458
459 QualType
getInjectedClassNameSpecialization()460 ClassTemplateDecl::getInjectedClassNameSpecialization() {
461 Common *CommonPtr = getCommonPtr();
462 if (!CommonPtr->InjectedClassNameType.isNull())
463 return CommonPtr->InjectedClassNameType;
464
465 // C++0x [temp.dep.type]p2:
466 // The template argument list of a primary template is a template argument
467 // list in which the nth template argument has the value of the nth template
468 // parameter of the class template. If the nth template parameter is a
469 // template parameter pack (14.5.3), the nth template argument is a pack
470 // expansion (14.5.3) whose pattern is the name of the template parameter
471 // pack.
472 ASTContext &Context = getASTContext();
473 TemplateParameterList *Params = getTemplateParameters();
474 SmallVector<TemplateArgument, 16> TemplateArgs;
475 Context.getInjectedTemplateArgs(Params, TemplateArgs);
476 CommonPtr->InjectedClassNameType
477 = Context.getTemplateSpecializationType(TemplateName(this),
478 TemplateArgs);
479 return CommonPtr->InjectedClassNameType;
480 }
481
482 //===----------------------------------------------------------------------===//
483 // TemplateTypeParm Allocation/Deallocation Method Implementations
484 //===----------------------------------------------------------------------===//
485
486 TemplateTypeParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation KeyLoc,SourceLocation NameLoc,unsigned D,unsigned P,IdentifierInfo * Id,bool Typename,bool ParameterPack)487 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
488 SourceLocation KeyLoc, SourceLocation NameLoc,
489 unsigned D, unsigned P, IdentifierInfo *Id,
490 bool Typename, bool ParameterPack) {
491 auto *TTPDecl =
492 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
493 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
494 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
495 return TTPDecl;
496 }
497
498 TemplateTypeParmDecl *
CreateDeserialized(const ASTContext & C,unsigned ID)499 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
500 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
501 SourceLocation(), nullptr, false);
502 }
503
getDefaultArgumentLoc() const504 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
505 return hasDefaultArgument()
506 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
507 : SourceLocation();
508 }
509
getSourceRange() const510 SourceRange TemplateTypeParmDecl::getSourceRange() const {
511 if (hasDefaultArgument() && !defaultArgumentWasInherited())
512 return SourceRange(getBeginLoc(),
513 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
514 else
515 return TypeDecl::getSourceRange();
516 }
517
getDepth() const518 unsigned TemplateTypeParmDecl::getDepth() const {
519 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
520 }
521
getIndex() const522 unsigned TemplateTypeParmDecl::getIndex() const {
523 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
524 }
525
isParameterPack() const526 bool TemplateTypeParmDecl::isParameterPack() const {
527 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
528 }
529
530 //===----------------------------------------------------------------------===//
531 // NonTypeTemplateParmDecl Method Implementations
532 //===----------------------------------------------------------------------===//
533
NonTypeTemplateParmDecl(DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,ArrayRef<QualType> ExpandedTypes,ArrayRef<TypeSourceInfo * > ExpandedTInfos)534 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
535 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
536 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
537 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
538 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
539 TemplateParmPosition(D, P), ParameterPack(true),
540 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
541 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
542 auto TypesAndInfos =
543 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
544 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
545 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
546 TypesAndInfos[I].second = ExpandedTInfos[I];
547 }
548 }
549 }
550
551 NonTypeTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,bool ParameterPack,TypeSourceInfo * TInfo)552 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
553 SourceLocation StartLoc, SourceLocation IdLoc,
554 unsigned D, unsigned P, IdentifierInfo *Id,
555 QualType T, bool ParameterPack,
556 TypeSourceInfo *TInfo) {
557 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
558 T, ParameterPack, TInfo);
559 }
560
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)561 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
562 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
563 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
564 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
565 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
566 return new (C, DC,
567 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
568 ExpandedTypes.size()))
569 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
570 ExpandedTypes, ExpandedTInfos);
571 }
572
573 NonTypeTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID)574 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
575 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
576 SourceLocation(), 0, 0, nullptr,
577 QualType(), false, nullptr);
578 }
579
580 NonTypeTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID,unsigned NumExpandedTypes)581 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
582 unsigned NumExpandedTypes) {
583 auto *NTTP =
584 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
585 NumExpandedTypes))
586 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
587 0, 0, nullptr, QualType(), nullptr, None,
588 None);
589 NTTP->NumExpandedTypes = NumExpandedTypes;
590 return NTTP;
591 }
592
getSourceRange() const593 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
594 if (hasDefaultArgument() && !defaultArgumentWasInherited())
595 return SourceRange(getOuterLocStart(),
596 getDefaultArgument()->getSourceRange().getEnd());
597 return DeclaratorDecl::getSourceRange();
598 }
599
getDefaultArgumentLoc() const600 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
601 return hasDefaultArgument()
602 ? getDefaultArgument()->getSourceRange().getBegin()
603 : SourceLocation();
604 }
605
606 //===----------------------------------------------------------------------===//
607 // TemplateTemplateParmDecl Method Implementations
608 //===----------------------------------------------------------------------===//
609
anchor()610 void TemplateTemplateParmDecl::anchor() {}
611
TemplateTemplateParmDecl(DeclContext * DC,SourceLocation L,unsigned D,unsigned P,IdentifierInfo * Id,TemplateParameterList * Params,ArrayRef<TemplateParameterList * > Expansions)612 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
613 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
614 IdentifierInfo *Id, TemplateParameterList *Params,
615 ArrayRef<TemplateParameterList *> Expansions)
616 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
617 TemplateParmPosition(D, P), ParameterPack(true),
618 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
619 if (!Expansions.empty())
620 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
621 getTrailingObjects<TemplateParameterList *>());
622 }
623
624 TemplateTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation L,unsigned D,unsigned P,bool ParameterPack,IdentifierInfo * Id,TemplateParameterList * Params)625 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
626 SourceLocation L, unsigned D, unsigned P,
627 bool ParameterPack, IdentifierInfo *Id,
628 TemplateParameterList *Params) {
629 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
630 Params);
631 }
632
633 TemplateTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation L,unsigned D,unsigned P,IdentifierInfo * Id,TemplateParameterList * Params,ArrayRef<TemplateParameterList * > Expansions)634 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
635 SourceLocation L, unsigned D, unsigned P,
636 IdentifierInfo *Id,
637 TemplateParameterList *Params,
638 ArrayRef<TemplateParameterList *> Expansions) {
639 return new (C, DC,
640 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
641 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
642 }
643
644 TemplateTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID)645 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
646 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
647 false, nullptr, nullptr);
648 }
649
650 TemplateTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID,unsigned NumExpansions)651 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
652 unsigned NumExpansions) {
653 auto *TTP =
654 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
655 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
656 nullptr, None);
657 TTP->NumExpandedParams = NumExpansions;
658 return TTP;
659 }
660
getDefaultArgumentLoc() const661 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
662 return hasDefaultArgument() ? getDefaultArgument().getLocation()
663 : SourceLocation();
664 }
665
setDefaultArgument(const ASTContext & C,const TemplateArgumentLoc & DefArg)666 void TemplateTemplateParmDecl::setDefaultArgument(
667 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
668 if (DefArg.getArgument().isNull())
669 DefaultArgument.set(nullptr);
670 else
671 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
672 }
673
674 //===----------------------------------------------------------------------===//
675 // TemplateArgumentList Implementation
676 //===----------------------------------------------------------------------===//
TemplateArgumentList(ArrayRef<TemplateArgument> Args)677 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
678 : Arguments(getTrailingObjects<TemplateArgument>()),
679 NumArguments(Args.size()) {
680 std::uninitialized_copy(Args.begin(), Args.end(),
681 getTrailingObjects<TemplateArgument>());
682 }
683
684 TemplateArgumentList *
CreateCopy(ASTContext & Context,ArrayRef<TemplateArgument> Args)685 TemplateArgumentList::CreateCopy(ASTContext &Context,
686 ArrayRef<TemplateArgument> Args) {
687 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
688 return new (Mem) TemplateArgumentList(Args);
689 }
690
691 FunctionTemplateSpecializationInfo *
Create(ASTContext & C,FunctionDecl * FD,FunctionTemplateDecl * Template,TemplateSpecializationKind TSK,const TemplateArgumentList * TemplateArgs,const TemplateArgumentListInfo * TemplateArgsAsWritten,SourceLocation POI)692 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
693 FunctionTemplateDecl *Template,
694 TemplateSpecializationKind TSK,
695 const TemplateArgumentList *TemplateArgs,
696 const TemplateArgumentListInfo *TemplateArgsAsWritten,
697 SourceLocation POI) {
698 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
699 if (TemplateArgsAsWritten)
700 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
701 *TemplateArgsAsWritten);
702
703 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
704 TemplateArgs,
705 ArgsAsWritten,
706 POI);
707 }
708
709 //===----------------------------------------------------------------------===//
710 // TemplateDecl Implementation
711 //===----------------------------------------------------------------------===//
712
anchor()713 void TemplateDecl::anchor() {}
714
715 //===----------------------------------------------------------------------===//
716 // ClassTemplateSpecializationDecl Implementation
717 //===----------------------------------------------------------------------===//
718
719 ClassTemplateSpecializationDecl::
ClassTemplateSpecializationDecl(ASTContext & Context,Kind DK,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,ClassTemplateSpecializationDecl * PrevDecl)720 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
721 DeclContext *DC, SourceLocation StartLoc,
722 SourceLocation IdLoc,
723 ClassTemplateDecl *SpecializedTemplate,
724 ArrayRef<TemplateArgument> Args,
725 ClassTemplateSpecializationDecl *PrevDecl)
726 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
727 SpecializedTemplate->getIdentifier(), PrevDecl),
728 SpecializedTemplate(SpecializedTemplate),
729 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
730 SpecializationKind(TSK_Undeclared) {
731 }
732
ClassTemplateSpecializationDecl(ASTContext & C,Kind DK)733 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
734 Kind DK)
735 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
736 SourceLocation(), nullptr, nullptr),
737 SpecializationKind(TSK_Undeclared) {}
738
739 ClassTemplateSpecializationDecl *
Create(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,ClassTemplateSpecializationDecl * PrevDecl)740 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
741 DeclContext *DC,
742 SourceLocation StartLoc,
743 SourceLocation IdLoc,
744 ClassTemplateDecl *SpecializedTemplate,
745 ArrayRef<TemplateArgument> Args,
746 ClassTemplateSpecializationDecl *PrevDecl) {
747 auto *Result =
748 new (Context, DC) ClassTemplateSpecializationDecl(
749 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
750 SpecializedTemplate, Args, PrevDecl);
751 Result->setMayHaveOutOfDateDef(false);
752
753 Context.getTypeDeclType(Result, PrevDecl);
754 return Result;
755 }
756
757 ClassTemplateSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)758 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
759 unsigned ID) {
760 auto *Result =
761 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
762 Result->setMayHaveOutOfDateDef(false);
763 return Result;
764 }
765
getNameForDiagnostic(raw_ostream & OS,const PrintingPolicy & Policy,bool Qualified) const766 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
767 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
768 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
769
770 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
771 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
772 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
773 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
774 } else {
775 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
776 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
777 }
778 }
779
780 ClassTemplateDecl *
getSpecializedTemplate() const781 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
782 if (const auto *PartialSpec =
783 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
784 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
785 return SpecializedTemplate.get<ClassTemplateDecl*>();
786 }
787
788 SourceRange
getSourceRange() const789 ClassTemplateSpecializationDecl::getSourceRange() const {
790 if (ExplicitInfo) {
791 SourceLocation Begin = getTemplateKeywordLoc();
792 if (Begin.isValid()) {
793 // Here we have an explicit (partial) specialization or instantiation.
794 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
795 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
796 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
797 if (getExternLoc().isValid())
798 Begin = getExternLoc();
799 SourceLocation End = getBraceRange().getEnd();
800 if (End.isInvalid())
801 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
802 return SourceRange(Begin, End);
803 }
804 // An implicit instantiation of a class template partial specialization
805 // uses ExplicitInfo to record the TypeAsWritten, but the source
806 // locations should be retrieved from the instantiation pattern.
807 using CTPSDecl = ClassTemplatePartialSpecializationDecl;
808 auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
809 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
810 assert(inst_from != nullptr);
811 return inst_from->getSourceRange();
812 }
813 else {
814 // No explicit info available.
815 llvm::PointerUnion<ClassTemplateDecl *,
816 ClassTemplatePartialSpecializationDecl *>
817 inst_from = getInstantiatedFrom();
818 if (inst_from.isNull())
819 return getSpecializedTemplate()->getSourceRange();
820 if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
821 return ctd->getSourceRange();
822 return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
823 ->getSourceRange();
824 }
825 }
826
827 //===----------------------------------------------------------------------===//
828 // ClassTemplatePartialSpecializationDecl Implementation
829 //===----------------------------------------------------------------------===//
anchor()830 void ClassTemplatePartialSpecializationDecl::anchor() {}
831
832 ClassTemplatePartialSpecializationDecl::
ClassTemplatePartialSpecializationDecl(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,const ASTTemplateArgumentListInfo * ArgInfos,ClassTemplatePartialSpecializationDecl * PrevDecl)833 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
834 DeclContext *DC,
835 SourceLocation StartLoc,
836 SourceLocation IdLoc,
837 TemplateParameterList *Params,
838 ClassTemplateDecl *SpecializedTemplate,
839 ArrayRef<TemplateArgument> Args,
840 const ASTTemplateArgumentListInfo *ArgInfos,
841 ClassTemplatePartialSpecializationDecl *PrevDecl)
842 : ClassTemplateSpecializationDecl(Context,
843 ClassTemplatePartialSpecialization,
844 TK, DC, StartLoc, IdLoc,
845 SpecializedTemplate, Args, PrevDecl),
846 TemplateParams(Params), ArgsAsWritten(ArgInfos),
847 InstantiatedFromMember(nullptr, false) {
848 AdoptTemplateParameterList(Params, this);
849 }
850
851 ClassTemplatePartialSpecializationDecl *
852 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)853 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
854 SourceLocation StartLoc, SourceLocation IdLoc,
855 TemplateParameterList *Params,
856 ClassTemplateDecl *SpecializedTemplate,
857 ArrayRef<TemplateArgument> Args,
858 const TemplateArgumentListInfo &ArgInfos,
859 QualType CanonInjectedType,
860 ClassTemplatePartialSpecializationDecl *PrevDecl) {
861 const ASTTemplateArgumentListInfo *ASTArgInfos =
862 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
863
864 auto *Result = new (Context, DC)
865 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
866 Params, SpecializedTemplate, Args,
867 ASTArgInfos, PrevDecl);
868 Result->setSpecializationKind(TSK_ExplicitSpecialization);
869 Result->setMayHaveOutOfDateDef(false);
870
871 Context.getInjectedClassNameType(Result, CanonInjectedType);
872 return Result;
873 }
874
875 ClassTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)876 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
877 unsigned ID) {
878 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
879 Result->setMayHaveOutOfDateDef(false);
880 return Result;
881 }
882
883 //===----------------------------------------------------------------------===//
884 // FriendTemplateDecl Implementation
885 //===----------------------------------------------------------------------===//
886
anchor()887 void FriendTemplateDecl::anchor() {}
888
889 FriendTemplateDecl *
Create(ASTContext & Context,DeclContext * DC,SourceLocation L,MutableArrayRef<TemplateParameterList * > Params,FriendUnion Friend,SourceLocation FLoc)890 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
891 SourceLocation L,
892 MutableArrayRef<TemplateParameterList *> Params,
893 FriendUnion Friend, SourceLocation FLoc) {
894 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
895 }
896
CreateDeserialized(ASTContext & C,unsigned ID)897 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
898 unsigned ID) {
899 return new (C, ID) FriendTemplateDecl(EmptyShell());
900 }
901
902 //===----------------------------------------------------------------------===//
903 // TypeAliasTemplateDecl Implementation
904 //===----------------------------------------------------------------------===//
905
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)906 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
907 DeclContext *DC,
908 SourceLocation L,
909 DeclarationName Name,
910 TemplateParameterList *Params,
911 NamedDecl *Decl) {
912 AdoptTemplateParameterList(Params, DC);
913 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
914 }
915
CreateDeserialized(ASTContext & C,unsigned ID)916 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
917 unsigned ID) {
918 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
919 DeclarationName(), nullptr, nullptr);
920 }
921
922 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const923 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
924 auto *CommonPtr = new (C) Common;
925 C.addDestruction(CommonPtr);
926 return CommonPtr;
927 }
928
929 //===----------------------------------------------------------------------===//
930 // ClassScopeFunctionSpecializationDecl Implementation
931 //===----------------------------------------------------------------------===//
932
anchor()933 void ClassScopeFunctionSpecializationDecl::anchor() {}
934
935 ClassScopeFunctionSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)936 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
937 unsigned ID) {
938 return new (C, ID) ClassScopeFunctionSpecializationDecl(
939 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
940 }
941
942 //===----------------------------------------------------------------------===//
943 // VarTemplateDecl Implementation
944 //===----------------------------------------------------------------------===//
945
getDefinition()946 VarTemplateDecl *VarTemplateDecl::getDefinition() {
947 VarTemplateDecl *CurD = this;
948 while (CurD) {
949 if (CurD->isThisDeclarationADefinition())
950 return CurD;
951 CurD = CurD->getPreviousDecl();
952 }
953 return nullptr;
954 }
955
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,VarDecl * Decl)956 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
957 SourceLocation L, DeclarationName Name,
958 TemplateParameterList *Params,
959 VarDecl *Decl) {
960 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
961 }
962
CreateDeserialized(ASTContext & C,unsigned ID)963 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
964 unsigned ID) {
965 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
966 DeclarationName(), nullptr, nullptr);
967 }
968
LoadLazySpecializations() const969 void VarTemplateDecl::LoadLazySpecializations() const {
970 loadLazySpecializationsImpl();
971 }
972
973 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
getSpecializations() const974 VarTemplateDecl::getSpecializations() const {
975 LoadLazySpecializations();
976 return getCommonPtr()->Specializations;
977 }
978
979 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
getPartialSpecializations()980 VarTemplateDecl::getPartialSpecializations() {
981 LoadLazySpecializations();
982 return getCommonPtr()->PartialSpecializations;
983 }
984
985 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const986 VarTemplateDecl::newCommon(ASTContext &C) const {
987 auto *CommonPtr = new (C) Common;
988 C.addDestruction(CommonPtr);
989 return CommonPtr;
990 }
991
992 VarTemplateSpecializationDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)993 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
994 void *&InsertPos) {
995 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
996 }
997
AddSpecialization(VarTemplateSpecializationDecl * D,void * InsertPos)998 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
999 void *InsertPos) {
1000 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1001 }
1002
1003 VarTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)1004 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1005 void *&InsertPos) {
1006 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
1007 }
1008
AddPartialSpecialization(VarTemplatePartialSpecializationDecl * D,void * InsertPos)1009 void VarTemplateDecl::AddPartialSpecialization(
1010 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1011 if (InsertPos)
1012 getPartialSpecializations().InsertNode(D, InsertPos);
1013 else {
1014 VarTemplatePartialSpecializationDecl *Existing =
1015 getPartialSpecializations().GetOrInsertNode(D);
1016 (void)Existing;
1017 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1018 }
1019
1020 if (ASTMutationListener *L = getASTMutationListener())
1021 L->AddedCXXTemplateSpecialization(this, D);
1022 }
1023
getPartialSpecializations(SmallVectorImpl<VarTemplatePartialSpecializationDecl * > & PS)1024 void VarTemplateDecl::getPartialSpecializations(
1025 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1026 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1027 getPartialSpecializations();
1028 PS.clear();
1029 PS.reserve(PartialSpecs.size());
1030 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1031 PS.push_back(P.getMostRecentDecl());
1032 }
1033
1034 VarTemplatePartialSpecializationDecl *
findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl * D)1035 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1036 VarTemplatePartialSpecializationDecl *D) {
1037 Decl *DCanon = D->getCanonicalDecl();
1038 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1039 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1040 return P.getMostRecentDecl();
1041 }
1042
1043 return nullptr;
1044 }
1045
1046 //===----------------------------------------------------------------------===//
1047 // VarTemplateSpecializationDecl Implementation
1048 //===----------------------------------------------------------------------===//
1049
VarTemplateSpecializationDecl(Kind DK,ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args)1050 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1051 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1052 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1053 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1054 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1055 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1056 SpecializedTemplate(SpecializedTemplate),
1057 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1058 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1059
VarTemplateSpecializationDecl(Kind DK,ASTContext & C)1060 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1061 ASTContext &C)
1062 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1063 QualType(), nullptr, SC_None),
1064 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1065
Create(ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args)1066 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1067 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1068 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1069 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1070 return new (Context, DC) VarTemplateSpecializationDecl(
1071 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1072 SpecializedTemplate, T, TInfo, S, Args);
1073 }
1074
1075 VarTemplateSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1076 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1077 return new (C, ID)
1078 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1079 }
1080
getNameForDiagnostic(raw_ostream & OS,const PrintingPolicy & Policy,bool Qualified) const1081 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1082 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1083 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1084
1085 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1086 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1087 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1088 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
1089 } else {
1090 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1091 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
1092 }
1093 }
1094
getSpecializedTemplate() const1095 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1096 if (const auto *PartialSpec =
1097 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1098 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1099 return SpecializedTemplate.get<VarTemplateDecl *>();
1100 }
1101
setTemplateArgsInfo(const TemplateArgumentListInfo & ArgsInfo)1102 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1103 const TemplateArgumentListInfo &ArgsInfo) {
1104 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1105 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1106 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1107 TemplateArgsInfo.addArgument(Loc);
1108 }
1109
1110 //===----------------------------------------------------------------------===//
1111 // VarTemplatePartialSpecializationDecl Implementation
1112 //===----------------------------------------------------------------------===//
1113
anchor()1114 void VarTemplatePartialSpecializationDecl::anchor() {}
1115
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)1116 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1117 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1118 SourceLocation IdLoc, TemplateParameterList *Params,
1119 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1120 StorageClass S, ArrayRef<TemplateArgument> Args,
1121 const ASTTemplateArgumentListInfo *ArgInfos)
1122 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1123 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1124 TInfo, S, Args),
1125 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1126 InstantiatedFromMember(nullptr, false) {
1127 // TODO: The template parameters should be in DC by now. Verify.
1128 // AdoptTemplateParameterList(Params, DC);
1129 }
1130
1131 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)1132 VarTemplatePartialSpecializationDecl::Create(
1133 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1134 SourceLocation IdLoc, TemplateParameterList *Params,
1135 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1136 StorageClass S, ArrayRef<TemplateArgument> Args,
1137 const TemplateArgumentListInfo &ArgInfos) {
1138 const ASTTemplateArgumentListInfo *ASTArgInfos
1139 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1140
1141 auto *Result =
1142 new (Context, DC) VarTemplatePartialSpecializationDecl(
1143 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1144 S, Args, ASTArgInfos);
1145 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1146 return Result;
1147 }
1148
1149 VarTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1150 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1151 unsigned ID) {
1152 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1153 }
1154
1155 static TemplateParameterList *
createMakeIntegerSeqParameterList(const ASTContext & C,DeclContext * DC)1156 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1157 // typename T
1158 auto *T = TemplateTypeParmDecl::Create(
1159 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1160 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1161 T->setImplicit(true);
1162
1163 // T ...Ints
1164 TypeSourceInfo *TI =
1165 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1166 auto *N = NonTypeTemplateParmDecl::Create(
1167 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1168 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1169 N->setImplicit(true);
1170
1171 // <typename T, T ...Ints>
1172 NamedDecl *P[2] = {T, N};
1173 auto *TPL = TemplateParameterList::Create(
1174 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1175
1176 // template <typename T, ...Ints> class IntSeq
1177 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1178 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1179 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1180 TemplateTemplateParm->setImplicit(true);
1181
1182 // typename T
1183 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1184 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1185 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1186 TemplateTypeParm->setImplicit(true);
1187
1188 // T N
1189 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1190 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1191 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1192 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1193 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1194 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1195 NonTypeTemplateParm};
1196
1197 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1198 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1199 Params, SourceLocation(), nullptr);
1200 }
1201
1202 static TemplateParameterList *
createTypePackElementParameterList(const ASTContext & C,DeclContext * DC)1203 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1204 // std::size_t Index
1205 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1206 auto *Index = NonTypeTemplateParmDecl::Create(
1207 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1208 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1209
1210 // typename ...T
1211 auto *Ts = TemplateTypeParmDecl::Create(
1212 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1213 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1214 Ts->setImplicit(true);
1215
1216 // template <std::size_t Index, typename ...T>
1217 NamedDecl *Params[] = {Index, Ts};
1218 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1219 llvm::makeArrayRef(Params),
1220 SourceLocation(), nullptr);
1221 }
1222
createBuiltinTemplateParameterList(const ASTContext & C,DeclContext * DC,BuiltinTemplateKind BTK)1223 static TemplateParameterList *createBuiltinTemplateParameterList(
1224 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1225 switch (BTK) {
1226 case BTK__make_integer_seq:
1227 return createMakeIntegerSeqParameterList(C, DC);
1228 case BTK__type_pack_element:
1229 return createTypePackElementParameterList(C, DC);
1230 }
1231
1232 llvm_unreachable("unhandled BuiltinTemplateKind!");
1233 }
1234
anchor()1235 void BuiltinTemplateDecl::anchor() {}
1236
BuiltinTemplateDecl(const ASTContext & C,DeclContext * DC,DeclarationName Name,BuiltinTemplateKind BTK)1237 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1238 DeclarationName Name,
1239 BuiltinTemplateKind BTK)
1240 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1241 createBuiltinTemplateParameterList(C, DC, BTK)),
1242 BTK(BTK) {}
1243