blob: cde497b012e2ff3467e9e4386023b6e42d7dfccc [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
Richard Smithe7bd6de2015-06-10 20:30:23 +0000127namespace clang {
128void *allocateDefaultArgStorageChain(const ASTContext &C) {
129 return new (C) char[sizeof(void*) * 2];
130}
131}
132
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000133//===----------------------------------------------------------------------===//
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000134// RedeclarableTemplateDecl Implementation
135//===----------------------------------------------------------------------===//
136
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000137RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000138 if (Common)
139 return Common;
140
141 // Walk the previous-declaration chain until we either find a declaration
142 // with a common pointer or we run out of previous declarations.
143 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
144 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
145 Prev = Prev->getPreviousDecl()) {
146 if (Prev->Common) {
147 Common = Prev->Common;
148 break;
Douglas Gregor68444de2012-01-14 15:13:49 +0000149 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000150
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000151 PrevDecls.push_back(Prev);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000152 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000153
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000154 // If we never found a common pointer, allocate one now.
155 if (!Common) {
156 // FIXME: If any of the declarations is from an AST file, we probably
157 // need an update record to add the common data.
158
159 Common = newCommon(getASTContext());
160 }
161
162 // Update any previous declarations we saw with the common pointer.
163 for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I)
164 PrevDecls[I]->Common = Common;
165
Douglas Gregor68444de2012-01-14 15:13:49 +0000166 return Common;
Peter Collingbourne029fd692010-07-29 16:12:09 +0000167}
168
Richard Smithe977e512015-02-24 01:23:23 +0000169template<class EntryType>
170typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000171RedeclarableTemplateDecl::findSpecializationImpl(
Richard Smithe977e512015-02-24 01:23:23 +0000172 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
173 void *&InsertPos) {
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000174 typedef SpecEntryTraits<EntryType> SETraits;
175 llvm::FoldingSetNodeID ID;
Craig Topper7e0daca2014-06-26 04:58:53 +0000176 EntryType::Profile(ID,Args, getASTContext());
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000177 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
Richard Smithe977e512015-02-24 01:23:23 +0000178 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
179}
180
181template<class Derived, class EntryType>
182void RedeclarableTemplateDecl::addSpecializationImpl(
183 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
184 void *InsertPos) {
185 typedef SpecEntryTraits<EntryType> SETraits;
186 if (InsertPos) {
187#ifndef NDEBUG
188 void *CorrectInsertPos;
189 assert(!findSpecializationImpl(Specializations,
190 SETraits::getTemplateArgs(Entry),
191 CorrectInsertPos) &&
192 InsertPos == CorrectInsertPos &&
193 "given incorrect InsertPos for specialization");
194#endif
195 Specializations.InsertNode(Entry, InsertPos);
196 } else {
197 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
198 (void)Existing;
199 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
200 "non-canonical specialization?");
201 }
202
203 if (ASTMutationListener *L = getASTMutationListener())
204 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
205 SETraits::getDecl(Entry));
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000206}
207
Douglas Gregor43669f82011-03-05 17:54:25 +0000208/// \brief Generate the injected template arguments for the given template
209/// parameter list, e.g., for the injected-class-name of a class template.
210static void GenerateInjectedTemplateArgs(ASTContext &Context,
211 TemplateParameterList *Params,
212 TemplateArgument *Args) {
213 for (TemplateParameterList::iterator Param = Params->begin(),
214 ParamEnd = Params->end();
215 Param != ParamEnd; ++Param) {
216 TemplateArgument Arg;
217 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
218 QualType ArgType = Context.getTypeDeclType(TTP);
219 if (TTP->isParameterPack())
David Blaikie7a30dc52013-02-21 01:47:18 +0000220 ArgType = Context.getPackExpansionType(ArgType, None);
David Blaikie05785d12013-02-20 22:23:23 +0000221
Douglas Gregor43669f82011-03-05 17:54:25 +0000222 Arg = TemplateArgument(ArgType);
223 } else if (NonTypeTemplateParmDecl *NTTP =
224 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
John McCall113bee02012-03-10 09:33:50 +0000225 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
Douglas Gregor43669f82011-03-05 17:54:25 +0000226 NTTP->getType().getNonLValueExprType(Context),
227 Expr::getValueKindForType(NTTP->getType()),
228 NTTP->getLocation());
229
230 if (NTTP->isParameterPack())
David Blaikie7a30dc52013-02-21 01:47:18 +0000231 E = new (Context) PackExpansionExpr(Context.DependentTy, E,
232 NTTP->getLocation(), None);
Douglas Gregor43669f82011-03-05 17:54:25 +0000233 Arg = TemplateArgument(E);
234 } else {
235 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
236 if (TTP->isParameterPack())
David Blaikie05785d12013-02-20 22:23:23 +0000237 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
Douglas Gregor43669f82011-03-05 17:54:25 +0000238 else
239 Arg = TemplateArgument(TemplateName(TTP));
240 }
241
242 if ((*Param)->isTemplateParameterPack())
243 Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
244
245 *Args++ = Arg;
246 }
247}
248
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000249//===----------------------------------------------------------------------===//
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000250// FunctionTemplateDecl Implementation
251//===----------------------------------------------------------------------===//
252
Douglas Gregor1a809332010-05-23 18:26:36 +0000253void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
254 static_cast<Common *>(Ptr)->~Common();
255}
256
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000257FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
258 DeclContext *DC,
259 SourceLocation L,
260 DeclarationName Name,
Douglas Gregor8f5d4422009-06-29 20:59:39 +0000261 TemplateParameterList *Params,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000262 NamedDecl *Decl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000263 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Richard Smith053f6c62014-05-16 23:01:30 +0000264 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000265}
266
Douglas Gregor72172e92012-01-05 21:55:30 +0000267FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
268 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000269 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000270 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000271}
272
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000273RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000274FunctionTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000275 Common *CommonPtr = new (C) Common;
276 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000277 return CommonPtr;
278}
279
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000280void FunctionTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000281 // Grab the most recent declaration to ensure we've loaded any lazy
282 // redeclarations of this template.
283 //
284 // FIXME: Avoid walking the entire redeclaration chain here.
285 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000286 if (CommonPtr->LazySpecializations) {
287 ASTContext &Context = getASTContext();
288 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000289 CommonPtr->LazySpecializations = nullptr;
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000290 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
291 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
292 }
293}
294
295llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
296FunctionTemplateDecl::getSpecializations() const {
297 LoadLazySpecializations();
298 return getCommonPtr()->Specializations;
299}
300
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000301FunctionDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000302FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
303 void *&InsertPos) {
304 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000305}
306
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000307void FunctionTemplateDecl::addSpecialization(
308 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000309 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
310 InsertPos);
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000311}
312
Richard Smith841d8b22013-05-17 03:04:50 +0000313ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
Douglas Gregor43669f82011-03-05 17:54:25 +0000314 TemplateParameterList *Params = getTemplateParameters();
315 Common *CommonPtr = getCommonPtr();
316 if (!CommonPtr->InjectedArgs) {
317 CommonPtr->InjectedArgs
Richard Smith841d8b22013-05-17 03:04:50 +0000318 = new (getASTContext()) TemplateArgument[Params->size()];
319 GenerateInjectedTemplateArgs(getASTContext(), Params,
Douglas Gregor43669f82011-03-05 17:54:25 +0000320 CommonPtr->InjectedArgs);
321 }
Richard Smith841d8b22013-05-17 03:04:50 +0000322
323 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
Douglas Gregor43669f82011-03-05 17:54:25 +0000324}
325
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000326//===----------------------------------------------------------------------===//
327// ClassTemplateDecl Implementation
328//===----------------------------------------------------------------------===//
329
Douglas Gregor1a809332010-05-23 18:26:36 +0000330void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
331 static_cast<Common *>(Ptr)->~Common();
332}
333
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000334ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
335 DeclContext *DC,
336 SourceLocation L,
337 DeclarationName Name,
338 TemplateParameterList *Params,
Douglas Gregor90a1a652009-03-19 17:26:29 +0000339 NamedDecl *Decl,
340 ClassTemplateDecl *PrevDecl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000341 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Richard Smith053f6c62014-05-16 23:01:30 +0000342 ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
343 Params, Decl);
Rafael Espindola8db352d2013-10-17 15:37:26 +0000344 New->setPreviousDecl(PrevDecl);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +0000345 return New;
Douglas Gregor90a1a652009-03-19 17:26:29 +0000346}
347
Richard Smith053f6c62014-05-16 23:01:30 +0000348ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000349 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000350 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
351 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000352}
353
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000354void ClassTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000355 // Grab the most recent declaration to ensure we've loaded any lazy
356 // redeclarations of this template.
357 //
358 // FIXME: Avoid walking the entire redeclaration chain here.
359 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000360 if (CommonPtr->LazySpecializations) {
361 ASTContext &Context = getASTContext();
362 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000363 CommonPtr->LazySpecializations = nullptr;
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000364 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
365 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
366 }
367}
368
Chandler Carruthb41171b2012-05-03 23:49:05 +0000369llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000370ClassTemplateDecl::getSpecializations() const {
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000371 LoadLazySpecializations();
372 return getCommonPtr()->Specializations;
373}
374
Chandler Carruthb41171b2012-05-03 23:49:05 +0000375llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000376ClassTemplateDecl::getPartialSpecializations() {
377 LoadLazySpecializations();
378 return getCommonPtr()->PartialSpecializations;
379}
380
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000381RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000382ClassTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000383 Common *CommonPtr = new (C) Common;
384 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000385 return CommonPtr;
386}
387
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000388ClassTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000389ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
390 void *&InsertPos) {
391 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000392}
393
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000394void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
395 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000396 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000397}
398
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000399ClassTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000400ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000401 void *&InsertPos) {
Craig Topper7e0daca2014-06-26 04:58:53 +0000402 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000403}
404
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000405void ClassTemplateDecl::AddPartialSpecialization(
406 ClassTemplatePartialSpecializationDecl *D,
407 void *InsertPos) {
Douglas Gregorce9978f2012-03-28 14:34:23 +0000408 if (InsertPos)
409 getPartialSpecializations().InsertNode(D, InsertPos);
410 else {
411 ClassTemplatePartialSpecializationDecl *Existing
412 = getPartialSpecializations().GetOrInsertNode(D);
413 (void)Existing;
414 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
415 }
416
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000417 if (ASTMutationListener *L = getASTMutationListener())
418 L->AddedCXXTemplateSpecialization(this, D);
419}
420
Douglas Gregor407e9612010-04-30 05:56:50 +0000421void ClassTemplateDecl::getPartialSpecializations(
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000422 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
Chandler Carruthb41171b2012-05-03 23:49:05 +0000423 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000424 = getPartialSpecializations();
Douglas Gregor407e9612010-04-30 05:56:50 +0000425 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +0000426 PS.reserve(PartialSpecs.size());
Chandler Carruthb41171b2012-05-03 23:49:05 +0000427 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregor407e9612010-04-30 05:56:50 +0000428 P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
Richard Smithb2f61b42013-08-22 23:27:37 +0000429 P != PEnd; ++P)
430 PS.push_back(P->getMostRecentDecl());
Douglas Gregor407e9612010-04-30 05:56:50 +0000431}
432
Douglas Gregor15301382009-07-30 17:40:51 +0000433ClassTemplatePartialSpecializationDecl *
434ClassTemplateDecl::findPartialSpecialization(QualType T) {
435 ASTContext &Context = getASTContext();
Chandler Carruthb41171b2012-05-03 23:49:05 +0000436 using llvm::FoldingSetVector;
437 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregor15301382009-07-30 17:40:51 +0000438 partial_spec_iterator;
439 for (partial_spec_iterator P = getPartialSpecializations().begin(),
440 PEnd = getPartialSpecializations().end();
441 P != PEnd; ++P) {
John McCall2408e322010-04-27 00:57:59 +0000442 if (Context.hasSameType(P->getInjectedSpecializationType(), T))
Douglas Gregorec9fd132012-01-14 16:38:05 +0000443 return P->getMostRecentDecl();
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000444 }
445
Craig Topper36250ad2014-05-12 05:36:57 +0000446 return nullptr;
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000447}
448
449ClassTemplatePartialSpecializationDecl *
450ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
451 ClassTemplatePartialSpecializationDecl *D) {
452 Decl *DCanon = D->getCanonicalDecl();
Chandler Carruthb41171b2012-05-03 23:49:05 +0000453 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000454 P = getPartialSpecializations().begin(),
455 PEnd = getPartialSpecializations().end();
456 P != PEnd; ++P) {
457 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
Douglas Gregorec9fd132012-01-14 16:38:05 +0000458 return P->getMostRecentDecl();
Douglas Gregor15301382009-07-30 17:40:51 +0000459 }
Mike Stump11289f42009-09-09 15:08:12 +0000460
Craig Topper36250ad2014-05-12 05:36:57 +0000461 return nullptr;
Douglas Gregor15301382009-07-30 17:40:51 +0000462}
463
John McCalle78aac42010-03-10 03:28:59 +0000464QualType
Douglas Gregor9961ce92010-07-08 18:37:38 +0000465ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000466 Common *CommonPtr = getCommonPtr();
Douglas Gregore362cea2009-05-10 22:57:19 +0000467 if (!CommonPtr->InjectedClassNameType.isNull())
468 return CommonPtr->InjectedClassNameType;
469
Douglas Gregor8092e802010-12-23 16:00:30 +0000470 // C++0x [temp.dep.type]p2:
471 // The template argument list of a primary template is a template argument
472 // list in which the nth template argument has the value of the nth template
473 // parameter of the class template. If the nth template parameter is a
474 // template parameter pack (14.5.3), the nth template argument is a pack
475 // expansion (14.5.3) whose pattern is the name of the template parameter
476 // pack.
Douglas Gregor9961ce92010-07-08 18:37:38 +0000477 ASTContext &Context = getASTContext();
Douglas Gregore362cea2009-05-10 22:57:19 +0000478 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000479 SmallVector<TemplateArgument, 16> TemplateArgs;
Douglas Gregor43669f82011-03-05 17:54:25 +0000480 TemplateArgs.resize(Params->size());
481 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
Douglas Gregore362cea2009-05-10 22:57:19 +0000482 CommonPtr->InjectedClassNameType
Douglas Gregora8e02e72009-07-28 23:00:59 +0000483 = Context.getTemplateSpecializationType(TemplateName(this),
Douglas Gregore362cea2009-05-10 22:57:19 +0000484 &TemplateArgs[0],
Douglas Gregora8e02e72009-07-28 23:00:59 +0000485 TemplateArgs.size());
Douglas Gregore362cea2009-05-10 22:57:19 +0000486 return CommonPtr->InjectedClassNameType;
487}
488
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000489//===----------------------------------------------------------------------===//
490// TemplateTypeParm Allocation/Deallocation Method Implementations
491//===----------------------------------------------------------------------===//
492
493TemplateTypeParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000494TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000495 SourceLocation KeyLoc, SourceLocation NameLoc,
496 unsigned D, unsigned P, IdentifierInfo *Id,
497 bool Typename, bool ParameterPack) {
Chandler Carruth08836322011-05-01 00:51:33 +0000498 TemplateTypeParmDecl *TTPDecl =
Richard Smithf7981722013-11-22 09:01:48 +0000499 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
Chandler Carruth08836322011-05-01 00:51:33 +0000500 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
Richard Smith5b21db82014-04-23 18:20:42 +0000501 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
Chandler Carruth08836322011-05-01 00:51:33 +0000502 return TTPDecl;
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000503}
504
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000505TemplateTypeParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000506TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000507 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
508 SourceLocation(), nullptr, false);
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000509}
510
John McCall0ad16662009-10-29 08:12:44 +0000511SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara23485e02011-03-04 12:42:03 +0000512 return hasDefaultArgument()
Richard Smith1469b912015-06-10 00:29:03 +0000513 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
514 : SourceLocation();
Abramo Bagnara23485e02011-03-04 12:42:03 +0000515}
516
517SourceRange TemplateTypeParmDecl::getSourceRange() const {
518 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000519 return SourceRange(getLocStart(),
Richard Smith1469b912015-06-10 00:29:03 +0000520 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
Abramo Bagnara23485e02011-03-04 12:42:03 +0000521 else
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000522 return TypeDecl::getSourceRange();
John McCall0ad16662009-10-29 08:12:44 +0000523}
524
Douglas Gregor21610382009-10-29 00:04:11 +0000525unsigned TemplateTypeParmDecl::getDepth() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000526 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
Douglas Gregor21610382009-10-29 00:04:11 +0000527}
528
529unsigned TemplateTypeParmDecl::getIndex() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000530 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
Douglas Gregor21610382009-10-29 00:04:11 +0000531}
532
Chandler Carruth08836322011-05-01 00:51:33 +0000533bool TemplateTypeParmDecl::isParameterPack() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000534 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
Chandler Carruth08836322011-05-01 00:51:33 +0000535}
536
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000537//===----------------------------------------------------------------------===//
538// NonTypeTemplateParmDecl Method Implementations
539//===----------------------------------------------------------------------===//
540
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000541NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000542 SourceLocation StartLoc,
543 SourceLocation IdLoc,
544 unsigned D, unsigned P,
545 IdentifierInfo *Id,
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000546 QualType T,
547 TypeSourceInfo *TInfo,
548 const QualType *ExpandedTypes,
549 unsigned NumExpandedTypes,
550 TypeSourceInfo **ExpandedTInfos)
Abramo Bagnaradff19302011-03-08 08:55:46 +0000551 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
Richard Smith1469b912015-06-10 00:29:03 +0000552 TemplateParmPosition(D, P), ParameterPack(true),
553 ExpandedParameterPack(true), NumExpandedTypes(NumExpandedTypes) {
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000554 if (ExpandedTypes && ExpandedTInfos) {
555 void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
556 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
557 TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
558 TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
559 }
560 }
561}
562
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000563NonTypeTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000564NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000565 SourceLocation StartLoc, SourceLocation IdLoc,
566 unsigned D, unsigned P, IdentifierInfo *Id,
567 QualType T, bool ParameterPack,
568 TypeSourceInfo *TInfo) {
Richard Smithf7981722013-11-22 09:01:48 +0000569 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
570 T, ParameterPack, TInfo);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000571}
572
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000573NonTypeTemplateParmDecl *
574NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000575 SourceLocation StartLoc, SourceLocation IdLoc,
576 unsigned D, unsigned P,
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000577 IdentifierInfo *Id, QualType T,
578 TypeSourceInfo *TInfo,
579 const QualType *ExpandedTypes,
580 unsigned NumExpandedTypes,
581 TypeSourceInfo **ExpandedTInfos) {
Richard Smithf7981722013-11-22 09:01:48 +0000582 unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
583 return new (C, DC, Extra) NonTypeTemplateParmDecl(
584 DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
585 ExpandedTypes, NumExpandedTypes, ExpandedTInfos);
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000586}
587
Douglas Gregor72172e92012-01-05 21:55:30 +0000588NonTypeTemplateParmDecl *
589NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000590 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
591 SourceLocation(), 0, 0, nullptr,
592 QualType(), false, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000593}
594
595NonTypeTemplateParmDecl *
596NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
597 unsigned NumExpandedTypes) {
Richard Smithf7981722013-11-22 09:01:48 +0000598 unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
599 return new (C, ID, Extra) NonTypeTemplateParmDecl(
Craig Topper36250ad2014-05-12 05:36:57 +0000600 nullptr, SourceLocation(), SourceLocation(), 0, 0, nullptr, QualType(),
601 nullptr, nullptr, NumExpandedTypes, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000602}
603
John McCallf4cd4f92011-02-09 01:13:10 +0000604SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnarae15d5532011-03-04 11:03:48 +0000605 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraea947882011-03-08 16:41:52 +0000606 return SourceRange(getOuterLocStart(),
607 getDefaultArgument()->getSourceRange().getEnd());
608 return DeclaratorDecl::getSourceRange();
John McCallf4cd4f92011-02-09 01:13:10 +0000609}
610
Douglas Gregordba32632009-02-10 19:49:53 +0000611SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara656e3002010-06-09 09:26:05 +0000612 return hasDefaultArgument()
613 ? getDefaultArgument()->getSourceRange().getBegin()
614 : SourceLocation();
Douglas Gregordba32632009-02-10 19:49:53 +0000615}
616
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000617//===----------------------------------------------------------------------===//
618// TemplateTemplateParmDecl Method Implementations
619//===----------------------------------------------------------------------===//
620
David Blaikie68e081d2011-12-20 02:48:34 +0000621void TemplateTemplateParmDecl::anchor() { }
622
Richard Smith1fde8ec2012-09-07 02:06:42 +0000623TemplateTemplateParmDecl::TemplateTemplateParmDecl(
624 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
625 IdentifierInfo *Id, TemplateParameterList *Params,
626 unsigned NumExpansions, TemplateParameterList * const *Expansions)
627 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
Richard Smith1469b912015-06-10 00:29:03 +0000628 TemplateParmPosition(D, P), ParameterPack(true),
Richard Smith1fde8ec2012-09-07 02:06:42 +0000629 ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
630 if (Expansions)
631 std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
632 sizeof(TemplateParameterList*) * NumExpandedParams);
633}
634
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000635TemplateTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000636TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000637 SourceLocation L, unsigned D, unsigned P,
Douglas Gregorf5500772011-01-05 15:48:55 +0000638 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000639 TemplateParameterList *Params) {
Richard Smithf7981722013-11-22 09:01:48 +0000640 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
641 Params);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000642}
643
Douglas Gregor72172e92012-01-05 21:55:30 +0000644TemplateTemplateParmDecl *
Richard Smith1fde8ec2012-09-07 02:06:42 +0000645TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
646 SourceLocation L, unsigned D, unsigned P,
647 IdentifierInfo *Id,
648 TemplateParameterList *Params,
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000649 ArrayRef<TemplateParameterList *> Expansions) {
Richard Smithf7981722013-11-22 09:01:48 +0000650 return new (C, DC, sizeof(TemplateParameterList*) * Expansions.size())
651 TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
652 Expansions.size(), Expansions.data());
Richard Smith1fde8ec2012-09-07 02:06:42 +0000653}
654
655TemplateTemplateParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000656TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000657 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
658 false, nullptr, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000659}
660
Richard Smith1fde8ec2012-09-07 02:06:42 +0000661TemplateTemplateParmDecl *
662TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
663 unsigned NumExpansions) {
Richard Smithf7981722013-11-22 09:01:48 +0000664 return new (C, ID, sizeof(TemplateParameterList*) * NumExpansions)
Craig Topper36250ad2014-05-12 05:36:57 +0000665 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
666 nullptr, NumExpansions, nullptr);
Richard Smith1fde8ec2012-09-07 02:06:42 +0000667}
668
Richard Smith35c1df52015-06-17 20:16:32 +0000669SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
670 return hasDefaultArgument() ? getDefaultArgument().getLocation()
671 : SourceLocation();
672}
673
Richard Smith1469b912015-06-10 00:29:03 +0000674void TemplateTemplateParmDecl::setDefaultArgument(
675 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
676 if (DefArg.getArgument().isNull())
677 DefaultArgument.set(nullptr);
678 else
679 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
680}
681
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000682//===----------------------------------------------------------------------===//
Douglas Gregord002c7b2009-05-11 23:53:27 +0000683// TemplateArgumentList Implementation
684//===----------------------------------------------------------------------===//
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000685TemplateArgumentList *
686TemplateArgumentList::CreateCopy(ASTContext &Context,
687 const TemplateArgument *Args,
688 unsigned NumArgs) {
689 std::size_t Size = sizeof(TemplateArgumentList)
690 + NumArgs * sizeof(TemplateArgument);
691 void *Mem = Context.Allocate(Size);
692 TemplateArgument *StoredArgs
693 = reinterpret_cast<TemplateArgument *>(
694 static_cast<TemplateArgumentList *>(Mem) + 1);
695 std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
696 return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000697}
698
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000699FunctionTemplateSpecializationInfo *
700FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
701 FunctionTemplateDecl *Template,
702 TemplateSpecializationKind TSK,
703 const TemplateArgumentList *TemplateArgs,
704 const TemplateArgumentListInfo *TemplateArgsAsWritten,
705 SourceLocation POI) {
Craig Topper36250ad2014-05-12 05:36:57 +0000706 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000707 if (TemplateArgsAsWritten)
708 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
709 *TemplateArgsAsWritten);
710
711 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
712 TemplateArgs,
713 ArgsAsWritten,
714 POI);
715}
716
Douglas Gregord002c7b2009-05-11 23:53:27 +0000717//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000718// TemplateDecl Implementation
719//===----------------------------------------------------------------------===//
720
721void TemplateDecl::anchor() { }
722
723//===----------------------------------------------------------------------===//
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000724// ClassTemplateSpecializationDecl Implementation
725//===----------------------------------------------------------------------===//
726ClassTemplateSpecializationDecl::
Douglas Gregore9029562010-05-06 00:28:52 +0000727ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000728 DeclContext *DC, 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 Gregorb6b8f9e2009-07-29 23:36:44 +0000733 ClassTemplateSpecializationDecl *PrevDecl)
Richard Smith053f6c62014-05-16 23:01:30 +0000734 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000735 SpecializedTemplate->getIdentifier(),
736 PrevDecl),
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000737 SpecializedTemplate(SpecializedTemplate),
Craig Topper36250ad2014-05-12 05:36:57 +0000738 ExplicitInfo(nullptr),
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000739 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
Douglas Gregord002c7b2009-05-11 23:53:27 +0000740 SpecializationKind(TSK_Undeclared) {
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000741}
Mike Stump11289f42009-09-09 15:08:12 +0000742
Richard Smith053f6c62014-05-16 23:01:30 +0000743ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
744 Kind DK)
745 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
746 SourceLocation(), nullptr, nullptr),
747 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000748
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000749ClassTemplateSpecializationDecl *
Douglas Gregore9029562010-05-06 00:28:52 +0000750ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000751 DeclContext *DC,
752 SourceLocation StartLoc,
753 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000754 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000755 const TemplateArgument *Args,
756 unsigned NumArgs,
Douglas Gregor67a65642009-02-17 23:15:12 +0000757 ClassTemplateSpecializationDecl *PrevDecl) {
Richard Smithf7981722013-11-22 09:01:48 +0000758 ClassTemplateSpecializationDecl *Result =
759 new (Context, DC) ClassTemplateSpecializationDecl(
760 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
761 SpecializedTemplate, Args, NumArgs, PrevDecl);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000762 Result->MayHaveOutOfDateDef = false;
763
Douglas Gregor67a65642009-02-17 23:15:12 +0000764 Context.getTypeDeclType(Result, PrevDecl);
765 return Result;
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000766}
Douglas Gregor2373c592009-05-31 09:31:02 +0000767
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000768ClassTemplateSpecializationDecl *
Richard Smithf7981722013-11-22 09:01:48 +0000769ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000770 unsigned ID) {
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000771 ClassTemplateSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000772 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000773 Result->MayHaveOutOfDateDef = false;
774 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000775}
776
Benjamin Kramer9170e912013-02-22 15:46:01 +0000777void ClassTemplateSpecializationDecl::getNameForDiagnostic(
778 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
779 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000780
781 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Benjamin Kramer9170e912013-02-22 15:46:01 +0000782 TemplateSpecializationType::PrintTemplateArgumentList(
783 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000784}
785
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000786ClassTemplateDecl *
Mike Stump11289f42009-09-09 15:08:12 +0000787ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
788 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000789 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
790 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
791 return SpecializedTemplate.get<ClassTemplateDecl*>();
792}
793
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000794SourceRange
795ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000796 if (ExplicitInfo) {
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000797 SourceLocation Begin = getTemplateKeywordLoc();
798 if (Begin.isValid()) {
799 // Here we have an explicit (partial) specialization or instantiation.
800 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
801 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
802 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
803 if (getExternLoc().isValid())
804 Begin = getExternLoc();
805 SourceLocation End = getRBraceLoc();
806 if (End.isInvalid())
807 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
808 return SourceRange(Begin, End);
809 }
810 // An implicit instantiation of a class template partial specialization
811 // uses ExplicitInfo to record the TypeAsWritten, but the source
812 // locations should be retrieved from the instantiation pattern.
813 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
814 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
815 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
Craig Topper36250ad2014-05-12 05:36:57 +0000816 assert(inst_from != nullptr);
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000817 return inst_from->getSourceRange();
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000818 }
819 else {
820 // No explicit info available.
821 llvm::PointerUnion<ClassTemplateDecl *,
822 ClassTemplatePartialSpecializationDecl *>
823 inst_from = getInstantiatedFrom();
824 if (inst_from.isNull())
825 return getSpecializedTemplate()->getSourceRange();
826 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
827 return ctd->getSourceRange();
828 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
829 ->getSourceRange();
830 }
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000831}
832
Douglas Gregor2373c592009-05-31 09:31:02 +0000833//===----------------------------------------------------------------------===//
834// ClassTemplatePartialSpecializationDecl Implementation
835//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000836void ClassTemplatePartialSpecializationDecl::anchor() { }
837
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000838ClassTemplatePartialSpecializationDecl::
839ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000840 DeclContext *DC,
841 SourceLocation StartLoc,
842 SourceLocation IdLoc,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000843 TemplateParameterList *Params,
844 ClassTemplateDecl *SpecializedTemplate,
845 const TemplateArgument *Args,
846 unsigned NumArgs,
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000847 const ASTTemplateArgumentListInfo *ArgInfos,
Richard Smithb2f61b42013-08-22 23:27:37 +0000848 ClassTemplatePartialSpecializationDecl *PrevDecl)
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000849 : ClassTemplateSpecializationDecl(Context,
850 ClassTemplatePartialSpecialization,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000851 TK, DC, StartLoc, IdLoc,
852 SpecializedTemplate,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000853 Args, NumArgs, PrevDecl),
854 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +0000855 InstantiatedFromMember(nullptr, false)
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000856{
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000857 AdoptTemplateParameterList(Params, this);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000858}
859
Douglas Gregor2373c592009-05-31 09:31:02 +0000860ClassTemplatePartialSpecializationDecl *
861ClassTemplatePartialSpecializationDecl::
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000862Create(ASTContext &Context, TagKind TK,DeclContext *DC,
863 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregor2373c592009-05-31 09:31:02 +0000864 TemplateParameterList *Params,
865 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000866 const TemplateArgument *Args,
867 unsigned NumArgs,
John McCall6b51f282009-11-23 01:53:49 +0000868 const TemplateArgumentListInfo &ArgInfos,
John McCalle78aac42010-03-10 03:28:59 +0000869 QualType CanonInjectedType,
Richard Smithb2f61b42013-08-22 23:27:37 +0000870 ClassTemplatePartialSpecializationDecl *PrevDecl) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000871 const ASTTemplateArgumentListInfo *ASTArgInfos =
872 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
John McCall0ad16662009-10-29 08:12:44 +0000873
Richard Smithf7981722013-11-22 09:01:48 +0000874 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
875 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
876 Params, SpecializedTemplate, Args,
877 NumArgs, ASTArgInfos, PrevDecl);
Douglas Gregor2373c592009-05-31 09:31:02 +0000878 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000879 Result->MayHaveOutOfDateDef = false;
John McCalle78aac42010-03-10 03:28:59 +0000880
881 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregor2373c592009-05-31 09:31:02 +0000882 return Result;
883}
John McCall11083da2009-09-16 22:47:08 +0000884
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000885ClassTemplatePartialSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000886ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
887 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000888 ClassTemplatePartialSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000889 new (C, ID) ClassTemplatePartialSpecializationDecl(C);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000890 Result->MayHaveOutOfDateDef = false;
891 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000892}
893
John McCall11083da2009-09-16 22:47:08 +0000894//===----------------------------------------------------------------------===//
895// FriendTemplateDecl Implementation
896//===----------------------------------------------------------------------===//
897
David Blaikie68e081d2011-12-20 02:48:34 +0000898void FriendTemplateDecl::anchor() { }
899
John McCall11083da2009-09-16 22:47:08 +0000900FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
901 DeclContext *DC,
902 SourceLocation L,
903 unsigned NParams,
904 TemplateParameterList **Params,
905 FriendUnion Friend,
906 SourceLocation FLoc) {
Richard Smithf7981722013-11-22 09:01:48 +0000907 return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params,
908 Friend, FLoc);
John McCall11083da2009-09-16 22:47:08 +0000909}
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000910
Douglas Gregor72172e92012-01-05 21:55:30 +0000911FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
912 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000913 return new (C, ID) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000914}
Richard Smith3f1b5d02011-05-05 21:57:07 +0000915
916//===----------------------------------------------------------------------===//
917// TypeAliasTemplateDecl Implementation
918//===----------------------------------------------------------------------===//
919
920TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
921 DeclContext *DC,
922 SourceLocation L,
923 DeclarationName Name,
924 TemplateParameterList *Params,
925 NamedDecl *Decl) {
926 AdoptTemplateParameterList(Params, DC);
Richard Smith053f6c62014-05-16 23:01:30 +0000927 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000928}
929
Douglas Gregor72172e92012-01-05 21:55:30 +0000930TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
931 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000932 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000933 DeclarationName(), nullptr, nullptr);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000934}
935
936void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
937 static_cast<Common *>(Ptr)->~Common();
938}
939RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000940TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3f1b5d02011-05-05 21:57:07 +0000941 Common *CommonPtr = new (C) Common;
942 C.AddDeallocation(DeallocateCommon, CommonPtr);
943 return CommonPtr;
944}
945
David Blaikie68e081d2011-12-20 02:48:34 +0000946//===----------------------------------------------------------------------===//
947// ClassScopeFunctionSpecializationDecl Implementation
948//===----------------------------------------------------------------------===//
949
950void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor72172e92012-01-05 21:55:30 +0000951
952ClassScopeFunctionSpecializationDecl *
953ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
954 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000955 return new (C, ID) ClassScopeFunctionSpecializationDecl(
Craig Topper36250ad2014-05-12 05:36:57 +0000956 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
Douglas Gregor72172e92012-01-05 21:55:30 +0000957}
Larisse Voufo39a1e502013-08-06 01:03:05 +0000958
959//===----------------------------------------------------------------------===//
960// VarTemplateDecl Implementation
961//===----------------------------------------------------------------------===//
962
963void VarTemplateDecl::DeallocateCommon(void *Ptr) {
964 static_cast<Common *>(Ptr)->~Common();
965}
966
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000967VarTemplateDecl *VarTemplateDecl::getDefinition() {
968 VarTemplateDecl *CurD = this;
969 while (CurD) {
970 if (CurD->isThisDeclarationADefinition())
971 return CurD;
972 CurD = CurD->getPreviousDecl();
973 }
Craig Topper36250ad2014-05-12 05:36:57 +0000974 return nullptr;
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000975}
976
Larisse Voufo39a1e502013-08-06 01:03:05 +0000977VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
978 SourceLocation L, DeclarationName Name,
979 TemplateParameterList *Params,
Richard Smithbeef3452014-01-16 23:39:20 +0000980 VarDecl *Decl) {
Richard Smith053f6c62014-05-16 23:01:30 +0000981 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000982}
983
984VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
985 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000986 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
987 DeclarationName(), nullptr, nullptr);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000988}
989
Alp Tokerf6a24ce2013-12-05 16:25:25 +0000990// TODO: Unify across class, function and variable templates?
Larisse Voufo30616382013-08-23 22:21:36 +0000991// May require moving this and Common to RedeclarableTemplateDecl.
Larisse Voufo39a1e502013-08-06 01:03:05 +0000992void VarTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000993 // Grab the most recent declaration to ensure we've loaded any lazy
994 // redeclarations of this template.
995 //
996 // FIXME: Avoid walking the entire redeclaration chain here.
997 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Larisse Voufo39a1e502013-08-06 01:03:05 +0000998 if (CommonPtr->LazySpecializations) {
999 ASTContext &Context = getASTContext();
1000 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +00001001 CommonPtr->LazySpecializations = nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +00001002 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
1003 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
1004 }
1005}
1006
1007llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1008VarTemplateDecl::getSpecializations() const {
1009 LoadLazySpecializations();
1010 return getCommonPtr()->Specializations;
1011}
1012
1013llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1014VarTemplateDecl::getPartialSpecializations() {
1015 LoadLazySpecializations();
1016 return getCommonPtr()->PartialSpecializations;
1017}
1018
1019RedeclarableTemplateDecl::CommonBase *
1020VarTemplateDecl::newCommon(ASTContext &C) const {
1021 Common *CommonPtr = new (C) Common;
1022 C.AddDeallocation(DeallocateCommon, CommonPtr);
1023 return CommonPtr;
1024}
1025
1026VarTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +00001027VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1028 void *&InsertPos) {
1029 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001030}
1031
1032void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1033 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +00001034 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001035}
1036
1037VarTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +00001038VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1039 void *&InsertPos) {
1040 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001041}
1042
1043void VarTemplateDecl::AddPartialSpecialization(
1044 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1045 if (InsertPos)
1046 getPartialSpecializations().InsertNode(D, InsertPos);
1047 else {
1048 VarTemplatePartialSpecializationDecl *Existing =
1049 getPartialSpecializations().GetOrInsertNode(D);
1050 (void)Existing;
1051 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1052 }
1053
1054 if (ASTMutationListener *L = getASTMutationListener())
1055 L->AddedCXXTemplateSpecialization(this, D);
1056}
1057
1058void VarTemplateDecl::getPartialSpecializations(
1059 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1060 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1061 getPartialSpecializations();
1062 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +00001063 PS.reserve(PartialSpecs.size());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001064 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1065 P = PartialSpecs.begin(),
1066 PEnd = PartialSpecs.end();
Richard Smithb2f61b42013-08-22 23:27:37 +00001067 P != PEnd; ++P)
1068 PS.push_back(P->getMostRecentDecl());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001069}
1070
1071VarTemplatePartialSpecializationDecl *
1072VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1073 VarTemplatePartialSpecializationDecl *D) {
1074 Decl *DCanon = D->getCanonicalDecl();
1075 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1076 P = getPartialSpecializations().begin(),
1077 PEnd = getPartialSpecializations().end();
1078 P != PEnd; ++P) {
1079 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1080 return P->getMostRecentDecl();
1081 }
1082
Craig Topper36250ad2014-05-12 05:36:57 +00001083 return nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +00001084}
1085
1086//===----------------------------------------------------------------------===//
1087// VarTemplateSpecializationDecl Implementation
1088//===----------------------------------------------------------------------===//
1089VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001090 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001091 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1092 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1093 unsigned NumArgs)
Richard Smith053f6c62014-05-16 23:01:30 +00001094 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1095 SpecializedTemplate->getIdentifier(), T, TInfo, S),
Craig Topper36250ad2014-05-12 05:36:57 +00001096 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001097 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
1098 SpecializationKind(TSK_Undeclared) {}
1099
Richard Smith053f6c62014-05-16 23:01:30 +00001100VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1101 ASTContext &C)
1102 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
Craig Topper36250ad2014-05-12 05:36:57 +00001103 QualType(), nullptr, SC_None),
1104 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Larisse Voufo39a1e502013-08-06 01:03:05 +00001105
1106VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1107 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1108 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1109 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1110 unsigned NumArgs) {
Richard Smithf7981722013-11-22 09:01:48 +00001111 return new (Context, DC) VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001112 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
Richard Smithf7981722013-11-22 09:01:48 +00001113 SpecializedTemplate, T, TInfo, S, Args, NumArgs);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001114}
1115
1116VarTemplateSpecializationDecl *
1117VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001118 return new (C, ID)
1119 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001120}
1121
1122void VarTemplateSpecializationDecl::getNameForDiagnostic(
1123 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1124 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1125
1126 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1127 TemplateSpecializationType::PrintTemplateArgumentList(
1128 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
1129}
1130
1131VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1132 if (SpecializedPartialSpecialization *PartialSpec =
1133 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1134 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1135 return SpecializedTemplate.get<VarTemplateDecl *>();
1136}
1137
1138void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1139 const TemplateArgumentListInfo &ArgsInfo) {
1140 unsigned N = ArgsInfo.size();
1141 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1142 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1143 for (unsigned I = 0; I != N; ++I)
1144 TemplateArgsInfo.addArgument(ArgsInfo[I]);
1145}
1146
1147//===----------------------------------------------------------------------===//
1148// VarTemplatePartialSpecializationDecl Implementation
1149//===----------------------------------------------------------------------===//
1150void VarTemplatePartialSpecializationDecl::anchor() {}
1151
1152VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1153 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1154 SourceLocation IdLoc, TemplateParameterList *Params,
1155 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1156 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
Richard Smithb2f61b42013-08-22 23:27:37 +00001157 const ASTTemplateArgumentListInfo *ArgInfos)
Richard Smith053f6c62014-05-16 23:01:30 +00001158 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001159 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1160 TInfo, S, Args, NumArgs),
1161 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +00001162 InstantiatedFromMember(nullptr, false) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001163 // TODO: The template parameters should be in DC by now. Verify.
1164 // AdoptTemplateParameterList(Params, DC);
1165}
1166
1167VarTemplatePartialSpecializationDecl *
1168VarTemplatePartialSpecializationDecl::Create(
1169 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1170 SourceLocation IdLoc, TemplateParameterList *Params,
1171 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1172 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
Richard Smithb2f61b42013-08-22 23:27:37 +00001173 const TemplateArgumentListInfo &ArgInfos) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +00001174 const ASTTemplateArgumentListInfo *ASTArgInfos
1175 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001176
1177 VarTemplatePartialSpecializationDecl *Result =
Richard Smithf7981722013-11-22 09:01:48 +00001178 new (Context, DC) VarTemplatePartialSpecializationDecl(
Larisse Voufo39a1e502013-08-06 01:03:05 +00001179 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
Richard Smithb2f61b42013-08-22 23:27:37 +00001180 S, Args, NumArgs, ASTArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001181 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1182 return Result;
1183}
1184
1185VarTemplatePartialSpecializationDecl *
1186VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1187 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001188 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001189}