blob: 18a30b2f1c514f8f1417b2e887aef22ceeedebad [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,
Douglas Gregorbe999392009-09-15 16:23:51 +000033 NamedDecl **Params, unsigned NumParams,
Douglas Gregorcd72ba92009-02-06 22:42:48 +000034 SourceLocation RAngleLoc)
35 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
Richard Smith1fde8ec2012-09-07 02:06:42 +000036 NumParams(NumParams), ContainsUnexpandedParameterPack(false) {
37 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
57TemplateParameterList *
Jay Foad39c79802011-01-12 09:06:06 +000058TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
Douglas Gregorbe999392009-09-15 16:23:51 +000059 SourceLocation LAngleLoc, NamedDecl **Params,
Douglas Gregorcd72ba92009-02-06 22:42:48 +000060 unsigned NumParams, SourceLocation RAngleLoc) {
James Y Knight7a22b242015-08-06 20:26:32 +000061 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *>(NumParams),
62 llvm::alignOf<TemplateParameterList>());
Mike Stump11289f42009-09-09 15:08:12 +000063 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
Douglas Gregorcd72ba92009-02-06 22:42:48 +000064 NumParams, RAngleLoc);
Douglas Gregorded2d7b2009-02-04 19:02:06 +000065}
66
Douglas Gregorf8f86832009-02-11 18:16:40 +000067unsigned TemplateParameterList::getMinRequiredArguments() const {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000068 unsigned NumRequiredArgs = 0;
69 for (iterator P = const_cast<TemplateParameterList *>(this)->begin(),
70 PEnd = const_cast<TemplateParameterList *>(this)->end();
71 P != PEnd; ++P) {
72 if ((*P)->isTemplateParameterPack()) {
73 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P))
74 if (NTTP->isExpandedParameterPack()) {
75 NumRequiredArgs += NTTP->getNumExpansionTypes();
76 continue;
77 }
78
Douglas Gregorf8f86832009-02-11 18:16:40 +000079 break;
Douglas Gregor0231d8d2011-01-19 20:10:05 +000080 }
81
82 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
83 if (TTP->hasDefaultArgument())
84 break;
85 } else if (NonTypeTemplateParmDecl *NTTP
86 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
87 if (NTTP->hasDefaultArgument())
88 break;
89 } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument())
90 break;
91
92 ++NumRequiredArgs;
Douglas Gregorf8f86832009-02-11 18:16:40 +000093 }
Douglas Gregor0231d8d2011-01-19 20:10:05 +000094
Douglas Gregorf8f86832009-02-11 18:16:40 +000095 return NumRequiredArgs;
96}
97
Douglas Gregor21610382009-10-29 00:04:11 +000098unsigned TemplateParameterList::getDepth() const {
99 if (size() == 0)
100 return 0;
101
102 const NamedDecl *FirstParm = getParam(0);
103 if (const TemplateTypeParmDecl *TTP
104 = dyn_cast<TemplateTypeParmDecl>(FirstParm))
105 return TTP->getDepth();
106 else if (const NonTypeTemplateParmDecl *NTTP
107 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
108 return NTTP->getDepth();
109 else
110 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
111}
112
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000113static void AdoptTemplateParameterList(TemplateParameterList *Params,
114 DeclContext *Owner) {
115 for (TemplateParameterList::iterator P = Params->begin(),
116 PEnd = Params->end();
117 P != PEnd; ++P) {
118 (*P)->setDeclContext(Owner);
119
120 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P))
121 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
122 }
123}
124
Richard Smithe7bd6de2015-06-10 20:30:23 +0000125namespace clang {
126void *allocateDefaultArgStorageChain(const ASTContext &C) {
127 return new (C) char[sizeof(void*) * 2];
128}
129}
130
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000131//===----------------------------------------------------------------------===//
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000132// RedeclarableTemplateDecl Implementation
133//===----------------------------------------------------------------------===//
134
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000135RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000136 if (Common)
137 return Common;
138
139 // Walk the previous-declaration chain until we either find a declaration
140 // with a common pointer or we run out of previous declarations.
141 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
142 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
143 Prev = Prev->getPreviousDecl()) {
144 if (Prev->Common) {
145 Common = Prev->Common;
146 break;
Douglas Gregor68444de2012-01-14 15:13:49 +0000147 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000148
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000149 PrevDecls.push_back(Prev);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000150 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000151
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000152 // If we never found a common pointer, allocate one now.
153 if (!Common) {
154 // FIXME: If any of the declarations is from an AST file, we probably
155 // need an update record to add the common data.
156
157 Common = newCommon(getASTContext());
158 }
159
160 // Update any previous declarations we saw with the common pointer.
161 for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I)
162 PrevDecls[I]->Common = Common;
163
Douglas Gregor68444de2012-01-14 15:13:49 +0000164 return Common;
Peter Collingbourne029fd692010-07-29 16:12:09 +0000165}
166
Richard Smithe977e512015-02-24 01:23:23 +0000167template<class EntryType>
168typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000169RedeclarableTemplateDecl::findSpecializationImpl(
Richard Smithe977e512015-02-24 01:23:23 +0000170 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
171 void *&InsertPos) {
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000172 typedef SpecEntryTraits<EntryType> SETraits;
173 llvm::FoldingSetNodeID ID;
Craig Topper7e0daca2014-06-26 04:58:53 +0000174 EntryType::Profile(ID,Args, getASTContext());
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000175 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
Richard Smithe977e512015-02-24 01:23:23 +0000176 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
177}
178
179template<class Derived, class EntryType>
180void RedeclarableTemplateDecl::addSpecializationImpl(
181 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
182 void *InsertPos) {
183 typedef SpecEntryTraits<EntryType> SETraits;
184 if (InsertPos) {
185#ifndef NDEBUG
186 void *CorrectInsertPos;
187 assert(!findSpecializationImpl(Specializations,
188 SETraits::getTemplateArgs(Entry),
189 CorrectInsertPos) &&
190 InsertPos == CorrectInsertPos &&
191 "given incorrect InsertPos for specialization");
192#endif
193 Specializations.InsertNode(Entry, InsertPos);
194 } else {
195 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
196 (void)Existing;
197 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
198 "non-canonical specialization?");
199 }
200
201 if (ASTMutationListener *L = getASTMutationListener())
202 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
203 SETraits::getDecl(Entry));
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000204}
205
Douglas Gregor43669f82011-03-05 17:54:25 +0000206/// \brief Generate the injected template arguments for the given template
207/// parameter list, e.g., for the injected-class-name of a class template.
208static void GenerateInjectedTemplateArgs(ASTContext &Context,
209 TemplateParameterList *Params,
210 TemplateArgument *Args) {
211 for (TemplateParameterList::iterator Param = Params->begin(),
212 ParamEnd = Params->end();
213 Param != ParamEnd; ++Param) {
214 TemplateArgument Arg;
215 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
216 QualType ArgType = Context.getTypeDeclType(TTP);
217 if (TTP->isParameterPack())
David Blaikie7a30dc52013-02-21 01:47:18 +0000218 ArgType = Context.getPackExpansionType(ArgType, None);
David Blaikie05785d12013-02-20 22:23:23 +0000219
Douglas Gregor43669f82011-03-05 17:54:25 +0000220 Arg = TemplateArgument(ArgType);
221 } else if (NonTypeTemplateParmDecl *NTTP =
222 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
John McCall113bee02012-03-10 09:33:50 +0000223 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
Douglas Gregor43669f82011-03-05 17:54:25 +0000224 NTTP->getType().getNonLValueExprType(Context),
225 Expr::getValueKindForType(NTTP->getType()),
226 NTTP->getLocation());
227
228 if (NTTP->isParameterPack())
David Blaikie7a30dc52013-02-21 01:47:18 +0000229 E = new (Context) PackExpansionExpr(Context.DependentTy, E,
230 NTTP->getLocation(), None);
Douglas Gregor43669f82011-03-05 17:54:25 +0000231 Arg = TemplateArgument(E);
232 } else {
233 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
234 if (TTP->isParameterPack())
David Blaikie05785d12013-02-20 22:23:23 +0000235 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
Douglas Gregor43669f82011-03-05 17:54:25 +0000236 else
237 Arg = TemplateArgument(TemplateName(TTP));
238 }
239
240 if ((*Param)->isTemplateParameterPack())
Benjamin Kramercce63472015-08-05 09:40:22 +0000241 Arg = TemplateArgument::CreatePackCopy(Context, Arg);
242
Douglas Gregor43669f82011-03-05 17:54:25 +0000243 *Args++ = Arg;
244 }
245}
246
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000247//===----------------------------------------------------------------------===//
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000248// FunctionTemplateDecl Implementation
249//===----------------------------------------------------------------------===//
250
Douglas Gregor1a809332010-05-23 18:26:36 +0000251void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
252 static_cast<Common *>(Ptr)->~Common();
253}
254
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000255FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
256 DeclContext *DC,
257 SourceLocation L,
258 DeclarationName Name,
Douglas Gregor8f5d4422009-06-29 20:59:39 +0000259 TemplateParameterList *Params,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000260 NamedDecl *Decl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000261 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Richard Smith053f6c62014-05-16 23:01:30 +0000262 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000263}
264
Douglas Gregor72172e92012-01-05 21:55:30 +0000265FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
266 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000267 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000268 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000269}
270
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000271RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000272FunctionTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000273 Common *CommonPtr = new (C) Common;
274 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000275 return CommonPtr;
276}
277
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000278void FunctionTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000279 // Grab the most recent declaration to ensure we've loaded any lazy
280 // redeclarations of this template.
281 //
282 // FIXME: Avoid walking the entire redeclaration chain here.
283 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000284 if (CommonPtr->LazySpecializations) {
285 ASTContext &Context = getASTContext();
286 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000287 CommonPtr->LazySpecializations = nullptr;
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000288 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
289 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
290 }
291}
292
293llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
294FunctionTemplateDecl::getSpecializations() const {
295 LoadLazySpecializations();
296 return getCommonPtr()->Specializations;
297}
298
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000299FunctionDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000300FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
301 void *&InsertPos) {
302 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000303}
304
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000305void FunctionTemplateDecl::addSpecialization(
306 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000307 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
308 InsertPos);
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000309}
310
Richard Smith841d8b22013-05-17 03:04:50 +0000311ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
Douglas Gregor43669f82011-03-05 17:54:25 +0000312 TemplateParameterList *Params = getTemplateParameters();
313 Common *CommonPtr = getCommonPtr();
314 if (!CommonPtr->InjectedArgs) {
315 CommonPtr->InjectedArgs
Richard Smith841d8b22013-05-17 03:04:50 +0000316 = new (getASTContext()) TemplateArgument[Params->size()];
317 GenerateInjectedTemplateArgs(getASTContext(), Params,
Douglas Gregor43669f82011-03-05 17:54:25 +0000318 CommonPtr->InjectedArgs);
319 }
Richard Smith841d8b22013-05-17 03:04:50 +0000320
321 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
Douglas Gregor43669f82011-03-05 17:54:25 +0000322}
323
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000324//===----------------------------------------------------------------------===//
325// ClassTemplateDecl Implementation
326//===----------------------------------------------------------------------===//
327
Douglas Gregor1a809332010-05-23 18:26:36 +0000328void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
329 static_cast<Common *>(Ptr)->~Common();
330}
331
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000332ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
333 DeclContext *DC,
334 SourceLocation L,
335 DeclarationName Name,
336 TemplateParameterList *Params,
Douglas Gregor90a1a652009-03-19 17:26:29 +0000337 NamedDecl *Decl,
338 ClassTemplateDecl *PrevDecl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000339 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Richard Smith053f6c62014-05-16 23:01:30 +0000340 ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
341 Params, Decl);
Rafael Espindola8db352d2013-10-17 15:37:26 +0000342 New->setPreviousDecl(PrevDecl);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +0000343 return New;
Douglas Gregor90a1a652009-03-19 17:26:29 +0000344}
345
Richard Smith053f6c62014-05-16 23:01:30 +0000346ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000347 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000348 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
349 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000350}
351
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000352void ClassTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000353 // Grab the most recent declaration to ensure we've loaded any lazy
354 // redeclarations of this template.
355 //
356 // FIXME: Avoid walking the entire redeclaration chain here.
357 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000358 if (CommonPtr->LazySpecializations) {
359 ASTContext &Context = getASTContext();
360 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000361 CommonPtr->LazySpecializations = nullptr;
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000362 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
363 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
364 }
365}
366
Chandler Carruthb41171b2012-05-03 23:49:05 +0000367llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000368ClassTemplateDecl::getSpecializations() const {
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000369 LoadLazySpecializations();
370 return getCommonPtr()->Specializations;
371}
372
Chandler Carruthb41171b2012-05-03 23:49:05 +0000373llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000374ClassTemplateDecl::getPartialSpecializations() {
375 LoadLazySpecializations();
376 return getCommonPtr()->PartialSpecializations;
377}
378
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000379RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000380ClassTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000381 Common *CommonPtr = new (C) Common;
382 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000383 return CommonPtr;
384}
385
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000386ClassTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000387ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
388 void *&InsertPos) {
389 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000390}
391
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000392void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
393 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000394 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000395}
396
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000397ClassTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000398ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000399 void *&InsertPos) {
Craig Topper7e0daca2014-06-26 04:58:53 +0000400 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000401}
402
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000403void ClassTemplateDecl::AddPartialSpecialization(
404 ClassTemplatePartialSpecializationDecl *D,
405 void *InsertPos) {
Douglas Gregorce9978f2012-03-28 14:34:23 +0000406 if (InsertPos)
407 getPartialSpecializations().InsertNode(D, InsertPos);
408 else {
409 ClassTemplatePartialSpecializationDecl *Existing
410 = getPartialSpecializations().GetOrInsertNode(D);
411 (void)Existing;
412 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
413 }
414
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000415 if (ASTMutationListener *L = getASTMutationListener())
416 L->AddedCXXTemplateSpecialization(this, D);
417}
418
Douglas Gregor407e9612010-04-30 05:56:50 +0000419void ClassTemplateDecl::getPartialSpecializations(
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000420 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
Chandler Carruthb41171b2012-05-03 23:49:05 +0000421 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000422 = getPartialSpecializations();
Douglas Gregor407e9612010-04-30 05:56:50 +0000423 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +0000424 PS.reserve(PartialSpecs.size());
Chandler Carruthb41171b2012-05-03 23:49:05 +0000425 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregor407e9612010-04-30 05:56:50 +0000426 P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
Richard Smithb2f61b42013-08-22 23:27:37 +0000427 P != PEnd; ++P)
428 PS.push_back(P->getMostRecentDecl());
Douglas Gregor407e9612010-04-30 05:56:50 +0000429}
430
Douglas Gregor15301382009-07-30 17:40:51 +0000431ClassTemplatePartialSpecializationDecl *
432ClassTemplateDecl::findPartialSpecialization(QualType T) {
433 ASTContext &Context = getASTContext();
Chandler Carruthb41171b2012-05-03 23:49:05 +0000434 using llvm::FoldingSetVector;
435 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Douglas Gregor15301382009-07-30 17:40:51 +0000436 partial_spec_iterator;
437 for (partial_spec_iterator P = getPartialSpecializations().begin(),
438 PEnd = getPartialSpecializations().end();
439 P != PEnd; ++P) {
John McCall2408e322010-04-27 00:57:59 +0000440 if (Context.hasSameType(P->getInjectedSpecializationType(), T))
Douglas Gregorec9fd132012-01-14 16:38:05 +0000441 return P->getMostRecentDecl();
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000442 }
443
Craig Topper36250ad2014-05-12 05:36:57 +0000444 return nullptr;
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000445}
446
447ClassTemplatePartialSpecializationDecl *
448ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
449 ClassTemplatePartialSpecializationDecl *D) {
450 Decl *DCanon = D->getCanonicalDecl();
Chandler Carruthb41171b2012-05-03 23:49:05 +0000451 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000452 P = getPartialSpecializations().begin(),
453 PEnd = getPartialSpecializations().end();
454 P != PEnd; ++P) {
455 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
Douglas Gregorec9fd132012-01-14 16:38:05 +0000456 return P->getMostRecentDecl();
Douglas Gregor15301382009-07-30 17:40:51 +0000457 }
Mike Stump11289f42009-09-09 15:08:12 +0000458
Craig Topper36250ad2014-05-12 05:36:57 +0000459 return nullptr;
Douglas Gregor15301382009-07-30 17:40:51 +0000460}
461
John McCalle78aac42010-03-10 03:28:59 +0000462QualType
Douglas Gregor9961ce92010-07-08 18:37:38 +0000463ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000464 Common *CommonPtr = getCommonPtr();
Douglas Gregore362cea2009-05-10 22:57:19 +0000465 if (!CommonPtr->InjectedClassNameType.isNull())
466 return CommonPtr->InjectedClassNameType;
467
Douglas Gregor8092e802010-12-23 16:00:30 +0000468 // C++0x [temp.dep.type]p2:
469 // The template argument list of a primary template is a template argument
470 // list in which the nth template argument has the value of the nth template
471 // parameter of the class template. If the nth template parameter is a
472 // template parameter pack (14.5.3), the nth template argument is a pack
473 // expansion (14.5.3) whose pattern is the name of the template parameter
474 // pack.
Douglas Gregor9961ce92010-07-08 18:37:38 +0000475 ASTContext &Context = getASTContext();
Douglas Gregore362cea2009-05-10 22:57:19 +0000476 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000477 SmallVector<TemplateArgument, 16> TemplateArgs;
Douglas Gregor43669f82011-03-05 17:54:25 +0000478 TemplateArgs.resize(Params->size());
479 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
Douglas Gregore362cea2009-05-10 22:57:19 +0000480 CommonPtr->InjectedClassNameType
Douglas Gregora8e02e72009-07-28 23:00:59 +0000481 = Context.getTemplateSpecializationType(TemplateName(this),
Douglas Gregore362cea2009-05-10 22:57:19 +0000482 &TemplateArgs[0],
Douglas Gregora8e02e72009-07-28 23:00:59 +0000483 TemplateArgs.size());
Douglas Gregore362cea2009-05-10 22:57:19 +0000484 return CommonPtr->InjectedClassNameType;
485}
486
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000487//===----------------------------------------------------------------------===//
488// TemplateTypeParm Allocation/Deallocation Method Implementations
489//===----------------------------------------------------------------------===//
490
491TemplateTypeParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000492TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000493 SourceLocation KeyLoc, SourceLocation NameLoc,
494 unsigned D, unsigned P, IdentifierInfo *Id,
495 bool Typename, bool ParameterPack) {
Chandler Carruth08836322011-05-01 00:51:33 +0000496 TemplateTypeParmDecl *TTPDecl =
Richard Smithf7981722013-11-22 09:01:48 +0000497 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
Chandler Carruth08836322011-05-01 00:51:33 +0000498 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
Richard Smith5b21db82014-04-23 18:20:42 +0000499 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
Chandler Carruth08836322011-05-01 00:51:33 +0000500 return TTPDecl;
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000501}
502
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000503TemplateTypeParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000504TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000505 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
506 SourceLocation(), nullptr, false);
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000507}
508
John McCall0ad16662009-10-29 08:12:44 +0000509SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara23485e02011-03-04 12:42:03 +0000510 return hasDefaultArgument()
Richard Smith1469b912015-06-10 00:29:03 +0000511 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
512 : SourceLocation();
Abramo Bagnara23485e02011-03-04 12:42:03 +0000513}
514
515SourceRange TemplateTypeParmDecl::getSourceRange() const {
516 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000517 return SourceRange(getLocStart(),
Richard Smith1469b912015-06-10 00:29:03 +0000518 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
Abramo Bagnara23485e02011-03-04 12:42:03 +0000519 else
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000520 return TypeDecl::getSourceRange();
John McCall0ad16662009-10-29 08:12:44 +0000521}
522
Douglas Gregor21610382009-10-29 00:04:11 +0000523unsigned TemplateTypeParmDecl::getDepth() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000524 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
Douglas Gregor21610382009-10-29 00:04:11 +0000525}
526
527unsigned TemplateTypeParmDecl::getIndex() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000528 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
Douglas Gregor21610382009-10-29 00:04:11 +0000529}
530
Chandler Carruth08836322011-05-01 00:51:33 +0000531bool TemplateTypeParmDecl::isParameterPack() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000532 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
Chandler Carruth08836322011-05-01 00:51:33 +0000533}
534
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000535//===----------------------------------------------------------------------===//
536// NonTypeTemplateParmDecl Method Implementations
537//===----------------------------------------------------------------------===//
538
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000539NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000540 SourceLocation StartLoc,
541 SourceLocation IdLoc,
542 unsigned D, unsigned P,
543 IdentifierInfo *Id,
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000544 QualType T,
545 TypeSourceInfo *TInfo,
546 const QualType *ExpandedTypes,
547 unsigned NumExpandedTypes,
548 TypeSourceInfo **ExpandedTInfos)
Abramo Bagnaradff19302011-03-08 08:55:46 +0000549 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
Richard Smith1469b912015-06-10 00:29:03 +0000550 TemplateParmPosition(D, P), ParameterPack(true),
551 ExpandedParameterPack(true), NumExpandedTypes(NumExpandedTypes) {
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000552 if (ExpandedTypes && ExpandedTInfos) {
James Y Knight7a22b242015-08-06 20:26:32 +0000553 auto TypesAndInfos =
554 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000555 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
James Y Knight7a22b242015-08-06 20:26:32 +0000556 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
557 TypesAndInfos[I].second = ExpandedTInfos[I];
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000558 }
559 }
560}
561
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000562NonTypeTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000563NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000564 SourceLocation StartLoc, SourceLocation IdLoc,
565 unsigned D, unsigned P, IdentifierInfo *Id,
566 QualType T, bool ParameterPack,
567 TypeSourceInfo *TInfo) {
Richard Smithf7981722013-11-22 09:01:48 +0000568 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
569 T, ParameterPack, TInfo);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000570}
571
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000572NonTypeTemplateParmDecl *
573NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000574 SourceLocation StartLoc, SourceLocation IdLoc,
575 unsigned D, unsigned P,
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000576 IdentifierInfo *Id, QualType T,
577 TypeSourceInfo *TInfo,
578 const QualType *ExpandedTypes,
579 unsigned NumExpandedTypes,
580 TypeSourceInfo **ExpandedTInfos) {
James Y Knight7a22b242015-08-06 20:26:32 +0000581 return new (C, DC,
582 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
583 NumExpandedTypes))
584 NonTypeTemplateParmDecl(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) {
James Y Knight7a22b242015-08-06 20:26:32 +0000598 return new (C, ID,
599 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
600 NumExpandedTypes))
601 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), 0, 0,
602 nullptr, QualType(), nullptr, nullptr,
603 NumExpandedTypes, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000604}
605
John McCallf4cd4f92011-02-09 01:13:10 +0000606SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnarae15d5532011-03-04 11:03:48 +0000607 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraea947882011-03-08 16:41:52 +0000608 return SourceRange(getOuterLocStart(),
609 getDefaultArgument()->getSourceRange().getEnd());
610 return DeclaratorDecl::getSourceRange();
John McCallf4cd4f92011-02-09 01:13:10 +0000611}
612
Douglas Gregordba32632009-02-10 19:49:53 +0000613SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara656e3002010-06-09 09:26:05 +0000614 return hasDefaultArgument()
615 ? getDefaultArgument()->getSourceRange().getBegin()
616 : SourceLocation();
Douglas Gregordba32632009-02-10 19:49:53 +0000617}
618
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000619//===----------------------------------------------------------------------===//
620// TemplateTemplateParmDecl Method Implementations
621//===----------------------------------------------------------------------===//
622
David Blaikie68e081d2011-12-20 02:48:34 +0000623void TemplateTemplateParmDecl::anchor() { }
624
Richard Smith1fde8ec2012-09-07 02:06:42 +0000625TemplateTemplateParmDecl::TemplateTemplateParmDecl(
626 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
627 IdentifierInfo *Id, TemplateParameterList *Params,
628 unsigned NumExpansions, TemplateParameterList * const *Expansions)
629 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
Richard Smith1469b912015-06-10 00:29:03 +0000630 TemplateParmPosition(D, P), ParameterPack(true),
Richard Smith1fde8ec2012-09-07 02:06:42 +0000631 ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
632 if (Expansions)
James Y Knight7a22b242015-08-06 20:26:32 +0000633 std::uninitialized_copy(Expansions, Expansions + NumExpandedParams,
634 getTrailingObjects<TemplateParameterList *>());
Richard Smith1fde8ec2012-09-07 02:06:42 +0000635}
636
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000637TemplateTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000638TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000639 SourceLocation L, unsigned D, unsigned P,
Douglas Gregorf5500772011-01-05 15:48:55 +0000640 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000641 TemplateParameterList *Params) {
Richard Smithf7981722013-11-22 09:01:48 +0000642 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
643 Params);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000644}
645
Douglas Gregor72172e92012-01-05 21:55:30 +0000646TemplateTemplateParmDecl *
Richard Smith1fde8ec2012-09-07 02:06:42 +0000647TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
648 SourceLocation L, unsigned D, unsigned P,
649 IdentifierInfo *Id,
650 TemplateParameterList *Params,
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000651 ArrayRef<TemplateParameterList *> Expansions) {
James Y Knight7a22b242015-08-06 20:26:32 +0000652 return new (C, DC,
653 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
654 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions.size(),
655 Expansions.data());
Richard Smith1fde8ec2012-09-07 02:06:42 +0000656}
657
658TemplateTemplateParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000659TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000660 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
661 false, nullptr, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000662}
663
Richard Smith1fde8ec2012-09-07 02:06:42 +0000664TemplateTemplateParmDecl *
665TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
666 unsigned NumExpansions) {
James Y Knight7a22b242015-08-06 20:26:32 +0000667 return new (C, ID,
668 additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
Craig Topper36250ad2014-05-12 05:36:57 +0000669 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
670 nullptr, NumExpansions, nullptr);
Richard Smith1fde8ec2012-09-07 02:06:42 +0000671}
672
Richard Smith35c1df52015-06-17 20:16:32 +0000673SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
674 return hasDefaultArgument() ? getDefaultArgument().getLocation()
675 : SourceLocation();
676}
677
Richard Smith1469b912015-06-10 00:29:03 +0000678void TemplateTemplateParmDecl::setDefaultArgument(
679 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
680 if (DefArg.getArgument().isNull())
681 DefaultArgument.set(nullptr);
682 else
683 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
684}
685
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000686//===----------------------------------------------------------------------===//
Douglas Gregord002c7b2009-05-11 23:53:27 +0000687// TemplateArgumentList Implementation
688//===----------------------------------------------------------------------===//
James Y Knight7a22b242015-08-06 20:26:32 +0000689TemplateArgumentList::TemplateArgumentList(const TemplateArgument *Args,
690 unsigned NumArgs)
691 : Arguments(getTrailingObjects<TemplateArgument>()), NumArguments(NumArgs) {
692 std::uninitialized_copy(Args, Args + NumArgs,
693 getTrailingObjects<TemplateArgument>());
694}
695
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000696TemplateArgumentList *
697TemplateArgumentList::CreateCopy(ASTContext &Context,
698 const TemplateArgument *Args,
699 unsigned NumArgs) {
James Y Knight7a22b242015-08-06 20:26:32 +0000700 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(NumArgs));
701 return new (Mem) TemplateArgumentList(Args, NumArgs);
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000702}
703
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000704FunctionTemplateSpecializationInfo *
705FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
706 FunctionTemplateDecl *Template,
707 TemplateSpecializationKind TSK,
708 const TemplateArgumentList *TemplateArgs,
709 const TemplateArgumentListInfo *TemplateArgsAsWritten,
710 SourceLocation POI) {
Craig Topper36250ad2014-05-12 05:36:57 +0000711 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000712 if (TemplateArgsAsWritten)
713 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
714 *TemplateArgsAsWritten);
715
716 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
717 TemplateArgs,
718 ArgsAsWritten,
719 POI);
720}
721
Douglas Gregord002c7b2009-05-11 23:53:27 +0000722//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000723// TemplateDecl Implementation
724//===----------------------------------------------------------------------===//
725
726void TemplateDecl::anchor() { }
727
728//===----------------------------------------------------------------------===//
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000729// ClassTemplateSpecializationDecl Implementation
730//===----------------------------------------------------------------------===//
731ClassTemplateSpecializationDecl::
Douglas Gregore9029562010-05-06 00:28:52 +0000732ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000733 DeclContext *DC, SourceLocation StartLoc,
734 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000735 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000736 const TemplateArgument *Args,
737 unsigned NumArgs,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000738 ClassTemplateSpecializationDecl *PrevDecl)
Richard Smith053f6c62014-05-16 23:01:30 +0000739 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000740 SpecializedTemplate->getIdentifier(),
741 PrevDecl),
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000742 SpecializedTemplate(SpecializedTemplate),
Craig Topper36250ad2014-05-12 05:36:57 +0000743 ExplicitInfo(nullptr),
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000744 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
Douglas Gregord002c7b2009-05-11 23:53:27 +0000745 SpecializationKind(TSK_Undeclared) {
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000746}
Mike Stump11289f42009-09-09 15:08:12 +0000747
Richard Smith053f6c62014-05-16 23:01:30 +0000748ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
749 Kind DK)
750 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
751 SourceLocation(), nullptr, nullptr),
752 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000753
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000754ClassTemplateSpecializationDecl *
Douglas Gregore9029562010-05-06 00:28:52 +0000755ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000756 DeclContext *DC,
757 SourceLocation StartLoc,
758 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000759 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000760 const TemplateArgument *Args,
761 unsigned NumArgs,
Douglas Gregor67a65642009-02-17 23:15:12 +0000762 ClassTemplateSpecializationDecl *PrevDecl) {
Richard Smithf7981722013-11-22 09:01:48 +0000763 ClassTemplateSpecializationDecl *Result =
764 new (Context, DC) ClassTemplateSpecializationDecl(
765 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
766 SpecializedTemplate, Args, NumArgs, PrevDecl);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000767 Result->MayHaveOutOfDateDef = false;
768
Douglas Gregor67a65642009-02-17 23:15:12 +0000769 Context.getTypeDeclType(Result, PrevDecl);
770 return Result;
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000771}
Douglas Gregor2373c592009-05-31 09:31:02 +0000772
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000773ClassTemplateSpecializationDecl *
Richard Smithf7981722013-11-22 09:01:48 +0000774ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000775 unsigned ID) {
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000776 ClassTemplateSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000777 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000778 Result->MayHaveOutOfDateDef = false;
779 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000780}
781
Benjamin Kramer9170e912013-02-22 15:46:01 +0000782void ClassTemplateSpecializationDecl::getNameForDiagnostic(
783 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
784 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000785
786 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Benjamin Kramer9170e912013-02-22 15:46:01 +0000787 TemplateSpecializationType::PrintTemplateArgumentList(
788 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000789}
790
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000791ClassTemplateDecl *
Mike Stump11289f42009-09-09 15:08:12 +0000792ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
793 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000794 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
795 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
796 return SpecializedTemplate.get<ClassTemplateDecl*>();
797}
798
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000799SourceRange
800ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000801 if (ExplicitInfo) {
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000802 SourceLocation Begin = getTemplateKeywordLoc();
803 if (Begin.isValid()) {
804 // Here we have an explicit (partial) specialization or instantiation.
805 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
806 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
807 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
808 if (getExternLoc().isValid())
809 Begin = getExternLoc();
810 SourceLocation End = getRBraceLoc();
811 if (End.isInvalid())
812 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
813 return SourceRange(Begin, End);
814 }
815 // An implicit instantiation of a class template partial specialization
816 // uses ExplicitInfo to record the TypeAsWritten, but the source
817 // locations should be retrieved from the instantiation pattern.
818 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
819 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
820 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
Craig Topper36250ad2014-05-12 05:36:57 +0000821 assert(inst_from != nullptr);
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000822 return inst_from->getSourceRange();
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000823 }
824 else {
825 // No explicit info available.
826 llvm::PointerUnion<ClassTemplateDecl *,
827 ClassTemplatePartialSpecializationDecl *>
828 inst_from = getInstantiatedFrom();
829 if (inst_from.isNull())
830 return getSpecializedTemplate()->getSourceRange();
831 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
832 return ctd->getSourceRange();
833 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
834 ->getSourceRange();
835 }
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000836}
837
Douglas Gregor2373c592009-05-31 09:31:02 +0000838//===----------------------------------------------------------------------===//
839// ClassTemplatePartialSpecializationDecl Implementation
840//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000841void ClassTemplatePartialSpecializationDecl::anchor() { }
842
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000843ClassTemplatePartialSpecializationDecl::
844ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000845 DeclContext *DC,
846 SourceLocation StartLoc,
847 SourceLocation IdLoc,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000848 TemplateParameterList *Params,
849 ClassTemplateDecl *SpecializedTemplate,
850 const TemplateArgument *Args,
851 unsigned NumArgs,
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000852 const ASTTemplateArgumentListInfo *ArgInfos,
Richard Smithb2f61b42013-08-22 23:27:37 +0000853 ClassTemplatePartialSpecializationDecl *PrevDecl)
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000854 : ClassTemplateSpecializationDecl(Context,
855 ClassTemplatePartialSpecialization,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000856 TK, DC, StartLoc, IdLoc,
857 SpecializedTemplate,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000858 Args, NumArgs, PrevDecl),
859 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +0000860 InstantiatedFromMember(nullptr, false)
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000861{
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000862 AdoptTemplateParameterList(Params, this);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000863}
864
Douglas Gregor2373c592009-05-31 09:31:02 +0000865ClassTemplatePartialSpecializationDecl *
866ClassTemplatePartialSpecializationDecl::
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000867Create(ASTContext &Context, TagKind TK,DeclContext *DC,
868 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregor2373c592009-05-31 09:31:02 +0000869 TemplateParameterList *Params,
870 ClassTemplateDecl *SpecializedTemplate,
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000871 const TemplateArgument *Args,
872 unsigned NumArgs,
John McCall6b51f282009-11-23 01:53:49 +0000873 const TemplateArgumentListInfo &ArgInfos,
John McCalle78aac42010-03-10 03:28:59 +0000874 QualType CanonInjectedType,
Richard Smithb2f61b42013-08-22 23:27:37 +0000875 ClassTemplatePartialSpecializationDecl *PrevDecl) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000876 const ASTTemplateArgumentListInfo *ASTArgInfos =
877 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
John McCall0ad16662009-10-29 08:12:44 +0000878
Richard Smithf7981722013-11-22 09:01:48 +0000879 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
880 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
881 Params, SpecializedTemplate, Args,
882 NumArgs, ASTArgInfos, PrevDecl);
Douglas Gregor2373c592009-05-31 09:31:02 +0000883 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000884 Result->MayHaveOutOfDateDef = false;
John McCalle78aac42010-03-10 03:28:59 +0000885
886 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregor2373c592009-05-31 09:31:02 +0000887 return Result;
888}
John McCall11083da2009-09-16 22:47:08 +0000889
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000890ClassTemplatePartialSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000891ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
892 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000893 ClassTemplatePartialSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000894 new (C, ID) ClassTemplatePartialSpecializationDecl(C);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000895 Result->MayHaveOutOfDateDef = false;
896 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000897}
898
John McCall11083da2009-09-16 22:47:08 +0000899//===----------------------------------------------------------------------===//
900// FriendTemplateDecl Implementation
901//===----------------------------------------------------------------------===//
902
David Blaikie68e081d2011-12-20 02:48:34 +0000903void FriendTemplateDecl::anchor() { }
904
John McCall11083da2009-09-16 22:47:08 +0000905FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
906 DeclContext *DC,
907 SourceLocation L,
908 unsigned NParams,
909 TemplateParameterList **Params,
910 FriendUnion Friend,
911 SourceLocation FLoc) {
Richard Smithf7981722013-11-22 09:01:48 +0000912 return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params,
913 Friend, FLoc);
John McCall11083da2009-09-16 22:47:08 +0000914}
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000915
Douglas Gregor72172e92012-01-05 21:55:30 +0000916FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
917 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000918 return new (C, ID) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000919}
Richard Smith3f1b5d02011-05-05 21:57:07 +0000920
921//===----------------------------------------------------------------------===//
922// TypeAliasTemplateDecl Implementation
923//===----------------------------------------------------------------------===//
924
925TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
926 DeclContext *DC,
927 SourceLocation L,
928 DeclarationName Name,
929 TemplateParameterList *Params,
930 NamedDecl *Decl) {
931 AdoptTemplateParameterList(Params, DC);
Richard Smith053f6c62014-05-16 23:01:30 +0000932 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000933}
934
Douglas Gregor72172e92012-01-05 21:55:30 +0000935TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
936 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000937 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000938 DeclarationName(), nullptr, nullptr);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000939}
940
941void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
942 static_cast<Common *>(Ptr)->~Common();
943}
944RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000945TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3f1b5d02011-05-05 21:57:07 +0000946 Common *CommonPtr = new (C) Common;
947 C.AddDeallocation(DeallocateCommon, CommonPtr);
948 return CommonPtr;
949}
950
David Blaikie68e081d2011-12-20 02:48:34 +0000951//===----------------------------------------------------------------------===//
952// ClassScopeFunctionSpecializationDecl Implementation
953//===----------------------------------------------------------------------===//
954
955void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor72172e92012-01-05 21:55:30 +0000956
957ClassScopeFunctionSpecializationDecl *
958ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
959 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000960 return new (C, ID) ClassScopeFunctionSpecializationDecl(
Craig Topper36250ad2014-05-12 05:36:57 +0000961 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
Douglas Gregor72172e92012-01-05 21:55:30 +0000962}
Larisse Voufo39a1e502013-08-06 01:03:05 +0000963
964//===----------------------------------------------------------------------===//
965// VarTemplateDecl Implementation
966//===----------------------------------------------------------------------===//
967
968void VarTemplateDecl::DeallocateCommon(void *Ptr) {
969 static_cast<Common *>(Ptr)->~Common();
970}
971
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000972VarTemplateDecl *VarTemplateDecl::getDefinition() {
973 VarTemplateDecl *CurD = this;
974 while (CurD) {
975 if (CurD->isThisDeclarationADefinition())
976 return CurD;
977 CurD = CurD->getPreviousDecl();
978 }
Craig Topper36250ad2014-05-12 05:36:57 +0000979 return nullptr;
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000980}
981
Larisse Voufo39a1e502013-08-06 01:03:05 +0000982VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
983 SourceLocation L, DeclarationName Name,
984 TemplateParameterList *Params,
Richard Smithbeef3452014-01-16 23:39:20 +0000985 VarDecl *Decl) {
Richard Smith053f6c62014-05-16 23:01:30 +0000986 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000987}
988
989VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
990 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000991 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
992 DeclarationName(), nullptr, nullptr);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000993}
994
Alp Tokerf6a24ce2013-12-05 16:25:25 +0000995// TODO: Unify across class, function and variable templates?
Larisse Voufo30616382013-08-23 22:21:36 +0000996// May require moving this and Common to RedeclarableTemplateDecl.
Larisse Voufo39a1e502013-08-06 01:03:05 +0000997void VarTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000998 // Grab the most recent declaration to ensure we've loaded any lazy
999 // redeclarations of this template.
1000 //
1001 // FIXME: Avoid walking the entire redeclaration chain here.
1002 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Larisse Voufo39a1e502013-08-06 01:03:05 +00001003 if (CommonPtr->LazySpecializations) {
1004 ASTContext &Context = getASTContext();
1005 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +00001006 CommonPtr->LazySpecializations = nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +00001007 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
1008 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
1009 }
1010}
1011
1012llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1013VarTemplateDecl::getSpecializations() const {
1014 LoadLazySpecializations();
1015 return getCommonPtr()->Specializations;
1016}
1017
1018llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1019VarTemplateDecl::getPartialSpecializations() {
1020 LoadLazySpecializations();
1021 return getCommonPtr()->PartialSpecializations;
1022}
1023
1024RedeclarableTemplateDecl::CommonBase *
1025VarTemplateDecl::newCommon(ASTContext &C) const {
1026 Common *CommonPtr = new (C) Common;
1027 C.AddDeallocation(DeallocateCommon, CommonPtr);
1028 return CommonPtr;
1029}
1030
1031VarTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +00001032VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1033 void *&InsertPos) {
1034 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001035}
1036
1037void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1038 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +00001039 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001040}
1041
1042VarTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +00001043VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1044 void *&InsertPos) {
1045 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001046}
1047
1048void VarTemplateDecl::AddPartialSpecialization(
1049 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1050 if (InsertPos)
1051 getPartialSpecializations().InsertNode(D, InsertPos);
1052 else {
1053 VarTemplatePartialSpecializationDecl *Existing =
1054 getPartialSpecializations().GetOrInsertNode(D);
1055 (void)Existing;
1056 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1057 }
1058
1059 if (ASTMutationListener *L = getASTMutationListener())
1060 L->AddedCXXTemplateSpecialization(this, D);
1061}
1062
1063void VarTemplateDecl::getPartialSpecializations(
1064 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1065 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1066 getPartialSpecializations();
1067 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +00001068 PS.reserve(PartialSpecs.size());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001069 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1070 P = PartialSpecs.begin(),
1071 PEnd = PartialSpecs.end();
Richard Smithb2f61b42013-08-22 23:27:37 +00001072 P != PEnd; ++P)
1073 PS.push_back(P->getMostRecentDecl());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001074}
1075
1076VarTemplatePartialSpecializationDecl *
1077VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1078 VarTemplatePartialSpecializationDecl *D) {
1079 Decl *DCanon = D->getCanonicalDecl();
1080 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1081 P = getPartialSpecializations().begin(),
1082 PEnd = getPartialSpecializations().end();
1083 P != PEnd; ++P) {
1084 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1085 return P->getMostRecentDecl();
1086 }
1087
Craig Topper36250ad2014-05-12 05:36:57 +00001088 return nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +00001089}
1090
1091//===----------------------------------------------------------------------===//
1092// VarTemplateSpecializationDecl Implementation
1093//===----------------------------------------------------------------------===//
1094VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001095 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001096 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1097 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1098 unsigned NumArgs)
Richard Smith053f6c62014-05-16 23:01:30 +00001099 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1100 SpecializedTemplate->getIdentifier(), T, TInfo, S),
Craig Topper36250ad2014-05-12 05:36:57 +00001101 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001102 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
1103 SpecializationKind(TSK_Undeclared) {}
1104
Richard Smith053f6c62014-05-16 23:01:30 +00001105VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1106 ASTContext &C)
1107 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
Craig Topper36250ad2014-05-12 05:36:57 +00001108 QualType(), nullptr, SC_None),
1109 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Larisse Voufo39a1e502013-08-06 01:03:05 +00001110
1111VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1112 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1113 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1114 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1115 unsigned NumArgs) {
Richard Smithf7981722013-11-22 09:01:48 +00001116 return new (Context, DC) VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001117 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
Richard Smithf7981722013-11-22 09:01:48 +00001118 SpecializedTemplate, T, TInfo, S, Args, NumArgs);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001119}
1120
1121VarTemplateSpecializationDecl *
1122VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001123 return new (C, ID)
1124 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001125}
1126
1127void VarTemplateSpecializationDecl::getNameForDiagnostic(
1128 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1129 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1130
1131 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1132 TemplateSpecializationType::PrintTemplateArgumentList(
1133 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
1134}
1135
1136VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1137 if (SpecializedPartialSpecialization *PartialSpec =
1138 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1139 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1140 return SpecializedTemplate.get<VarTemplateDecl *>();
1141}
1142
1143void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1144 const TemplateArgumentListInfo &ArgsInfo) {
1145 unsigned N = ArgsInfo.size();
1146 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1147 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1148 for (unsigned I = 0; I != N; ++I)
1149 TemplateArgsInfo.addArgument(ArgsInfo[I]);
1150}
1151
1152//===----------------------------------------------------------------------===//
1153// VarTemplatePartialSpecializationDecl Implementation
1154//===----------------------------------------------------------------------===//
1155void VarTemplatePartialSpecializationDecl::anchor() {}
1156
1157VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1158 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1159 SourceLocation IdLoc, TemplateParameterList *Params,
1160 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1161 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
Richard Smithb2f61b42013-08-22 23:27:37 +00001162 const ASTTemplateArgumentListInfo *ArgInfos)
Richard Smith053f6c62014-05-16 23:01:30 +00001163 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001164 DC, StartLoc, IdLoc, SpecializedTemplate, T,
1165 TInfo, S, Args, NumArgs),
1166 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +00001167 InstantiatedFromMember(nullptr, false) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001168 // TODO: The template parameters should be in DC by now. Verify.
1169 // AdoptTemplateParameterList(Params, DC);
1170}
1171
1172VarTemplatePartialSpecializationDecl *
1173VarTemplatePartialSpecializationDecl::Create(
1174 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1175 SourceLocation IdLoc, TemplateParameterList *Params,
1176 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1177 StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
Richard Smithb2f61b42013-08-22 23:27:37 +00001178 const TemplateArgumentListInfo &ArgInfos) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +00001179 const ASTTemplateArgumentListInfo *ASTArgInfos
1180 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001181
1182 VarTemplatePartialSpecializationDecl *Result =
Richard Smithf7981722013-11-22 09:01:48 +00001183 new (Context, DC) VarTemplatePartialSpecializationDecl(
Larisse Voufo39a1e502013-08-06 01:03:05 +00001184 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
Richard Smithb2f61b42013-08-22 23:27:37 +00001185 S, Args, NumArgs, ASTArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001186 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1187 return Result;
1188}
1189
1190VarTemplatePartialSpecializationDecl *
1191VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1192 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001193 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001194}
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001195
1196static TemplateParameterList *
1197createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1198 // typename T
1199 auto *T = TemplateTypeParmDecl::Create(
1200 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1201 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1202 T->setImplicit(true);
1203
1204 // T ...Ints
1205 TypeSourceInfo *TI =
1206 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1207 auto *N = NonTypeTemplateParmDecl::Create(
1208 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1209 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1210 N->setImplicit(true);
1211
1212 // <typename T, T ...Ints>
1213 NamedDecl *P[2] = {T, N};
1214 auto *TPL = TemplateParameterList::Create(
1215 C, SourceLocation(), SourceLocation(), P, 2, SourceLocation());
1216
1217 // template <typename T, ...Ints> class IntSeq
1218 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1219 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1220 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1221 TemplateTemplateParm->setImplicit(true);
1222
1223 // typename T
1224 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1225 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1226 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1227 TemplateTypeParm->setImplicit(true);
1228
1229 // T N
1230 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1231 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1232 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1233 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1234 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1235 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1236 NonTypeTemplateParm};
1237
1238 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1239 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1240 Params, 3, SourceLocation());
1241}
1242
1243static TemplateParameterList *createBuiltinTemplateParameterList(
1244 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1245 switch (BTK) {
1246 case BTK__make_integer_seq:
1247 return createMakeIntegerSeqParameterList(C, DC);
1248 }
1249
1250 llvm_unreachable("unhandled BuiltinTemplateKind!");
1251}
1252
1253void BuiltinTemplateDecl::anchor() {}
1254
1255BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1256 DeclarationName Name,
1257 BuiltinTemplateKind BTK)
1258 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1259 createBuiltinTemplateParameterList(C, DC, BTK)),
1260 BTK(BTK) {}