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