blob: 8e3b783a53a71532224de4e552f8452ba9aed079 [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 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
40 NamedDecl *P = Params[Idx];
41 begin()[Idx] = P;
42
43 if (!P->isTemplateParameterPack()) {
44 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
45 if (NTTP->getType()->containsUnexpandedParameterPack())
46 ContainsUnexpandedParameterPack = true;
47
48 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
49 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
50 ContainsUnexpandedParameterPack = true;
51
52 // FIXME: If a default argument contains an unexpanded parameter pack, the
53 // template parameter list does too.
54 }
55 }
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000056 if (RequiresClause) {
57 *getTrailingObjects<Expr *>() = RequiresClause;
58 }
Douglas Gregorded2d7b2009-02-04 19:02:06 +000059}
60
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000061TemplateParameterList *
62TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
63 SourceLocation LAngleLoc,
64 ArrayRef<NamedDecl *> Params,
65 SourceLocation RAngleLoc, Expr *RequiresClause) {
66 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
67 Params.size(), RequiresClause ? 1u : 0u),
Benjamin Kramerc3f89252016-10-20 14:27:22 +000068 alignof(TemplateParameterList));
Mike Stump11289f42009-09-09 15:08:12 +000069 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000070 RAngleLoc, RequiresClause);
Douglas Gregorded2d7b2009-02-04 19:02:06 +000071}
72
Douglas Gregorf8f86832009-02-11 18:16:40 +000073unsigned TemplateParameterList::getMinRequiredArguments() const {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000074 unsigned NumRequiredArgs = 0;
David Majnemerdfecf1a2016-07-06 04:19:16 +000075 for (const NamedDecl *P : asArray()) {
76 if (P->isTemplateParameterPack()) {
77 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
Douglas Gregor0231d8d2011-01-19 20:10:05 +000078 if (NTTP->isExpandedParameterPack()) {
79 NumRequiredArgs += NTTP->getNumExpansionTypes();
80 continue;
81 }
David Majnemerdfecf1a2016-07-06 04:19:16 +000082
Douglas Gregorf8f86832009-02-11 18:16:40 +000083 break;
Douglas Gregor0231d8d2011-01-19 20:10:05 +000084 }
David Majnemerdfecf1a2016-07-06 04:19:16 +000085
86 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000087 if (TTP->hasDefaultArgument())
88 break;
David Majnemerdfecf1a2016-07-06 04:19:16 +000089 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000090 if (NTTP->hasDefaultArgument())
91 break;
David Majnemerdfecf1a2016-07-06 04:19:16 +000092 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
Douglas Gregor0231d8d2011-01-19 20:10:05 +000093 break;
David Majnemerdfecf1a2016-07-06 04:19:16 +000094
Douglas Gregor0231d8d2011-01-19 20:10:05 +000095 ++NumRequiredArgs;
Douglas Gregorf8f86832009-02-11 18:16:40 +000096 }
David Majnemerdfecf1a2016-07-06 04:19:16 +000097
Douglas Gregorf8f86832009-02-11 18:16:40 +000098 return NumRequiredArgs;
99}
100
Douglas Gregor21610382009-10-29 00:04:11 +0000101unsigned TemplateParameterList::getDepth() const {
102 if (size() == 0)
103 return 0;
104
105 const NamedDecl *FirstParm = getParam(0);
106 if (const TemplateTypeParmDecl *TTP
107 = dyn_cast<TemplateTypeParmDecl>(FirstParm))
108 return TTP->getDepth();
109 else if (const NonTypeTemplateParmDecl *NTTP
110 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
111 return NTTP->getDepth();
112 else
113 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
114}
115
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000116static void AdoptTemplateParameterList(TemplateParameterList *Params,
117 DeclContext *Owner) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000118 for (NamedDecl *P : *Params) {
119 P->setDeclContext(Owner);
120
121 if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000122 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
123 }
124}
125
Richard Smithe7bd6de2015-06-10 20:30:23 +0000126namespace clang {
127void *allocateDefaultArgStorageChain(const ASTContext &C) {
128 return new (C) char[sizeof(void*) * 2];
129}
130}
131
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000132//===----------------------------------------------------------------------===//
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000133// RedeclarableTemplateDecl Implementation
134//===----------------------------------------------------------------------===//
135
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000136RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000137 if (Common)
138 return Common;
139
140 // Walk the previous-declaration chain until we either find a declaration
141 // with a common pointer or we run out of previous declarations.
142 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
143 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
144 Prev = Prev->getPreviousDecl()) {
145 if (Prev->Common) {
146 Common = Prev->Common;
147 break;
Douglas Gregor68444de2012-01-14 15:13:49 +0000148 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000149
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000150 PrevDecls.push_back(Prev);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000151 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000152
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000153 // If we never found a common pointer, allocate one now.
154 if (!Common) {
155 // FIXME: If any of the declarations is from an AST file, we probably
156 // need an update record to add the common data.
157
158 Common = newCommon(getASTContext());
159 }
160
161 // Update any previous declarations we saw with the common pointer.
David Majnemerdfecf1a2016-07-06 04:19:16 +0000162 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
163 Prev->Common = Common;
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000164
Douglas Gregor68444de2012-01-14 15:13:49 +0000165 return Common;
Peter Collingbourne029fd692010-07-29 16:12:09 +0000166}
167
Richard Smithe977e512015-02-24 01:23:23 +0000168template<class EntryType>
169typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000170RedeclarableTemplateDecl::findSpecializationImpl(
Richard Smithe977e512015-02-24 01:23:23 +0000171 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
172 void *&InsertPos) {
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000173 typedef SpecEntryTraits<EntryType> SETraits;
174 llvm::FoldingSetNodeID ID;
Craig Topper7e0daca2014-06-26 04:58:53 +0000175 EntryType::Profile(ID,Args, getASTContext());
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000176 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
Richard Smithe977e512015-02-24 01:23:23 +0000177 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
178}
179
180template<class Derived, class EntryType>
181void RedeclarableTemplateDecl::addSpecializationImpl(
182 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
183 void *InsertPos) {
184 typedef SpecEntryTraits<EntryType> SETraits;
185 if (InsertPos) {
186#ifndef NDEBUG
187 void *CorrectInsertPos;
188 assert(!findSpecializationImpl(Specializations,
189 SETraits::getTemplateArgs(Entry),
190 CorrectInsertPos) &&
191 InsertPos == CorrectInsertPos &&
192 "given incorrect InsertPos for specialization");
193#endif
194 Specializations.InsertNode(Entry, InsertPos);
195 } else {
196 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
197 (void)Existing;
198 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
199 "non-canonical specialization?");
200 }
201
202 if (ASTMutationListener *L = getASTMutationListener())
203 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
204 SETraits::getDecl(Entry));
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000205}
206
Douglas Gregor43669f82011-03-05 17:54:25 +0000207/// \brief Generate the injected template arguments for the given template
208/// parameter list, e.g., for the injected-class-name of a class template.
209static void GenerateInjectedTemplateArgs(ASTContext &Context,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000210 TemplateParameterList *Params,
Douglas Gregor43669f82011-03-05 17:54:25 +0000211 TemplateArgument *Args) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000212 for (NamedDecl *Param : *Params) {
Douglas Gregor43669f82011-03-05 17:54:25 +0000213 TemplateArgument Arg;
David Majnemerdfecf1a2016-07-06 04:19:16 +0000214 if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
Douglas Gregor43669f82011-03-05 17:54:25 +0000215 QualType ArgType = Context.getTypeDeclType(TTP);
216 if (TTP->isParameterPack())
David Blaikie7a30dc52013-02-21 01:47:18 +0000217 ArgType = Context.getPackExpansionType(ArgType, None);
David Blaikie05785d12013-02-20 22:23:23 +0000218
Douglas Gregor43669f82011-03-05 17:54:25 +0000219 Arg = TemplateArgument(ArgType);
David Majnemerdfecf1a2016-07-06 04:19:16 +0000220 } else if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
John McCall113bee02012-03-10 09:33:50 +0000221 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
Douglas Gregor43669f82011-03-05 17:54:25 +0000222 NTTP->getType().getNonLValueExprType(Context),
223 Expr::getValueKindForType(NTTP->getType()),
224 NTTP->getLocation());
David Majnemerdfecf1a2016-07-06 04:19:16 +0000225
Douglas Gregor43669f82011-03-05 17:54:25 +0000226 if (NTTP->isParameterPack())
David Blaikie7a30dc52013-02-21 01:47:18 +0000227 E = new (Context) PackExpansionExpr(Context.DependentTy, E,
228 NTTP->getLocation(), None);
Douglas Gregor43669f82011-03-05 17:54:25 +0000229 Arg = TemplateArgument(E);
230 } else {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000231 auto *TTP = cast<TemplateTemplateParmDecl>(Param);
Douglas Gregor43669f82011-03-05 17:54:25 +0000232 if (TTP->isParameterPack())
David Blaikie05785d12013-02-20 22:23:23 +0000233 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
Douglas Gregor43669f82011-03-05 17:54:25 +0000234 else
235 Arg = TemplateArgument(TemplateName(TTP));
236 }
David Majnemerdfecf1a2016-07-06 04:19:16 +0000237
238 if (Param->isTemplateParameterPack())
Benjamin Kramercce63472015-08-05 09:40:22 +0000239 Arg = TemplateArgument::CreatePackCopy(Context, Arg);
240
Douglas Gregor43669f82011-03-05 17:54:25 +0000241 *Args++ = Arg;
242 }
243}
David Majnemerdfecf1a2016-07-06 04:19:16 +0000244
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000245//===----------------------------------------------------------------------===//
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000246// FunctionTemplateDecl Implementation
247//===----------------------------------------------------------------------===//
248
Douglas Gregor1a809332010-05-23 18:26:36 +0000249void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
250 static_cast<Common *>(Ptr)->~Common();
251}
252
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000253FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
254 DeclContext *DC,
255 SourceLocation L,
256 DeclarationName Name,
Douglas Gregor8f5d4422009-06-29 20:59:39 +0000257 TemplateParameterList *Params,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000258 NamedDecl *Decl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000259 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Richard Smith053f6c62014-05-16 23:01:30 +0000260 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000261}
262
Douglas Gregor72172e92012-01-05 21:55:30 +0000263FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
264 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000265 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000266 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000267}
268
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000269RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000270FunctionTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000271 Common *CommonPtr = new (C) Common;
272 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000273 return CommonPtr;
274}
275
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000276void FunctionTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000277 // Grab the most recent declaration to ensure we've loaded any lazy
278 // redeclarations of this template.
279 //
280 // FIXME: Avoid walking the entire redeclaration chain here.
281 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000282 if (CommonPtr->LazySpecializations) {
283 ASTContext &Context = getASTContext();
284 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000285 CommonPtr->LazySpecializations = nullptr;
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000286 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
287 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
288 }
289}
290
291llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
292FunctionTemplateDecl::getSpecializations() const {
293 LoadLazySpecializations();
294 return getCommonPtr()->Specializations;
295}
296
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000297FunctionDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000298FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
299 void *&InsertPos) {
300 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000301}
302
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000303void FunctionTemplateDecl::addSpecialization(
304 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000305 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
306 InsertPos);
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000307}
308
Richard Smith841d8b22013-05-17 03:04:50 +0000309ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
Douglas Gregor43669f82011-03-05 17:54:25 +0000310 TemplateParameterList *Params = getTemplateParameters();
311 Common *CommonPtr = getCommonPtr();
312 if (!CommonPtr->InjectedArgs) {
313 CommonPtr->InjectedArgs
Richard Smith841d8b22013-05-17 03:04:50 +0000314 = new (getASTContext()) TemplateArgument[Params->size()];
315 GenerateInjectedTemplateArgs(getASTContext(), Params,
Douglas Gregor43669f82011-03-05 17:54:25 +0000316 CommonPtr->InjectedArgs);
317 }
Richard Smith841d8b22013-05-17 03:04:50 +0000318
319 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
Douglas Gregor43669f82011-03-05 17:54:25 +0000320}
321
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000322//===----------------------------------------------------------------------===//
323// ClassTemplateDecl Implementation
324//===----------------------------------------------------------------------===//
325
Douglas Gregor1a809332010-05-23 18:26:36 +0000326void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
327 static_cast<Common *>(Ptr)->~Common();
328}
329
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000330ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
331 DeclContext *DC,
332 SourceLocation L,
333 DeclarationName Name,
334 TemplateParameterList *Params,
Douglas Gregor90a1a652009-03-19 17:26:29 +0000335 NamedDecl *Decl,
336 ClassTemplateDecl *PrevDecl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000337 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Richard Smith053f6c62014-05-16 23:01:30 +0000338 ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
339 Params, Decl);
Rafael Espindola8db352d2013-10-17 15:37:26 +0000340 New->setPreviousDecl(PrevDecl);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +0000341 return New;
Douglas Gregor90a1a652009-03-19 17:26:29 +0000342}
343
Richard Smith053f6c62014-05-16 23:01:30 +0000344ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000345 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000346 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
347 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000348}
349
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000350void ClassTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000351 // Grab the most recent declaration to ensure we've loaded any lazy
352 // redeclarations of this template.
353 //
354 // FIXME: Avoid walking the entire redeclaration chain here.
355 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000356 if (CommonPtr->LazySpecializations) {
357 ASTContext &Context = getASTContext();
358 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000359 CommonPtr->LazySpecializations = nullptr;
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000360 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
361 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
362 }
363}
364
Chandler Carruthb41171b2012-05-03 23:49:05 +0000365llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000366ClassTemplateDecl::getSpecializations() const {
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000367 LoadLazySpecializations();
368 return getCommonPtr()->Specializations;
369}
370
Chandler Carruthb41171b2012-05-03 23:49:05 +0000371llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000372ClassTemplateDecl::getPartialSpecializations() {
373 LoadLazySpecializations();
374 return getCommonPtr()->PartialSpecializations;
375}
376
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000377RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000378ClassTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000379 Common *CommonPtr = new (C) Common;
380 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000381 return CommonPtr;
382}
383
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000384ClassTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000385ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
386 void *&InsertPos) {
387 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000388}
389
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000390void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
391 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000392 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000393}
394
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000395ClassTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000396ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000397 void *&InsertPos) {
Craig Topper7e0daca2014-06-26 04:58:53 +0000398 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000399}
400
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000401void ClassTemplateDecl::AddPartialSpecialization(
402 ClassTemplatePartialSpecializationDecl *D,
403 void *InsertPos) {
Douglas Gregorce9978f2012-03-28 14:34:23 +0000404 if (InsertPos)
405 getPartialSpecializations().InsertNode(D, InsertPos);
406 else {
407 ClassTemplatePartialSpecializationDecl *Existing
408 = getPartialSpecializations().GetOrInsertNode(D);
409 (void)Existing;
410 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
411 }
412
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000413 if (ASTMutationListener *L = getASTMutationListener())
414 L->AddedCXXTemplateSpecialization(this, D);
415}
416
Douglas Gregor407e9612010-04-30 05:56:50 +0000417void ClassTemplateDecl::getPartialSpecializations(
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000418 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
Chandler Carruthb41171b2012-05-03 23:49:05 +0000419 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000420 = getPartialSpecializations();
Douglas Gregor407e9612010-04-30 05:56:50 +0000421 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +0000422 PS.reserve(PartialSpecs.size());
David Majnemerdfecf1a2016-07-06 04:19:16 +0000423 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
424 PS.push_back(P.getMostRecentDecl());
Douglas Gregor407e9612010-04-30 05:56:50 +0000425}
426
Douglas Gregor15301382009-07-30 17:40:51 +0000427ClassTemplatePartialSpecializationDecl *
428ClassTemplateDecl::findPartialSpecialization(QualType T) {
429 ASTContext &Context = getASTContext();
David Majnemerdfecf1a2016-07-06 04:19:16 +0000430 for (ClassTemplatePartialSpecializationDecl &P :
431 getPartialSpecializations()) {
432 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
433 return P.getMostRecentDecl();
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000434 }
435
Craig Topper36250ad2014-05-12 05:36:57 +0000436 return nullptr;
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000437}
438
439ClassTemplatePartialSpecializationDecl *
440ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
441 ClassTemplatePartialSpecializationDecl *D) {
442 Decl *DCanon = D->getCanonicalDecl();
David Majnemerdfecf1a2016-07-06 04:19:16 +0000443 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
444 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
445 return P.getMostRecentDecl();
Douglas Gregor15301382009-07-30 17:40:51 +0000446 }
Mike Stump11289f42009-09-09 15:08:12 +0000447
Craig Topper36250ad2014-05-12 05:36:57 +0000448 return nullptr;
Douglas Gregor15301382009-07-30 17:40:51 +0000449}
450
John McCalle78aac42010-03-10 03:28:59 +0000451QualType
Douglas Gregor9961ce92010-07-08 18:37:38 +0000452ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000453 Common *CommonPtr = getCommonPtr();
Douglas Gregore362cea2009-05-10 22:57:19 +0000454 if (!CommonPtr->InjectedClassNameType.isNull())
455 return CommonPtr->InjectedClassNameType;
456
Douglas Gregor8092e802010-12-23 16:00:30 +0000457 // C++0x [temp.dep.type]p2:
458 // The template argument list of a primary template is a template argument
459 // list in which the nth template argument has the value of the nth template
460 // parameter of the class template. If the nth template parameter is a
461 // template parameter pack (14.5.3), the nth template argument is a pack
462 // expansion (14.5.3) whose pattern is the name of the template parameter
463 // pack.
Douglas Gregor9961ce92010-07-08 18:37:38 +0000464 ASTContext &Context = getASTContext();
Douglas Gregore362cea2009-05-10 22:57:19 +0000465 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000466 SmallVector<TemplateArgument, 16> TemplateArgs;
Douglas Gregor43669f82011-03-05 17:54:25 +0000467 TemplateArgs.resize(Params->size());
468 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
Douglas Gregore362cea2009-05-10 22:57:19 +0000469 CommonPtr->InjectedClassNameType
Douglas Gregora8e02e72009-07-28 23:00:59 +0000470 = Context.getTemplateSpecializationType(TemplateName(this),
David Majnemer6fbeee32016-07-07 04:43:07 +0000471 TemplateArgs);
Douglas Gregore362cea2009-05-10 22:57:19 +0000472 return CommonPtr->InjectedClassNameType;
473}
474
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000475//===----------------------------------------------------------------------===//
476// TemplateTypeParm Allocation/Deallocation Method Implementations
477//===----------------------------------------------------------------------===//
478
479TemplateTypeParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000480TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000481 SourceLocation KeyLoc, SourceLocation NameLoc,
482 unsigned D, unsigned P, IdentifierInfo *Id,
483 bool Typename, bool ParameterPack) {
Chandler Carruth08836322011-05-01 00:51:33 +0000484 TemplateTypeParmDecl *TTPDecl =
Richard Smithf7981722013-11-22 09:01:48 +0000485 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
Chandler Carruth08836322011-05-01 00:51:33 +0000486 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
Richard Smith5b21db82014-04-23 18:20:42 +0000487 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
Chandler Carruth08836322011-05-01 00:51:33 +0000488 return TTPDecl;
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000489}
490
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000491TemplateTypeParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000492TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000493 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
494 SourceLocation(), nullptr, false);
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000495}
496
John McCall0ad16662009-10-29 08:12:44 +0000497SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara23485e02011-03-04 12:42:03 +0000498 return hasDefaultArgument()
Richard Smith1469b912015-06-10 00:29:03 +0000499 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
500 : SourceLocation();
Abramo Bagnara23485e02011-03-04 12:42:03 +0000501}
502
503SourceRange TemplateTypeParmDecl::getSourceRange() const {
504 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000505 return SourceRange(getLocStart(),
Richard Smith1469b912015-06-10 00:29:03 +0000506 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
Abramo Bagnara23485e02011-03-04 12:42:03 +0000507 else
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000508 return TypeDecl::getSourceRange();
John McCall0ad16662009-10-29 08:12:44 +0000509}
510
Douglas Gregor21610382009-10-29 00:04:11 +0000511unsigned TemplateTypeParmDecl::getDepth() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000512 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
Douglas Gregor21610382009-10-29 00:04:11 +0000513}
514
515unsigned TemplateTypeParmDecl::getIndex() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000516 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
Douglas Gregor21610382009-10-29 00:04:11 +0000517}
518
Chandler Carruth08836322011-05-01 00:51:33 +0000519bool TemplateTypeParmDecl::isParameterPack() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000520 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
Chandler Carruth08836322011-05-01 00:51:33 +0000521}
522
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000523//===----------------------------------------------------------------------===//
524// NonTypeTemplateParmDecl Method Implementations
525//===----------------------------------------------------------------------===//
526
David Majnemerdfecf1a2016-07-06 04:19:16 +0000527NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
528 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
529 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
530 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
531 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
532 TemplateParmPosition(D, P), ParameterPack(true),
533 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
534 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
James Y Knight7a22b242015-08-06 20:26:32 +0000535 auto TypesAndInfos =
536 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000537 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
James Y Knight7a22b242015-08-06 20:26:32 +0000538 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
539 TypesAndInfos[I].second = ExpandedTInfos[I];
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000540 }
541 }
542}
543
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000544NonTypeTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000545NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000546 SourceLocation StartLoc, SourceLocation IdLoc,
547 unsigned D, unsigned P, IdentifierInfo *Id,
548 QualType T, bool ParameterPack,
549 TypeSourceInfo *TInfo) {
Richard Smithf7981722013-11-22 09:01:48 +0000550 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
551 T, ParameterPack, TInfo);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000552}
553
David Majnemerdfecf1a2016-07-06 04:19:16 +0000554NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
555 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
556 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
557 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
558 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
James Y Knight7a22b242015-08-06 20:26:32 +0000559 return new (C, DC,
560 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
David Majnemerdfecf1a2016-07-06 04:19:16 +0000561 ExpandedTypes.size()))
James Y Knight7a22b242015-08-06 20:26:32 +0000562 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000563 ExpandedTypes, ExpandedTInfos);
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000564}
565
Douglas Gregor72172e92012-01-05 21:55:30 +0000566NonTypeTemplateParmDecl *
567NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000568 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
569 SourceLocation(), 0, 0, nullptr,
570 QualType(), false, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000571}
572
573NonTypeTemplateParmDecl *
574NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
575 unsigned NumExpandedTypes) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000576 auto *NTTP =
577 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
578 NumExpandedTypes))
579 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
580 0, 0, nullptr, QualType(), nullptr, None,
581 None);
582 NTTP->NumExpandedTypes = NumExpandedTypes;
583 return NTTP;
Douglas Gregor72172e92012-01-05 21:55:30 +0000584}
585
John McCallf4cd4f92011-02-09 01:13:10 +0000586SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnarae15d5532011-03-04 11:03:48 +0000587 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraea947882011-03-08 16:41:52 +0000588 return SourceRange(getOuterLocStart(),
589 getDefaultArgument()->getSourceRange().getEnd());
590 return DeclaratorDecl::getSourceRange();
John McCallf4cd4f92011-02-09 01:13:10 +0000591}
592
Douglas Gregordba32632009-02-10 19:49:53 +0000593SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara656e3002010-06-09 09:26:05 +0000594 return hasDefaultArgument()
595 ? getDefaultArgument()->getSourceRange().getBegin()
596 : SourceLocation();
Douglas Gregordba32632009-02-10 19:49:53 +0000597}
598
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000599//===----------------------------------------------------------------------===//
600// TemplateTemplateParmDecl Method Implementations
601//===----------------------------------------------------------------------===//
602
David Blaikie68e081d2011-12-20 02:48:34 +0000603void TemplateTemplateParmDecl::anchor() { }
604
Richard Smith1fde8ec2012-09-07 02:06:42 +0000605TemplateTemplateParmDecl::TemplateTemplateParmDecl(
606 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
607 IdentifierInfo *Id, TemplateParameterList *Params,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000608 ArrayRef<TemplateParameterList *> Expansions)
609 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
610 TemplateParmPosition(D, P), ParameterPack(true),
611 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
612 if (!Expansions.empty())
613 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
James Y Knight7a22b242015-08-06 20:26:32 +0000614 getTrailingObjects<TemplateParameterList *>());
Richard Smith1fde8ec2012-09-07 02:06:42 +0000615}
616
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000617TemplateTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000618TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000619 SourceLocation L, unsigned D, unsigned P,
Douglas Gregorf5500772011-01-05 15:48:55 +0000620 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000621 TemplateParameterList *Params) {
Richard Smithf7981722013-11-22 09:01:48 +0000622 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
623 Params);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000624}
625
Douglas Gregor72172e92012-01-05 21:55:30 +0000626TemplateTemplateParmDecl *
Richard Smith1fde8ec2012-09-07 02:06:42 +0000627TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
628 SourceLocation L, unsigned D, unsigned P,
629 IdentifierInfo *Id,
630 TemplateParameterList *Params,
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000631 ArrayRef<TemplateParameterList *> Expansions) {
James Y Knight7a22b242015-08-06 20:26:32 +0000632 return new (C, DC,
633 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
David Majnemerdfecf1a2016-07-06 04:19:16 +0000634 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
Richard Smith1fde8ec2012-09-07 02:06:42 +0000635}
636
637TemplateTemplateParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000638TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000639 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
640 false, nullptr, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000641}
642
Richard Smith1fde8ec2012-09-07 02:06:42 +0000643TemplateTemplateParmDecl *
644TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
645 unsigned NumExpansions) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000646 auto *TTP =
647 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
648 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
649 nullptr, None);
650 TTP->NumExpandedParams = NumExpansions;
651 return TTP;
Richard Smith1fde8ec2012-09-07 02:06:42 +0000652}
653
Richard Smith35c1df52015-06-17 20:16:32 +0000654SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
655 return hasDefaultArgument() ? getDefaultArgument().getLocation()
656 : SourceLocation();
657}
658
Richard Smith1469b912015-06-10 00:29:03 +0000659void TemplateTemplateParmDecl::setDefaultArgument(
660 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
661 if (DefArg.getArgument().isNull())
662 DefaultArgument.set(nullptr);
663 else
664 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
665}
666
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000667//===----------------------------------------------------------------------===//
Douglas Gregord002c7b2009-05-11 23:53:27 +0000668// TemplateArgumentList Implementation
669//===----------------------------------------------------------------------===//
David Majnemer8b622692016-07-03 21:17:51 +0000670TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
671 : Arguments(getTrailingObjects<TemplateArgument>()),
672 NumArguments(Args.size()) {
673 std::uninitialized_copy(Args.begin(), Args.end(),
James Y Knight7a22b242015-08-06 20:26:32 +0000674 getTrailingObjects<TemplateArgument>());
675}
676
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000677TemplateArgumentList *
678TemplateArgumentList::CreateCopy(ASTContext &Context,
David Majnemer8b622692016-07-03 21:17:51 +0000679 ArrayRef<TemplateArgument> Args) {
680 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
681 return new (Mem) TemplateArgumentList(Args);
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000682}
683
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000684FunctionTemplateSpecializationInfo *
685FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
686 FunctionTemplateDecl *Template,
687 TemplateSpecializationKind TSK,
688 const TemplateArgumentList *TemplateArgs,
689 const TemplateArgumentListInfo *TemplateArgsAsWritten,
690 SourceLocation POI) {
Craig Topper36250ad2014-05-12 05:36:57 +0000691 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000692 if (TemplateArgsAsWritten)
693 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
694 *TemplateArgsAsWritten);
695
696 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
697 TemplateArgs,
698 ArgsAsWritten,
699 POI);
700}
701
Douglas Gregord002c7b2009-05-11 23:53:27 +0000702//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000703// TemplateDecl Implementation
704//===----------------------------------------------------------------------===//
705
706void TemplateDecl::anchor() { }
707
708//===----------------------------------------------------------------------===//
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000709// ClassTemplateSpecializationDecl Implementation
710//===----------------------------------------------------------------------===//
711ClassTemplateSpecializationDecl::
Douglas Gregore9029562010-05-06 00:28:52 +0000712ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000713 DeclContext *DC, SourceLocation StartLoc,
714 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000715 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000716 ArrayRef<TemplateArgument> Args,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000717 ClassTemplateSpecializationDecl *PrevDecl)
Richard Smith053f6c62014-05-16 23:01:30 +0000718 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000719 SpecializedTemplate->getIdentifier(),
720 PrevDecl),
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000721 SpecializedTemplate(SpecializedTemplate),
Craig Topper36250ad2014-05-12 05:36:57 +0000722 ExplicitInfo(nullptr),
David Majnemer8b622692016-07-03 21:17:51 +0000723 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
Douglas Gregord002c7b2009-05-11 23:53:27 +0000724 SpecializationKind(TSK_Undeclared) {
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000725}
Mike Stump11289f42009-09-09 15:08:12 +0000726
Richard Smith053f6c62014-05-16 23:01:30 +0000727ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
728 Kind DK)
729 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
730 SourceLocation(), nullptr, nullptr),
731 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000732
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000733ClassTemplateSpecializationDecl *
Douglas Gregore9029562010-05-06 00:28:52 +0000734ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000735 DeclContext *DC,
736 SourceLocation StartLoc,
737 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000738 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000739 ArrayRef<TemplateArgument> Args,
Douglas Gregor67a65642009-02-17 23:15:12 +0000740 ClassTemplateSpecializationDecl *PrevDecl) {
Richard Smithf7981722013-11-22 09:01:48 +0000741 ClassTemplateSpecializationDecl *Result =
742 new (Context, DC) ClassTemplateSpecializationDecl(
743 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
David Majnemer8b622692016-07-03 21:17:51 +0000744 SpecializedTemplate, Args, PrevDecl);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000745 Result->MayHaveOutOfDateDef = false;
746
Douglas Gregor67a65642009-02-17 23:15:12 +0000747 Context.getTypeDeclType(Result, PrevDecl);
748 return Result;
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000749}
Douglas Gregor2373c592009-05-31 09:31:02 +0000750
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000751ClassTemplateSpecializationDecl *
Richard Smithf7981722013-11-22 09:01:48 +0000752ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000753 unsigned ID) {
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000754 ClassTemplateSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000755 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000756 Result->MayHaveOutOfDateDef = false;
757 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000758}
759
Benjamin Kramer9170e912013-02-22 15:46:01 +0000760void ClassTemplateSpecializationDecl::getNameForDiagnostic(
761 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
762 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000763
764 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Benjamin Kramer9170e912013-02-22 15:46:01 +0000765 TemplateSpecializationType::PrintTemplateArgumentList(
David Majnemer6fbeee32016-07-07 04:43:07 +0000766 OS, TemplateArgs.asArray(), Policy);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000767}
768
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000769ClassTemplateDecl *
Mike Stump11289f42009-09-09 15:08:12 +0000770ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
771 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000772 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
773 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
774 return SpecializedTemplate.get<ClassTemplateDecl*>();
775}
776
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000777SourceRange
778ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000779 if (ExplicitInfo) {
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000780 SourceLocation Begin = getTemplateKeywordLoc();
781 if (Begin.isValid()) {
782 // Here we have an explicit (partial) specialization or instantiation.
783 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
784 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
785 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
786 if (getExternLoc().isValid())
787 Begin = getExternLoc();
Argyrios Kyrtzidisd798c052016-07-15 18:11:33 +0000788 SourceLocation End = getBraceRange().getEnd();
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000789 if (End.isInvalid())
790 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
791 return SourceRange(Begin, End);
792 }
793 // An implicit instantiation of a class template partial specialization
794 // uses ExplicitInfo to record the TypeAsWritten, but the source
795 // locations should be retrieved from the instantiation pattern.
796 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
797 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
798 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
Craig Topper36250ad2014-05-12 05:36:57 +0000799 assert(inst_from != nullptr);
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000800 return inst_from->getSourceRange();
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000801 }
802 else {
803 // No explicit info available.
804 llvm::PointerUnion<ClassTemplateDecl *,
805 ClassTemplatePartialSpecializationDecl *>
806 inst_from = getInstantiatedFrom();
807 if (inst_from.isNull())
808 return getSpecializedTemplate()->getSourceRange();
809 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
810 return ctd->getSourceRange();
811 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
812 ->getSourceRange();
813 }
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000814}
815
Douglas Gregor2373c592009-05-31 09:31:02 +0000816//===----------------------------------------------------------------------===//
817// ClassTemplatePartialSpecializationDecl Implementation
818//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000819void ClassTemplatePartialSpecializationDecl::anchor() { }
820
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000821ClassTemplatePartialSpecializationDecl::
822ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000823 DeclContext *DC,
824 SourceLocation StartLoc,
825 SourceLocation IdLoc,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000826 TemplateParameterList *Params,
827 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000828 ArrayRef<TemplateArgument> Args,
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000829 const ASTTemplateArgumentListInfo *ArgInfos,
Richard Smithb2f61b42013-08-22 23:27:37 +0000830 ClassTemplatePartialSpecializationDecl *PrevDecl)
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000831 : ClassTemplateSpecializationDecl(Context,
832 ClassTemplatePartialSpecialization,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000833 TK, DC, StartLoc, IdLoc,
834 SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000835 Args, PrevDecl),
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000836 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +0000837 InstantiatedFromMember(nullptr, false)
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000838{
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000839 AdoptTemplateParameterList(Params, this);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000840}
841
Douglas Gregor2373c592009-05-31 09:31:02 +0000842ClassTemplatePartialSpecializationDecl *
843ClassTemplatePartialSpecializationDecl::
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000844Create(ASTContext &Context, TagKind TK,DeclContext *DC,
845 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregor2373c592009-05-31 09:31:02 +0000846 TemplateParameterList *Params,
847 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000848 ArrayRef<TemplateArgument> Args,
John McCall6b51f282009-11-23 01:53:49 +0000849 const TemplateArgumentListInfo &ArgInfos,
John McCalle78aac42010-03-10 03:28:59 +0000850 QualType CanonInjectedType,
Richard Smithb2f61b42013-08-22 23:27:37 +0000851 ClassTemplatePartialSpecializationDecl *PrevDecl) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000852 const ASTTemplateArgumentListInfo *ASTArgInfos =
853 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
John McCall0ad16662009-10-29 08:12:44 +0000854
Richard Smithf7981722013-11-22 09:01:48 +0000855 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
856 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
857 Params, SpecializedTemplate, Args,
David Majnemer8b622692016-07-03 21:17:51 +0000858 ASTArgInfos, PrevDecl);
Douglas Gregor2373c592009-05-31 09:31:02 +0000859 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000860 Result->MayHaveOutOfDateDef = false;
John McCalle78aac42010-03-10 03:28:59 +0000861
862 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregor2373c592009-05-31 09:31:02 +0000863 return Result;
864}
John McCall11083da2009-09-16 22:47:08 +0000865
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000866ClassTemplatePartialSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000867ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
868 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000869 ClassTemplatePartialSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000870 new (C, ID) ClassTemplatePartialSpecializationDecl(C);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000871 Result->MayHaveOutOfDateDef = false;
872 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000873}
874
John McCall11083da2009-09-16 22:47:08 +0000875//===----------------------------------------------------------------------===//
876// FriendTemplateDecl Implementation
877//===----------------------------------------------------------------------===//
878
David Blaikie68e081d2011-12-20 02:48:34 +0000879void FriendTemplateDecl::anchor() { }
880
David Majnemerdfecf1a2016-07-06 04:19:16 +0000881FriendTemplateDecl *
882FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
883 SourceLocation L,
884 MutableArrayRef<TemplateParameterList *> Params,
885 FriendUnion Friend, SourceLocation FLoc) {
886 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
John McCall11083da2009-09-16 22:47:08 +0000887}
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000888
Douglas Gregor72172e92012-01-05 21:55:30 +0000889FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
890 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000891 return new (C, ID) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000892}
Richard Smith3f1b5d02011-05-05 21:57:07 +0000893
894//===----------------------------------------------------------------------===//
895// TypeAliasTemplateDecl Implementation
896//===----------------------------------------------------------------------===//
897
898TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
899 DeclContext *DC,
900 SourceLocation L,
901 DeclarationName Name,
902 TemplateParameterList *Params,
903 NamedDecl *Decl) {
904 AdoptTemplateParameterList(Params, DC);
Richard Smith053f6c62014-05-16 23:01:30 +0000905 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000906}
907
Douglas Gregor72172e92012-01-05 21:55:30 +0000908TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
909 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000910 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000911 DeclarationName(), nullptr, nullptr);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000912}
913
914void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
915 static_cast<Common *>(Ptr)->~Common();
916}
917RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000918TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3f1b5d02011-05-05 21:57:07 +0000919 Common *CommonPtr = new (C) Common;
920 C.AddDeallocation(DeallocateCommon, CommonPtr);
921 return CommonPtr;
922}
923
David Blaikie68e081d2011-12-20 02:48:34 +0000924//===----------------------------------------------------------------------===//
925// ClassScopeFunctionSpecializationDecl Implementation
926//===----------------------------------------------------------------------===//
927
928void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor72172e92012-01-05 21:55:30 +0000929
930ClassScopeFunctionSpecializationDecl *
931ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
932 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000933 return new (C, ID) ClassScopeFunctionSpecializationDecl(
Craig Topper36250ad2014-05-12 05:36:57 +0000934 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
Douglas Gregor72172e92012-01-05 21:55:30 +0000935}
Larisse Voufo39a1e502013-08-06 01:03:05 +0000936
937//===----------------------------------------------------------------------===//
938// VarTemplateDecl Implementation
939//===----------------------------------------------------------------------===//
940
941void VarTemplateDecl::DeallocateCommon(void *Ptr) {
942 static_cast<Common *>(Ptr)->~Common();
943}
944
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000945VarTemplateDecl *VarTemplateDecl::getDefinition() {
946 VarTemplateDecl *CurD = this;
947 while (CurD) {
948 if (CurD->isThisDeclarationADefinition())
949 return CurD;
950 CurD = CurD->getPreviousDecl();
951 }
Craig Topper36250ad2014-05-12 05:36:57 +0000952 return nullptr;
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000953}
954
Larisse Voufo39a1e502013-08-06 01:03:05 +0000955VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
956 SourceLocation L, DeclarationName Name,
957 TemplateParameterList *Params,
Richard Smithbeef3452014-01-16 23:39:20 +0000958 VarDecl *Decl) {
Richard Smith053f6c62014-05-16 23:01:30 +0000959 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000960}
961
962VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
963 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000964 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
965 DeclarationName(), nullptr, nullptr);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000966}
967
Alp Tokerf6a24ce2013-12-05 16:25:25 +0000968// TODO: Unify across class, function and variable templates?
Larisse Voufo30616382013-08-23 22:21:36 +0000969// May require moving this and Common to RedeclarableTemplateDecl.
Larisse Voufo39a1e502013-08-06 01:03:05 +0000970void VarTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000971 // Grab the most recent declaration to ensure we've loaded any lazy
972 // redeclarations of this template.
973 //
974 // FIXME: Avoid walking the entire redeclaration chain here.
975 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Larisse Voufo39a1e502013-08-06 01:03:05 +0000976 if (CommonPtr->LazySpecializations) {
977 ASTContext &Context = getASTContext();
978 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000979 CommonPtr->LazySpecializations = nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +0000980 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
981 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
982 }
983}
984
985llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
986VarTemplateDecl::getSpecializations() const {
987 LoadLazySpecializations();
988 return getCommonPtr()->Specializations;
989}
990
991llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
992VarTemplateDecl::getPartialSpecializations() {
993 LoadLazySpecializations();
994 return getCommonPtr()->PartialSpecializations;
995}
996
997RedeclarableTemplateDecl::CommonBase *
998VarTemplateDecl::newCommon(ASTContext &C) const {
999 Common *CommonPtr = new (C) Common;
1000 C.AddDeallocation(DeallocateCommon, CommonPtr);
1001 return CommonPtr;
1002}
1003
1004VarTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +00001005VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1006 void *&InsertPos) {
1007 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001008}
1009
1010void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1011 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +00001012 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001013}
1014
1015VarTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +00001016VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1017 void *&InsertPos) {
1018 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001019}
1020
1021void VarTemplateDecl::AddPartialSpecialization(
1022 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1023 if (InsertPos)
1024 getPartialSpecializations().InsertNode(D, InsertPos);
1025 else {
1026 VarTemplatePartialSpecializationDecl *Existing =
1027 getPartialSpecializations().GetOrInsertNode(D);
1028 (void)Existing;
1029 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1030 }
1031
1032 if (ASTMutationListener *L = getASTMutationListener())
1033 L->AddedCXXTemplateSpecialization(this, D);
1034}
1035
1036void VarTemplateDecl::getPartialSpecializations(
1037 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1038 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1039 getPartialSpecializations();
1040 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +00001041 PS.reserve(PartialSpecs.size());
David Majnemerdfecf1a2016-07-06 04:19:16 +00001042 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1043 PS.push_back(P.getMostRecentDecl());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001044}
1045
1046VarTemplatePartialSpecializationDecl *
1047VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1048 VarTemplatePartialSpecializationDecl *D) {
1049 Decl *DCanon = D->getCanonicalDecl();
David Majnemerdfecf1a2016-07-06 04:19:16 +00001050 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1051 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1052 return P.getMostRecentDecl();
Larisse Voufo39a1e502013-08-06 01:03:05 +00001053 }
1054
Craig Topper36250ad2014-05-12 05:36:57 +00001055 return nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +00001056}
1057
1058//===----------------------------------------------------------------------===//
1059// VarTemplateSpecializationDecl Implementation
1060//===----------------------------------------------------------------------===//
1061VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001062 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001063 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
David Majnemer8b622692016-07-03 21:17:51 +00001064 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
Richard Smith053f6c62014-05-16 23:01:30 +00001065 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1066 SpecializedTemplate->getIdentifier(), T, TInfo, S),
Craig Topper36250ad2014-05-12 05:36:57 +00001067 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
David Majnemer8b622692016-07-03 21:17:51 +00001068 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001069 SpecializationKind(TSK_Undeclared) {}
1070
Richard Smith053f6c62014-05-16 23:01:30 +00001071VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1072 ASTContext &C)
1073 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
Craig Topper36250ad2014-05-12 05:36:57 +00001074 QualType(), nullptr, SC_None),
1075 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Larisse Voufo39a1e502013-08-06 01:03:05 +00001076
1077VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1078 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1079 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
David Majnemer8b622692016-07-03 21:17:51 +00001080 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
Richard Smithf7981722013-11-22 09:01:48 +00001081 return new (Context, DC) VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001082 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
David Majnemer8b622692016-07-03 21:17:51 +00001083 SpecializedTemplate, T, TInfo, S, Args);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001084}
1085
1086VarTemplateSpecializationDecl *
1087VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001088 return new (C, ID)
1089 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001090}
1091
1092void VarTemplateSpecializationDecl::getNameForDiagnostic(
1093 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1094 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1095
1096 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1097 TemplateSpecializationType::PrintTemplateArgumentList(
David Majnemer6fbeee32016-07-07 04:43:07 +00001098 OS, TemplateArgs.asArray(), Policy);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001099}
1100
1101VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1102 if (SpecializedPartialSpecialization *PartialSpec =
1103 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1104 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1105 return SpecializedTemplate.get<VarTemplateDecl *>();
1106}
1107
1108void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1109 const TemplateArgumentListInfo &ArgsInfo) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001110 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1111 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
David Majnemerdfecf1a2016-07-06 04:19:16 +00001112 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1113 TemplateArgsInfo.addArgument(Loc);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001114}
1115
1116//===----------------------------------------------------------------------===//
1117// VarTemplatePartialSpecializationDecl Implementation
1118//===----------------------------------------------------------------------===//
1119void VarTemplatePartialSpecializationDecl::anchor() {}
1120
1121VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1122 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1123 SourceLocation IdLoc, TemplateParameterList *Params,
1124 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001125 StorageClass S, ArrayRef<TemplateArgument> Args,
Richard Smithb2f61b42013-08-22 23:27:37 +00001126 const ASTTemplateArgumentListInfo *ArgInfos)
Richard Smith053f6c62014-05-16 23:01:30 +00001127 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001128 DC, StartLoc, IdLoc, SpecializedTemplate, T,
David Majnemer8b622692016-07-03 21:17:51 +00001129 TInfo, S, Args),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001130 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +00001131 InstantiatedFromMember(nullptr, false) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001132 // TODO: The template parameters should be in DC by now. Verify.
1133 // AdoptTemplateParameterList(Params, DC);
1134}
1135
1136VarTemplatePartialSpecializationDecl *
1137VarTemplatePartialSpecializationDecl::Create(
1138 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1139 SourceLocation IdLoc, TemplateParameterList *Params,
1140 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001141 StorageClass S, ArrayRef<TemplateArgument> Args,
Richard Smithb2f61b42013-08-22 23:27:37 +00001142 const TemplateArgumentListInfo &ArgInfos) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +00001143 const ASTTemplateArgumentListInfo *ASTArgInfos
1144 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001145
1146 VarTemplatePartialSpecializationDecl *Result =
Richard Smithf7981722013-11-22 09:01:48 +00001147 new (Context, DC) VarTemplatePartialSpecializationDecl(
Larisse Voufo39a1e502013-08-06 01:03:05 +00001148 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001149 S, Args, ASTArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001150 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1151 return Result;
1152}
1153
1154VarTemplatePartialSpecializationDecl *
1155VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1156 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001157 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001158}
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001159
1160static TemplateParameterList *
1161createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1162 // typename T
1163 auto *T = TemplateTypeParmDecl::Create(
1164 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1165 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1166 T->setImplicit(true);
1167
1168 // T ...Ints
1169 TypeSourceInfo *TI =
1170 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1171 auto *N = NonTypeTemplateParmDecl::Create(
1172 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1173 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1174 N->setImplicit(true);
1175
1176 // <typename T, T ...Ints>
1177 NamedDecl *P[2] = {T, N};
1178 auto *TPL = TemplateParameterList::Create(
Hubert Tonge4a0c0e2016-07-30 22:33:34 +00001179 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001180
1181 // template <typename T, ...Ints> class IntSeq
1182 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1183 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1184 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1185 TemplateTemplateParm->setImplicit(true);
1186
1187 // typename T
1188 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1189 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1190 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1191 TemplateTypeParm->setImplicit(true);
1192
1193 // T N
1194 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1195 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1196 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1197 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1198 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1199 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1200 NonTypeTemplateParm};
1201
1202 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1203 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
Hubert Tonge4a0c0e2016-07-30 22:33:34 +00001204 Params, SourceLocation(), nullptr);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001205}
1206
Eric Fiselier6ad68552016-07-01 01:24:09 +00001207static TemplateParameterList *
1208createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1209 // std::size_t Index
1210 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1211 auto *Index = NonTypeTemplateParmDecl::Create(
1212 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1213 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1214
1215 // typename ...T
1216 auto *Ts = TemplateTypeParmDecl::Create(
1217 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1218 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1219 Ts->setImplicit(true);
1220
1221 // template <std::size_t Index, typename ...T>
1222 NamedDecl *Params[] = {Index, Ts};
1223 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1224 llvm::makeArrayRef(Params),
Hubert Tonge4a0c0e2016-07-30 22:33:34 +00001225 SourceLocation(), nullptr);
Eric Fiselier6ad68552016-07-01 01:24:09 +00001226}
1227
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001228static TemplateParameterList *createBuiltinTemplateParameterList(
1229 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1230 switch (BTK) {
1231 case BTK__make_integer_seq:
1232 return createMakeIntegerSeqParameterList(C, DC);
Eric Fiselier6ad68552016-07-01 01:24:09 +00001233 case BTK__type_pack_element:
1234 return createTypePackElementParameterList(C, DC);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001235 }
1236
1237 llvm_unreachable("unhandled BuiltinTemplateKind!");
1238}
1239
1240void BuiltinTemplateDecl::anchor() {}
1241
1242BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1243 DeclarationName Name,
1244 BuiltinTemplateKind BTK)
1245 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1246 createBuiltinTemplateParameterList(C, DC, BTK)),
1247 BTK(BTK) {}