blob: d764d2bedb1d21eec836d4a0b9a4169bf4e9a7cb [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
Argyrios Kyrtzidis2c853e42010-07-20 13:59:58 +0000248FunctionDecl *
249FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
250 unsigned NumArgs, void *&InsertPos) {
Peter Collingbourne40485902010-07-30 17:09:04 +0000251 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
Argyrios Kyrtzidis2c853e42010-07-20 13:59:58 +0000252}
253
Sebastian Redl5bbcdbf2011-04-14 14:07:59 +0000254void FunctionTemplateDecl::addSpecialization(
255 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
Douglas Gregor1e1e9722012-03-28 14:34:23 +0000256 if (InsertPos)
257 getSpecializations().InsertNode(Info, InsertPos);
258 else
259 getSpecializations().GetOrInsertNode(Info);
Sebastian Redl5bbcdbf2011-04-14 14:07:59 +0000260 if (ASTMutationListener *L = getASTMutationListener())
261 L->AddedCXXTemplateSpecialization(this, Info->Function);
262}
263
Richard Smith7a9f7c72013-05-17 03:04:50 +0000264ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
Douglas Gregorc494f772011-03-05 17:54:25 +0000265 TemplateParameterList *Params = getTemplateParameters();
266 Common *CommonPtr = getCommonPtr();
267 if (!CommonPtr->InjectedArgs) {
268 CommonPtr->InjectedArgs
Richard Smith7a9f7c72013-05-17 03:04:50 +0000269 = new (getASTContext()) TemplateArgument[Params->size()];
270 GenerateInjectedTemplateArgs(getASTContext(), Params,
Douglas Gregorc494f772011-03-05 17:54:25 +0000271 CommonPtr->InjectedArgs);
272 }
Richard Smith7a9f7c72013-05-17 03:04:50 +0000273
274 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
Douglas Gregorc494f772011-03-05 17:54:25 +0000275}
276
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000277//===----------------------------------------------------------------------===//
278// ClassTemplateDecl Implementation
279//===----------------------------------------------------------------------===//
280
Douglas Gregor00545312010-05-23 18:26:36 +0000281void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
282 static_cast<Common *>(Ptr)->~Common();
283}
284
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000285ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
286 DeclContext *DC,
287 SourceLocation L,
288 DeclarationName Name,
289 TemplateParameterList *Params,
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000290 NamedDecl *Decl,
291 ClassTemplateDecl *PrevDecl) {
Douglas Gregor787a40d2011-03-04 18:32:38 +0000292 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +0000293 ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
Argyrios Kyrtzidis5bf1bdc2010-06-21 10:57:41 +0000294 New->setPreviousDeclaration(PrevDecl);
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +0000295 return New;
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000296}
297
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000298ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
299 unsigned ID) {
300 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ClassTemplateDecl));
301 return new (Mem) ClassTemplateDecl(EmptyShell());
Douglas Gregor9a299e02011-03-04 17:52:15 +0000302}
303
Dmitri Gribenkoe252a892013-02-14 13:20:36 +0000304void ClassTemplateDecl::LoadLazySpecializations() const {
Douglas Gregorc8e5cf82010-10-27 22:21:36 +0000305 Common *CommonPtr = getCommonPtr();
306 if (CommonPtr->LazySpecializations) {
307 ASTContext &Context = getASTContext();
308 uint32_t *Specs = CommonPtr->LazySpecializations;
309 CommonPtr->LazySpecializations = 0;
310 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
311 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
312 }
313}
314
Chandler Carruthd964d632012-05-03 23:49:05 +0000315llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
Dmitri Gribenkoe252a892013-02-14 13:20:36 +0000316ClassTemplateDecl::getSpecializations() const {
Douglas Gregorc8e5cf82010-10-27 22:21:36 +0000317 LoadLazySpecializations();
318 return getCommonPtr()->Specializations;
319}
320
Chandler Carruthd964d632012-05-03 23:49:05 +0000321llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
Douglas Gregorc8e5cf82010-10-27 22:21:36 +0000322ClassTemplateDecl::getPartialSpecializations() {
323 LoadLazySpecializations();
324 return getCommonPtr()->PartialSpecializations;
325}
326
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +0000327RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob76d9712013-01-23 16:52:57 +0000328ClassTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +0000329 Common *CommonPtr = new (C) Common;
330 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000331 return CommonPtr;
332}
333
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000334ClassTemplateSpecializationDecl *
335ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
336 unsigned NumArgs, void *&InsertPos) {
Peter Collingbourne40485902010-07-30 17:09:04 +0000337 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000338}
339
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000340void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
341 void *InsertPos) {
Douglas Gregor1e1e9722012-03-28 14:34:23 +0000342 if (InsertPos)
343 getSpecializations().InsertNode(D, InsertPos);
344 else {
345 ClassTemplateSpecializationDecl *Existing
346 = getSpecializations().GetOrInsertNode(D);
347 (void)Existing;
348 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
349 }
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000350 if (ASTMutationListener *L = getASTMutationListener())
351 L->AddedCXXTemplateSpecialization(this, D);
352}
353
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000354ClassTemplatePartialSpecializationDecl *
355ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
356 unsigned NumArgs,
357 void *&InsertPos) {
Peter Collingbourne40485902010-07-30 17:09:04 +0000358 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
359 InsertPos);
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000360}
361
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000362void ClassTemplateDecl::AddPartialSpecialization(
363 ClassTemplatePartialSpecializationDecl *D,
364 void *InsertPos) {
Douglas Gregor1e1e9722012-03-28 14:34:23 +0000365 if (InsertPos)
366 getPartialSpecializations().InsertNode(D, InsertPos);
367 else {
368 ClassTemplatePartialSpecializationDecl *Existing
369 = getPartialSpecializations().GetOrInsertNode(D);
370 (void)Existing;
371 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
372 }
373
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000374 if (ASTMutationListener *L = getASTMutationListener())
375 L->AddedCXXTemplateSpecialization(this, D);
376}
377
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000378void ClassTemplateDecl::getPartialSpecializations(
Chris Lattner5f9e2722011-07-23 10:55:15 +0000379 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
Chandler Carruthd964d632012-05-03 23:49:05 +0000380 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
Argyrios Kyrtzidis5bf1bdc2010-06-21 10:57:41 +0000381 = getPartialSpecializations();
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000382 PS.clear();
383 PS.resize(PartialSpecs.size());
Chandler Carruthd964d632012-05-03 23:49:05 +0000384 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000385 P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
386 P != PEnd; ++P) {
387 assert(!PS[P->getSequenceNumber()]);
Douglas Gregoref96ee02012-01-14 16:38:05 +0000388 PS[P->getSequenceNumber()] = P->getMostRecentDecl();
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000389 }
390}
391
Douglas Gregorb88e8882009-07-30 17:40:51 +0000392ClassTemplatePartialSpecializationDecl *
393ClassTemplateDecl::findPartialSpecialization(QualType T) {
394 ASTContext &Context = getASTContext();
Chandler Carruthd964d632012-05-03 23:49:05 +0000395 using llvm::FoldingSetVector;
396 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregorb88e8882009-07-30 17:40:51 +0000397 partial_spec_iterator;
398 for (partial_spec_iterator P = getPartialSpecializations().begin(),
399 PEnd = getPartialSpecializations().end();
400 P != PEnd; ++P) {
John McCall31f17ec2010-04-27 00:57:59 +0000401 if (Context.hasSameType(P->getInjectedSpecializationType(), T))
Douglas Gregoref96ee02012-01-14 16:38:05 +0000402 return P->getMostRecentDecl();
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000403 }
404
405 return 0;
406}
407
408ClassTemplatePartialSpecializationDecl *
409ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
410 ClassTemplatePartialSpecializationDecl *D) {
411 Decl *DCanon = D->getCanonicalDecl();
Chandler Carruthd964d632012-05-03 23:49:05 +0000412 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000413 P = getPartialSpecializations().begin(),
414 PEnd = getPartialSpecializations().end();
415 P != PEnd; ++P) {
416 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
Douglas Gregoref96ee02012-01-14 16:38:05 +0000417 return P->getMostRecentDecl();
Douglas Gregorb88e8882009-07-30 17:40:51 +0000418 }
Mike Stump1eb44332009-09-09 15:08:12 +0000419
Douglas Gregorb88e8882009-07-30 17:40:51 +0000420 return 0;
421}
422
John McCall3cb0ebd2010-03-10 03:28:59 +0000423QualType
Douglas Gregor24bae922010-07-08 18:37:38 +0000424ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidis5bf1bdc2010-06-21 10:57:41 +0000425 Common *CommonPtr = getCommonPtr();
Douglas Gregor7da97d02009-05-10 22:57:19 +0000426 if (!CommonPtr->InjectedClassNameType.isNull())
427 return CommonPtr->InjectedClassNameType;
428
Douglas Gregorb7d09d62010-12-23 16:00:30 +0000429 // C++0x [temp.dep.type]p2:
430 // The template argument list of a primary template is a template argument
431 // list in which the nth template argument has the value of the nth template
432 // parameter of the class template. If the nth template parameter is a
433 // template parameter pack (14.5.3), the nth template argument is a pack
434 // expansion (14.5.3) whose pattern is the name of the template parameter
435 // pack.
Douglas Gregor24bae922010-07-08 18:37:38 +0000436 ASTContext &Context = getASTContext();
Douglas Gregor7da97d02009-05-10 22:57:19 +0000437 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner5f9e2722011-07-23 10:55:15 +0000438 SmallVector<TemplateArgument, 16> TemplateArgs;
Douglas Gregorc494f772011-03-05 17:54:25 +0000439 TemplateArgs.resize(Params->size());
440 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
Douglas Gregor7da97d02009-05-10 22:57:19 +0000441 CommonPtr->InjectedClassNameType
Douglas Gregor1275ae02009-07-28 23:00:59 +0000442 = Context.getTemplateSpecializationType(TemplateName(this),
Douglas Gregor7da97d02009-05-10 22:57:19 +0000443 &TemplateArgs[0],
Douglas Gregor1275ae02009-07-28 23:00:59 +0000444 TemplateArgs.size());
Douglas Gregor7da97d02009-05-10 22:57:19 +0000445 return CommonPtr->InjectedClassNameType;
446}
447
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000448//===----------------------------------------------------------------------===//
449// TemplateTypeParm Allocation/Deallocation Method Implementations
450//===----------------------------------------------------------------------===//
451
452TemplateTypeParmDecl *
Jay Foad4ba2a172011-01-12 09:06:06 +0000453TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnara344577e2011-03-06 15:48:19 +0000454 SourceLocation KeyLoc, SourceLocation NameLoc,
455 unsigned D, unsigned P, IdentifierInfo *Id,
456 bool Typename, bool ParameterPack) {
Chandler Carruth4fb86f82011-05-01 00:51:33 +0000457 TemplateTypeParmDecl *TTPDecl =
458 new (C) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
459 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
460 TTPDecl->TypeForDecl = TTPType.getTypePtr();
461 return TTPDecl;
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000462}
463
Argyrios Kyrtzidisb8b03e62010-07-02 11:54:55 +0000464TemplateTypeParmDecl *
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000465TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
466 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTypeParmDecl));
467 return new (Mem) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(),
468 0, false);
Argyrios Kyrtzidisb8b03e62010-07-02 11:54:55 +0000469}
470
John McCall833ca992009-10-29 08:12:44 +0000471SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara77d4ee22011-03-04 12:42:03 +0000472 return hasDefaultArgument()
473 ? DefaultArgument->getTypeLoc().getBeginLoc()
474 : SourceLocation();
475}
476
477SourceRange TemplateTypeParmDecl::getSourceRange() const {
478 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnara344577e2011-03-06 15:48:19 +0000479 return SourceRange(getLocStart(),
Abramo Bagnara77d4ee22011-03-04 12:42:03 +0000480 DefaultArgument->getTypeLoc().getEndLoc());
481 else
Abramo Bagnara344577e2011-03-06 15:48:19 +0000482 return TypeDecl::getSourceRange();
John McCall833ca992009-10-29 08:12:44 +0000483}
484
Douglas Gregored9c0f92009-10-29 00:04:11 +0000485unsigned TemplateTypeParmDecl::getDepth() const {
486 return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
487}
488
489unsigned TemplateTypeParmDecl::getIndex() const {
490 return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
491}
492
Chandler Carruth4fb86f82011-05-01 00:51:33 +0000493bool TemplateTypeParmDecl::isParameterPack() const {
494 return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack();
495}
496
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000497//===----------------------------------------------------------------------===//
498// NonTypeTemplateParmDecl Method Implementations
499//===----------------------------------------------------------------------===//
500
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000501NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000502 SourceLocation StartLoc,
503 SourceLocation IdLoc,
504 unsigned D, unsigned P,
505 IdentifierInfo *Id,
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000506 QualType T,
507 TypeSourceInfo *TInfo,
508 const QualType *ExpandedTypes,
509 unsigned NumExpandedTypes,
510 TypeSourceInfo **ExpandedTInfos)
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000511 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000512 TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
513 ParameterPack(true), ExpandedParameterPack(true),
514 NumExpandedTypes(NumExpandedTypes)
515{
516 if (ExpandedTypes && ExpandedTInfos) {
517 void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
518 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
519 TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
520 TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
521 }
522 }
523}
524
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000525NonTypeTemplateParmDecl *
Jay Foad4ba2a172011-01-12 09:06:06 +0000526NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000527 SourceLocation StartLoc, SourceLocation IdLoc,
528 unsigned D, unsigned P, IdentifierInfo *Id,
529 QualType T, bool ParameterPack,
530 TypeSourceInfo *TInfo) {
531 return new (C) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
532 T, ParameterPack, TInfo);
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000533}
534
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000535NonTypeTemplateParmDecl *
536NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000537 SourceLocation StartLoc, SourceLocation IdLoc,
538 unsigned D, unsigned P,
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000539 IdentifierInfo *Id, QualType T,
540 TypeSourceInfo *TInfo,
541 const QualType *ExpandedTypes,
542 unsigned NumExpandedTypes,
543 TypeSourceInfo **ExpandedTInfos) {
544 unsigned Size = sizeof(NonTypeTemplateParmDecl)
545 + NumExpandedTypes * 2 * sizeof(void*);
546 void *Mem = C.Allocate(Size);
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000547 return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc,
548 D, P, Id, T, TInfo,
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000549 ExpandedTypes, NumExpandedTypes,
550 ExpandedTInfos);
551}
552
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000553NonTypeTemplateParmDecl *
554NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
555 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NonTypeTemplateParmDecl));
556 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
557 SourceLocation(), 0, 0, 0,
558 QualType(), false, 0);
559}
560
561NonTypeTemplateParmDecl *
562NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
563 unsigned NumExpandedTypes) {
564 unsigned Size = sizeof(NonTypeTemplateParmDecl)
565 + NumExpandedTypes * 2 * sizeof(void*);
566
567 void *Mem = AllocateDeserializedDecl(C, ID, Size);
568 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
569 SourceLocation(), 0, 0, 0,
570 QualType(), 0, 0, NumExpandedTypes,
571 0);
572}
573
John McCall76a40212011-02-09 01:13:10 +0000574SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnaraee4bfd42011-03-04 11:03:48 +0000575 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraa2026c92011-03-08 16:41:52 +0000576 return SourceRange(getOuterLocStart(),
577 getDefaultArgument()->getSourceRange().getEnd());
578 return DeclaratorDecl::getSourceRange();
John McCall76a40212011-02-09 01:13:10 +0000579}
580
Douglas Gregord684b002009-02-10 19:49:53 +0000581SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnarad92f7a22010-06-09 09:26:05 +0000582 return hasDefaultArgument()
583 ? getDefaultArgument()->getSourceRange().getBegin()
584 : SourceLocation();
Douglas Gregord684b002009-02-10 19:49:53 +0000585}
586
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000587//===----------------------------------------------------------------------===//
588// TemplateTemplateParmDecl Method Implementations
589//===----------------------------------------------------------------------===//
590
David Blaikie99ba9e32011-12-20 02:48:34 +0000591void TemplateTemplateParmDecl::anchor() { }
592
Richard Smith6964b3f2012-09-07 02:06:42 +0000593TemplateTemplateParmDecl::TemplateTemplateParmDecl(
594 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
595 IdentifierInfo *Id, TemplateParameterList *Params,
596 unsigned NumExpansions, TemplateParameterList * const *Expansions)
597 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
598 TemplateParmPosition(D, P), DefaultArgument(),
599 DefaultArgumentWasInherited(false), ParameterPack(true),
600 ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
601 if (Expansions)
602 std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
603 sizeof(TemplateParameterList*) * NumExpandedParams);
604}
605
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000606TemplateTemplateParmDecl *
Jay Foad4ba2a172011-01-12 09:06:06 +0000607TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000608 SourceLocation L, unsigned D, unsigned P,
Douglas Gregor61c4d282011-01-05 15:48:55 +0000609 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000610 TemplateParameterList *Params) {
Douglas Gregor61c4d282011-01-05 15:48:55 +0000611 return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
612 Params);
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000613}
614
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000615TemplateTemplateParmDecl *
Richard Smith6964b3f2012-09-07 02:06:42 +0000616TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
617 SourceLocation L, unsigned D, unsigned P,
618 IdentifierInfo *Id,
619 TemplateParameterList *Params,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000620 ArrayRef<TemplateParameterList *> Expansions) {
Richard Smith6964b3f2012-09-07 02:06:42 +0000621 void *Mem = C.Allocate(sizeof(TemplateTemplateParmDecl) +
622 sizeof(TemplateParameterList*) * Expansions.size());
623 return new (Mem) TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
624 Expansions.size(),
625 Expansions.data());
626}
627
628TemplateTemplateParmDecl *
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000629TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
630 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTemplateParmDecl));
631 return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, false,
632 0, 0);
633}
634
Richard Smith6964b3f2012-09-07 02:06:42 +0000635TemplateTemplateParmDecl *
636TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
637 unsigned NumExpansions) {
638 unsigned Size = sizeof(TemplateTemplateParmDecl) +
639 sizeof(TemplateParameterList*) * NumExpansions;
640 void *Mem = AllocateDeserializedDecl(C, ID, Size);
641 return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, 0, 0,
642 NumExpansions, 0);
643}
644
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000645//===----------------------------------------------------------------------===//
Douglas Gregor7e063902009-05-11 23:53:27 +0000646// TemplateArgumentList Implementation
647//===----------------------------------------------------------------------===//
Douglas Gregor910f8002010-11-07 23:05:16 +0000648TemplateArgumentList *
649TemplateArgumentList::CreateCopy(ASTContext &Context,
650 const TemplateArgument *Args,
651 unsigned NumArgs) {
652 std::size_t Size = sizeof(TemplateArgumentList)
653 + NumArgs * sizeof(TemplateArgument);
654 void *Mem = Context.Allocate(Size);
655 TemplateArgument *StoredArgs
656 = reinterpret_cast<TemplateArgument *>(
657 static_cast<TemplateArgumentList *>(Mem) + 1);
658 std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
659 return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000660}
661
Argyrios Kyrtzidis71a76052011-09-22 20:07:09 +0000662FunctionTemplateSpecializationInfo *
663FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
664 FunctionTemplateDecl *Template,
665 TemplateSpecializationKind TSK,
666 const TemplateArgumentList *TemplateArgs,
667 const TemplateArgumentListInfo *TemplateArgsAsWritten,
668 SourceLocation POI) {
669 const ASTTemplateArgumentListInfo *ArgsAsWritten = 0;
670 if (TemplateArgsAsWritten)
671 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
672 *TemplateArgsAsWritten);
673
674 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
675 TemplateArgs,
676 ArgsAsWritten,
677 POI);
678}
679
Douglas Gregor7e063902009-05-11 23:53:27 +0000680//===----------------------------------------------------------------------===//
David Blaikie99ba9e32011-12-20 02:48:34 +0000681// TemplateDecl Implementation
682//===----------------------------------------------------------------------===//
683
684void TemplateDecl::anchor() { }
685
686//===----------------------------------------------------------------------===//
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000687// ClassTemplateSpecializationDecl Implementation
688//===----------------------------------------------------------------------===//
689ClassTemplateSpecializationDecl::
Douglas Gregor13c85772010-05-06 00:28:52 +0000690ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000691 DeclContext *DC, SourceLocation StartLoc,
692 SourceLocation IdLoc,
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000693 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000694 const TemplateArgument *Args,
695 unsigned NumArgs,
Douglas Gregor8e9e9ef2009-07-29 23:36:44 +0000696 ClassTemplateSpecializationDecl *PrevDecl)
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000697 : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc,
Douglas Gregor8e9e9ef2009-07-29 23:36:44 +0000698 SpecializedTemplate->getIdentifier(),
699 PrevDecl),
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000700 SpecializedTemplate(SpecializedTemplate),
Abramo Bagnarac98971d2010-06-12 07:44:57 +0000701 ExplicitInfo(0),
Douglas Gregor910f8002010-11-07 23:05:16 +0000702 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
Douglas Gregor7e063902009-05-11 23:53:27 +0000703 SpecializationKind(TSK_Undeclared) {
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000704}
Mike Stump1eb44332009-09-09 15:08:12 +0000705
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000706ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000707 : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0),
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000708 ExplicitInfo(0),
709 SpecializationKind(TSK_Undeclared) {
710}
711
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000712ClassTemplateSpecializationDecl *
Douglas Gregor13c85772010-05-06 00:28:52 +0000713ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000714 DeclContext *DC,
715 SourceLocation StartLoc,
716 SourceLocation IdLoc,
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000717 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000718 const TemplateArgument *Args,
719 unsigned NumArgs,
Douglas Gregorcc636682009-02-17 23:15:12 +0000720 ClassTemplateSpecializationDecl *PrevDecl) {
Douglas Gregorcc636682009-02-17 23:15:12 +0000721 ClassTemplateSpecializationDecl *Result
Mike Stump1eb44332009-09-09 15:08:12 +0000722 = new (Context)ClassTemplateSpecializationDecl(Context,
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000723 ClassTemplateSpecialization,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000724 TK, DC, StartLoc, IdLoc,
Douglas Gregor7e063902009-05-11 23:53:27 +0000725 SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000726 Args, NumArgs,
Douglas Gregor8e9e9ef2009-07-29 23:36:44 +0000727 PrevDecl);
Douglas Gregor6bd99292013-02-09 01:35:03 +0000728 Result->MayHaveOutOfDateDef = false;
729
Douglas Gregorcc636682009-02-17 23:15:12 +0000730 Context.getTypeDeclType(Result, PrevDecl);
731 return Result;
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000732}
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000733
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000734ClassTemplateSpecializationDecl *
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000735ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
736 unsigned ID) {
737 void *Mem = AllocateDeserializedDecl(C, ID,
738 sizeof(ClassTemplateSpecializationDecl));
Douglas Gregor6bd99292013-02-09 01:35:03 +0000739 ClassTemplateSpecializationDecl *Result =
740 new (Mem) ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
741 Result->MayHaveOutOfDateDef = false;
742 return Result;
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000743}
744
Benjamin Kramer5eada842013-02-22 15:46:01 +0000745void ClassTemplateSpecializationDecl::getNameForDiagnostic(
746 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
747 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
Douglas Gregorda2142f2011-02-19 18:51:44 +0000748
749 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Benjamin Kramer5eada842013-02-22 15:46:01 +0000750 TemplateSpecializationType::PrintTemplateArgumentList(
751 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
Douglas Gregorda2142f2011-02-19 18:51:44 +0000752}
753
Douglas Gregor37d93e92009-08-02 23:24:31 +0000754ClassTemplateDecl *
Mike Stump1eb44332009-09-09 15:08:12 +0000755ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
756 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor37d93e92009-08-02 23:24:31 +0000757 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
758 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
759 return SpecializedTemplate.get<ClassTemplateDecl*>();
760}
761
Abramo Bagnara4a85a732011-03-04 14:20:30 +0000762SourceRange
763ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnara09d82122011-10-03 20:34:03 +0000764 if (ExplicitInfo) {
Abramo Bagnarab2e80012012-10-15 21:06:42 +0000765 SourceLocation Begin = getTemplateKeywordLoc();
766 if (Begin.isValid()) {
767 // Here we have an explicit (partial) specialization or instantiation.
768 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
769 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
770 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
771 if (getExternLoc().isValid())
772 Begin = getExternLoc();
773 SourceLocation End = getRBraceLoc();
774 if (End.isInvalid())
775 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
776 return SourceRange(Begin, End);
777 }
778 // An implicit instantiation of a class template partial specialization
779 // uses ExplicitInfo to record the TypeAsWritten, but the source
780 // locations should be retrieved from the instantiation pattern.
781 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
782 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
783 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
784 assert(inst_from != 0);
785 return inst_from->getSourceRange();
Abramo Bagnara09d82122011-10-03 20:34:03 +0000786 }
787 else {
788 // No explicit info available.
789 llvm::PointerUnion<ClassTemplateDecl *,
790 ClassTemplatePartialSpecializationDecl *>
791 inst_from = getInstantiatedFrom();
792 if (inst_from.isNull())
793 return getSpecializedTemplate()->getSourceRange();
794 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
795 return ctd->getSourceRange();
796 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
797 ->getSourceRange();
798 }
Abramo Bagnara4a85a732011-03-04 14:20:30 +0000799}
800
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000801//===----------------------------------------------------------------------===//
802// ClassTemplatePartialSpecializationDecl Implementation
803//===----------------------------------------------------------------------===//
David Blaikie99ba9e32011-12-20 02:48:34 +0000804void ClassTemplatePartialSpecializationDecl::anchor() { }
805
Douglas Gregor9a299e02011-03-04 17:52:15 +0000806ClassTemplatePartialSpecializationDecl::
807ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000808 DeclContext *DC,
809 SourceLocation StartLoc,
810 SourceLocation IdLoc,
Douglas Gregor9a299e02011-03-04 17:52:15 +0000811 TemplateParameterList *Params,
812 ClassTemplateDecl *SpecializedTemplate,
813 const TemplateArgument *Args,
814 unsigned NumArgs,
815 TemplateArgumentLoc *ArgInfos,
816 unsigned NumArgInfos,
817 ClassTemplatePartialSpecializationDecl *PrevDecl,
818 unsigned SequenceNumber)
819 : ClassTemplateSpecializationDecl(Context,
820 ClassTemplatePartialSpecialization,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000821 TK, DC, StartLoc, IdLoc,
822 SpecializedTemplate,
Douglas Gregor9a299e02011-03-04 17:52:15 +0000823 Args, NumArgs, PrevDecl),
824 TemplateParams(Params), ArgsAsWritten(ArgInfos),
825 NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
826 InstantiatedFromMember(0, false)
827{
Douglas Gregor787a40d2011-03-04 18:32:38 +0000828 AdoptTemplateParameterList(Params, this);
Douglas Gregor9a299e02011-03-04 17:52:15 +0000829}
830
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000831ClassTemplatePartialSpecializationDecl *
832ClassTemplatePartialSpecializationDecl::
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000833Create(ASTContext &Context, TagKind TK,DeclContext *DC,
834 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000835 TemplateParameterList *Params,
836 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000837 const TemplateArgument *Args,
838 unsigned NumArgs,
John McCalld5532b62009-11-23 01:53:49 +0000839 const TemplateArgumentListInfo &ArgInfos,
John McCall3cb0ebd2010-03-10 03:28:59 +0000840 QualType CanonInjectedType,
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000841 ClassTemplatePartialSpecializationDecl *PrevDecl,
842 unsigned SequenceNumber) {
John McCalld5532b62009-11-23 01:53:49 +0000843 unsigned N = ArgInfos.size();
John McCall833ca992009-10-29 08:12:44 +0000844 TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
845 for (unsigned I = 0; I != N; ++I)
846 ClonedArgs[I] = ArgInfos[I];
847
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000848 ClassTemplatePartialSpecializationDecl *Result
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000849 = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC,
850 StartLoc, IdLoc,
851 Params,
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000852 SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000853 Args, NumArgs,
John McCall833ca992009-10-29 08:12:44 +0000854 ClonedArgs, N,
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000855 PrevDecl,
856 SequenceNumber);
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000857 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor6bd99292013-02-09 01:35:03 +0000858 Result->MayHaveOutOfDateDef = false;
John McCall3cb0ebd2010-03-10 03:28:59 +0000859
860 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000861 return Result;
862}
John McCalldd4a3b02009-09-16 22:47:08 +0000863
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000864ClassTemplatePartialSpecializationDecl *
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000865ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
866 unsigned ID) {
867 void *Mem = AllocateDeserializedDecl(C, ID,
868 sizeof(ClassTemplatePartialSpecializationDecl));
Douglas Gregor6bd99292013-02-09 01:35:03 +0000869 ClassTemplatePartialSpecializationDecl *Result
870 = new (Mem) ClassTemplatePartialSpecializationDecl();
871 Result->MayHaveOutOfDateDef = false;
872 return Result;
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000873}
874
John McCalldd4a3b02009-09-16 22:47:08 +0000875//===----------------------------------------------------------------------===//
876// FriendTemplateDecl Implementation
877//===----------------------------------------------------------------------===//
878
David Blaikie99ba9e32011-12-20 02:48:34 +0000879void FriendTemplateDecl::anchor() { }
880
John McCalldd4a3b02009-09-16 22:47:08 +0000881FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
882 DeclContext *DC,
883 SourceLocation L,
884 unsigned NParams,
885 TemplateParameterList **Params,
886 FriendUnion Friend,
887 SourceLocation FLoc) {
888 FriendTemplateDecl *Result
889 = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
890 return Result;
891}
Argyrios Kyrtzidis554e6aa2010-07-22 16:04:10 +0000892
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000893FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
894 unsigned ID) {
895 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FriendTemplateDecl));
896 return new (Mem) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis554e6aa2010-07-22 16:04:10 +0000897}
Richard Smith3e4c6c42011-05-05 21:57:07 +0000898
899//===----------------------------------------------------------------------===//
900// TypeAliasTemplateDecl Implementation
901//===----------------------------------------------------------------------===//
902
903TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
904 DeclContext *DC,
905 SourceLocation L,
906 DeclarationName Name,
907 TemplateParameterList *Params,
908 NamedDecl *Decl) {
909 AdoptTemplateParameterList(Params, DC);
910 return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl);
911}
912
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000913TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
914 unsigned ID) {
915 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasTemplateDecl));
916 return new (Mem) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(),
917 0, 0);
Richard Smith3e4c6c42011-05-05 21:57:07 +0000918}
919
920void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
921 static_cast<Common *>(Ptr)->~Common();
922}
923RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob76d9712013-01-23 16:52:57 +0000924TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3e4c6c42011-05-05 21:57:07 +0000925 Common *CommonPtr = new (C) Common;
926 C.AddDeallocation(DeallocateCommon, CommonPtr);
927 return CommonPtr;
928}
929
David Blaikie99ba9e32011-12-20 02:48:34 +0000930//===----------------------------------------------------------------------===//
931// ClassScopeFunctionSpecializationDecl Implementation
932//===----------------------------------------------------------------------===//
933
934void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000935
936ClassScopeFunctionSpecializationDecl *
937ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
938 unsigned ID) {
939 void *Mem = AllocateDeserializedDecl(C, ID,
940 sizeof(ClassScopeFunctionSpecializationDecl));
Nico Weber6b020092012-06-25 17:21:05 +0000941 return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0,
942 false, TemplateArgumentListInfo());
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000943}