blob: ac0d54f5011e1ae4676ace2f5c80a404140c37df [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();
400 PS.resize(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();
403 P != PEnd; ++P) {
404 assert(!PS[P->getSequenceNumber()]);
Douglas Gregorec9fd132012-01-14 16:38:05 +0000405 PS[P->getSequenceNumber()] = P->getMostRecentDecl();
Douglas Gregor407e9612010-04-30 05:56:50 +0000406 }
407}
408
Douglas Gregor15301382009-07-30 17:40:51 +0000409ClassTemplatePartialSpecializationDecl *
410ClassTemplateDecl::findPartialSpecialization(QualType T) {
411 ASTContext &Context = getASTContext();
Chandler Carruthb41171b2012-05-03 23:49:05 +0000412 using llvm::FoldingSetVector;
413 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregor15301382009-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 McCall2408e322010-04-27 00:57:59 +0000418 if (Context.hasSameType(P->getInjectedSpecializationType(), T))
Douglas Gregorec9fd132012-01-14 16:38:05 +0000419 return P->getMostRecentDecl();
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000420 }
421
422 return 0;
423}
424
425ClassTemplatePartialSpecializationDecl *
426ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
427 ClassTemplatePartialSpecializationDecl *D) {
428 Decl *DCanon = D->getCanonicalDecl();
Chandler Carruthb41171b2012-05-03 23:49:05 +0000429 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000430 P = getPartialSpecializations().begin(),
431 PEnd = getPartialSpecializations().end();
432 P != PEnd; ++P) {
433 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
Douglas Gregorec9fd132012-01-14 16:38:05 +0000434 return P->getMostRecentDecl();
Douglas Gregor15301382009-07-30 17:40:51 +0000435 }
Mike Stump11289f42009-09-09 15:08:12 +0000436
Douglas Gregor15301382009-07-30 17:40:51 +0000437 return 0;
438}
439
John McCalle78aac42010-03-10 03:28:59 +0000440QualType
Douglas Gregor9961ce92010-07-08 18:37:38 +0000441ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000442 Common *CommonPtr = getCommonPtr();
Douglas Gregore362cea2009-05-10 22:57:19 +0000443 if (!CommonPtr->InjectedClassNameType.isNull())
444 return CommonPtr->InjectedClassNameType;
445
Douglas Gregor8092e802010-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 Gregor9961ce92010-07-08 18:37:38 +0000453 ASTContext &Context = getASTContext();
Douglas Gregore362cea2009-05-10 22:57:19 +0000454 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000455 SmallVector<TemplateArgument, 16> TemplateArgs;
Douglas Gregor43669f82011-03-05 17:54:25 +0000456 TemplateArgs.resize(Params->size());
457 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
Douglas Gregore362cea2009-05-10 22:57:19 +0000458 CommonPtr->InjectedClassNameType
Douglas Gregora8e02e72009-07-28 23:00:59 +0000459 = Context.getTemplateSpecializationType(TemplateName(this),
Douglas Gregore362cea2009-05-10 22:57:19 +0000460 &TemplateArgs[0],
Douglas Gregora8e02e72009-07-28 23:00:59 +0000461 TemplateArgs.size());
Douglas Gregore362cea2009-05-10 22:57:19 +0000462 return CommonPtr->InjectedClassNameType;
463}
464
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000465//===----------------------------------------------------------------------===//
466// TemplateTypeParm Allocation/Deallocation Method Implementations
467//===----------------------------------------------------------------------===//
468
469TemplateTypeParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000470TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000471 SourceLocation KeyLoc, SourceLocation NameLoc,
472 unsigned D, unsigned P, IdentifierInfo *Id,
473 bool Typename, bool ParameterPack) {
Chandler Carruth08836322011-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 Gregorded2d7b2009-02-04 19:02:06 +0000479}
480
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000481TemplateTypeParmDecl *
Douglas Gregor72172e92012-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 Kyrtzidis39f0e302010-07-02 11:54:55 +0000486}
487
John McCall0ad16662009-10-29 08:12:44 +0000488SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara23485e02011-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 Bagnarab3185b02011-03-06 15:48:19 +0000496 return SourceRange(getLocStart(),
Abramo Bagnara23485e02011-03-04 12:42:03 +0000497 DefaultArgument->getTypeLoc().getEndLoc());
498 else
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000499 return TypeDecl::getSourceRange();
John McCall0ad16662009-10-29 08:12:44 +0000500}
501
Douglas Gregor21610382009-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 Carruth08836322011-05-01 00:51:33 +0000510bool TemplateTypeParmDecl::isParameterPack() const {
511 return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack();
512}
513
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000514//===----------------------------------------------------------------------===//
515// NonTypeTemplateParmDecl Method Implementations
516//===----------------------------------------------------------------------===//
517
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000518NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000519 SourceLocation StartLoc,
520 SourceLocation IdLoc,
521 unsigned D, unsigned P,
522 IdentifierInfo *Id,
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000523 QualType T,
524 TypeSourceInfo *TInfo,
525 const QualType *ExpandedTypes,
526 unsigned NumExpandedTypes,
527 TypeSourceInfo **ExpandedTInfos)
Abramo Bagnaradff19302011-03-08 08:55:46 +0000528 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
Douglas Gregor0231d8d2011-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 Gregorded2d7b2009-02-04 19:02:06 +0000542NonTypeTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000543NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-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 Gregorded2d7b2009-02-04 19:02:06 +0000550}
551
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000552NonTypeTemplateParmDecl *
553NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000554 SourceLocation StartLoc, SourceLocation IdLoc,
555 unsigned D, unsigned P,
Douglas Gregor0231d8d2011-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 Bagnaradff19302011-03-08 08:55:46 +0000564 return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc,
565 D, P, Id, T, TInfo,
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000566 ExpandedTypes, NumExpandedTypes,
567 ExpandedTInfos);
568}
569
Douglas Gregor72172e92012-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 McCallf4cd4f92011-02-09 01:13:10 +0000591SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnarae15d5532011-03-04 11:03:48 +0000592 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraea947882011-03-08 16:41:52 +0000593 return SourceRange(getOuterLocStart(),
594 getDefaultArgument()->getSourceRange().getEnd());
595 return DeclaratorDecl::getSourceRange();
John McCallf4cd4f92011-02-09 01:13:10 +0000596}
597
Douglas Gregordba32632009-02-10 19:49:53 +0000598SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara656e3002010-06-09 09:26:05 +0000599 return hasDefaultArgument()
600 ? getDefaultArgument()->getSourceRange().getBegin()
601 : SourceLocation();
Douglas Gregordba32632009-02-10 19:49:53 +0000602}
603
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000604//===----------------------------------------------------------------------===//
605// TemplateTemplateParmDecl Method Implementations
606//===----------------------------------------------------------------------===//
607
David Blaikie68e081d2011-12-20 02:48:34 +0000608void TemplateTemplateParmDecl::anchor() { }
609
Richard Smith1fde8ec2012-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 Gregorded2d7b2009-02-04 19:02:06 +0000623TemplateTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000624TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000625 SourceLocation L, unsigned D, unsigned P,
Douglas Gregorf5500772011-01-05 15:48:55 +0000626 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000627 TemplateParameterList *Params) {
Douglas Gregorf5500772011-01-05 15:48:55 +0000628 return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
629 Params);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000630}
631
Douglas Gregor72172e92012-01-05 21:55:30 +0000632TemplateTemplateParmDecl *
Richard Smith1fde8ec2012-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 Gribenkof8579502013-01-12 19:30:44 +0000637 ArrayRef<TemplateParameterList *> Expansions) {
Richard Smith1fde8ec2012-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 Gregor72172e92012-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 Smith1fde8ec2012-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 Gregor264ec4f2009-02-17 01:05:43 +0000662//===----------------------------------------------------------------------===//
Douglas Gregord002c7b2009-05-11 23:53:27 +0000663// TemplateArgumentList Implementation
664//===----------------------------------------------------------------------===//
Douglas Gregor1ccc8412010-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 Kyrtzidisfe6ba882010-06-23 13:48:23 +0000677}
678
Argyrios Kyrtzidise9a24432011-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 Gregord002c7b2009-05-11 23:53:27 +0000697//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000698// TemplateDecl Implementation
699//===----------------------------------------------------------------------===//
700
701void TemplateDecl::anchor() { }
702
703//===----------------------------------------------------------------------===//
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000704// ClassTemplateSpecializationDecl Implementation
705//===----------------------------------------------------------------------===//
706ClassTemplateSpecializationDecl::
Douglas Gregore9029562010-05-06 00:28:52 +0000707ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000708 DeclContext *DC, SourceLocation StartLoc,
709 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000710 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000711 const TemplateArgument *Args,
712 unsigned NumArgs,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000713 ClassTemplateSpecializationDecl *PrevDecl)
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000714 : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000715 SpecializedTemplate->getIdentifier(),
716 PrevDecl),
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000717 SpecializedTemplate(SpecializedTemplate),
Abramo Bagnara8075c852010-06-12 07:44:57 +0000718 ExplicitInfo(0),
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000719 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
Douglas Gregord002c7b2009-05-11 23:53:27 +0000720 SpecializationKind(TSK_Undeclared) {
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000721}
Mike Stump11289f42009-09-09 15:08:12 +0000722
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000723ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000724 : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0),
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000725 ExplicitInfo(0),
726 SpecializationKind(TSK_Undeclared) {
727}
728
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000729ClassTemplateSpecializationDecl *
Douglas Gregore9029562010-05-06 00:28:52 +0000730ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000731 DeclContext *DC,
732 SourceLocation StartLoc,
733 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000734 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000735 const TemplateArgument *Args,
736 unsigned NumArgs,
Douglas Gregor67a65642009-02-17 23:15:12 +0000737 ClassTemplateSpecializationDecl *PrevDecl) {
Douglas Gregor67a65642009-02-17 23:15:12 +0000738 ClassTemplateSpecializationDecl *Result
Mike Stump11289f42009-09-09 15:08:12 +0000739 = new (Context)ClassTemplateSpecializationDecl(Context,
Douglas Gregor2373c592009-05-31 09:31:02 +0000740 ClassTemplateSpecialization,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000741 TK, DC, StartLoc, IdLoc,
Douglas Gregord002c7b2009-05-11 23:53:27 +0000742 SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000743 Args, NumArgs,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000744 PrevDecl);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000745 Result->MayHaveOutOfDateDef = false;
746
Douglas Gregor67a65642009-02-17 23:15:12 +0000747 Context.getTypeDeclType(Result, PrevDecl);
748 return Result;
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000749}
Douglas Gregor2373c592009-05-31 09:31:02 +0000750
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000751ClassTemplateSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000752ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
753 unsigned ID) {
754 void *Mem = AllocateDeserializedDecl(C, ID,
755 sizeof(ClassTemplateSpecializationDecl));
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000756 ClassTemplateSpecializationDecl *Result =
757 new (Mem) ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
758 Result->MayHaveOutOfDateDef = false;
759 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000760}
761
Benjamin Kramer9170e912013-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 Gregorb11aad82011-02-19 18:51:44 +0000765
766 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Benjamin Kramer9170e912013-02-22 15:46:01 +0000767 TemplateSpecializationType::PrintTemplateArgumentList(
768 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000769}
770
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000771ClassTemplateDecl *
Mike Stump11289f42009-09-09 15:08:12 +0000772ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
773 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000774 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
775 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
776 return SpecializedTemplate.get<ClassTemplateDecl*>();
777}
778
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000779SourceRange
780ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000781 if (ExplicitInfo) {
Abramo Bagnarac76dcbd2012-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 Bagnarafd3a4552011-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 Bagnaraa0935262011-03-04 14:20:30 +0000816}
817
Douglas Gregor2373c592009-05-31 09:31:02 +0000818//===----------------------------------------------------------------------===//
819// ClassTemplatePartialSpecializationDecl Implementation
820//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000821void ClassTemplatePartialSpecializationDecl::anchor() { }
822
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000823ClassTemplatePartialSpecializationDecl::
824ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000825 DeclContext *DC,
826 SourceLocation StartLoc,
827 SourceLocation IdLoc,
Douglas Gregorfd7c2252011-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 Bagnara29c2d462011-03-09 14:09:51 +0000838 TK, DC, StartLoc, IdLoc,
839 SpecializedTemplate,
Douglas Gregorfd7c2252011-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 Gregor3c41bf72011-03-04 18:32:38 +0000845 AdoptTemplateParameterList(Params, this);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000846}
847
Douglas Gregor2373c592009-05-31 09:31:02 +0000848ClassTemplatePartialSpecializationDecl *
849ClassTemplatePartialSpecializationDecl::
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000850Create(ASTContext &Context, TagKind TK,DeclContext *DC,
851 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregor2373c592009-05-31 09:31:02 +0000852 TemplateParameterList *Params,
853 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000854 const TemplateArgument *Args,
855 unsigned NumArgs,
John McCall6b51f282009-11-23 01:53:49 +0000856 const TemplateArgumentListInfo &ArgInfos,
John McCalle78aac42010-03-10 03:28:59 +0000857 QualType CanonInjectedType,
Douglas Gregor407e9612010-04-30 05:56:50 +0000858 ClassTemplatePartialSpecializationDecl *PrevDecl,
859 unsigned SequenceNumber) {
John McCall6b51f282009-11-23 01:53:49 +0000860 unsigned N = ArgInfos.size();
John McCall0ad16662009-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 Gregor2373c592009-05-31 09:31:02 +0000865 ClassTemplatePartialSpecializationDecl *Result
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000866 = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC,
867 StartLoc, IdLoc,
868 Params,
Douglas Gregor2373c592009-05-31 09:31:02 +0000869 SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000870 Args, NumArgs,
John McCall0ad16662009-10-29 08:12:44 +0000871 ClonedArgs, N,
Douglas Gregor407e9612010-04-30 05:56:50 +0000872 PrevDecl,
873 SequenceNumber);
Douglas Gregor2373c592009-05-31 09:31:02 +0000874 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000875 Result->MayHaveOutOfDateDef = false;
John McCalle78aac42010-03-10 03:28:59 +0000876
877 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregor2373c592009-05-31 09:31:02 +0000878 return Result;
879}
John McCall11083da2009-09-16 22:47:08 +0000880
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000881ClassTemplatePartialSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000882ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
883 unsigned ID) {
884 void *Mem = AllocateDeserializedDecl(C, ID,
885 sizeof(ClassTemplatePartialSpecializationDecl));
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000886 ClassTemplatePartialSpecializationDecl *Result
887 = new (Mem) ClassTemplatePartialSpecializationDecl();
888 Result->MayHaveOutOfDateDef = false;
889 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000890}
891
John McCall11083da2009-09-16 22:47:08 +0000892//===----------------------------------------------------------------------===//
893// FriendTemplateDecl Implementation
894//===----------------------------------------------------------------------===//
895
David Blaikie68e081d2011-12-20 02:48:34 +0000896void FriendTemplateDecl::anchor() { }
897
John McCall11083da2009-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 Kyrtzidis165b5812010-07-22 16:04:10 +0000909
Douglas Gregor72172e92012-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 Kyrtzidis165b5812010-07-22 16:04:10 +0000914}
Richard Smith3f1b5d02011-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 Gregor72172e92012-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 Smith3f1b5d02011-05-05 21:57:07 +0000935}
936
937void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
938 static_cast<Common *>(Ptr)->~Common();
939}
940RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000941TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3f1b5d02011-05-05 21:57:07 +0000942 Common *CommonPtr = new (C) Common;
943 C.AddDeallocation(DeallocateCommon, CommonPtr);
944 return CommonPtr;
945}
946
David Blaikie68e081d2011-12-20 02:48:34 +0000947//===----------------------------------------------------------------------===//
948// ClassScopeFunctionSpecializationDecl Implementation
949//===----------------------------------------------------------------------===//
950
951void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor72172e92012-01-05 21:55:30 +0000952
953ClassScopeFunctionSpecializationDecl *
954ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
955 unsigned ID) {
956 void *Mem = AllocateDeserializedDecl(C, ID,
957 sizeof(ClassScopeFunctionSpecializationDecl));
Nico Weber7b5a7162012-06-25 17:21:05 +0000958 return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0,
959 false, TemplateArgumentListInfo());
Douglas Gregor72172e92012-01-05 21:55:30 +0000960}