blob: 7172fb7b487fc73ff239ade1f3e47b5051d2be99 [file] [log] [blame]
Sebastian Redle2530ec2009-10-23 22:13:42 +00001//===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
Douglas Gregorded2d7b2009-02-04 19:02:06 +00002//
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
Douglas Gregorded2d7b2009-02-04 19:02:06 +000014#include "clang/AST/DeclTemplate.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000015#include "clang/AST/ASTContext.h"
16#include "clang/AST/ASTMutationListener.h"
17#include "clang/AST/DeclCXX.h"
Douglas Gregor8bf42052009-02-09 18:46:07 +000018#include "clang/AST/Expr.h"
Douglas Gregor85759112011-01-04 02:33:52 +000019#include "clang/AST/ExprCXX.h"
John McCall0ad16662009-10-29 08:12:44 +000020#include "clang/AST/TypeLoc.h"
Douglas Gregorded2d7b2009-02-04 19:02:06 +000021#include "clang/Basic/IdentifierTable.h"
22#include "llvm/ADT/STLExtras.h"
Douglas Gregor1ccc8412010-11-07 23:05:16 +000023#include <memory>
Douglas Gregorded2d7b2009-02-04 19:02:06 +000024using namespace clang;
25
26//===----------------------------------------------------------------------===//
27// TemplateParameterList Implementation
28//===----------------------------------------------------------------------===//
29
Douglas Gregorcd72ba92009-02-06 22:42:48 +000030TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
31 SourceLocation LAngleLoc,
Douglas Gregorbe999392009-09-15 16:23:51 +000032 NamedDecl **Params, unsigned NumParams,
Douglas Gregorcd72ba92009-02-06 22:42:48 +000033 SourceLocation RAngleLoc)
34 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
Richard Smith1fde8ec2012-09-07 02:06:42 +000035 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 }
Douglas Gregorded2d7b2009-02-04 19:02:06 +000054}
55
56TemplateParameterList *
Jay Foad39c79802011-01-12 09:06:06 +000057TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
Douglas Gregorbe999392009-09-15 16:23:51 +000058 SourceLocation LAngleLoc, NamedDecl **Params,
Douglas Gregorcd72ba92009-02-06 22:42:48 +000059 unsigned NumParams, SourceLocation RAngleLoc) {
Douglas Gregorbe999392009-09-15 16:23:51 +000060 unsigned Size = sizeof(TemplateParameterList)
61 + sizeof(NamedDecl *) * NumParams;
Richard Smith426f7852012-08-16 22:51:34 +000062 unsigned Align = std::max(llvm::alignOf<TemplateParameterList>(),
63 llvm::alignOf<NamedDecl*>());
Douglas Gregorded2d7b2009-02-04 19:02:06 +000064 void *Mem = C.Allocate(Size, Align);
Mike Stump11289f42009-09-09 15:08:12 +000065 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
Douglas Gregorcd72ba92009-02-06 22:42:48 +000066 NumParams, RAngleLoc);
Douglas Gregorded2d7b2009-02-04 19:02:06 +000067}
68
Douglas Gregorf8f86832009-02-11 18:16:40 +000069unsigned TemplateParameterList::getMinRequiredArguments() const {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000070 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
Douglas Gregorf8f86832009-02-11 18:16:40 +000081 break;
Douglas Gregor0231d8d2011-01-19 20:10:05 +000082 }
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;
Douglas Gregorf8f86832009-02-11 18:16:40 +000095 }
Douglas Gregor0231d8d2011-01-19 20:10:05 +000096
Douglas Gregorf8f86832009-02-11 18:16:40 +000097 return NumRequiredArgs;
98}
99
Douglas Gregor21610382009-10-29 00:04:11 +0000100unsigned 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
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000115static 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
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000127//===----------------------------------------------------------------------===//
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000128// RedeclarableTemplateDecl Implementation
129//===----------------------------------------------------------------------===//
130
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000131RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000132 if (Common)
133 return Common;
134
135 // Walk the previous-declaration chain until we either find a declaration
136 // with a common pointer or we run out of previous declarations.
137 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
138 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
139 Prev = Prev->getPreviousDecl()) {
140 if (Prev->Common) {
141 Common = Prev->Common;
142 break;
Douglas Gregor68444de2012-01-14 15:13:49 +0000143 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000144
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000145 PrevDecls.push_back(Prev);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000146 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000147
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000148 // If we never found a common pointer, allocate one now.
149 if (!Common) {
150 // FIXME: If any of the declarations is from an AST file, we probably
151 // need an update record to add the common data.
152
153 Common = newCommon(getASTContext());
154 }
155
156 // Update any previous declarations we saw with the common pointer.
157 for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I)
158 PrevDecls[I]->Common = Common;
159
Douglas Gregor68444de2012-01-14 15:13:49 +0000160 return Common;
Peter Collingbourne029fd692010-07-29 16:12:09 +0000161}
162
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000163template <class EntryType>
164typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
165RedeclarableTemplateDecl::findSpecializationImpl(
Chandler Carruthb41171b2012-05-03 23:49:05 +0000166 llvm::FoldingSetVector<EntryType> &Specs,
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000167 const TemplateArgument *Args, unsigned NumArgs,
168 void *&InsertPos) {
169 typedef SpecEntryTraits<EntryType> SETraits;
170 llvm::FoldingSetNodeID ID;
171 EntryType::Profile(ID,Args,NumArgs, getASTContext());
172 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
Douglas Gregorec9fd132012-01-14 16:38:05 +0000173 return Entry ? SETraits::getMostRecentDecl(Entry) : 0;
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000174}
175
Douglas Gregor43669f82011-03-05 17:54:25 +0000176/// \brief Generate the injected template arguments for the given template
177/// parameter list, e.g., for the injected-class-name of a class template.
178static 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())
David Blaikie7a30dc52013-02-21 01:47:18 +0000188 ArgType = Context.getPackExpansionType(ArgType, None);
David Blaikie05785d12013-02-20 22:23:23 +0000189
Douglas Gregor43669f82011-03-05 17:54:25 +0000190 Arg = TemplateArgument(ArgType);
191 } else if (NonTypeTemplateParmDecl *NTTP =
192 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
John McCall113bee02012-03-10 09:33:50 +0000193 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
Douglas Gregor43669f82011-03-05 17:54:25 +0000194 NTTP->getType().getNonLValueExprType(Context),
195 Expr::getValueKindForType(NTTP->getType()),
196 NTTP->getLocation());
197
198 if (NTTP->isParameterPack())
David Blaikie7a30dc52013-02-21 01:47:18 +0000199 E = new (Context) PackExpansionExpr(Context.DependentTy, E,
200 NTTP->getLocation(), None);
Douglas Gregor43669f82011-03-05 17:54:25 +0000201 Arg = TemplateArgument(E);
202 } else {
203 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
204 if (TTP->isParameterPack())
David Blaikie05785d12013-02-20 22:23:23 +0000205 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
Douglas Gregor43669f82011-03-05 17:54:25 +0000206 else
207 Arg = TemplateArgument(TemplateName(TTP));
208 }
209
210 if ((*Param)->isTemplateParameterPack())
211 Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
212
213 *Args++ = Arg;
214 }
215}
216
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000217//===----------------------------------------------------------------------===//
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000218// FunctionTemplateDecl Implementation
219//===----------------------------------------------------------------------===//
220
Douglas Gregor1a809332010-05-23 18:26:36 +0000221void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
222 static_cast<Common *>(Ptr)->~Common();
223}
224
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000225FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
226 DeclContext *DC,
227 SourceLocation L,
228 DeclarationName Name,
Douglas Gregor8f5d4422009-06-29 20:59:39 +0000229 TemplateParameterList *Params,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000230 NamedDecl *Decl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000231 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000232 return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
233}
234
Douglas Gregor72172e92012-01-05 21:55:30 +0000235FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
236 unsigned ID) {
237 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FunctionTemplateDecl));
238 return new (Mem) FunctionTemplateDecl(0, SourceLocation(), DeclarationName(),
239 0, 0);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000240}
241
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000242RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000243FunctionTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000244 Common *CommonPtr = new (C) Common;
245 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000246 return CommonPtr;
247}
248
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000249void 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]);
257 }
258}
259
260llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
261FunctionTemplateDecl::getSpecializations() const {
262 LoadLazySpecializations();
263 return getCommonPtr()->Specializations;
264}
265
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000266FunctionDecl *
267FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
268 unsigned NumArgs, void *&InsertPos) {
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000269 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000270}
271
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000272void FunctionTemplateDecl::addSpecialization(
273 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
Douglas Gregorce9978f2012-03-28 14:34:23 +0000274 if (InsertPos)
275 getSpecializations().InsertNode(Info, InsertPos);
276 else
277 getSpecializations().GetOrInsertNode(Info);
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000278 if (ASTMutationListener *L = getASTMutationListener())
279 L->AddedCXXTemplateSpecialization(this, Info->Function);
280}
281
Richard Smith841d8b22013-05-17 03:04:50 +0000282ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
Douglas Gregor43669f82011-03-05 17:54:25 +0000283 TemplateParameterList *Params = getTemplateParameters();
284 Common *CommonPtr = getCommonPtr();
285 if (!CommonPtr->InjectedArgs) {
286 CommonPtr->InjectedArgs
Richard Smith841d8b22013-05-17 03:04:50 +0000287 = new (getASTContext()) TemplateArgument[Params->size()];
288 GenerateInjectedTemplateArgs(getASTContext(), Params,
Douglas Gregor43669f82011-03-05 17:54:25 +0000289 CommonPtr->InjectedArgs);
290 }
Richard Smith841d8b22013-05-17 03:04:50 +0000291
292 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
Douglas Gregor43669f82011-03-05 17:54:25 +0000293}
294
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000295//===----------------------------------------------------------------------===//
296// ClassTemplateDecl Implementation
297//===----------------------------------------------------------------------===//
298
Douglas Gregor1a809332010-05-23 18:26:36 +0000299void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
300 static_cast<Common *>(Ptr)->~Common();
301}
302
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000303ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
304 DeclContext *DC,
305 SourceLocation L,
306 DeclarationName Name,
307 TemplateParameterList *Params,
Douglas Gregor90a1a652009-03-19 17:26:29 +0000308 NamedDecl *Decl,
309 ClassTemplateDecl *PrevDecl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000310 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +0000311 ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
Rafael Espindola8db352d2013-10-17 15:37:26 +0000312 New->setPreviousDecl(PrevDecl);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +0000313 return New;
Douglas Gregor90a1a652009-03-19 17:26:29 +0000314}
315
Douglas Gregor72172e92012-01-05 21:55:30 +0000316ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
317 unsigned ID) {
318 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ClassTemplateDecl));
319 return new (Mem) ClassTemplateDecl(EmptyShell());
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000320}
321
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000322void ClassTemplateDecl::LoadLazySpecializations() const {
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000323 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]);
330 }
331}
332
Chandler Carruthb41171b2012-05-03 23:49:05 +0000333llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000334ClassTemplateDecl::getSpecializations() const {
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000335 LoadLazySpecializations();
336 return getCommonPtr()->Specializations;
337}
338
Chandler Carruthb41171b2012-05-03 23:49:05 +0000339llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000340ClassTemplateDecl::getPartialSpecializations() {
341 LoadLazySpecializations();
342 return getCommonPtr()->PartialSpecializations;
343}
344
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000345RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000346ClassTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000347 Common *CommonPtr = new (C) Common;
348 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000349 return CommonPtr;
350}
351
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000352ClassTemplateSpecializationDecl *
353ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
354 unsigned NumArgs, void *&InsertPos) {
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000355 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000356}
357
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000358void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
359 void *InsertPos) {
Douglas Gregorce9978f2012-03-28 14:34:23 +0000360 if (InsertPos)
361 getSpecializations().InsertNode(D, InsertPos);
362 else {
363 ClassTemplateSpecializationDecl *Existing
364 = getSpecializations().GetOrInsertNode(D);
365 (void)Existing;
366 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
367 }
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000368 if (ASTMutationListener *L = getASTMutationListener())
369 L->AddedCXXTemplateSpecialization(this, D);
370}
371
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000372ClassTemplatePartialSpecializationDecl *
373ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
374 unsigned NumArgs,
375 void *&InsertPos) {
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000376 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
377 InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000378}
379
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000380void ClassTemplateDecl::AddPartialSpecialization(
381 ClassTemplatePartialSpecializationDecl *D,
382 void *InsertPos) {
Douglas Gregorce9978f2012-03-28 14:34:23 +0000383 if (InsertPos)
384 getPartialSpecializations().InsertNode(D, InsertPos);
385 else {
386 ClassTemplatePartialSpecializationDecl *Existing
387 = getPartialSpecializations().GetOrInsertNode(D);
388 (void)Existing;
389 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
390 }
391
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000392 if (ASTMutationListener *L = getASTMutationListener())
393 L->AddedCXXTemplateSpecialization(this, D);
394}
395
Douglas Gregor407e9612010-04-30 05:56:50 +0000396void ClassTemplateDecl::getPartialSpecializations(
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000397 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
Chandler Carruthb41171b2012-05-03 23:49:05 +0000398 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000399 = getPartialSpecializations();
Douglas Gregor407e9612010-04-30 05:56:50 +0000400 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +0000401 PS.reserve(PartialSpecs.size());
Chandler Carruthb41171b2012-05-03 23:49:05 +0000402 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregor407e9612010-04-30 05:56:50 +0000403 P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
Richard Smithb2f61b42013-08-22 23:27:37 +0000404 P != PEnd; ++P)
405 PS.push_back(P->getMostRecentDecl());
Douglas Gregor407e9612010-04-30 05:56:50 +0000406}
407
Douglas Gregor15301382009-07-30 17:40:51 +0000408ClassTemplatePartialSpecializationDecl *
409ClassTemplateDecl::findPartialSpecialization(QualType T) {
410 ASTContext &Context = getASTContext();
Chandler Carruthb41171b2012-05-03 23:49:05 +0000411 using llvm::FoldingSetVector;
412 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregor15301382009-07-30 17:40:51 +0000413 partial_spec_iterator;
414 for (partial_spec_iterator P = getPartialSpecializations().begin(),
415 PEnd = getPartialSpecializations().end();
416 P != PEnd; ++P) {
John McCall2408e322010-04-27 00:57:59 +0000417 if (Context.hasSameType(P->getInjectedSpecializationType(), T))
Douglas Gregorec9fd132012-01-14 16:38:05 +0000418 return P->getMostRecentDecl();
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000419 }
420
421 return 0;
422}
423
424ClassTemplatePartialSpecializationDecl *
425ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
426 ClassTemplatePartialSpecializationDecl *D) {
427 Decl *DCanon = D->getCanonicalDecl();
Chandler Carruthb41171b2012-05-03 23:49:05 +0000428 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000429 P = getPartialSpecializations().begin(),
430 PEnd = getPartialSpecializations().end();
431 P != PEnd; ++P) {
432 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
Douglas Gregorec9fd132012-01-14 16:38:05 +0000433 return P->getMostRecentDecl();
Douglas Gregor15301382009-07-30 17:40:51 +0000434 }
Mike Stump11289f42009-09-09 15:08:12 +0000435
Douglas Gregor15301382009-07-30 17:40:51 +0000436 return 0;
437}
438
John McCalle78aac42010-03-10 03:28:59 +0000439QualType
Douglas Gregor9961ce92010-07-08 18:37:38 +0000440ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000441 Common *CommonPtr = getCommonPtr();
Douglas Gregore362cea2009-05-10 22:57:19 +0000442 if (!CommonPtr->InjectedClassNameType.isNull())
443 return CommonPtr->InjectedClassNameType;
444
Douglas Gregor8092e802010-12-23 16:00:30 +0000445 // 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
451 // pack.
Douglas Gregor9961ce92010-07-08 18:37:38 +0000452 ASTContext &Context = getASTContext();
Douglas Gregore362cea2009-05-10 22:57:19 +0000453 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000454 SmallVector<TemplateArgument, 16> TemplateArgs;
Douglas Gregor43669f82011-03-05 17:54:25 +0000455 TemplateArgs.resize(Params->size());
456 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
Douglas Gregore362cea2009-05-10 22:57:19 +0000457 CommonPtr->InjectedClassNameType
Douglas Gregora8e02e72009-07-28 23:00:59 +0000458 = Context.getTemplateSpecializationType(TemplateName(this),
Douglas Gregore362cea2009-05-10 22:57:19 +0000459 &TemplateArgs[0],
Douglas Gregora8e02e72009-07-28 23:00:59 +0000460 TemplateArgs.size());
Douglas Gregore362cea2009-05-10 22:57:19 +0000461 return CommonPtr->InjectedClassNameType;
462}
463
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000464//===----------------------------------------------------------------------===//
465// TemplateTypeParm Allocation/Deallocation Method Implementations
466//===----------------------------------------------------------------------===//
467
468TemplateTypeParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000469TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000470 SourceLocation KeyLoc, SourceLocation NameLoc,
471 unsigned D, unsigned P, IdentifierInfo *Id,
472 bool Typename, bool ParameterPack) {
Chandler Carruth08836322011-05-01 00:51:33 +0000473 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();
477 return TTPDecl;
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000478}
479
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000480TemplateTypeParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000481TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
482 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTypeParmDecl));
483 return new (Mem) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(),
484 0, false);
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000485}
486
John McCall0ad16662009-10-29 08:12:44 +0000487SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara23485e02011-03-04 12:42:03 +0000488 return hasDefaultArgument()
489 ? DefaultArgument->getTypeLoc().getBeginLoc()
490 : SourceLocation();
491}
492
493SourceRange TemplateTypeParmDecl::getSourceRange() const {
494 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000495 return SourceRange(getLocStart(),
Abramo Bagnara23485e02011-03-04 12:42:03 +0000496 DefaultArgument->getTypeLoc().getEndLoc());
497 else
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000498 return TypeDecl::getSourceRange();
John McCall0ad16662009-10-29 08:12:44 +0000499}
500
Douglas Gregor21610382009-10-29 00:04:11 +0000501unsigned TemplateTypeParmDecl::getDepth() const {
502 return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
503}
504
505unsigned TemplateTypeParmDecl::getIndex() const {
506 return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
507}
508
Chandler Carruth08836322011-05-01 00:51:33 +0000509bool TemplateTypeParmDecl::isParameterPack() const {
510 return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack();
511}
512
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000513//===----------------------------------------------------------------------===//
514// NonTypeTemplateParmDecl Method Implementations
515//===----------------------------------------------------------------------===//
516
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000517NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000518 SourceLocation StartLoc,
519 SourceLocation IdLoc,
520 unsigned D, unsigned P,
521 IdentifierInfo *Id,
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000522 QualType T,
523 TypeSourceInfo *TInfo,
524 const QualType *ExpandedTypes,
525 unsigned NumExpandedTypes,
526 TypeSourceInfo **ExpandedTInfos)
Abramo Bagnaradff19302011-03-08 08:55:46 +0000527 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000528 TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
529 ParameterPack(true), ExpandedParameterPack(true),
530 NumExpandedTypes(NumExpandedTypes)
531{
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];
537 }
538 }
539}
540
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000541NonTypeTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000542NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000543 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);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000549}
550
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000551NonTypeTemplateParmDecl *
552NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000553 SourceLocation StartLoc, SourceLocation IdLoc,
554 unsigned D, unsigned P,
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000555 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);
Abramo Bagnaradff19302011-03-08 08:55:46 +0000563 return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc,
564 D, P, Id, T, TInfo,
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000565 ExpandedTypes, NumExpandedTypes,
566 ExpandedTInfos);
567}
568
Douglas Gregor72172e92012-01-05 21:55:30 +0000569NonTypeTemplateParmDecl *
570NonTypeTemplateParmDecl::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);
575}
576
577NonTypeTemplateParmDecl *
578NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
579 unsigned NumExpandedTypes) {
580 unsigned Size = sizeof(NonTypeTemplateParmDecl)
581 + NumExpandedTypes * 2 * sizeof(void*);
582
583 void *Mem = AllocateDeserializedDecl(C, ID, Size);
584 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
585 SourceLocation(), 0, 0, 0,
586 QualType(), 0, 0, NumExpandedTypes,
587 0);
588}
589
John McCallf4cd4f92011-02-09 01:13:10 +0000590SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnarae15d5532011-03-04 11:03:48 +0000591 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraea947882011-03-08 16:41:52 +0000592 return SourceRange(getOuterLocStart(),
593 getDefaultArgument()->getSourceRange().getEnd());
594 return DeclaratorDecl::getSourceRange();
John McCallf4cd4f92011-02-09 01:13:10 +0000595}
596
Douglas Gregordba32632009-02-10 19:49:53 +0000597SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara656e3002010-06-09 09:26:05 +0000598 return hasDefaultArgument()
599 ? getDefaultArgument()->getSourceRange().getBegin()
600 : SourceLocation();
Douglas Gregordba32632009-02-10 19:49:53 +0000601}
602
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000603//===----------------------------------------------------------------------===//
604// TemplateTemplateParmDecl Method Implementations
605//===----------------------------------------------------------------------===//
606
David Blaikie68e081d2011-12-20 02:48:34 +0000607void TemplateTemplateParmDecl::anchor() { }
608
Richard Smith1fde8ec2012-09-07 02:06:42 +0000609TemplateTemplateParmDecl::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) {
617 if (Expansions)
618 std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
619 sizeof(TemplateParameterList*) * NumExpandedParams);
620}
621
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000622TemplateTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000623TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000624 SourceLocation L, unsigned D, unsigned P,
Douglas Gregorf5500772011-01-05 15:48:55 +0000625 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000626 TemplateParameterList *Params) {
Douglas Gregorf5500772011-01-05 15:48:55 +0000627 return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
628 Params);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000629}
630
Douglas Gregor72172e92012-01-05 21:55:30 +0000631TemplateTemplateParmDecl *
Richard Smith1fde8ec2012-09-07 02:06:42 +0000632TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
633 SourceLocation L, unsigned D, unsigned P,
634 IdentifierInfo *Id,
635 TemplateParameterList *Params,
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000636 ArrayRef<TemplateParameterList *> Expansions) {
Richard Smith1fde8ec2012-09-07 02:06:42 +0000637 void *Mem = C.Allocate(sizeof(TemplateTemplateParmDecl) +
638 sizeof(TemplateParameterList*) * Expansions.size());
639 return new (Mem) TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
640 Expansions.size(),
641 Expansions.data());
642}
643
644TemplateTemplateParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000645TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
646 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTemplateParmDecl));
647 return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, false,
648 0, 0);
649}
650
Richard Smith1fde8ec2012-09-07 02:06:42 +0000651TemplateTemplateParmDecl *
652TemplateTemplateParmDecl::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,
658 NumExpansions, 0);
659}
660
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000661//===----------------------------------------------------------------------===//
Douglas Gregord002c7b2009-05-11 23:53:27 +0000662// TemplateArgumentList Implementation
663//===----------------------------------------------------------------------===//
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000664TemplateArgumentList *
665TemplateArgumentList::CreateCopy(ASTContext &Context,
666 const TemplateArgument *Args,
667 unsigned NumArgs) {
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);
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000676}
677
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000678FunctionTemplateSpecializationInfo *
679FunctionTemplateSpecializationInfo::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);
689
690 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
691 TemplateArgs,
692 ArgsAsWritten,
693 POI);
694}
695
Douglas Gregord002c7b2009-05-11 23:53:27 +0000696//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000697// TemplateDecl Implementation
698//===----------------------------------------------------------------------===//
699
700void TemplateDecl::anchor() { }
701
702//===----------------------------------------------------------------------===//
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000703// ClassTemplateSpecializationDecl Implementation
704//===----------------------------------------------------------------------===//
705ClassTemplateSpecializationDecl::
Douglas Gregore9029562010-05-06 00:28:52 +0000706ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000707 DeclContext *DC, SourceLocation StartLoc,
708 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000709 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000710 const TemplateArgument *Args,
711 unsigned NumArgs,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000712 ClassTemplateSpecializationDecl *PrevDecl)
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000713 : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000714 SpecializedTemplate->getIdentifier(),
715 PrevDecl),
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000716 SpecializedTemplate(SpecializedTemplate),
Abramo Bagnara8075c852010-06-12 07:44:57 +0000717 ExplicitInfo(0),
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000718 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
Douglas Gregord002c7b2009-05-11 23:53:27 +0000719 SpecializationKind(TSK_Undeclared) {
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000720}
Mike Stump11289f42009-09-09 15:08:12 +0000721
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000722ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000723 : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0),
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000724 ExplicitInfo(0),
725 SpecializationKind(TSK_Undeclared) {
726}
727
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000728ClassTemplateSpecializationDecl *
Douglas Gregore9029562010-05-06 00:28:52 +0000729ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000730 DeclContext *DC,
731 SourceLocation StartLoc,
732 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000733 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000734 const TemplateArgument *Args,
735 unsigned NumArgs,
Douglas Gregor67a65642009-02-17 23:15:12 +0000736 ClassTemplateSpecializationDecl *PrevDecl) {
Douglas Gregor67a65642009-02-17 23:15:12 +0000737 ClassTemplateSpecializationDecl *Result
Mike Stump11289f42009-09-09 15:08:12 +0000738 = new (Context)ClassTemplateSpecializationDecl(Context,
Douglas Gregor2373c592009-05-31 09:31:02 +0000739 ClassTemplateSpecialization,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000740 TK, DC, StartLoc, IdLoc,
Douglas Gregord002c7b2009-05-11 23:53:27 +0000741 SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000742 Args, NumArgs,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000743 PrevDecl);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000744 Result->MayHaveOutOfDateDef = false;
745
Douglas Gregor67a65642009-02-17 23:15:12 +0000746 Context.getTypeDeclType(Result, PrevDecl);
747 return Result;
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000748}
Douglas Gregor2373c592009-05-31 09:31:02 +0000749
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000750ClassTemplateSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000751ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
752 unsigned ID) {
753 void *Mem = AllocateDeserializedDecl(C, ID,
754 sizeof(ClassTemplateSpecializationDecl));
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000755 ClassTemplateSpecializationDecl *Result =
756 new (Mem) ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
757 Result->MayHaveOutOfDateDef = false;
758 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000759}
760
Benjamin Kramer9170e912013-02-22 15:46:01 +0000761void ClassTemplateSpecializationDecl::getNameForDiagnostic(
762 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
763 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000764
765 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Benjamin Kramer9170e912013-02-22 15:46:01 +0000766 TemplateSpecializationType::PrintTemplateArgumentList(
767 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000768}
769
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000770ClassTemplateDecl *
Mike Stump11289f42009-09-09 15:08:12 +0000771ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
772 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000773 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
774 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
775 return SpecializedTemplate.get<ClassTemplateDecl*>();
776}
777
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000778SourceRange
779ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000780 if (ExplicitInfo) {
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000781 SourceLocation Begin = getTemplateKeywordLoc();
782 if (Begin.isValid()) {
783 // Here we have an explicit (partial) specialization or instantiation.
784 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
785 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
786 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
787 if (getExternLoc().isValid())
788 Begin = getExternLoc();
789 SourceLocation End = getRBraceLoc();
790 if (End.isInvalid())
791 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
792 return SourceRange(Begin, End);
793 }
794 // An implicit instantiation of a class template partial specialization
795 // uses ExplicitInfo to record the TypeAsWritten, but the source
796 // locations should be retrieved from the instantiation pattern.
797 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
798 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
799 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
800 assert(inst_from != 0);
801 return inst_from->getSourceRange();
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000802 }
803 else {
804 // No explicit info available.
805 llvm::PointerUnion<ClassTemplateDecl *,
806 ClassTemplatePartialSpecializationDecl *>
807 inst_from = getInstantiatedFrom();
808 if (inst_from.isNull())
809 return getSpecializedTemplate()->getSourceRange();
810 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
811 return ctd->getSourceRange();
812 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
813 ->getSourceRange();
814 }
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000815}
816
Douglas Gregor2373c592009-05-31 09:31:02 +0000817//===----------------------------------------------------------------------===//
818// ClassTemplatePartialSpecializationDecl Implementation
819//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000820void ClassTemplatePartialSpecializationDecl::anchor() { }
821
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000822ClassTemplatePartialSpecializationDecl::
823ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000824 DeclContext *DC,
825 SourceLocation StartLoc,
826 SourceLocation IdLoc,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000827 TemplateParameterList *Params,
828 ClassTemplateDecl *SpecializedTemplate,
829 const TemplateArgument *Args,
830 unsigned NumArgs,
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000831 const ASTTemplateArgumentListInfo *ArgInfos,
Richard Smithb2f61b42013-08-22 23:27:37 +0000832 ClassTemplatePartialSpecializationDecl *PrevDecl)
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000833 : ClassTemplateSpecializationDecl(Context,
834 ClassTemplatePartialSpecialization,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000835 TK, DC, StartLoc, IdLoc,
836 SpecializedTemplate,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000837 Args, NumArgs, PrevDecl),
838 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Richard Smithb2f61b42013-08-22 23:27:37 +0000839 InstantiatedFromMember(0, false)
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000840{
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000841 AdoptTemplateParameterList(Params, this);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000842}
843
Douglas Gregor2373c592009-05-31 09:31:02 +0000844ClassTemplatePartialSpecializationDecl *
845ClassTemplatePartialSpecializationDecl::
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000846Create(ASTContext &Context, TagKind TK,DeclContext *DC,
847 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregor2373c592009-05-31 09:31:02 +0000848 TemplateParameterList *Params,
849 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000850 const TemplateArgument *Args,
851 unsigned NumArgs,
John McCall6b51f282009-11-23 01:53:49 +0000852 const TemplateArgumentListInfo &ArgInfos,
John McCalle78aac42010-03-10 03:28:59 +0000853 QualType CanonInjectedType,
Richard Smithb2f61b42013-08-22 23:27:37 +0000854 ClassTemplatePartialSpecializationDecl *PrevDecl) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000855 const ASTTemplateArgumentListInfo *ASTArgInfos =
856 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
John McCall0ad16662009-10-29 08:12:44 +0000857
Douglas Gregor2373c592009-05-31 09:31:02 +0000858 ClassTemplatePartialSpecializationDecl *Result
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000859 = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC,
860 StartLoc, IdLoc,
861 Params,
Douglas Gregor2373c592009-05-31 09:31:02 +0000862 SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000863 Args, NumArgs,
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000864 ASTArgInfos,
Richard Smithb2f61b42013-08-22 23:27:37 +0000865 PrevDecl);
Douglas Gregor2373c592009-05-31 09:31:02 +0000866 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000867 Result->MayHaveOutOfDateDef = false;
John McCalle78aac42010-03-10 03:28:59 +0000868
869 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregor2373c592009-05-31 09:31:02 +0000870 return Result;
871}
John McCall11083da2009-09-16 22:47:08 +0000872
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000873ClassTemplatePartialSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000874ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
875 unsigned ID) {
876 void *Mem = AllocateDeserializedDecl(C, ID,
877 sizeof(ClassTemplatePartialSpecializationDecl));
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000878 ClassTemplatePartialSpecializationDecl *Result
879 = new (Mem) ClassTemplatePartialSpecializationDecl();
880 Result->MayHaveOutOfDateDef = false;
881 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000882}
883
John McCall11083da2009-09-16 22:47:08 +0000884//===----------------------------------------------------------------------===//
885// FriendTemplateDecl Implementation
886//===----------------------------------------------------------------------===//
887
David Blaikie68e081d2011-12-20 02:48:34 +0000888void FriendTemplateDecl::anchor() { }
889
John McCall11083da2009-09-16 22:47:08 +0000890FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
891 DeclContext *DC,
892 SourceLocation L,
893 unsigned NParams,
894 TemplateParameterList **Params,
895 FriendUnion Friend,
896 SourceLocation FLoc) {
897 FriendTemplateDecl *Result
898 = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
899 return Result;
900}
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000901
Douglas Gregor72172e92012-01-05 21:55:30 +0000902FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
903 unsigned ID) {
904 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FriendTemplateDecl));
905 return new (Mem) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000906}
Richard Smith3f1b5d02011-05-05 21:57:07 +0000907
908//===----------------------------------------------------------------------===//
909// TypeAliasTemplateDecl Implementation
910//===----------------------------------------------------------------------===//
911
912TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
913 DeclContext *DC,
914 SourceLocation L,
915 DeclarationName Name,
916 TemplateParameterList *Params,
917 NamedDecl *Decl) {
918 AdoptTemplateParameterList(Params, DC);
919 return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl);
920}
921
Douglas Gregor72172e92012-01-05 21:55:30 +0000922TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
923 unsigned ID) {
924 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasTemplateDecl));
925 return new (Mem) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(),
926 0, 0);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000927}
928
929void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
930 static_cast<Common *>(Ptr)->~Common();
931}
932RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000933TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3f1b5d02011-05-05 21:57:07 +0000934 Common *CommonPtr = new (C) Common;
935 C.AddDeallocation(DeallocateCommon, CommonPtr);
936 return CommonPtr;
937}
938
David Blaikie68e081d2011-12-20 02:48:34 +0000939//===----------------------------------------------------------------------===//
940// ClassScopeFunctionSpecializationDecl Implementation
941//===----------------------------------------------------------------------===//
942
943void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor72172e92012-01-05 21:55:30 +0000944
945ClassScopeFunctionSpecializationDecl *
946ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
947 unsigned ID) {
948 void *Mem = AllocateDeserializedDecl(C, ID,
949 sizeof(ClassScopeFunctionSpecializationDecl));
Nico Weber7b5a7162012-06-25 17:21:05 +0000950 return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0,
951 false, TemplateArgumentListInfo());
Douglas Gregor72172e92012-01-05 21:55:30 +0000952}
Larisse Voufo39a1e502013-08-06 01:03:05 +0000953
954//===----------------------------------------------------------------------===//
955// VarTemplateDecl Implementation
956//===----------------------------------------------------------------------===//
957
958void VarTemplateDecl::DeallocateCommon(void *Ptr) {
959 static_cast<Common *>(Ptr)->~Common();
960}
961
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000962VarTemplateDecl *VarTemplateDecl::getDefinition() {
963 VarTemplateDecl *CurD = this;
964 while (CurD) {
965 if (CurD->isThisDeclarationADefinition())
966 return CurD;
967 CurD = CurD->getPreviousDecl();
968 }
969 return 0;
970}
971
Larisse Voufo39a1e502013-08-06 01:03:05 +0000972VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
973 SourceLocation L, DeclarationName Name,
974 TemplateParameterList *Params,
975 NamedDecl *Decl,
976 VarTemplateDecl *PrevDecl) {
977 VarTemplateDecl *New = new (C) VarTemplateDecl(DC, L, Name, Params, Decl);
Rafael Espindola8db352d2013-10-17 15:37:26 +0000978 New->setPreviousDecl(PrevDecl);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000979 return New;
980}
981
982VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
983 unsigned ID) {
984 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(VarTemplateDecl));
985 return new (Mem) VarTemplateDecl(EmptyShell());
986}
987
Larisse Voufo30616382013-08-23 22:21:36 +0000988// TODO: Unify accross class, function and variable templates?
989// May require moving this and Common to RedeclarableTemplateDecl.
Larisse Voufo39a1e502013-08-06 01:03:05 +0000990void 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]);
998 }
999}
1000
1001llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1002VarTemplateDecl::getSpecializations() const {
1003 LoadLazySpecializations();
1004 return getCommonPtr()->Specializations;
1005}
1006
1007llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1008VarTemplateDecl::getPartialSpecializations() {
1009 LoadLazySpecializations();
1010 return getCommonPtr()->PartialSpecializations;
1011}
1012
1013RedeclarableTemplateDecl::CommonBase *
1014VarTemplateDecl::newCommon(ASTContext &C) const {
1015 Common *CommonPtr = new (C) Common;
1016 C.AddDeallocation(DeallocateCommon, CommonPtr);
1017 return CommonPtr;
1018}
1019
1020VarTemplateSpecializationDecl *
1021VarTemplateDecl::findSpecialization(const TemplateArgument *Args,
1022 unsigned NumArgs, void *&InsertPos) {
1023 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
1024}
1025
1026void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1027 void *InsertPos) {
1028 if (InsertPos)
1029 getSpecializations().InsertNode(D, InsertPos);
1030 else {
1031 VarTemplateSpecializationDecl *Existing =
1032 getSpecializations().GetOrInsertNode(D);
1033 (void)Existing;
1034 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1035 }
1036 if (ASTMutationListener *L = getASTMutationListener())
1037 L->AddedCXXTemplateSpecialization(this, D);
1038}
1039
1040VarTemplatePartialSpecializationDecl *
1041VarTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
1042 unsigned NumArgs, void *&InsertPos) {
1043 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
1044 InsertPos);
1045}
1046
1047void VarTemplateDecl::AddPartialSpecialization(
1048 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1049 if (InsertPos)
1050 getPartialSpecializations().InsertNode(D, InsertPos);
1051 else {
1052 VarTemplatePartialSpecializationDecl *Existing =
1053 getPartialSpecializations().GetOrInsertNode(D);
1054 (void)Existing;
1055 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1056 }
1057
1058 if (ASTMutationListener *L = getASTMutationListener())
1059 L->AddedCXXTemplateSpecialization(this, D);
1060}
1061
1062void VarTemplateDecl::getPartialSpecializations(
1063 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1064 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1065 getPartialSpecializations();
1066 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +00001067 PS.reserve(PartialSpecs.size());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001068 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1069 P = PartialSpecs.begin(),
1070 PEnd = PartialSpecs.end();
Richard Smithb2f61b42013-08-22 23:27:37 +00001071 P != PEnd; ++P)
1072 PS.push_back(P->getMostRecentDecl());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001073}
1074
1075VarTemplatePartialSpecializationDecl *
1076VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1077 VarTemplatePartialSpecializationDecl *D) {
1078 Decl *DCanon = D->getCanonicalDecl();
1079 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1080 P = getPartialSpecializations().begin(),
1081 PEnd = getPartialSpecializations().end();
1082 P != PEnd; ++P) {
1083 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1084 return P->getMostRecentDecl();
1085 }
1086
1087 return 0;
1088}
1089
1090//===----------------------------------------------------------------------===//
1091// VarTemplateSpecializationDecl Implementation
1092//===----------------------------------------------------------------------===//
1093VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1094 ASTContext &Context, Kind DK, DeclContext *DC, SourceLocation StartLoc,
1095 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1096 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1097 unsigned NumArgs)
1098 : VarDecl(DK, DC, StartLoc, IdLoc, SpecializedTemplate->getIdentifier(), T,
1099 TInfo, S),
1100 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(0),
1101 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
1102 SpecializationKind(TSK_Undeclared) {}
1103
1104VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK)
1105 : VarDecl(DK, 0, SourceLocation(), SourceLocation(), 0, QualType(), 0,
1106 SC_None),
1107 ExplicitInfo(0), SpecializationKind(TSK_Undeclared) {}
1108
1109VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1110 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1111 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1112 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1113 unsigned NumArgs) {
1114 VarTemplateSpecializationDecl *Result = new (Context)
1115 VarTemplateSpecializationDecl(Context, VarTemplateSpecialization, DC,
1116 StartLoc, IdLoc, SpecializedTemplate, T,
1117 TInfo, S, Args, NumArgs);
1118 return Result;
1119}
1120
1121VarTemplateSpecializationDecl *
1122VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1123 void *Mem =
1124 AllocateDeserializedDecl(C, ID, sizeof(VarTemplateSpecializationDecl));
1125 VarTemplateSpecializationDecl *Result =
1126 new (Mem) VarTemplateSpecializationDecl(VarTemplateSpecialization);
1127 return Result;
1128}
1129
1130void VarTemplateSpecializationDecl::getNameForDiagnostic(
1131 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1132 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1133
1134 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1135 TemplateSpecializationType::PrintTemplateArgumentList(
1136 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
1137}
1138
1139VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1140 if (SpecializedPartialSpecialization *PartialSpec =
1141 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1142 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1143 return SpecializedTemplate.get<VarTemplateDecl *>();
1144}
1145
1146void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1147 const TemplateArgumentListInfo &ArgsInfo) {
1148 unsigned N = ArgsInfo.size();
1149 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1150 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1151 for (unsigned I = 0; I != N; ++I)
1152 TemplateArgsInfo.addArgument(ArgsInfo[I]);
1153}
1154
1155//===----------------------------------------------------------------------===//
1156// VarTemplatePartialSpecializationDecl Implementation
1157//===----------------------------------------------------------------------===//
1158void VarTemplatePartialSpecializationDecl::anchor() {}
1159
1160VarTemplatePartialSpecializationDecl::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,
Richard Smithb2f61b42013-08-22 23:27:37 +00001165 const ASTTemplateArgumentListInfo *ArgInfos)
Larisse Voufo39a1e502013-08-06 01:03:05 +00001166 : VarTemplateSpecializationDecl(Context, VarTemplatePartialSpecialization,
1167 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1168 TInfo, S, Args, NumArgs),
1169 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Richard Smithb2f61b42013-08-22 23:27:37 +00001170 InstantiatedFromMember(0, false) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001171 // TODO: The template parameters should be in DC by now. Verify.
1172 // AdoptTemplateParameterList(Params, DC);
1173}
1174
1175VarTemplatePartialSpecializationDecl *
1176VarTemplatePartialSpecializationDecl::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,
Richard Smithb2f61b42013-08-22 23:27:37 +00001181 const TemplateArgumentListInfo &ArgInfos) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +00001182 const ASTTemplateArgumentListInfo *ASTArgInfos
1183 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001184
1185 VarTemplatePartialSpecializationDecl *Result =
1186 new (Context) VarTemplatePartialSpecializationDecl(
1187 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
Richard Smithb2f61b42013-08-22 23:27:37 +00001188 S, Args, NumArgs, ASTArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001189 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1190 return Result;
1191}
1192
1193VarTemplatePartialSpecializationDecl *
1194VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1195 unsigned ID) {
1196 void *Mem = AllocateDeserializedDecl(
1197 C, ID, sizeof(VarTemplatePartialSpecializationDecl));
1198 VarTemplatePartialSpecializationDecl *Result =
1199 new (Mem) VarTemplatePartialSpecializationDecl();
1200 return Result;
1201}