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