blob: 42929aa71d4bbc7f62da51f9b6eddc39315ad160 [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())
187 ArgType = Context.getPackExpansionType(ArgType,
188 llvm::Optional<unsigned>());
189
190 Arg = TemplateArgument(ArgType);
191 } else if (NonTypeTemplateParmDecl *NTTP =
192 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
John McCallf4b88a42012-03-10 09:33:50 +0000193 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
Douglas Gregorc494f772011-03-05 17:54:25 +0000194 NTTP->getType().getNonLValueExprType(Context),
195 Expr::getValueKindForType(NTTP->getType()),
196 NTTP->getLocation());
197
198 if (NTTP->isParameterPack())
199 E = new (Context) PackExpansionExpr(Context.DependentTy, E,
200 NTTP->getLocation(),
201 llvm::Optional<unsigned>());
202 Arg = TemplateArgument(E);
203 } else {
204 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
205 if (TTP->isParameterPack())
206 Arg = TemplateArgument(TemplateName(TTP), llvm::Optional<unsigned>());
207 else
208 Arg = TemplateArgument(TemplateName(TTP));
209 }
210
211 if ((*Param)->isTemplateParameterPack())
212 Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
213
214 *Args++ = Arg;
215 }
216}
217
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000218//===----------------------------------------------------------------------===//
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000219// FunctionTemplateDecl Implementation
220//===----------------------------------------------------------------------===//
221
Douglas Gregor00545312010-05-23 18:26:36 +0000222void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
223 static_cast<Common *>(Ptr)->~Common();
224}
225
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000226FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
227 DeclContext *DC,
228 SourceLocation L,
229 DeclarationName Name,
Douglas Gregor127102b2009-06-29 20:59:39 +0000230 TemplateParameterList *Params,
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000231 NamedDecl *Decl) {
Douglas Gregor787a40d2011-03-04 18:32:38 +0000232 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000233 return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
234}
235
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000236FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
237 unsigned ID) {
238 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FunctionTemplateDecl));
239 return new (Mem) FunctionTemplateDecl(0, SourceLocation(), DeclarationName(),
240 0, 0);
Douglas Gregor9a299e02011-03-04 17:52:15 +0000241}
242
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +0000243RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob76d9712013-01-23 16:52:57 +0000244FunctionTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +0000245 Common *CommonPtr = new (C) Common;
246 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000247 return CommonPtr;
248}
249
Argyrios Kyrtzidis2c853e42010-07-20 13:59:58 +0000250FunctionDecl *
251FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
252 unsigned NumArgs, void *&InsertPos) {
Peter Collingbourne40485902010-07-30 17:09:04 +0000253 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
Argyrios Kyrtzidis2c853e42010-07-20 13:59:58 +0000254}
255
Sebastian Redl5bbcdbf2011-04-14 14:07:59 +0000256void FunctionTemplateDecl::addSpecialization(
257 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
Douglas Gregor1e1e9722012-03-28 14:34:23 +0000258 if (InsertPos)
259 getSpecializations().InsertNode(Info, InsertPos);
260 else
261 getSpecializations().GetOrInsertNode(Info);
Sebastian Redl5bbcdbf2011-04-14 14:07:59 +0000262 if (ASTMutationListener *L = getASTMutationListener())
263 L->AddedCXXTemplateSpecialization(this, Info->Function);
264}
265
Douglas Gregorc494f772011-03-05 17:54:25 +0000266std::pair<const TemplateArgument *, unsigned>
267FunctionTemplateDecl::getInjectedTemplateArgs() {
268 TemplateParameterList *Params = getTemplateParameters();
269 Common *CommonPtr = getCommonPtr();
270 if (!CommonPtr->InjectedArgs) {
271 CommonPtr->InjectedArgs
272 = new (getASTContext()) TemplateArgument [Params->size()];
273 GenerateInjectedTemplateArgs(getASTContext(), Params,
274 CommonPtr->InjectedArgs);
275 }
276
277 return std::make_pair(CommonPtr->InjectedArgs, Params->size());
278}
279
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000280//===----------------------------------------------------------------------===//
281// ClassTemplateDecl Implementation
282//===----------------------------------------------------------------------===//
283
Douglas Gregor00545312010-05-23 18:26:36 +0000284void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
285 static_cast<Common *>(Ptr)->~Common();
286}
287
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000288ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
289 DeclContext *DC,
290 SourceLocation L,
291 DeclarationName Name,
292 TemplateParameterList *Params,
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000293 NamedDecl *Decl,
294 ClassTemplateDecl *PrevDecl) {
Douglas Gregor787a40d2011-03-04 18:32:38 +0000295 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +0000296 ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
Argyrios Kyrtzidis5bf1bdc2010-06-21 10:57:41 +0000297 New->setPreviousDeclaration(PrevDecl);
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +0000298 return New;
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000299}
300
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000301ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
302 unsigned ID) {
303 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ClassTemplateDecl));
304 return new (Mem) ClassTemplateDecl(EmptyShell());
Douglas Gregor9a299e02011-03-04 17:52:15 +0000305}
306
Douglas Gregorc8e5cf82010-10-27 22:21:36 +0000307void ClassTemplateDecl::LoadLazySpecializations() {
308 Common *CommonPtr = getCommonPtr();
309 if (CommonPtr->LazySpecializations) {
310 ASTContext &Context = getASTContext();
311 uint32_t *Specs = CommonPtr->LazySpecializations;
312 CommonPtr->LazySpecializations = 0;
313 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
314 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
315 }
316}
317
Chandler Carruthd964d632012-05-03 23:49:05 +0000318llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
Douglas Gregorc8e5cf82010-10-27 22:21:36 +0000319ClassTemplateDecl::getSpecializations() {
320 LoadLazySpecializations();
321 return getCommonPtr()->Specializations;
322}
323
Chandler Carruthd964d632012-05-03 23:49:05 +0000324llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
Douglas Gregorc8e5cf82010-10-27 22:21:36 +0000325ClassTemplateDecl::getPartialSpecializations() {
326 LoadLazySpecializations();
327 return getCommonPtr()->PartialSpecializations;
328}
329
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +0000330RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob76d9712013-01-23 16:52:57 +0000331ClassTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +0000332 Common *CommonPtr = new (C) Common;
333 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000334 return CommonPtr;
335}
336
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000337ClassTemplateSpecializationDecl *
338ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
339 unsigned NumArgs, void *&InsertPos) {
Peter Collingbourne40485902010-07-30 17:09:04 +0000340 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000341}
342
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000343void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
344 void *InsertPos) {
Douglas Gregor1e1e9722012-03-28 14:34:23 +0000345 if (InsertPos)
346 getSpecializations().InsertNode(D, InsertPos);
347 else {
348 ClassTemplateSpecializationDecl *Existing
349 = getSpecializations().GetOrInsertNode(D);
350 (void)Existing;
351 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
352 }
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000353 if (ASTMutationListener *L = getASTMutationListener())
354 L->AddedCXXTemplateSpecialization(this, D);
355}
356
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000357ClassTemplatePartialSpecializationDecl *
358ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
359 unsigned NumArgs,
360 void *&InsertPos) {
Peter Collingbourne40485902010-07-30 17:09:04 +0000361 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
362 InsertPos);
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000363}
364
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000365void ClassTemplateDecl::AddPartialSpecialization(
366 ClassTemplatePartialSpecializationDecl *D,
367 void *InsertPos) {
Douglas Gregor1e1e9722012-03-28 14:34:23 +0000368 if (InsertPos)
369 getPartialSpecializations().InsertNode(D, InsertPos);
370 else {
371 ClassTemplatePartialSpecializationDecl *Existing
372 = getPartialSpecializations().GetOrInsertNode(D);
373 (void)Existing;
374 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
375 }
376
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000377 if (ASTMutationListener *L = getASTMutationListener())
378 L->AddedCXXTemplateSpecialization(this, D);
379}
380
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000381void ClassTemplateDecl::getPartialSpecializations(
Chris Lattner5f9e2722011-07-23 10:55:15 +0000382 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
Chandler Carruthd964d632012-05-03 23:49:05 +0000383 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
Argyrios Kyrtzidis5bf1bdc2010-06-21 10:57:41 +0000384 = getPartialSpecializations();
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000385 PS.clear();
386 PS.resize(PartialSpecs.size());
Chandler Carruthd964d632012-05-03 23:49:05 +0000387 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000388 P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
389 P != PEnd; ++P) {
390 assert(!PS[P->getSequenceNumber()]);
Douglas Gregoref96ee02012-01-14 16:38:05 +0000391 PS[P->getSequenceNumber()] = P->getMostRecentDecl();
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000392 }
393}
394
Douglas Gregorb88e8882009-07-30 17:40:51 +0000395ClassTemplatePartialSpecializationDecl *
396ClassTemplateDecl::findPartialSpecialization(QualType T) {
397 ASTContext &Context = getASTContext();
Chandler Carruthd964d632012-05-03 23:49:05 +0000398 using llvm::FoldingSetVector;
399 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregorb88e8882009-07-30 17:40:51 +0000400 partial_spec_iterator;
401 for (partial_spec_iterator P = getPartialSpecializations().begin(),
402 PEnd = getPartialSpecializations().end();
403 P != PEnd; ++P) {
John McCall31f17ec2010-04-27 00:57:59 +0000404 if (Context.hasSameType(P->getInjectedSpecializationType(), T))
Douglas Gregoref96ee02012-01-14 16:38:05 +0000405 return P->getMostRecentDecl();
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000406 }
407
408 return 0;
409}
410
411ClassTemplatePartialSpecializationDecl *
412ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
413 ClassTemplatePartialSpecializationDecl *D) {
414 Decl *DCanon = D->getCanonicalDecl();
Chandler Carruthd964d632012-05-03 23:49:05 +0000415 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000416 P = getPartialSpecializations().begin(),
417 PEnd = getPartialSpecializations().end();
418 P != PEnd; ++P) {
419 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
Douglas Gregoref96ee02012-01-14 16:38:05 +0000420 return P->getMostRecentDecl();
Douglas Gregorb88e8882009-07-30 17:40:51 +0000421 }
Mike Stump1eb44332009-09-09 15:08:12 +0000422
Douglas Gregorb88e8882009-07-30 17:40:51 +0000423 return 0;
424}
425
John McCall3cb0ebd2010-03-10 03:28:59 +0000426QualType
Douglas Gregor24bae922010-07-08 18:37:38 +0000427ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidis5bf1bdc2010-06-21 10:57:41 +0000428 Common *CommonPtr = getCommonPtr();
Douglas Gregor7da97d02009-05-10 22:57:19 +0000429 if (!CommonPtr->InjectedClassNameType.isNull())
430 return CommonPtr->InjectedClassNameType;
431
Douglas Gregorb7d09d62010-12-23 16:00:30 +0000432 // C++0x [temp.dep.type]p2:
433 // The template argument list of a primary template is a template argument
434 // list in which the nth template argument has the value of the nth template
435 // parameter of the class template. If the nth template parameter is a
436 // template parameter pack (14.5.3), the nth template argument is a pack
437 // expansion (14.5.3) whose pattern is the name of the template parameter
438 // pack.
Douglas Gregor24bae922010-07-08 18:37:38 +0000439 ASTContext &Context = getASTContext();
Douglas Gregor7da97d02009-05-10 22:57:19 +0000440 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner5f9e2722011-07-23 10:55:15 +0000441 SmallVector<TemplateArgument, 16> TemplateArgs;
Douglas Gregorc494f772011-03-05 17:54:25 +0000442 TemplateArgs.resize(Params->size());
443 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
Douglas Gregor7da97d02009-05-10 22:57:19 +0000444 CommonPtr->InjectedClassNameType
Douglas Gregor1275ae02009-07-28 23:00:59 +0000445 = Context.getTemplateSpecializationType(TemplateName(this),
Douglas Gregor7da97d02009-05-10 22:57:19 +0000446 &TemplateArgs[0],
Douglas Gregor1275ae02009-07-28 23:00:59 +0000447 TemplateArgs.size());
Douglas Gregor7da97d02009-05-10 22:57:19 +0000448 return CommonPtr->InjectedClassNameType;
449}
450
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000451//===----------------------------------------------------------------------===//
452// TemplateTypeParm Allocation/Deallocation Method Implementations
453//===----------------------------------------------------------------------===//
454
455TemplateTypeParmDecl *
Jay Foad4ba2a172011-01-12 09:06:06 +0000456TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnara344577e2011-03-06 15:48:19 +0000457 SourceLocation KeyLoc, SourceLocation NameLoc,
458 unsigned D, unsigned P, IdentifierInfo *Id,
459 bool Typename, bool ParameterPack) {
Chandler Carruth4fb86f82011-05-01 00:51:33 +0000460 TemplateTypeParmDecl *TTPDecl =
461 new (C) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
462 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
463 TTPDecl->TypeForDecl = TTPType.getTypePtr();
464 return TTPDecl;
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000465}
466
Argyrios Kyrtzidisb8b03e62010-07-02 11:54:55 +0000467TemplateTypeParmDecl *
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000468TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
469 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTypeParmDecl));
470 return new (Mem) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(),
471 0, false);
Argyrios Kyrtzidisb8b03e62010-07-02 11:54:55 +0000472}
473
John McCall833ca992009-10-29 08:12:44 +0000474SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara77d4ee22011-03-04 12:42:03 +0000475 return hasDefaultArgument()
476 ? DefaultArgument->getTypeLoc().getBeginLoc()
477 : SourceLocation();
478}
479
480SourceRange TemplateTypeParmDecl::getSourceRange() const {
481 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnara344577e2011-03-06 15:48:19 +0000482 return SourceRange(getLocStart(),
Abramo Bagnara77d4ee22011-03-04 12:42:03 +0000483 DefaultArgument->getTypeLoc().getEndLoc());
484 else
Abramo Bagnara344577e2011-03-06 15:48:19 +0000485 return TypeDecl::getSourceRange();
John McCall833ca992009-10-29 08:12:44 +0000486}
487
Douglas Gregored9c0f92009-10-29 00:04:11 +0000488unsigned TemplateTypeParmDecl::getDepth() const {
489 return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
490}
491
492unsigned TemplateTypeParmDecl::getIndex() const {
493 return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
494}
495
Chandler Carruth4fb86f82011-05-01 00:51:33 +0000496bool TemplateTypeParmDecl::isParameterPack() const {
497 return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack();
498}
499
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000500//===----------------------------------------------------------------------===//
501// NonTypeTemplateParmDecl Method Implementations
502//===----------------------------------------------------------------------===//
503
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000504NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000505 SourceLocation StartLoc,
506 SourceLocation IdLoc,
507 unsigned D, unsigned P,
508 IdentifierInfo *Id,
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000509 QualType T,
510 TypeSourceInfo *TInfo,
511 const QualType *ExpandedTypes,
512 unsigned NumExpandedTypes,
513 TypeSourceInfo **ExpandedTInfos)
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000514 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000515 TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
516 ParameterPack(true), ExpandedParameterPack(true),
517 NumExpandedTypes(NumExpandedTypes)
518{
519 if (ExpandedTypes && ExpandedTInfos) {
520 void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
521 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
522 TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
523 TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
524 }
525 }
526}
527
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000528NonTypeTemplateParmDecl *
Jay Foad4ba2a172011-01-12 09:06:06 +0000529NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000530 SourceLocation StartLoc, SourceLocation IdLoc,
531 unsigned D, unsigned P, IdentifierInfo *Id,
532 QualType T, bool ParameterPack,
533 TypeSourceInfo *TInfo) {
534 return new (C) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
535 T, ParameterPack, TInfo);
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000536}
537
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000538NonTypeTemplateParmDecl *
539NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000540 SourceLocation StartLoc, SourceLocation IdLoc,
541 unsigned D, unsigned P,
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000542 IdentifierInfo *Id, QualType T,
543 TypeSourceInfo *TInfo,
544 const QualType *ExpandedTypes,
545 unsigned NumExpandedTypes,
546 TypeSourceInfo **ExpandedTInfos) {
547 unsigned Size = sizeof(NonTypeTemplateParmDecl)
548 + NumExpandedTypes * 2 * sizeof(void*);
549 void *Mem = C.Allocate(Size);
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000550 return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc,
551 D, P, Id, T, TInfo,
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000552 ExpandedTypes, NumExpandedTypes,
553 ExpandedTInfos);
554}
555
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000556NonTypeTemplateParmDecl *
557NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
558 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NonTypeTemplateParmDecl));
559 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
560 SourceLocation(), 0, 0, 0,
561 QualType(), false, 0);
562}
563
564NonTypeTemplateParmDecl *
565NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
566 unsigned NumExpandedTypes) {
567 unsigned Size = sizeof(NonTypeTemplateParmDecl)
568 + NumExpandedTypes * 2 * sizeof(void*);
569
570 void *Mem = AllocateDeserializedDecl(C, ID, Size);
571 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
572 SourceLocation(), 0, 0, 0,
573 QualType(), 0, 0, NumExpandedTypes,
574 0);
575}
576
John McCall76a40212011-02-09 01:13:10 +0000577SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnaraee4bfd42011-03-04 11:03:48 +0000578 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraa2026c92011-03-08 16:41:52 +0000579 return SourceRange(getOuterLocStart(),
580 getDefaultArgument()->getSourceRange().getEnd());
581 return DeclaratorDecl::getSourceRange();
John McCall76a40212011-02-09 01:13:10 +0000582}
583
Douglas Gregord684b002009-02-10 19:49:53 +0000584SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnarad92f7a22010-06-09 09:26:05 +0000585 return hasDefaultArgument()
586 ? getDefaultArgument()->getSourceRange().getBegin()
587 : SourceLocation();
Douglas Gregord684b002009-02-10 19:49:53 +0000588}
589
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000590//===----------------------------------------------------------------------===//
591// TemplateTemplateParmDecl Method Implementations
592//===----------------------------------------------------------------------===//
593
David Blaikie99ba9e32011-12-20 02:48:34 +0000594void TemplateTemplateParmDecl::anchor() { }
595
Richard Smith6964b3f2012-09-07 02:06:42 +0000596TemplateTemplateParmDecl::TemplateTemplateParmDecl(
597 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
598 IdentifierInfo *Id, TemplateParameterList *Params,
599 unsigned NumExpansions, TemplateParameterList * const *Expansions)
600 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
601 TemplateParmPosition(D, P), DefaultArgument(),
602 DefaultArgumentWasInherited(false), ParameterPack(true),
603 ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
604 if (Expansions)
605 std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
606 sizeof(TemplateParameterList*) * NumExpandedParams);
607}
608
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000609TemplateTemplateParmDecl *
Jay Foad4ba2a172011-01-12 09:06:06 +0000610TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000611 SourceLocation L, unsigned D, unsigned P,
Douglas Gregor61c4d282011-01-05 15:48:55 +0000612 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000613 TemplateParameterList *Params) {
Douglas Gregor61c4d282011-01-05 15:48:55 +0000614 return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
615 Params);
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000616}
617
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000618TemplateTemplateParmDecl *
Richard Smith6964b3f2012-09-07 02:06:42 +0000619TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
620 SourceLocation L, unsigned D, unsigned P,
621 IdentifierInfo *Id,
622 TemplateParameterList *Params,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000623 ArrayRef<TemplateParameterList *> Expansions) {
Richard Smith6964b3f2012-09-07 02:06:42 +0000624 void *Mem = C.Allocate(sizeof(TemplateTemplateParmDecl) +
625 sizeof(TemplateParameterList*) * Expansions.size());
626 return new (Mem) TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
627 Expansions.size(),
628 Expansions.data());
629}
630
631TemplateTemplateParmDecl *
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000632TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
633 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTemplateParmDecl));
634 return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, false,
635 0, 0);
636}
637
Richard Smith6964b3f2012-09-07 02:06:42 +0000638TemplateTemplateParmDecl *
639TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
640 unsigned NumExpansions) {
641 unsigned Size = sizeof(TemplateTemplateParmDecl) +
642 sizeof(TemplateParameterList*) * NumExpansions;
643 void *Mem = AllocateDeserializedDecl(C, ID, Size);
644 return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, 0, 0,
645 NumExpansions, 0);
646}
647
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000648//===----------------------------------------------------------------------===//
Douglas Gregor7e063902009-05-11 23:53:27 +0000649// TemplateArgumentList Implementation
650//===----------------------------------------------------------------------===//
Douglas Gregor910f8002010-11-07 23:05:16 +0000651TemplateArgumentList *
652TemplateArgumentList::CreateCopy(ASTContext &Context,
653 const TemplateArgument *Args,
654 unsigned NumArgs) {
655 std::size_t Size = sizeof(TemplateArgumentList)
656 + NumArgs * sizeof(TemplateArgument);
657 void *Mem = Context.Allocate(Size);
658 TemplateArgument *StoredArgs
659 = reinterpret_cast<TemplateArgument *>(
660 static_cast<TemplateArgumentList *>(Mem) + 1);
661 std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
662 return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000663}
664
Argyrios Kyrtzidis71a76052011-09-22 20:07:09 +0000665FunctionTemplateSpecializationInfo *
666FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
667 FunctionTemplateDecl *Template,
668 TemplateSpecializationKind TSK,
669 const TemplateArgumentList *TemplateArgs,
670 const TemplateArgumentListInfo *TemplateArgsAsWritten,
671 SourceLocation POI) {
672 const ASTTemplateArgumentListInfo *ArgsAsWritten = 0;
673 if (TemplateArgsAsWritten)
674 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
675 *TemplateArgsAsWritten);
676
677 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
678 TemplateArgs,
679 ArgsAsWritten,
680 POI);
681}
682
Douglas Gregor7e063902009-05-11 23:53:27 +0000683//===----------------------------------------------------------------------===//
David Blaikie99ba9e32011-12-20 02:48:34 +0000684// TemplateDecl Implementation
685//===----------------------------------------------------------------------===//
686
687void TemplateDecl::anchor() { }
688
689//===----------------------------------------------------------------------===//
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000690// ClassTemplateSpecializationDecl Implementation
691//===----------------------------------------------------------------------===//
692ClassTemplateSpecializationDecl::
Douglas Gregor13c85772010-05-06 00:28:52 +0000693ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000694 DeclContext *DC, SourceLocation StartLoc,
695 SourceLocation IdLoc,
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000696 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000697 const TemplateArgument *Args,
698 unsigned NumArgs,
Douglas Gregor8e9e9ef2009-07-29 23:36:44 +0000699 ClassTemplateSpecializationDecl *PrevDecl)
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000700 : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc,
Douglas Gregor8e9e9ef2009-07-29 23:36:44 +0000701 SpecializedTemplate->getIdentifier(),
702 PrevDecl),
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000703 SpecializedTemplate(SpecializedTemplate),
Abramo Bagnarac98971d2010-06-12 07:44:57 +0000704 ExplicitInfo(0),
Douglas Gregor910f8002010-11-07 23:05:16 +0000705 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
Douglas Gregor7e063902009-05-11 23:53:27 +0000706 SpecializationKind(TSK_Undeclared) {
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000707}
Mike Stump1eb44332009-09-09 15:08:12 +0000708
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000709ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000710 : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0),
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000711 ExplicitInfo(0),
712 SpecializationKind(TSK_Undeclared) {
713}
714
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000715ClassTemplateSpecializationDecl *
Douglas Gregor13c85772010-05-06 00:28:52 +0000716ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000717 DeclContext *DC,
718 SourceLocation StartLoc,
719 SourceLocation IdLoc,
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000720 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000721 const TemplateArgument *Args,
722 unsigned NumArgs,
Douglas Gregorcc636682009-02-17 23:15:12 +0000723 ClassTemplateSpecializationDecl *PrevDecl) {
Douglas Gregorcc636682009-02-17 23:15:12 +0000724 ClassTemplateSpecializationDecl *Result
Mike Stump1eb44332009-09-09 15:08:12 +0000725 = new (Context)ClassTemplateSpecializationDecl(Context,
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000726 ClassTemplateSpecialization,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000727 TK, DC, StartLoc, IdLoc,
Douglas Gregor7e063902009-05-11 23:53:27 +0000728 SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000729 Args, NumArgs,
Douglas Gregor8e9e9ef2009-07-29 23:36:44 +0000730 PrevDecl);
Douglas Gregor6bd99292013-02-09 01:35:03 +0000731 Result->MayHaveOutOfDateDef = false;
732
Douglas Gregorcc636682009-02-17 23:15:12 +0000733 Context.getTypeDeclType(Result, PrevDecl);
734 return Result;
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000735}
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000736
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000737ClassTemplateSpecializationDecl *
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000738ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
739 unsigned ID) {
740 void *Mem = AllocateDeserializedDecl(C, ID,
741 sizeof(ClassTemplateSpecializationDecl));
Douglas Gregor6bd99292013-02-09 01:35:03 +0000742 ClassTemplateSpecializationDecl *Result =
743 new (Mem) ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
744 Result->MayHaveOutOfDateDef = false;
745 return Result;
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000746}
747
Douglas Gregorda2142f2011-02-19 18:51:44 +0000748void
749ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S,
750 const PrintingPolicy &Policy,
751 bool Qualified) const {
752 NamedDecl::getNameForDiagnostic(S, Policy, Qualified);
753
754 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
755 S += TemplateSpecializationType::PrintTemplateArgumentList(
756 TemplateArgs.data(),
757 TemplateArgs.size(),
758 Policy);
759}
760
Douglas Gregor37d93e92009-08-02 23:24:31 +0000761ClassTemplateDecl *
Mike Stump1eb44332009-09-09 15:08:12 +0000762ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
763 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor37d93e92009-08-02 23:24:31 +0000764 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
765 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
766 return SpecializedTemplate.get<ClassTemplateDecl*>();
767}
768
Abramo Bagnara4a85a732011-03-04 14:20:30 +0000769SourceRange
770ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnara09d82122011-10-03 20:34:03 +0000771 if (ExplicitInfo) {
Abramo Bagnarab2e80012012-10-15 21:06:42 +0000772 SourceLocation Begin = getTemplateKeywordLoc();
773 if (Begin.isValid()) {
774 // Here we have an explicit (partial) specialization or instantiation.
775 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
776 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
777 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
778 if (getExternLoc().isValid())
779 Begin = getExternLoc();
780 SourceLocation End = getRBraceLoc();
781 if (End.isInvalid())
782 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
783 return SourceRange(Begin, End);
784 }
785 // An implicit instantiation of a class template partial specialization
786 // uses ExplicitInfo to record the TypeAsWritten, but the source
787 // locations should be retrieved from the instantiation pattern.
788 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
789 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
790 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
791 assert(inst_from != 0);
792 return inst_from->getSourceRange();
Abramo Bagnara09d82122011-10-03 20:34:03 +0000793 }
794 else {
795 // No explicit info available.
796 llvm::PointerUnion<ClassTemplateDecl *,
797 ClassTemplatePartialSpecializationDecl *>
798 inst_from = getInstantiatedFrom();
799 if (inst_from.isNull())
800 return getSpecializedTemplate()->getSourceRange();
801 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
802 return ctd->getSourceRange();
803 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
804 ->getSourceRange();
805 }
Abramo Bagnara4a85a732011-03-04 14:20:30 +0000806}
807
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000808//===----------------------------------------------------------------------===//
809// ClassTemplatePartialSpecializationDecl Implementation
810//===----------------------------------------------------------------------===//
David Blaikie99ba9e32011-12-20 02:48:34 +0000811void ClassTemplatePartialSpecializationDecl::anchor() { }
812
Douglas Gregor9a299e02011-03-04 17:52:15 +0000813ClassTemplatePartialSpecializationDecl::
814ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000815 DeclContext *DC,
816 SourceLocation StartLoc,
817 SourceLocation IdLoc,
Douglas Gregor9a299e02011-03-04 17:52:15 +0000818 TemplateParameterList *Params,
819 ClassTemplateDecl *SpecializedTemplate,
820 const TemplateArgument *Args,
821 unsigned NumArgs,
822 TemplateArgumentLoc *ArgInfos,
823 unsigned NumArgInfos,
824 ClassTemplatePartialSpecializationDecl *PrevDecl,
825 unsigned SequenceNumber)
826 : ClassTemplateSpecializationDecl(Context,
827 ClassTemplatePartialSpecialization,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000828 TK, DC, StartLoc, IdLoc,
829 SpecializedTemplate,
Douglas Gregor9a299e02011-03-04 17:52:15 +0000830 Args, NumArgs, PrevDecl),
831 TemplateParams(Params), ArgsAsWritten(ArgInfos),
832 NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
833 InstantiatedFromMember(0, false)
834{
Douglas Gregor787a40d2011-03-04 18:32:38 +0000835 AdoptTemplateParameterList(Params, this);
Douglas Gregor9a299e02011-03-04 17:52:15 +0000836}
837
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000838ClassTemplatePartialSpecializationDecl *
839ClassTemplatePartialSpecializationDecl::
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000840Create(ASTContext &Context, TagKind TK,DeclContext *DC,
841 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000842 TemplateParameterList *Params,
843 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000844 const TemplateArgument *Args,
845 unsigned NumArgs,
John McCalld5532b62009-11-23 01:53:49 +0000846 const TemplateArgumentListInfo &ArgInfos,
John McCall3cb0ebd2010-03-10 03:28:59 +0000847 QualType CanonInjectedType,
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000848 ClassTemplatePartialSpecializationDecl *PrevDecl,
849 unsigned SequenceNumber) {
John McCalld5532b62009-11-23 01:53:49 +0000850 unsigned N = ArgInfos.size();
John McCall833ca992009-10-29 08:12:44 +0000851 TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
852 for (unsigned I = 0; I != N; ++I)
853 ClonedArgs[I] = ArgInfos[I];
854
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000855 ClassTemplatePartialSpecializationDecl *Result
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000856 = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC,
857 StartLoc, IdLoc,
858 Params,
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000859 SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000860 Args, NumArgs,
John McCall833ca992009-10-29 08:12:44 +0000861 ClonedArgs, N,
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000862 PrevDecl,
863 SequenceNumber);
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000864 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor6bd99292013-02-09 01:35:03 +0000865 Result->MayHaveOutOfDateDef = false;
John McCall3cb0ebd2010-03-10 03:28:59 +0000866
867 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000868 return Result;
869}
John McCalldd4a3b02009-09-16 22:47:08 +0000870
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000871ClassTemplatePartialSpecializationDecl *
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000872ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
873 unsigned ID) {
874 void *Mem = AllocateDeserializedDecl(C, ID,
875 sizeof(ClassTemplatePartialSpecializationDecl));
Douglas Gregor6bd99292013-02-09 01:35:03 +0000876 ClassTemplatePartialSpecializationDecl *Result
877 = new (Mem) ClassTemplatePartialSpecializationDecl();
878 Result->MayHaveOutOfDateDef = false;
879 return Result;
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000880}
881
John McCalldd4a3b02009-09-16 22:47:08 +0000882//===----------------------------------------------------------------------===//
883// FriendTemplateDecl Implementation
884//===----------------------------------------------------------------------===//
885
David Blaikie99ba9e32011-12-20 02:48:34 +0000886void FriendTemplateDecl::anchor() { }
887
John McCalldd4a3b02009-09-16 22:47:08 +0000888FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
889 DeclContext *DC,
890 SourceLocation L,
891 unsigned NParams,
892 TemplateParameterList **Params,
893 FriendUnion Friend,
894 SourceLocation FLoc) {
895 FriendTemplateDecl *Result
896 = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
897 return Result;
898}
Argyrios Kyrtzidis554e6aa2010-07-22 16:04:10 +0000899
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000900FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
901 unsigned ID) {
902 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FriendTemplateDecl));
903 return new (Mem) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis554e6aa2010-07-22 16:04:10 +0000904}
Richard Smith3e4c6c42011-05-05 21:57:07 +0000905
906//===----------------------------------------------------------------------===//
907// TypeAliasTemplateDecl Implementation
908//===----------------------------------------------------------------------===//
909
910TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
911 DeclContext *DC,
912 SourceLocation L,
913 DeclarationName Name,
914 TemplateParameterList *Params,
915 NamedDecl *Decl) {
916 AdoptTemplateParameterList(Params, DC);
917 return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl);
918}
919
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000920TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
921 unsigned ID) {
922 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasTemplateDecl));
923 return new (Mem) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(),
924 0, 0);
Richard Smith3e4c6c42011-05-05 21:57:07 +0000925}
926
927void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
928 static_cast<Common *>(Ptr)->~Common();
929}
930RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob76d9712013-01-23 16:52:57 +0000931TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3e4c6c42011-05-05 21:57:07 +0000932 Common *CommonPtr = new (C) Common;
933 C.AddDeallocation(DeallocateCommon, CommonPtr);
934 return CommonPtr;
935}
936
David Blaikie99ba9e32011-12-20 02:48:34 +0000937//===----------------------------------------------------------------------===//
938// ClassScopeFunctionSpecializationDecl Implementation
939//===----------------------------------------------------------------------===//
940
941void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000942
943ClassScopeFunctionSpecializationDecl *
944ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
945 unsigned ID) {
946 void *Mem = AllocateDeserializedDecl(C, ID,
947 sizeof(ClassScopeFunctionSpecializationDecl));
Nico Weber6b020092012-06-25 17:21:05 +0000948 return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0,
949 false, TemplateArgumentListInfo());
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000950}