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