blob: 2c64e5933bd8979d91e38c38240cb1a20cbcd438 [file] [log] [blame]
Sebastian Redle2530ec2009-10-23 22:13:42 +00001//===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
Douglas Gregorded2d7b2009-02-04 19:02:06 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the C++ related Decl classes for templates.
11//
12//===----------------------------------------------------------------------===//
13
Douglas Gregorded2d7b2009-02-04 19:02:06 +000014#include "clang/AST/DeclTemplate.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000015#include "clang/AST/ASTContext.h"
16#include "clang/AST/ASTMutationListener.h"
17#include "clang/AST/DeclCXX.h"
Douglas Gregor8bf42052009-02-09 18:46:07 +000018#include "clang/AST/Expr.h"
Douglas Gregor85759112011-01-04 02:33:52 +000019#include "clang/AST/ExprCXX.h"
John McCall0ad16662009-10-29 08:12:44 +000020#include "clang/AST/TypeLoc.h"
Douglas Gregorded2d7b2009-02-04 19:02:06 +000021#include "clang/Basic/IdentifierTable.h"
22#include "llvm/ADT/STLExtras.h"
Douglas Gregor1ccc8412010-11-07 23:05:16 +000023#include <memory>
Douglas Gregorded2d7b2009-02-04 19:02:06 +000024using namespace clang;
25
26//===----------------------------------------------------------------------===//
27// TemplateParameterList Implementation
28//===----------------------------------------------------------------------===//
29
Douglas Gregorcd72ba92009-02-06 22:42:48 +000030TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
31 SourceLocation LAngleLoc,
Douglas Gregorbe999392009-09-15 16:23:51 +000032 NamedDecl **Params, unsigned NumParams,
Douglas Gregorcd72ba92009-02-06 22:42:48 +000033 SourceLocation RAngleLoc)
34 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
Richard Smith1fde8ec2012-09-07 02:06:42 +000035 NumParams(NumParams), ContainsUnexpandedParameterPack(false) {
36 assert(this->NumParams == NumParams && "Too many template parameters");
37 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
38 NamedDecl *P = Params[Idx];
39 begin()[Idx] = P;
40
41 if (!P->isTemplateParameterPack()) {
42 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
43 if (NTTP->getType()->containsUnexpandedParameterPack())
44 ContainsUnexpandedParameterPack = true;
45
46 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
47 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
48 ContainsUnexpandedParameterPack = true;
49
50 // FIXME: If a default argument contains an unexpanded parameter pack, the
51 // template parameter list does too.
52 }
53 }
Douglas Gregorded2d7b2009-02-04 19:02:06 +000054}
55
56TemplateParameterList *
Jay Foad39c79802011-01-12 09:06:06 +000057TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
Douglas Gregorbe999392009-09-15 16:23:51 +000058 SourceLocation LAngleLoc, NamedDecl **Params,
Douglas Gregorcd72ba92009-02-06 22:42:48 +000059 unsigned NumParams, SourceLocation RAngleLoc) {
Douglas Gregorbe999392009-09-15 16:23:51 +000060 unsigned Size = sizeof(TemplateParameterList)
61 + sizeof(NamedDecl *) * NumParams;
Richard Smith426f7852012-08-16 22:51:34 +000062 unsigned Align = std::max(llvm::alignOf<TemplateParameterList>(),
63 llvm::alignOf<NamedDecl*>());
Douglas Gregorded2d7b2009-02-04 19:02:06 +000064 void *Mem = C.Allocate(Size, Align);
Mike Stump11289f42009-09-09 15:08:12 +000065 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
Douglas Gregorcd72ba92009-02-06 22:42:48 +000066 NumParams, RAngleLoc);
Douglas Gregorded2d7b2009-02-04 19:02:06 +000067}
68
Douglas Gregorf8f86832009-02-11 18:16:40 +000069unsigned TemplateParameterList::getMinRequiredArguments() const {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000070 unsigned NumRequiredArgs = 0;
71 for (iterator P = const_cast<TemplateParameterList *>(this)->begin(),
72 PEnd = const_cast<TemplateParameterList *>(this)->end();
73 P != PEnd; ++P) {
74 if ((*P)->isTemplateParameterPack()) {
75 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P))
76 if (NTTP->isExpandedParameterPack()) {
77 NumRequiredArgs += NTTP->getNumExpansionTypes();
78 continue;
79 }
80
Douglas Gregorf8f86832009-02-11 18:16:40 +000081 break;
Douglas Gregor0231d8d2011-01-19 20:10:05 +000082 }
83
84 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
85 if (TTP->hasDefaultArgument())
86 break;
87 } else if (NonTypeTemplateParmDecl *NTTP
88 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
89 if (NTTP->hasDefaultArgument())
90 break;
91 } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument())
92 break;
93
94 ++NumRequiredArgs;
Douglas Gregorf8f86832009-02-11 18:16:40 +000095 }
Douglas Gregor0231d8d2011-01-19 20:10:05 +000096
Douglas Gregorf8f86832009-02-11 18:16:40 +000097 return NumRequiredArgs;
98}
99
Douglas Gregor21610382009-10-29 00:04:11 +0000100unsigned TemplateParameterList::getDepth() const {
101 if (size() == 0)
102 return 0;
103
104 const NamedDecl *FirstParm = getParam(0);
105 if (const TemplateTypeParmDecl *TTP
106 = dyn_cast<TemplateTypeParmDecl>(FirstParm))
107 return TTP->getDepth();
108 else if (const NonTypeTemplateParmDecl *NTTP
109 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
110 return NTTP->getDepth();
111 else
112 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
113}
114
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000115static void AdoptTemplateParameterList(TemplateParameterList *Params,
116 DeclContext *Owner) {
117 for (TemplateParameterList::iterator P = Params->begin(),
118 PEnd = Params->end();
119 P != PEnd; ++P) {
120 (*P)->setDeclContext(Owner);
121
122 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P))
123 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
124 }
125}
126
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000127//===----------------------------------------------------------------------===//
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000128// RedeclarableTemplateDecl Implementation
129//===----------------------------------------------------------------------===//
130
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000131RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000132 if (Common)
133 return Common;
134
135 // Walk the previous-declaration chain until we either find a declaration
136 // with a common pointer or we run out of previous declarations.
137 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
138 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
139 Prev = Prev->getPreviousDecl()) {
140 if (Prev->Common) {
141 Common = Prev->Common;
142 break;
Douglas Gregor68444de2012-01-14 15:13:49 +0000143 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000144
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000145 PrevDecls.push_back(Prev);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000146 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000147
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000148 // If we never found a common pointer, allocate one now.
149 if (!Common) {
150 // FIXME: If any of the declarations is from an AST file, we probably
151 // need an update record to add the common data.
152
153 Common = newCommon(getASTContext());
154 }
155
156 // Update any previous declarations we saw with the common pointer.
157 for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I)
158 PrevDecls[I]->Common = Common;
159
Douglas Gregor68444de2012-01-14 15:13:49 +0000160 return Common;
Peter Collingbourne029fd692010-07-29 16:12:09 +0000161}
162
Richard Smithe977e512015-02-24 01:23:23 +0000163template<class EntryType>
164typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000165RedeclarableTemplateDecl::findSpecializationImpl(
Richard Smithe977e512015-02-24 01:23:23 +0000166 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
167 void *&InsertPos) {
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000168 typedef SpecEntryTraits<EntryType> SETraits;
169 llvm::FoldingSetNodeID ID;
Craig Topper7e0daca2014-06-26 04:58:53 +0000170 EntryType::Profile(ID,Args, getASTContext());
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000171 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
Richard Smithe977e512015-02-24 01:23:23 +0000172 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
173}
174
175template<class Derived, class EntryType>
176void RedeclarableTemplateDecl::addSpecializationImpl(
177 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
178 void *InsertPos) {
179 typedef SpecEntryTraits<EntryType> SETraits;
180 if (InsertPos) {
181#ifndef NDEBUG
182 void *CorrectInsertPos;
183 assert(!findSpecializationImpl(Specializations,
184 SETraits::getTemplateArgs(Entry),
185 CorrectInsertPos) &&
186 InsertPos == CorrectInsertPos &&
187 "given incorrect InsertPos for specialization");
188#endif
189 Specializations.InsertNode(Entry, InsertPos);
190 } else {
191 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
192 (void)Existing;
193 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
194 "non-canonical specialization?");
195 }
196
197 if (ASTMutationListener *L = getASTMutationListener())
198 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
199 SETraits::getDecl(Entry));
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000200}
201
Douglas Gregor43669f82011-03-05 17:54:25 +0000202/// \brief Generate the injected template arguments for the given template
203/// parameter list, e.g., for the injected-class-name of a class template.
204static void GenerateInjectedTemplateArgs(ASTContext &Context,
205 TemplateParameterList *Params,
206 TemplateArgument *Args) {
207 for (TemplateParameterList::iterator Param = Params->begin(),
208 ParamEnd = Params->end();
209 Param != ParamEnd; ++Param) {
210 TemplateArgument Arg;
211 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
212 QualType ArgType = Context.getTypeDeclType(TTP);
213 if (TTP->isParameterPack())
David Blaikie7a30dc52013-02-21 01:47:18 +0000214 ArgType = Context.getPackExpansionType(ArgType, None);
David Blaikie05785d12013-02-20 22:23:23 +0000215
Douglas Gregor43669f82011-03-05 17:54:25 +0000216 Arg = TemplateArgument(ArgType);
217 } else if (NonTypeTemplateParmDecl *NTTP =
218 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
John McCall113bee02012-03-10 09:33:50 +0000219 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
Douglas Gregor43669f82011-03-05 17:54:25 +0000220 NTTP->getType().getNonLValueExprType(Context),
221 Expr::getValueKindForType(NTTP->getType()),
222 NTTP->getLocation());
223
224 if (NTTP->isParameterPack())
David Blaikie7a30dc52013-02-21 01:47:18 +0000225 E = new (Context) PackExpansionExpr(Context.DependentTy, E,
226 NTTP->getLocation(), None);
Douglas Gregor43669f82011-03-05 17:54:25 +0000227 Arg = TemplateArgument(E);
228 } else {
229 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
230 if (TTP->isParameterPack())
David Blaikie05785d12013-02-20 22:23:23 +0000231 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
Douglas Gregor43669f82011-03-05 17:54:25 +0000232 else
233 Arg = TemplateArgument(TemplateName(TTP));
234 }
235
236 if ((*Param)->isTemplateParameterPack())
237 Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
238
239 *Args++ = Arg;
240 }
241}
242
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000243//===----------------------------------------------------------------------===//
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000244// FunctionTemplateDecl Implementation
245//===----------------------------------------------------------------------===//
246
Douglas Gregor1a809332010-05-23 18:26:36 +0000247void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
248 static_cast<Common *>(Ptr)->~Common();
249}
250
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000251FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
252 DeclContext *DC,
253 SourceLocation L,
254 DeclarationName Name,
Douglas Gregor8f5d4422009-06-29 20:59:39 +0000255 TemplateParameterList *Params,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000256 NamedDecl *Decl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000257 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Richard Smith053f6c62014-05-16 23:01:30 +0000258 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000259}
260
Douglas Gregor72172e92012-01-05 21:55:30 +0000261FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
262 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000263 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000264 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000265}
266
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000267RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000268FunctionTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000269 Common *CommonPtr = new (C) Common;
270 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000271 return CommonPtr;
272}
273
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000274void FunctionTemplateDecl::LoadLazySpecializations() const {
275 Common *CommonPtr = getCommonPtr();
276 if (CommonPtr->LazySpecializations) {
277 ASTContext &Context = getASTContext();
278 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000279 CommonPtr->LazySpecializations = nullptr;
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000280 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
281 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
282 }
283}
284
285llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
286FunctionTemplateDecl::getSpecializations() const {
287 LoadLazySpecializations();
288 return getCommonPtr()->Specializations;
289}
290
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000291FunctionDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000292FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
293 void *&InsertPos) {
294 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000295}
296
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000297void FunctionTemplateDecl::addSpecialization(
298 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000299 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
300 InsertPos);
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000301}
302
Richard Smith841d8b22013-05-17 03:04:50 +0000303ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
Douglas Gregor43669f82011-03-05 17:54:25 +0000304 TemplateParameterList *Params = getTemplateParameters();
305 Common *CommonPtr = getCommonPtr();
306 if (!CommonPtr->InjectedArgs) {
307 CommonPtr->InjectedArgs
Richard Smith841d8b22013-05-17 03:04:50 +0000308 = new (getASTContext()) TemplateArgument[Params->size()];
309 GenerateInjectedTemplateArgs(getASTContext(), Params,
Douglas Gregor43669f82011-03-05 17:54:25 +0000310 CommonPtr->InjectedArgs);
311 }
Richard Smith841d8b22013-05-17 03:04:50 +0000312
313 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
Douglas Gregor43669f82011-03-05 17:54:25 +0000314}
315
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000316//===----------------------------------------------------------------------===//
317// ClassTemplateDecl Implementation
318//===----------------------------------------------------------------------===//
319
Douglas Gregor1a809332010-05-23 18:26:36 +0000320void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
321 static_cast<Common *>(Ptr)->~Common();
322}
323
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000324ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
325 DeclContext *DC,
326 SourceLocation L,
327 DeclarationName Name,
328 TemplateParameterList *Params,
Douglas Gregor90a1a652009-03-19 17:26:29 +0000329 NamedDecl *Decl,
330 ClassTemplateDecl *PrevDecl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000331 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Richard Smith053f6c62014-05-16 23:01:30 +0000332 ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
333 Params, Decl);
Rafael Espindola8db352d2013-10-17 15:37:26 +0000334 New->setPreviousDecl(PrevDecl);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +0000335 return New;
Douglas Gregor90a1a652009-03-19 17:26:29 +0000336}
337
Richard Smith053f6c62014-05-16 23:01:30 +0000338ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000339 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000340 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
341 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000342}
343
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000344void ClassTemplateDecl::LoadLazySpecializations() const {
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000345 Common *CommonPtr = getCommonPtr();
346 if (CommonPtr->LazySpecializations) {
347 ASTContext &Context = getASTContext();
348 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000349 CommonPtr->LazySpecializations = nullptr;
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000350 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
351 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
352 }
353}
354
Chandler Carruthb41171b2012-05-03 23:49:05 +0000355llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000356ClassTemplateDecl::getSpecializations() const {
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000357 LoadLazySpecializations();
358 return getCommonPtr()->Specializations;
359}
360
Chandler Carruthb41171b2012-05-03 23:49:05 +0000361llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000362ClassTemplateDecl::getPartialSpecializations() {
363 LoadLazySpecializations();
364 return getCommonPtr()->PartialSpecializations;
365}
366
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000367RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000368ClassTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000369 Common *CommonPtr = new (C) Common;
370 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000371 return CommonPtr;
372}
373
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000374ClassTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000375ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
376 void *&InsertPos) {
377 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000378}
379
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000380void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
381 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000382 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000383}
384
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000385ClassTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000386ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000387 void *&InsertPos) {
Craig Topper7e0daca2014-06-26 04:58:53 +0000388 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000389}
390
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000391void ClassTemplateDecl::AddPartialSpecialization(
392 ClassTemplatePartialSpecializationDecl *D,
393 void *InsertPos) {
Douglas Gregorce9978f2012-03-28 14:34:23 +0000394 if (InsertPos)
395 getPartialSpecializations().InsertNode(D, InsertPos);
396 else {
397 ClassTemplatePartialSpecializationDecl *Existing
398 = getPartialSpecializations().GetOrInsertNode(D);
399 (void)Existing;
400 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
401 }
402
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000403 if (ASTMutationListener *L = getASTMutationListener())
404 L->AddedCXXTemplateSpecialization(this, D);
405}
406
Douglas Gregor407e9612010-04-30 05:56:50 +0000407void ClassTemplateDecl::getPartialSpecializations(
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000408 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
Chandler Carruthb41171b2012-05-03 23:49:05 +0000409 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000410 = getPartialSpecializations();
Douglas Gregor407e9612010-04-30 05:56:50 +0000411 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +0000412 PS.reserve(PartialSpecs.size());
Chandler Carruthb41171b2012-05-03 23:49:05 +0000413 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregor407e9612010-04-30 05:56:50 +0000414 P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
Richard Smithb2f61b42013-08-22 23:27:37 +0000415 P != PEnd; ++P)
416 PS.push_back(P->getMostRecentDecl());
Douglas Gregor407e9612010-04-30 05:56:50 +0000417}
418
Douglas Gregor15301382009-07-30 17:40:51 +0000419ClassTemplatePartialSpecializationDecl *
420ClassTemplateDecl::findPartialSpecialization(QualType T) {
421 ASTContext &Context = getASTContext();
Chandler Carruthb41171b2012-05-03 23:49:05 +0000422 using llvm::FoldingSetVector;
423 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregor15301382009-07-30 17:40:51 +0000424 partial_spec_iterator;
425 for (partial_spec_iterator P = getPartialSpecializations().begin(),
426 PEnd = getPartialSpecializations().end();
427 P != PEnd; ++P) {
John McCall2408e322010-04-27 00:57:59 +0000428 if (Context.hasSameType(P->getInjectedSpecializationType(), T))
Douglas Gregorec9fd132012-01-14 16:38:05 +0000429 return P->getMostRecentDecl();
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000430 }
431
Craig Topper36250ad2014-05-12 05:36:57 +0000432 return nullptr;
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000433}
434
435ClassTemplatePartialSpecializationDecl *
436ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
437 ClassTemplatePartialSpecializationDecl *D) {
438 Decl *DCanon = D->getCanonicalDecl();
Chandler Carruthb41171b2012-05-03 23:49:05 +0000439 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000440 P = getPartialSpecializations().begin(),
441 PEnd = getPartialSpecializations().end();
442 P != PEnd; ++P) {
443 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
Douglas Gregorec9fd132012-01-14 16:38:05 +0000444 return P->getMostRecentDecl();
Douglas Gregor15301382009-07-30 17:40:51 +0000445 }
Mike Stump11289f42009-09-09 15:08:12 +0000446
Craig Topper36250ad2014-05-12 05:36:57 +0000447 return nullptr;
Douglas Gregor15301382009-07-30 17:40:51 +0000448}
449
John McCalle78aac42010-03-10 03:28:59 +0000450QualType
Douglas Gregor9961ce92010-07-08 18:37:38 +0000451ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000452 Common *CommonPtr = getCommonPtr();
Douglas Gregore362cea2009-05-10 22:57:19 +0000453 if (!CommonPtr->InjectedClassNameType.isNull())
454 return CommonPtr->InjectedClassNameType;
455
Douglas Gregor8092e802010-12-23 16:00:30 +0000456 // C++0x [temp.dep.type]p2:
457 // The template argument list of a primary template is a template argument
458 // list in which the nth template argument has the value of the nth template
459 // parameter of the class template. If the nth template parameter is a
460 // template parameter pack (14.5.3), the nth template argument is a pack
461 // expansion (14.5.3) whose pattern is the name of the template parameter
462 // pack.
Douglas Gregor9961ce92010-07-08 18:37:38 +0000463 ASTContext &Context = getASTContext();
Douglas Gregore362cea2009-05-10 22:57:19 +0000464 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000465 SmallVector<TemplateArgument, 16> TemplateArgs;
Douglas Gregor43669f82011-03-05 17:54:25 +0000466 TemplateArgs.resize(Params->size());
467 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
Douglas Gregore362cea2009-05-10 22:57:19 +0000468 CommonPtr->InjectedClassNameType
Douglas Gregora8e02e72009-07-28 23:00:59 +0000469 = Context.getTemplateSpecializationType(TemplateName(this),
Douglas Gregore362cea2009-05-10 22:57:19 +0000470 &TemplateArgs[0],
Douglas Gregora8e02e72009-07-28 23:00:59 +0000471 TemplateArgs.size());
Douglas Gregore362cea2009-05-10 22:57:19 +0000472 return CommonPtr->InjectedClassNameType;
473}
474
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000475//===----------------------------------------------------------------------===//
476// TemplateTypeParm Allocation/Deallocation Method Implementations
477//===----------------------------------------------------------------------===//
478
479TemplateTypeParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000480TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000481 SourceLocation KeyLoc, SourceLocation NameLoc,
482 unsigned D, unsigned P, IdentifierInfo *Id,
483 bool Typename, bool ParameterPack) {
Chandler Carruth08836322011-05-01 00:51:33 +0000484 TemplateTypeParmDecl *TTPDecl =
Richard Smithf7981722013-11-22 09:01:48 +0000485 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
Chandler Carruth08836322011-05-01 00:51:33 +0000486 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
Richard Smith5b21db82014-04-23 18:20:42 +0000487 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
Chandler Carruth08836322011-05-01 00:51:33 +0000488 return TTPDecl;
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000489}
490
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000491TemplateTypeParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000492TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000493 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
494 SourceLocation(), nullptr, false);
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000495}
496
John McCall0ad16662009-10-29 08:12:44 +0000497SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara23485e02011-03-04 12:42:03 +0000498 return hasDefaultArgument()
499 ? DefaultArgument->getTypeLoc().getBeginLoc()
500 : SourceLocation();
501}
502
503SourceRange TemplateTypeParmDecl::getSourceRange() const {
504 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000505 return SourceRange(getLocStart(),
Abramo Bagnara23485e02011-03-04 12:42:03 +0000506 DefaultArgument->getTypeLoc().getEndLoc());
507 else
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000508 return TypeDecl::getSourceRange();
John McCall0ad16662009-10-29 08:12:44 +0000509}
510
Douglas Gregor21610382009-10-29 00:04:11 +0000511unsigned TemplateTypeParmDecl::getDepth() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000512 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
Douglas Gregor21610382009-10-29 00:04:11 +0000513}
514
515unsigned TemplateTypeParmDecl::getIndex() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000516 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
Douglas Gregor21610382009-10-29 00:04:11 +0000517}
518
Chandler Carruth08836322011-05-01 00:51:33 +0000519bool TemplateTypeParmDecl::isParameterPack() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000520 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
Chandler Carruth08836322011-05-01 00:51:33 +0000521}
522
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000523//===----------------------------------------------------------------------===//
524// NonTypeTemplateParmDecl Method Implementations
525//===----------------------------------------------------------------------===//
526
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000527NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000528 SourceLocation StartLoc,
529 SourceLocation IdLoc,
530 unsigned D, unsigned P,
531 IdentifierInfo *Id,
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000532 QualType T,
533 TypeSourceInfo *TInfo,
534 const QualType *ExpandedTypes,
535 unsigned NumExpandedTypes,
536 TypeSourceInfo **ExpandedTInfos)
Abramo Bagnaradff19302011-03-08 08:55:46 +0000537 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
Craig Topper36250ad2014-05-12 05:36:57 +0000538 TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false),
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000539 ParameterPack(true), ExpandedParameterPack(true),
540 NumExpandedTypes(NumExpandedTypes)
541{
542 if (ExpandedTypes && ExpandedTInfos) {
543 void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
544 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
545 TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
546 TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
547 }
548 }
549}
550
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000551NonTypeTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000552NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000553 SourceLocation StartLoc, SourceLocation IdLoc,
554 unsigned D, unsigned P, IdentifierInfo *Id,
555 QualType T, bool ParameterPack,
556 TypeSourceInfo *TInfo) {
Richard Smithf7981722013-11-22 09:01:48 +0000557 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
558 T, ParameterPack, TInfo);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000559}
560
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000561NonTypeTemplateParmDecl *
562NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000563 SourceLocation StartLoc, SourceLocation IdLoc,
564 unsigned D, unsigned P,
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000565 IdentifierInfo *Id, QualType T,
566 TypeSourceInfo *TInfo,
567 const QualType *ExpandedTypes,
568 unsigned NumExpandedTypes,
569 TypeSourceInfo **ExpandedTInfos) {
Richard Smithf7981722013-11-22 09:01:48 +0000570 unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
571 return new (C, DC, Extra) NonTypeTemplateParmDecl(
572 DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
573 ExpandedTypes, NumExpandedTypes, ExpandedTInfos);
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000574}
575
Douglas Gregor72172e92012-01-05 21:55:30 +0000576NonTypeTemplateParmDecl *
577NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000578 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
579 SourceLocation(), 0, 0, nullptr,
580 QualType(), false, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000581}
582
583NonTypeTemplateParmDecl *
584NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
585 unsigned NumExpandedTypes) {
Richard Smithf7981722013-11-22 09:01:48 +0000586 unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
587 return new (C, ID, Extra) NonTypeTemplateParmDecl(
Craig Topper36250ad2014-05-12 05:36:57 +0000588 nullptr, SourceLocation(), SourceLocation(), 0, 0, nullptr, QualType(),
589 nullptr, nullptr, NumExpandedTypes, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000590}
591
John McCallf4cd4f92011-02-09 01:13:10 +0000592SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnarae15d5532011-03-04 11:03:48 +0000593 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraea947882011-03-08 16:41:52 +0000594 return SourceRange(getOuterLocStart(),
595 getDefaultArgument()->getSourceRange().getEnd());
596 return DeclaratorDecl::getSourceRange();
John McCallf4cd4f92011-02-09 01:13:10 +0000597}
598
Douglas Gregordba32632009-02-10 19:49:53 +0000599SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara656e3002010-06-09 09:26:05 +0000600 return hasDefaultArgument()
601 ? getDefaultArgument()->getSourceRange().getBegin()
602 : SourceLocation();
Douglas Gregordba32632009-02-10 19:49:53 +0000603}
604
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000605//===----------------------------------------------------------------------===//
606// TemplateTemplateParmDecl Method Implementations
607//===----------------------------------------------------------------------===//
608
David Blaikie68e081d2011-12-20 02:48:34 +0000609void TemplateTemplateParmDecl::anchor() { }
610
Richard Smith1fde8ec2012-09-07 02:06:42 +0000611TemplateTemplateParmDecl::TemplateTemplateParmDecl(
612 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
613 IdentifierInfo *Id, TemplateParameterList *Params,
614 unsigned NumExpansions, TemplateParameterList * const *Expansions)
615 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
616 TemplateParmPosition(D, P), DefaultArgument(),
617 DefaultArgumentWasInherited(false), ParameterPack(true),
618 ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
619 if (Expansions)
620 std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
621 sizeof(TemplateParameterList*) * NumExpandedParams);
622}
623
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000624TemplateTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000625TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000626 SourceLocation L, unsigned D, unsigned P,
Douglas Gregorf5500772011-01-05 15:48:55 +0000627 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000628 TemplateParameterList *Params) {
Richard Smithf7981722013-11-22 09:01:48 +0000629 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
630 Params);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000631}
632
Douglas Gregor72172e92012-01-05 21:55:30 +0000633TemplateTemplateParmDecl *
Richard Smith1fde8ec2012-09-07 02:06:42 +0000634TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
635 SourceLocation L, unsigned D, unsigned P,
636 IdentifierInfo *Id,
637 TemplateParameterList *Params,
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000638 ArrayRef<TemplateParameterList *> Expansions) {
Richard Smithf7981722013-11-22 09:01:48 +0000639 return new (C, DC, sizeof(TemplateParameterList*) * Expansions.size())
640 TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
641 Expansions.size(), Expansions.data());
Richard Smith1fde8ec2012-09-07 02:06:42 +0000642}
643
644TemplateTemplateParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000645TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000646 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
647 false, nullptr, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000648}
649
Richard Smith1fde8ec2012-09-07 02:06:42 +0000650TemplateTemplateParmDecl *
651TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
652 unsigned NumExpansions) {
Richard Smithf7981722013-11-22 09:01:48 +0000653 return new (C, ID, sizeof(TemplateParameterList*) * NumExpansions)
Craig Topper36250ad2014-05-12 05:36:57 +0000654 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
655 nullptr, NumExpansions, nullptr);
Richard Smith1fde8ec2012-09-07 02:06:42 +0000656}
657
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000658//===----------------------------------------------------------------------===//
Douglas Gregord002c7b2009-05-11 23:53:27 +0000659// TemplateArgumentList Implementation
660//===----------------------------------------------------------------------===//
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000661TemplateArgumentList *
662TemplateArgumentList::CreateCopy(ASTContext &Context,
663 const TemplateArgument *Args,
664 unsigned NumArgs) {
665 std::size_t Size = sizeof(TemplateArgumentList)
666 + NumArgs * sizeof(TemplateArgument);
667 void *Mem = Context.Allocate(Size);
668 TemplateArgument *StoredArgs
669 = reinterpret_cast<TemplateArgument *>(
670 static_cast<TemplateArgumentList *>(Mem) + 1);
671 std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
672 return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000673}
674
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000675FunctionTemplateSpecializationInfo *
676FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
677 FunctionTemplateDecl *Template,
678 TemplateSpecializationKind TSK,
679 const TemplateArgumentList *TemplateArgs,
680 const TemplateArgumentListInfo *TemplateArgsAsWritten,
681 SourceLocation POI) {
Craig Topper36250ad2014-05-12 05:36:57 +0000682 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000683 if (TemplateArgsAsWritten)
684 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
685 *TemplateArgsAsWritten);
686
687 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
688 TemplateArgs,
689 ArgsAsWritten,
690 POI);
691}
692
Douglas Gregord002c7b2009-05-11 23:53:27 +0000693//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000694// TemplateDecl Implementation
695//===----------------------------------------------------------------------===//
696
697void TemplateDecl::anchor() { }
698
699//===----------------------------------------------------------------------===//
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000700// ClassTemplateSpecializationDecl Implementation
701//===----------------------------------------------------------------------===//
702ClassTemplateSpecializationDecl::
Douglas Gregore9029562010-05-06 00:28:52 +0000703ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000704 DeclContext *DC, SourceLocation StartLoc,
705 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000706 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000707 const TemplateArgument *Args,
708 unsigned NumArgs,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000709 ClassTemplateSpecializationDecl *PrevDecl)
Richard Smith053f6c62014-05-16 23:01:30 +0000710 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000711 SpecializedTemplate->getIdentifier(),
712 PrevDecl),
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000713 SpecializedTemplate(SpecializedTemplate),
Craig Topper36250ad2014-05-12 05:36:57 +0000714 ExplicitInfo(nullptr),
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000715 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
Douglas Gregord002c7b2009-05-11 23:53:27 +0000716 SpecializationKind(TSK_Undeclared) {
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000717}
Mike Stump11289f42009-09-09 15:08:12 +0000718
Richard Smith053f6c62014-05-16 23:01:30 +0000719ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
720 Kind DK)
721 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
722 SourceLocation(), nullptr, nullptr),
723 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000724
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000725ClassTemplateSpecializationDecl *
Douglas Gregore9029562010-05-06 00:28:52 +0000726ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000727 DeclContext *DC,
728 SourceLocation StartLoc,
729 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000730 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000731 const TemplateArgument *Args,
732 unsigned NumArgs,
Douglas Gregor67a65642009-02-17 23:15:12 +0000733 ClassTemplateSpecializationDecl *PrevDecl) {
Richard Smithf7981722013-11-22 09:01:48 +0000734 ClassTemplateSpecializationDecl *Result =
735 new (Context, DC) ClassTemplateSpecializationDecl(
736 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
737 SpecializedTemplate, Args, NumArgs, PrevDecl);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000738 Result->MayHaveOutOfDateDef = false;
739
Douglas Gregor67a65642009-02-17 23:15:12 +0000740 Context.getTypeDeclType(Result, PrevDecl);
741 return Result;
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000742}
Douglas Gregor2373c592009-05-31 09:31:02 +0000743
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000744ClassTemplateSpecializationDecl *
Richard Smithf7981722013-11-22 09:01:48 +0000745ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000746 unsigned ID) {
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000747 ClassTemplateSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000748 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000749 Result->MayHaveOutOfDateDef = false;
750 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000751}
752
Benjamin Kramer9170e912013-02-22 15:46:01 +0000753void ClassTemplateSpecializationDecl::getNameForDiagnostic(
754 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
755 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000756
757 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Benjamin Kramer9170e912013-02-22 15:46:01 +0000758 TemplateSpecializationType::PrintTemplateArgumentList(
759 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000760}
761
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000762ClassTemplateDecl *
Mike Stump11289f42009-09-09 15:08:12 +0000763ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
764 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000765 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
766 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
767 return SpecializedTemplate.get<ClassTemplateDecl*>();
768}
769
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000770SourceRange
771ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000772 if (ExplicitInfo) {
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000773 SourceLocation Begin = getTemplateKeywordLoc();
774 if (Begin.isValid()) {
775 // Here we have an explicit (partial) specialization or instantiation.
776 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
777 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
778 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
779 if (getExternLoc().isValid())
780 Begin = getExternLoc();
781 SourceLocation End = getRBraceLoc();
782 if (End.isInvalid())
783 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
784 return SourceRange(Begin, End);
785 }
786 // An implicit instantiation of a class template partial specialization
787 // uses ExplicitInfo to record the TypeAsWritten, but the source
788 // locations should be retrieved from the instantiation pattern.
789 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
790 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
791 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
Craig Topper36250ad2014-05-12 05:36:57 +0000792 assert(inst_from != nullptr);
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000793 return inst_from->getSourceRange();
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000794 }
795 else {
796 // No explicit info available.
797 llvm::PointerUnion<ClassTemplateDecl *,
798 ClassTemplatePartialSpecializationDecl *>
799 inst_from = getInstantiatedFrom();
800 if (inst_from.isNull())
801 return getSpecializedTemplate()->getSourceRange();
802 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
803 return ctd->getSourceRange();
804 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
805 ->getSourceRange();
806 }
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000807}
808
Douglas Gregor2373c592009-05-31 09:31:02 +0000809//===----------------------------------------------------------------------===//
810// ClassTemplatePartialSpecializationDecl Implementation
811//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000812void ClassTemplatePartialSpecializationDecl::anchor() { }
813
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000814ClassTemplatePartialSpecializationDecl::
815ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000816 DeclContext *DC,
817 SourceLocation StartLoc,
818 SourceLocation IdLoc,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000819 TemplateParameterList *Params,
820 ClassTemplateDecl *SpecializedTemplate,
821 const TemplateArgument *Args,
822 unsigned NumArgs,
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000823 const ASTTemplateArgumentListInfo *ArgInfos,
Richard Smithb2f61b42013-08-22 23:27:37 +0000824 ClassTemplatePartialSpecializationDecl *PrevDecl)
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000825 : ClassTemplateSpecializationDecl(Context,
826 ClassTemplatePartialSpecialization,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000827 TK, DC, StartLoc, IdLoc,
828 SpecializedTemplate,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000829 Args, NumArgs, PrevDecl),
830 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +0000831 InstantiatedFromMember(nullptr, false)
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000832{
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000833 AdoptTemplateParameterList(Params, this);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000834}
835
Douglas Gregor2373c592009-05-31 09:31:02 +0000836ClassTemplatePartialSpecializationDecl *
837ClassTemplatePartialSpecializationDecl::
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000838Create(ASTContext &Context, TagKind TK,DeclContext *DC,
839 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregor2373c592009-05-31 09:31:02 +0000840 TemplateParameterList *Params,
841 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000842 const TemplateArgument *Args,
843 unsigned NumArgs,
John McCall6b51f282009-11-23 01:53:49 +0000844 const TemplateArgumentListInfo &ArgInfos,
John McCalle78aac42010-03-10 03:28:59 +0000845 QualType CanonInjectedType,
Richard Smithb2f61b42013-08-22 23:27:37 +0000846 ClassTemplatePartialSpecializationDecl *PrevDecl) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000847 const ASTTemplateArgumentListInfo *ASTArgInfos =
848 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
John McCall0ad16662009-10-29 08:12:44 +0000849
Richard Smithf7981722013-11-22 09:01:48 +0000850 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
851 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
852 Params, SpecializedTemplate, Args,
853 NumArgs, ASTArgInfos, PrevDecl);
Douglas Gregor2373c592009-05-31 09:31:02 +0000854 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000855 Result->MayHaveOutOfDateDef = false;
John McCalle78aac42010-03-10 03:28:59 +0000856
857 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregor2373c592009-05-31 09:31:02 +0000858 return Result;
859}
John McCall11083da2009-09-16 22:47:08 +0000860
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000861ClassTemplatePartialSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000862ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
863 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000864 ClassTemplatePartialSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000865 new (C, ID) ClassTemplatePartialSpecializationDecl(C);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000866 Result->MayHaveOutOfDateDef = false;
867 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000868}
869
John McCall11083da2009-09-16 22:47:08 +0000870//===----------------------------------------------------------------------===//
871// FriendTemplateDecl Implementation
872//===----------------------------------------------------------------------===//
873
David Blaikie68e081d2011-12-20 02:48:34 +0000874void FriendTemplateDecl::anchor() { }
875
John McCall11083da2009-09-16 22:47:08 +0000876FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
877 DeclContext *DC,
878 SourceLocation L,
879 unsigned NParams,
880 TemplateParameterList **Params,
881 FriendUnion Friend,
882 SourceLocation FLoc) {
Richard Smithf7981722013-11-22 09:01:48 +0000883 return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params,
884 Friend, FLoc);
John McCall11083da2009-09-16 22:47:08 +0000885}
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000886
Douglas Gregor72172e92012-01-05 21:55:30 +0000887FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
888 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000889 return new (C, ID) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000890}
Richard Smith3f1b5d02011-05-05 21:57:07 +0000891
892//===----------------------------------------------------------------------===//
893// TypeAliasTemplateDecl Implementation
894//===----------------------------------------------------------------------===//
895
896TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
897 DeclContext *DC,
898 SourceLocation L,
899 DeclarationName Name,
900 TemplateParameterList *Params,
901 NamedDecl *Decl) {
902 AdoptTemplateParameterList(Params, DC);
Richard Smith053f6c62014-05-16 23:01:30 +0000903 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000904}
905
Douglas Gregor72172e92012-01-05 21:55:30 +0000906TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
907 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000908 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000909 DeclarationName(), nullptr, nullptr);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000910}
911
912void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
913 static_cast<Common *>(Ptr)->~Common();
914}
915RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000916TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3f1b5d02011-05-05 21:57:07 +0000917 Common *CommonPtr = new (C) Common;
918 C.AddDeallocation(DeallocateCommon, CommonPtr);
919 return CommonPtr;
920}
921
David Blaikie68e081d2011-12-20 02:48:34 +0000922//===----------------------------------------------------------------------===//
923// ClassScopeFunctionSpecializationDecl Implementation
924//===----------------------------------------------------------------------===//
925
926void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor72172e92012-01-05 21:55:30 +0000927
928ClassScopeFunctionSpecializationDecl *
929ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
930 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000931 return new (C, ID) ClassScopeFunctionSpecializationDecl(
Craig Topper36250ad2014-05-12 05:36:57 +0000932 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
Douglas Gregor72172e92012-01-05 21:55:30 +0000933}
Larisse Voufo39a1e502013-08-06 01:03:05 +0000934
935//===----------------------------------------------------------------------===//
936// VarTemplateDecl Implementation
937//===----------------------------------------------------------------------===//
938
939void VarTemplateDecl::DeallocateCommon(void *Ptr) {
940 static_cast<Common *>(Ptr)->~Common();
941}
942
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000943VarTemplateDecl *VarTemplateDecl::getDefinition() {
944 VarTemplateDecl *CurD = this;
945 while (CurD) {
946 if (CurD->isThisDeclarationADefinition())
947 return CurD;
948 CurD = CurD->getPreviousDecl();
949 }
Craig Topper36250ad2014-05-12 05:36:57 +0000950 return nullptr;
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000951}
952
Larisse Voufo39a1e502013-08-06 01:03:05 +0000953VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
954 SourceLocation L, DeclarationName Name,
955 TemplateParameterList *Params,
Richard Smithbeef3452014-01-16 23:39:20 +0000956 VarDecl *Decl) {
Richard Smith053f6c62014-05-16 23:01:30 +0000957 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000958}
959
960VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
961 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000962 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
963 DeclarationName(), nullptr, nullptr);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000964}
965
Alp Tokerf6a24ce2013-12-05 16:25:25 +0000966// TODO: Unify across class, function and variable templates?
Larisse Voufo30616382013-08-23 22:21:36 +0000967// May require moving this and Common to RedeclarableTemplateDecl.
Larisse Voufo39a1e502013-08-06 01:03:05 +0000968void VarTemplateDecl::LoadLazySpecializations() const {
969 Common *CommonPtr = getCommonPtr();
970 if (CommonPtr->LazySpecializations) {
971 ASTContext &Context = getASTContext();
972 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000973 CommonPtr->LazySpecializations = nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +0000974 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
975 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
976 }
977}
978
979llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
980VarTemplateDecl::getSpecializations() const {
981 LoadLazySpecializations();
982 return getCommonPtr()->Specializations;
983}
984
985llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
986VarTemplateDecl::getPartialSpecializations() {
987 LoadLazySpecializations();
988 return getCommonPtr()->PartialSpecializations;
989}
990
991RedeclarableTemplateDecl::CommonBase *
992VarTemplateDecl::newCommon(ASTContext &C) const {
993 Common *CommonPtr = new (C) Common;
994 C.AddDeallocation(DeallocateCommon, CommonPtr);
995 return CommonPtr;
996}
997
998VarTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000999VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1000 void *&InsertPos) {
1001 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001002}
1003
1004void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1005 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +00001006 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001007}
1008
1009VarTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +00001010VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1011 void *&InsertPos) {
1012 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001013}
1014
1015void VarTemplateDecl::AddPartialSpecialization(
1016 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1017 if (InsertPos)
1018 getPartialSpecializations().InsertNode(D, InsertPos);
1019 else {
1020 VarTemplatePartialSpecializationDecl *Existing =
1021 getPartialSpecializations().GetOrInsertNode(D);
1022 (void)Existing;
1023 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1024 }
1025
1026 if (ASTMutationListener *L = getASTMutationListener())
1027 L->AddedCXXTemplateSpecialization(this, D);
1028}
1029
1030void VarTemplateDecl::getPartialSpecializations(
1031 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1032 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1033 getPartialSpecializations();
1034 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +00001035 PS.reserve(PartialSpecs.size());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001036 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1037 P = PartialSpecs.begin(),
1038 PEnd = PartialSpecs.end();
Richard Smithb2f61b42013-08-22 23:27:37 +00001039 P != PEnd; ++P)
1040 PS.push_back(P->getMostRecentDecl());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001041}
1042
1043VarTemplatePartialSpecializationDecl *
1044VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1045 VarTemplatePartialSpecializationDecl *D) {
1046 Decl *DCanon = D->getCanonicalDecl();
1047 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1048 P = getPartialSpecializations().begin(),
1049 PEnd = getPartialSpecializations().end();
1050 P != PEnd; ++P) {
1051 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1052 return P->getMostRecentDecl();
1053 }
1054
Craig Topper36250ad2014-05-12 05:36:57 +00001055 return nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +00001056}
1057
1058//===----------------------------------------------------------------------===//
1059// VarTemplateSpecializationDecl Implementation
1060//===----------------------------------------------------------------------===//
1061VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001062 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001063 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1064 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1065 unsigned NumArgs)
Richard Smith053f6c62014-05-16 23:01:30 +00001066 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1067 SpecializedTemplate->getIdentifier(), T, TInfo, S),
Craig Topper36250ad2014-05-12 05:36:57 +00001068 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001069 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
1070 SpecializationKind(TSK_Undeclared) {}
1071
Richard Smith053f6c62014-05-16 23:01:30 +00001072VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1073 ASTContext &C)
1074 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
Craig Topper36250ad2014-05-12 05:36:57 +00001075 QualType(), nullptr, SC_None),
1076 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Larisse Voufo39a1e502013-08-06 01:03:05 +00001077
1078VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1079 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1080 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1081 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1082 unsigned NumArgs) {
Richard Smithf7981722013-11-22 09:01:48 +00001083 return new (Context, DC) VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001084 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
Richard Smithf7981722013-11-22 09:01:48 +00001085 SpecializedTemplate, T, TInfo, S, Args, NumArgs);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001086}
1087
1088VarTemplateSpecializationDecl *
1089VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001090 return new (C, ID)
1091 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001092}
1093
1094void VarTemplateSpecializationDecl::getNameForDiagnostic(
1095 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1096 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1097
1098 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1099 TemplateSpecializationType::PrintTemplateArgumentList(
1100 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
1101}
1102
1103VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1104 if (SpecializedPartialSpecialization *PartialSpec =
1105 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1106 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1107 return SpecializedTemplate.get<VarTemplateDecl *>();
1108}
1109
1110void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1111 const TemplateArgumentListInfo &ArgsInfo) {
1112 unsigned N = ArgsInfo.size();
1113 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1114 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1115 for (unsigned I = 0; I != N; ++I)
1116 TemplateArgsInfo.addArgument(ArgsInfo[I]);
1117}
1118
1119//===----------------------------------------------------------------------===//
1120// VarTemplatePartialSpecializationDecl Implementation
1121//===----------------------------------------------------------------------===//
1122void VarTemplatePartialSpecializationDecl::anchor() {}
1123
1124VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1125 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1126 SourceLocation IdLoc, TemplateParameterList *Params,
1127 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1128 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
Richard Smithb2f61b42013-08-22 23:27:37 +00001129 const ASTTemplateArgumentListInfo *ArgInfos)
Richard Smith053f6c62014-05-16 23:01:30 +00001130 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001131 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1132 TInfo, S, Args, NumArgs),
1133 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +00001134 InstantiatedFromMember(nullptr, false) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001135 // TODO: The template parameters should be in DC by now. Verify.
1136 // AdoptTemplateParameterList(Params, DC);
1137}
1138
1139VarTemplatePartialSpecializationDecl *
1140VarTemplatePartialSpecializationDecl::Create(
1141 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1142 SourceLocation IdLoc, TemplateParameterList *Params,
1143 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1144 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
Richard Smithb2f61b42013-08-22 23:27:37 +00001145 const TemplateArgumentListInfo &ArgInfos) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +00001146 const ASTTemplateArgumentListInfo *ASTArgInfos
1147 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001148
1149 VarTemplatePartialSpecializationDecl *Result =
Richard Smithf7981722013-11-22 09:01:48 +00001150 new (Context, DC) VarTemplatePartialSpecializationDecl(
Larisse Voufo39a1e502013-08-06 01:03:05 +00001151 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
Richard Smithb2f61b42013-08-22 23:27:37 +00001152 S, Args, NumArgs, ASTArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001153 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1154 return Result;
1155}
1156
1157VarTemplatePartialSpecializationDecl *
1158VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1159 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001160 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001161}