1 //===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the C++ related Decl classes for templates.
12 //===----------------------------------------------------------------------===//
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"
24 using namespace clang;
26 //===----------------------------------------------------------------------===//
27 // TemplateParameterList Implementation
28 //===----------------------------------------------------------------------===//
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];
41 if (!P->isTemplateParameterPack()) {
42 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
43 if (NTTP->getType()->containsUnexpandedParameterPack())
44 ContainsUnexpandedParameterPack = true;
46 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
47 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
48 ContainsUnexpandedParameterPack = true;
50 // FIXME: If a default argument contains an unexpanded parameter pack, the
51 // template parameter list does too.
56 TemplateParameterList *
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);
69 unsigned TemplateParameterList::getMinRequiredArguments() const {
70 unsigned NumRequiredArgs = 0;
71 for (iterator P = const_cast<TemplateParameterList *>(this)->begin(),
72 PEnd = const_cast<TemplateParameterList *>(this)->end();
74 if ((*P)->isTemplateParameterPack()) {
75 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P))
76 if (NTTP->isExpandedParameterPack()) {
77 NumRequiredArgs += NTTP->getNumExpansionTypes();
84 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
85 if (TTP->hasDefaultArgument())
87 } else if (NonTypeTemplateParmDecl *NTTP
88 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
89 if (NTTP->hasDefaultArgument())
91 } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument())
97 return NumRequiredArgs;
100 unsigned TemplateParameterList::getDepth() const {
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();
112 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
115 static void AdoptTemplateParameterList(TemplateParameterList *Params,
116 DeclContext *Owner) {
117 for (TemplateParameterList::iterator P = Params->begin(),
118 PEnd = Params->end();
120 (*P)->setDeclContext(Owner);
122 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P))
123 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
127 //===----------------------------------------------------------------------===//
128 // RedeclarableTemplateDecl Implementation
129 //===----------------------------------------------------------------------===//
131 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
135 // Walk the previous-declaration chain until we either find a declaration
136 // with a common pointer or we run out of previous declarations.
137 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
138 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
139 Prev = Prev->getPreviousDecl()) {
141 Common = Prev->Common;
145 PrevDecls.push_back(Prev);
148 // If we never found a common pointer, allocate one now.
150 // FIXME: If any of the declarations is from an AST file, we probably
151 // need an update record to add the common data.
153 Common = newCommon(getASTContext());
156 // Update any previous declarations we saw with the common pointer.
157 for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I)
158 PrevDecls[I]->Common = Common;
163 template <class EntryType>
164 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
165 RedeclarableTemplateDecl::findSpecializationImpl(
166 llvm::FoldingSetVector<EntryType> &Specs,
167 const TemplateArgument *Args, unsigned NumArgs,
169 typedef SpecEntryTraits<EntryType> SETraits;
170 llvm::FoldingSetNodeID ID;
171 EntryType::Profile(ID,Args,NumArgs, getASTContext());
172 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
173 return Entry ? SETraits::getMostRecentDecl(Entry) : 0;
176 /// \brief Generate the injected template arguments for the given template
177 /// parameter list, e.g., for the injected-class-name of a class template.
178 static void GenerateInjectedTemplateArgs(ASTContext &Context,
179 TemplateParameterList *Params,
180 TemplateArgument *Args) {
181 for (TemplateParameterList::iterator Param = Params->begin(),
182 ParamEnd = Params->end();
183 Param != ParamEnd; ++Param) {
184 TemplateArgument Arg;
185 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
186 QualType ArgType = Context.getTypeDeclType(TTP);
187 if (TTP->isParameterPack())
188 ArgType = Context.getPackExpansionType(ArgType, None);
190 Arg = TemplateArgument(ArgType);
191 } else if (NonTypeTemplateParmDecl *NTTP =
192 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
193 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
194 NTTP->getType().getNonLValueExprType(Context),
195 Expr::getValueKindForType(NTTP->getType()),
196 NTTP->getLocation());
198 if (NTTP->isParameterPack())
199 E = new (Context) PackExpansionExpr(Context.DependentTy, E,
200 NTTP->getLocation(), None);
201 Arg = TemplateArgument(E);
203 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
204 if (TTP->isParameterPack())
205 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
207 Arg = TemplateArgument(TemplateName(TTP));
210 if ((*Param)->isTemplateParameterPack())
211 Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
217 //===----------------------------------------------------------------------===//
218 // FunctionTemplateDecl Implementation
219 //===----------------------------------------------------------------------===//
221 void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
222 static_cast<Common *>(Ptr)->~Common();
225 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
228 DeclarationName Name,
229 TemplateParameterList *Params,
231 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
232 return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
235 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
237 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FunctionTemplateDecl));
238 return new (Mem) FunctionTemplateDecl(0, SourceLocation(), DeclarationName(),
242 RedeclarableTemplateDecl::CommonBase *
243 FunctionTemplateDecl::newCommon(ASTContext &C) const {
244 Common *CommonPtr = new (C) Common;
245 C.AddDeallocation(DeallocateCommon, CommonPtr);
249 void FunctionTemplateDecl::LoadLazySpecializations() const {
250 Common *CommonPtr = getCommonPtr();
251 if (CommonPtr->LazySpecializations) {
252 ASTContext &Context = getASTContext();
253 uint32_t *Specs = CommonPtr->LazySpecializations;
254 CommonPtr->LazySpecializations = 0;
255 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
256 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
260 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
261 FunctionTemplateDecl::getSpecializations() const {
262 LoadLazySpecializations();
263 return getCommonPtr()->Specializations;
267 FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
268 unsigned NumArgs, void *&InsertPos) {
269 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
272 void FunctionTemplateDecl::addSpecialization(
273 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
275 getSpecializations().InsertNode(Info, InsertPos);
277 getSpecializations().GetOrInsertNode(Info);
278 if (ASTMutationListener *L = getASTMutationListener())
279 L->AddedCXXTemplateSpecialization(this, Info->Function);
282 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
283 TemplateParameterList *Params = getTemplateParameters();
284 Common *CommonPtr = getCommonPtr();
285 if (!CommonPtr->InjectedArgs) {
286 CommonPtr->InjectedArgs
287 = new (getASTContext()) TemplateArgument[Params->size()];
288 GenerateInjectedTemplateArgs(getASTContext(), Params,
289 CommonPtr->InjectedArgs);
292 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
295 //===----------------------------------------------------------------------===//
296 // ClassTemplateDecl Implementation
297 //===----------------------------------------------------------------------===//
299 void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
300 static_cast<Common *>(Ptr)->~Common();
303 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
306 DeclarationName Name,
307 TemplateParameterList *Params,
309 ClassTemplateDecl *PrevDecl) {
310 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
311 ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
312 New->setPreviousDecl(PrevDecl);
316 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
318 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ClassTemplateDecl));
319 return new (Mem) ClassTemplateDecl(EmptyShell());
322 void ClassTemplateDecl::LoadLazySpecializations() const {
323 Common *CommonPtr = getCommonPtr();
324 if (CommonPtr->LazySpecializations) {
325 ASTContext &Context = getASTContext();
326 uint32_t *Specs = CommonPtr->LazySpecializations;
327 CommonPtr->LazySpecializations = 0;
328 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
329 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
333 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
334 ClassTemplateDecl::getSpecializations() const {
335 LoadLazySpecializations();
336 return getCommonPtr()->Specializations;
339 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
340 ClassTemplateDecl::getPartialSpecializations() {
341 LoadLazySpecializations();
342 return getCommonPtr()->PartialSpecializations;
345 RedeclarableTemplateDecl::CommonBase *
346 ClassTemplateDecl::newCommon(ASTContext &C) const {
347 Common *CommonPtr = new (C) Common;
348 C.AddDeallocation(DeallocateCommon, CommonPtr);
352 ClassTemplateSpecializationDecl *
353 ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
354 unsigned NumArgs, void *&InsertPos) {
355 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
358 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
361 getSpecializations().InsertNode(D, InsertPos);
363 ClassTemplateSpecializationDecl *Existing
364 = getSpecializations().GetOrInsertNode(D);
366 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
368 if (ASTMutationListener *L = getASTMutationListener())
369 L->AddedCXXTemplateSpecialization(this, D);
372 ClassTemplatePartialSpecializationDecl *
373 ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
376 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
380 void ClassTemplateDecl::AddPartialSpecialization(
381 ClassTemplatePartialSpecializationDecl *D,
384 getPartialSpecializations().InsertNode(D, InsertPos);
386 ClassTemplatePartialSpecializationDecl *Existing
387 = getPartialSpecializations().GetOrInsertNode(D);
389 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
392 if (ASTMutationListener *L = getASTMutationListener())
393 L->AddedCXXTemplateSpecialization(this, D);
396 void ClassTemplateDecl::getPartialSpecializations(
397 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
398 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
399 = getPartialSpecializations();
401 PS.reserve(PartialSpecs.size());
402 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
403 P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
405 PS.push_back(P->getMostRecentDecl());
408 ClassTemplatePartialSpecializationDecl *
409 ClassTemplateDecl::findPartialSpecialization(QualType T) {
410 ASTContext &Context = getASTContext();
411 using llvm::FoldingSetVector;
412 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
413 partial_spec_iterator;
414 for (partial_spec_iterator P = getPartialSpecializations().begin(),
415 PEnd = getPartialSpecializations().end();
417 if (Context.hasSameType(P->getInjectedSpecializationType(), T))
418 return P->getMostRecentDecl();
424 ClassTemplatePartialSpecializationDecl *
425 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
426 ClassTemplatePartialSpecializationDecl *D) {
427 Decl *DCanon = D->getCanonicalDecl();
428 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
429 P = getPartialSpecializations().begin(),
430 PEnd = getPartialSpecializations().end();
432 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
433 return P->getMostRecentDecl();
440 ClassTemplateDecl::getInjectedClassNameSpecialization() {
441 Common *CommonPtr = getCommonPtr();
442 if (!CommonPtr->InjectedClassNameType.isNull())
443 return CommonPtr->InjectedClassNameType;
445 // C++0x [temp.dep.type]p2:
446 // The template argument list of a primary template is a template argument
447 // list in which the nth template argument has the value of the nth template
448 // parameter of the class template. If the nth template parameter is a
449 // template parameter pack (14.5.3), the nth template argument is a pack
450 // expansion (14.5.3) whose pattern is the name of the template parameter
452 ASTContext &Context = getASTContext();
453 TemplateParameterList *Params = getTemplateParameters();
454 SmallVector<TemplateArgument, 16> TemplateArgs;
455 TemplateArgs.resize(Params->size());
456 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
457 CommonPtr->InjectedClassNameType
458 = Context.getTemplateSpecializationType(TemplateName(this),
460 TemplateArgs.size());
461 return CommonPtr->InjectedClassNameType;
464 //===----------------------------------------------------------------------===//
465 // TemplateTypeParm Allocation/Deallocation Method Implementations
466 //===----------------------------------------------------------------------===//
468 TemplateTypeParmDecl *
469 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
470 SourceLocation KeyLoc, SourceLocation NameLoc,
471 unsigned D, unsigned P, IdentifierInfo *Id,
472 bool Typename, bool ParameterPack) {
473 TemplateTypeParmDecl *TTPDecl =
474 new (C) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
475 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
476 TTPDecl->TypeForDecl = TTPType.getTypePtr();
480 TemplateTypeParmDecl *
481 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
482 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTypeParmDecl));
483 return new (Mem) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(),
487 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
488 return hasDefaultArgument()
489 ? DefaultArgument->getTypeLoc().getBeginLoc()
493 SourceRange TemplateTypeParmDecl::getSourceRange() const {
494 if (hasDefaultArgument() && !defaultArgumentWasInherited())
495 return SourceRange(getLocStart(),
496 DefaultArgument->getTypeLoc().getEndLoc());
498 return TypeDecl::getSourceRange();
501 unsigned TemplateTypeParmDecl::getDepth() const {
502 return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
505 unsigned TemplateTypeParmDecl::getIndex() const {
506 return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
509 bool TemplateTypeParmDecl::isParameterPack() const {
510 return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack();
513 //===----------------------------------------------------------------------===//
514 // NonTypeTemplateParmDecl Method Implementations
515 //===----------------------------------------------------------------------===//
517 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
518 SourceLocation StartLoc,
519 SourceLocation IdLoc,
520 unsigned D, unsigned P,
523 TypeSourceInfo *TInfo,
524 const QualType *ExpandedTypes,
525 unsigned NumExpandedTypes,
526 TypeSourceInfo **ExpandedTInfos)
527 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
528 TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
529 ParameterPack(true), ExpandedParameterPack(true),
530 NumExpandedTypes(NumExpandedTypes)
532 if (ExpandedTypes && ExpandedTInfos) {
533 void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
534 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
535 TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
536 TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
541 NonTypeTemplateParmDecl *
542 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
543 SourceLocation StartLoc, SourceLocation IdLoc,
544 unsigned D, unsigned P, IdentifierInfo *Id,
545 QualType T, bool ParameterPack,
546 TypeSourceInfo *TInfo) {
547 return new (C) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
548 T, ParameterPack, TInfo);
551 NonTypeTemplateParmDecl *
552 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
553 SourceLocation StartLoc, SourceLocation IdLoc,
554 unsigned D, unsigned P,
555 IdentifierInfo *Id, QualType T,
556 TypeSourceInfo *TInfo,
557 const QualType *ExpandedTypes,
558 unsigned NumExpandedTypes,
559 TypeSourceInfo **ExpandedTInfos) {
560 unsigned Size = sizeof(NonTypeTemplateParmDecl)
561 + NumExpandedTypes * 2 * sizeof(void*);
562 void *Mem = C.Allocate(Size);
563 return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc,
565 ExpandedTypes, NumExpandedTypes,
569 NonTypeTemplateParmDecl *
570 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
571 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NonTypeTemplateParmDecl));
572 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
573 SourceLocation(), 0, 0, 0,
574 QualType(), false, 0);
577 NonTypeTemplateParmDecl *
578 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
579 unsigned NumExpandedTypes) {
580 unsigned Size = sizeof(NonTypeTemplateParmDecl)
581 + NumExpandedTypes * 2 * sizeof(void*);
583 void *Mem = AllocateDeserializedDecl(C, ID, Size);
584 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
585 SourceLocation(), 0, 0, 0,
586 QualType(), 0, 0, NumExpandedTypes,
590 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
591 if (hasDefaultArgument() && !defaultArgumentWasInherited())
592 return SourceRange(getOuterLocStart(),
593 getDefaultArgument()->getSourceRange().getEnd());
594 return DeclaratorDecl::getSourceRange();
597 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
598 return hasDefaultArgument()
599 ? getDefaultArgument()->getSourceRange().getBegin()
603 //===----------------------------------------------------------------------===//
604 // TemplateTemplateParmDecl Method Implementations
605 //===----------------------------------------------------------------------===//
607 void TemplateTemplateParmDecl::anchor() { }
609 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
610 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
611 IdentifierInfo *Id, TemplateParameterList *Params,
612 unsigned NumExpansions, TemplateParameterList * const *Expansions)
613 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
614 TemplateParmPosition(D, P), DefaultArgument(),
615 DefaultArgumentWasInherited(false), ParameterPack(true),
616 ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
618 std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
619 sizeof(TemplateParameterList*) * NumExpandedParams);
622 TemplateTemplateParmDecl *
623 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
624 SourceLocation L, unsigned D, unsigned P,
625 bool ParameterPack, IdentifierInfo *Id,
626 TemplateParameterList *Params) {
627 return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
631 TemplateTemplateParmDecl *
632 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
633 SourceLocation L, unsigned D, unsigned P,
635 TemplateParameterList *Params,
636 ArrayRef<TemplateParameterList *> Expansions) {
637 void *Mem = C.Allocate(sizeof(TemplateTemplateParmDecl) +
638 sizeof(TemplateParameterList*) * Expansions.size());
639 return new (Mem) TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
644 TemplateTemplateParmDecl *
645 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
646 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTemplateParmDecl));
647 return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, false,
651 TemplateTemplateParmDecl *
652 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
653 unsigned NumExpansions) {
654 unsigned Size = sizeof(TemplateTemplateParmDecl) +
655 sizeof(TemplateParameterList*) * NumExpansions;
656 void *Mem = AllocateDeserializedDecl(C, ID, Size);
657 return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, 0, 0,
661 //===----------------------------------------------------------------------===//
662 // TemplateArgumentList Implementation
663 //===----------------------------------------------------------------------===//
664 TemplateArgumentList *
665 TemplateArgumentList::CreateCopy(ASTContext &Context,
666 const TemplateArgument *Args,
668 std::size_t Size = sizeof(TemplateArgumentList)
669 + NumArgs * sizeof(TemplateArgument);
670 void *Mem = Context.Allocate(Size);
671 TemplateArgument *StoredArgs
672 = reinterpret_cast<TemplateArgument *>(
673 static_cast<TemplateArgumentList *>(Mem) + 1);
674 std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
675 return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
678 FunctionTemplateSpecializationInfo *
679 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
680 FunctionTemplateDecl *Template,
681 TemplateSpecializationKind TSK,
682 const TemplateArgumentList *TemplateArgs,
683 const TemplateArgumentListInfo *TemplateArgsAsWritten,
684 SourceLocation POI) {
685 const ASTTemplateArgumentListInfo *ArgsAsWritten = 0;
686 if (TemplateArgsAsWritten)
687 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
688 *TemplateArgsAsWritten);
690 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
696 //===----------------------------------------------------------------------===//
697 // TemplateDecl Implementation
698 //===----------------------------------------------------------------------===//
700 void TemplateDecl::anchor() { }
702 //===----------------------------------------------------------------------===//
703 // ClassTemplateSpecializationDecl Implementation
704 //===----------------------------------------------------------------------===//
705 ClassTemplateSpecializationDecl::
706 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
707 DeclContext *DC, SourceLocation StartLoc,
708 SourceLocation IdLoc,
709 ClassTemplateDecl *SpecializedTemplate,
710 const TemplateArgument *Args,
712 ClassTemplateSpecializationDecl *PrevDecl)
713 : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc,
714 SpecializedTemplate->getIdentifier(),
716 SpecializedTemplate(SpecializedTemplate),
718 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
719 SpecializationKind(TSK_Undeclared) {
722 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
723 : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0),
725 SpecializationKind(TSK_Undeclared) {
728 ClassTemplateSpecializationDecl *
729 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
731 SourceLocation StartLoc,
732 SourceLocation IdLoc,
733 ClassTemplateDecl *SpecializedTemplate,
734 const TemplateArgument *Args,
736 ClassTemplateSpecializationDecl *PrevDecl) {
737 ClassTemplateSpecializationDecl *Result
738 = new (Context)ClassTemplateSpecializationDecl(Context,
739 ClassTemplateSpecialization,
740 TK, DC, StartLoc, IdLoc,
744 Result->MayHaveOutOfDateDef = false;
746 Context.getTypeDeclType(Result, PrevDecl);
750 ClassTemplateSpecializationDecl *
751 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
753 void *Mem = AllocateDeserializedDecl(C, ID,
754 sizeof(ClassTemplateSpecializationDecl));
755 ClassTemplateSpecializationDecl *Result =
756 new (Mem) ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
757 Result->MayHaveOutOfDateDef = false;
761 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
762 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
763 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
765 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
766 TemplateSpecializationType::PrintTemplateArgumentList(
767 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
771 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
772 if (SpecializedPartialSpecialization *PartialSpec
773 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
774 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
775 return SpecializedTemplate.get<ClassTemplateDecl*>();
779 ClassTemplateSpecializationDecl::getSourceRange() const {
781 SourceLocation Begin = getTemplateKeywordLoc();
782 if (Begin.isValid()) {
783 // Here we have an explicit (partial) specialization or instantiation.
784 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
785 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
786 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
787 if (getExternLoc().isValid())
788 Begin = getExternLoc();
789 SourceLocation End = getRBraceLoc();
791 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
792 return SourceRange(Begin, End);
794 // An implicit instantiation of a class template partial specialization
795 // uses ExplicitInfo to record the TypeAsWritten, but the source
796 // locations should be retrieved from the instantiation pattern.
797 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
798 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
799 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
800 assert(inst_from != 0);
801 return inst_from->getSourceRange();
804 // No explicit info available.
805 llvm::PointerUnion<ClassTemplateDecl *,
806 ClassTemplatePartialSpecializationDecl *>
807 inst_from = getInstantiatedFrom();
808 if (inst_from.isNull())
809 return getSpecializedTemplate()->getSourceRange();
810 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
811 return ctd->getSourceRange();
812 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
817 //===----------------------------------------------------------------------===//
818 // ClassTemplatePartialSpecializationDecl Implementation
819 //===----------------------------------------------------------------------===//
820 void ClassTemplatePartialSpecializationDecl::anchor() { }
822 ClassTemplatePartialSpecializationDecl::
823 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
825 SourceLocation StartLoc,
826 SourceLocation IdLoc,
827 TemplateParameterList *Params,
828 ClassTemplateDecl *SpecializedTemplate,
829 const TemplateArgument *Args,
831 const ASTTemplateArgumentListInfo *ArgInfos,
832 ClassTemplatePartialSpecializationDecl *PrevDecl)
833 : ClassTemplateSpecializationDecl(Context,
834 ClassTemplatePartialSpecialization,
835 TK, DC, StartLoc, IdLoc,
837 Args, NumArgs, PrevDecl),
838 TemplateParams(Params), ArgsAsWritten(ArgInfos),
839 InstantiatedFromMember(0, false)
841 AdoptTemplateParameterList(Params, this);
844 ClassTemplatePartialSpecializationDecl *
845 ClassTemplatePartialSpecializationDecl::
846 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
847 SourceLocation StartLoc, SourceLocation IdLoc,
848 TemplateParameterList *Params,
849 ClassTemplateDecl *SpecializedTemplate,
850 const TemplateArgument *Args,
852 const TemplateArgumentListInfo &ArgInfos,
853 QualType CanonInjectedType,
854 ClassTemplatePartialSpecializationDecl *PrevDecl) {
855 const ASTTemplateArgumentListInfo *ASTArgInfos =
856 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
858 ClassTemplatePartialSpecializationDecl *Result
859 = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC,
866 Result->setSpecializationKind(TSK_ExplicitSpecialization);
867 Result->MayHaveOutOfDateDef = false;
869 Context.getInjectedClassNameType(Result, CanonInjectedType);
873 ClassTemplatePartialSpecializationDecl *
874 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
876 void *Mem = AllocateDeserializedDecl(C, ID,
877 sizeof(ClassTemplatePartialSpecializationDecl));
878 ClassTemplatePartialSpecializationDecl *Result
879 = new (Mem) ClassTemplatePartialSpecializationDecl();
880 Result->MayHaveOutOfDateDef = false;
884 //===----------------------------------------------------------------------===//
885 // FriendTemplateDecl Implementation
886 //===----------------------------------------------------------------------===//
888 void FriendTemplateDecl::anchor() { }
890 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
894 TemplateParameterList **Params,
896 SourceLocation FLoc) {
897 FriendTemplateDecl *Result
898 = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
902 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
904 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FriendTemplateDecl));
905 return new (Mem) FriendTemplateDecl(EmptyShell());
908 //===----------------------------------------------------------------------===//
909 // TypeAliasTemplateDecl Implementation
910 //===----------------------------------------------------------------------===//
912 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
915 DeclarationName Name,
916 TemplateParameterList *Params,
918 AdoptTemplateParameterList(Params, DC);
919 return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl);
922 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
924 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasTemplateDecl));
925 return new (Mem) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(),
929 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
930 static_cast<Common *>(Ptr)->~Common();
932 RedeclarableTemplateDecl::CommonBase *
933 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
934 Common *CommonPtr = new (C) Common;
935 C.AddDeallocation(DeallocateCommon, CommonPtr);
939 //===----------------------------------------------------------------------===//
940 // ClassScopeFunctionSpecializationDecl Implementation
941 //===----------------------------------------------------------------------===//
943 void ClassScopeFunctionSpecializationDecl::anchor() { }
945 ClassScopeFunctionSpecializationDecl *
946 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
948 void *Mem = AllocateDeserializedDecl(C, ID,
949 sizeof(ClassScopeFunctionSpecializationDecl));
950 return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0,
951 false, TemplateArgumentListInfo());
954 //===----------------------------------------------------------------------===//
955 // VarTemplateDecl Implementation
956 //===----------------------------------------------------------------------===//
958 void VarTemplateDecl::DeallocateCommon(void *Ptr) {
959 static_cast<Common *>(Ptr)->~Common();
962 VarTemplateDecl *VarTemplateDecl::getDefinition() {
963 VarTemplateDecl *CurD = this;
965 if (CurD->isThisDeclarationADefinition())
967 CurD = CurD->getPreviousDecl();
972 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
973 SourceLocation L, DeclarationName Name,
974 TemplateParameterList *Params,
976 VarTemplateDecl *PrevDecl) {
977 VarTemplateDecl *New = new (C) VarTemplateDecl(DC, L, Name, Params, Decl);
978 New->setPreviousDecl(PrevDecl);
982 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
984 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(VarTemplateDecl));
985 return new (Mem) VarTemplateDecl(EmptyShell());
988 // TODO: Unify accross class, function and variable templates?
989 // May require moving this and Common to RedeclarableTemplateDecl.
990 void VarTemplateDecl::LoadLazySpecializations() const {
991 Common *CommonPtr = getCommonPtr();
992 if (CommonPtr->LazySpecializations) {
993 ASTContext &Context = getASTContext();
994 uint32_t *Specs = CommonPtr->LazySpecializations;
995 CommonPtr->LazySpecializations = 0;
996 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
997 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
1001 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1002 VarTemplateDecl::getSpecializations() const {
1003 LoadLazySpecializations();
1004 return getCommonPtr()->Specializations;
1007 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1008 VarTemplateDecl::getPartialSpecializations() {
1009 LoadLazySpecializations();
1010 return getCommonPtr()->PartialSpecializations;
1013 RedeclarableTemplateDecl::CommonBase *
1014 VarTemplateDecl::newCommon(ASTContext &C) const {
1015 Common *CommonPtr = new (C) Common;
1016 C.AddDeallocation(DeallocateCommon, CommonPtr);
1020 VarTemplateSpecializationDecl *
1021 VarTemplateDecl::findSpecialization(const TemplateArgument *Args,
1022 unsigned NumArgs, void *&InsertPos) {
1023 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
1026 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1029 getSpecializations().InsertNode(D, InsertPos);
1031 VarTemplateSpecializationDecl *Existing =
1032 getSpecializations().GetOrInsertNode(D);
1034 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1036 if (ASTMutationListener *L = getASTMutationListener())
1037 L->AddedCXXTemplateSpecialization(this, D);
1040 VarTemplatePartialSpecializationDecl *
1041 VarTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
1042 unsigned NumArgs, void *&InsertPos) {
1043 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
1047 void VarTemplateDecl::AddPartialSpecialization(
1048 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1050 getPartialSpecializations().InsertNode(D, InsertPos);
1052 VarTemplatePartialSpecializationDecl *Existing =
1053 getPartialSpecializations().GetOrInsertNode(D);
1055 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1058 if (ASTMutationListener *L = getASTMutationListener())
1059 L->AddedCXXTemplateSpecialization(this, D);
1062 void VarTemplateDecl::getPartialSpecializations(
1063 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1064 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1065 getPartialSpecializations();
1067 PS.reserve(PartialSpecs.size());
1068 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1069 P = PartialSpecs.begin(),
1070 PEnd = PartialSpecs.end();
1072 PS.push_back(P->getMostRecentDecl());
1075 VarTemplatePartialSpecializationDecl *
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();
1083 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1084 return P->getMostRecentDecl();
1090 //===----------------------------------------------------------------------===//
1091 // VarTemplateSpecializationDecl Implementation
1092 //===----------------------------------------------------------------------===//
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,
1098 : VarDecl(DK, DC, StartLoc, IdLoc, SpecializedTemplate->getIdentifier(), T,
1100 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(0),
1101 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
1102 SpecializationKind(TSK_Undeclared) {}
1104 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK)
1105 : VarDecl(DK, 0, SourceLocation(), SourceLocation(), 0, QualType(), 0,
1107 ExplicitInfo(0), SpecializationKind(TSK_Undeclared) {}
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,
1114 VarTemplateSpecializationDecl *Result = new (Context)
1115 VarTemplateSpecializationDecl(Context, VarTemplateSpecialization, DC,
1116 StartLoc, IdLoc, SpecializedTemplate, T,
1117 TInfo, S, Args, NumArgs);
1121 VarTemplateSpecializationDecl *
1122 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1124 AllocateDeserializedDecl(C, ID, sizeof(VarTemplateSpecializationDecl));
1125 VarTemplateSpecializationDecl *Result =
1126 new (Mem) VarTemplateSpecializationDecl(VarTemplateSpecialization);
1130 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1131 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1132 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1134 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1135 TemplateSpecializationType::PrintTemplateArgumentList(
1136 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
1139 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1140 if (SpecializedPartialSpecialization *PartialSpec =
1141 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1142 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1143 return SpecializedTemplate.get<VarTemplateDecl *>();
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]);
1155 //===----------------------------------------------------------------------===//
1156 // VarTemplatePartialSpecializationDecl Implementation
1157 //===----------------------------------------------------------------------===//
1158 void VarTemplatePartialSpecializationDecl::anchor() {}
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 const ASTTemplateArgumentListInfo *ArgInfos)
1166 : VarTemplateSpecializationDecl(Context, VarTemplatePartialSpecialization,
1167 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1168 TInfo, S, Args, NumArgs),
1169 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1170 InstantiatedFromMember(0, false) {
1171 // TODO: The template parameters should be in DC by now. Verify.
1172 // AdoptTemplateParameterList(Params, DC);
1175 VarTemplatePartialSpecializationDecl *
1176 VarTemplatePartialSpecializationDecl::Create(
1177 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1178 SourceLocation IdLoc, TemplateParameterList *Params,
1179 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1180 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
1181 const TemplateArgumentListInfo &ArgInfos) {
1182 const ASTTemplateArgumentListInfo *ASTArgInfos
1183 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1185 VarTemplatePartialSpecializationDecl *Result =
1186 new (Context) VarTemplatePartialSpecializationDecl(
1187 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1188 S, Args, NumArgs, ASTArgInfos);
1189 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1193 VarTemplatePartialSpecializationDecl *
1194 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1196 void *Mem = AllocateDeserializedDecl(
1197 C, ID, sizeof(VarTemplatePartialSpecializationDecl));
1198 VarTemplatePartialSpecializationDecl *Result =
1199 new (Mem) VarTemplatePartialSpecializationDecl();