blob: bcc8878eeae72e791d52c814671dae373ad1e641 [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,
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000034 SourceLocation RAngleLoc,
35 Expr *RequiresClause)
Douglas Gregorcd72ba92009-02-06 22:42:48 +000036 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000037 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
38 HasRequiresClause(static_cast<bool>(RequiresClause)) {
Richard Smith1fde8ec2012-09-07 02:06:42 +000039 assert(this->NumParams == NumParams && "Too many template parameters");
40 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
41 NamedDecl *P = Params[Idx];
42 begin()[Idx] = P;
43
44 if (!P->isTemplateParameterPack()) {
45 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
46 if (NTTP->getType()->containsUnexpandedParameterPack())
47 ContainsUnexpandedParameterPack = true;
48
49 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
50 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
51 ContainsUnexpandedParameterPack = true;
52
53 // FIXME: If a default argument contains an unexpanded parameter pack, the
54 // template parameter list does too.
55 }
56 }
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000057 if (RequiresClause) {
58 *getTrailingObjects<Expr *>() = RequiresClause;
59 }
Douglas Gregorded2d7b2009-02-04 19:02:06 +000060}
61
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000062TemplateParameterList *
63TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
64 SourceLocation LAngleLoc,
65 ArrayRef<NamedDecl *> Params,
66 SourceLocation RAngleLoc, Expr *RequiresClause) {
67 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
68 Params.size(), RequiresClause ? 1u : 0u),
James Y Knight7a22b242015-08-06 20:26:32 +000069 llvm::alignOf<TemplateParameterList>());
Mike Stump11289f42009-09-09 15:08:12 +000070 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000071 RAngleLoc, RequiresClause);
Douglas Gregorded2d7b2009-02-04 19:02:06 +000072}
73
Douglas Gregorf8f86832009-02-11 18:16:40 +000074unsigned TemplateParameterList::getMinRequiredArguments() const {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000075 unsigned NumRequiredArgs = 0;
David Majnemerdfecf1a2016-07-06 04:19:16 +000076 for (const NamedDecl *P : asArray()) {
77 if (P->isTemplateParameterPack()) {
78 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
Douglas Gregor0231d8d2011-01-19 20:10:05 +000079 if (NTTP->isExpandedParameterPack()) {
80 NumRequiredArgs += NTTP->getNumExpansionTypes();
81 continue;
82 }
David Majnemerdfecf1a2016-07-06 04:19:16 +000083
Douglas Gregorf8f86832009-02-11 18:16:40 +000084 break;
Douglas Gregor0231d8d2011-01-19 20:10:05 +000085 }
David Majnemerdfecf1a2016-07-06 04:19:16 +000086
87 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000088 if (TTP->hasDefaultArgument())
89 break;
David Majnemerdfecf1a2016-07-06 04:19:16 +000090 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000091 if (NTTP->hasDefaultArgument())
92 break;
David Majnemerdfecf1a2016-07-06 04:19:16 +000093 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
Douglas Gregor0231d8d2011-01-19 20:10:05 +000094 break;
David Majnemerdfecf1a2016-07-06 04:19:16 +000095
Douglas Gregor0231d8d2011-01-19 20:10:05 +000096 ++NumRequiredArgs;
Douglas Gregorf8f86832009-02-11 18:16:40 +000097 }
David Majnemerdfecf1a2016-07-06 04:19:16 +000098
Douglas Gregorf8f86832009-02-11 18:16:40 +000099 return NumRequiredArgs;
100}
101
Douglas Gregor21610382009-10-29 00:04:11 +0000102unsigned TemplateParameterList::getDepth() const {
103 if (size() == 0)
104 return 0;
105
106 const NamedDecl *FirstParm = getParam(0);
107 if (const TemplateTypeParmDecl *TTP
108 = dyn_cast<TemplateTypeParmDecl>(FirstParm))
109 return TTP->getDepth();
110 else if (const NonTypeTemplateParmDecl *NTTP
111 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
112 return NTTP->getDepth();
113 else
114 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
115}
116
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000117static void AdoptTemplateParameterList(TemplateParameterList *Params,
118 DeclContext *Owner) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000119 for (NamedDecl *P : *Params) {
120 P->setDeclContext(Owner);
121
122 if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000123 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
124 }
125}
126
Richard Smithe7bd6de2015-06-10 20:30:23 +0000127namespace clang {
128void *allocateDefaultArgStorageChain(const ASTContext &C) {
129 return new (C) char[sizeof(void*) * 2];
130}
131}
132
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000133//===----------------------------------------------------------------------===//
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000134// RedeclarableTemplateDecl Implementation
135//===----------------------------------------------------------------------===//
136
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000137RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000138 if (Common)
139 return Common;
140
141 // Walk the previous-declaration chain until we either find a declaration
142 // with a common pointer or we run out of previous declarations.
143 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
144 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
145 Prev = Prev->getPreviousDecl()) {
146 if (Prev->Common) {
147 Common = Prev->Common;
148 break;
Douglas Gregor68444de2012-01-14 15:13:49 +0000149 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000150
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000151 PrevDecls.push_back(Prev);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000152 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000153
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000154 // If we never found a common pointer, allocate one now.
155 if (!Common) {
156 // FIXME: If any of the declarations is from an AST file, we probably
157 // need an update record to add the common data.
158
159 Common = newCommon(getASTContext());
160 }
161
162 // Update any previous declarations we saw with the common pointer.
David Majnemerdfecf1a2016-07-06 04:19:16 +0000163 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
164 Prev->Common = Common;
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000165
Douglas Gregor68444de2012-01-14 15:13:49 +0000166 return Common;
Peter Collingbourne029fd692010-07-29 16:12:09 +0000167}
168
Richard Smithe977e512015-02-24 01:23:23 +0000169template<class EntryType>
170typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000171RedeclarableTemplateDecl::findSpecializationImpl(
Richard Smithe977e512015-02-24 01:23:23 +0000172 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
173 void *&InsertPos) {
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000174 typedef SpecEntryTraits<EntryType> SETraits;
175 llvm::FoldingSetNodeID ID;
Craig Topper7e0daca2014-06-26 04:58:53 +0000176 EntryType::Profile(ID,Args, getASTContext());
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000177 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
Richard Smithe977e512015-02-24 01:23:23 +0000178 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
179}
180
181template<class Derived, class EntryType>
182void RedeclarableTemplateDecl::addSpecializationImpl(
183 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
184 void *InsertPos) {
185 typedef SpecEntryTraits<EntryType> SETraits;
186 if (InsertPos) {
187#ifndef NDEBUG
188 void *CorrectInsertPos;
189 assert(!findSpecializationImpl(Specializations,
190 SETraits::getTemplateArgs(Entry),
191 CorrectInsertPos) &&
192 InsertPos == CorrectInsertPos &&
193 "given incorrect InsertPos for specialization");
194#endif
195 Specializations.InsertNode(Entry, InsertPos);
196 } else {
197 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
198 (void)Existing;
199 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
200 "non-canonical specialization?");
201 }
202
203 if (ASTMutationListener *L = getASTMutationListener())
204 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
205 SETraits::getDecl(Entry));
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000206}
207
Douglas Gregor43669f82011-03-05 17:54:25 +0000208/// \brief Generate the injected template arguments for the given template
209/// parameter list, e.g., for the injected-class-name of a class template.
210static void GenerateInjectedTemplateArgs(ASTContext &Context,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000211 TemplateParameterList *Params,
Douglas Gregor43669f82011-03-05 17:54:25 +0000212 TemplateArgument *Args) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000213 for (NamedDecl *Param : *Params) {
Douglas Gregor43669f82011-03-05 17:54:25 +0000214 TemplateArgument Arg;
David Majnemerdfecf1a2016-07-06 04:19:16 +0000215 if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
Douglas Gregor43669f82011-03-05 17:54:25 +0000216 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);
David Majnemerdfecf1a2016-07-06 04:19:16 +0000221 } else if (auto *NTTP = 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());
David Majnemerdfecf1a2016-07-06 04:19:16 +0000226
Douglas Gregor43669f82011-03-05 17:54:25 +0000227 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 {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000232 auto *TTP = cast<TemplateTemplateParmDecl>(Param);
Douglas Gregor43669f82011-03-05 17:54:25 +0000233 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 }
David Majnemerdfecf1a2016-07-06 04:19:16 +0000238
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}
David Majnemerdfecf1a2016-07-06 04:19:16 +0000245
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());
David Majnemerdfecf1a2016-07-06 04:19:16 +0000424 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
425 PS.push_back(P.getMostRecentDecl());
Douglas Gregor407e9612010-04-30 05:56:50 +0000426}
427
Douglas Gregor15301382009-07-30 17:40:51 +0000428ClassTemplatePartialSpecializationDecl *
429ClassTemplateDecl::findPartialSpecialization(QualType T) {
430 ASTContext &Context = getASTContext();
David Majnemerdfecf1a2016-07-06 04:19:16 +0000431 for (ClassTemplatePartialSpecializationDecl &P :
432 getPartialSpecializations()) {
433 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
434 return P.getMostRecentDecl();
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000435 }
436
Craig Topper36250ad2014-05-12 05:36:57 +0000437 return nullptr;
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000438}
439
440ClassTemplatePartialSpecializationDecl *
441ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
442 ClassTemplatePartialSpecializationDecl *D) {
443 Decl *DCanon = D->getCanonicalDecl();
David Majnemerdfecf1a2016-07-06 04:19:16 +0000444 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
445 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
446 return P.getMostRecentDecl();
Douglas Gregor15301382009-07-30 17:40:51 +0000447 }
Mike Stump11289f42009-09-09 15:08:12 +0000448
Craig Topper36250ad2014-05-12 05:36:57 +0000449 return nullptr;
Douglas Gregor15301382009-07-30 17:40:51 +0000450}
451
John McCalle78aac42010-03-10 03:28:59 +0000452QualType
Douglas Gregor9961ce92010-07-08 18:37:38 +0000453ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000454 Common *CommonPtr = getCommonPtr();
Douglas Gregore362cea2009-05-10 22:57:19 +0000455 if (!CommonPtr->InjectedClassNameType.isNull())
456 return CommonPtr->InjectedClassNameType;
457
Douglas Gregor8092e802010-12-23 16:00:30 +0000458 // C++0x [temp.dep.type]p2:
459 // The template argument list of a primary template is a template argument
460 // list in which the nth template argument has the value of the nth template
461 // parameter of the class template. If the nth template parameter is a
462 // template parameter pack (14.5.3), the nth template argument is a pack
463 // expansion (14.5.3) whose pattern is the name of the template parameter
464 // pack.
Douglas Gregor9961ce92010-07-08 18:37:38 +0000465 ASTContext &Context = getASTContext();
Douglas Gregore362cea2009-05-10 22:57:19 +0000466 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000467 SmallVector<TemplateArgument, 16> TemplateArgs;
Douglas Gregor43669f82011-03-05 17:54:25 +0000468 TemplateArgs.resize(Params->size());
469 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
Douglas Gregore362cea2009-05-10 22:57:19 +0000470 CommonPtr->InjectedClassNameType
Douglas Gregora8e02e72009-07-28 23:00:59 +0000471 = Context.getTemplateSpecializationType(TemplateName(this),
David Majnemer6fbeee32016-07-07 04:43:07 +0000472 TemplateArgs);
Douglas Gregore362cea2009-05-10 22:57:19 +0000473 return CommonPtr->InjectedClassNameType;
474}
475
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000476//===----------------------------------------------------------------------===//
477// TemplateTypeParm Allocation/Deallocation Method Implementations
478//===----------------------------------------------------------------------===//
479
480TemplateTypeParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000481TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000482 SourceLocation KeyLoc, SourceLocation NameLoc,
483 unsigned D, unsigned P, IdentifierInfo *Id,
484 bool Typename, bool ParameterPack) {
Chandler Carruth08836322011-05-01 00:51:33 +0000485 TemplateTypeParmDecl *TTPDecl =
Richard Smithf7981722013-11-22 09:01:48 +0000486 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
Chandler Carruth08836322011-05-01 00:51:33 +0000487 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
Richard Smith5b21db82014-04-23 18:20:42 +0000488 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
Chandler Carruth08836322011-05-01 00:51:33 +0000489 return TTPDecl;
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000490}
491
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000492TemplateTypeParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000493TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000494 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
495 SourceLocation(), nullptr, false);
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000496}
497
John McCall0ad16662009-10-29 08:12:44 +0000498SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara23485e02011-03-04 12:42:03 +0000499 return hasDefaultArgument()
Richard Smith1469b912015-06-10 00:29:03 +0000500 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
501 : SourceLocation();
Abramo Bagnara23485e02011-03-04 12:42:03 +0000502}
503
504SourceRange TemplateTypeParmDecl::getSourceRange() const {
505 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000506 return SourceRange(getLocStart(),
Richard Smith1469b912015-06-10 00:29:03 +0000507 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
Abramo Bagnara23485e02011-03-04 12:42:03 +0000508 else
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000509 return TypeDecl::getSourceRange();
John McCall0ad16662009-10-29 08:12:44 +0000510}
511
Douglas Gregor21610382009-10-29 00:04:11 +0000512unsigned TemplateTypeParmDecl::getDepth() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000513 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
Douglas Gregor21610382009-10-29 00:04:11 +0000514}
515
516unsigned TemplateTypeParmDecl::getIndex() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000517 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
Douglas Gregor21610382009-10-29 00:04:11 +0000518}
519
Chandler Carruth08836322011-05-01 00:51:33 +0000520bool TemplateTypeParmDecl::isParameterPack() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000521 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
Chandler Carruth08836322011-05-01 00:51:33 +0000522}
523
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000524//===----------------------------------------------------------------------===//
525// NonTypeTemplateParmDecl Method Implementations
526//===----------------------------------------------------------------------===//
527
David Majnemerdfecf1a2016-07-06 04:19:16 +0000528NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
529 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
530 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
531 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
532 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
533 TemplateParmPosition(D, P), ParameterPack(true),
534 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
535 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
James Y Knight7a22b242015-08-06 20:26:32 +0000536 auto TypesAndInfos =
537 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000538 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
James Y Knight7a22b242015-08-06 20:26:32 +0000539 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
540 TypesAndInfos[I].second = ExpandedTInfos[I];
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000541 }
542 }
543}
544
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000545NonTypeTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000546NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000547 SourceLocation StartLoc, SourceLocation IdLoc,
548 unsigned D, unsigned P, IdentifierInfo *Id,
549 QualType T, bool ParameterPack,
550 TypeSourceInfo *TInfo) {
Richard Smithf7981722013-11-22 09:01:48 +0000551 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
552 T, ParameterPack, TInfo);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000553}
554
David Majnemerdfecf1a2016-07-06 04:19:16 +0000555NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
556 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
557 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
558 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
559 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
James Y Knight7a22b242015-08-06 20:26:32 +0000560 return new (C, DC,
561 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
David Majnemerdfecf1a2016-07-06 04:19:16 +0000562 ExpandedTypes.size()))
James Y Knight7a22b242015-08-06 20:26:32 +0000563 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000564 ExpandedTypes, ExpandedTInfos);
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000565}
566
Douglas Gregor72172e92012-01-05 21:55:30 +0000567NonTypeTemplateParmDecl *
568NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000569 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
570 SourceLocation(), 0, 0, nullptr,
571 QualType(), false, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000572}
573
574NonTypeTemplateParmDecl *
575NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
576 unsigned NumExpandedTypes) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000577 auto *NTTP =
578 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
579 NumExpandedTypes))
580 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
581 0, 0, nullptr, QualType(), nullptr, None,
582 None);
583 NTTP->NumExpandedTypes = NumExpandedTypes;
584 return NTTP;
Douglas Gregor72172e92012-01-05 21:55:30 +0000585}
586
John McCallf4cd4f92011-02-09 01:13:10 +0000587SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnarae15d5532011-03-04 11:03:48 +0000588 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraea947882011-03-08 16:41:52 +0000589 return SourceRange(getOuterLocStart(),
590 getDefaultArgument()->getSourceRange().getEnd());
591 return DeclaratorDecl::getSourceRange();
John McCallf4cd4f92011-02-09 01:13:10 +0000592}
593
Douglas Gregordba32632009-02-10 19:49:53 +0000594SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara656e3002010-06-09 09:26:05 +0000595 return hasDefaultArgument()
596 ? getDefaultArgument()->getSourceRange().getBegin()
597 : SourceLocation();
Douglas Gregordba32632009-02-10 19:49:53 +0000598}
599
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000600//===----------------------------------------------------------------------===//
601// TemplateTemplateParmDecl Method Implementations
602//===----------------------------------------------------------------------===//
603
David Blaikie68e081d2011-12-20 02:48:34 +0000604void TemplateTemplateParmDecl::anchor() { }
605
Richard Smith1fde8ec2012-09-07 02:06:42 +0000606TemplateTemplateParmDecl::TemplateTemplateParmDecl(
607 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
608 IdentifierInfo *Id, TemplateParameterList *Params,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000609 ArrayRef<TemplateParameterList *> Expansions)
610 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
611 TemplateParmPosition(D, P), ParameterPack(true),
612 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
613 if (!Expansions.empty())
614 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
James Y Knight7a22b242015-08-06 20:26:32 +0000615 getTrailingObjects<TemplateParameterList *>());
Richard Smith1fde8ec2012-09-07 02:06:42 +0000616}
617
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000618TemplateTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000619TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000620 SourceLocation L, unsigned D, unsigned P,
Douglas Gregorf5500772011-01-05 15:48:55 +0000621 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000622 TemplateParameterList *Params) {
Richard Smithf7981722013-11-22 09:01:48 +0000623 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
624 Params);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000625}
626
Douglas Gregor72172e92012-01-05 21:55:30 +0000627TemplateTemplateParmDecl *
Richard Smith1fde8ec2012-09-07 02:06:42 +0000628TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
629 SourceLocation L, unsigned D, unsigned P,
630 IdentifierInfo *Id,
631 TemplateParameterList *Params,
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000632 ArrayRef<TemplateParameterList *> Expansions) {
James Y Knight7a22b242015-08-06 20:26:32 +0000633 return new (C, DC,
634 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
David Majnemerdfecf1a2016-07-06 04:19:16 +0000635 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
Richard Smith1fde8ec2012-09-07 02:06:42 +0000636}
637
638TemplateTemplateParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000639TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000640 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
641 false, nullptr, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000642}
643
Richard Smith1fde8ec2012-09-07 02:06:42 +0000644TemplateTemplateParmDecl *
645TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
646 unsigned NumExpansions) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000647 auto *TTP =
648 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
649 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
650 nullptr, None);
651 TTP->NumExpandedParams = NumExpansions;
652 return TTP;
Richard Smith1fde8ec2012-09-07 02:06:42 +0000653}
654
Richard Smith35c1df52015-06-17 20:16:32 +0000655SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
656 return hasDefaultArgument() ? getDefaultArgument().getLocation()
657 : SourceLocation();
658}
659
Richard Smith1469b912015-06-10 00:29:03 +0000660void TemplateTemplateParmDecl::setDefaultArgument(
661 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
662 if (DefArg.getArgument().isNull())
663 DefaultArgument.set(nullptr);
664 else
665 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
666}
667
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000668//===----------------------------------------------------------------------===//
Douglas Gregord002c7b2009-05-11 23:53:27 +0000669// TemplateArgumentList Implementation
670//===----------------------------------------------------------------------===//
David Majnemer8b622692016-07-03 21:17:51 +0000671TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
672 : Arguments(getTrailingObjects<TemplateArgument>()),
673 NumArguments(Args.size()) {
674 std::uninitialized_copy(Args.begin(), Args.end(),
James Y Knight7a22b242015-08-06 20:26:32 +0000675 getTrailingObjects<TemplateArgument>());
676}
677
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000678TemplateArgumentList *
679TemplateArgumentList::CreateCopy(ASTContext &Context,
David Majnemer8b622692016-07-03 21:17:51 +0000680 ArrayRef<TemplateArgument> Args) {
681 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
682 return new (Mem) TemplateArgumentList(Args);
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000683}
684
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000685FunctionTemplateSpecializationInfo *
686FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
687 FunctionTemplateDecl *Template,
688 TemplateSpecializationKind TSK,
689 const TemplateArgumentList *TemplateArgs,
690 const TemplateArgumentListInfo *TemplateArgsAsWritten,
691 SourceLocation POI) {
Craig Topper36250ad2014-05-12 05:36:57 +0000692 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000693 if (TemplateArgsAsWritten)
694 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
695 *TemplateArgsAsWritten);
696
697 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
698 TemplateArgs,
699 ArgsAsWritten,
700 POI);
701}
702
Douglas Gregord002c7b2009-05-11 23:53:27 +0000703//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000704// TemplateDecl Implementation
705//===----------------------------------------------------------------------===//
706
707void TemplateDecl::anchor() { }
708
709//===----------------------------------------------------------------------===//
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000710// ClassTemplateSpecializationDecl Implementation
711//===----------------------------------------------------------------------===//
712ClassTemplateSpecializationDecl::
Douglas Gregore9029562010-05-06 00:28:52 +0000713ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000714 DeclContext *DC, SourceLocation StartLoc,
715 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000716 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000717 ArrayRef<TemplateArgument> Args,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000718 ClassTemplateSpecializationDecl *PrevDecl)
Richard Smith053f6c62014-05-16 23:01:30 +0000719 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000720 SpecializedTemplate->getIdentifier(),
721 PrevDecl),
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000722 SpecializedTemplate(SpecializedTemplate),
Craig Topper36250ad2014-05-12 05:36:57 +0000723 ExplicitInfo(nullptr),
David Majnemer8b622692016-07-03 21:17:51 +0000724 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
Douglas Gregord002c7b2009-05-11 23:53:27 +0000725 SpecializationKind(TSK_Undeclared) {
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000726}
Mike Stump11289f42009-09-09 15:08:12 +0000727
Richard Smith053f6c62014-05-16 23:01:30 +0000728ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
729 Kind DK)
730 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
731 SourceLocation(), nullptr, nullptr),
732 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000733
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000734ClassTemplateSpecializationDecl *
Douglas Gregore9029562010-05-06 00:28:52 +0000735ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000736 DeclContext *DC,
737 SourceLocation StartLoc,
738 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000739 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000740 ArrayRef<TemplateArgument> Args,
Douglas Gregor67a65642009-02-17 23:15:12 +0000741 ClassTemplateSpecializationDecl *PrevDecl) {
Richard Smithf7981722013-11-22 09:01:48 +0000742 ClassTemplateSpecializationDecl *Result =
743 new (Context, DC) ClassTemplateSpecializationDecl(
744 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
David Majnemer8b622692016-07-03 21:17:51 +0000745 SpecializedTemplate, Args, PrevDecl);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000746 Result->MayHaveOutOfDateDef = false;
747
Douglas Gregor67a65642009-02-17 23:15:12 +0000748 Context.getTypeDeclType(Result, PrevDecl);
749 return Result;
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000750}
Douglas Gregor2373c592009-05-31 09:31:02 +0000751
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000752ClassTemplateSpecializationDecl *
Richard Smithf7981722013-11-22 09:01:48 +0000753ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000754 unsigned ID) {
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000755 ClassTemplateSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000756 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000757 Result->MayHaveOutOfDateDef = false;
758 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000759}
760
Benjamin Kramer9170e912013-02-22 15:46:01 +0000761void ClassTemplateSpecializationDecl::getNameForDiagnostic(
762 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
763 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000764
765 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Benjamin Kramer9170e912013-02-22 15:46:01 +0000766 TemplateSpecializationType::PrintTemplateArgumentList(
David Majnemer6fbeee32016-07-07 04:43:07 +0000767 OS, TemplateArgs.asArray(), Policy);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000768}
769
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000770ClassTemplateDecl *
Mike Stump11289f42009-09-09 15:08:12 +0000771ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
772 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000773 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
774 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
775 return SpecializedTemplate.get<ClassTemplateDecl*>();
776}
777
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000778SourceRange
779ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000780 if (ExplicitInfo) {
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000781 SourceLocation Begin = getTemplateKeywordLoc();
782 if (Begin.isValid()) {
783 // Here we have an explicit (partial) specialization or instantiation.
784 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
785 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
786 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
787 if (getExternLoc().isValid())
788 Begin = getExternLoc();
Argyrios Kyrtzidisd798c052016-07-15 18:11:33 +0000789 SourceLocation End = getBraceRange().getEnd();
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000790 if (End.isInvalid())
791 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
792 return SourceRange(Begin, End);
793 }
794 // An implicit instantiation of a class template partial specialization
795 // uses ExplicitInfo to record the TypeAsWritten, but the source
796 // locations should be retrieved from the instantiation pattern.
797 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
798 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
799 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
Craig Topper36250ad2014-05-12 05:36:57 +0000800 assert(inst_from != nullptr);
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000801 return inst_from->getSourceRange();
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000802 }
803 else {
804 // No explicit info available.
805 llvm::PointerUnion<ClassTemplateDecl *,
806 ClassTemplatePartialSpecializationDecl *>
807 inst_from = getInstantiatedFrom();
808 if (inst_from.isNull())
809 return getSpecializedTemplate()->getSourceRange();
810 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
811 return ctd->getSourceRange();
812 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
813 ->getSourceRange();
814 }
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000815}
816
Douglas Gregor2373c592009-05-31 09:31:02 +0000817//===----------------------------------------------------------------------===//
818// ClassTemplatePartialSpecializationDecl Implementation
819//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000820void ClassTemplatePartialSpecializationDecl::anchor() { }
821
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000822ClassTemplatePartialSpecializationDecl::
823ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000824 DeclContext *DC,
825 SourceLocation StartLoc,
826 SourceLocation IdLoc,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000827 TemplateParameterList *Params,
828 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000829 ArrayRef<TemplateArgument> Args,
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000830 const ASTTemplateArgumentListInfo *ArgInfos,
Richard Smithb2f61b42013-08-22 23:27:37 +0000831 ClassTemplatePartialSpecializationDecl *PrevDecl)
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000832 : ClassTemplateSpecializationDecl(Context,
833 ClassTemplatePartialSpecialization,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000834 TK, DC, StartLoc, IdLoc,
835 SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000836 Args, PrevDecl),
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000837 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +0000838 InstantiatedFromMember(nullptr, false)
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000839{
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000840 AdoptTemplateParameterList(Params, this);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000841}
842
Douglas Gregor2373c592009-05-31 09:31:02 +0000843ClassTemplatePartialSpecializationDecl *
844ClassTemplatePartialSpecializationDecl::
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000845Create(ASTContext &Context, TagKind TK,DeclContext *DC,
846 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregor2373c592009-05-31 09:31:02 +0000847 TemplateParameterList *Params,
848 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000849 ArrayRef<TemplateArgument> Args,
John McCall6b51f282009-11-23 01:53:49 +0000850 const TemplateArgumentListInfo &ArgInfos,
John McCalle78aac42010-03-10 03:28:59 +0000851 QualType CanonInjectedType,
Richard Smithb2f61b42013-08-22 23:27:37 +0000852 ClassTemplatePartialSpecializationDecl *PrevDecl) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000853 const ASTTemplateArgumentListInfo *ASTArgInfos =
854 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
John McCall0ad16662009-10-29 08:12:44 +0000855
Richard Smithf7981722013-11-22 09:01:48 +0000856 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
857 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
858 Params, SpecializedTemplate, Args,
David Majnemer8b622692016-07-03 21:17:51 +0000859 ASTArgInfos, PrevDecl);
Douglas Gregor2373c592009-05-31 09:31:02 +0000860 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000861 Result->MayHaveOutOfDateDef = false;
John McCalle78aac42010-03-10 03:28:59 +0000862
863 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregor2373c592009-05-31 09:31:02 +0000864 return Result;
865}
John McCall11083da2009-09-16 22:47:08 +0000866
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000867ClassTemplatePartialSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000868ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
869 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000870 ClassTemplatePartialSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000871 new (C, ID) ClassTemplatePartialSpecializationDecl(C);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000872 Result->MayHaveOutOfDateDef = false;
873 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000874}
875
John McCall11083da2009-09-16 22:47:08 +0000876//===----------------------------------------------------------------------===//
877// FriendTemplateDecl Implementation
878//===----------------------------------------------------------------------===//
879
David Blaikie68e081d2011-12-20 02:48:34 +0000880void FriendTemplateDecl::anchor() { }
881
David Majnemerdfecf1a2016-07-06 04:19:16 +0000882FriendTemplateDecl *
883FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
884 SourceLocation L,
885 MutableArrayRef<TemplateParameterList *> Params,
886 FriendUnion Friend, SourceLocation FLoc) {
887 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
John McCall11083da2009-09-16 22:47:08 +0000888}
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000889
Douglas Gregor72172e92012-01-05 21:55:30 +0000890FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
891 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000892 return new (C, ID) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000893}
Richard Smith3f1b5d02011-05-05 21:57:07 +0000894
895//===----------------------------------------------------------------------===//
896// TypeAliasTemplateDecl Implementation
897//===----------------------------------------------------------------------===//
898
899TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
900 DeclContext *DC,
901 SourceLocation L,
902 DeclarationName Name,
903 TemplateParameterList *Params,
904 NamedDecl *Decl) {
905 AdoptTemplateParameterList(Params, DC);
Richard Smith053f6c62014-05-16 23:01:30 +0000906 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000907}
908
Douglas Gregor72172e92012-01-05 21:55:30 +0000909TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
910 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000911 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000912 DeclarationName(), nullptr, nullptr);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000913}
914
915void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
916 static_cast<Common *>(Ptr)->~Common();
917}
918RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000919TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3f1b5d02011-05-05 21:57:07 +0000920 Common *CommonPtr = new (C) Common;
921 C.AddDeallocation(DeallocateCommon, CommonPtr);
922 return CommonPtr;
923}
924
David Blaikie68e081d2011-12-20 02:48:34 +0000925//===----------------------------------------------------------------------===//
926// ClassScopeFunctionSpecializationDecl Implementation
927//===----------------------------------------------------------------------===//
928
929void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor72172e92012-01-05 21:55:30 +0000930
931ClassScopeFunctionSpecializationDecl *
932ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
933 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000934 return new (C, ID) ClassScopeFunctionSpecializationDecl(
Craig Topper36250ad2014-05-12 05:36:57 +0000935 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
Douglas Gregor72172e92012-01-05 21:55:30 +0000936}
Larisse Voufo39a1e502013-08-06 01:03:05 +0000937
938//===----------------------------------------------------------------------===//
939// VarTemplateDecl Implementation
940//===----------------------------------------------------------------------===//
941
942void VarTemplateDecl::DeallocateCommon(void *Ptr) {
943 static_cast<Common *>(Ptr)->~Common();
944}
945
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000946VarTemplateDecl *VarTemplateDecl::getDefinition() {
947 VarTemplateDecl *CurD = this;
948 while (CurD) {
949 if (CurD->isThisDeclarationADefinition())
950 return CurD;
951 CurD = CurD->getPreviousDecl();
952 }
Craig Topper36250ad2014-05-12 05:36:57 +0000953 return nullptr;
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000954}
955
Larisse Voufo39a1e502013-08-06 01:03:05 +0000956VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
957 SourceLocation L, DeclarationName Name,
958 TemplateParameterList *Params,
Richard Smithbeef3452014-01-16 23:39:20 +0000959 VarDecl *Decl) {
Richard Smith053f6c62014-05-16 23:01:30 +0000960 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000961}
962
963VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
964 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000965 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
966 DeclarationName(), nullptr, nullptr);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000967}
968
Alp Tokerf6a24ce2013-12-05 16:25:25 +0000969// TODO: Unify across class, function and variable templates?
Larisse Voufo30616382013-08-23 22:21:36 +0000970// May require moving this and Common to RedeclarableTemplateDecl.
Larisse Voufo39a1e502013-08-06 01:03:05 +0000971void VarTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000972 // Grab the most recent declaration to ensure we've loaded any lazy
973 // redeclarations of this template.
974 //
975 // FIXME: Avoid walking the entire redeclaration chain here.
976 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Larisse Voufo39a1e502013-08-06 01:03:05 +0000977 if (CommonPtr->LazySpecializations) {
978 ASTContext &Context = getASTContext();
979 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000980 CommonPtr->LazySpecializations = nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +0000981 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
982 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
983 }
984}
985
986llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
987VarTemplateDecl::getSpecializations() const {
988 LoadLazySpecializations();
989 return getCommonPtr()->Specializations;
990}
991
992llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
993VarTemplateDecl::getPartialSpecializations() {
994 LoadLazySpecializations();
995 return getCommonPtr()->PartialSpecializations;
996}
997
998RedeclarableTemplateDecl::CommonBase *
999VarTemplateDecl::newCommon(ASTContext &C) const {
1000 Common *CommonPtr = new (C) Common;
1001 C.AddDeallocation(DeallocateCommon, CommonPtr);
1002 return CommonPtr;
1003}
1004
1005VarTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +00001006VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1007 void *&InsertPos) {
1008 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001009}
1010
1011void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1012 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +00001013 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001014}
1015
1016VarTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +00001017VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1018 void *&InsertPos) {
1019 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001020}
1021
1022void VarTemplateDecl::AddPartialSpecialization(
1023 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1024 if (InsertPos)
1025 getPartialSpecializations().InsertNode(D, InsertPos);
1026 else {
1027 VarTemplatePartialSpecializationDecl *Existing =
1028 getPartialSpecializations().GetOrInsertNode(D);
1029 (void)Existing;
1030 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1031 }
1032
1033 if (ASTMutationListener *L = getASTMutationListener())
1034 L->AddedCXXTemplateSpecialization(this, D);
1035}
1036
1037void VarTemplateDecl::getPartialSpecializations(
1038 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1039 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1040 getPartialSpecializations();
1041 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +00001042 PS.reserve(PartialSpecs.size());
David Majnemerdfecf1a2016-07-06 04:19:16 +00001043 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1044 PS.push_back(P.getMostRecentDecl());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001045}
1046
1047VarTemplatePartialSpecializationDecl *
1048VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1049 VarTemplatePartialSpecializationDecl *D) {
1050 Decl *DCanon = D->getCanonicalDecl();
David Majnemerdfecf1a2016-07-06 04:19:16 +00001051 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1052 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1053 return P.getMostRecentDecl();
Larisse Voufo39a1e502013-08-06 01:03:05 +00001054 }
1055
Craig Topper36250ad2014-05-12 05:36:57 +00001056 return nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +00001057}
1058
1059//===----------------------------------------------------------------------===//
1060// VarTemplateSpecializationDecl Implementation
1061//===----------------------------------------------------------------------===//
1062VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001063 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001064 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
David Majnemer8b622692016-07-03 21:17:51 +00001065 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
Richard Smith053f6c62014-05-16 23:01:30 +00001066 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1067 SpecializedTemplate->getIdentifier(), T, TInfo, S),
Craig Topper36250ad2014-05-12 05:36:57 +00001068 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
David Majnemer8b622692016-07-03 21:17:51 +00001069 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001070 SpecializationKind(TSK_Undeclared) {}
1071
Richard Smith053f6c62014-05-16 23:01:30 +00001072VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1073 ASTContext &C)
1074 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
Craig Topper36250ad2014-05-12 05:36:57 +00001075 QualType(), nullptr, SC_None),
1076 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Larisse Voufo39a1e502013-08-06 01:03:05 +00001077
1078VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1079 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1080 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
David Majnemer8b622692016-07-03 21:17:51 +00001081 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
Richard Smithf7981722013-11-22 09:01:48 +00001082 return new (Context, DC) VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001083 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
David Majnemer8b622692016-07-03 21:17:51 +00001084 SpecializedTemplate, T, TInfo, S, Args);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001085}
1086
1087VarTemplateSpecializationDecl *
1088VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001089 return new (C, ID)
1090 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001091}
1092
1093void VarTemplateSpecializationDecl::getNameForDiagnostic(
1094 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1095 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1096
1097 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1098 TemplateSpecializationType::PrintTemplateArgumentList(
David Majnemer6fbeee32016-07-07 04:43:07 +00001099 OS, TemplateArgs.asArray(), Policy);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001100}
1101
1102VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1103 if (SpecializedPartialSpecialization *PartialSpec =
1104 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1105 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1106 return SpecializedTemplate.get<VarTemplateDecl *>();
1107}
1108
1109void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1110 const TemplateArgumentListInfo &ArgsInfo) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001111 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1112 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
David Majnemerdfecf1a2016-07-06 04:19:16 +00001113 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1114 TemplateArgsInfo.addArgument(Loc);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001115}
1116
1117//===----------------------------------------------------------------------===//
1118// VarTemplatePartialSpecializationDecl Implementation
1119//===----------------------------------------------------------------------===//
1120void VarTemplatePartialSpecializationDecl::anchor() {}
1121
1122VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1123 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1124 SourceLocation IdLoc, TemplateParameterList *Params,
1125 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001126 StorageClass S, ArrayRef<TemplateArgument> Args,
Richard Smithb2f61b42013-08-22 23:27:37 +00001127 const ASTTemplateArgumentListInfo *ArgInfos)
Richard Smith053f6c62014-05-16 23:01:30 +00001128 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001129 DC, StartLoc, IdLoc, SpecializedTemplate, T,
David Majnemer8b622692016-07-03 21:17:51 +00001130 TInfo, S, Args),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001131 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +00001132 InstantiatedFromMember(nullptr, false) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001133 // TODO: The template parameters should be in DC by now. Verify.
1134 // AdoptTemplateParameterList(Params, DC);
1135}
1136
1137VarTemplatePartialSpecializationDecl *
1138VarTemplatePartialSpecializationDecl::Create(
1139 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1140 SourceLocation IdLoc, TemplateParameterList *Params,
1141 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001142 StorageClass S, ArrayRef<TemplateArgument> Args,
Richard Smithb2f61b42013-08-22 23:27:37 +00001143 const TemplateArgumentListInfo &ArgInfos) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +00001144 const ASTTemplateArgumentListInfo *ASTArgInfos
1145 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001146
1147 VarTemplatePartialSpecializationDecl *Result =
Richard Smithf7981722013-11-22 09:01:48 +00001148 new (Context, DC) VarTemplatePartialSpecializationDecl(
Larisse Voufo39a1e502013-08-06 01:03:05 +00001149 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001150 S, Args, ASTArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001151 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1152 return Result;
1153}
1154
1155VarTemplatePartialSpecializationDecl *
1156VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1157 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001158 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001159}
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001160
1161static TemplateParameterList *
1162createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1163 // typename T
1164 auto *T = TemplateTypeParmDecl::Create(
1165 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1166 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1167 T->setImplicit(true);
1168
1169 // T ...Ints
1170 TypeSourceInfo *TI =
1171 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1172 auto *N = NonTypeTemplateParmDecl::Create(
1173 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1174 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1175 N->setImplicit(true);
1176
1177 // <typename T, T ...Ints>
1178 NamedDecl *P[2] = {T, N};
1179 auto *TPL = TemplateParameterList::Create(
Hubert Tonge4a0c0e2016-07-30 22:33:34 +00001180 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001181
1182 // template <typename T, ...Ints> class IntSeq
1183 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1184 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1185 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1186 TemplateTemplateParm->setImplicit(true);
1187
1188 // typename T
1189 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1190 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1191 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1192 TemplateTypeParm->setImplicit(true);
1193
1194 // T N
1195 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1196 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1197 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1198 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1199 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1200 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1201 NonTypeTemplateParm};
1202
1203 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1204 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
Hubert Tonge4a0c0e2016-07-30 22:33:34 +00001205 Params, SourceLocation(), nullptr);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001206}
1207
Eric Fiselier6ad68552016-07-01 01:24:09 +00001208static TemplateParameterList *
1209createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1210 // std::size_t Index
1211 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1212 auto *Index = NonTypeTemplateParmDecl::Create(
1213 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1214 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1215
1216 // typename ...T
1217 auto *Ts = TemplateTypeParmDecl::Create(
1218 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1219 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1220 Ts->setImplicit(true);
1221
1222 // template <std::size_t Index, typename ...T>
1223 NamedDecl *Params[] = {Index, Ts};
1224 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1225 llvm::makeArrayRef(Params),
Hubert Tonge4a0c0e2016-07-30 22:33:34 +00001226 SourceLocation(), nullptr);
Eric Fiselier6ad68552016-07-01 01:24:09 +00001227}
1228
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001229static TemplateParameterList *createBuiltinTemplateParameterList(
1230 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1231 switch (BTK) {
1232 case BTK__make_integer_seq:
1233 return createMakeIntegerSeqParameterList(C, DC);
Eric Fiselier6ad68552016-07-01 01:24:09 +00001234 case BTK__type_pack_element:
1235 return createTypePackElementParameterList(C, DC);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001236 }
1237
1238 llvm_unreachable("unhandled BuiltinTemplateKind!");
1239}
1240
1241void BuiltinTemplateDecl::anchor() {}
1242
1243BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1244 DeclarationName Name,
1245 BuiltinTemplateKind BTK)
1246 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1247 createBuiltinTemplateParameterList(C, DC, BTK)),
1248 BTK(BTK) {}