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, ArrayRef<TemplateArgument> Args,
167 void *&InsertPos) {
168 typedef SpecEntryTraits<EntryType> SETraits;
169 llvm::FoldingSetNodeID ID;
170 EntryType::Profile(ID,Args, getASTContext());
171 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
172 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
173 }
174
175 template<class Derived, class EntryType>
addSpecializationImpl(llvm::FoldingSetVector<EntryType> & Specializations,EntryType * Entry,void * InsertPos)176 void RedeclarableTemplateDecl::addSpecializationImpl(
177 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
178 void *InsertPos) {
179 typedef SpecEntryTraits<EntryType> SETraits;
180 if (InsertPos) {
181 #ifndef NDEBUG
182 void *CorrectInsertPos;
183 assert(!findSpecializationImpl(Specializations,
184 SETraits::getTemplateArgs(Entry),
185 CorrectInsertPos) &&
186 InsertPos == CorrectInsertPos &&
187 "given incorrect InsertPos for specialization");
188 #endif
189 Specializations.InsertNode(Entry, InsertPos);
190 } else {
191 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
192 (void)Existing;
193 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
194 "non-canonical specialization?");
195 }
196
197 if (ASTMutationListener *L = getASTMutationListener())
198 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
199 SETraits::getDecl(Entry));
200 }
201
202 /// \brief Generate the injected template arguments for the given template
203 /// parameter list, e.g., for the injected-class-name of a class template.
GenerateInjectedTemplateArgs(ASTContext & Context,TemplateParameterList * Params,TemplateArgument * Args)204 static void GenerateInjectedTemplateArgs(ASTContext &Context,
205 TemplateParameterList *Params,
206 TemplateArgument *Args) {
207 for (TemplateParameterList::iterator Param = Params->begin(),
208 ParamEnd = Params->end();
209 Param != ParamEnd; ++Param) {
210 TemplateArgument Arg;
211 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
212 QualType ArgType = Context.getTypeDeclType(TTP);
213 if (TTP->isParameterPack())
214 ArgType = Context.getPackExpansionType(ArgType, None);
215
216 Arg = TemplateArgument(ArgType);
217 } else if (NonTypeTemplateParmDecl *NTTP =
218 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
219 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
220 NTTP->getType().getNonLValueExprType(Context),
221 Expr::getValueKindForType(NTTP->getType()),
222 NTTP->getLocation());
223
224 if (NTTP->isParameterPack())
225 E = new (Context) PackExpansionExpr(Context.DependentTy, E,
226 NTTP->getLocation(), None);
227 Arg = TemplateArgument(E);
228 } else {
229 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
230 if (TTP->isParameterPack())
231 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
232 else
233 Arg = TemplateArgument(TemplateName(TTP));
234 }
235
236 if ((*Param)->isTemplateParameterPack())
237 Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
238
239 *Args++ = Arg;
240 }
241 }
242
243 //===----------------------------------------------------------------------===//
244 // FunctionTemplateDecl Implementation
245 //===----------------------------------------------------------------------===//
246
DeallocateCommon(void * Ptr)247 void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
248 static_cast<Common *>(Ptr)->~Common();
249 }
250
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)251 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
252 DeclContext *DC,
253 SourceLocation L,
254 DeclarationName Name,
255 TemplateParameterList *Params,
256 NamedDecl *Decl) {
257 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
258 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
259 }
260
CreateDeserialized(ASTContext & C,unsigned ID)261 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
262 unsigned ID) {
263 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
264 DeclarationName(), nullptr, nullptr);
265 }
266
267 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const268 FunctionTemplateDecl::newCommon(ASTContext &C) const {
269 Common *CommonPtr = new (C) Common;
270 C.AddDeallocation(DeallocateCommon, CommonPtr);
271 return CommonPtr;
272 }
273
LoadLazySpecializations() const274 void FunctionTemplateDecl::LoadLazySpecializations() const {
275 // Grab the most recent declaration to ensure we've loaded any lazy
276 // redeclarations of this template.
277 //
278 // FIXME: Avoid walking the entire redeclaration chain here.
279 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
280 if (CommonPtr->LazySpecializations) {
281 ASTContext &Context = getASTContext();
282 uint32_t *Specs = CommonPtr->LazySpecializations;
283 CommonPtr->LazySpecializations = nullptr;
284 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
285 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
286 }
287 }
288
289 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
getSpecializations() const290 FunctionTemplateDecl::getSpecializations() const {
291 LoadLazySpecializations();
292 return getCommonPtr()->Specializations;
293 }
294
295 FunctionDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)296 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
297 void *&InsertPos) {
298 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
299 }
300
addSpecialization(FunctionTemplateSpecializationInfo * Info,void * InsertPos)301 void FunctionTemplateDecl::addSpecialization(
302 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
303 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
304 InsertPos);
305 }
306
getInjectedTemplateArgs()307 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
308 TemplateParameterList *Params = getTemplateParameters();
309 Common *CommonPtr = getCommonPtr();
310 if (!CommonPtr->InjectedArgs) {
311 CommonPtr->InjectedArgs
312 = new (getASTContext()) TemplateArgument[Params->size()];
313 GenerateInjectedTemplateArgs(getASTContext(), Params,
314 CommonPtr->InjectedArgs);
315 }
316
317 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
318 }
319
320 //===----------------------------------------------------------------------===//
321 // ClassTemplateDecl Implementation
322 //===----------------------------------------------------------------------===//
323
DeallocateCommon(void * Ptr)324 void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
325 static_cast<Common *>(Ptr)->~Common();
326 }
327
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl,ClassTemplateDecl * PrevDecl)328 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
329 DeclContext *DC,
330 SourceLocation L,
331 DeclarationName Name,
332 TemplateParameterList *Params,
333 NamedDecl *Decl,
334 ClassTemplateDecl *PrevDecl) {
335 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
336 ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
337 Params, Decl);
338 New->setPreviousDecl(PrevDecl);
339 return New;
340 }
341
CreateDeserialized(ASTContext & C,unsigned ID)342 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
343 unsigned ID) {
344 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
345 DeclarationName(), nullptr, nullptr);
346 }
347
LoadLazySpecializations() const348 void ClassTemplateDecl::LoadLazySpecializations() const {
349 // Grab the most recent declaration to ensure we've loaded any lazy
350 // redeclarations of this template.
351 //
352 // FIXME: Avoid walking the entire redeclaration chain here.
353 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
354 if (CommonPtr->LazySpecializations) {
355 ASTContext &Context = getASTContext();
356 uint32_t *Specs = CommonPtr->LazySpecializations;
357 CommonPtr->LazySpecializations = nullptr;
358 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
359 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
360 }
361 }
362
363 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
getSpecializations() const364 ClassTemplateDecl::getSpecializations() const {
365 LoadLazySpecializations();
366 return getCommonPtr()->Specializations;
367 }
368
369 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations()370 ClassTemplateDecl::getPartialSpecializations() {
371 LoadLazySpecializations();
372 return getCommonPtr()->PartialSpecializations;
373 }
374
375 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const376 ClassTemplateDecl::newCommon(ASTContext &C) const {
377 Common *CommonPtr = new (C) Common;
378 C.AddDeallocation(DeallocateCommon, CommonPtr);
379 return CommonPtr;
380 }
381
382 ClassTemplateSpecializationDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)383 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
384 void *&InsertPos) {
385 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
386 }
387
AddSpecialization(ClassTemplateSpecializationDecl * D,void * InsertPos)388 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
389 void *InsertPos) {
390 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
391 }
392
393 ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)394 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
395 void *&InsertPos) {
396 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
397 }
398
AddPartialSpecialization(ClassTemplatePartialSpecializationDecl * D,void * InsertPos)399 void ClassTemplateDecl::AddPartialSpecialization(
400 ClassTemplatePartialSpecializationDecl *D,
401 void *InsertPos) {
402 if (InsertPos)
403 getPartialSpecializations().InsertNode(D, InsertPos);
404 else {
405 ClassTemplatePartialSpecializationDecl *Existing
406 = getPartialSpecializations().GetOrInsertNode(D);
407 (void)Existing;
408 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
409 }
410
411 if (ASTMutationListener *L = getASTMutationListener())
412 L->AddedCXXTemplateSpecialization(this, D);
413 }
414
getPartialSpecializations(SmallVectorImpl<ClassTemplatePartialSpecializationDecl * > & PS)415 void ClassTemplateDecl::getPartialSpecializations(
416 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
417 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
418 = getPartialSpecializations();
419 PS.clear();
420 PS.reserve(PartialSpecs.size());
421 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
422 P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
423 P != PEnd; ++P)
424 PS.push_back(P->getMostRecentDecl());
425 }
426
427 ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(QualType T)428 ClassTemplateDecl::findPartialSpecialization(QualType T) {
429 ASTContext &Context = getASTContext();
430 using llvm::FoldingSetVector;
431 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
432 partial_spec_iterator;
433 for (partial_spec_iterator P = getPartialSpecializations().begin(),
434 PEnd = getPartialSpecializations().end();
435 P != PEnd; ++P) {
436 if (Context.hasSameType(P->getInjectedSpecializationType(), T))
437 return P->getMostRecentDecl();
438 }
439
440 return nullptr;
441 }
442
443 ClassTemplatePartialSpecializationDecl *
findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl * D)444 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
445 ClassTemplatePartialSpecializationDecl *D) {
446 Decl *DCanon = D->getCanonicalDecl();
447 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
448 P = getPartialSpecializations().begin(),
449 PEnd = getPartialSpecializations().end();
450 P != PEnd; ++P) {
451 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
452 return P->getMostRecentDecl();
453 }
454
455 return nullptr;
456 }
457
458 QualType
getInjectedClassNameSpecialization()459 ClassTemplateDecl::getInjectedClassNameSpecialization() {
460 Common *CommonPtr = getCommonPtr();
461 if (!CommonPtr->InjectedClassNameType.isNull())
462 return CommonPtr->InjectedClassNameType;
463
464 // C++0x [temp.dep.type]p2:
465 // The template argument list of a primary template is a template argument
466 // list in which the nth template argument has the value of the nth template
467 // parameter of the class template. If the nth template parameter is a
468 // template parameter pack (14.5.3), the nth template argument is a pack
469 // expansion (14.5.3) whose pattern is the name of the template parameter
470 // pack.
471 ASTContext &Context = getASTContext();
472 TemplateParameterList *Params = getTemplateParameters();
473 SmallVector<TemplateArgument, 16> TemplateArgs;
474 TemplateArgs.resize(Params->size());
475 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
476 CommonPtr->InjectedClassNameType
477 = Context.getTemplateSpecializationType(TemplateName(this),
478 &TemplateArgs[0],
479 TemplateArgs.size());
480 return CommonPtr->InjectedClassNameType;
481 }
482
483 //===----------------------------------------------------------------------===//
484 // TemplateTypeParm Allocation/Deallocation Method Implementations
485 //===----------------------------------------------------------------------===//
486
487 TemplateTypeParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation KeyLoc,SourceLocation NameLoc,unsigned D,unsigned P,IdentifierInfo * Id,bool Typename,bool ParameterPack)488 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
489 SourceLocation KeyLoc, SourceLocation NameLoc,
490 unsigned D, unsigned P, IdentifierInfo *Id,
491 bool Typename, bool ParameterPack) {
492 TemplateTypeParmDecl *TTPDecl =
493 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
494 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
495 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
496 return TTPDecl;
497 }
498
499 TemplateTypeParmDecl *
CreateDeserialized(const ASTContext & C,unsigned ID)500 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
501 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
502 SourceLocation(), nullptr, false);
503 }
504
getDefaultArgumentLoc() const505 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
506 return hasDefaultArgument()
507 ? DefaultArgument->getTypeLoc().getBeginLoc()
508 : SourceLocation();
509 }
510
getSourceRange() const511 SourceRange TemplateTypeParmDecl::getSourceRange() const {
512 if (hasDefaultArgument() && !defaultArgumentWasInherited())
513 return SourceRange(getLocStart(),
514 DefaultArgument->getTypeLoc().getEndLoc());
515 else
516 return TypeDecl::getSourceRange();
517 }
518
getDepth() const519 unsigned TemplateTypeParmDecl::getDepth() const {
520 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
521 }
522
getIndex() const523 unsigned TemplateTypeParmDecl::getIndex() const {
524 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
525 }
526
isParameterPack() const527 bool TemplateTypeParmDecl::isParameterPack() const {
528 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
529 }
530
531 //===----------------------------------------------------------------------===//
532 // NonTypeTemplateParmDecl Method Implementations
533 //===----------------------------------------------------------------------===//
534
NonTypeTemplateParmDecl(DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,const QualType * ExpandedTypes,unsigned NumExpandedTypes,TypeSourceInfo ** ExpandedTInfos)535 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
536 SourceLocation StartLoc,
537 SourceLocation IdLoc,
538 unsigned D, unsigned P,
539 IdentifierInfo *Id,
540 QualType T,
541 TypeSourceInfo *TInfo,
542 const QualType *ExpandedTypes,
543 unsigned NumExpandedTypes,
544 TypeSourceInfo **ExpandedTInfos)
545 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
546 TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false),
547 ParameterPack(true), ExpandedParameterPack(true),
548 NumExpandedTypes(NumExpandedTypes)
549 {
550 if (ExpandedTypes && ExpandedTInfos) {
551 void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
552 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
553 TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
554 TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
555 }
556 }
557 }
558
559 NonTypeTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,bool ParameterPack,TypeSourceInfo * TInfo)560 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
561 SourceLocation StartLoc, SourceLocation IdLoc,
562 unsigned D, unsigned P, IdentifierInfo *Id,
563 QualType T, bool ParameterPack,
564 TypeSourceInfo *TInfo) {
565 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
566 T, ParameterPack, TInfo);
567 }
568
569 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)570 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
571 SourceLocation StartLoc, SourceLocation IdLoc,
572 unsigned D, unsigned P,
573 IdentifierInfo *Id, QualType T,
574 TypeSourceInfo *TInfo,
575 const QualType *ExpandedTypes,
576 unsigned NumExpandedTypes,
577 TypeSourceInfo **ExpandedTInfos) {
578 unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
579 return new (C, DC, Extra) NonTypeTemplateParmDecl(
580 DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
581 ExpandedTypes, NumExpandedTypes, ExpandedTInfos);
582 }
583
584 NonTypeTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID)585 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
586 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
587 SourceLocation(), 0, 0, nullptr,
588 QualType(), false, nullptr);
589 }
590
591 NonTypeTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID,unsigned NumExpandedTypes)592 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
593 unsigned NumExpandedTypes) {
594 unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
595 return new (C, ID, Extra) NonTypeTemplateParmDecl(
596 nullptr, SourceLocation(), SourceLocation(), 0, 0, nullptr, QualType(),
597 nullptr, nullptr, NumExpandedTypes, nullptr);
598 }
599
getSourceRange() const600 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
601 if (hasDefaultArgument() && !defaultArgumentWasInherited())
602 return SourceRange(getOuterLocStart(),
603 getDefaultArgument()->getSourceRange().getEnd());
604 return DeclaratorDecl::getSourceRange();
605 }
606
getDefaultArgumentLoc() const607 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
608 return hasDefaultArgument()
609 ? getDefaultArgument()->getSourceRange().getBegin()
610 : SourceLocation();
611 }
612
613 //===----------------------------------------------------------------------===//
614 // TemplateTemplateParmDecl Method Implementations
615 //===----------------------------------------------------------------------===//
616
anchor()617 void TemplateTemplateParmDecl::anchor() { }
618
TemplateTemplateParmDecl(DeclContext * DC,SourceLocation L,unsigned D,unsigned P,IdentifierInfo * Id,TemplateParameterList * Params,unsigned NumExpansions,TemplateParameterList * const * Expansions)619 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
620 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
621 IdentifierInfo *Id, TemplateParameterList *Params,
622 unsigned NumExpansions, TemplateParameterList * const *Expansions)
623 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
624 TemplateParmPosition(D, P), DefaultArgument(),
625 DefaultArgumentWasInherited(false), ParameterPack(true),
626 ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
627 if (Expansions)
628 std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
629 sizeof(TemplateParameterList*) * NumExpandedParams);
630 }
631
632 TemplateTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation L,unsigned D,unsigned P,bool ParameterPack,IdentifierInfo * Id,TemplateParameterList * Params)633 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
634 SourceLocation L, unsigned D, unsigned P,
635 bool ParameterPack, IdentifierInfo *Id,
636 TemplateParameterList *Params) {
637 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
638 Params);
639 }
640
641 TemplateTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation L,unsigned D,unsigned P,IdentifierInfo * Id,TemplateParameterList * Params,ArrayRef<TemplateParameterList * > Expansions)642 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
643 SourceLocation L, unsigned D, unsigned P,
644 IdentifierInfo *Id,
645 TemplateParameterList *Params,
646 ArrayRef<TemplateParameterList *> Expansions) {
647 return new (C, DC, sizeof(TemplateParameterList*) * Expansions.size())
648 TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
649 Expansions.size(), Expansions.data());
650 }
651
652 TemplateTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID)653 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
654 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
655 false, nullptr, nullptr);
656 }
657
658 TemplateTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID,unsigned NumExpansions)659 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
660 unsigned NumExpansions) {
661 return new (C, ID, sizeof(TemplateParameterList*) * NumExpansions)
662 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
663 nullptr, NumExpansions, nullptr);
664 }
665
666 //===----------------------------------------------------------------------===//
667 // TemplateArgumentList Implementation
668 //===----------------------------------------------------------------------===//
669 TemplateArgumentList *
CreateCopy(ASTContext & Context,const TemplateArgument * Args,unsigned NumArgs)670 TemplateArgumentList::CreateCopy(ASTContext &Context,
671 const TemplateArgument *Args,
672 unsigned NumArgs) {
673 std::size_t Size = sizeof(TemplateArgumentList)
674 + NumArgs * sizeof(TemplateArgument);
675 void *Mem = Context.Allocate(Size);
676 TemplateArgument *StoredArgs
677 = reinterpret_cast<TemplateArgument *>(
678 static_cast<TemplateArgumentList *>(Mem) + 1);
679 std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
680 return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
681 }
682
683 FunctionTemplateSpecializationInfo *
Create(ASTContext & C,FunctionDecl * FD,FunctionTemplateDecl * Template,TemplateSpecializationKind TSK,const TemplateArgumentList * TemplateArgs,const TemplateArgumentListInfo * TemplateArgsAsWritten,SourceLocation POI)684 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
685 FunctionTemplateDecl *Template,
686 TemplateSpecializationKind TSK,
687 const TemplateArgumentList *TemplateArgs,
688 const TemplateArgumentListInfo *TemplateArgsAsWritten,
689 SourceLocation POI) {
690 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
691 if (TemplateArgsAsWritten)
692 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
693 *TemplateArgsAsWritten);
694
695 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
696 TemplateArgs,
697 ArgsAsWritten,
698 POI);
699 }
700
701 //===----------------------------------------------------------------------===//
702 // TemplateDecl Implementation
703 //===----------------------------------------------------------------------===//
704
anchor()705 void TemplateDecl::anchor() { }
706
707 //===----------------------------------------------------------------------===//
708 // ClassTemplateSpecializationDecl Implementation
709 //===----------------------------------------------------------------------===//
710 ClassTemplateSpecializationDecl::
ClassTemplateSpecializationDecl(ASTContext & Context,Kind DK,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,ClassTemplateDecl * SpecializedTemplate,const TemplateArgument * Args,unsigned NumArgs,ClassTemplateSpecializationDecl * PrevDecl)711 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
712 DeclContext *DC, SourceLocation StartLoc,
713 SourceLocation IdLoc,
714 ClassTemplateDecl *SpecializedTemplate,
715 const TemplateArgument *Args,
716 unsigned NumArgs,
717 ClassTemplateSpecializationDecl *PrevDecl)
718 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
719 SpecializedTemplate->getIdentifier(),
720 PrevDecl),
721 SpecializedTemplate(SpecializedTemplate),
722 ExplicitInfo(nullptr),
723 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
724 SpecializationKind(TSK_Undeclared) {
725 }
726
ClassTemplateSpecializationDecl(ASTContext & C,Kind DK)727 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
728 Kind DK)
729 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
730 SourceLocation(), nullptr, nullptr),
731 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
732
733 ClassTemplateSpecializationDecl *
Create(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,ClassTemplateDecl * SpecializedTemplate,const TemplateArgument * Args,unsigned NumArgs,ClassTemplateSpecializationDecl * PrevDecl)734 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
735 DeclContext *DC,
736 SourceLocation StartLoc,
737 SourceLocation IdLoc,
738 ClassTemplateDecl *SpecializedTemplate,
739 const TemplateArgument *Args,
740 unsigned NumArgs,
741 ClassTemplateSpecializationDecl *PrevDecl) {
742 ClassTemplateSpecializationDecl *Result =
743 new (Context, DC) ClassTemplateSpecializationDecl(
744 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
745 SpecializedTemplate, Args, NumArgs, PrevDecl);
746 Result->MayHaveOutOfDateDef = false;
747
748 Context.getTypeDeclType(Result, PrevDecl);
749 return Result;
750 }
751
752 ClassTemplateSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)753 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
754 unsigned ID) {
755 ClassTemplateSpecializationDecl *Result =
756 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
757 Result->MayHaveOutOfDateDef = false;
758 return Result;
759 }
760
getNameForDiagnostic(raw_ostream & OS,const PrintingPolicy & Policy,bool Qualified) const761 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
762 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
763 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
764
765 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
766 TemplateSpecializationType::PrintTemplateArgumentList(
767 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
768 }
769
770 ClassTemplateDecl *
getSpecializedTemplate() const771 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
772 if (SpecializedPartialSpecialization *PartialSpec
773 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
774 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
775 return SpecializedTemplate.get<ClassTemplateDecl*>();
776 }
777
778 SourceRange
getSourceRange() const779 ClassTemplateSpecializationDecl::getSourceRange() const {
780 if (ExplicitInfo) {
781 SourceLocation Begin = getTemplateKeywordLoc();
782 if (Begin.isValid()) {
783 // Here we have an explicit (partial) specialization or instantiation.
784 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
785 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
786 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
787 if (getExternLoc().isValid())
788 Begin = getExternLoc();
789 SourceLocation End = getRBraceLoc();
790 if (End.isInvalid())
791 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
792 return SourceRange(Begin, End);
793 }
794 // An implicit instantiation of a class template partial specialization
795 // uses ExplicitInfo to record the TypeAsWritten, but the source
796 // locations should be retrieved from the instantiation pattern.
797 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
798 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
799 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
800 assert(inst_from != nullptr);
801 return inst_from->getSourceRange();
802 }
803 else {
804 // No explicit info available.
805 llvm::PointerUnion<ClassTemplateDecl *,
806 ClassTemplatePartialSpecializationDecl *>
807 inst_from = getInstantiatedFrom();
808 if (inst_from.isNull())
809 return getSpecializedTemplate()->getSourceRange();
810 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
811 return ctd->getSourceRange();
812 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
813 ->getSourceRange();
814 }
815 }
816
817 //===----------------------------------------------------------------------===//
818 // ClassTemplatePartialSpecializationDecl Implementation
819 //===----------------------------------------------------------------------===//
anchor()820 void ClassTemplatePartialSpecializationDecl::anchor() { }
821
822 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)823 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
824 DeclContext *DC,
825 SourceLocation StartLoc,
826 SourceLocation IdLoc,
827 TemplateParameterList *Params,
828 ClassTemplateDecl *SpecializedTemplate,
829 const TemplateArgument *Args,
830 unsigned NumArgs,
831 const ASTTemplateArgumentListInfo *ArgInfos,
832 ClassTemplatePartialSpecializationDecl *PrevDecl)
833 : ClassTemplateSpecializationDecl(Context,
834 ClassTemplatePartialSpecialization,
835 TK, DC, StartLoc, IdLoc,
836 SpecializedTemplate,
837 Args, NumArgs, PrevDecl),
838 TemplateParams(Params), ArgsAsWritten(ArgInfos),
839 InstantiatedFromMember(nullptr, false)
840 {
841 AdoptTemplateParameterList(Params, this);
842 }
843
844 ClassTemplatePartialSpecializationDecl *
845 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)846 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
847 SourceLocation StartLoc, SourceLocation IdLoc,
848 TemplateParameterList *Params,
849 ClassTemplateDecl *SpecializedTemplate,
850 const TemplateArgument *Args,
851 unsigned NumArgs,
852 const TemplateArgumentListInfo &ArgInfos,
853 QualType CanonInjectedType,
854 ClassTemplatePartialSpecializationDecl *PrevDecl) {
855 const ASTTemplateArgumentListInfo *ASTArgInfos =
856 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
857
858 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
859 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
860 Params, SpecializedTemplate, Args,
861 NumArgs, ASTArgInfos, PrevDecl);
862 Result->setSpecializationKind(TSK_ExplicitSpecialization);
863 Result->MayHaveOutOfDateDef = false;
864
865 Context.getInjectedClassNameType(Result, CanonInjectedType);
866 return Result;
867 }
868
869 ClassTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)870 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
871 unsigned ID) {
872 ClassTemplatePartialSpecializationDecl *Result =
873 new (C, ID) ClassTemplatePartialSpecializationDecl(C);
874 Result->MayHaveOutOfDateDef = false;
875 return Result;
876 }
877
878 //===----------------------------------------------------------------------===//
879 // FriendTemplateDecl Implementation
880 //===----------------------------------------------------------------------===//
881
anchor()882 void FriendTemplateDecl::anchor() { }
883
Create(ASTContext & Context,DeclContext * DC,SourceLocation L,unsigned NParams,TemplateParameterList ** Params,FriendUnion Friend,SourceLocation FLoc)884 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
885 DeclContext *DC,
886 SourceLocation L,
887 unsigned NParams,
888 TemplateParameterList **Params,
889 FriendUnion Friend,
890 SourceLocation FLoc) {
891 return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params,
892 Friend, FLoc);
893 }
894
CreateDeserialized(ASTContext & C,unsigned ID)895 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
896 unsigned ID) {
897 return new (C, ID) FriendTemplateDecl(EmptyShell());
898 }
899
900 //===----------------------------------------------------------------------===//
901 // TypeAliasTemplateDecl Implementation
902 //===----------------------------------------------------------------------===//
903
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)904 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
905 DeclContext *DC,
906 SourceLocation L,
907 DeclarationName Name,
908 TemplateParameterList *Params,
909 NamedDecl *Decl) {
910 AdoptTemplateParameterList(Params, DC);
911 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
912 }
913
CreateDeserialized(ASTContext & C,unsigned ID)914 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
915 unsigned ID) {
916 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
917 DeclarationName(), nullptr, nullptr);
918 }
919
DeallocateCommon(void * Ptr)920 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
921 static_cast<Common *>(Ptr)->~Common();
922 }
923 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const924 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
925 Common *CommonPtr = new (C) Common;
926 C.AddDeallocation(DeallocateCommon, CommonPtr);
927 return CommonPtr;
928 }
929
930 //===----------------------------------------------------------------------===//
931 // ClassScopeFunctionSpecializationDecl Implementation
932 //===----------------------------------------------------------------------===//
933
anchor()934 void ClassScopeFunctionSpecializationDecl::anchor() { }
935
936 ClassScopeFunctionSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)937 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
938 unsigned ID) {
939 return new (C, ID) ClassScopeFunctionSpecializationDecl(
940 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
941 }
942
943 //===----------------------------------------------------------------------===//
944 // VarTemplateDecl Implementation
945 //===----------------------------------------------------------------------===//
946
DeallocateCommon(void * Ptr)947 void VarTemplateDecl::DeallocateCommon(void *Ptr) {
948 static_cast<Common *>(Ptr)->~Common();
949 }
950
getDefinition()951 VarTemplateDecl *VarTemplateDecl::getDefinition() {
952 VarTemplateDecl *CurD = this;
953 while (CurD) {
954 if (CurD->isThisDeclarationADefinition())
955 return CurD;
956 CurD = CurD->getPreviousDecl();
957 }
958 return nullptr;
959 }
960
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,VarDecl * Decl)961 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
962 SourceLocation L, DeclarationName Name,
963 TemplateParameterList *Params,
964 VarDecl *Decl) {
965 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
966 }
967
CreateDeserialized(ASTContext & C,unsigned ID)968 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
969 unsigned ID) {
970 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
971 DeclarationName(), nullptr, nullptr);
972 }
973
974 // TODO: Unify across class, function and variable templates?
975 // May require moving this and Common to RedeclarableTemplateDecl.
LoadLazySpecializations() const976 void VarTemplateDecl::LoadLazySpecializations() const {
977 // Grab the most recent declaration to ensure we've loaded any lazy
978 // redeclarations of this template.
979 //
980 // FIXME: Avoid walking the entire redeclaration chain here.
981 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
982 if (CommonPtr->LazySpecializations) {
983 ASTContext &Context = getASTContext();
984 uint32_t *Specs = CommonPtr->LazySpecializations;
985 CommonPtr->LazySpecializations = nullptr;
986 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
987 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
988 }
989 }
990
991 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
getSpecializations() const992 VarTemplateDecl::getSpecializations() const {
993 LoadLazySpecializations();
994 return getCommonPtr()->Specializations;
995 }
996
997 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
getPartialSpecializations()998 VarTemplateDecl::getPartialSpecializations() {
999 LoadLazySpecializations();
1000 return getCommonPtr()->PartialSpecializations;
1001 }
1002
1003 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const1004 VarTemplateDecl::newCommon(ASTContext &C) const {
1005 Common *CommonPtr = new (C) Common;
1006 C.AddDeallocation(DeallocateCommon, CommonPtr);
1007 return CommonPtr;
1008 }
1009
1010 VarTemplateSpecializationDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)1011 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1012 void *&InsertPos) {
1013 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
1014 }
1015
AddSpecialization(VarTemplateSpecializationDecl * D,void * InsertPos)1016 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1017 void *InsertPos) {
1018 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1019 }
1020
1021 VarTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)1022 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1023 void *&InsertPos) {
1024 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
1025 }
1026
AddPartialSpecialization(VarTemplatePartialSpecializationDecl * D,void * InsertPos)1027 void VarTemplateDecl::AddPartialSpecialization(
1028 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1029 if (InsertPos)
1030 getPartialSpecializations().InsertNode(D, InsertPos);
1031 else {
1032 VarTemplatePartialSpecializationDecl *Existing =
1033 getPartialSpecializations().GetOrInsertNode(D);
1034 (void)Existing;
1035 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1036 }
1037
1038 if (ASTMutationListener *L = getASTMutationListener())
1039 L->AddedCXXTemplateSpecialization(this, D);
1040 }
1041
getPartialSpecializations(SmallVectorImpl<VarTemplatePartialSpecializationDecl * > & PS)1042 void VarTemplateDecl::getPartialSpecializations(
1043 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1044 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1045 getPartialSpecializations();
1046 PS.clear();
1047 PS.reserve(PartialSpecs.size());
1048 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1049 P = PartialSpecs.begin(),
1050 PEnd = PartialSpecs.end();
1051 P != PEnd; ++P)
1052 PS.push_back(P->getMostRecentDecl());
1053 }
1054
1055 VarTemplatePartialSpecializationDecl *
findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl * D)1056 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1057 VarTemplatePartialSpecializationDecl *D) {
1058 Decl *DCanon = D->getCanonicalDecl();
1059 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1060 P = getPartialSpecializations().begin(),
1061 PEnd = getPartialSpecializations().end();
1062 P != PEnd; ++P) {
1063 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1064 return P->getMostRecentDecl();
1065 }
1066
1067 return nullptr;
1068 }
1069
1070 //===----------------------------------------------------------------------===//
1071 // VarTemplateSpecializationDecl Implementation
1072 //===----------------------------------------------------------------------===//
VarTemplateSpecializationDecl(Kind DK,ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,const TemplateArgument * Args,unsigned NumArgs)1073 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1074 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1075 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1076 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1077 unsigned NumArgs)
1078 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1079 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1080 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
1081 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
1082 SpecializationKind(TSK_Undeclared) {}
1083
VarTemplateSpecializationDecl(Kind DK,ASTContext & C)1084 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1085 ASTContext &C)
1086 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1087 QualType(), nullptr, SC_None),
1088 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
1089
Create(ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,const TemplateArgument * Args,unsigned NumArgs)1090 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1091 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1092 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1093 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1094 unsigned NumArgs) {
1095 return new (Context, DC) VarTemplateSpecializationDecl(
1096 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1097 SpecializedTemplate, T, TInfo, S, Args, NumArgs);
1098 }
1099
1100 VarTemplateSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1101 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1102 return new (C, ID)
1103 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1104 }
1105
getNameForDiagnostic(raw_ostream & OS,const PrintingPolicy & Policy,bool Qualified) const1106 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1107 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1108 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1109
1110 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1111 TemplateSpecializationType::PrintTemplateArgumentList(
1112 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
1113 }
1114
getSpecializedTemplate() const1115 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1116 if (SpecializedPartialSpecialization *PartialSpec =
1117 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1118 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1119 return SpecializedTemplate.get<VarTemplateDecl *>();
1120 }
1121
setTemplateArgsInfo(const TemplateArgumentListInfo & ArgsInfo)1122 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1123 const TemplateArgumentListInfo &ArgsInfo) {
1124 unsigned N = ArgsInfo.size();
1125 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1126 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1127 for (unsigned I = 0; I != N; ++I)
1128 TemplateArgsInfo.addArgument(ArgsInfo[I]);
1129 }
1130
1131 //===----------------------------------------------------------------------===//
1132 // VarTemplatePartialSpecializationDecl Implementation
1133 //===----------------------------------------------------------------------===//
anchor()1134 void VarTemplatePartialSpecializationDecl::anchor() {}
1135
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)1136 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
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 ASTTemplateArgumentListInfo *ArgInfos)
1142 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1143 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1144 TInfo, S, Args, NumArgs),
1145 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1146 InstantiatedFromMember(nullptr, false) {
1147 // TODO: The template parameters should be in DC by now. Verify.
1148 // AdoptTemplateParameterList(Params, DC);
1149 }
1150
1151 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)1152 VarTemplatePartialSpecializationDecl::Create(
1153 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1154 SourceLocation IdLoc, TemplateParameterList *Params,
1155 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1156 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
1157 const TemplateArgumentListInfo &ArgInfos) {
1158 const ASTTemplateArgumentListInfo *ASTArgInfos
1159 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1160
1161 VarTemplatePartialSpecializationDecl *Result =
1162 new (Context, DC) VarTemplatePartialSpecializationDecl(
1163 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1164 S, Args, NumArgs, ASTArgInfos);
1165 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1166 return Result;
1167 }
1168
1169 VarTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1170 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1171 unsigned ID) {
1172 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1173 }
1174