blob: de3ebd23ef4f5d7e363b28ab66321b848c147b1e [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"
David Majnemerd9b1a4f2015-11-04 03:40:30 +000021#include "clang/Basic/Builtins.h"
Douglas Gregorded2d7b2009-02-04 19:02:06 +000022#include "clang/Basic/IdentifierTable.h"
23#include "llvm/ADT/STLExtras.h"
Douglas Gregor1ccc8412010-11-07 23:05:16 +000024#include <memory>
Douglas Gregorded2d7b2009-02-04 19:02:06 +000025using namespace clang;
26
27//===----------------------------------------------------------------------===//
28// TemplateParameterList Implementation
29//===----------------------------------------------------------------------===//
30
Douglas Gregorcd72ba92009-02-06 22:42:48 +000031TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
32 SourceLocation LAngleLoc,
David Majnemer902f8c62015-12-27 07:16:27 +000033 ArrayRef<NamedDecl *> Params,
Douglas Gregorcd72ba92009-02-06 22:42:48 +000034 SourceLocation RAngleLoc)
35 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
David Majnemer902f8c62015-12-27 07:16:27 +000036 NumParams(Params.size()), ContainsUnexpandedParameterPack(false) {
Richard Smith1fde8ec2012-09-07 02:06:42 +000037 assert(this->NumParams == NumParams && "Too many template parameters");
38 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
39 NamedDecl *P = Params[Idx];
40 begin()[Idx] = P;
41
42 if (!P->isTemplateParameterPack()) {
43 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
44 if (NTTP->getType()->containsUnexpandedParameterPack())
45 ContainsUnexpandedParameterPack = true;
46
47 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
48 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
49 ContainsUnexpandedParameterPack = true;
50
51 // FIXME: If a default argument contains an unexpanded parameter pack, the
52 // template parameter list does too.
53 }
54 }
Douglas Gregorded2d7b2009-02-04 19:02:06 +000055}
56
David Majnemer902f8c62015-12-27 07:16:27 +000057TemplateParameterList *TemplateParameterList::Create(
58 const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc,
59 ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc) {
60 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *>(Params.size()),
James Y Knight7a22b242015-08-06 20:26:32 +000061 llvm::alignOf<TemplateParameterList>());
Mike Stump11289f42009-09-09 15:08:12 +000062 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
David Majnemer902f8c62015-12-27 07:16:27 +000063 RAngleLoc);
Douglas Gregorded2d7b2009-02-04 19:02:06 +000064}
65
Douglas Gregorf8f86832009-02-11 18:16:40 +000066unsigned TemplateParameterList::getMinRequiredArguments() const {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000067 unsigned NumRequiredArgs = 0;
68 for (iterator P = const_cast<TemplateParameterList *>(this)->begin(),
69 PEnd = const_cast<TemplateParameterList *>(this)->end();
70 P != PEnd; ++P) {
71 if ((*P)->isTemplateParameterPack()) {
72 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P))
73 if (NTTP->isExpandedParameterPack()) {
74 NumRequiredArgs += NTTP->getNumExpansionTypes();
75 continue;
76 }
77
Douglas Gregorf8f86832009-02-11 18:16:40 +000078 break;
Douglas Gregor0231d8d2011-01-19 20:10:05 +000079 }
80
81 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
82 if (TTP->hasDefaultArgument())
83 break;
84 } else if (NonTypeTemplateParmDecl *NTTP
85 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
86 if (NTTP->hasDefaultArgument())
87 break;
88 } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument())
89 break;
90
91 ++NumRequiredArgs;
Douglas Gregorf8f86832009-02-11 18:16:40 +000092 }
Douglas Gregor0231d8d2011-01-19 20:10:05 +000093
Douglas Gregorf8f86832009-02-11 18:16:40 +000094 return NumRequiredArgs;
95}
96
Douglas Gregor21610382009-10-29 00:04:11 +000097unsigned TemplateParameterList::getDepth() const {
98 if (size() == 0)
99 return 0;
100
101 const NamedDecl *FirstParm = getParam(0);
102 if (const TemplateTypeParmDecl *TTP
103 = dyn_cast<TemplateTypeParmDecl>(FirstParm))
104 return TTP->getDepth();
105 else if (const NonTypeTemplateParmDecl *NTTP
106 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
107 return NTTP->getDepth();
108 else
109 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
110}
111
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000112static void AdoptTemplateParameterList(TemplateParameterList *Params,
113 DeclContext *Owner) {
114 for (TemplateParameterList::iterator P = Params->begin(),
115 PEnd = Params->end();
116 P != PEnd; ++P) {
117 (*P)->setDeclContext(Owner);
118
119 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P))
120 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
121 }
122}
123
Richard Smithe7bd6de2015-06-10 20:30:23 +0000124namespace clang {
125void *allocateDefaultArgStorageChain(const ASTContext &C) {
126 return new (C) char[sizeof(void*) * 2];
127}
128}
129
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000130//===----------------------------------------------------------------------===//
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000131// RedeclarableTemplateDecl Implementation
132//===----------------------------------------------------------------------===//
133
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000134RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000135 if (Common)
136 return Common;
137
138 // Walk the previous-declaration chain until we either find a declaration
139 // with a common pointer or we run out of previous declarations.
140 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
141 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
142 Prev = Prev->getPreviousDecl()) {
143 if (Prev->Common) {
144 Common = Prev->Common;
145 break;
Douglas Gregor68444de2012-01-14 15:13:49 +0000146 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000147
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000148 PrevDecls.push_back(Prev);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000149 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000150
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000151 // If we never found a common pointer, allocate one now.
152 if (!Common) {
153 // FIXME: If any of the declarations is from an AST file, we probably
154 // need an update record to add the common data.
155
156 Common = newCommon(getASTContext());
157 }
158
159 // Update any previous declarations we saw with the common pointer.
160 for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I)
161 PrevDecls[I]->Common = Common;
162
Douglas Gregor68444de2012-01-14 15:13:49 +0000163 return Common;
Peter Collingbourne029fd692010-07-29 16:12:09 +0000164}
165
Richard Smithe977e512015-02-24 01:23:23 +0000166template<class EntryType>
167typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000168RedeclarableTemplateDecl::findSpecializationImpl(
Richard Smithe977e512015-02-24 01:23:23 +0000169 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
170 void *&InsertPos) {
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000171 typedef SpecEntryTraits<EntryType> SETraits;
172 llvm::FoldingSetNodeID ID;
Craig Topper7e0daca2014-06-26 04:58:53 +0000173 EntryType::Profile(ID,Args, getASTContext());
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000174 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
Richard Smithe977e512015-02-24 01:23:23 +0000175 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
176}
177
178template<class Derived, class EntryType>
179void RedeclarableTemplateDecl::addSpecializationImpl(
180 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
181 void *InsertPos) {
182 typedef SpecEntryTraits<EntryType> SETraits;
183 if (InsertPos) {
184#ifndef NDEBUG
185 void *CorrectInsertPos;
186 assert(!findSpecializationImpl(Specializations,
187 SETraits::getTemplateArgs(Entry),
188 CorrectInsertPos) &&
189 InsertPos == CorrectInsertPos &&
190 "given incorrect InsertPos for specialization");
191#endif
192 Specializations.InsertNode(Entry, InsertPos);
193 } else {
194 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
195 (void)Existing;
196 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
197 "non-canonical specialization?");
198 }
199
200 if (ASTMutationListener *L = getASTMutationListener())
201 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
202 SETraits::getDecl(Entry));
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000203}
204
Douglas Gregor43669f82011-03-05 17:54:25 +0000205/// \brief Generate the injected template arguments for the given template
206/// parameter list, e.g., for the injected-class-name of a class template.
207static void GenerateInjectedTemplateArgs(ASTContext &Context,
208 TemplateParameterList *Params,
209 TemplateArgument *Args) {
210 for (TemplateParameterList::iterator Param = Params->begin(),
211 ParamEnd = Params->end();
212 Param != ParamEnd; ++Param) {
213 TemplateArgument Arg;
214 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
215 QualType ArgType = Context.getTypeDeclType(TTP);
216 if (TTP->isParameterPack())
David Blaikie7a30dc52013-02-21 01:47:18 +0000217 ArgType = Context.getPackExpansionType(ArgType, None);
David Blaikie05785d12013-02-20 22:23:23 +0000218
Douglas Gregor43669f82011-03-05 17:54:25 +0000219 Arg = TemplateArgument(ArgType);
220 } else if (NonTypeTemplateParmDecl *NTTP =
221 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
John McCall113bee02012-03-10 09:33:50 +0000222 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
Douglas Gregor43669f82011-03-05 17:54:25 +0000223 NTTP->getType().getNonLValueExprType(Context),
224 Expr::getValueKindForType(NTTP->getType()),
225 NTTP->getLocation());
226
227 if (NTTP->isParameterPack())
David Blaikie7a30dc52013-02-21 01:47:18 +0000228 E = new (Context) PackExpansionExpr(Context.DependentTy, E,
229 NTTP->getLocation(), None);
Douglas Gregor43669f82011-03-05 17:54:25 +0000230 Arg = TemplateArgument(E);
231 } else {
232 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
233 if (TTP->isParameterPack())
David Blaikie05785d12013-02-20 22:23:23 +0000234 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
Douglas Gregor43669f82011-03-05 17:54:25 +0000235 else
236 Arg = TemplateArgument(TemplateName(TTP));
237 }
238
239 if ((*Param)->isTemplateParameterPack())
Benjamin Kramercce63472015-08-05 09:40:22 +0000240 Arg = TemplateArgument::CreatePackCopy(Context, Arg);
241
Douglas Gregor43669f82011-03-05 17:54:25 +0000242 *Args++ = Arg;
243 }
244}
245
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000246//===----------------------------------------------------------------------===//
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000247// FunctionTemplateDecl Implementation
248//===----------------------------------------------------------------------===//
249
Douglas Gregor1a809332010-05-23 18:26:36 +0000250void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
251 static_cast<Common *>(Ptr)->~Common();
252}
253
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000254FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
255 DeclContext *DC,
256 SourceLocation L,
257 DeclarationName Name,
Douglas Gregor8f5d4422009-06-29 20:59:39 +0000258 TemplateParameterList *Params,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000259 NamedDecl *Decl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000260 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Richard Smith053f6c62014-05-16 23:01:30 +0000261 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000262}
263
Douglas Gregor72172e92012-01-05 21:55:30 +0000264FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
265 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000266 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000267 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000268}
269
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000270RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000271FunctionTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000272 Common *CommonPtr = new (C) Common;
273 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000274 return CommonPtr;
275}
276
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000277void FunctionTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000278 // Grab the most recent declaration to ensure we've loaded any lazy
279 // redeclarations of this template.
280 //
281 // FIXME: Avoid walking the entire redeclaration chain here.
282 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000283 if (CommonPtr->LazySpecializations) {
284 ASTContext &Context = getASTContext();
285 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000286 CommonPtr->LazySpecializations = nullptr;
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000287 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
288 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
289 }
290}
291
292llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
293FunctionTemplateDecl::getSpecializations() const {
294 LoadLazySpecializations();
295 return getCommonPtr()->Specializations;
296}
297
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000298FunctionDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000299FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
300 void *&InsertPos) {
301 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000302}
303
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000304void FunctionTemplateDecl::addSpecialization(
305 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000306 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
307 InsertPos);
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000308}
309
Richard Smith841d8b22013-05-17 03:04:50 +0000310ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
Douglas Gregor43669f82011-03-05 17:54:25 +0000311 TemplateParameterList *Params = getTemplateParameters();
312 Common *CommonPtr = getCommonPtr();
313 if (!CommonPtr->InjectedArgs) {
314 CommonPtr->InjectedArgs
Richard Smith841d8b22013-05-17 03:04:50 +0000315 = new (getASTContext()) TemplateArgument[Params->size()];
316 GenerateInjectedTemplateArgs(getASTContext(), Params,
Douglas Gregor43669f82011-03-05 17:54:25 +0000317 CommonPtr->InjectedArgs);
318 }
Richard Smith841d8b22013-05-17 03:04:50 +0000319
320 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
Douglas Gregor43669f82011-03-05 17:54:25 +0000321}
322
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000323//===----------------------------------------------------------------------===//
324// ClassTemplateDecl Implementation
325//===----------------------------------------------------------------------===//
326
Douglas Gregor1a809332010-05-23 18:26:36 +0000327void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
328 static_cast<Common *>(Ptr)->~Common();
329}
330
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000331ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
332 DeclContext *DC,
333 SourceLocation L,
334 DeclarationName Name,
335 TemplateParameterList *Params,
Douglas Gregor90a1a652009-03-19 17:26:29 +0000336 NamedDecl *Decl,
337 ClassTemplateDecl *PrevDecl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000338 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Richard Smith053f6c62014-05-16 23:01:30 +0000339 ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
340 Params, Decl);
Rafael Espindola8db352d2013-10-17 15:37:26 +0000341 New->setPreviousDecl(PrevDecl);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +0000342 return New;
Douglas Gregor90a1a652009-03-19 17:26:29 +0000343}
344
Richard Smith053f6c62014-05-16 23:01:30 +0000345ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000346 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000347 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
348 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000349}
350
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000351void ClassTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000352 // Grab the most recent declaration to ensure we've loaded any lazy
353 // redeclarations of this template.
354 //
355 // FIXME: Avoid walking the entire redeclaration chain here.
356 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000357 if (CommonPtr->LazySpecializations) {
358 ASTContext &Context = getASTContext();
359 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000360 CommonPtr->LazySpecializations = nullptr;
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000361 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
362 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
363 }
364}
365
Chandler Carruthb41171b2012-05-03 23:49:05 +0000366llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000367ClassTemplateDecl::getSpecializations() const {
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000368 LoadLazySpecializations();
369 return getCommonPtr()->Specializations;
370}
371
Chandler Carruthb41171b2012-05-03 23:49:05 +0000372llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000373ClassTemplateDecl::getPartialSpecializations() {
374 LoadLazySpecializations();
375 return getCommonPtr()->PartialSpecializations;
376}
377
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000378RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000379ClassTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000380 Common *CommonPtr = new (C) Common;
381 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000382 return CommonPtr;
383}
384
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000385ClassTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000386ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
387 void *&InsertPos) {
388 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000389}
390
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000391void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
392 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000393 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000394}
395
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000396ClassTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000397ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000398 void *&InsertPos) {
Craig Topper7e0daca2014-06-26 04:58:53 +0000399 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000400}
401
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000402void ClassTemplateDecl::AddPartialSpecialization(
403 ClassTemplatePartialSpecializationDecl *D,
404 void *InsertPos) {
Douglas Gregorce9978f2012-03-28 14:34:23 +0000405 if (InsertPos)
406 getPartialSpecializations().InsertNode(D, InsertPos);
407 else {
408 ClassTemplatePartialSpecializationDecl *Existing
409 = getPartialSpecializations().GetOrInsertNode(D);
410 (void)Existing;
411 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
412 }
413
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000414 if (ASTMutationListener *L = getASTMutationListener())
415 L->AddedCXXTemplateSpecialization(this, D);
416}
417
Douglas Gregor407e9612010-04-30 05:56:50 +0000418void ClassTemplateDecl::getPartialSpecializations(
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000419 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
Chandler Carruthb41171b2012-05-03 23:49:05 +0000420 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000421 = getPartialSpecializations();
Douglas Gregor407e9612010-04-30 05:56:50 +0000422 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +0000423 PS.reserve(PartialSpecs.size());
Chandler Carruthb41171b2012-05-03 23:49:05 +0000424 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregor407e9612010-04-30 05:56:50 +0000425 P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
Richard Smithb2f61b42013-08-22 23:27:37 +0000426 P != PEnd; ++P)
427 PS.push_back(P->getMostRecentDecl());
Douglas Gregor407e9612010-04-30 05:56:50 +0000428}
429
Douglas Gregor15301382009-07-30 17:40:51 +0000430ClassTemplatePartialSpecializationDecl *
431ClassTemplateDecl::findPartialSpecialization(QualType T) {
432 ASTContext &Context = getASTContext();
Chandler Carruthb41171b2012-05-03 23:49:05 +0000433 using llvm::FoldingSetVector;
434 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregor15301382009-07-30 17:40:51 +0000435 partial_spec_iterator;
436 for (partial_spec_iterator P = getPartialSpecializations().begin(),
437 PEnd = getPartialSpecializations().end();
438 P != PEnd; ++P) {
John McCall2408e322010-04-27 00:57:59 +0000439 if (Context.hasSameType(P->getInjectedSpecializationType(), T))
Douglas Gregorec9fd132012-01-14 16:38:05 +0000440 return P->getMostRecentDecl();
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000441 }
442
Craig Topper36250ad2014-05-12 05:36:57 +0000443 return nullptr;
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000444}
445
446ClassTemplatePartialSpecializationDecl *
447ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
448 ClassTemplatePartialSpecializationDecl *D) {
449 Decl *DCanon = D->getCanonicalDecl();
Chandler Carruthb41171b2012-05-03 23:49:05 +0000450 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000451 P = getPartialSpecializations().begin(),
452 PEnd = getPartialSpecializations().end();
453 P != PEnd; ++P) {
454 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
Douglas Gregorec9fd132012-01-14 16:38:05 +0000455 return P->getMostRecentDecl();
Douglas Gregor15301382009-07-30 17:40:51 +0000456 }
Mike Stump11289f42009-09-09 15:08:12 +0000457
Craig Topper36250ad2014-05-12 05:36:57 +0000458 return nullptr;
Douglas Gregor15301382009-07-30 17:40:51 +0000459}
460
John McCalle78aac42010-03-10 03:28:59 +0000461QualType
Douglas Gregor9961ce92010-07-08 18:37:38 +0000462ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000463 Common *CommonPtr = getCommonPtr();
Douglas Gregore362cea2009-05-10 22:57:19 +0000464 if (!CommonPtr->InjectedClassNameType.isNull())
465 return CommonPtr->InjectedClassNameType;
466
Douglas Gregor8092e802010-12-23 16:00:30 +0000467 // C++0x [temp.dep.type]p2:
468 // The template argument list of a primary template is a template argument
469 // list in which the nth template argument has the value of the nth template
470 // parameter of the class template. If the nth template parameter is a
471 // template parameter pack (14.5.3), the nth template argument is a pack
472 // expansion (14.5.3) whose pattern is the name of the template parameter
473 // pack.
Douglas Gregor9961ce92010-07-08 18:37:38 +0000474 ASTContext &Context = getASTContext();
Douglas Gregore362cea2009-05-10 22:57:19 +0000475 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000476 SmallVector<TemplateArgument, 16> TemplateArgs;
Douglas Gregor43669f82011-03-05 17:54:25 +0000477 TemplateArgs.resize(Params->size());
478 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
Douglas Gregore362cea2009-05-10 22:57:19 +0000479 CommonPtr->InjectedClassNameType
Douglas Gregora8e02e72009-07-28 23:00:59 +0000480 = Context.getTemplateSpecializationType(TemplateName(this),
Douglas Gregore362cea2009-05-10 22:57:19 +0000481 &TemplateArgs[0],
Douglas Gregora8e02e72009-07-28 23:00:59 +0000482 TemplateArgs.size());
Douglas Gregore362cea2009-05-10 22:57:19 +0000483 return CommonPtr->InjectedClassNameType;
484}
485
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000486//===----------------------------------------------------------------------===//
487// TemplateTypeParm Allocation/Deallocation Method Implementations
488//===----------------------------------------------------------------------===//
489
490TemplateTypeParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000491TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000492 SourceLocation KeyLoc, SourceLocation NameLoc,
493 unsigned D, unsigned P, IdentifierInfo *Id,
494 bool Typename, bool ParameterPack) {
Chandler Carruth08836322011-05-01 00:51:33 +0000495 TemplateTypeParmDecl *TTPDecl =
Richard Smithf7981722013-11-22 09:01:48 +0000496 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
Chandler Carruth08836322011-05-01 00:51:33 +0000497 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
Richard Smith5b21db82014-04-23 18:20:42 +0000498 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
Chandler Carruth08836322011-05-01 00:51:33 +0000499 return TTPDecl;
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000500}
501
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000502TemplateTypeParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000503TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000504 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
505 SourceLocation(), nullptr, false);
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000506}
507
John McCall0ad16662009-10-29 08:12:44 +0000508SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara23485e02011-03-04 12:42:03 +0000509 return hasDefaultArgument()
Richard Smith1469b912015-06-10 00:29:03 +0000510 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
511 : SourceLocation();
Abramo Bagnara23485e02011-03-04 12:42:03 +0000512}
513
514SourceRange TemplateTypeParmDecl::getSourceRange() const {
515 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000516 return SourceRange(getLocStart(),
Richard Smith1469b912015-06-10 00:29:03 +0000517 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
Abramo Bagnara23485e02011-03-04 12:42:03 +0000518 else
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000519 return TypeDecl::getSourceRange();
John McCall0ad16662009-10-29 08:12:44 +0000520}
521
Douglas Gregor21610382009-10-29 00:04:11 +0000522unsigned TemplateTypeParmDecl::getDepth() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000523 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
Douglas Gregor21610382009-10-29 00:04:11 +0000524}
525
526unsigned TemplateTypeParmDecl::getIndex() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000527 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
Douglas Gregor21610382009-10-29 00:04:11 +0000528}
529
Chandler Carruth08836322011-05-01 00:51:33 +0000530bool TemplateTypeParmDecl::isParameterPack() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000531 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
Chandler Carruth08836322011-05-01 00:51:33 +0000532}
533
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000534//===----------------------------------------------------------------------===//
535// NonTypeTemplateParmDecl Method Implementations
536//===----------------------------------------------------------------------===//
537
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000538NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000539 SourceLocation StartLoc,
540 SourceLocation IdLoc,
541 unsigned D, unsigned P,
542 IdentifierInfo *Id,
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000543 QualType T,
544 TypeSourceInfo *TInfo,
545 const QualType *ExpandedTypes,
546 unsigned NumExpandedTypes,
547 TypeSourceInfo **ExpandedTInfos)
Abramo Bagnaradff19302011-03-08 08:55:46 +0000548 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
Richard Smith1469b912015-06-10 00:29:03 +0000549 TemplateParmPosition(D, P), ParameterPack(true),
550 ExpandedParameterPack(true), NumExpandedTypes(NumExpandedTypes) {
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000551 if (ExpandedTypes && ExpandedTInfos) {
James Y Knight7a22b242015-08-06 20:26:32 +0000552 auto TypesAndInfos =
553 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000554 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
James Y Knight7a22b242015-08-06 20:26:32 +0000555 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
556 TypesAndInfos[I].second = ExpandedTInfos[I];
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000557 }
558 }
559}
560
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000561NonTypeTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000562NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000563 SourceLocation StartLoc, SourceLocation IdLoc,
564 unsigned D, unsigned P, IdentifierInfo *Id,
565 QualType T, bool ParameterPack,
566 TypeSourceInfo *TInfo) {
Richard Smithf7981722013-11-22 09:01:48 +0000567 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
568 T, ParameterPack, TInfo);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000569}
570
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000571NonTypeTemplateParmDecl *
572NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000573 SourceLocation StartLoc, SourceLocation IdLoc,
574 unsigned D, unsigned P,
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000575 IdentifierInfo *Id, QualType T,
576 TypeSourceInfo *TInfo,
577 const QualType *ExpandedTypes,
578 unsigned NumExpandedTypes,
579 TypeSourceInfo **ExpandedTInfos) {
James Y Knight7a22b242015-08-06 20:26:32 +0000580 return new (C, DC,
581 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
582 NumExpandedTypes))
583 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
584 ExpandedTypes, NumExpandedTypes, ExpandedTInfos);
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000585}
586
Douglas Gregor72172e92012-01-05 21:55:30 +0000587NonTypeTemplateParmDecl *
588NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000589 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
590 SourceLocation(), 0, 0, nullptr,
591 QualType(), false, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000592}
593
594NonTypeTemplateParmDecl *
595NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
596 unsigned NumExpandedTypes) {
James Y Knight7a22b242015-08-06 20:26:32 +0000597 return new (C, ID,
598 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
599 NumExpandedTypes))
600 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), 0, 0,
601 nullptr, QualType(), nullptr, nullptr,
602 NumExpandedTypes, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000603}
604
John McCallf4cd4f92011-02-09 01:13:10 +0000605SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnarae15d5532011-03-04 11:03:48 +0000606 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraea947882011-03-08 16:41:52 +0000607 return SourceRange(getOuterLocStart(),
608 getDefaultArgument()->getSourceRange().getEnd());
609 return DeclaratorDecl::getSourceRange();
John McCallf4cd4f92011-02-09 01:13:10 +0000610}
611
Douglas Gregordba32632009-02-10 19:49:53 +0000612SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara656e3002010-06-09 09:26:05 +0000613 return hasDefaultArgument()
614 ? getDefaultArgument()->getSourceRange().getBegin()
615 : SourceLocation();
Douglas Gregordba32632009-02-10 19:49:53 +0000616}
617
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000618//===----------------------------------------------------------------------===//
619// TemplateTemplateParmDecl Method Implementations
620//===----------------------------------------------------------------------===//
621
David Blaikie68e081d2011-12-20 02:48:34 +0000622void TemplateTemplateParmDecl::anchor() { }
623
Richard Smith1fde8ec2012-09-07 02:06:42 +0000624TemplateTemplateParmDecl::TemplateTemplateParmDecl(
625 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
626 IdentifierInfo *Id, TemplateParameterList *Params,
627 unsigned NumExpansions, TemplateParameterList * const *Expansions)
628 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
Richard Smith1469b912015-06-10 00:29:03 +0000629 TemplateParmPosition(D, P), ParameterPack(true),
Richard Smith1fde8ec2012-09-07 02:06:42 +0000630 ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
631 if (Expansions)
James Y Knight7a22b242015-08-06 20:26:32 +0000632 std::uninitialized_copy(Expansions, Expansions + NumExpandedParams,
633 getTrailingObjects<TemplateParameterList *>());
Richard Smith1fde8ec2012-09-07 02:06:42 +0000634}
635
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000636TemplateTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000637TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000638 SourceLocation L, unsigned D, unsigned P,
Douglas Gregorf5500772011-01-05 15:48:55 +0000639 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000640 TemplateParameterList *Params) {
Richard Smithf7981722013-11-22 09:01:48 +0000641 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
642 Params);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000643}
644
Douglas Gregor72172e92012-01-05 21:55:30 +0000645TemplateTemplateParmDecl *
Richard Smith1fde8ec2012-09-07 02:06:42 +0000646TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
647 SourceLocation L, unsigned D, unsigned P,
648 IdentifierInfo *Id,
649 TemplateParameterList *Params,
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000650 ArrayRef<TemplateParameterList *> Expansions) {
James Y Knight7a22b242015-08-06 20:26:32 +0000651 return new (C, DC,
652 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
653 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions.size(),
654 Expansions.data());
Richard Smith1fde8ec2012-09-07 02:06:42 +0000655}
656
657TemplateTemplateParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000658TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000659 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
660 false, nullptr, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000661}
662
Richard Smith1fde8ec2012-09-07 02:06:42 +0000663TemplateTemplateParmDecl *
664TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
665 unsigned NumExpansions) {
James Y Knight7a22b242015-08-06 20:26:32 +0000666 return new (C, ID,
667 additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
Craig Topper36250ad2014-05-12 05:36:57 +0000668 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
669 nullptr, NumExpansions, nullptr);
Richard Smith1fde8ec2012-09-07 02:06:42 +0000670}
671
Richard Smith35c1df52015-06-17 20:16:32 +0000672SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
673 return hasDefaultArgument() ? getDefaultArgument().getLocation()
674 : SourceLocation();
675}
676
Richard Smith1469b912015-06-10 00:29:03 +0000677void TemplateTemplateParmDecl::setDefaultArgument(
678 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
679 if (DefArg.getArgument().isNull())
680 DefaultArgument.set(nullptr);
681 else
682 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
683}
684
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000685//===----------------------------------------------------------------------===//
Douglas Gregord002c7b2009-05-11 23:53:27 +0000686// TemplateArgumentList Implementation
687//===----------------------------------------------------------------------===//
James Y Knight7a22b242015-08-06 20:26:32 +0000688TemplateArgumentList::TemplateArgumentList(const TemplateArgument *Args,
689 unsigned NumArgs)
690 : Arguments(getTrailingObjects<TemplateArgument>()), NumArguments(NumArgs) {
691 std::uninitialized_copy(Args, Args + NumArgs,
692 getTrailingObjects<TemplateArgument>());
693}
694
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000695TemplateArgumentList *
696TemplateArgumentList::CreateCopy(ASTContext &Context,
697 const TemplateArgument *Args,
698 unsigned NumArgs) {
James Y Knight7a22b242015-08-06 20:26:32 +0000699 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(NumArgs));
700 return new (Mem) TemplateArgumentList(Args, NumArgs);
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000701}
702
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000703FunctionTemplateSpecializationInfo *
704FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
705 FunctionTemplateDecl *Template,
706 TemplateSpecializationKind TSK,
707 const TemplateArgumentList *TemplateArgs,
708 const TemplateArgumentListInfo *TemplateArgsAsWritten,
709 SourceLocation POI) {
Craig Topper36250ad2014-05-12 05:36:57 +0000710 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000711 if (TemplateArgsAsWritten)
712 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
713 *TemplateArgsAsWritten);
714
715 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
716 TemplateArgs,
717 ArgsAsWritten,
718 POI);
719}
720
Douglas Gregord002c7b2009-05-11 23:53:27 +0000721//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000722// TemplateDecl Implementation
723//===----------------------------------------------------------------------===//
724
725void TemplateDecl::anchor() { }
726
727//===----------------------------------------------------------------------===//
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000728// ClassTemplateSpecializationDecl Implementation
729//===----------------------------------------------------------------------===//
730ClassTemplateSpecializationDecl::
Douglas Gregore9029562010-05-06 00:28:52 +0000731ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000732 DeclContext *DC, SourceLocation StartLoc,
733 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000734 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000735 const TemplateArgument *Args,
736 unsigned NumArgs,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000737 ClassTemplateSpecializationDecl *PrevDecl)
Richard Smith053f6c62014-05-16 23:01:30 +0000738 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000739 SpecializedTemplate->getIdentifier(),
740 PrevDecl),
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000741 SpecializedTemplate(SpecializedTemplate),
Craig Topper36250ad2014-05-12 05:36:57 +0000742 ExplicitInfo(nullptr),
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000743 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
Douglas Gregord002c7b2009-05-11 23:53:27 +0000744 SpecializationKind(TSK_Undeclared) {
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000745}
Mike Stump11289f42009-09-09 15:08:12 +0000746
Richard Smith053f6c62014-05-16 23:01:30 +0000747ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
748 Kind DK)
749 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
750 SourceLocation(), nullptr, nullptr),
751 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000752
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000753ClassTemplateSpecializationDecl *
Douglas Gregore9029562010-05-06 00:28:52 +0000754ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000755 DeclContext *DC,
756 SourceLocation StartLoc,
757 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000758 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000759 const TemplateArgument *Args,
760 unsigned NumArgs,
Douglas Gregor67a65642009-02-17 23:15:12 +0000761 ClassTemplateSpecializationDecl *PrevDecl) {
Richard Smithf7981722013-11-22 09:01:48 +0000762 ClassTemplateSpecializationDecl *Result =
763 new (Context, DC) ClassTemplateSpecializationDecl(
764 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
765 SpecializedTemplate, Args, NumArgs, PrevDecl);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000766 Result->MayHaveOutOfDateDef = false;
767
Douglas Gregor67a65642009-02-17 23:15:12 +0000768 Context.getTypeDeclType(Result, PrevDecl);
769 return Result;
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000770}
Douglas Gregor2373c592009-05-31 09:31:02 +0000771
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000772ClassTemplateSpecializationDecl *
Richard Smithf7981722013-11-22 09:01:48 +0000773ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000774 unsigned ID) {
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000775 ClassTemplateSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000776 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000777 Result->MayHaveOutOfDateDef = false;
778 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000779}
780
Benjamin Kramer9170e912013-02-22 15:46:01 +0000781void ClassTemplateSpecializationDecl::getNameForDiagnostic(
782 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
783 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000784
785 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Benjamin Kramer9170e912013-02-22 15:46:01 +0000786 TemplateSpecializationType::PrintTemplateArgumentList(
787 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000788}
789
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000790ClassTemplateDecl *
Mike Stump11289f42009-09-09 15:08:12 +0000791ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
792 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000793 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
794 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
795 return SpecializedTemplate.get<ClassTemplateDecl*>();
796}
797
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000798SourceRange
799ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000800 if (ExplicitInfo) {
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000801 SourceLocation Begin = getTemplateKeywordLoc();
802 if (Begin.isValid()) {
803 // Here we have an explicit (partial) specialization or instantiation.
804 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
805 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
806 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
807 if (getExternLoc().isValid())
808 Begin = getExternLoc();
809 SourceLocation End = getRBraceLoc();
810 if (End.isInvalid())
811 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
812 return SourceRange(Begin, End);
813 }
814 // An implicit instantiation of a class template partial specialization
815 // uses ExplicitInfo to record the TypeAsWritten, but the source
816 // locations should be retrieved from the instantiation pattern.
817 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
818 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
819 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
Craig Topper36250ad2014-05-12 05:36:57 +0000820 assert(inst_from != nullptr);
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000821 return inst_from->getSourceRange();
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000822 }
823 else {
824 // No explicit info available.
825 llvm::PointerUnion<ClassTemplateDecl *,
826 ClassTemplatePartialSpecializationDecl *>
827 inst_from = getInstantiatedFrom();
828 if (inst_from.isNull())
829 return getSpecializedTemplate()->getSourceRange();
830 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
831 return ctd->getSourceRange();
832 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
833 ->getSourceRange();
834 }
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000835}
836
Douglas Gregor2373c592009-05-31 09:31:02 +0000837//===----------------------------------------------------------------------===//
838// ClassTemplatePartialSpecializationDecl Implementation
839//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000840void ClassTemplatePartialSpecializationDecl::anchor() { }
841
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000842ClassTemplatePartialSpecializationDecl::
843ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000844 DeclContext *DC,
845 SourceLocation StartLoc,
846 SourceLocation IdLoc,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000847 TemplateParameterList *Params,
848 ClassTemplateDecl *SpecializedTemplate,
849 const TemplateArgument *Args,
850 unsigned NumArgs,
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000851 const ASTTemplateArgumentListInfo *ArgInfos,
Richard Smithb2f61b42013-08-22 23:27:37 +0000852 ClassTemplatePartialSpecializationDecl *PrevDecl)
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000853 : ClassTemplateSpecializationDecl(Context,
854 ClassTemplatePartialSpecialization,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000855 TK, DC, StartLoc, IdLoc,
856 SpecializedTemplate,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000857 Args, NumArgs, PrevDecl),
858 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +0000859 InstantiatedFromMember(nullptr, false)
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000860{
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000861 AdoptTemplateParameterList(Params, this);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000862}
863
Douglas Gregor2373c592009-05-31 09:31:02 +0000864ClassTemplatePartialSpecializationDecl *
865ClassTemplatePartialSpecializationDecl::
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000866Create(ASTContext &Context, TagKind TK,DeclContext *DC,
867 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregor2373c592009-05-31 09:31:02 +0000868 TemplateParameterList *Params,
869 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000870 const TemplateArgument *Args,
871 unsigned NumArgs,
John McCall6b51f282009-11-23 01:53:49 +0000872 const TemplateArgumentListInfo &ArgInfos,
John McCalle78aac42010-03-10 03:28:59 +0000873 QualType CanonInjectedType,
Richard Smithb2f61b42013-08-22 23:27:37 +0000874 ClassTemplatePartialSpecializationDecl *PrevDecl) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000875 const ASTTemplateArgumentListInfo *ASTArgInfos =
876 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
John McCall0ad16662009-10-29 08:12:44 +0000877
Richard Smithf7981722013-11-22 09:01:48 +0000878 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
879 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
880 Params, SpecializedTemplate, Args,
881 NumArgs, ASTArgInfos, PrevDecl);
Douglas Gregor2373c592009-05-31 09:31:02 +0000882 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000883 Result->MayHaveOutOfDateDef = false;
John McCalle78aac42010-03-10 03:28:59 +0000884
885 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregor2373c592009-05-31 09:31:02 +0000886 return Result;
887}
John McCall11083da2009-09-16 22:47:08 +0000888
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000889ClassTemplatePartialSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000890ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
891 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000892 ClassTemplatePartialSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000893 new (C, ID) ClassTemplatePartialSpecializationDecl(C);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000894 Result->MayHaveOutOfDateDef = false;
895 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000896}
897
John McCall11083da2009-09-16 22:47:08 +0000898//===----------------------------------------------------------------------===//
899// FriendTemplateDecl Implementation
900//===----------------------------------------------------------------------===//
901
David Blaikie68e081d2011-12-20 02:48:34 +0000902void FriendTemplateDecl::anchor() { }
903
John McCall11083da2009-09-16 22:47:08 +0000904FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
905 DeclContext *DC,
906 SourceLocation L,
907 unsigned NParams,
908 TemplateParameterList **Params,
909 FriendUnion Friend,
910 SourceLocation FLoc) {
Richard Smithf7981722013-11-22 09:01:48 +0000911 return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params,
912 Friend, FLoc);
John McCall11083da2009-09-16 22:47:08 +0000913}
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000914
Douglas Gregor72172e92012-01-05 21:55:30 +0000915FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
916 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000917 return new (C, ID) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000918}
Richard Smith3f1b5d02011-05-05 21:57:07 +0000919
920//===----------------------------------------------------------------------===//
921// TypeAliasTemplateDecl Implementation
922//===----------------------------------------------------------------------===//
923
924TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
925 DeclContext *DC,
926 SourceLocation L,
927 DeclarationName Name,
928 TemplateParameterList *Params,
929 NamedDecl *Decl) {
930 AdoptTemplateParameterList(Params, DC);
Richard Smith053f6c62014-05-16 23:01:30 +0000931 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000932}
933
Douglas Gregor72172e92012-01-05 21:55:30 +0000934TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
935 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000936 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000937 DeclarationName(), nullptr, nullptr);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000938}
939
940void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
941 static_cast<Common *>(Ptr)->~Common();
942}
943RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000944TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3f1b5d02011-05-05 21:57:07 +0000945 Common *CommonPtr = new (C) Common;
946 C.AddDeallocation(DeallocateCommon, CommonPtr);
947 return CommonPtr;
948}
949
David Blaikie68e081d2011-12-20 02:48:34 +0000950//===----------------------------------------------------------------------===//
951// ClassScopeFunctionSpecializationDecl Implementation
952//===----------------------------------------------------------------------===//
953
954void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor72172e92012-01-05 21:55:30 +0000955
956ClassScopeFunctionSpecializationDecl *
957ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
958 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000959 return new (C, ID) ClassScopeFunctionSpecializationDecl(
Craig Topper36250ad2014-05-12 05:36:57 +0000960 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
Douglas Gregor72172e92012-01-05 21:55:30 +0000961}
Larisse Voufo39a1e502013-08-06 01:03:05 +0000962
963//===----------------------------------------------------------------------===//
964// VarTemplateDecl Implementation
965//===----------------------------------------------------------------------===//
966
967void VarTemplateDecl::DeallocateCommon(void *Ptr) {
968 static_cast<Common *>(Ptr)->~Common();
969}
970
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000971VarTemplateDecl *VarTemplateDecl::getDefinition() {
972 VarTemplateDecl *CurD = this;
973 while (CurD) {
974 if (CurD->isThisDeclarationADefinition())
975 return CurD;
976 CurD = CurD->getPreviousDecl();
977 }
Craig Topper36250ad2014-05-12 05:36:57 +0000978 return nullptr;
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000979}
980
Larisse Voufo39a1e502013-08-06 01:03:05 +0000981VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
982 SourceLocation L, DeclarationName Name,
983 TemplateParameterList *Params,
Richard Smithbeef3452014-01-16 23:39:20 +0000984 VarDecl *Decl) {
Richard Smith053f6c62014-05-16 23:01:30 +0000985 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000986}
987
988VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
989 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000990 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
991 DeclarationName(), nullptr, nullptr);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000992}
993
Alp Tokerf6a24ce2013-12-05 16:25:25 +0000994// TODO: Unify across class, function and variable templates?
Larisse Voufo30616382013-08-23 22:21:36 +0000995// May require moving this and Common to RedeclarableTemplateDecl.
Larisse Voufo39a1e502013-08-06 01:03:05 +0000996void VarTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000997 // Grab the most recent declaration to ensure we've loaded any lazy
998 // redeclarations of this template.
999 //
1000 // FIXME: Avoid walking the entire redeclaration chain here.
1001 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Larisse Voufo39a1e502013-08-06 01:03:05 +00001002 if (CommonPtr->LazySpecializations) {
1003 ASTContext &Context = getASTContext();
1004 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +00001005 CommonPtr->LazySpecializations = nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +00001006 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
1007 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
1008 }
1009}
1010
1011llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1012VarTemplateDecl::getSpecializations() const {
1013 LoadLazySpecializations();
1014 return getCommonPtr()->Specializations;
1015}
1016
1017llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1018VarTemplateDecl::getPartialSpecializations() {
1019 LoadLazySpecializations();
1020 return getCommonPtr()->PartialSpecializations;
1021}
1022
1023RedeclarableTemplateDecl::CommonBase *
1024VarTemplateDecl::newCommon(ASTContext &C) const {
1025 Common *CommonPtr = new (C) Common;
1026 C.AddDeallocation(DeallocateCommon, CommonPtr);
1027 return CommonPtr;
1028}
1029
1030VarTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +00001031VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1032 void *&InsertPos) {
1033 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001034}
1035
1036void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1037 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +00001038 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001039}
1040
1041VarTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +00001042VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1043 void *&InsertPos) {
1044 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001045}
1046
1047void VarTemplateDecl::AddPartialSpecialization(
1048 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1049 if (InsertPos)
1050 getPartialSpecializations().InsertNode(D, InsertPos);
1051 else {
1052 VarTemplatePartialSpecializationDecl *Existing =
1053 getPartialSpecializations().GetOrInsertNode(D);
1054 (void)Existing;
1055 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1056 }
1057
1058 if (ASTMutationListener *L = getASTMutationListener())
1059 L->AddedCXXTemplateSpecialization(this, D);
1060}
1061
1062void VarTemplateDecl::getPartialSpecializations(
1063 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1064 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1065 getPartialSpecializations();
1066 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +00001067 PS.reserve(PartialSpecs.size());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001068 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1069 P = PartialSpecs.begin(),
1070 PEnd = PartialSpecs.end();
Richard Smithb2f61b42013-08-22 23:27:37 +00001071 P != PEnd; ++P)
1072 PS.push_back(P->getMostRecentDecl());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001073}
1074
1075VarTemplatePartialSpecializationDecl *
1076VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1077 VarTemplatePartialSpecializationDecl *D) {
1078 Decl *DCanon = D->getCanonicalDecl();
1079 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1080 P = getPartialSpecializations().begin(),
1081 PEnd = getPartialSpecializations().end();
1082 P != PEnd; ++P) {
1083 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1084 return P->getMostRecentDecl();
1085 }
1086
Craig Topper36250ad2014-05-12 05:36:57 +00001087 return nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +00001088}
1089
1090//===----------------------------------------------------------------------===//
1091// VarTemplateSpecializationDecl Implementation
1092//===----------------------------------------------------------------------===//
1093VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001094 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001095 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1096 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1097 unsigned NumArgs)
Richard Smith053f6c62014-05-16 23:01:30 +00001098 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1099 SpecializedTemplate->getIdentifier(), T, TInfo, S),
Craig Topper36250ad2014-05-12 05:36:57 +00001100 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001101 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
1102 SpecializationKind(TSK_Undeclared) {}
1103
Richard Smith053f6c62014-05-16 23:01:30 +00001104VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1105 ASTContext &C)
1106 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
Craig Topper36250ad2014-05-12 05:36:57 +00001107 QualType(), nullptr, SC_None),
1108 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Larisse Voufo39a1e502013-08-06 01:03:05 +00001109
1110VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1111 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1112 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1113 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1114 unsigned NumArgs) {
Richard Smithf7981722013-11-22 09:01:48 +00001115 return new (Context, DC) VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001116 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
Richard Smithf7981722013-11-22 09:01:48 +00001117 SpecializedTemplate, T, TInfo, S, Args, NumArgs);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001118}
1119
1120VarTemplateSpecializationDecl *
1121VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001122 return new (C, ID)
1123 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001124}
1125
1126void VarTemplateSpecializationDecl::getNameForDiagnostic(
1127 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1128 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1129
1130 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1131 TemplateSpecializationType::PrintTemplateArgumentList(
1132 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
1133}
1134
1135VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1136 if (SpecializedPartialSpecialization *PartialSpec =
1137 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1138 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1139 return SpecializedTemplate.get<VarTemplateDecl *>();
1140}
1141
1142void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1143 const TemplateArgumentListInfo &ArgsInfo) {
1144 unsigned N = ArgsInfo.size();
1145 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1146 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1147 for (unsigned I = 0; I != N; ++I)
1148 TemplateArgsInfo.addArgument(ArgsInfo[I]);
1149}
1150
1151//===----------------------------------------------------------------------===//
1152// VarTemplatePartialSpecializationDecl Implementation
1153//===----------------------------------------------------------------------===//
1154void VarTemplatePartialSpecializationDecl::anchor() {}
1155
1156VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1157 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1158 SourceLocation IdLoc, TemplateParameterList *Params,
1159 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1160 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
Richard Smithb2f61b42013-08-22 23:27:37 +00001161 const ASTTemplateArgumentListInfo *ArgInfos)
Richard Smith053f6c62014-05-16 23:01:30 +00001162 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001163 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1164 TInfo, S, Args, NumArgs),
1165 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +00001166 InstantiatedFromMember(nullptr, false) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001167 // TODO: The template parameters should be in DC by now. Verify.
1168 // AdoptTemplateParameterList(Params, DC);
1169}
1170
1171VarTemplatePartialSpecializationDecl *
1172VarTemplatePartialSpecializationDecl::Create(
1173 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1174 SourceLocation IdLoc, TemplateParameterList *Params,
1175 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1176 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
Richard Smithb2f61b42013-08-22 23:27:37 +00001177 const TemplateArgumentListInfo &ArgInfos) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +00001178 const ASTTemplateArgumentListInfo *ASTArgInfos
1179 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001180
1181 VarTemplatePartialSpecializationDecl *Result =
Richard Smithf7981722013-11-22 09:01:48 +00001182 new (Context, DC) VarTemplatePartialSpecializationDecl(
Larisse Voufo39a1e502013-08-06 01:03:05 +00001183 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
Richard Smithb2f61b42013-08-22 23:27:37 +00001184 S, Args, NumArgs, ASTArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001185 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1186 return Result;
1187}
1188
1189VarTemplatePartialSpecializationDecl *
1190VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1191 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001192 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001193}
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001194
1195static TemplateParameterList *
1196createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1197 // typename T
1198 auto *T = TemplateTypeParmDecl::Create(
1199 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1200 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1201 T->setImplicit(true);
1202
1203 // T ...Ints
1204 TypeSourceInfo *TI =
1205 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1206 auto *N = NonTypeTemplateParmDecl::Create(
1207 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1208 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1209 N->setImplicit(true);
1210
1211 // <typename T, T ...Ints>
1212 NamedDecl *P[2] = {T, N};
1213 auto *TPL = TemplateParameterList::Create(
David Majnemer902f8c62015-12-27 07:16:27 +00001214 C, SourceLocation(), SourceLocation(), P, SourceLocation());
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001215
1216 // template <typename T, ...Ints> class IntSeq
1217 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1218 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1219 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1220 TemplateTemplateParm->setImplicit(true);
1221
1222 // typename T
1223 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1224 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1225 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1226 TemplateTypeParm->setImplicit(true);
1227
1228 // T N
1229 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1230 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1231 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1232 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1233 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1234 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1235 NonTypeTemplateParm};
1236
1237 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1238 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
David Majnemer902f8c62015-12-27 07:16:27 +00001239 Params, SourceLocation());
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001240}
1241
1242static TemplateParameterList *createBuiltinTemplateParameterList(
1243 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1244 switch (BTK) {
1245 case BTK__make_integer_seq:
1246 return createMakeIntegerSeqParameterList(C, DC);
1247 }
1248
1249 llvm_unreachable("unhandled BuiltinTemplateKind!");
1250}
1251
1252void BuiltinTemplateDecl::anchor() {}
1253
1254BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1255 DeclarationName Name,
1256 BuiltinTemplateKind BTK)
1257 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1258 createBuiltinTemplateParameterList(C, DC, BTK)),
1259 BTK(BTK) {}