blob: 555800a8befd6f1b706e7d53b68e18055a1d0dea [file] [log] [blame]
Sebastian Redl06a59bb2009-10-23 22:13:42 +00001//===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
Douglas Gregoraaba5e32009-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 Gregoraaba5e32009-02-04 19:02:06 +000014#include "clang/AST/DeclTemplate.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000015#include "clang/AST/ASTContext.h"
16#include "clang/AST/ASTMutationListener.h"
17#include "clang/AST/DeclCXX.h"
Douglas Gregor55f6b142009-02-09 18:46:07 +000018#include "clang/AST/Expr.h"
Douglas Gregorb95cc972011-01-04 02:33:52 +000019#include "clang/AST/ExprCXX.h"
John McCall833ca992009-10-29 08:12:44 +000020#include "clang/AST/TypeLoc.h"
Douglas Gregoraaba5e32009-02-04 19:02:06 +000021#include "clang/Basic/IdentifierTable.h"
22#include "llvm/ADT/STLExtras.h"
Douglas Gregor910f8002010-11-07 23:05:16 +000023#include <memory>
Douglas Gregoraaba5e32009-02-04 19:02:06 +000024using namespace clang;
25
26//===----------------------------------------------------------------------===//
27// TemplateParameterList Implementation
28//===----------------------------------------------------------------------===//
29
Douglas Gregorddc29e12009-02-06 22:42:48 +000030TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
31 SourceLocation LAngleLoc,
Douglas Gregorbf4ea562009-09-15 16:23:51 +000032 NamedDecl **Params, unsigned NumParams,
Douglas Gregorddc29e12009-02-06 22:42:48 +000033 SourceLocation RAngleLoc)
34 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
Richard Smith6964b3f2012-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 Gregoraaba5e32009-02-04 19:02:06 +000054}
55
56TemplateParameterList *
Jay Foad4ba2a172011-01-12 09:06:06 +000057TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
Douglas Gregorbf4ea562009-09-15 16:23:51 +000058 SourceLocation LAngleLoc, NamedDecl **Params,
Douglas Gregorddc29e12009-02-06 22:42:48 +000059 unsigned NumParams, SourceLocation RAngleLoc) {
Douglas Gregorbf4ea562009-09-15 16:23:51 +000060 unsigned Size = sizeof(TemplateParameterList)
61 + sizeof(NamedDecl *) * NumParams;
Richard Smith1a30edb2012-08-16 22:51:34 +000062 unsigned Align = std::max(llvm::alignOf<TemplateParameterList>(),
63 llvm::alignOf<NamedDecl*>());
Douglas Gregoraaba5e32009-02-04 19:02:06 +000064 void *Mem = C.Allocate(Size, Align);
Mike Stump1eb44332009-09-09 15:08:12 +000065 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
Douglas Gregorddc29e12009-02-06 22:42:48 +000066 NumParams, RAngleLoc);
Douglas Gregoraaba5e32009-02-04 19:02:06 +000067}
68
Douglas Gregor62cb18d2009-02-11 18:16:40 +000069unsigned TemplateParameterList::getMinRequiredArguments() const {
Douglas Gregor6952f1e2011-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 Gregor62cb18d2009-02-11 18:16:40 +000081 break;
Douglas Gregor6952f1e2011-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 Gregor62cb18d2009-02-11 18:16:40 +000095 }
Douglas Gregor6952f1e2011-01-19 20:10:05 +000096
Douglas Gregor62cb18d2009-02-11 18:16:40 +000097 return NumRequiredArgs;
98}
99
Douglas Gregored9c0f92009-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 Gregor787a40d2011-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 Gregoraaba5e32009-02-04 19:02:06 +0000127//===----------------------------------------------------------------------===//
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000128// RedeclarableTemplateDecl Implementation
129//===----------------------------------------------------------------------===//
130
Dmitri Gribenkob76d9712013-01-23 16:52:57 +0000131RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
Douglas Gregor7c99bb5c2012-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 Gribenkob76d9712013-01-23 16:52:57 +0000135 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
136 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
Douglas Gregoref96ee02012-01-14 16:38:05 +0000137 Prev = Prev->getPreviousDecl()) {
Douglas Gregor7c99bb5c2012-01-14 15:13:49 +0000138 if (Prev->Common) {
139 Common = Prev->Common;
140 break;
141 }
142
143 PrevDecls.push_back(Prev);
144 }
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000145
Douglas Gregor7c99bb5c2012-01-14 15:13:49 +0000146 // If we never found a common pointer, allocate one now.
Douglas Gregor8a8950b2012-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 Gregor7c99bb5c2012-01-14 15:13:49 +0000151 Common = newCommon(getASTContext());
Douglas Gregor8a8950b2012-01-14 15:30:55 +0000152 }
Douglas Gregor7c99bb5c2012-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 Collingbourne9eabeba2010-07-29 16:11:51 +0000157 }
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000158
Douglas Gregor7c99bb5c2012-01-14 15:13:49 +0000159 return Common;
Peter Collingbournef88718e2010-07-29 16:12:09 +0000160}
161
Peter Collingbourne40485902010-07-30 17:09:04 +0000162template <class EntryType>
163typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
164RedeclarableTemplateDecl::findSpecializationImpl(
Chandler Carruthd964d632012-05-03 23:49:05 +0000165 llvm::FoldingSetVector<EntryType> &Specs,
Peter Collingbourne40485902010-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 Gregoref96ee02012-01-14 16:38:05 +0000172 return Entry ? SETraits::getMostRecentDecl(Entry) : 0;
Peter Collingbourne40485902010-07-30 17:09:04 +0000173}
174
Douglas Gregorc494f772011-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 Blaikie66874fb2013-02-21 01:47:18 +0000187 ArgType = Context.getPackExpansionType(ArgType, None);
David Blaikiedc84cd52013-02-20 22:23:23 +0000188
Douglas Gregorc494f772011-03-05 17:54:25 +0000189 Arg = TemplateArgument(ArgType);
190 } else if (NonTypeTemplateParmDecl *NTTP =
191 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
John McCallf4b88a42012-03-10 09:33:50 +0000192 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
Douglas Gregorc494f772011-03-05 17:54:25 +0000193 NTTP->getType().getNonLValueExprType(Context),
194 Expr::getValueKindForType(NTTP->getType()),
195 NTTP->getLocation());
196
197 if (NTTP->isParameterPack())
David Blaikie66874fb2013-02-21 01:47:18 +0000198 E = new (Context) PackExpansionExpr(Context.DependentTy, E,
199 NTTP->getLocation(), None);
Douglas Gregorc494f772011-03-05 17:54:25 +0000200 Arg = TemplateArgument(E);
201 } else {
202 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
203 if (TTP->isParameterPack())
David Blaikiedc84cd52013-02-20 22:23:23 +0000204 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
Douglas Gregorc494f772011-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 Collingbourne9eabeba2010-07-29 16:11:51 +0000216//===----------------------------------------------------------------------===//
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000217// FunctionTemplateDecl Implementation
218//===----------------------------------------------------------------------===//
219
Douglas Gregor00545312010-05-23 18:26:36 +0000220void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
221 static_cast<Common *>(Ptr)->~Common();
222}
223
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000224FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
225 DeclContext *DC,
226 SourceLocation L,
227 DeclarationName Name,
Douglas Gregor127102b2009-06-29 20:59:39 +0000228 TemplateParameterList *Params,
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000229 NamedDecl *Decl) {
Douglas Gregor787a40d2011-03-04 18:32:38 +0000230 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000231 return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
232}
233
Douglas Gregor1e68ecc2012-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 Gregor9a299e02011-03-04 17:52:15 +0000239}
240
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +0000241RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob76d9712013-01-23 16:52:57 +0000242FunctionTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +0000243 Common *CommonPtr = new (C) Common;
244 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000245 return CommonPtr;
246}
247
Richard Smith6982bf42013-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 Kyrtzidis2c853e42010-07-20 13:59:58 +0000265FunctionDecl *
266FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
267 unsigned NumArgs, void *&InsertPos) {
Peter Collingbourne40485902010-07-30 17:09:04 +0000268 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
Argyrios Kyrtzidis2c853e42010-07-20 13:59:58 +0000269}
270
Sebastian Redl5bbcdbf2011-04-14 14:07:59 +0000271void FunctionTemplateDecl::addSpecialization(
272 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
Douglas Gregor1e1e9722012-03-28 14:34:23 +0000273 if (InsertPos)
274 getSpecializations().InsertNode(Info, InsertPos);
275 else
276 getSpecializations().GetOrInsertNode(Info);
Sebastian Redl5bbcdbf2011-04-14 14:07:59 +0000277 if (ASTMutationListener *L = getASTMutationListener())
278 L->AddedCXXTemplateSpecialization(this, Info->Function);
279}
280
Richard Smith7a9f7c72013-05-17 03:04:50 +0000281ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
Douglas Gregorc494f772011-03-05 17:54:25 +0000282 TemplateParameterList *Params = getTemplateParameters();
283 Common *CommonPtr = getCommonPtr();
284 if (!CommonPtr->InjectedArgs) {
285 CommonPtr->InjectedArgs
Richard Smith7a9f7c72013-05-17 03:04:50 +0000286 = new (getASTContext()) TemplateArgument[Params->size()];
287 GenerateInjectedTemplateArgs(getASTContext(), Params,
Douglas Gregorc494f772011-03-05 17:54:25 +0000288 CommonPtr->InjectedArgs);
289 }
Richard Smith7a9f7c72013-05-17 03:04:50 +0000290
291 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
Douglas Gregorc494f772011-03-05 17:54:25 +0000292}
293
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000294//===----------------------------------------------------------------------===//
295// ClassTemplateDecl Implementation
296//===----------------------------------------------------------------------===//
297
Douglas Gregor00545312010-05-23 18:26:36 +0000298void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
299 static_cast<Common *>(Ptr)->~Common();
300}
301
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000302ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
303 DeclContext *DC,
304 SourceLocation L,
305 DeclarationName Name,
306 TemplateParameterList *Params,
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000307 NamedDecl *Decl,
308 ClassTemplateDecl *PrevDecl) {
Douglas Gregor787a40d2011-03-04 18:32:38 +0000309 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +0000310 ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
Argyrios Kyrtzidis5bf1bdc2010-06-21 10:57:41 +0000311 New->setPreviousDeclaration(PrevDecl);
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +0000312 return New;
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000313}
314
Douglas Gregor1e68ecc2012-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 Gregor9a299e02011-03-04 17:52:15 +0000319}
320
Dmitri Gribenkoe252a892013-02-14 13:20:36 +0000321void ClassTemplateDecl::LoadLazySpecializations() const {
Douglas Gregorc8e5cf82010-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 Carruthd964d632012-05-03 23:49:05 +0000332llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
Dmitri Gribenkoe252a892013-02-14 13:20:36 +0000333ClassTemplateDecl::getSpecializations() const {
Douglas Gregorc8e5cf82010-10-27 22:21:36 +0000334 LoadLazySpecializations();
335 return getCommonPtr()->Specializations;
336}
337
Chandler Carruthd964d632012-05-03 23:49:05 +0000338llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
Douglas Gregorc8e5cf82010-10-27 22:21:36 +0000339ClassTemplateDecl::getPartialSpecializations() {
340 LoadLazySpecializations();
341 return getCommonPtr()->PartialSpecializations;
342}
343
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +0000344RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob76d9712013-01-23 16:52:57 +0000345ClassTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +0000346 Common *CommonPtr = new (C) Common;
347 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000348 return CommonPtr;
349}
350
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000351ClassTemplateSpecializationDecl *
352ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
353 unsigned NumArgs, void *&InsertPos) {
Peter Collingbourne40485902010-07-30 17:09:04 +0000354 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000355}
356
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000357void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
358 void *InsertPos) {
Douglas Gregor1e1e9722012-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 Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000367 if (ASTMutationListener *L = getASTMutationListener())
368 L->AddedCXXTemplateSpecialization(this, D);
369}
370
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000371ClassTemplatePartialSpecializationDecl *
372ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
373 unsigned NumArgs,
374 void *&InsertPos) {
Peter Collingbourne40485902010-07-30 17:09:04 +0000375 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
376 InsertPos);
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000377}
378
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000379void ClassTemplateDecl::AddPartialSpecialization(
380 ClassTemplatePartialSpecializationDecl *D,
381 void *InsertPos) {
Douglas Gregor1e1e9722012-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 Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000391 if (ASTMutationListener *L = getASTMutationListener())
392 L->AddedCXXTemplateSpecialization(this, D);
393}
394
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000395void ClassTemplateDecl::getPartialSpecializations(
Chris Lattner5f9e2722011-07-23 10:55:15 +0000396 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
Chandler Carruthd964d632012-05-03 23:49:05 +0000397 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
Argyrios Kyrtzidis5bf1bdc2010-06-21 10:57:41 +0000398 = getPartialSpecializations();
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000399 PS.clear();
400 PS.resize(PartialSpecs.size());
Chandler Carruthd964d632012-05-03 23:49:05 +0000401 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000402 P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
403 P != PEnd; ++P) {
404 assert(!PS[P->getSequenceNumber()]);
Douglas Gregoref96ee02012-01-14 16:38:05 +0000405 PS[P->getSequenceNumber()] = P->getMostRecentDecl();
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000406 }
407}
408
Douglas Gregorb88e8882009-07-30 17:40:51 +0000409ClassTemplatePartialSpecializationDecl *
410ClassTemplateDecl::findPartialSpecialization(QualType T) {
411 ASTContext &Context = getASTContext();
Chandler Carruthd964d632012-05-03 23:49:05 +0000412 using llvm::FoldingSetVector;
413 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregorb88e8882009-07-30 17:40:51 +0000414 partial_spec_iterator;
415 for (partial_spec_iterator P = getPartialSpecializations().begin(),
416 PEnd = getPartialSpecializations().end();
417 P != PEnd; ++P) {
John McCall31f17ec2010-04-27 00:57:59 +0000418 if (Context.hasSameType(P->getInjectedSpecializationType(), T))
Douglas Gregoref96ee02012-01-14 16:38:05 +0000419 return P->getMostRecentDecl();
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000420 }
421
422 return 0;
423}
424
425ClassTemplatePartialSpecializationDecl *
426ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
427 ClassTemplatePartialSpecializationDecl *D) {
428 Decl *DCanon = D->getCanonicalDecl();
Chandler Carruthd964d632012-05-03 23:49:05 +0000429 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000430 P = getPartialSpecializations().begin(),
431 PEnd = getPartialSpecializations().end();
432 P != PEnd; ++P) {
433 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
Douglas Gregoref96ee02012-01-14 16:38:05 +0000434 return P->getMostRecentDecl();
Douglas Gregorb88e8882009-07-30 17:40:51 +0000435 }
Mike Stump1eb44332009-09-09 15:08:12 +0000436
Douglas Gregorb88e8882009-07-30 17:40:51 +0000437 return 0;
438}
439
John McCall3cb0ebd2010-03-10 03:28:59 +0000440QualType
Douglas Gregor24bae922010-07-08 18:37:38 +0000441ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidis5bf1bdc2010-06-21 10:57:41 +0000442 Common *CommonPtr = getCommonPtr();
Douglas Gregor7da97d02009-05-10 22:57:19 +0000443 if (!CommonPtr->InjectedClassNameType.isNull())
444 return CommonPtr->InjectedClassNameType;
445
Douglas Gregorb7d09d62010-12-23 16:00:30 +0000446 // C++0x [temp.dep.type]p2:
447 // The template argument list of a primary template is a template argument
448 // list in which the nth template argument has the value of the nth template
449 // parameter of the class template. If the nth template parameter is a
450 // template parameter pack (14.5.3), the nth template argument is a pack
451 // expansion (14.5.3) whose pattern is the name of the template parameter
452 // pack.
Douglas Gregor24bae922010-07-08 18:37:38 +0000453 ASTContext &Context = getASTContext();
Douglas Gregor7da97d02009-05-10 22:57:19 +0000454 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner5f9e2722011-07-23 10:55:15 +0000455 SmallVector<TemplateArgument, 16> TemplateArgs;
Douglas Gregorc494f772011-03-05 17:54:25 +0000456 TemplateArgs.resize(Params->size());
457 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
Douglas Gregor7da97d02009-05-10 22:57:19 +0000458 CommonPtr->InjectedClassNameType
Douglas Gregor1275ae02009-07-28 23:00:59 +0000459 = Context.getTemplateSpecializationType(TemplateName(this),
Douglas Gregor7da97d02009-05-10 22:57:19 +0000460 &TemplateArgs[0],
Douglas Gregor1275ae02009-07-28 23:00:59 +0000461 TemplateArgs.size());
Douglas Gregor7da97d02009-05-10 22:57:19 +0000462 return CommonPtr->InjectedClassNameType;
463}
464
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000465//===----------------------------------------------------------------------===//
466// TemplateTypeParm Allocation/Deallocation Method Implementations
467//===----------------------------------------------------------------------===//
468
469TemplateTypeParmDecl *
Jay Foad4ba2a172011-01-12 09:06:06 +0000470TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnara344577e2011-03-06 15:48:19 +0000471 SourceLocation KeyLoc, SourceLocation NameLoc,
472 unsigned D, unsigned P, IdentifierInfo *Id,
473 bool Typename, bool ParameterPack) {
Chandler Carruth4fb86f82011-05-01 00:51:33 +0000474 TemplateTypeParmDecl *TTPDecl =
475 new (C) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
476 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
477 TTPDecl->TypeForDecl = TTPType.getTypePtr();
478 return TTPDecl;
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000479}
480
Argyrios Kyrtzidisb8b03e62010-07-02 11:54:55 +0000481TemplateTypeParmDecl *
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000482TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
483 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTypeParmDecl));
484 return new (Mem) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(),
485 0, false);
Argyrios Kyrtzidisb8b03e62010-07-02 11:54:55 +0000486}
487
John McCall833ca992009-10-29 08:12:44 +0000488SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara77d4ee22011-03-04 12:42:03 +0000489 return hasDefaultArgument()
490 ? DefaultArgument->getTypeLoc().getBeginLoc()
491 : SourceLocation();
492}
493
494SourceRange TemplateTypeParmDecl::getSourceRange() const {
495 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnara344577e2011-03-06 15:48:19 +0000496 return SourceRange(getLocStart(),
Abramo Bagnara77d4ee22011-03-04 12:42:03 +0000497 DefaultArgument->getTypeLoc().getEndLoc());
498 else
Abramo Bagnara344577e2011-03-06 15:48:19 +0000499 return TypeDecl::getSourceRange();
John McCall833ca992009-10-29 08:12:44 +0000500}
501
Douglas Gregored9c0f92009-10-29 00:04:11 +0000502unsigned TemplateTypeParmDecl::getDepth() const {
503 return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
504}
505
506unsigned TemplateTypeParmDecl::getIndex() const {
507 return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
508}
509
Chandler Carruth4fb86f82011-05-01 00:51:33 +0000510bool TemplateTypeParmDecl::isParameterPack() const {
511 return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack();
512}
513
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000514//===----------------------------------------------------------------------===//
515// NonTypeTemplateParmDecl Method Implementations
516//===----------------------------------------------------------------------===//
517
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000518NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000519 SourceLocation StartLoc,
520 SourceLocation IdLoc,
521 unsigned D, unsigned P,
522 IdentifierInfo *Id,
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000523 QualType T,
524 TypeSourceInfo *TInfo,
525 const QualType *ExpandedTypes,
526 unsigned NumExpandedTypes,
527 TypeSourceInfo **ExpandedTInfos)
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000528 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000529 TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
530 ParameterPack(true), ExpandedParameterPack(true),
531 NumExpandedTypes(NumExpandedTypes)
532{
533 if (ExpandedTypes && ExpandedTInfos) {
534 void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
535 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
536 TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
537 TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
538 }
539 }
540}
541
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000542NonTypeTemplateParmDecl *
Jay Foad4ba2a172011-01-12 09:06:06 +0000543NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000544 SourceLocation StartLoc, SourceLocation IdLoc,
545 unsigned D, unsigned P, IdentifierInfo *Id,
546 QualType T, bool ParameterPack,
547 TypeSourceInfo *TInfo) {
548 return new (C) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
549 T, ParameterPack, TInfo);
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000550}
551
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000552NonTypeTemplateParmDecl *
553NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000554 SourceLocation StartLoc, SourceLocation IdLoc,
555 unsigned D, unsigned P,
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000556 IdentifierInfo *Id, QualType T,
557 TypeSourceInfo *TInfo,
558 const QualType *ExpandedTypes,
559 unsigned NumExpandedTypes,
560 TypeSourceInfo **ExpandedTInfos) {
561 unsigned Size = sizeof(NonTypeTemplateParmDecl)
562 + NumExpandedTypes * 2 * sizeof(void*);
563 void *Mem = C.Allocate(Size);
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000564 return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc,
565 D, P, Id, T, TInfo,
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000566 ExpandedTypes, NumExpandedTypes,
567 ExpandedTInfos);
568}
569
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000570NonTypeTemplateParmDecl *
571NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
572 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NonTypeTemplateParmDecl));
573 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
574 SourceLocation(), 0, 0, 0,
575 QualType(), false, 0);
576}
577
578NonTypeTemplateParmDecl *
579NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
580 unsigned NumExpandedTypes) {
581 unsigned Size = sizeof(NonTypeTemplateParmDecl)
582 + NumExpandedTypes * 2 * sizeof(void*);
583
584 void *Mem = AllocateDeserializedDecl(C, ID, Size);
585 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
586 SourceLocation(), 0, 0, 0,
587 QualType(), 0, 0, NumExpandedTypes,
588 0);
589}
590
John McCall76a40212011-02-09 01:13:10 +0000591SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnaraee4bfd42011-03-04 11:03:48 +0000592 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraa2026c92011-03-08 16:41:52 +0000593 return SourceRange(getOuterLocStart(),
594 getDefaultArgument()->getSourceRange().getEnd());
595 return DeclaratorDecl::getSourceRange();
John McCall76a40212011-02-09 01:13:10 +0000596}
597
Douglas Gregord684b002009-02-10 19:49:53 +0000598SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnarad92f7a22010-06-09 09:26:05 +0000599 return hasDefaultArgument()
600 ? getDefaultArgument()->getSourceRange().getBegin()
601 : SourceLocation();
Douglas Gregord684b002009-02-10 19:49:53 +0000602}
603
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000604//===----------------------------------------------------------------------===//
605// TemplateTemplateParmDecl Method Implementations
606//===----------------------------------------------------------------------===//
607
David Blaikie99ba9e32011-12-20 02:48:34 +0000608void TemplateTemplateParmDecl::anchor() { }
609
Richard Smith6964b3f2012-09-07 02:06:42 +0000610TemplateTemplateParmDecl::TemplateTemplateParmDecl(
611 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
612 IdentifierInfo *Id, TemplateParameterList *Params,
613 unsigned NumExpansions, TemplateParameterList * const *Expansions)
614 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
615 TemplateParmPosition(D, P), DefaultArgument(),
616 DefaultArgumentWasInherited(false), ParameterPack(true),
617 ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
618 if (Expansions)
619 std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
620 sizeof(TemplateParameterList*) * NumExpandedParams);
621}
622
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000623TemplateTemplateParmDecl *
Jay Foad4ba2a172011-01-12 09:06:06 +0000624TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000625 SourceLocation L, unsigned D, unsigned P,
Douglas Gregor61c4d282011-01-05 15:48:55 +0000626 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000627 TemplateParameterList *Params) {
Douglas Gregor61c4d282011-01-05 15:48:55 +0000628 return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
629 Params);
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000630}
631
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000632TemplateTemplateParmDecl *
Richard Smith6964b3f2012-09-07 02:06:42 +0000633TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
634 SourceLocation L, unsigned D, unsigned P,
635 IdentifierInfo *Id,
636 TemplateParameterList *Params,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000637 ArrayRef<TemplateParameterList *> Expansions) {
Richard Smith6964b3f2012-09-07 02:06:42 +0000638 void *Mem = C.Allocate(sizeof(TemplateTemplateParmDecl) +
639 sizeof(TemplateParameterList*) * Expansions.size());
640 return new (Mem) TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
641 Expansions.size(),
642 Expansions.data());
643}
644
645TemplateTemplateParmDecl *
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000646TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
647 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTemplateParmDecl));
648 return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, false,
649 0, 0);
650}
651
Richard Smith6964b3f2012-09-07 02:06:42 +0000652TemplateTemplateParmDecl *
653TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
654 unsigned NumExpansions) {
655 unsigned Size = sizeof(TemplateTemplateParmDecl) +
656 sizeof(TemplateParameterList*) * NumExpansions;
657 void *Mem = AllocateDeserializedDecl(C, ID, Size);
658 return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, 0, 0,
659 NumExpansions, 0);
660}
661
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000662//===----------------------------------------------------------------------===//
Douglas Gregor7e063902009-05-11 23:53:27 +0000663// TemplateArgumentList Implementation
664//===----------------------------------------------------------------------===//
Douglas Gregor910f8002010-11-07 23:05:16 +0000665TemplateArgumentList *
666TemplateArgumentList::CreateCopy(ASTContext &Context,
667 const TemplateArgument *Args,
668 unsigned NumArgs) {
669 std::size_t Size = sizeof(TemplateArgumentList)
670 + NumArgs * sizeof(TemplateArgument);
671 void *Mem = Context.Allocate(Size);
672 TemplateArgument *StoredArgs
673 = reinterpret_cast<TemplateArgument *>(
674 static_cast<TemplateArgumentList *>(Mem) + 1);
675 std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
676 return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000677}
678
Argyrios Kyrtzidis71a76052011-09-22 20:07:09 +0000679FunctionTemplateSpecializationInfo *
680FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
681 FunctionTemplateDecl *Template,
682 TemplateSpecializationKind TSK,
683 const TemplateArgumentList *TemplateArgs,
684 const TemplateArgumentListInfo *TemplateArgsAsWritten,
685 SourceLocation POI) {
686 const ASTTemplateArgumentListInfo *ArgsAsWritten = 0;
687 if (TemplateArgsAsWritten)
688 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
689 *TemplateArgsAsWritten);
690
691 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
692 TemplateArgs,
693 ArgsAsWritten,
694 POI);
695}
696
Douglas Gregor7e063902009-05-11 23:53:27 +0000697//===----------------------------------------------------------------------===//
David Blaikie99ba9e32011-12-20 02:48:34 +0000698// TemplateDecl Implementation
699//===----------------------------------------------------------------------===//
700
701void TemplateDecl::anchor() { }
702
703//===----------------------------------------------------------------------===//
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000704// ClassTemplateSpecializationDecl Implementation
705//===----------------------------------------------------------------------===//
706ClassTemplateSpecializationDecl::
Douglas Gregor13c85772010-05-06 00:28:52 +0000707ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000708 DeclContext *DC, SourceLocation StartLoc,
709 SourceLocation IdLoc,
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000710 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000711 const TemplateArgument *Args,
712 unsigned NumArgs,
Douglas Gregor8e9e9ef2009-07-29 23:36:44 +0000713 ClassTemplateSpecializationDecl *PrevDecl)
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000714 : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc,
Douglas Gregor8e9e9ef2009-07-29 23:36:44 +0000715 SpecializedTemplate->getIdentifier(),
716 PrevDecl),
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000717 SpecializedTemplate(SpecializedTemplate),
Abramo Bagnarac98971d2010-06-12 07:44:57 +0000718 ExplicitInfo(0),
Douglas Gregor910f8002010-11-07 23:05:16 +0000719 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
Douglas Gregor7e063902009-05-11 23:53:27 +0000720 SpecializationKind(TSK_Undeclared) {
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000721}
Mike Stump1eb44332009-09-09 15:08:12 +0000722
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000723ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000724 : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0),
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000725 ExplicitInfo(0),
726 SpecializationKind(TSK_Undeclared) {
727}
728
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000729ClassTemplateSpecializationDecl *
Douglas Gregor13c85772010-05-06 00:28:52 +0000730ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000731 DeclContext *DC,
732 SourceLocation StartLoc,
733 SourceLocation IdLoc,
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000734 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000735 const TemplateArgument *Args,
736 unsigned NumArgs,
Douglas Gregorcc636682009-02-17 23:15:12 +0000737 ClassTemplateSpecializationDecl *PrevDecl) {
Douglas Gregorcc636682009-02-17 23:15:12 +0000738 ClassTemplateSpecializationDecl *Result
Mike Stump1eb44332009-09-09 15:08:12 +0000739 = new (Context)ClassTemplateSpecializationDecl(Context,
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000740 ClassTemplateSpecialization,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000741 TK, DC, StartLoc, IdLoc,
Douglas Gregor7e063902009-05-11 23:53:27 +0000742 SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000743 Args, NumArgs,
Douglas Gregor8e9e9ef2009-07-29 23:36:44 +0000744 PrevDecl);
Douglas Gregor6bd99292013-02-09 01:35:03 +0000745 Result->MayHaveOutOfDateDef = false;
746
Douglas Gregorcc636682009-02-17 23:15:12 +0000747 Context.getTypeDeclType(Result, PrevDecl);
748 return Result;
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000749}
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000750
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000751ClassTemplateSpecializationDecl *
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000752ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
753 unsigned ID) {
754 void *Mem = AllocateDeserializedDecl(C, ID,
755 sizeof(ClassTemplateSpecializationDecl));
Douglas Gregor6bd99292013-02-09 01:35:03 +0000756 ClassTemplateSpecializationDecl *Result =
757 new (Mem) ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
758 Result->MayHaveOutOfDateDef = false;
759 return Result;
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000760}
761
Benjamin Kramer5eada842013-02-22 15:46:01 +0000762void ClassTemplateSpecializationDecl::getNameForDiagnostic(
763 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
764 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
Douglas Gregorda2142f2011-02-19 18:51:44 +0000765
766 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Benjamin Kramer5eada842013-02-22 15:46:01 +0000767 TemplateSpecializationType::PrintTemplateArgumentList(
768 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
Douglas Gregorda2142f2011-02-19 18:51:44 +0000769}
770
Douglas Gregor37d93e92009-08-02 23:24:31 +0000771ClassTemplateDecl *
Mike Stump1eb44332009-09-09 15:08:12 +0000772ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
773 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor37d93e92009-08-02 23:24:31 +0000774 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
775 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
776 return SpecializedTemplate.get<ClassTemplateDecl*>();
777}
778
Abramo Bagnara4a85a732011-03-04 14:20:30 +0000779SourceRange
780ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnara09d82122011-10-03 20:34:03 +0000781 if (ExplicitInfo) {
Abramo Bagnarab2e80012012-10-15 21:06:42 +0000782 SourceLocation Begin = getTemplateKeywordLoc();
783 if (Begin.isValid()) {
784 // Here we have an explicit (partial) specialization or instantiation.
785 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
786 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
787 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
788 if (getExternLoc().isValid())
789 Begin = getExternLoc();
790 SourceLocation End = getRBraceLoc();
791 if (End.isInvalid())
792 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
793 return SourceRange(Begin, End);
794 }
795 // An implicit instantiation of a class template partial specialization
796 // uses ExplicitInfo to record the TypeAsWritten, but the source
797 // locations should be retrieved from the instantiation pattern.
798 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
799 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
800 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
801 assert(inst_from != 0);
802 return inst_from->getSourceRange();
Abramo Bagnara09d82122011-10-03 20:34:03 +0000803 }
804 else {
805 // No explicit info available.
806 llvm::PointerUnion<ClassTemplateDecl *,
807 ClassTemplatePartialSpecializationDecl *>
808 inst_from = getInstantiatedFrom();
809 if (inst_from.isNull())
810 return getSpecializedTemplate()->getSourceRange();
811 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
812 return ctd->getSourceRange();
813 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
814 ->getSourceRange();
815 }
Abramo Bagnara4a85a732011-03-04 14:20:30 +0000816}
817
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000818//===----------------------------------------------------------------------===//
819// ClassTemplatePartialSpecializationDecl Implementation
820//===----------------------------------------------------------------------===//
David Blaikie99ba9e32011-12-20 02:48:34 +0000821void ClassTemplatePartialSpecializationDecl::anchor() { }
822
Douglas Gregor9a299e02011-03-04 17:52:15 +0000823ClassTemplatePartialSpecializationDecl::
824ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000825 DeclContext *DC,
826 SourceLocation StartLoc,
827 SourceLocation IdLoc,
Douglas Gregor9a299e02011-03-04 17:52:15 +0000828 TemplateParameterList *Params,
829 ClassTemplateDecl *SpecializedTemplate,
830 const TemplateArgument *Args,
831 unsigned NumArgs,
832 TemplateArgumentLoc *ArgInfos,
833 unsigned NumArgInfos,
834 ClassTemplatePartialSpecializationDecl *PrevDecl,
835 unsigned SequenceNumber)
836 : ClassTemplateSpecializationDecl(Context,
837 ClassTemplatePartialSpecialization,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000838 TK, DC, StartLoc, IdLoc,
839 SpecializedTemplate,
Douglas Gregor9a299e02011-03-04 17:52:15 +0000840 Args, NumArgs, PrevDecl),
841 TemplateParams(Params), ArgsAsWritten(ArgInfos),
842 NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
843 InstantiatedFromMember(0, false)
844{
Douglas Gregor787a40d2011-03-04 18:32:38 +0000845 AdoptTemplateParameterList(Params, this);
Douglas Gregor9a299e02011-03-04 17:52:15 +0000846}
847
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000848ClassTemplatePartialSpecializationDecl *
849ClassTemplatePartialSpecializationDecl::
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000850Create(ASTContext &Context, TagKind TK,DeclContext *DC,
851 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000852 TemplateParameterList *Params,
853 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000854 const TemplateArgument *Args,
855 unsigned NumArgs,
John McCalld5532b62009-11-23 01:53:49 +0000856 const TemplateArgumentListInfo &ArgInfos,
John McCall3cb0ebd2010-03-10 03:28:59 +0000857 QualType CanonInjectedType,
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000858 ClassTemplatePartialSpecializationDecl *PrevDecl,
859 unsigned SequenceNumber) {
John McCalld5532b62009-11-23 01:53:49 +0000860 unsigned N = ArgInfos.size();
John McCall833ca992009-10-29 08:12:44 +0000861 TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
862 for (unsigned I = 0; I != N; ++I)
863 ClonedArgs[I] = ArgInfos[I];
864
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000865 ClassTemplatePartialSpecializationDecl *Result
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000866 = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC,
867 StartLoc, IdLoc,
868 Params,
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000869 SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000870 Args, NumArgs,
John McCall833ca992009-10-29 08:12:44 +0000871 ClonedArgs, N,
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000872 PrevDecl,
873 SequenceNumber);
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000874 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor6bd99292013-02-09 01:35:03 +0000875 Result->MayHaveOutOfDateDef = false;
John McCall3cb0ebd2010-03-10 03:28:59 +0000876
877 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000878 return Result;
879}
John McCalldd4a3b02009-09-16 22:47:08 +0000880
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000881ClassTemplatePartialSpecializationDecl *
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000882ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
883 unsigned ID) {
884 void *Mem = AllocateDeserializedDecl(C, ID,
885 sizeof(ClassTemplatePartialSpecializationDecl));
Douglas Gregor6bd99292013-02-09 01:35:03 +0000886 ClassTemplatePartialSpecializationDecl *Result
887 = new (Mem) ClassTemplatePartialSpecializationDecl();
888 Result->MayHaveOutOfDateDef = false;
889 return Result;
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000890}
891
John McCalldd4a3b02009-09-16 22:47:08 +0000892//===----------------------------------------------------------------------===//
893// FriendTemplateDecl Implementation
894//===----------------------------------------------------------------------===//
895
David Blaikie99ba9e32011-12-20 02:48:34 +0000896void FriendTemplateDecl::anchor() { }
897
John McCalldd4a3b02009-09-16 22:47:08 +0000898FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
899 DeclContext *DC,
900 SourceLocation L,
901 unsigned NParams,
902 TemplateParameterList **Params,
903 FriendUnion Friend,
904 SourceLocation FLoc) {
905 FriendTemplateDecl *Result
906 = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
907 return Result;
908}
Argyrios Kyrtzidis554e6aa2010-07-22 16:04:10 +0000909
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000910FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
911 unsigned ID) {
912 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FriendTemplateDecl));
913 return new (Mem) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis554e6aa2010-07-22 16:04:10 +0000914}
Richard Smith3e4c6c42011-05-05 21:57:07 +0000915
916//===----------------------------------------------------------------------===//
917// TypeAliasTemplateDecl Implementation
918//===----------------------------------------------------------------------===//
919
920TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
921 DeclContext *DC,
922 SourceLocation L,
923 DeclarationName Name,
924 TemplateParameterList *Params,
925 NamedDecl *Decl) {
926 AdoptTemplateParameterList(Params, DC);
927 return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl);
928}
929
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000930TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
931 unsigned ID) {
932 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasTemplateDecl));
933 return new (Mem) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(),
934 0, 0);
Richard Smith3e4c6c42011-05-05 21:57:07 +0000935}
936
937void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
938 static_cast<Common *>(Ptr)->~Common();
939}
940RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob76d9712013-01-23 16:52:57 +0000941TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3e4c6c42011-05-05 21:57:07 +0000942 Common *CommonPtr = new (C) Common;
943 C.AddDeallocation(DeallocateCommon, CommonPtr);
944 return CommonPtr;
945}
946
David Blaikie99ba9e32011-12-20 02:48:34 +0000947//===----------------------------------------------------------------------===//
948// ClassScopeFunctionSpecializationDecl Implementation
949//===----------------------------------------------------------------------===//
950
951void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000952
953ClassScopeFunctionSpecializationDecl *
954ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
955 unsigned ID) {
956 void *Mem = AllocateDeserializedDecl(C, ID,
957 sizeof(ClassScopeFunctionSpecializationDecl));
Nico Weber6b020092012-06-25 17:21:05 +0000958 return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0,
959 false, TemplateArgumentListInfo());
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000960}
Larisse Voufoef4579c2013-08-06 01:03:05 +0000961
962//===----------------------------------------------------------------------===//
963// VarTemplateDecl Implementation
964//===----------------------------------------------------------------------===//
965
966void VarTemplateDecl::DeallocateCommon(void *Ptr) {
967 static_cast<Common *>(Ptr)->~Common();
968}
969
970VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
971 SourceLocation L, DeclarationName Name,
972 TemplateParameterList *Params,
973 NamedDecl *Decl,
974 VarTemplateDecl *PrevDecl) {
975 VarTemplateDecl *New = new (C) VarTemplateDecl(DC, L, Name, Params, Decl);
976 New->setPreviousDeclaration(PrevDecl);
977 return New;
978}
979
980VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
981 unsigned ID) {
982 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(VarTemplateDecl));
983 return new (Mem) VarTemplateDecl(EmptyShell());
984}
985
986// FIXME: Should this be unified accross class, function and variable
987// templates? Perhaps also moved to RedeclarableTemplateDecl?
988void VarTemplateDecl::LoadLazySpecializations() const {
989 Common *CommonPtr = getCommonPtr();
990 if (CommonPtr->LazySpecializations) {
991 ASTContext &Context = getASTContext();
992 uint32_t *Specs = CommonPtr->LazySpecializations;
993 CommonPtr->LazySpecializations = 0;
994 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
995 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
996 }
997}
998
999llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1000VarTemplateDecl::getSpecializations() const {
1001 LoadLazySpecializations();
1002 return getCommonPtr()->Specializations;
1003}
1004
1005llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1006VarTemplateDecl::getPartialSpecializations() {
1007 LoadLazySpecializations();
1008 return getCommonPtr()->PartialSpecializations;
1009}
1010
1011RedeclarableTemplateDecl::CommonBase *
1012VarTemplateDecl::newCommon(ASTContext &C) const {
1013 Common *CommonPtr = new (C) Common;
1014 C.AddDeallocation(DeallocateCommon, CommonPtr);
1015 return CommonPtr;
1016}
1017
1018VarTemplateSpecializationDecl *
1019VarTemplateDecl::findSpecialization(const TemplateArgument *Args,
1020 unsigned NumArgs, void *&InsertPos) {
1021 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
1022}
1023
1024void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1025 void *InsertPos) {
1026 if (InsertPos)
1027 getSpecializations().InsertNode(D, InsertPos);
1028 else {
1029 VarTemplateSpecializationDecl *Existing =
1030 getSpecializations().GetOrInsertNode(D);
1031 (void)Existing;
1032 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1033 }
1034 if (ASTMutationListener *L = getASTMutationListener())
1035 L->AddedCXXTemplateSpecialization(this, D);
1036}
1037
1038VarTemplatePartialSpecializationDecl *
1039VarTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
1040 unsigned NumArgs, void *&InsertPos) {
1041 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
1042 InsertPos);
1043}
1044
1045void VarTemplateDecl::AddPartialSpecialization(
1046 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1047 if (InsertPos)
1048 getPartialSpecializations().InsertNode(D, InsertPos);
1049 else {
1050 VarTemplatePartialSpecializationDecl *Existing =
1051 getPartialSpecializations().GetOrInsertNode(D);
1052 (void)Existing;
1053 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1054 }
1055
1056 if (ASTMutationListener *L = getASTMutationListener())
1057 L->AddedCXXTemplateSpecialization(this, D);
1058}
1059
1060void VarTemplateDecl::getPartialSpecializations(
1061 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1062 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1063 getPartialSpecializations();
1064 PS.clear();
1065 PS.resize(PartialSpecs.size());
1066 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1067 P = PartialSpecs.begin(),
1068 PEnd = PartialSpecs.end();
1069 P != PEnd; ++P) {
1070 assert(!PS[P->getSequenceNumber()]);
1071 PS[P->getSequenceNumber()] = P->getMostRecentDecl();
1072 }
1073}
1074
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,
1165 TemplateArgumentLoc *ArgInfos, unsigned NumArgInfos,
1166 unsigned SequenceNumber)
1167 : VarTemplateSpecializationDecl(Context, VarTemplatePartialSpecialization,
1168 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1169 TInfo, S, Args, NumArgs),
1170 TemplateParams(Params), ArgsAsWritten(ArgInfos),
1171 NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
1172 InstantiatedFromMember(0, false) {
1173 // TODO: The template parameters should be in DC by now. Verify.
1174 // AdoptTemplateParameterList(Params, DC);
1175}
1176
1177VarTemplatePartialSpecializationDecl *
1178VarTemplatePartialSpecializationDecl::Create(
1179 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1180 SourceLocation IdLoc, TemplateParameterList *Params,
1181 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1182 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
1183 const TemplateArgumentListInfo &ArgInfos, unsigned SequenceNumber) {
1184 unsigned N = ArgInfos.size();
1185 TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
1186 for (unsigned I = 0; I != N; ++I)
1187 ClonedArgs[I] = ArgInfos[I];
1188
1189 VarTemplatePartialSpecializationDecl *Result =
1190 new (Context) VarTemplatePartialSpecializationDecl(
1191 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1192 S, Args, NumArgs, ClonedArgs, N, SequenceNumber);
1193 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1194 return Result;
1195}
1196
1197VarTemplatePartialSpecializationDecl *
1198VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1199 unsigned ID) {
1200 void *Mem = AllocateDeserializedDecl(
1201 C, ID, sizeof(VarTemplatePartialSpecializationDecl));
1202 VarTemplatePartialSpecializationDecl *Result =
1203 new (Mem) VarTemplatePartialSpecializationDecl();
1204 return Result;
1205}