blob: 0d1d2a4613dc848198d67677f59269da4abc5504 [file] [log] [blame]
Sebastian Redl06a59bb2009-10-23 22:13:42 +00001//===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
Douglas Gregoraaba5e32009-02-04 19:02:06 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the C++ related Decl classes for templates.
11//
12//===----------------------------------------------------------------------===//
13
Douglas Gregoraaba5e32009-02-04 19:02:06 +000014#include "clang/AST/DeclTemplate.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000015#include "clang/AST/ASTContext.h"
16#include "clang/AST/ASTMutationListener.h"
17#include "clang/AST/DeclCXX.h"
Douglas Gregor55f6b142009-02-09 18:46:07 +000018#include "clang/AST/Expr.h"
Douglas Gregorb95cc972011-01-04 02:33:52 +000019#include "clang/AST/ExprCXX.h"
John McCall833ca992009-10-29 08:12:44 +000020#include "clang/AST/TypeLoc.h"
Douglas Gregoraaba5e32009-02-04 19:02:06 +000021#include "clang/Basic/IdentifierTable.h"
22#include "llvm/ADT/STLExtras.h"
Douglas Gregor910f8002010-11-07 23:05:16 +000023#include <memory>
Douglas Gregoraaba5e32009-02-04 19:02:06 +000024using namespace clang;
25
26//===----------------------------------------------------------------------===//
27// TemplateParameterList Implementation
28//===----------------------------------------------------------------------===//
29
Douglas Gregorddc29e12009-02-06 22:42:48 +000030TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
31 SourceLocation LAngleLoc,
Douglas Gregorbf4ea562009-09-15 16:23:51 +000032 NamedDecl **Params, unsigned NumParams,
Douglas Gregorddc29e12009-02-06 22:42:48 +000033 SourceLocation RAngleLoc)
34 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
Richard Smith6964b3f2012-09-07 02:06:42 +000035 NumParams(NumParams), ContainsUnexpandedParameterPack(false) {
36 assert(this->NumParams == NumParams && "Too many template parameters");
37 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
38 NamedDecl *P = Params[Idx];
39 begin()[Idx] = P;
40
41 if (!P->isTemplateParameterPack()) {
42 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
43 if (NTTP->getType()->containsUnexpandedParameterPack())
44 ContainsUnexpandedParameterPack = true;
45
46 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
47 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
48 ContainsUnexpandedParameterPack = true;
49
50 // FIXME: If a default argument contains an unexpanded parameter pack, the
51 // template parameter list does too.
52 }
53 }
Douglas Gregoraaba5e32009-02-04 19:02:06 +000054}
55
56TemplateParameterList *
Jay Foad4ba2a172011-01-12 09:06:06 +000057TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
Douglas Gregorbf4ea562009-09-15 16:23:51 +000058 SourceLocation LAngleLoc, NamedDecl **Params,
Douglas Gregorddc29e12009-02-06 22:42:48 +000059 unsigned NumParams, SourceLocation RAngleLoc) {
Douglas Gregorbf4ea562009-09-15 16:23:51 +000060 unsigned Size = sizeof(TemplateParameterList)
61 + sizeof(NamedDecl *) * NumParams;
Richard Smith1a30edb2012-08-16 22:51:34 +000062 unsigned Align = std::max(llvm::alignOf<TemplateParameterList>(),
63 llvm::alignOf<NamedDecl*>());
Douglas Gregoraaba5e32009-02-04 19:02:06 +000064 void *Mem = C.Allocate(Size, Align);
Mike Stump1eb44332009-09-09 15:08:12 +000065 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
Douglas Gregorddc29e12009-02-06 22:42:48 +000066 NumParams, RAngleLoc);
Douglas Gregoraaba5e32009-02-04 19:02:06 +000067}
68
Douglas Gregor62cb18d2009-02-11 18:16:40 +000069unsigned TemplateParameterList::getMinRequiredArguments() const {
Douglas Gregor6952f1e2011-01-19 20:10:05 +000070 unsigned NumRequiredArgs = 0;
71 for (iterator P = const_cast<TemplateParameterList *>(this)->begin(),
72 PEnd = const_cast<TemplateParameterList *>(this)->end();
73 P != PEnd; ++P) {
74 if ((*P)->isTemplateParameterPack()) {
75 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P))
76 if (NTTP->isExpandedParameterPack()) {
77 NumRequiredArgs += NTTP->getNumExpansionTypes();
78 continue;
79 }
80
Douglas Gregor62cb18d2009-02-11 18:16:40 +000081 break;
Douglas Gregor6952f1e2011-01-19 20:10:05 +000082 }
83
84 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
85 if (TTP->hasDefaultArgument())
86 break;
87 } else if (NonTypeTemplateParmDecl *NTTP
88 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
89 if (NTTP->hasDefaultArgument())
90 break;
91 } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument())
92 break;
93
94 ++NumRequiredArgs;
Douglas Gregor62cb18d2009-02-11 18:16:40 +000095 }
Douglas Gregor6952f1e2011-01-19 20:10:05 +000096
Douglas Gregor62cb18d2009-02-11 18:16:40 +000097 return NumRequiredArgs;
98}
99
Douglas Gregored9c0f92009-10-29 00:04:11 +0000100unsigned TemplateParameterList::getDepth() const {
101 if (size() == 0)
102 return 0;
103
104 const NamedDecl *FirstParm = getParam(0);
105 if (const TemplateTypeParmDecl *TTP
106 = dyn_cast<TemplateTypeParmDecl>(FirstParm))
107 return TTP->getDepth();
108 else if (const NonTypeTemplateParmDecl *NTTP
109 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
110 return NTTP->getDepth();
111 else
112 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
113}
114
Douglas Gregor787a40d2011-03-04 18:32:38 +0000115static void AdoptTemplateParameterList(TemplateParameterList *Params,
116 DeclContext *Owner) {
117 for (TemplateParameterList::iterator P = Params->begin(),
118 PEnd = Params->end();
119 P != PEnd; ++P) {
120 (*P)->setDeclContext(Owner);
121
122 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P))
123 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
124 }
125}
126
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000127//===----------------------------------------------------------------------===//
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000128// RedeclarableTemplateDecl Implementation
129//===----------------------------------------------------------------------===//
130
Dmitri Gribenkob76d9712013-01-23 16:52:57 +0000131RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
Rafael Espindola92975352013-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 Gregor7c99bb5c2012-01-14 15:13:49 +0000143 }
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000144
Rafael Espindola92975352013-10-19 02:28:17 +0000145 PrevDecls.push_back(Prev);
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000146 }
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000147
Rafael Espindola92975352013-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 Gregor7c99bb5c2012-01-14 15:13:49 +0000160 return Common;
Peter Collingbournef88718e2010-07-29 16:12:09 +0000161}
162
Peter Collingbourne40485902010-07-30 17:09:04 +0000163template <class EntryType>
164typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
165RedeclarableTemplateDecl::findSpecializationImpl(
Chandler Carruthd964d632012-05-03 23:49:05 +0000166 llvm::FoldingSetVector<EntryType> &Specs,
Stephen Hinesef822542014-07-21 00:47:37 -0700167 ArrayRef<TemplateArgument> Args,
Peter Collingbourne40485902010-07-30 17:09:04 +0000168 void *&InsertPos) {
169 typedef SpecEntryTraits<EntryType> SETraits;
170 llvm::FoldingSetNodeID ID;
Stephen Hinesef822542014-07-21 00:47:37 -0700171 EntryType::Profile(ID,Args, getASTContext());
Peter Collingbourne40485902010-07-30 17:09:04 +0000172 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700173 return Entry ? SETraits::getMostRecentDecl(Entry) : nullptr;
Peter Collingbourne40485902010-07-30 17:09:04 +0000174}
175
Douglas Gregorc494f772011-03-05 17:54:25 +0000176/// \brief Generate the injected template arguments for the given template
177/// parameter list, e.g., for the injected-class-name of a class template.
178static void GenerateInjectedTemplateArgs(ASTContext &Context,
179 TemplateParameterList *Params,
180 TemplateArgument *Args) {
181 for (TemplateParameterList::iterator Param = Params->begin(),
182 ParamEnd = Params->end();
183 Param != ParamEnd; ++Param) {
184 TemplateArgument Arg;
185 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
186 QualType ArgType = Context.getTypeDeclType(TTP);
187 if (TTP->isParameterPack())
David Blaikie66874fb2013-02-21 01:47:18 +0000188 ArgType = Context.getPackExpansionType(ArgType, None);
David Blaikiedc84cd52013-02-20 22:23:23 +0000189
Douglas Gregorc494f772011-03-05 17:54:25 +0000190 Arg = TemplateArgument(ArgType);
191 } else if (NonTypeTemplateParmDecl *NTTP =
192 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
John McCallf4b88a42012-03-10 09:33:50 +0000193 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
Douglas Gregorc494f772011-03-05 17:54:25 +0000194 NTTP->getType().getNonLValueExprType(Context),
195 Expr::getValueKindForType(NTTP->getType()),
196 NTTP->getLocation());
197
198 if (NTTP->isParameterPack())
David Blaikie66874fb2013-02-21 01:47:18 +0000199 E = new (Context) PackExpansionExpr(Context.DependentTy, E,
200 NTTP->getLocation(), None);
Douglas Gregorc494f772011-03-05 17:54:25 +0000201 Arg = TemplateArgument(E);
202 } else {
203 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
204 if (TTP->isParameterPack())
David Blaikiedc84cd52013-02-20 22:23:23 +0000205 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
Douglas Gregorc494f772011-03-05 17:54:25 +0000206 else
207 Arg = TemplateArgument(TemplateName(TTP));
208 }
209
210 if ((*Param)->isTemplateParameterPack())
211 Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
212
213 *Args++ = Arg;
214 }
215}
216
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000217//===----------------------------------------------------------------------===//
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000218// FunctionTemplateDecl Implementation
219//===----------------------------------------------------------------------===//
220
Douglas Gregor00545312010-05-23 18:26:36 +0000221void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
222 static_cast<Common *>(Ptr)->~Common();
223}
224
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000225FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
226 DeclContext *DC,
227 SourceLocation L,
228 DeclarationName Name,
Douglas Gregor127102b2009-06-29 20:59:39 +0000229 TemplateParameterList *Params,
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000230 NamedDecl *Decl) {
Douglas Gregor787a40d2011-03-04 18:32:38 +0000231 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700232 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000233}
234
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000235FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
236 unsigned ID) {
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700237 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
238 DeclarationName(), nullptr, nullptr);
Douglas Gregor9a299e02011-03-04 17:52:15 +0000239}
240
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +0000241RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob76d9712013-01-23 16:52:57 +0000242FunctionTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +0000243 Common *CommonPtr = new (C) Common;
244 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000245 return CommonPtr;
246}
247
Richard Smith6982bf42013-06-28 04:37:53 +0000248void FunctionTemplateDecl::LoadLazySpecializations() const {
249 Common *CommonPtr = getCommonPtr();
250 if (CommonPtr->LazySpecializations) {
251 ASTContext &Context = getASTContext();
252 uint32_t *Specs = CommonPtr->LazySpecializations;
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700253 CommonPtr->LazySpecializations = nullptr;
Richard Smith6982bf42013-06-28 04:37:53 +0000254 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
255 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
256 }
257}
258
259llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
260FunctionTemplateDecl::getSpecializations() const {
261 LoadLazySpecializations();
262 return getCommonPtr()->Specializations;
263}
264
Argyrios Kyrtzidis2c853e42010-07-20 13:59:58 +0000265FunctionDecl *
Stephen Hinesef822542014-07-21 00:47:37 -0700266FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
267 void *&InsertPos) {
268 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis2c853e42010-07-20 13:59:58 +0000269}
270
Sebastian Redl5bbcdbf2011-04-14 14:07:59 +0000271void FunctionTemplateDecl::addSpecialization(
272 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
Douglas Gregor1e1e9722012-03-28 14:34:23 +0000273 if (InsertPos)
274 getSpecializations().InsertNode(Info, InsertPos);
275 else
276 getSpecializations().GetOrInsertNode(Info);
Sebastian Redl5bbcdbf2011-04-14 14:07:59 +0000277 if (ASTMutationListener *L = getASTMutationListener())
278 L->AddedCXXTemplateSpecialization(this, Info->Function);
279}
280
Richard Smith7a9f7c72013-05-17 03:04:50 +0000281ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
Douglas Gregorc494f772011-03-05 17:54:25 +0000282 TemplateParameterList *Params = getTemplateParameters();
283 Common *CommonPtr = getCommonPtr();
284 if (!CommonPtr->InjectedArgs) {
285 CommonPtr->InjectedArgs
Richard Smith7a9f7c72013-05-17 03:04:50 +0000286 = new (getASTContext()) TemplateArgument[Params->size()];
287 GenerateInjectedTemplateArgs(getASTContext(), Params,
Douglas Gregorc494f772011-03-05 17:54:25 +0000288 CommonPtr->InjectedArgs);
289 }
Richard Smith7a9f7c72013-05-17 03:04:50 +0000290
291 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
Douglas Gregorc494f772011-03-05 17:54:25 +0000292}
293
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000294//===----------------------------------------------------------------------===//
295// ClassTemplateDecl Implementation
296//===----------------------------------------------------------------------===//
297
Douglas Gregor00545312010-05-23 18:26:36 +0000298void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
299 static_cast<Common *>(Ptr)->~Common();
300}
301
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000302ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
303 DeclContext *DC,
304 SourceLocation L,
305 DeclarationName Name,
306 TemplateParameterList *Params,
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000307 NamedDecl *Decl,
308 ClassTemplateDecl *PrevDecl) {
Douglas Gregor787a40d2011-03-04 18:32:38 +0000309 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700310 ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
311 Params, Decl);
Rafael Espindolabc650912013-10-17 15:37:26 +0000312 New->setPreviousDecl(PrevDecl);
Argyrios Kyrtzidis8731ca72010-06-19 19:29:09 +0000313 return New;
Douglas Gregor5953d8b2009-03-19 17:26:29 +0000314}
315
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700316ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000317 unsigned ID) {
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700318 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
319 DeclarationName(), nullptr, nullptr);
Douglas Gregor9a299e02011-03-04 17:52:15 +0000320}
321
Dmitri Gribenkoe252a892013-02-14 13:20:36 +0000322void ClassTemplateDecl::LoadLazySpecializations() const {
Douglas Gregorc8e5cf82010-10-27 22:21:36 +0000323 Common *CommonPtr = getCommonPtr();
324 if (CommonPtr->LazySpecializations) {
325 ASTContext &Context = getASTContext();
326 uint32_t *Specs = CommonPtr->LazySpecializations;
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700327 CommonPtr->LazySpecializations = nullptr;
Douglas Gregorc8e5cf82010-10-27 22:21:36 +0000328 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
329 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
330 }
331}
332
Chandler Carruthd964d632012-05-03 23:49:05 +0000333llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
Dmitri Gribenkoe252a892013-02-14 13:20:36 +0000334ClassTemplateDecl::getSpecializations() const {
Douglas Gregorc8e5cf82010-10-27 22:21:36 +0000335 LoadLazySpecializations();
336 return getCommonPtr()->Specializations;
337}
338
Chandler Carruthd964d632012-05-03 23:49:05 +0000339llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
Douglas Gregorc8e5cf82010-10-27 22:21:36 +0000340ClassTemplateDecl::getPartialSpecializations() {
341 LoadLazySpecializations();
342 return getCommonPtr()->PartialSpecializations;
343}
344
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +0000345RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob76d9712013-01-23 16:52:57 +0000346ClassTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidis6b541512010-09-08 19:31:22 +0000347 Common *CommonPtr = new (C) Common;
348 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne9eabeba2010-07-29 16:11:51 +0000349 return CommonPtr;
350}
351
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000352ClassTemplateSpecializationDecl *
Stephen Hinesef822542014-07-21 00:47:37 -0700353ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
354 void *&InsertPos) {
355 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000356}
357
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000358void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
359 void *InsertPos) {
Douglas Gregor1e1e9722012-03-28 14:34:23 +0000360 if (InsertPos)
361 getSpecializations().InsertNode(D, InsertPos);
362 else {
363 ClassTemplateSpecializationDecl *Existing
364 = getSpecializations().GetOrInsertNode(D);
365 (void)Existing;
366 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
367 }
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000368 if (ASTMutationListener *L = getASTMutationListener())
369 L->AddedCXXTemplateSpecialization(this, D);
370}
371
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000372ClassTemplatePartialSpecializationDecl *
Stephen Hinesef822542014-07-21 00:47:37 -0700373ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000374 void *&InsertPos) {
Stephen Hinesef822542014-07-21 00:47:37 -0700375 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000376}
377
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000378void ClassTemplateDecl::AddPartialSpecialization(
379 ClassTemplatePartialSpecializationDecl *D,
380 void *InsertPos) {
Douglas Gregor1e1e9722012-03-28 14:34:23 +0000381 if (InsertPos)
382 getPartialSpecializations().InsertNode(D, InsertPos);
383 else {
384 ClassTemplatePartialSpecializationDecl *Existing
385 = getPartialSpecializations().GetOrInsertNode(D);
386 (void)Existing;
387 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
388 }
389
Argyrios Kyrtzidisbef1a7b2010-10-28 07:38:42 +0000390 if (ASTMutationListener *L = getASTMutationListener())
391 L->AddedCXXTemplateSpecialization(this, D);
392}
393
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000394void ClassTemplateDecl::getPartialSpecializations(
Chris Lattner5f9e2722011-07-23 10:55:15 +0000395 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
Chandler Carruthd964d632012-05-03 23:49:05 +0000396 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
Argyrios Kyrtzidis5bf1bdc2010-06-21 10:57:41 +0000397 = getPartialSpecializations();
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000398 PS.clear();
Richard Smith37fd27d2013-08-22 23:27:37 +0000399 PS.reserve(PartialSpecs.size());
Chandler Carruthd964d632012-05-03 23:49:05 +0000400 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000401 P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
Richard Smith37fd27d2013-08-22 23:27:37 +0000402 P != PEnd; ++P)
403 PS.push_back(P->getMostRecentDecl());
Douglas Gregordc60c1e2010-04-30 05:56:50 +0000404}
405
Douglas Gregorb88e8882009-07-30 17:40:51 +0000406ClassTemplatePartialSpecializationDecl *
407ClassTemplateDecl::findPartialSpecialization(QualType T) {
408 ASTContext &Context = getASTContext();
Chandler Carruthd964d632012-05-03 23:49:05 +0000409 using llvm::FoldingSetVector;
410 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregorb88e8882009-07-30 17:40:51 +0000411 partial_spec_iterator;
412 for (partial_spec_iterator P = getPartialSpecializations().begin(),
413 PEnd = getPartialSpecializations().end();
414 P != PEnd; ++P) {
John McCall31f17ec2010-04-27 00:57:59 +0000415 if (Context.hasSameType(P->getInjectedSpecializationType(), T))
Douglas Gregoref96ee02012-01-14 16:38:05 +0000416 return P->getMostRecentDecl();
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000417 }
418
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700419 return nullptr;
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000420}
421
422ClassTemplatePartialSpecializationDecl *
423ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
424 ClassTemplatePartialSpecializationDecl *D) {
425 Decl *DCanon = D->getCanonicalDecl();
Chandler Carruthd964d632012-05-03 23:49:05 +0000426 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Argyrios Kyrtzidiscc0b1bc2010-07-20 13:59:28 +0000427 P = getPartialSpecializations().begin(),
428 PEnd = getPartialSpecializations().end();
429 P != PEnd; ++P) {
430 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
Douglas Gregoref96ee02012-01-14 16:38:05 +0000431 return P->getMostRecentDecl();
Douglas Gregorb88e8882009-07-30 17:40:51 +0000432 }
Mike Stump1eb44332009-09-09 15:08:12 +0000433
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700434 return nullptr;
Douglas Gregorb88e8882009-07-30 17:40:51 +0000435}
436
John McCall3cb0ebd2010-03-10 03:28:59 +0000437QualType
Douglas Gregor24bae922010-07-08 18:37:38 +0000438ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidis5bf1bdc2010-06-21 10:57:41 +0000439 Common *CommonPtr = getCommonPtr();
Douglas Gregor7da97d02009-05-10 22:57:19 +0000440 if (!CommonPtr->InjectedClassNameType.isNull())
441 return CommonPtr->InjectedClassNameType;
442
Douglas Gregorb7d09d62010-12-23 16:00:30 +0000443 // C++0x [temp.dep.type]p2:
444 // The template argument list of a primary template is a template argument
445 // list in which the nth template argument has the value of the nth template
446 // parameter of the class template. If the nth template parameter is a
447 // template parameter pack (14.5.3), the nth template argument is a pack
448 // expansion (14.5.3) whose pattern is the name of the template parameter
449 // pack.
Douglas Gregor24bae922010-07-08 18:37:38 +0000450 ASTContext &Context = getASTContext();
Douglas Gregor7da97d02009-05-10 22:57:19 +0000451 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner5f9e2722011-07-23 10:55:15 +0000452 SmallVector<TemplateArgument, 16> TemplateArgs;
Douglas Gregorc494f772011-03-05 17:54:25 +0000453 TemplateArgs.resize(Params->size());
454 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
Douglas Gregor7da97d02009-05-10 22:57:19 +0000455 CommonPtr->InjectedClassNameType
Douglas Gregor1275ae02009-07-28 23:00:59 +0000456 = Context.getTemplateSpecializationType(TemplateName(this),
Douglas Gregor7da97d02009-05-10 22:57:19 +0000457 &TemplateArgs[0],
Douglas Gregor1275ae02009-07-28 23:00:59 +0000458 TemplateArgs.size());
Douglas Gregor7da97d02009-05-10 22:57:19 +0000459 return CommonPtr->InjectedClassNameType;
460}
461
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000462//===----------------------------------------------------------------------===//
463// TemplateTypeParm Allocation/Deallocation Method Implementations
464//===----------------------------------------------------------------------===//
465
466TemplateTypeParmDecl *
Jay Foad4ba2a172011-01-12 09:06:06 +0000467TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnara344577e2011-03-06 15:48:19 +0000468 SourceLocation KeyLoc, SourceLocation NameLoc,
469 unsigned D, unsigned P, IdentifierInfo *Id,
470 bool Typename, bool ParameterPack) {
Chandler Carruth4fb86f82011-05-01 00:51:33 +0000471 TemplateTypeParmDecl *TTPDecl =
Stephen Hines651f13c2014-04-23 16:59:28 -0700472 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
Chandler Carruth4fb86f82011-05-01 00:51:33 +0000473 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700474 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
Chandler Carruth4fb86f82011-05-01 00:51:33 +0000475 return TTPDecl;
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000476}
477
Argyrios Kyrtzidisb8b03e62010-07-02 11:54:55 +0000478TemplateTypeParmDecl *
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000479TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700480 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
481 SourceLocation(), nullptr, false);
Argyrios Kyrtzidisb8b03e62010-07-02 11:54:55 +0000482}
483
John McCall833ca992009-10-29 08:12:44 +0000484SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara77d4ee22011-03-04 12:42:03 +0000485 return hasDefaultArgument()
486 ? DefaultArgument->getTypeLoc().getBeginLoc()
487 : SourceLocation();
488}
489
490SourceRange TemplateTypeParmDecl::getSourceRange() const {
491 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnara344577e2011-03-06 15:48:19 +0000492 return SourceRange(getLocStart(),
Abramo Bagnara77d4ee22011-03-04 12:42:03 +0000493 DefaultArgument->getTypeLoc().getEndLoc());
494 else
Abramo Bagnara344577e2011-03-06 15:48:19 +0000495 return TypeDecl::getSourceRange();
John McCall833ca992009-10-29 08:12:44 +0000496}
497
Douglas Gregored9c0f92009-10-29 00:04:11 +0000498unsigned TemplateTypeParmDecl::getDepth() const {
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700499 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
Douglas Gregored9c0f92009-10-29 00:04:11 +0000500}
501
502unsigned TemplateTypeParmDecl::getIndex() const {
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700503 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
Douglas Gregored9c0f92009-10-29 00:04:11 +0000504}
505
Chandler Carruth4fb86f82011-05-01 00:51:33 +0000506bool TemplateTypeParmDecl::isParameterPack() const {
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700507 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
Chandler Carruth4fb86f82011-05-01 00:51:33 +0000508}
509
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000510//===----------------------------------------------------------------------===//
511// NonTypeTemplateParmDecl Method Implementations
512//===----------------------------------------------------------------------===//
513
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000514NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000515 SourceLocation StartLoc,
516 SourceLocation IdLoc,
517 unsigned D, unsigned P,
518 IdentifierInfo *Id,
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000519 QualType T,
520 TypeSourceInfo *TInfo,
521 const QualType *ExpandedTypes,
522 unsigned NumExpandedTypes,
523 TypeSourceInfo **ExpandedTInfos)
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000524 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700525 TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false),
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000526 ParameterPack(true), ExpandedParameterPack(true),
527 NumExpandedTypes(NumExpandedTypes)
528{
529 if (ExpandedTypes && ExpandedTInfos) {
530 void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
531 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
532 TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
533 TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
534 }
535 }
536}
537
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000538NonTypeTemplateParmDecl *
Jay Foad4ba2a172011-01-12 09:06:06 +0000539NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000540 SourceLocation StartLoc, SourceLocation IdLoc,
541 unsigned D, unsigned P, IdentifierInfo *Id,
542 QualType T, bool ParameterPack,
543 TypeSourceInfo *TInfo) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700544 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
545 T, ParameterPack, TInfo);
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000546}
547
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000548NonTypeTemplateParmDecl *
549NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaraff676cb2011-03-08 08:55:46 +0000550 SourceLocation StartLoc, SourceLocation IdLoc,
551 unsigned D, unsigned P,
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000552 IdentifierInfo *Id, QualType T,
553 TypeSourceInfo *TInfo,
554 const QualType *ExpandedTypes,
555 unsigned NumExpandedTypes,
556 TypeSourceInfo **ExpandedTInfos) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700557 unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
558 return new (C, DC, Extra) NonTypeTemplateParmDecl(
559 DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
560 ExpandedTypes, NumExpandedTypes, ExpandedTInfos);
Douglas Gregor6952f1e2011-01-19 20:10:05 +0000561}
562
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000563NonTypeTemplateParmDecl *
564NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700565 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
566 SourceLocation(), 0, 0, nullptr,
567 QualType(), false, nullptr);
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000568}
569
570NonTypeTemplateParmDecl *
571NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
572 unsigned NumExpandedTypes) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700573 unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
574 return new (C, ID, Extra) NonTypeTemplateParmDecl(
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700575 nullptr, SourceLocation(), SourceLocation(), 0, 0, nullptr, QualType(),
576 nullptr, nullptr, NumExpandedTypes, nullptr);
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000577}
578
John McCall76a40212011-02-09 01:13:10 +0000579SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnaraee4bfd42011-03-04 11:03:48 +0000580 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraa2026c92011-03-08 16:41:52 +0000581 return SourceRange(getOuterLocStart(),
582 getDefaultArgument()->getSourceRange().getEnd());
583 return DeclaratorDecl::getSourceRange();
John McCall76a40212011-02-09 01:13:10 +0000584}
585
Douglas Gregord684b002009-02-10 19:49:53 +0000586SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnarad92f7a22010-06-09 09:26:05 +0000587 return hasDefaultArgument()
588 ? getDefaultArgument()->getSourceRange().getBegin()
589 : SourceLocation();
Douglas Gregord684b002009-02-10 19:49:53 +0000590}
591
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000592//===----------------------------------------------------------------------===//
593// TemplateTemplateParmDecl Method Implementations
594//===----------------------------------------------------------------------===//
595
David Blaikie99ba9e32011-12-20 02:48:34 +0000596void TemplateTemplateParmDecl::anchor() { }
597
Richard Smith6964b3f2012-09-07 02:06:42 +0000598TemplateTemplateParmDecl::TemplateTemplateParmDecl(
599 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
600 IdentifierInfo *Id, TemplateParameterList *Params,
601 unsigned NumExpansions, TemplateParameterList * const *Expansions)
602 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
603 TemplateParmPosition(D, P), DefaultArgument(),
604 DefaultArgumentWasInherited(false), ParameterPack(true),
605 ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
606 if (Expansions)
607 std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
608 sizeof(TemplateParameterList*) * NumExpandedParams);
609}
610
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000611TemplateTemplateParmDecl *
Jay Foad4ba2a172011-01-12 09:06:06 +0000612TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000613 SourceLocation L, unsigned D, unsigned P,
Douglas Gregor61c4d282011-01-05 15:48:55 +0000614 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000615 TemplateParameterList *Params) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700616 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
617 Params);
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000618}
619
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000620TemplateTemplateParmDecl *
Richard Smith6964b3f2012-09-07 02:06:42 +0000621TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
622 SourceLocation L, unsigned D, unsigned P,
623 IdentifierInfo *Id,
624 TemplateParameterList *Params,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000625 ArrayRef<TemplateParameterList *> Expansions) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700626 return new (C, DC, sizeof(TemplateParameterList*) * Expansions.size())
627 TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
628 Expansions.size(), Expansions.data());
Richard Smith6964b3f2012-09-07 02:06:42 +0000629}
630
631TemplateTemplateParmDecl *
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000632TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700633 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
634 false, nullptr, nullptr);
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000635}
636
Richard Smith6964b3f2012-09-07 02:06:42 +0000637TemplateTemplateParmDecl *
638TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
639 unsigned NumExpansions) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700640 return new (C, ID, sizeof(TemplateParameterList*) * NumExpansions)
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700641 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
642 nullptr, NumExpansions, nullptr);
Richard Smith6964b3f2012-09-07 02:06:42 +0000643}
644
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000645//===----------------------------------------------------------------------===//
Douglas Gregor7e063902009-05-11 23:53:27 +0000646// TemplateArgumentList Implementation
647//===----------------------------------------------------------------------===//
Douglas Gregor910f8002010-11-07 23:05:16 +0000648TemplateArgumentList *
649TemplateArgumentList::CreateCopy(ASTContext &Context,
650 const TemplateArgument *Args,
651 unsigned NumArgs) {
652 std::size_t Size = sizeof(TemplateArgumentList)
653 + NumArgs * sizeof(TemplateArgument);
654 void *Mem = Context.Allocate(Size);
655 TemplateArgument *StoredArgs
656 = reinterpret_cast<TemplateArgument *>(
657 static_cast<TemplateArgumentList *>(Mem) + 1);
658 std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
659 return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000660}
661
Argyrios Kyrtzidis71a76052011-09-22 20:07:09 +0000662FunctionTemplateSpecializationInfo *
663FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
664 FunctionTemplateDecl *Template,
665 TemplateSpecializationKind TSK,
666 const TemplateArgumentList *TemplateArgs,
667 const TemplateArgumentListInfo *TemplateArgsAsWritten,
668 SourceLocation POI) {
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700669 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
Argyrios Kyrtzidis71a76052011-09-22 20:07:09 +0000670 if (TemplateArgsAsWritten)
671 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
672 *TemplateArgsAsWritten);
673
674 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
675 TemplateArgs,
676 ArgsAsWritten,
677 POI);
678}
679
Douglas Gregor7e063902009-05-11 23:53:27 +0000680//===----------------------------------------------------------------------===//
David Blaikie99ba9e32011-12-20 02:48:34 +0000681// TemplateDecl Implementation
682//===----------------------------------------------------------------------===//
683
684void TemplateDecl::anchor() { }
685
686//===----------------------------------------------------------------------===//
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000687// ClassTemplateSpecializationDecl Implementation
688//===----------------------------------------------------------------------===//
689ClassTemplateSpecializationDecl::
Douglas Gregor13c85772010-05-06 00:28:52 +0000690ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000691 DeclContext *DC, SourceLocation StartLoc,
692 SourceLocation IdLoc,
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000693 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000694 const TemplateArgument *Args,
695 unsigned NumArgs,
Douglas Gregor8e9e9ef2009-07-29 23:36:44 +0000696 ClassTemplateSpecializationDecl *PrevDecl)
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700697 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
Douglas Gregor8e9e9ef2009-07-29 23:36:44 +0000698 SpecializedTemplate->getIdentifier(),
699 PrevDecl),
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000700 SpecializedTemplate(SpecializedTemplate),
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700701 ExplicitInfo(nullptr),
Douglas Gregor910f8002010-11-07 23:05:16 +0000702 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
Douglas Gregor7e063902009-05-11 23:53:27 +0000703 SpecializationKind(TSK_Undeclared) {
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000704}
Mike Stump1eb44332009-09-09 15:08:12 +0000705
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700706ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
707 Kind DK)
708 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
709 SourceLocation(), nullptr, nullptr),
710 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000711
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000712ClassTemplateSpecializationDecl *
Douglas Gregor13c85772010-05-06 00:28:52 +0000713ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000714 DeclContext *DC,
715 SourceLocation StartLoc,
716 SourceLocation IdLoc,
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000717 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000718 const TemplateArgument *Args,
719 unsigned NumArgs,
Douglas Gregorcc636682009-02-17 23:15:12 +0000720 ClassTemplateSpecializationDecl *PrevDecl) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700721 ClassTemplateSpecializationDecl *Result =
722 new (Context, DC) ClassTemplateSpecializationDecl(
723 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
724 SpecializedTemplate, Args, NumArgs, PrevDecl);
Douglas Gregor6bd99292013-02-09 01:35:03 +0000725 Result->MayHaveOutOfDateDef = false;
726
Douglas Gregorcc636682009-02-17 23:15:12 +0000727 Context.getTypeDeclType(Result, PrevDecl);
728 return Result;
Douglas Gregor3e00bad2009-02-17 01:05:43 +0000729}
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000730
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000731ClassTemplateSpecializationDecl *
Stephen Hines651f13c2014-04-23 16:59:28 -0700732ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000733 unsigned ID) {
Douglas Gregor6bd99292013-02-09 01:35:03 +0000734 ClassTemplateSpecializationDecl *Result =
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700735 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
Douglas Gregor6bd99292013-02-09 01:35:03 +0000736 Result->MayHaveOutOfDateDef = false;
737 return Result;
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000738}
739
Benjamin Kramer5eada842013-02-22 15:46:01 +0000740void ClassTemplateSpecializationDecl::getNameForDiagnostic(
741 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
742 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
Douglas Gregorda2142f2011-02-19 18:51:44 +0000743
744 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Benjamin Kramer5eada842013-02-22 15:46:01 +0000745 TemplateSpecializationType::PrintTemplateArgumentList(
746 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
Douglas Gregorda2142f2011-02-19 18:51:44 +0000747}
748
Douglas Gregor37d93e92009-08-02 23:24:31 +0000749ClassTemplateDecl *
Mike Stump1eb44332009-09-09 15:08:12 +0000750ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
751 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor37d93e92009-08-02 23:24:31 +0000752 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
753 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
754 return SpecializedTemplate.get<ClassTemplateDecl*>();
755}
756
Abramo Bagnara4a85a732011-03-04 14:20:30 +0000757SourceRange
758ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnara09d82122011-10-03 20:34:03 +0000759 if (ExplicitInfo) {
Abramo Bagnarab2e80012012-10-15 21:06:42 +0000760 SourceLocation Begin = getTemplateKeywordLoc();
761 if (Begin.isValid()) {
762 // Here we have an explicit (partial) specialization or instantiation.
763 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
764 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
765 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
766 if (getExternLoc().isValid())
767 Begin = getExternLoc();
768 SourceLocation End = getRBraceLoc();
769 if (End.isInvalid())
770 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
771 return SourceRange(Begin, End);
772 }
773 // An implicit instantiation of a class template partial specialization
774 // uses ExplicitInfo to record the TypeAsWritten, but the source
775 // locations should be retrieved from the instantiation pattern.
776 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
777 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
778 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700779 assert(inst_from != nullptr);
Abramo Bagnarab2e80012012-10-15 21:06:42 +0000780 return inst_from->getSourceRange();
Abramo Bagnara09d82122011-10-03 20:34:03 +0000781 }
782 else {
783 // No explicit info available.
784 llvm::PointerUnion<ClassTemplateDecl *,
785 ClassTemplatePartialSpecializationDecl *>
786 inst_from = getInstantiatedFrom();
787 if (inst_from.isNull())
788 return getSpecializedTemplate()->getSourceRange();
789 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
790 return ctd->getSourceRange();
791 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
792 ->getSourceRange();
793 }
Abramo Bagnara4a85a732011-03-04 14:20:30 +0000794}
795
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000796//===----------------------------------------------------------------------===//
797// ClassTemplatePartialSpecializationDecl Implementation
798//===----------------------------------------------------------------------===//
David Blaikie99ba9e32011-12-20 02:48:34 +0000799void ClassTemplatePartialSpecializationDecl::anchor() { }
800
Douglas Gregor9a299e02011-03-04 17:52:15 +0000801ClassTemplatePartialSpecializationDecl::
802ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000803 DeclContext *DC,
804 SourceLocation StartLoc,
805 SourceLocation IdLoc,
Douglas Gregor9a299e02011-03-04 17:52:15 +0000806 TemplateParameterList *Params,
807 ClassTemplateDecl *SpecializedTemplate,
808 const TemplateArgument *Args,
809 unsigned NumArgs,
Enea Zaffanellac1cef082013-08-10 07:24:53 +0000810 const ASTTemplateArgumentListInfo *ArgInfos,
Richard Smith37fd27d2013-08-22 23:27:37 +0000811 ClassTemplatePartialSpecializationDecl *PrevDecl)
Douglas Gregor9a299e02011-03-04 17:52:15 +0000812 : ClassTemplateSpecializationDecl(Context,
813 ClassTemplatePartialSpecialization,
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000814 TK, DC, StartLoc, IdLoc,
815 SpecializedTemplate,
Douglas Gregor9a299e02011-03-04 17:52:15 +0000816 Args, NumArgs, PrevDecl),
817 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700818 InstantiatedFromMember(nullptr, false)
Enea Zaffanellac1cef082013-08-10 07:24:53 +0000819{
Douglas Gregor787a40d2011-03-04 18:32:38 +0000820 AdoptTemplateParameterList(Params, this);
Douglas Gregor9a299e02011-03-04 17:52:15 +0000821}
822
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000823ClassTemplatePartialSpecializationDecl *
824ClassTemplatePartialSpecializationDecl::
Abramo Bagnaraba877ad2011-03-09 14:09:51 +0000825Create(ASTContext &Context, TagKind TK,DeclContext *DC,
826 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000827 TemplateParameterList *Params,
828 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor910f8002010-11-07 23:05:16 +0000829 const TemplateArgument *Args,
830 unsigned NumArgs,
John McCalld5532b62009-11-23 01:53:49 +0000831 const TemplateArgumentListInfo &ArgInfos,
John McCall3cb0ebd2010-03-10 03:28:59 +0000832 QualType CanonInjectedType,
Richard Smith37fd27d2013-08-22 23:27:37 +0000833 ClassTemplatePartialSpecializationDecl *PrevDecl) {
Enea Zaffanellac1cef082013-08-10 07:24:53 +0000834 const ASTTemplateArgumentListInfo *ASTArgInfos =
835 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
John McCall833ca992009-10-29 08:12:44 +0000836
Stephen Hines651f13c2014-04-23 16:59:28 -0700837 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
838 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
839 Params, SpecializedTemplate, Args,
840 NumArgs, ASTArgInfos, PrevDecl);
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000841 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor6bd99292013-02-09 01:35:03 +0000842 Result->MayHaveOutOfDateDef = false;
John McCall3cb0ebd2010-03-10 03:28:59 +0000843
844 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregorc8ab2562009-05-31 09:31:02 +0000845 return Result;
846}
John McCalldd4a3b02009-09-16 22:47:08 +0000847
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000848ClassTemplatePartialSpecializationDecl *
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000849ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
850 unsigned ID) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700851 ClassTemplatePartialSpecializationDecl *Result =
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700852 new (C, ID) ClassTemplatePartialSpecializationDecl(C);
Douglas Gregor6bd99292013-02-09 01:35:03 +0000853 Result->MayHaveOutOfDateDef = false;
854 return Result;
Argyrios Kyrtzidis94d228d2010-06-23 13:48:23 +0000855}
856
John McCalldd4a3b02009-09-16 22:47:08 +0000857//===----------------------------------------------------------------------===//
858// FriendTemplateDecl Implementation
859//===----------------------------------------------------------------------===//
860
David Blaikie99ba9e32011-12-20 02:48:34 +0000861void FriendTemplateDecl::anchor() { }
862
John McCalldd4a3b02009-09-16 22:47:08 +0000863FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
864 DeclContext *DC,
865 SourceLocation L,
866 unsigned NParams,
867 TemplateParameterList **Params,
868 FriendUnion Friend,
869 SourceLocation FLoc) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700870 return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params,
871 Friend, FLoc);
John McCalldd4a3b02009-09-16 22:47:08 +0000872}
Argyrios Kyrtzidis554e6aa2010-07-22 16:04:10 +0000873
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000874FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
875 unsigned ID) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700876 return new (C, ID) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis554e6aa2010-07-22 16:04:10 +0000877}
Richard Smith3e4c6c42011-05-05 21:57:07 +0000878
879//===----------------------------------------------------------------------===//
880// TypeAliasTemplateDecl Implementation
881//===----------------------------------------------------------------------===//
882
883TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
884 DeclContext *DC,
885 SourceLocation L,
886 DeclarationName Name,
887 TemplateParameterList *Params,
888 NamedDecl *Decl) {
889 AdoptTemplateParameterList(Params, DC);
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700890 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
Richard Smith3e4c6c42011-05-05 21:57:07 +0000891}
892
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000893TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
894 unsigned ID) {
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700895 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
896 DeclarationName(), nullptr, nullptr);
Richard Smith3e4c6c42011-05-05 21:57:07 +0000897}
898
899void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
900 static_cast<Common *>(Ptr)->~Common();
901}
902RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob76d9712013-01-23 16:52:57 +0000903TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3e4c6c42011-05-05 21:57:07 +0000904 Common *CommonPtr = new (C) Common;
905 C.AddDeallocation(DeallocateCommon, CommonPtr);
906 return CommonPtr;
907}
908
David Blaikie99ba9e32011-12-20 02:48:34 +0000909//===----------------------------------------------------------------------===//
910// ClassScopeFunctionSpecializationDecl Implementation
911//===----------------------------------------------------------------------===//
912
913void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000914
915ClassScopeFunctionSpecializationDecl *
916ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
917 unsigned ID) {
Stephen Hines651f13c2014-04-23 16:59:28 -0700918 return new (C, ID) ClassScopeFunctionSpecializationDecl(
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700919 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
Douglas Gregor1e68ecc2012-01-05 21:55:30 +0000920}
Larisse Voufoef4579c2013-08-06 01:03:05 +0000921
922//===----------------------------------------------------------------------===//
923// VarTemplateDecl Implementation
924//===----------------------------------------------------------------------===//
925
926void VarTemplateDecl::DeallocateCommon(void *Ptr) {
927 static_cast<Common *>(Ptr)->~Common();
928}
929
Larisse Voufo439d6652013-08-13 02:02:26 +0000930VarTemplateDecl *VarTemplateDecl::getDefinition() {
931 VarTemplateDecl *CurD = this;
932 while (CurD) {
933 if (CurD->isThisDeclarationADefinition())
934 return CurD;
935 CurD = CurD->getPreviousDecl();
936 }
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700937 return nullptr;
Larisse Voufo439d6652013-08-13 02:02:26 +0000938}
939
Larisse Voufoef4579c2013-08-06 01:03:05 +0000940VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
941 SourceLocation L, DeclarationName Name,
942 TemplateParameterList *Params,
Stephen Hines651f13c2014-04-23 16:59:28 -0700943 VarDecl *Decl) {
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700944 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
Larisse Voufoef4579c2013-08-06 01:03:05 +0000945}
946
947VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
948 unsigned ID) {
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700949 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
950 DeclarationName(), nullptr, nullptr);
Larisse Voufoef4579c2013-08-06 01:03:05 +0000951}
952
Stephen Hines651f13c2014-04-23 16:59:28 -0700953// TODO: Unify across class, function and variable templates?
Larisse Voufo8d2a5ea2013-08-23 22:21:36 +0000954// May require moving this and Common to RedeclarableTemplateDecl.
Larisse Voufoef4579c2013-08-06 01:03:05 +0000955void VarTemplateDecl::LoadLazySpecializations() const {
956 Common *CommonPtr = getCommonPtr();
957 if (CommonPtr->LazySpecializations) {
958 ASTContext &Context = getASTContext();
959 uint32_t *Specs = CommonPtr->LazySpecializations;
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700960 CommonPtr->LazySpecializations = nullptr;
Larisse Voufoef4579c2013-08-06 01:03:05 +0000961 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
962 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
963 }
964}
965
966llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
967VarTemplateDecl::getSpecializations() const {
968 LoadLazySpecializations();
969 return getCommonPtr()->Specializations;
970}
971
972llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
973VarTemplateDecl::getPartialSpecializations() {
974 LoadLazySpecializations();
975 return getCommonPtr()->PartialSpecializations;
976}
977
978RedeclarableTemplateDecl::CommonBase *
979VarTemplateDecl::newCommon(ASTContext &C) const {
980 Common *CommonPtr = new (C) Common;
981 C.AddDeallocation(DeallocateCommon, CommonPtr);
982 return CommonPtr;
983}
984
985VarTemplateSpecializationDecl *
Stephen Hinesef822542014-07-21 00:47:37 -0700986VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
987 void *&InsertPos) {
988 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Larisse Voufoef4579c2013-08-06 01:03:05 +0000989}
990
991void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
992 void *InsertPos) {
993 if (InsertPos)
994 getSpecializations().InsertNode(D, InsertPos);
995 else {
996 VarTemplateSpecializationDecl *Existing =
997 getSpecializations().GetOrInsertNode(D);
998 (void)Existing;
999 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1000 }
1001 if (ASTMutationListener *L = getASTMutationListener())
1002 L->AddedCXXTemplateSpecialization(this, D);
1003}
1004
1005VarTemplatePartialSpecializationDecl *
Stephen Hinesef822542014-07-21 00:47:37 -07001006VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1007 void *&InsertPos) {
1008 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Larisse Voufoef4579c2013-08-06 01:03:05 +00001009}
1010
1011void VarTemplateDecl::AddPartialSpecialization(
1012 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1013 if (InsertPos)
1014 getPartialSpecializations().InsertNode(D, InsertPos);
1015 else {
1016 VarTemplatePartialSpecializationDecl *Existing =
1017 getPartialSpecializations().GetOrInsertNode(D);
1018 (void)Existing;
1019 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1020 }
1021
1022 if (ASTMutationListener *L = getASTMutationListener())
1023 L->AddedCXXTemplateSpecialization(this, D);
1024}
1025
1026void VarTemplateDecl::getPartialSpecializations(
1027 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1028 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1029 getPartialSpecializations();
1030 PS.clear();
Richard Smith37fd27d2013-08-22 23:27:37 +00001031 PS.reserve(PartialSpecs.size());
Larisse Voufoef4579c2013-08-06 01:03:05 +00001032 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1033 P = PartialSpecs.begin(),
1034 PEnd = PartialSpecs.end();
Richard Smith37fd27d2013-08-22 23:27:37 +00001035 P != PEnd; ++P)
1036 PS.push_back(P->getMostRecentDecl());
Larisse Voufoef4579c2013-08-06 01:03:05 +00001037}
1038
1039VarTemplatePartialSpecializationDecl *
1040VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1041 VarTemplatePartialSpecializationDecl *D) {
1042 Decl *DCanon = D->getCanonicalDecl();
1043 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1044 P = getPartialSpecializations().begin(),
1045 PEnd = getPartialSpecializations().end();
1046 P != PEnd; ++P) {
1047 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1048 return P->getMostRecentDecl();
1049 }
1050
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001051 return nullptr;
Larisse Voufoef4579c2013-08-06 01:03:05 +00001052}
1053
1054//===----------------------------------------------------------------------===//
1055// VarTemplateSpecializationDecl Implementation
1056//===----------------------------------------------------------------------===//
1057VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001058 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
Larisse Voufoef4579c2013-08-06 01:03:05 +00001059 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1060 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1061 unsigned NumArgs)
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001062 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1063 SpecializedTemplate->getIdentifier(), T, TInfo, S),
1064 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
Larisse Voufoef4579c2013-08-06 01:03:05 +00001065 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
1066 SpecializationKind(TSK_Undeclared) {}
1067
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001068VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1069 ASTContext &C)
1070 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1071 QualType(), nullptr, SC_None),
1072 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Larisse Voufoef4579c2013-08-06 01:03:05 +00001073
1074VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1075 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1076 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1077 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1078 unsigned NumArgs) {
Stephen Hines651f13c2014-04-23 16:59:28 -07001079 return new (Context, DC) VarTemplateSpecializationDecl(
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001080 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
Stephen Hines651f13c2014-04-23 16:59:28 -07001081 SpecializedTemplate, T, TInfo, S, Args, NumArgs);
Larisse Voufoef4579c2013-08-06 01:03:05 +00001082}
1083
1084VarTemplateSpecializationDecl *
1085VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001086 return new (C, ID)
1087 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
Larisse Voufoef4579c2013-08-06 01:03:05 +00001088}
1089
1090void VarTemplateSpecializationDecl::getNameForDiagnostic(
1091 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1092 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1093
1094 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1095 TemplateSpecializationType::PrintTemplateArgumentList(
1096 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
1097}
1098
1099VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1100 if (SpecializedPartialSpecialization *PartialSpec =
1101 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1102 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1103 return SpecializedTemplate.get<VarTemplateDecl *>();
1104}
1105
1106void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1107 const TemplateArgumentListInfo &ArgsInfo) {
1108 unsigned N = ArgsInfo.size();
1109 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1110 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1111 for (unsigned I = 0; I != N; ++I)
1112 TemplateArgsInfo.addArgument(ArgsInfo[I]);
1113}
1114
1115//===----------------------------------------------------------------------===//
1116// VarTemplatePartialSpecializationDecl Implementation
1117//===----------------------------------------------------------------------===//
1118void VarTemplatePartialSpecializationDecl::anchor() {}
1119
1120VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1121 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1122 SourceLocation IdLoc, TemplateParameterList *Params,
1123 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1124 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
Richard Smith37fd27d2013-08-22 23:27:37 +00001125 const ASTTemplateArgumentListInfo *ArgInfos)
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001126 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
Larisse Voufoef4579c2013-08-06 01:03:05 +00001127 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1128 TInfo, S, Args, NumArgs),
1129 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001130 InstantiatedFromMember(nullptr, false) {
Larisse Voufoef4579c2013-08-06 01:03:05 +00001131 // TODO: The template parameters should be in DC by now. Verify.
1132 // AdoptTemplateParameterList(Params, DC);
1133}
1134
1135VarTemplatePartialSpecializationDecl *
1136VarTemplatePartialSpecializationDecl::Create(
1137 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1138 SourceLocation IdLoc, TemplateParameterList *Params,
1139 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1140 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
Richard Smith37fd27d2013-08-22 23:27:37 +00001141 const TemplateArgumentListInfo &ArgInfos) {
Enea Zaffanellac1cef082013-08-10 07:24:53 +00001142 const ASTTemplateArgumentListInfo *ASTArgInfos
1143 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
Larisse Voufoef4579c2013-08-06 01:03:05 +00001144
1145 VarTemplatePartialSpecializationDecl *Result =
Stephen Hines651f13c2014-04-23 16:59:28 -07001146 new (Context, DC) VarTemplatePartialSpecializationDecl(
Larisse Voufoef4579c2013-08-06 01:03:05 +00001147 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
Richard Smith37fd27d2013-08-22 23:27:37 +00001148 S, Args, NumArgs, ASTArgInfos);
Larisse Voufoef4579c2013-08-06 01:03:05 +00001149 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1150 return Result;
1151}
1152
1153VarTemplatePartialSpecializationDecl *
1154VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1155 unsigned ID) {
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001156 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
Larisse Voufoef4579c2013-08-06 01:03:05 +00001157}