blob: c07d8320732b0df9ac53d96e4f6e44c0f3717a30 [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
14#include "clang/AST/DeclCXX.h"
15#include "clang/AST/DeclTemplate.h"
Douglas Gregor55f6b142009-02-09 18:46:07 +000016#include "clang/AST/Expr.h"
Douglas Gregoraaba5e32009-02-04 19:02:06 +000017#include "clang/AST/ASTContext.h"
John McCall833ca992009-10-29 08:12:44 +000018#include "clang/AST/TypeLoc.h"
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +000019#include "clang/AST/ASTMutationListener.h"
Douglas Gregoraaba5e32009-02-04 19:02:06 +000020#include "clang/Basic/IdentifierTable.h"
21#include "llvm/ADT/STLExtras.h"
22using namespace clang;
23
24//===----------------------------------------------------------------------===//
25// TemplateParameterList Implementation
26//===----------------------------------------------------------------------===//
27
Douglas Gregorddc29e12009-02-06 22:42:48 +000028TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
29 SourceLocation LAngleLoc,
Douglas Gregorbf4ea562009-09-15 16:23:51 +000030 NamedDecl **Params, unsigned NumParams,
Douglas Gregorddc29e12009-02-06 22:42:48 +000031 SourceLocation RAngleLoc)
32 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
33 NumParams(NumParams) {
Douglas Gregoraaba5e32009-02-04 19:02:06 +000034 for (unsigned Idx = 0; Idx < NumParams; ++Idx)
35 begin()[Idx] = Params[Idx];
36}
37
38TemplateParameterList *
Douglas Gregorddc29e12009-02-06 22:42:48 +000039TemplateParameterList::Create(ASTContext &C, SourceLocation TemplateLoc,
Douglas Gregorbf4ea562009-09-15 16:23:51 +000040 SourceLocation LAngleLoc, NamedDecl **Params,
Douglas Gregorddc29e12009-02-06 22:42:48 +000041 unsigned NumParams, SourceLocation RAngleLoc) {
Douglas Gregorbf4ea562009-09-15 16:23:51 +000042 unsigned Size = sizeof(TemplateParameterList)
43 + sizeof(NamedDecl *) * NumParams;
Douglas Gregoraaba5e32009-02-04 19:02:06 +000044 unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment;
45 void *Mem = C.Allocate(Size, Align);
Mike Stump1eb44332009-09-09 15:08:12 +000046 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
Douglas Gregorddc29e12009-02-06 22:42:48 +000047 NumParams, RAngleLoc);
Douglas Gregoraaba5e32009-02-04 19:02:06 +000048}
49
Douglas Gregor62cb18d2009-02-11 18:16:40 +000050unsigned TemplateParameterList::getMinRequiredArguments() const {
51 unsigned NumRequiredArgs = size();
Mike Stump1eb44332009-09-09 15:08:12 +000052 iterator Param = const_cast<TemplateParameterList *>(this)->end(),
Douglas Gregor62cb18d2009-02-11 18:16:40 +000053 ParamBegin = const_cast<TemplateParameterList *>(this)->begin();
54 while (Param != ParamBegin) {
55 --Param;
Mike Stump1eb44332009-09-09 15:08:12 +000056
Anders Carlsson0ceffb52009-06-13 02:08:00 +000057 if (!(*Param)->isTemplateParameterPack() &&
Mike Stump1eb44332009-09-09 15:08:12 +000058 !(isa<TemplateTypeParmDecl>(*Param) &&
Douglas Gregor62cb18d2009-02-11 18:16:40 +000059 cast<TemplateTypeParmDecl>(*Param)->hasDefaultArgument()) &&
60 !(isa<NonTypeTemplateParmDecl>(*Param) &&
61 cast<NonTypeTemplateParmDecl>(*Param)->hasDefaultArgument()) &&
62 !(isa<TemplateTemplateParmDecl>(*Param) &&
63 cast<TemplateTemplateParmDecl>(*Param)->hasDefaultArgument()))
64 break;
Mike Stump1eb44332009-09-09 15:08:12 +000065
Douglas Gregor62cb18d2009-02-11 18:16:40 +000066 --NumRequiredArgs;
67 }
68
69 return NumRequiredArgs;
70}
71
Douglas Gregored9c0f92009-10-29 00:04:11 +000072unsigned TemplateParameterList::getDepth() const {
73 if (size() == 0)
74 return 0;
75
76 const NamedDecl *FirstParm = getParam(0);
77 if (const TemplateTypeParmDecl *TTP
78 = dyn_cast<TemplateTypeParmDecl>(FirstParm))
79 return TTP->getDepth();
80 else if (const NonTypeTemplateParmDecl *NTTP
81 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
82 return NTTP->getDepth();
83 else
84 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
85}
86
Douglas Gregoraaba5e32009-02-04 19:02:06 +000087//===----------------------------------------------------------------------===//
Peter Collingbourne9eabeba2010-07-29 16:11:51 +000088// RedeclarableTemplateDecl Implementation
89//===----------------------------------------------------------------------===//
90
91RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() {
92 // Find the first declaration of this function template.
93 RedeclarableTemplateDecl *First = getCanonicalDecl();
94
95 if (First->CommonOrPrev.isNull()) {
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +000096 CommonBase *CommonPtr = First->newCommon(getASTContext());
Peter Collingbourne9eabeba2010-07-29 16:11:51 +000097 First->CommonOrPrev = CommonPtr;
Peter Collingbourne8a798a72010-07-29 16:12:01 +000098 CommonPtr->Latest = First;
Peter Collingbourne9eabeba2010-07-29 16:11:51 +000099 }
100 return First->CommonOrPrev.get<CommonBase*>();
101}
102
103
104RedeclarableTemplateDecl *RedeclarableTemplateDecl::getCanonicalDeclImpl() {
105 RedeclarableTemplateDecl *Tmpl = this;
106 while (Tmpl->getPreviousDeclaration())
107 Tmpl = Tmpl->getPreviousDeclaration();
108 return Tmpl;
109}
110
Peter Collingbourne8a798a72010-07-29 16:12:01 +0000111void RedeclarableTemplateDecl::setPreviousDeclarationImpl(
112 RedeclarableTemplateDecl *Prev) {
113 if (Prev) {
114 CommonBase *Common = Prev->getCommonPtr();
115 Prev = Common->Latest;
116 Common->Latest = this;
117 CommonOrPrev = Prev;
118 } else {
119 assert(CommonOrPrev.is<CommonBase*>() && "Cannot reset TemplateDecl Prev");
120 }
121}
122
Peter Collingbournef88718e2010-07-29 16:12:09 +0000123RedeclarableTemplateDecl *RedeclarableTemplateDecl::getNextRedeclaration() {
124 if (CommonOrPrev.is<RedeclarableTemplateDecl*>())
125 return CommonOrPrev.get<RedeclarableTemplateDecl*>();
126 CommonBase *Common = CommonOrPrev.get<CommonBase*>();
127 return Common ? Common->Latest : this;
128}
129
Peter Collingbourne40485902010-07-30 17:09:04 +0000130template <class EntryType>
131typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
132RedeclarableTemplateDecl::findSpecializationImpl(
133 llvm::FoldingSet<EntryType> &Specs,
134 const TemplateArgument *Args, unsigned NumArgs,
135 void *&InsertPos) {
136 typedef SpecEntryTraits<EntryType> SETraits;
137 llvm::FoldingSetNodeID ID;
138 EntryType::Profile(ID,Args,NumArgs, getASTContext());
139 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
140 return Entry ? SETraits::getMostRecentDeclaration(Entry) : 0;
141}
142
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000143//===----------------------------------------------------------------------===//
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000144// FunctionTemplateDecl Implementation
145//===----------------------------------------------------------------------===//
146
Douglas Gregor00545312010-05-23 18:26:36 +0000147void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
148 static_cast<Common *>(Ptr)->~Common();
149}
150
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000151FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
152 DeclContext *DC,
153 SourceLocation L,
154 DeclarationName Name,
Douglas Gregor127102b2009-06-29 20:59:39 +0000155 TemplateParameterList *Params,
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000156 NamedDecl *Decl) {
157 return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
158}
159
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +0000160RedeclarableTemplateDecl::CommonBase *
161FunctionTemplateDecl::newCommon(ASTContext &C) {
162 Common *CommonPtr = new (C) Common;
163 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000164 return CommonPtr;
165}
166
Argyrios Kyrtzidis2c853e42010-07-20 13:59:58 +0000167FunctionDecl *
168FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
169 unsigned NumArgs, void *&InsertPos) {
Peter Collingbourne40485902010-07-30 17:09:04 +0000170 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
Argyrios Kyrtzidis2c853e42010-07-20 13:59:58 +0000171}
172
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000173//===----------------------------------------------------------------------===//
174// ClassTemplateDecl Implementation
175//===----------------------------------------------------------------------===//
176
Douglas Gregor00545312010-05-23 18:26:36 +0000177void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
178 static_cast<Common *>(Ptr)->~Common();
179}
180
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000181ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
182 DeclContext *DC,
183 SourceLocation L,
184 DeclarationName Name,
185 TemplateParameterList *Params,
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000186 NamedDecl *Decl,
187 ClassTemplateDecl *PrevDecl) {
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +0000188 ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
Argyrios Kyrtzidis5bf1bdc2010-06-21 10:57:41 +0000189 New->setPreviousDeclaration(PrevDecl);
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +0000190 return New;
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000191}
192
Douglas Gregorc8e5cf82010-10-27 22:21:36 +0000193void ClassTemplateDecl::LoadLazySpecializations() {
194 Common *CommonPtr = getCommonPtr();
195 if (CommonPtr->LazySpecializations) {
196 ASTContext &Context = getASTContext();
197 uint32_t *Specs = CommonPtr->LazySpecializations;
198 CommonPtr->LazySpecializations = 0;
199 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
200 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
201 }
202}
203
204llvm::FoldingSet<ClassTemplateSpecializationDecl> &
205ClassTemplateDecl::getSpecializations() {
206 LoadLazySpecializations();
207 return getCommonPtr()->Specializations;
208}
209
210llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
211ClassTemplateDecl::getPartialSpecializations() {
212 LoadLazySpecializations();
213 return getCommonPtr()->PartialSpecializations;
214}
215
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +0000216RedeclarableTemplateDecl::CommonBase *
217ClassTemplateDecl::newCommon(ASTContext &C) {
218 Common *CommonPtr = new (C) Common;
219 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000220 return CommonPtr;
221}
222
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000223ClassTemplateSpecializationDecl *
224ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
225 unsigned NumArgs, void *&InsertPos) {
Peter Collingbourne40485902010-07-30 17:09:04 +0000226 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000227}
228
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000229void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
230 void *InsertPos) {
231 getSpecializations().InsertNode(D, InsertPos);
232 if (ASTMutationListener *L = getASTMutationListener())
233 L->AddedCXXTemplateSpecialization(this, D);
234}
235
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000236ClassTemplatePartialSpecializationDecl *
237ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
238 unsigned NumArgs,
239 void *&InsertPos) {
Peter Collingbourne40485902010-07-30 17:09:04 +0000240 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
241 InsertPos);
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000242}
243
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000244void ClassTemplateDecl::AddPartialSpecialization(
245 ClassTemplatePartialSpecializationDecl *D,
246 void *InsertPos) {
247 getPartialSpecializations().InsertNode(D, InsertPos);
248 if (ASTMutationListener *L = getASTMutationListener())
249 L->AddedCXXTemplateSpecialization(this, D);
250}
251
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000252void ClassTemplateDecl::getPartialSpecializations(
253 llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
254 llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &PartialSpecs
Argyrios Kyrtzidis5bf1bdc2010-06-21 10:57:41 +0000255 = getPartialSpecializations();
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000256 PS.clear();
257 PS.resize(PartialSpecs.size());
258 for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
259 P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
260 P != PEnd; ++P) {
261 assert(!PS[P->getSequenceNumber()]);
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000262 PS[P->getSequenceNumber()] = P->getMostRecentDeclaration();
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000263 }
264}
265
Douglas Gregorb88e8882009-07-30 17:40:51 +0000266ClassTemplatePartialSpecializationDecl *
267ClassTemplateDecl::findPartialSpecialization(QualType T) {
268 ASTContext &Context = getASTContext();
269 typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
270 partial_spec_iterator;
271 for (partial_spec_iterator P = getPartialSpecializations().begin(),
272 PEnd = getPartialSpecializations().end();
273 P != PEnd; ++P) {
John McCall31f17ec2010-04-27 00:57:59 +0000274 if (Context.hasSameType(P->getInjectedSpecializationType(), T))
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000275 return P->getMostRecentDeclaration();
276 }
277
278 return 0;
279}
280
281ClassTemplatePartialSpecializationDecl *
282ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
283 ClassTemplatePartialSpecializationDecl *D) {
284 Decl *DCanon = D->getCanonicalDecl();
285 for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
286 P = getPartialSpecializations().begin(),
287 PEnd = getPartialSpecializations().end();
288 P != PEnd; ++P) {
289 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
290 return P->getMostRecentDeclaration();
Douglas Gregorb88e8882009-07-30 17:40:51 +0000291 }
Mike Stump1eb44332009-09-09 15:08:12 +0000292
Douglas Gregorb88e8882009-07-30 17:40:51 +0000293 return 0;
294}
295
John McCall3cb0ebd2010-03-10 03:28:59 +0000296QualType
Douglas Gregor24bae922010-07-08 18:37:38 +0000297ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidis5bf1bdc2010-06-21 10:57:41 +0000298 Common *CommonPtr = getCommonPtr();
Douglas Gregor7da97d02009-05-10 22:57:19 +0000299 if (!CommonPtr->InjectedClassNameType.isNull())
300 return CommonPtr->InjectedClassNameType;
301
302 // FIXME: n2800 14.6.1p1 should say how the template arguments
303 // corresponding to template parameter packs should be pack
304 // expansions. We already say that in 14.6.2.1p2, so it would be
305 // better to fix that redundancy.
Douglas Gregor24bae922010-07-08 18:37:38 +0000306 ASTContext &Context = getASTContext();
Douglas Gregor7da97d02009-05-10 22:57:19 +0000307 TemplateParameterList *Params = getTemplateParameters();
Douglas Gregor7da97d02009-05-10 22:57:19 +0000308 llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
Douglas Gregor7da97d02009-05-10 22:57:19 +0000309 TemplateArgs.reserve(Params->size());
Mike Stump1eb44332009-09-09 15:08:12 +0000310 for (TemplateParameterList::iterator Param = Params->begin(),
311 ParamEnd = Params->end();
Douglas Gregor7da97d02009-05-10 22:57:19 +0000312 Param != ParamEnd; ++Param) {
313 if (isa<TemplateTypeParmDecl>(*Param)) {
314 QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param));
John McCall833ca992009-10-29 08:12:44 +0000315 TemplateArgs.push_back(TemplateArgument(ParamType));
Mike Stump1eb44332009-09-09 15:08:12 +0000316 } else if (NonTypeTemplateParmDecl *NTTP =
Douglas Gregor7da97d02009-05-10 22:57:19 +0000317 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
Chandler Carruthb7de1812010-01-31 07:24:03 +0000318 Expr *E = new (Context) DeclRefExpr(NTTP,
Douglas Gregor63982352010-07-13 18:40:04 +0000319 NTTP->getType().getNonLValueExprType(Context),
Douglas Gregor0da76df2009-11-23 11:41:28 +0000320 NTTP->getLocation());
Douglas Gregor7da97d02009-05-10 22:57:19 +0000321 TemplateArgs.push_back(TemplateArgument(E));
Mike Stump1eb44332009-09-09 15:08:12 +0000322 } else {
Douglas Gregor7da97d02009-05-10 22:57:19 +0000323 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
Douglas Gregor788cd062009-11-11 01:00:40 +0000324 TemplateArgs.push_back(TemplateArgument(TemplateName(TTP)));
Douglas Gregor7da97d02009-05-10 22:57:19 +0000325 }
326 }
327
Douglas Gregor7da97d02009-05-10 22:57:19 +0000328 CommonPtr->InjectedClassNameType
Douglas Gregor1275ae02009-07-28 23:00:59 +0000329 = Context.getTemplateSpecializationType(TemplateName(this),
Douglas Gregor7da97d02009-05-10 22:57:19 +0000330 &TemplateArgs[0],
Douglas Gregor1275ae02009-07-28 23:00:59 +0000331 TemplateArgs.size());
Douglas Gregor7da97d02009-05-10 22:57:19 +0000332 return CommonPtr->InjectedClassNameType;
333}
334
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000335//===----------------------------------------------------------------------===//
336// TemplateTypeParm Allocation/Deallocation Method Implementations
337//===----------------------------------------------------------------------===//
338
339TemplateTypeParmDecl *
340TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC,
341 SourceLocation L, unsigned D, unsigned P,
Anders Carlsson6d845ae2009-06-12 22:23:22 +0000342 IdentifierInfo *Id, bool Typename,
343 bool ParameterPack) {
Douglas Gregorefed5c82010-06-16 15:23:05 +0000344 QualType Type = C.getTemplateTypeParmType(D, P, ParameterPack, Id);
345 return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack);
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000346}
347
Argyrios Kyrtzidisb8b03e62010-07-02 11:54:55 +0000348TemplateTypeParmDecl *
349TemplateTypeParmDecl::Create(ASTContext &C, EmptyShell Empty) {
350 return new (C) TemplateTypeParmDecl(0, SourceLocation(), 0, false,
351 QualType(), false);
352}
353
John McCall833ca992009-10-29 08:12:44 +0000354SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnarabd054db2010-05-20 10:00:11 +0000355 return DefaultArgument->getTypeLoc().getSourceRange().getBegin();
John McCall833ca992009-10-29 08:12:44 +0000356}
357
Douglas Gregored9c0f92009-10-29 00:04:11 +0000358unsigned TemplateTypeParmDecl::getDepth() const {
359 return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
360}
361
362unsigned TemplateTypeParmDecl::getIndex() const {
363 return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
364}
365
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000366//===----------------------------------------------------------------------===//
367// NonTypeTemplateParmDecl Method Implementations
368//===----------------------------------------------------------------------===//
369
370NonTypeTemplateParmDecl *
371NonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
372 SourceLocation L, unsigned D, unsigned P,
373 IdentifierInfo *Id, QualType T,
John McCalla93c9342009-12-07 02:54:59 +0000374 TypeSourceInfo *TInfo) {
375 return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, TInfo);
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000376}
377
Douglas Gregord684b002009-02-10 19:49:53 +0000378SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnarad92f7a22010-06-09 09:26:05 +0000379 return hasDefaultArgument()
380 ? getDefaultArgument()->getSourceRange().getBegin()
381 : SourceLocation();
Douglas Gregord684b002009-02-10 19:49:53 +0000382}
383
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000384//===----------------------------------------------------------------------===//
385// TemplateTemplateParmDecl Method Implementations
386//===----------------------------------------------------------------------===//
387
388TemplateTemplateParmDecl *
389TemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
390 SourceLocation L, unsigned D, unsigned P,
391 IdentifierInfo *Id,
392 TemplateParameterList *Params) {
393 return new (C) TemplateTemplateParmDecl(DC, L, D, P, Id, Params);
394}
395
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000396//===----------------------------------------------------------------------===//
Anders Carlsson9ba41642009-06-05 05:31:27 +0000397// TemplateArgumentListBuilder Implementation
398//===----------------------------------------------------------------------===//
Anders Carlssonfb250522009-06-23 01:26:57 +0000399
Chris Lattner98d279b2010-05-20 00:25:36 +0000400void TemplateArgumentListBuilder::Append(const TemplateArgument &Arg) {
401 assert((Arg.getKind() != TemplateArgument::Type ||
402 Arg.getAsType().isCanonical()) && "Type must be canonical!");
403 assert(FlatArgs.size() < MaxFlatArgs && "Argument list builder is full!");
Mike Stump1eb44332009-09-09 15:08:12 +0000404 assert(!StructuredArgs &&
Anders Carlssonfb250522009-06-23 01:26:57 +0000405 "Can't append arguments when an argument pack has been added!");
Mike Stump1eb44332009-09-09 15:08:12 +0000406
Chris Lattner98d279b2010-05-20 00:25:36 +0000407 FlatArgs.push_back(Arg);
Anders Carlsson9ba41642009-06-05 05:31:27 +0000408}
409
Anders Carlssonfb250522009-06-23 01:26:57 +0000410void TemplateArgumentListBuilder::BeginPack() {
411 assert(!AddingToPack && "Already adding to pack!");
412 assert(!StructuredArgs && "Argument list already contains a pack!");
Mike Stump1eb44332009-09-09 15:08:12 +0000413
Anders Carlssonfb250522009-06-23 01:26:57 +0000414 AddingToPack = true;
Chris Lattner98d279b2010-05-20 00:25:36 +0000415 PackBeginIndex = FlatArgs.size();
Anders Carlsson67e33202009-06-13 00:08:58 +0000416}
417
Anders Carlssonfb250522009-06-23 01:26:57 +0000418void TemplateArgumentListBuilder::EndPack() {
419 assert(AddingToPack && "Not adding to pack!");
420 assert(!StructuredArgs && "Argument list already contains a pack!");
Mike Stump1eb44332009-09-09 15:08:12 +0000421
Anders Carlssonfb250522009-06-23 01:26:57 +0000422 AddingToPack = false;
Anders Carlsson3b36b662009-06-15 17:56:45 +0000423
Chris Lattner304d0fa2010-05-20 00:26:28 +0000424 // FIXME: This is a memory leak!
Anders Carlssonfb250522009-06-23 01:26:57 +0000425 StructuredArgs = new TemplateArgument[MaxStructuredArgs];
Mike Stump1eb44332009-09-09 15:08:12 +0000426
Anders Carlssonfb250522009-06-23 01:26:57 +0000427 // First copy the flat entries over to the list (if any)
428 for (unsigned I = 0; I != PackBeginIndex; ++I) {
429 NumStructuredArgs++;
430 StructuredArgs[I] = FlatArgs[I];
431 }
Mike Stump1eb44332009-09-09 15:08:12 +0000432
Anders Carlssonfb250522009-06-23 01:26:57 +0000433 // Next, set the pack.
434 TemplateArgument *PackArgs = 0;
435 unsigned NumPackArgs = NumFlatArgs - PackBeginIndex;
Chris Lattner98d279b2010-05-20 00:25:36 +0000436 // FIXME: NumPackArgs shouldn't be negative here???
Anders Carlssonfb250522009-06-23 01:26:57 +0000437 if (NumPackArgs)
Chris Lattner98d279b2010-05-20 00:25:36 +0000438 PackArgs = FlatArgs.data()+PackBeginIndex;
Mike Stump1eb44332009-09-09 15:08:12 +0000439
440 StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs,
Anders Carlssonfb250522009-06-23 01:26:57 +0000441 /*CopyArgs=*/false);
442}
443
Anders Carlsson9ba41642009-06-05 05:31:27 +0000444//===----------------------------------------------------------------------===//
Douglas Gregor7e063902009-05-11 23:53:27 +0000445// TemplateArgumentList Implementation
446//===----------------------------------------------------------------------===//
447TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
Anders Carlssone9c904b2009-06-05 04:47:51 +0000448 TemplateArgumentListBuilder &Builder,
Anders Carlssonfb250522009-06-23 01:26:57 +0000449 bool TakeArgs)
Mike Stump1eb44332009-09-09 15:08:12 +0000450 : FlatArguments(Builder.getFlatArguments(), TakeArgs),
451 NumFlatArguments(Builder.flatSize()),
Anders Carlssonfb250522009-06-23 01:26:57 +0000452 StructuredArguments(Builder.getStructuredArguments(), TakeArgs),
453 NumStructuredArguments(Builder.structuredSize()) {
Mike Stump1eb44332009-09-09 15:08:12 +0000454
Anders Carlssonfb250522009-06-23 01:26:57 +0000455 if (!TakeArgs)
456 return;
Mike Stump1eb44332009-09-09 15:08:12 +0000457
Chris Lattner56ef5502010-05-20 00:11:47 +0000458 // If this does take ownership of the arguments, then we have to new them
459 // and copy over.
Ted Kremenek3458d432010-05-25 20:43:29 +0000460 TemplateArgument *NewArgs =
461 new (Context) TemplateArgument[Builder.flatSize()];
Chris Lattner56ef5502010-05-20 00:11:47 +0000462 std::copy(Builder.getFlatArguments(),
463 Builder.getFlatArguments()+Builder.flatSize(), NewArgs);
464 FlatArguments.setPointer(NewArgs);
465
466 // Just reuse the structured and flat arguments array if possible.
467 if (Builder.getStructuredArguments() == Builder.getFlatArguments()) {
468 StructuredArguments.setPointer(NewArgs);
Anders Carlssonfb250522009-06-23 01:26:57 +0000469 StructuredArguments.setInt(0);
Chris Lattner56ef5502010-05-20 00:11:47 +0000470 } else {
Ted Kremenek3458d432010-05-25 20:43:29 +0000471 TemplateArgument *NewSArgs =
472 new (Context) TemplateArgument[Builder.flatSize()];
Chris Lattner56ef5502010-05-20 00:11:47 +0000473 std::copy(Builder.getFlatArguments(),
474 Builder.getFlatArguments()+Builder.flatSize(), NewSArgs);
475 StructuredArguments.setPointer(NewSArgs);
476 }
Douglas Gregor7e063902009-05-11 23:53:27 +0000477}
478
Argyrios Kyrtzidisd0913552010-06-22 09:54:51 +0000479TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000480 const TemplateArgument *Args,
Argyrios Kyrtzidisdc767e32010-06-28 09:31:34 +0000481 unsigned NumArgs)
482 : NumFlatArguments(0), NumStructuredArguments(0) {
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000483 init(Context, Args, NumArgs);
Argyrios Kyrtzidisd0913552010-06-22 09:54:51 +0000484}
485
Chris Lattner88598912010-05-20 00:19:09 +0000486/// Produces a shallow copy of the given template argument list. This
487/// assumes that the input argument list outlives it. This takes the list as
488/// a pointer to avoid looking like a copy constructor, since this really
489/// really isn't safe to use that way.
490TemplateArgumentList::TemplateArgumentList(const TemplateArgumentList *Other)
491 : FlatArguments(Other->FlatArguments.getPointer(), false),
492 NumFlatArguments(Other->flat_size()),
493 StructuredArguments(Other->StructuredArguments.getPointer(), false),
494 NumStructuredArguments(Other->NumStructuredArguments) { }
Douglas Gregorb9aa6b22009-09-24 23:14:47 +0000495
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000496void TemplateArgumentList::init(ASTContext &Context,
497 const TemplateArgument *Args,
498 unsigned NumArgs) {
499assert(NumFlatArguments == 0 && NumStructuredArguments == 0 &&
500 "Already initialized!");
501
502NumFlatArguments = NumStructuredArguments = NumArgs;
503TemplateArgument *NewArgs = new (Context) TemplateArgument[NumArgs];
504std::copy(Args, Args+NumArgs, NewArgs);
505FlatArguments.setPointer(NewArgs);
506FlatArguments.setInt(1); // Owns the pointer.
507
508// Just reuse the flat arguments array.
509StructuredArguments.setPointer(NewArgs);
510StructuredArguments.setInt(0); // Doesn't own the pointer.
511}
512
Douglas Gregor7e063902009-05-11 23:53:27 +0000513//===----------------------------------------------------------------------===//
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000514// ClassTemplateSpecializationDecl Implementation
515//===----------------------------------------------------------------------===//
516ClassTemplateSpecializationDecl::
Douglas Gregor13c85772010-05-06 00:28:52 +0000517ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Douglas Gregor7e063902009-05-11 23:53:27 +0000518 DeclContext *DC, SourceLocation L,
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000519 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor8e9e9ef2009-07-29 23:36:44 +0000520 TemplateArgumentListBuilder &Builder,
521 ClassTemplateSpecializationDecl *PrevDecl)
Douglas Gregor13c85772010-05-06 00:28:52 +0000522 : CXXRecordDecl(DK, TK, DC, L,
Douglas Gregor8e9e9ef2009-07-29 23:36:44 +0000523 SpecializedTemplate->getIdentifier(),
524 PrevDecl),
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000525 SpecializedTemplate(SpecializedTemplate),
Abramo Bagnarac98971d2010-06-12 07:44:57 +0000526 ExplicitInfo(0),
Anders Carlssonfb250522009-06-23 01:26:57 +0000527 TemplateArgs(Context, Builder, /*TakeArgs=*/true),
Douglas Gregor7e063902009-05-11 23:53:27 +0000528 SpecializationKind(TSK_Undeclared) {
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000529}
Mike Stump1eb44332009-09-09 15:08:12 +0000530
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000531ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
532 : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), 0, 0),
533 ExplicitInfo(0),
534 SpecializationKind(TSK_Undeclared) {
535}
536
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000537ClassTemplateSpecializationDecl *
Douglas Gregor13c85772010-05-06 00:28:52 +0000538ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000539 DeclContext *DC, SourceLocation L,
540 ClassTemplateDecl *SpecializedTemplate,
Anders Carlsson91fdf6f2009-06-05 04:06:48 +0000541 TemplateArgumentListBuilder &Builder,
Douglas Gregorcc636682009-02-17 23:15:12 +0000542 ClassTemplateSpecializationDecl *PrevDecl) {
Douglas Gregorcc636682009-02-17 23:15:12 +0000543 ClassTemplateSpecializationDecl *Result
Mike Stump1eb44332009-09-09 15:08:12 +0000544 = new (Context)ClassTemplateSpecializationDecl(Context,
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000545 ClassTemplateSpecialization,
Douglas Gregor13c85772010-05-06 00:28:52 +0000546 TK, DC, L,
Douglas Gregor7e063902009-05-11 23:53:27 +0000547 SpecializedTemplate,
Douglas Gregor8e9e9ef2009-07-29 23:36:44 +0000548 Builder,
549 PrevDecl);
Douglas Gregorcc636682009-02-17 23:15:12 +0000550 Context.getTypeDeclType(Result, PrevDecl);
551 return Result;
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000552}
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000553
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000554ClassTemplateSpecializationDecl *
Argyrios Kyrtzidisb8b03e62010-07-02 11:54:55 +0000555ClassTemplateSpecializationDecl::Create(ASTContext &Context, EmptyShell Empty) {
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000556 return
557 new (Context)ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
558}
559
John McCall136a6982009-09-11 06:45:03 +0000560void
561ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S,
562 const PrintingPolicy &Policy,
563 bool Qualified) const {
564 NamedDecl::getNameForDiagnostic(S, Policy, Qualified);
565
566 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
567 S += TemplateSpecializationType::PrintTemplateArgumentList(
568 TemplateArgs.getFlatArgumentList(),
569 TemplateArgs.flat_size(),
570 Policy);
571}
572
Douglas Gregor37d93e92009-08-02 23:24:31 +0000573ClassTemplateDecl *
Mike Stump1eb44332009-09-09 15:08:12 +0000574ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
575 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor37d93e92009-08-02 23:24:31 +0000576 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
577 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
578 return SpecializedTemplate.get<ClassTemplateDecl*>();
579}
580
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000581//===----------------------------------------------------------------------===//
582// ClassTemplatePartialSpecializationDecl Implementation
583//===----------------------------------------------------------------------===//
584ClassTemplatePartialSpecializationDecl *
585ClassTemplatePartialSpecializationDecl::
Douglas Gregor13c85772010-05-06 00:28:52 +0000586Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000587 TemplateParameterList *Params,
588 ClassTemplateDecl *SpecializedTemplate,
Anders Carlsson91fdf6f2009-06-05 04:06:48 +0000589 TemplateArgumentListBuilder &Builder,
John McCalld5532b62009-11-23 01:53:49 +0000590 const TemplateArgumentListInfo &ArgInfos,
John McCall3cb0ebd2010-03-10 03:28:59 +0000591 QualType CanonInjectedType,
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000592 ClassTemplatePartialSpecializationDecl *PrevDecl,
593 unsigned SequenceNumber) {
John McCalld5532b62009-11-23 01:53:49 +0000594 unsigned N = ArgInfos.size();
John McCall833ca992009-10-29 08:12:44 +0000595 TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
596 for (unsigned I = 0; I != N; ++I)
597 ClonedArgs[I] = ArgInfos[I];
598
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000599 ClassTemplatePartialSpecializationDecl *Result
Douglas Gregor13c85772010-05-06 00:28:52 +0000600 = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK,
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000601 DC, L, Params,
602 SpecializedTemplate,
John McCall833ca992009-10-29 08:12:44 +0000603 Builder,
604 ClonedArgs, N,
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000605 PrevDecl,
606 SequenceNumber);
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000607 Result->setSpecializationKind(TSK_ExplicitSpecialization);
John McCall3cb0ebd2010-03-10 03:28:59 +0000608
609 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000610 return Result;
611}
John McCalldd4a3b02009-09-16 22:47:08 +0000612
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000613ClassTemplatePartialSpecializationDecl *
Argyrios Kyrtzidisb8b03e62010-07-02 11:54:55 +0000614ClassTemplatePartialSpecializationDecl::Create(ASTContext &Context,
615 EmptyShell Empty) {
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000616 return new (Context)ClassTemplatePartialSpecializationDecl();
617}
618
John McCalldd4a3b02009-09-16 22:47:08 +0000619//===----------------------------------------------------------------------===//
620// FriendTemplateDecl Implementation
621//===----------------------------------------------------------------------===//
622
623FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
624 DeclContext *DC,
625 SourceLocation L,
626 unsigned NParams,
627 TemplateParameterList **Params,
628 FriendUnion Friend,
629 SourceLocation FLoc) {
630 FriendTemplateDecl *Result
631 = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
632 return Result;
633}
Argyrios Kyrtzidis554e6aa2010-07-22 16:04:10 +0000634
635FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
636 EmptyShell Empty) {
637 return new (Context) FriendTemplateDecl(Empty);
638}