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