blob: 94f05e9c2f7172eaff28c4fd4e4ad39297e2b550 [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 {
Douglas Gregor68444de2012-01-14 15:13:49 +0000132 if (!Common) {
133 // Walk the previous-declaration chain until we either find a declaration
134 // with a common pointer or we run out of previous declarations.
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000135 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
136 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
Douglas Gregorec9fd132012-01-14 16:38:05 +0000137 Prev = Prev->getPreviousDecl()) {
Douglas Gregor68444de2012-01-14 15:13:49 +0000138 if (Prev->Common) {
139 Common = Prev->Common;
140 break;
141 }
142
143 PrevDecls.push_back(Prev);
144 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000145
Douglas Gregor68444de2012-01-14 15:13:49 +0000146 // If we never found a common pointer, allocate one now.
Douglas Gregor463c8e72012-01-14 15:30:55 +0000147 if (!Common) {
148 // FIXME: If any of the declarations is from an AST file, we probably
149 // need an update record to add the common data.
150
Douglas Gregor68444de2012-01-14 15:13:49 +0000151 Common = newCommon(getASTContext());
Douglas Gregor463c8e72012-01-14 15:30:55 +0000152 }
Douglas Gregor68444de2012-01-14 15:13:49 +0000153
154 // Update any previous declarations we saw with the common pointer.
155 for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I)
156 PrevDecls[I]->Common = Common;
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000157 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000158
Douglas Gregor68444de2012-01-14 15:13:49 +0000159 return Common;
Peter Collingbourne029fd692010-07-29 16:12:09 +0000160}
161
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000162template <class EntryType>
163typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
164RedeclarableTemplateDecl::findSpecializationImpl(
Chandler Carruthb41171b2012-05-03 23:49:05 +0000165 llvm::FoldingSetVector<EntryType> &Specs,
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000166 const TemplateArgument *Args, unsigned NumArgs,
167 void *&InsertPos) {
168 typedef SpecEntryTraits<EntryType> SETraits;
169 llvm::FoldingSetNodeID ID;
170 EntryType::Profile(ID,Args,NumArgs, getASTContext());
171 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
Douglas Gregorec9fd132012-01-14 16:38:05 +0000172 return Entry ? SETraits::getMostRecentDecl(Entry) : 0;
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000173}
174
Douglas Gregor43669f82011-03-05 17:54:25 +0000175/// \brief Generate the injected template arguments for the given template
176/// parameter list, e.g., for the injected-class-name of a class template.
177static void GenerateInjectedTemplateArgs(ASTContext &Context,
178 TemplateParameterList *Params,
179 TemplateArgument *Args) {
180 for (TemplateParameterList::iterator Param = Params->begin(),
181 ParamEnd = Params->end();
182 Param != ParamEnd; ++Param) {
183 TemplateArgument Arg;
184 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
185 QualType ArgType = Context.getTypeDeclType(TTP);
186 if (TTP->isParameterPack())
David Blaikie7a30dc52013-02-21 01:47:18 +0000187 ArgType = Context.getPackExpansionType(ArgType, None);
David Blaikie05785d12013-02-20 22:23:23 +0000188
Douglas Gregor43669f82011-03-05 17:54:25 +0000189 Arg = TemplateArgument(ArgType);
190 } else if (NonTypeTemplateParmDecl *NTTP =
191 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
John McCall113bee02012-03-10 09:33:50 +0000192 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
Douglas Gregor43669f82011-03-05 17:54:25 +0000193 NTTP->getType().getNonLValueExprType(Context),
194 Expr::getValueKindForType(NTTP->getType()),
195 NTTP->getLocation());
196
197 if (NTTP->isParameterPack())
David Blaikie7a30dc52013-02-21 01:47:18 +0000198 E = new (Context) PackExpansionExpr(Context.DependentTy, E,
199 NTTP->getLocation(), None);
Douglas Gregor43669f82011-03-05 17:54:25 +0000200 Arg = TemplateArgument(E);
201 } else {
202 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
203 if (TTP->isParameterPack())
David Blaikie05785d12013-02-20 22:23:23 +0000204 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
Douglas Gregor43669f82011-03-05 17:54:25 +0000205 else
206 Arg = TemplateArgument(TemplateName(TTP));
207 }
208
209 if ((*Param)->isTemplateParameterPack())
210 Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
211
212 *Args++ = Arg;
213 }
214}
215
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000216//===----------------------------------------------------------------------===//
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000217// FunctionTemplateDecl Implementation
218//===----------------------------------------------------------------------===//
219
Douglas Gregor1a809332010-05-23 18:26:36 +0000220void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
221 static_cast<Common *>(Ptr)->~Common();
222}
223
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000224FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
225 DeclContext *DC,
226 SourceLocation L,
227 DeclarationName Name,
Douglas Gregor8f5d4422009-06-29 20:59:39 +0000228 TemplateParameterList *Params,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000229 NamedDecl *Decl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000230 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000231 return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
232}
233
Douglas Gregor72172e92012-01-05 21:55:30 +0000234FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
235 unsigned ID) {
236 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FunctionTemplateDecl));
237 return new (Mem) FunctionTemplateDecl(0, SourceLocation(), DeclarationName(),
238 0, 0);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000239}
240
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000241RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000242FunctionTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000243 Common *CommonPtr = new (C) Common;
244 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000245 return CommonPtr;
246}
247
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000248void FunctionTemplateDecl::LoadLazySpecializations() const {
249 Common *CommonPtr = getCommonPtr();
250 if (CommonPtr->LazySpecializations) {
251 ASTContext &Context = getASTContext();
252 uint32_t *Specs = CommonPtr->LazySpecializations;
253 CommonPtr->LazySpecializations = 0;
254 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
255 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
256 }
257}
258
259llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
260FunctionTemplateDecl::getSpecializations() const {
261 LoadLazySpecializations();
262 return getCommonPtr()->Specializations;
263}
264
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000265FunctionDecl *
266FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
267 unsigned NumArgs, void *&InsertPos) {
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000268 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000269}
270
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000271void FunctionTemplateDecl::addSpecialization(
272 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
Douglas Gregorce9978f2012-03-28 14:34:23 +0000273 if (InsertPos)
274 getSpecializations().InsertNode(Info, InsertPos);
275 else
276 getSpecializations().GetOrInsertNode(Info);
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000277 if (ASTMutationListener *L = getASTMutationListener())
278 L->AddedCXXTemplateSpecialization(this, Info->Function);
279}
280
Richard Smith841d8b22013-05-17 03:04:50 +0000281ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
Douglas Gregor43669f82011-03-05 17:54:25 +0000282 TemplateParameterList *Params = getTemplateParameters();
283 Common *CommonPtr = getCommonPtr();
284 if (!CommonPtr->InjectedArgs) {
285 CommonPtr->InjectedArgs
Richard Smith841d8b22013-05-17 03:04:50 +0000286 = new (getASTContext()) TemplateArgument[Params->size()];
287 GenerateInjectedTemplateArgs(getASTContext(), Params,
Douglas Gregor43669f82011-03-05 17:54:25 +0000288 CommonPtr->InjectedArgs);
289 }
Richard Smith841d8b22013-05-17 03:04:50 +0000290
291 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
Douglas Gregor43669f82011-03-05 17:54:25 +0000292}
293
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000294//===----------------------------------------------------------------------===//
295// ClassTemplateDecl Implementation
296//===----------------------------------------------------------------------===//
297
Douglas Gregor1a809332010-05-23 18:26:36 +0000298void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
299 static_cast<Common *>(Ptr)->~Common();
300}
301
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000302ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
303 DeclContext *DC,
304 SourceLocation L,
305 DeclarationName Name,
306 TemplateParameterList *Params,
Douglas Gregor90a1a652009-03-19 17:26:29 +0000307 NamedDecl *Decl,
308 ClassTemplateDecl *PrevDecl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000309 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +0000310 ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000311 New->setPreviousDeclaration(PrevDecl);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +0000312 return New;
Douglas Gregor90a1a652009-03-19 17:26:29 +0000313}
314
Douglas Gregor72172e92012-01-05 21:55:30 +0000315ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
316 unsigned ID) {
317 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ClassTemplateDecl));
318 return new (Mem) ClassTemplateDecl(EmptyShell());
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000319}
320
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000321void ClassTemplateDecl::LoadLazySpecializations() const {
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000322 Common *CommonPtr = getCommonPtr();
323 if (CommonPtr->LazySpecializations) {
324 ASTContext &Context = getASTContext();
325 uint32_t *Specs = CommonPtr->LazySpecializations;
326 CommonPtr->LazySpecializations = 0;
327 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
328 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
329 }
330}
331
Chandler Carruthb41171b2012-05-03 23:49:05 +0000332llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000333ClassTemplateDecl::getSpecializations() const {
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000334 LoadLazySpecializations();
335 return getCommonPtr()->Specializations;
336}
337
Chandler Carruthb41171b2012-05-03 23:49:05 +0000338llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000339ClassTemplateDecl::getPartialSpecializations() {
340 LoadLazySpecializations();
341 return getCommonPtr()->PartialSpecializations;
342}
343
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000344RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000345ClassTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000346 Common *CommonPtr = new (C) Common;
347 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000348 return CommonPtr;
349}
350
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000351ClassTemplateSpecializationDecl *
352ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
353 unsigned NumArgs, void *&InsertPos) {
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000354 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000355}
356
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000357void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
358 void *InsertPos) {
Douglas Gregorce9978f2012-03-28 14:34:23 +0000359 if (InsertPos)
360 getSpecializations().InsertNode(D, InsertPos);
361 else {
362 ClassTemplateSpecializationDecl *Existing
363 = getSpecializations().GetOrInsertNode(D);
364 (void)Existing;
365 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
366 }
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000367 if (ASTMutationListener *L = getASTMutationListener())
368 L->AddedCXXTemplateSpecialization(this, D);
369}
370
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000371ClassTemplatePartialSpecializationDecl *
372ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
373 unsigned NumArgs,
374 void *&InsertPos) {
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000375 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
376 InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000377}
378
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000379void ClassTemplateDecl::AddPartialSpecialization(
380 ClassTemplatePartialSpecializationDecl *D,
381 void *InsertPos) {
Douglas Gregorce9978f2012-03-28 14:34:23 +0000382 if (InsertPos)
383 getPartialSpecializations().InsertNode(D, InsertPos);
384 else {
385 ClassTemplatePartialSpecializationDecl *Existing
386 = getPartialSpecializations().GetOrInsertNode(D);
387 (void)Existing;
388 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
389 }
390
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000391 if (ASTMutationListener *L = getASTMutationListener())
392 L->AddedCXXTemplateSpecialization(this, D);
393}
394
Douglas Gregor407e9612010-04-30 05:56:50 +0000395void ClassTemplateDecl::getPartialSpecializations(
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000396 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
Chandler Carruthb41171b2012-05-03 23:49:05 +0000397 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000398 = getPartialSpecializations();
Douglas Gregor407e9612010-04-30 05:56:50 +0000399 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +0000400 PS.reserve(PartialSpecs.size());
Chandler Carruthb41171b2012-05-03 23:49:05 +0000401 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregor407e9612010-04-30 05:56:50 +0000402 P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
Richard Smithb2f61b42013-08-22 23:27:37 +0000403 P != PEnd; ++P)
404 PS.push_back(P->getMostRecentDecl());
Douglas Gregor407e9612010-04-30 05:56:50 +0000405}
406
Douglas Gregor15301382009-07-30 17:40:51 +0000407ClassTemplatePartialSpecializationDecl *
408ClassTemplateDecl::findPartialSpecialization(QualType T) {
409 ASTContext &Context = getASTContext();
Chandler Carruthb41171b2012-05-03 23:49:05 +0000410 using llvm::FoldingSetVector;
411 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregor15301382009-07-30 17:40:51 +0000412 partial_spec_iterator;
413 for (partial_spec_iterator P = getPartialSpecializations().begin(),
414 PEnd = getPartialSpecializations().end();
415 P != PEnd; ++P) {
John McCall2408e322010-04-27 00:57:59 +0000416 if (Context.hasSameType(P->getInjectedSpecializationType(), T))
Douglas Gregorec9fd132012-01-14 16:38:05 +0000417 return P->getMostRecentDecl();
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000418 }
419
420 return 0;
421}
422
423ClassTemplatePartialSpecializationDecl *
424ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
425 ClassTemplatePartialSpecializationDecl *D) {
426 Decl *DCanon = D->getCanonicalDecl();
Chandler Carruthb41171b2012-05-03 23:49:05 +0000427 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000428 P = getPartialSpecializations().begin(),
429 PEnd = getPartialSpecializations().end();
430 P != PEnd; ++P) {
431 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
Douglas Gregorec9fd132012-01-14 16:38:05 +0000432 return P->getMostRecentDecl();
Douglas Gregor15301382009-07-30 17:40:51 +0000433 }
Mike Stump11289f42009-09-09 15:08:12 +0000434
Douglas Gregor15301382009-07-30 17:40:51 +0000435 return 0;
436}
437
John McCalle78aac42010-03-10 03:28:59 +0000438QualType
Douglas Gregor9961ce92010-07-08 18:37:38 +0000439ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000440 Common *CommonPtr = getCommonPtr();
Douglas Gregore362cea2009-05-10 22:57:19 +0000441 if (!CommonPtr->InjectedClassNameType.isNull())
442 return CommonPtr->InjectedClassNameType;
443
Douglas Gregor8092e802010-12-23 16:00:30 +0000444 // C++0x [temp.dep.type]p2:
445 // The template argument list of a primary template is a template argument
446 // list in which the nth template argument has the value of the nth template
447 // parameter of the class template. If the nth template parameter is a
448 // template parameter pack (14.5.3), the nth template argument is a pack
449 // expansion (14.5.3) whose pattern is the name of the template parameter
450 // pack.
Douglas Gregor9961ce92010-07-08 18:37:38 +0000451 ASTContext &Context = getASTContext();
Douglas Gregore362cea2009-05-10 22:57:19 +0000452 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000453 SmallVector<TemplateArgument, 16> TemplateArgs;
Douglas Gregor43669f82011-03-05 17:54:25 +0000454 TemplateArgs.resize(Params->size());
455 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
Douglas Gregore362cea2009-05-10 22:57:19 +0000456 CommonPtr->InjectedClassNameType
Douglas Gregora8e02e72009-07-28 23:00:59 +0000457 = Context.getTemplateSpecializationType(TemplateName(this),
Douglas Gregore362cea2009-05-10 22:57:19 +0000458 &TemplateArgs[0],
Douglas Gregora8e02e72009-07-28 23:00:59 +0000459 TemplateArgs.size());
Douglas Gregore362cea2009-05-10 22:57:19 +0000460 return CommonPtr->InjectedClassNameType;
461}
462
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000463//===----------------------------------------------------------------------===//
464// TemplateTypeParm Allocation/Deallocation Method Implementations
465//===----------------------------------------------------------------------===//
466
467TemplateTypeParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000468TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000469 SourceLocation KeyLoc, SourceLocation NameLoc,
470 unsigned D, unsigned P, IdentifierInfo *Id,
471 bool Typename, bool ParameterPack) {
Chandler Carruth08836322011-05-01 00:51:33 +0000472 TemplateTypeParmDecl *TTPDecl =
473 new (C) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
474 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
475 TTPDecl->TypeForDecl = TTPType.getTypePtr();
476 return TTPDecl;
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000477}
478
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000479TemplateTypeParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000480TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
481 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTypeParmDecl));
482 return new (Mem) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(),
483 0, false);
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000484}
485
John McCall0ad16662009-10-29 08:12:44 +0000486SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara23485e02011-03-04 12:42:03 +0000487 return hasDefaultArgument()
488 ? DefaultArgument->getTypeLoc().getBeginLoc()
489 : SourceLocation();
490}
491
492SourceRange TemplateTypeParmDecl::getSourceRange() const {
493 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000494 return SourceRange(getLocStart(),
Abramo Bagnara23485e02011-03-04 12:42:03 +0000495 DefaultArgument->getTypeLoc().getEndLoc());
496 else
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000497 return TypeDecl::getSourceRange();
John McCall0ad16662009-10-29 08:12:44 +0000498}
499
Douglas Gregor21610382009-10-29 00:04:11 +0000500unsigned TemplateTypeParmDecl::getDepth() const {
501 return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
502}
503
504unsigned TemplateTypeParmDecl::getIndex() const {
505 return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
506}
507
Chandler Carruth08836322011-05-01 00:51:33 +0000508bool TemplateTypeParmDecl::isParameterPack() const {
509 return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack();
510}
511
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000512//===----------------------------------------------------------------------===//
513// NonTypeTemplateParmDecl Method Implementations
514//===----------------------------------------------------------------------===//
515
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000516NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000517 SourceLocation StartLoc,
518 SourceLocation IdLoc,
519 unsigned D, unsigned P,
520 IdentifierInfo *Id,
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000521 QualType T,
522 TypeSourceInfo *TInfo,
523 const QualType *ExpandedTypes,
524 unsigned NumExpandedTypes,
525 TypeSourceInfo **ExpandedTInfos)
Abramo Bagnaradff19302011-03-08 08:55:46 +0000526 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000527 TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
528 ParameterPack(true), ExpandedParameterPack(true),
529 NumExpandedTypes(NumExpandedTypes)
530{
531 if (ExpandedTypes && ExpandedTInfos) {
532 void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
533 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
534 TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
535 TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
536 }
537 }
538}
539
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000540NonTypeTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000541NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000542 SourceLocation StartLoc, SourceLocation IdLoc,
543 unsigned D, unsigned P, IdentifierInfo *Id,
544 QualType T, bool ParameterPack,
545 TypeSourceInfo *TInfo) {
546 return new (C) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
547 T, ParameterPack, TInfo);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000548}
549
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000550NonTypeTemplateParmDecl *
551NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000552 SourceLocation StartLoc, SourceLocation IdLoc,
553 unsigned D, unsigned P,
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000554 IdentifierInfo *Id, QualType T,
555 TypeSourceInfo *TInfo,
556 const QualType *ExpandedTypes,
557 unsigned NumExpandedTypes,
558 TypeSourceInfo **ExpandedTInfos) {
559 unsigned Size = sizeof(NonTypeTemplateParmDecl)
560 + NumExpandedTypes * 2 * sizeof(void*);
561 void *Mem = C.Allocate(Size);
Abramo Bagnaradff19302011-03-08 08:55:46 +0000562 return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc,
563 D, P, Id, T, TInfo,
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000564 ExpandedTypes, NumExpandedTypes,
565 ExpandedTInfos);
566}
567
Douglas Gregor72172e92012-01-05 21:55:30 +0000568NonTypeTemplateParmDecl *
569NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
570 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NonTypeTemplateParmDecl));
571 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
572 SourceLocation(), 0, 0, 0,
573 QualType(), false, 0);
574}
575
576NonTypeTemplateParmDecl *
577NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
578 unsigned NumExpandedTypes) {
579 unsigned Size = sizeof(NonTypeTemplateParmDecl)
580 + NumExpandedTypes * 2 * sizeof(void*);
581
582 void *Mem = AllocateDeserializedDecl(C, ID, Size);
583 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
584 SourceLocation(), 0, 0, 0,
585 QualType(), 0, 0, NumExpandedTypes,
586 0);
587}
588
John McCallf4cd4f92011-02-09 01:13:10 +0000589SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnarae15d5532011-03-04 11:03:48 +0000590 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraea947882011-03-08 16:41:52 +0000591 return SourceRange(getOuterLocStart(),
592 getDefaultArgument()->getSourceRange().getEnd());
593 return DeclaratorDecl::getSourceRange();
John McCallf4cd4f92011-02-09 01:13:10 +0000594}
595
Douglas Gregordba32632009-02-10 19:49:53 +0000596SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara656e3002010-06-09 09:26:05 +0000597 return hasDefaultArgument()
598 ? getDefaultArgument()->getSourceRange().getBegin()
599 : SourceLocation();
Douglas Gregordba32632009-02-10 19:49:53 +0000600}
601
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000602//===----------------------------------------------------------------------===//
603// TemplateTemplateParmDecl Method Implementations
604//===----------------------------------------------------------------------===//
605
David Blaikie68e081d2011-12-20 02:48:34 +0000606void TemplateTemplateParmDecl::anchor() { }
607
Richard Smith1fde8ec2012-09-07 02:06:42 +0000608TemplateTemplateParmDecl::TemplateTemplateParmDecl(
609 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
610 IdentifierInfo *Id, TemplateParameterList *Params,
611 unsigned NumExpansions, TemplateParameterList * const *Expansions)
612 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
613 TemplateParmPosition(D, P), DefaultArgument(),
614 DefaultArgumentWasInherited(false), ParameterPack(true),
615 ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
616 if (Expansions)
617 std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
618 sizeof(TemplateParameterList*) * NumExpandedParams);
619}
620
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000621TemplateTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000622TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000623 SourceLocation L, unsigned D, unsigned P,
Douglas Gregorf5500772011-01-05 15:48:55 +0000624 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000625 TemplateParameterList *Params) {
Douglas Gregorf5500772011-01-05 15:48:55 +0000626 return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
627 Params);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000628}
629
Douglas Gregor72172e92012-01-05 21:55:30 +0000630TemplateTemplateParmDecl *
Richard Smith1fde8ec2012-09-07 02:06:42 +0000631TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
632 SourceLocation L, unsigned D, unsigned P,
633 IdentifierInfo *Id,
634 TemplateParameterList *Params,
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000635 ArrayRef<TemplateParameterList *> Expansions) {
Richard Smith1fde8ec2012-09-07 02:06:42 +0000636 void *Mem = C.Allocate(sizeof(TemplateTemplateParmDecl) +
637 sizeof(TemplateParameterList*) * Expansions.size());
638 return new (Mem) TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
639 Expansions.size(),
640 Expansions.data());
641}
642
643TemplateTemplateParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000644TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
645 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTemplateParmDecl));
646 return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, false,
647 0, 0);
648}
649
Richard Smith1fde8ec2012-09-07 02:06:42 +0000650TemplateTemplateParmDecl *
651TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
652 unsigned NumExpansions) {
653 unsigned Size = sizeof(TemplateTemplateParmDecl) +
654 sizeof(TemplateParameterList*) * NumExpansions;
655 void *Mem = AllocateDeserializedDecl(C, ID, Size);
656 return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, 0, 0,
657 NumExpansions, 0);
658}
659
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000660//===----------------------------------------------------------------------===//
Douglas Gregord002c7b2009-05-11 23:53:27 +0000661// TemplateArgumentList Implementation
662//===----------------------------------------------------------------------===//
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000663TemplateArgumentList *
664TemplateArgumentList::CreateCopy(ASTContext &Context,
665 const TemplateArgument *Args,
666 unsigned NumArgs) {
667 std::size_t Size = sizeof(TemplateArgumentList)
668 + NumArgs * sizeof(TemplateArgument);
669 void *Mem = Context.Allocate(Size);
670 TemplateArgument *StoredArgs
671 = reinterpret_cast<TemplateArgument *>(
672 static_cast<TemplateArgumentList *>(Mem) + 1);
673 std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
674 return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000675}
676
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000677FunctionTemplateSpecializationInfo *
678FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
679 FunctionTemplateDecl *Template,
680 TemplateSpecializationKind TSK,
681 const TemplateArgumentList *TemplateArgs,
682 const TemplateArgumentListInfo *TemplateArgsAsWritten,
683 SourceLocation POI) {
684 const ASTTemplateArgumentListInfo *ArgsAsWritten = 0;
685 if (TemplateArgsAsWritten)
686 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
687 *TemplateArgsAsWritten);
688
689 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
690 TemplateArgs,
691 ArgsAsWritten,
692 POI);
693}
694
Douglas Gregord002c7b2009-05-11 23:53:27 +0000695//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000696// TemplateDecl Implementation
697//===----------------------------------------------------------------------===//
698
699void TemplateDecl::anchor() { }
700
701//===----------------------------------------------------------------------===//
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000702// ClassTemplateSpecializationDecl Implementation
703//===----------------------------------------------------------------------===//
704ClassTemplateSpecializationDecl::
Douglas Gregore9029562010-05-06 00:28:52 +0000705ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000706 DeclContext *DC, SourceLocation StartLoc,
707 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000708 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000709 const TemplateArgument *Args,
710 unsigned NumArgs,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000711 ClassTemplateSpecializationDecl *PrevDecl)
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000712 : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000713 SpecializedTemplate->getIdentifier(),
714 PrevDecl),
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000715 SpecializedTemplate(SpecializedTemplate),
Abramo Bagnara8075c852010-06-12 07:44:57 +0000716 ExplicitInfo(0),
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000717 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
Douglas Gregord002c7b2009-05-11 23:53:27 +0000718 SpecializationKind(TSK_Undeclared) {
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000719}
Mike Stump11289f42009-09-09 15:08:12 +0000720
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000721ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000722 : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0),
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000723 ExplicitInfo(0),
724 SpecializationKind(TSK_Undeclared) {
725}
726
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000727ClassTemplateSpecializationDecl *
Douglas Gregore9029562010-05-06 00:28:52 +0000728ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000729 DeclContext *DC,
730 SourceLocation StartLoc,
731 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000732 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000733 const TemplateArgument *Args,
734 unsigned NumArgs,
Douglas Gregor67a65642009-02-17 23:15:12 +0000735 ClassTemplateSpecializationDecl *PrevDecl) {
Douglas Gregor67a65642009-02-17 23:15:12 +0000736 ClassTemplateSpecializationDecl *Result
Mike Stump11289f42009-09-09 15:08:12 +0000737 = new (Context)ClassTemplateSpecializationDecl(Context,
Douglas Gregor2373c592009-05-31 09:31:02 +0000738 ClassTemplateSpecialization,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000739 TK, DC, StartLoc, IdLoc,
Douglas Gregord002c7b2009-05-11 23:53:27 +0000740 SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000741 Args, NumArgs,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000742 PrevDecl);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000743 Result->MayHaveOutOfDateDef = false;
744
Douglas Gregor67a65642009-02-17 23:15:12 +0000745 Context.getTypeDeclType(Result, PrevDecl);
746 return Result;
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000747}
Douglas Gregor2373c592009-05-31 09:31:02 +0000748
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000749ClassTemplateSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000750ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
751 unsigned ID) {
752 void *Mem = AllocateDeserializedDecl(C, ID,
753 sizeof(ClassTemplateSpecializationDecl));
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000754 ClassTemplateSpecializationDecl *Result =
755 new (Mem) ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
756 Result->MayHaveOutOfDateDef = false;
757 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000758}
759
Benjamin Kramer9170e912013-02-22 15:46:01 +0000760void ClassTemplateSpecializationDecl::getNameForDiagnostic(
761 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
762 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000763
764 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Benjamin Kramer9170e912013-02-22 15:46:01 +0000765 TemplateSpecializationType::PrintTemplateArgumentList(
766 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000767}
768
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000769ClassTemplateDecl *
Mike Stump11289f42009-09-09 15:08:12 +0000770ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
771 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000772 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
773 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
774 return SpecializedTemplate.get<ClassTemplateDecl*>();
775}
776
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000777SourceRange
778ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000779 if (ExplicitInfo) {
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000780 SourceLocation Begin = getTemplateKeywordLoc();
781 if (Begin.isValid()) {
782 // Here we have an explicit (partial) specialization or instantiation.
783 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
784 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
785 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
786 if (getExternLoc().isValid())
787 Begin = getExternLoc();
788 SourceLocation End = getRBraceLoc();
789 if (End.isInvalid())
790 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
791 return SourceRange(Begin, End);
792 }
793 // An implicit instantiation of a class template partial specialization
794 // uses ExplicitInfo to record the TypeAsWritten, but the source
795 // locations should be retrieved from the instantiation pattern.
796 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
797 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
798 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
799 assert(inst_from != 0);
800 return inst_from->getSourceRange();
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000801 }
802 else {
803 // No explicit info available.
804 llvm::PointerUnion<ClassTemplateDecl *,
805 ClassTemplatePartialSpecializationDecl *>
806 inst_from = getInstantiatedFrom();
807 if (inst_from.isNull())
808 return getSpecializedTemplate()->getSourceRange();
809 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
810 return ctd->getSourceRange();
811 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
812 ->getSourceRange();
813 }
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000814}
815
Douglas Gregor2373c592009-05-31 09:31:02 +0000816//===----------------------------------------------------------------------===//
817// ClassTemplatePartialSpecializationDecl Implementation
818//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000819void ClassTemplatePartialSpecializationDecl::anchor() { }
820
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000821ClassTemplatePartialSpecializationDecl::
822ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000823 DeclContext *DC,
824 SourceLocation StartLoc,
825 SourceLocation IdLoc,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000826 TemplateParameterList *Params,
827 ClassTemplateDecl *SpecializedTemplate,
828 const TemplateArgument *Args,
829 unsigned NumArgs,
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000830 const ASTTemplateArgumentListInfo *ArgInfos,
Richard Smithb2f61b42013-08-22 23:27:37 +0000831 ClassTemplatePartialSpecializationDecl *PrevDecl)
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000832 : ClassTemplateSpecializationDecl(Context,
833 ClassTemplatePartialSpecialization,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000834 TK, DC, StartLoc, IdLoc,
835 SpecializedTemplate,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000836 Args, NumArgs, PrevDecl),
837 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Richard Smithb2f61b42013-08-22 23:27:37 +0000838 InstantiatedFromMember(0, false)
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000839{
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000840 AdoptTemplateParameterList(Params, this);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000841}
842
Douglas Gregor2373c592009-05-31 09:31:02 +0000843ClassTemplatePartialSpecializationDecl *
844ClassTemplatePartialSpecializationDecl::
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000845Create(ASTContext &Context, TagKind TK,DeclContext *DC,
846 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregor2373c592009-05-31 09:31:02 +0000847 TemplateParameterList *Params,
848 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000849 const TemplateArgument *Args,
850 unsigned NumArgs,
John McCall6b51f282009-11-23 01:53:49 +0000851 const TemplateArgumentListInfo &ArgInfos,
John McCalle78aac42010-03-10 03:28:59 +0000852 QualType CanonInjectedType,
Richard Smithb2f61b42013-08-22 23:27:37 +0000853 ClassTemplatePartialSpecializationDecl *PrevDecl) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000854 const ASTTemplateArgumentListInfo *ASTArgInfos =
855 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
John McCall0ad16662009-10-29 08:12:44 +0000856
Douglas Gregor2373c592009-05-31 09:31:02 +0000857 ClassTemplatePartialSpecializationDecl *Result
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000858 = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC,
859 StartLoc, IdLoc,
860 Params,
Douglas Gregor2373c592009-05-31 09:31:02 +0000861 SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000862 Args, NumArgs,
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000863 ASTArgInfos,
Richard Smithb2f61b42013-08-22 23:27:37 +0000864 PrevDecl);
Douglas Gregor2373c592009-05-31 09:31:02 +0000865 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000866 Result->MayHaveOutOfDateDef = false;
John McCalle78aac42010-03-10 03:28:59 +0000867
868 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregor2373c592009-05-31 09:31:02 +0000869 return Result;
870}
John McCall11083da2009-09-16 22:47:08 +0000871
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000872ClassTemplatePartialSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000873ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
874 unsigned ID) {
875 void *Mem = AllocateDeserializedDecl(C, ID,
876 sizeof(ClassTemplatePartialSpecializationDecl));
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000877 ClassTemplatePartialSpecializationDecl *Result
878 = new (Mem) ClassTemplatePartialSpecializationDecl();
879 Result->MayHaveOutOfDateDef = false;
880 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000881}
882
John McCall11083da2009-09-16 22:47:08 +0000883//===----------------------------------------------------------------------===//
884// FriendTemplateDecl Implementation
885//===----------------------------------------------------------------------===//
886
David Blaikie68e081d2011-12-20 02:48:34 +0000887void FriendTemplateDecl::anchor() { }
888
John McCall11083da2009-09-16 22:47:08 +0000889FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
890 DeclContext *DC,
891 SourceLocation L,
892 unsigned NParams,
893 TemplateParameterList **Params,
894 FriendUnion Friend,
895 SourceLocation FLoc) {
896 FriendTemplateDecl *Result
897 = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
898 return Result;
899}
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000900
Douglas Gregor72172e92012-01-05 21:55:30 +0000901FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
902 unsigned ID) {
903 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FriendTemplateDecl));
904 return new (Mem) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000905}
Richard Smith3f1b5d02011-05-05 21:57:07 +0000906
907//===----------------------------------------------------------------------===//
908// TypeAliasTemplateDecl Implementation
909//===----------------------------------------------------------------------===//
910
911TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
912 DeclContext *DC,
913 SourceLocation L,
914 DeclarationName Name,
915 TemplateParameterList *Params,
916 NamedDecl *Decl) {
917 AdoptTemplateParameterList(Params, DC);
918 return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl);
919}
920
Douglas Gregor72172e92012-01-05 21:55:30 +0000921TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
922 unsigned ID) {
923 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasTemplateDecl));
924 return new (Mem) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(),
925 0, 0);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000926}
927
928void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
929 static_cast<Common *>(Ptr)->~Common();
930}
931RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000932TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3f1b5d02011-05-05 21:57:07 +0000933 Common *CommonPtr = new (C) Common;
934 C.AddDeallocation(DeallocateCommon, CommonPtr);
935 return CommonPtr;
936}
937
David Blaikie68e081d2011-12-20 02:48:34 +0000938//===----------------------------------------------------------------------===//
939// ClassScopeFunctionSpecializationDecl Implementation
940//===----------------------------------------------------------------------===//
941
942void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor72172e92012-01-05 21:55:30 +0000943
944ClassScopeFunctionSpecializationDecl *
945ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
946 unsigned ID) {
947 void *Mem = AllocateDeserializedDecl(C, ID,
948 sizeof(ClassScopeFunctionSpecializationDecl));
Nico Weber7b5a7162012-06-25 17:21:05 +0000949 return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0,
950 false, TemplateArgumentListInfo());
Douglas Gregor72172e92012-01-05 21:55:30 +0000951}
Larisse Voufo39a1e502013-08-06 01:03:05 +0000952
953//===----------------------------------------------------------------------===//
954// VarTemplateDecl Implementation
955//===----------------------------------------------------------------------===//
956
957void VarTemplateDecl::DeallocateCommon(void *Ptr) {
958 static_cast<Common *>(Ptr)->~Common();
959}
960
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000961VarTemplateDecl *VarTemplateDecl::getDefinition() {
962 VarTemplateDecl *CurD = this;
963 while (CurD) {
964 if (CurD->isThisDeclarationADefinition())
965 return CurD;
966 CurD = CurD->getPreviousDecl();
967 }
968 return 0;
969}
970
Larisse Voufo39a1e502013-08-06 01:03:05 +0000971VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
972 SourceLocation L, DeclarationName Name,
973 TemplateParameterList *Params,
974 NamedDecl *Decl,
975 VarTemplateDecl *PrevDecl) {
976 VarTemplateDecl *New = new (C) VarTemplateDecl(DC, L, Name, Params, Decl);
977 New->setPreviousDeclaration(PrevDecl);
978 return New;
979}
980
981VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
982 unsigned ID) {
983 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(VarTemplateDecl));
984 return new (Mem) VarTemplateDecl(EmptyShell());
985}
986
Larisse Voufo30616382013-08-23 22:21:36 +0000987// TODO: Unify accross class, function and variable templates?
988// May require moving this and Common to RedeclarableTemplateDecl.
Larisse Voufo39a1e502013-08-06 01:03:05 +0000989void VarTemplateDecl::LoadLazySpecializations() const {
990 Common *CommonPtr = getCommonPtr();
991 if (CommonPtr->LazySpecializations) {
992 ASTContext &Context = getASTContext();
993 uint32_t *Specs = CommonPtr->LazySpecializations;
994 CommonPtr->LazySpecializations = 0;
995 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
996 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
997 }
998}
999
1000llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1001VarTemplateDecl::getSpecializations() const {
1002 LoadLazySpecializations();
1003 return getCommonPtr()->Specializations;
1004}
1005
1006llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1007VarTemplateDecl::getPartialSpecializations() {
1008 LoadLazySpecializations();
1009 return getCommonPtr()->PartialSpecializations;
1010}
1011
1012RedeclarableTemplateDecl::CommonBase *
1013VarTemplateDecl::newCommon(ASTContext &C) const {
1014 Common *CommonPtr = new (C) Common;
1015 C.AddDeallocation(DeallocateCommon, CommonPtr);
1016 return CommonPtr;
1017}
1018
1019VarTemplateSpecializationDecl *
1020VarTemplateDecl::findSpecialization(const TemplateArgument *Args,
1021 unsigned NumArgs, void *&InsertPos) {
1022 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
1023}
1024
1025void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1026 void *InsertPos) {
1027 if (InsertPos)
1028 getSpecializations().InsertNode(D, InsertPos);
1029 else {
1030 VarTemplateSpecializationDecl *Existing =
1031 getSpecializations().GetOrInsertNode(D);
1032 (void)Existing;
1033 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1034 }
1035 if (ASTMutationListener *L = getASTMutationListener())
1036 L->AddedCXXTemplateSpecialization(this, D);
1037}
1038
1039VarTemplatePartialSpecializationDecl *
1040VarTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
1041 unsigned NumArgs, void *&InsertPos) {
1042 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
1043 InsertPos);
1044}
1045
1046void VarTemplateDecl::AddPartialSpecialization(
1047 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1048 if (InsertPos)
1049 getPartialSpecializations().InsertNode(D, InsertPos);
1050 else {
1051 VarTemplatePartialSpecializationDecl *Existing =
1052 getPartialSpecializations().GetOrInsertNode(D);
1053 (void)Existing;
1054 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1055 }
1056
1057 if (ASTMutationListener *L = getASTMutationListener())
1058 L->AddedCXXTemplateSpecialization(this, D);
1059}
1060
1061void VarTemplateDecl::getPartialSpecializations(
1062 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1063 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1064 getPartialSpecializations();
1065 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +00001066 PS.reserve(PartialSpecs.size());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001067 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1068 P = PartialSpecs.begin(),
1069 PEnd = PartialSpecs.end();
Richard Smithb2f61b42013-08-22 23:27:37 +00001070 P != PEnd; ++P)
1071 PS.push_back(P->getMostRecentDecl());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001072}
1073
1074VarTemplatePartialSpecializationDecl *
1075VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1076 VarTemplatePartialSpecializationDecl *D) {
1077 Decl *DCanon = D->getCanonicalDecl();
1078 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1079 P = getPartialSpecializations().begin(),
1080 PEnd = getPartialSpecializations().end();
1081 P != PEnd; ++P) {
1082 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1083 return P->getMostRecentDecl();
1084 }
1085
1086 return 0;
1087}
1088
1089//===----------------------------------------------------------------------===//
1090// VarTemplateSpecializationDecl Implementation
1091//===----------------------------------------------------------------------===//
1092VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1093 ASTContext &Context, Kind DK, DeclContext *DC, SourceLocation StartLoc,
1094 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1095 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1096 unsigned NumArgs)
1097 : VarDecl(DK, DC, StartLoc, IdLoc, SpecializedTemplate->getIdentifier(), T,
1098 TInfo, S),
1099 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(0),
1100 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
1101 SpecializationKind(TSK_Undeclared) {}
1102
1103VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK)
1104 : VarDecl(DK, 0, SourceLocation(), SourceLocation(), 0, QualType(), 0,
1105 SC_None),
1106 ExplicitInfo(0), SpecializationKind(TSK_Undeclared) {}
1107
1108VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1109 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1110 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1111 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1112 unsigned NumArgs) {
1113 VarTemplateSpecializationDecl *Result = new (Context)
1114 VarTemplateSpecializationDecl(Context, VarTemplateSpecialization, DC,
1115 StartLoc, IdLoc, SpecializedTemplate, T,
1116 TInfo, S, Args, NumArgs);
1117 return Result;
1118}
1119
1120VarTemplateSpecializationDecl *
1121VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1122 void *Mem =
1123 AllocateDeserializedDecl(C, ID, sizeof(VarTemplateSpecializationDecl));
1124 VarTemplateSpecializationDecl *Result =
1125 new (Mem) VarTemplateSpecializationDecl(VarTemplateSpecialization);
1126 return Result;
1127}
1128
1129void VarTemplateSpecializationDecl::getNameForDiagnostic(
1130 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1131 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1132
1133 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1134 TemplateSpecializationType::PrintTemplateArgumentList(
1135 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
1136}
1137
1138VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1139 if (SpecializedPartialSpecialization *PartialSpec =
1140 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1141 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1142 return SpecializedTemplate.get<VarTemplateDecl *>();
1143}
1144
1145void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1146 const TemplateArgumentListInfo &ArgsInfo) {
1147 unsigned N = ArgsInfo.size();
1148 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1149 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1150 for (unsigned I = 0; I != N; ++I)
1151 TemplateArgsInfo.addArgument(ArgsInfo[I]);
1152}
1153
1154//===----------------------------------------------------------------------===//
1155// VarTemplatePartialSpecializationDecl Implementation
1156//===----------------------------------------------------------------------===//
1157void VarTemplatePartialSpecializationDecl::anchor() {}
1158
1159VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1160 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1161 SourceLocation IdLoc, TemplateParameterList *Params,
1162 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1163 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
Richard Smithb2f61b42013-08-22 23:27:37 +00001164 const ASTTemplateArgumentListInfo *ArgInfos)
Larisse Voufo39a1e502013-08-06 01:03:05 +00001165 : VarTemplateSpecializationDecl(Context, VarTemplatePartialSpecialization,
1166 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1167 TInfo, S, Args, NumArgs),
1168 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Richard Smithb2f61b42013-08-22 23:27:37 +00001169 InstantiatedFromMember(0, false) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001170 // TODO: The template parameters should be in DC by now. Verify.
1171 // AdoptTemplateParameterList(Params, DC);
1172}
1173
1174VarTemplatePartialSpecializationDecl *
1175VarTemplatePartialSpecializationDecl::Create(
1176 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1177 SourceLocation IdLoc, TemplateParameterList *Params,
1178 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1179 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
Richard Smithb2f61b42013-08-22 23:27:37 +00001180 const TemplateArgumentListInfo &ArgInfos) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +00001181 const ASTTemplateArgumentListInfo *ASTArgInfos
1182 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001183
1184 VarTemplatePartialSpecializationDecl *Result =
1185 new (Context) VarTemplatePartialSpecializationDecl(
1186 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
Richard Smithb2f61b42013-08-22 23:27:37 +00001187 S, Args, NumArgs, ASTArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001188 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1189 return Result;
1190}
1191
1192VarTemplatePartialSpecializationDecl *
1193VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1194 unsigned ID) {
1195 void *Mem = AllocateDeserializedDecl(
1196 C, ID, sizeof(VarTemplatePartialSpecializationDecl));
1197 VarTemplatePartialSpecializationDecl *Result =
1198 new (Mem) VarTemplatePartialSpecializationDecl();
1199 return Result;
1200}