blob: bede057ff42202a0d8557f792a4aef28653c5ef5 [file] [log] [blame]
Sebastian Redle2530ec2009-10-23 22:13:42 +00001//===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
Douglas Gregorded2d7b2009-02-04 19:02:06 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the C++ related Decl classes for templates.
11//
12//===----------------------------------------------------------------------===//
13
Douglas Gregorded2d7b2009-02-04 19:02:06 +000014#include "clang/AST/DeclTemplate.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000015#include "clang/AST/ASTContext.h"
16#include "clang/AST/ASTMutationListener.h"
17#include "clang/AST/DeclCXX.h"
Douglas Gregor8bf42052009-02-09 18:46:07 +000018#include "clang/AST/Expr.h"
Douglas Gregor85759112011-01-04 02:33:52 +000019#include "clang/AST/ExprCXX.h"
John McCall0ad16662009-10-29 08:12:44 +000020#include "clang/AST/TypeLoc.h"
David Majnemerd9b1a4f2015-11-04 03:40:30 +000021#include "clang/Basic/Builtins.h"
Douglas Gregorded2d7b2009-02-04 19:02:06 +000022#include "clang/Basic/IdentifierTable.h"
23#include "llvm/ADT/STLExtras.h"
Douglas Gregor1ccc8412010-11-07 23:05:16 +000024#include <memory>
Douglas Gregorded2d7b2009-02-04 19:02:06 +000025using namespace clang;
26
27//===----------------------------------------------------------------------===//
28// TemplateParameterList Implementation
29//===----------------------------------------------------------------------===//
30
Douglas Gregorcd72ba92009-02-06 22:42:48 +000031TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
32 SourceLocation LAngleLoc,
David Majnemer902f8c62015-12-27 07:16:27 +000033 ArrayRef<NamedDecl *> Params,
Douglas Gregorcd72ba92009-02-06 22:42:48 +000034 SourceLocation RAngleLoc)
35 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
David Majnemer902f8c62015-12-27 07:16:27 +000036 NumParams(Params.size()), ContainsUnexpandedParameterPack(false) {
Richard Smith1fde8ec2012-09-07 02:06:42 +000037 assert(this->NumParams == NumParams && "Too many template parameters");
38 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
39 NamedDecl *P = Params[Idx];
40 begin()[Idx] = P;
41
42 if (!P->isTemplateParameterPack()) {
43 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
44 if (NTTP->getType()->containsUnexpandedParameterPack())
45 ContainsUnexpandedParameterPack = true;
46
47 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
48 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
49 ContainsUnexpandedParameterPack = true;
50
51 // FIXME: If a default argument contains an unexpanded parameter pack, the
52 // template parameter list does too.
53 }
54 }
Douglas Gregorded2d7b2009-02-04 19:02:06 +000055}
56
David Majnemer902f8c62015-12-27 07:16:27 +000057TemplateParameterList *TemplateParameterList::Create(
58 const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc,
59 ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc) {
60 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *>(Params.size()),
James Y Knight7a22b242015-08-06 20:26:32 +000061 llvm::alignOf<TemplateParameterList>());
Mike Stump11289f42009-09-09 15:08:12 +000062 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
David Majnemer902f8c62015-12-27 07:16:27 +000063 RAngleLoc);
Douglas Gregorded2d7b2009-02-04 19:02:06 +000064}
65
Douglas Gregorf8f86832009-02-11 18:16:40 +000066unsigned TemplateParameterList::getMinRequiredArguments() const {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000067 unsigned NumRequiredArgs = 0;
David Majnemerdfecf1a2016-07-06 04:19:16 +000068 for (const NamedDecl *P : asArray()) {
69 if (P->isTemplateParameterPack()) {
70 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
Douglas Gregor0231d8d2011-01-19 20:10:05 +000071 if (NTTP->isExpandedParameterPack()) {
72 NumRequiredArgs += NTTP->getNumExpansionTypes();
73 continue;
74 }
David Majnemerdfecf1a2016-07-06 04:19:16 +000075
Douglas Gregorf8f86832009-02-11 18:16:40 +000076 break;
Douglas Gregor0231d8d2011-01-19 20:10:05 +000077 }
David Majnemerdfecf1a2016-07-06 04:19:16 +000078
79 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000080 if (TTP->hasDefaultArgument())
81 break;
David Majnemerdfecf1a2016-07-06 04:19:16 +000082 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000083 if (NTTP->hasDefaultArgument())
84 break;
David Majnemerdfecf1a2016-07-06 04:19:16 +000085 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
Douglas Gregor0231d8d2011-01-19 20:10:05 +000086 break;
David Majnemerdfecf1a2016-07-06 04:19:16 +000087
Douglas Gregor0231d8d2011-01-19 20:10:05 +000088 ++NumRequiredArgs;
Douglas Gregorf8f86832009-02-11 18:16:40 +000089 }
David Majnemerdfecf1a2016-07-06 04:19:16 +000090
Douglas Gregorf8f86832009-02-11 18:16:40 +000091 return NumRequiredArgs;
92}
93
Douglas Gregor21610382009-10-29 00:04:11 +000094unsigned TemplateParameterList::getDepth() const {
95 if (size() == 0)
96 return 0;
97
98 const NamedDecl *FirstParm = getParam(0);
99 if (const TemplateTypeParmDecl *TTP
100 = dyn_cast<TemplateTypeParmDecl>(FirstParm))
101 return TTP->getDepth();
102 else if (const NonTypeTemplateParmDecl *NTTP
103 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
104 return NTTP->getDepth();
105 else
106 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
107}
108
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000109static void AdoptTemplateParameterList(TemplateParameterList *Params,
110 DeclContext *Owner) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000111 for (NamedDecl *P : *Params) {
112 P->setDeclContext(Owner);
113
114 if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000115 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
116 }
117}
118
Richard Smithe7bd6de2015-06-10 20:30:23 +0000119namespace clang {
120void *allocateDefaultArgStorageChain(const ASTContext &C) {
121 return new (C) char[sizeof(void*) * 2];
122}
123}
124
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000125//===----------------------------------------------------------------------===//
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000126// RedeclarableTemplateDecl Implementation
127//===----------------------------------------------------------------------===//
128
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000129RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000130 if (Common)
131 return Common;
132
133 // Walk the previous-declaration chain until we either find a declaration
134 // with a common pointer or we run out of previous declarations.
135 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
136 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
137 Prev = Prev->getPreviousDecl()) {
138 if (Prev->Common) {
139 Common = Prev->Common;
140 break;
Douglas Gregor68444de2012-01-14 15:13:49 +0000141 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000142
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000143 PrevDecls.push_back(Prev);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000144 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000145
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000146 // If we never found a common pointer, allocate one now.
147 if (!Common) {
148 // FIXME: If any of the declarations is from an AST file, we probably
149 // need an update record to add the common data.
150
151 Common = newCommon(getASTContext());
152 }
153
154 // Update any previous declarations we saw with the common pointer.
David Majnemerdfecf1a2016-07-06 04:19:16 +0000155 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
156 Prev->Common = Common;
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000157
Douglas Gregor68444de2012-01-14 15:13:49 +0000158 return Common;
Peter Collingbourne029fd692010-07-29 16:12:09 +0000159}
160
Richard Smithe977e512015-02-24 01:23:23 +0000161template<class EntryType>
162typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000163RedeclarableTemplateDecl::findSpecializationImpl(
Richard Smithe977e512015-02-24 01:23:23 +0000164 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
165 void *&InsertPos) {
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000166 typedef SpecEntryTraits<EntryType> SETraits;
167 llvm::FoldingSetNodeID ID;
Craig Topper7e0daca2014-06-26 04:58:53 +0000168 EntryType::Profile(ID,Args, getASTContext());
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000169 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
Richard Smithe977e512015-02-24 01:23:23 +0000170 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
171}
172
173template<class Derived, class EntryType>
174void RedeclarableTemplateDecl::addSpecializationImpl(
175 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
176 void *InsertPos) {
177 typedef SpecEntryTraits<EntryType> SETraits;
178 if (InsertPos) {
179#ifndef NDEBUG
180 void *CorrectInsertPos;
181 assert(!findSpecializationImpl(Specializations,
182 SETraits::getTemplateArgs(Entry),
183 CorrectInsertPos) &&
184 InsertPos == CorrectInsertPos &&
185 "given incorrect InsertPos for specialization");
186#endif
187 Specializations.InsertNode(Entry, InsertPos);
188 } else {
189 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
190 (void)Existing;
191 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
192 "non-canonical specialization?");
193 }
194
195 if (ASTMutationListener *L = getASTMutationListener())
196 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
197 SETraits::getDecl(Entry));
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000198}
199
Douglas Gregor43669f82011-03-05 17:54:25 +0000200/// \brief Generate the injected template arguments for the given template
201/// parameter list, e.g., for the injected-class-name of a class template.
202static void GenerateInjectedTemplateArgs(ASTContext &Context,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000203 TemplateParameterList *Params,
Douglas Gregor43669f82011-03-05 17:54:25 +0000204 TemplateArgument *Args) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000205 for (NamedDecl *Param : *Params) {
Douglas Gregor43669f82011-03-05 17:54:25 +0000206 TemplateArgument Arg;
David Majnemerdfecf1a2016-07-06 04:19:16 +0000207 if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
Douglas Gregor43669f82011-03-05 17:54:25 +0000208 QualType ArgType = Context.getTypeDeclType(TTP);
209 if (TTP->isParameterPack())
David Blaikie7a30dc52013-02-21 01:47:18 +0000210 ArgType = Context.getPackExpansionType(ArgType, None);
David Blaikie05785d12013-02-20 22:23:23 +0000211
Douglas Gregor43669f82011-03-05 17:54:25 +0000212 Arg = TemplateArgument(ArgType);
David Majnemerdfecf1a2016-07-06 04:19:16 +0000213 } else if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
John McCall113bee02012-03-10 09:33:50 +0000214 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
Douglas Gregor43669f82011-03-05 17:54:25 +0000215 NTTP->getType().getNonLValueExprType(Context),
216 Expr::getValueKindForType(NTTP->getType()),
217 NTTP->getLocation());
David Majnemerdfecf1a2016-07-06 04:19:16 +0000218
Douglas Gregor43669f82011-03-05 17:54:25 +0000219 if (NTTP->isParameterPack())
David Blaikie7a30dc52013-02-21 01:47:18 +0000220 E = new (Context) PackExpansionExpr(Context.DependentTy, E,
221 NTTP->getLocation(), None);
Douglas Gregor43669f82011-03-05 17:54:25 +0000222 Arg = TemplateArgument(E);
223 } else {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000224 auto *TTP = cast<TemplateTemplateParmDecl>(Param);
Douglas Gregor43669f82011-03-05 17:54:25 +0000225 if (TTP->isParameterPack())
David Blaikie05785d12013-02-20 22:23:23 +0000226 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
Douglas Gregor43669f82011-03-05 17:54:25 +0000227 else
228 Arg = TemplateArgument(TemplateName(TTP));
229 }
David Majnemerdfecf1a2016-07-06 04:19:16 +0000230
231 if (Param->isTemplateParameterPack())
Benjamin Kramercce63472015-08-05 09:40:22 +0000232 Arg = TemplateArgument::CreatePackCopy(Context, Arg);
233
Douglas Gregor43669f82011-03-05 17:54:25 +0000234 *Args++ = Arg;
235 }
236}
David Majnemerdfecf1a2016-07-06 04:19:16 +0000237
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000238//===----------------------------------------------------------------------===//
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000239// FunctionTemplateDecl Implementation
240//===----------------------------------------------------------------------===//
241
Douglas Gregor1a809332010-05-23 18:26:36 +0000242void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
243 static_cast<Common *>(Ptr)->~Common();
244}
245
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000246FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
247 DeclContext *DC,
248 SourceLocation L,
249 DeclarationName Name,
Douglas Gregor8f5d4422009-06-29 20:59:39 +0000250 TemplateParameterList *Params,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000251 NamedDecl *Decl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000252 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Richard Smith053f6c62014-05-16 23:01:30 +0000253 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000254}
255
Douglas Gregor72172e92012-01-05 21:55:30 +0000256FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
257 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000258 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000259 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000260}
261
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000262RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000263FunctionTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000264 Common *CommonPtr = new (C) Common;
265 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000266 return CommonPtr;
267}
268
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000269void FunctionTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000270 // Grab the most recent declaration to ensure we've loaded any lazy
271 // redeclarations of this template.
272 //
273 // FIXME: Avoid walking the entire redeclaration chain here.
274 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000275 if (CommonPtr->LazySpecializations) {
276 ASTContext &Context = getASTContext();
277 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000278 CommonPtr->LazySpecializations = nullptr;
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000279 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
280 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
281 }
282}
283
284llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
285FunctionTemplateDecl::getSpecializations() const {
286 LoadLazySpecializations();
287 return getCommonPtr()->Specializations;
288}
289
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000290FunctionDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000291FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
292 void *&InsertPos) {
293 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000294}
295
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000296void FunctionTemplateDecl::addSpecialization(
297 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000298 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
299 InsertPos);
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000300}
301
Richard Smith841d8b22013-05-17 03:04:50 +0000302ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
Douglas Gregor43669f82011-03-05 17:54:25 +0000303 TemplateParameterList *Params = getTemplateParameters();
304 Common *CommonPtr = getCommonPtr();
305 if (!CommonPtr->InjectedArgs) {
306 CommonPtr->InjectedArgs
Richard Smith841d8b22013-05-17 03:04:50 +0000307 = new (getASTContext()) TemplateArgument[Params->size()];
308 GenerateInjectedTemplateArgs(getASTContext(), Params,
Douglas Gregor43669f82011-03-05 17:54:25 +0000309 CommonPtr->InjectedArgs);
310 }
Richard Smith841d8b22013-05-17 03:04:50 +0000311
312 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
Douglas Gregor43669f82011-03-05 17:54:25 +0000313}
314
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000315//===----------------------------------------------------------------------===//
316// ClassTemplateDecl Implementation
317//===----------------------------------------------------------------------===//
318
Douglas Gregor1a809332010-05-23 18:26:36 +0000319void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
320 static_cast<Common *>(Ptr)->~Common();
321}
322
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000323ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
324 DeclContext *DC,
325 SourceLocation L,
326 DeclarationName Name,
327 TemplateParameterList *Params,
Douglas Gregor90a1a652009-03-19 17:26:29 +0000328 NamedDecl *Decl,
329 ClassTemplateDecl *PrevDecl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000330 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Richard Smith053f6c62014-05-16 23:01:30 +0000331 ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
332 Params, Decl);
Rafael Espindola8db352d2013-10-17 15:37:26 +0000333 New->setPreviousDecl(PrevDecl);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +0000334 return New;
Douglas Gregor90a1a652009-03-19 17:26:29 +0000335}
336
Richard Smith053f6c62014-05-16 23:01:30 +0000337ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000338 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000339 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
340 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000341}
342
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000343void ClassTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000344 // Grab the most recent declaration to ensure we've loaded any lazy
345 // redeclarations of this template.
346 //
347 // FIXME: Avoid walking the entire redeclaration chain here.
348 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000349 if (CommonPtr->LazySpecializations) {
350 ASTContext &Context = getASTContext();
351 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000352 CommonPtr->LazySpecializations = nullptr;
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000353 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
354 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
355 }
356}
357
Chandler Carruthb41171b2012-05-03 23:49:05 +0000358llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000359ClassTemplateDecl::getSpecializations() const {
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000360 LoadLazySpecializations();
361 return getCommonPtr()->Specializations;
362}
363
Chandler Carruthb41171b2012-05-03 23:49:05 +0000364llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000365ClassTemplateDecl::getPartialSpecializations() {
366 LoadLazySpecializations();
367 return getCommonPtr()->PartialSpecializations;
368}
369
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000370RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000371ClassTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000372 Common *CommonPtr = new (C) Common;
373 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000374 return CommonPtr;
375}
376
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000377ClassTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000378ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
379 void *&InsertPos) {
380 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000381}
382
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000383void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
384 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000385 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000386}
387
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000388ClassTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000389ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000390 void *&InsertPos) {
Craig Topper7e0daca2014-06-26 04:58:53 +0000391 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000392}
393
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000394void ClassTemplateDecl::AddPartialSpecialization(
395 ClassTemplatePartialSpecializationDecl *D,
396 void *InsertPos) {
Douglas Gregorce9978f2012-03-28 14:34:23 +0000397 if (InsertPos)
398 getPartialSpecializations().InsertNode(D, InsertPos);
399 else {
400 ClassTemplatePartialSpecializationDecl *Existing
401 = getPartialSpecializations().GetOrInsertNode(D);
402 (void)Existing;
403 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
404 }
405
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000406 if (ASTMutationListener *L = getASTMutationListener())
407 L->AddedCXXTemplateSpecialization(this, D);
408}
409
Douglas Gregor407e9612010-04-30 05:56:50 +0000410void ClassTemplateDecl::getPartialSpecializations(
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000411 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
Chandler Carruthb41171b2012-05-03 23:49:05 +0000412 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000413 = getPartialSpecializations();
Douglas Gregor407e9612010-04-30 05:56:50 +0000414 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +0000415 PS.reserve(PartialSpecs.size());
David Majnemerdfecf1a2016-07-06 04:19:16 +0000416 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
417 PS.push_back(P.getMostRecentDecl());
Douglas Gregor407e9612010-04-30 05:56:50 +0000418}
419
Douglas Gregor15301382009-07-30 17:40:51 +0000420ClassTemplatePartialSpecializationDecl *
421ClassTemplateDecl::findPartialSpecialization(QualType T) {
422 ASTContext &Context = getASTContext();
David Majnemerdfecf1a2016-07-06 04:19:16 +0000423 for (ClassTemplatePartialSpecializationDecl &P :
424 getPartialSpecializations()) {
425 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
426 return P.getMostRecentDecl();
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000427 }
428
Craig Topper36250ad2014-05-12 05:36:57 +0000429 return nullptr;
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000430}
431
432ClassTemplatePartialSpecializationDecl *
433ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
434 ClassTemplatePartialSpecializationDecl *D) {
435 Decl *DCanon = D->getCanonicalDecl();
David Majnemerdfecf1a2016-07-06 04:19:16 +0000436 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
437 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
438 return P.getMostRecentDecl();
Douglas Gregor15301382009-07-30 17:40:51 +0000439 }
Mike Stump11289f42009-09-09 15:08:12 +0000440
Craig Topper36250ad2014-05-12 05:36:57 +0000441 return nullptr;
Douglas Gregor15301382009-07-30 17:40:51 +0000442}
443
John McCalle78aac42010-03-10 03:28:59 +0000444QualType
Douglas Gregor9961ce92010-07-08 18:37:38 +0000445ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000446 Common *CommonPtr = getCommonPtr();
Douglas Gregore362cea2009-05-10 22:57:19 +0000447 if (!CommonPtr->InjectedClassNameType.isNull())
448 return CommonPtr->InjectedClassNameType;
449
Douglas Gregor8092e802010-12-23 16:00:30 +0000450 // C++0x [temp.dep.type]p2:
451 // The template argument list of a primary template is a template argument
452 // list in which the nth template argument has the value of the nth template
453 // parameter of the class template. If the nth template parameter is a
454 // template parameter pack (14.5.3), the nth template argument is a pack
455 // expansion (14.5.3) whose pattern is the name of the template parameter
456 // pack.
Douglas Gregor9961ce92010-07-08 18:37:38 +0000457 ASTContext &Context = getASTContext();
Douglas Gregore362cea2009-05-10 22:57:19 +0000458 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000459 SmallVector<TemplateArgument, 16> TemplateArgs;
Douglas Gregor43669f82011-03-05 17:54:25 +0000460 TemplateArgs.resize(Params->size());
461 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
Douglas Gregore362cea2009-05-10 22:57:19 +0000462 CommonPtr->InjectedClassNameType
Douglas Gregora8e02e72009-07-28 23:00:59 +0000463 = Context.getTemplateSpecializationType(TemplateName(this),
Douglas Gregore362cea2009-05-10 22:57:19 +0000464 &TemplateArgs[0],
Douglas Gregora8e02e72009-07-28 23:00:59 +0000465 TemplateArgs.size());
Douglas Gregore362cea2009-05-10 22:57:19 +0000466 return CommonPtr->InjectedClassNameType;
467}
468
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000469//===----------------------------------------------------------------------===//
470// TemplateTypeParm Allocation/Deallocation Method Implementations
471//===----------------------------------------------------------------------===//
472
473TemplateTypeParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000474TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000475 SourceLocation KeyLoc, SourceLocation NameLoc,
476 unsigned D, unsigned P, IdentifierInfo *Id,
477 bool Typename, bool ParameterPack) {
Chandler Carruth08836322011-05-01 00:51:33 +0000478 TemplateTypeParmDecl *TTPDecl =
Richard Smithf7981722013-11-22 09:01:48 +0000479 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
Chandler Carruth08836322011-05-01 00:51:33 +0000480 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
Richard Smith5b21db82014-04-23 18:20:42 +0000481 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
Chandler Carruth08836322011-05-01 00:51:33 +0000482 return TTPDecl;
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000483}
484
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000485TemplateTypeParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000486TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000487 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
488 SourceLocation(), nullptr, false);
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000489}
490
John McCall0ad16662009-10-29 08:12:44 +0000491SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara23485e02011-03-04 12:42:03 +0000492 return hasDefaultArgument()
Richard Smith1469b912015-06-10 00:29:03 +0000493 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
494 : SourceLocation();
Abramo Bagnara23485e02011-03-04 12:42:03 +0000495}
496
497SourceRange TemplateTypeParmDecl::getSourceRange() const {
498 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000499 return SourceRange(getLocStart(),
Richard Smith1469b912015-06-10 00:29:03 +0000500 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
Abramo Bagnara23485e02011-03-04 12:42:03 +0000501 else
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000502 return TypeDecl::getSourceRange();
John McCall0ad16662009-10-29 08:12:44 +0000503}
504
Douglas Gregor21610382009-10-29 00:04:11 +0000505unsigned TemplateTypeParmDecl::getDepth() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000506 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
Douglas Gregor21610382009-10-29 00:04:11 +0000507}
508
509unsigned TemplateTypeParmDecl::getIndex() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000510 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
Douglas Gregor21610382009-10-29 00:04:11 +0000511}
512
Chandler Carruth08836322011-05-01 00:51:33 +0000513bool TemplateTypeParmDecl::isParameterPack() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000514 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
Chandler Carruth08836322011-05-01 00:51:33 +0000515}
516
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000517//===----------------------------------------------------------------------===//
518// NonTypeTemplateParmDecl Method Implementations
519//===----------------------------------------------------------------------===//
520
David Majnemerdfecf1a2016-07-06 04:19:16 +0000521NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
522 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
523 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
524 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
525 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
526 TemplateParmPosition(D, P), ParameterPack(true),
527 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
528 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
James Y Knight7a22b242015-08-06 20:26:32 +0000529 auto TypesAndInfos =
530 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000531 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
James Y Knight7a22b242015-08-06 20:26:32 +0000532 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
533 TypesAndInfos[I].second = ExpandedTInfos[I];
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000534 }
535 }
536}
537
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000538NonTypeTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000539NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000540 SourceLocation StartLoc, SourceLocation IdLoc,
541 unsigned D, unsigned P, IdentifierInfo *Id,
542 QualType T, bool ParameterPack,
543 TypeSourceInfo *TInfo) {
Richard Smithf7981722013-11-22 09:01:48 +0000544 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
545 T, ParameterPack, TInfo);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000546}
547
David Majnemerdfecf1a2016-07-06 04:19:16 +0000548NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
549 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
550 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
551 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
552 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
James Y Knight7a22b242015-08-06 20:26:32 +0000553 return new (C, DC,
554 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
David Majnemerdfecf1a2016-07-06 04:19:16 +0000555 ExpandedTypes.size()))
James Y Knight7a22b242015-08-06 20:26:32 +0000556 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000557 ExpandedTypes, ExpandedTInfos);
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000558}
559
Douglas Gregor72172e92012-01-05 21:55:30 +0000560NonTypeTemplateParmDecl *
561NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000562 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
563 SourceLocation(), 0, 0, nullptr,
564 QualType(), false, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000565}
566
567NonTypeTemplateParmDecl *
568NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
569 unsigned NumExpandedTypes) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000570 auto *NTTP =
571 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
572 NumExpandedTypes))
573 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
574 0, 0, nullptr, QualType(), nullptr, None,
575 None);
576 NTTP->NumExpandedTypes = NumExpandedTypes;
577 return NTTP;
Douglas Gregor72172e92012-01-05 21:55:30 +0000578}
579
John McCallf4cd4f92011-02-09 01:13:10 +0000580SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnarae15d5532011-03-04 11:03:48 +0000581 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraea947882011-03-08 16:41:52 +0000582 return SourceRange(getOuterLocStart(),
583 getDefaultArgument()->getSourceRange().getEnd());
584 return DeclaratorDecl::getSourceRange();
John McCallf4cd4f92011-02-09 01:13:10 +0000585}
586
Douglas Gregordba32632009-02-10 19:49:53 +0000587SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara656e3002010-06-09 09:26:05 +0000588 return hasDefaultArgument()
589 ? getDefaultArgument()->getSourceRange().getBegin()
590 : SourceLocation();
Douglas Gregordba32632009-02-10 19:49:53 +0000591}
592
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000593//===----------------------------------------------------------------------===//
594// TemplateTemplateParmDecl Method Implementations
595//===----------------------------------------------------------------------===//
596
David Blaikie68e081d2011-12-20 02:48:34 +0000597void TemplateTemplateParmDecl::anchor() { }
598
Richard Smith1fde8ec2012-09-07 02:06:42 +0000599TemplateTemplateParmDecl::TemplateTemplateParmDecl(
600 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
601 IdentifierInfo *Id, TemplateParameterList *Params,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000602 ArrayRef<TemplateParameterList *> Expansions)
603 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
604 TemplateParmPosition(D, P), ParameterPack(true),
605 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
606 if (!Expansions.empty())
607 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
James Y Knight7a22b242015-08-06 20:26:32 +0000608 getTrailingObjects<TemplateParameterList *>());
Richard Smith1fde8ec2012-09-07 02:06:42 +0000609}
610
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000611TemplateTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000612TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000613 SourceLocation L, unsigned D, unsigned P,
Douglas Gregorf5500772011-01-05 15:48:55 +0000614 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000615 TemplateParameterList *Params) {
Richard Smithf7981722013-11-22 09:01:48 +0000616 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
617 Params);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000618}
619
Douglas Gregor72172e92012-01-05 21:55:30 +0000620TemplateTemplateParmDecl *
Richard Smith1fde8ec2012-09-07 02:06:42 +0000621TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
622 SourceLocation L, unsigned D, unsigned P,
623 IdentifierInfo *Id,
624 TemplateParameterList *Params,
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000625 ArrayRef<TemplateParameterList *> Expansions) {
James Y Knight7a22b242015-08-06 20:26:32 +0000626 return new (C, DC,
627 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
David Majnemerdfecf1a2016-07-06 04:19:16 +0000628 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
Richard Smith1fde8ec2012-09-07 02:06:42 +0000629}
630
631TemplateTemplateParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000632TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000633 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
634 false, nullptr, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000635}
636
Richard Smith1fde8ec2012-09-07 02:06:42 +0000637TemplateTemplateParmDecl *
638TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
639 unsigned NumExpansions) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000640 auto *TTP =
641 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
642 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
643 nullptr, None);
644 TTP->NumExpandedParams = NumExpansions;
645 return TTP;
Richard Smith1fde8ec2012-09-07 02:06:42 +0000646}
647
Richard Smith35c1df52015-06-17 20:16:32 +0000648SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
649 return hasDefaultArgument() ? getDefaultArgument().getLocation()
650 : SourceLocation();
651}
652
Richard Smith1469b912015-06-10 00:29:03 +0000653void TemplateTemplateParmDecl::setDefaultArgument(
654 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
655 if (DefArg.getArgument().isNull())
656 DefaultArgument.set(nullptr);
657 else
658 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
659}
660
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000661//===----------------------------------------------------------------------===//
Douglas Gregord002c7b2009-05-11 23:53:27 +0000662// TemplateArgumentList Implementation
663//===----------------------------------------------------------------------===//
David Majnemer8b622692016-07-03 21:17:51 +0000664TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
665 : Arguments(getTrailingObjects<TemplateArgument>()),
666 NumArguments(Args.size()) {
667 std::uninitialized_copy(Args.begin(), Args.end(),
James Y Knight7a22b242015-08-06 20:26:32 +0000668 getTrailingObjects<TemplateArgument>());
669}
670
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000671TemplateArgumentList *
672TemplateArgumentList::CreateCopy(ASTContext &Context,
David Majnemer8b622692016-07-03 21:17:51 +0000673 ArrayRef<TemplateArgument> Args) {
674 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
675 return new (Mem) TemplateArgumentList(Args);
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000676}
677
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000678FunctionTemplateSpecializationInfo *
679FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
680 FunctionTemplateDecl *Template,
681 TemplateSpecializationKind TSK,
682 const TemplateArgumentList *TemplateArgs,
683 const TemplateArgumentListInfo *TemplateArgsAsWritten,
684 SourceLocation POI) {
Craig Topper36250ad2014-05-12 05:36:57 +0000685 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000686 if (TemplateArgsAsWritten)
687 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
688 *TemplateArgsAsWritten);
689
690 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
691 TemplateArgs,
692 ArgsAsWritten,
693 POI);
694}
695
Douglas Gregord002c7b2009-05-11 23:53:27 +0000696//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000697// TemplateDecl Implementation
698//===----------------------------------------------------------------------===//
699
700void TemplateDecl::anchor() { }
701
702//===----------------------------------------------------------------------===//
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000703// ClassTemplateSpecializationDecl Implementation
704//===----------------------------------------------------------------------===//
705ClassTemplateSpecializationDecl::
Douglas Gregore9029562010-05-06 00:28:52 +0000706ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000707 DeclContext *DC, SourceLocation StartLoc,
708 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000709 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000710 ArrayRef<TemplateArgument> Args,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000711 ClassTemplateSpecializationDecl *PrevDecl)
Richard Smith053f6c62014-05-16 23:01:30 +0000712 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000713 SpecializedTemplate->getIdentifier(),
714 PrevDecl),
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000715 SpecializedTemplate(SpecializedTemplate),
Craig Topper36250ad2014-05-12 05:36:57 +0000716 ExplicitInfo(nullptr),
David Majnemer8b622692016-07-03 21:17:51 +0000717 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
Douglas Gregord002c7b2009-05-11 23:53:27 +0000718 SpecializationKind(TSK_Undeclared) {
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000719}
Mike Stump11289f42009-09-09 15:08:12 +0000720
Richard Smith053f6c62014-05-16 23:01:30 +0000721ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
722 Kind DK)
723 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
724 SourceLocation(), nullptr, nullptr),
725 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000726
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000727ClassTemplateSpecializationDecl *
Douglas Gregore9029562010-05-06 00:28:52 +0000728ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000729 DeclContext *DC,
730 SourceLocation StartLoc,
731 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000732 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000733 ArrayRef<TemplateArgument> Args,
Douglas Gregor67a65642009-02-17 23:15:12 +0000734 ClassTemplateSpecializationDecl *PrevDecl) {
Richard Smithf7981722013-11-22 09:01:48 +0000735 ClassTemplateSpecializationDecl *Result =
736 new (Context, DC) ClassTemplateSpecializationDecl(
737 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
David Majnemer8b622692016-07-03 21:17:51 +0000738 SpecializedTemplate, Args, PrevDecl);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000739 Result->MayHaveOutOfDateDef = false;
740
Douglas Gregor67a65642009-02-17 23:15:12 +0000741 Context.getTypeDeclType(Result, PrevDecl);
742 return Result;
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000743}
Douglas Gregor2373c592009-05-31 09:31:02 +0000744
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000745ClassTemplateSpecializationDecl *
Richard Smithf7981722013-11-22 09:01:48 +0000746ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000747 unsigned ID) {
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000748 ClassTemplateSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000749 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000750 Result->MayHaveOutOfDateDef = false;
751 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000752}
753
Benjamin Kramer9170e912013-02-22 15:46:01 +0000754void ClassTemplateSpecializationDecl::getNameForDiagnostic(
755 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
756 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000757
758 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Benjamin Kramer9170e912013-02-22 15:46:01 +0000759 TemplateSpecializationType::PrintTemplateArgumentList(
760 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000761}
762
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000763ClassTemplateDecl *
Mike Stump11289f42009-09-09 15:08:12 +0000764ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
765 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000766 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
767 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
768 return SpecializedTemplate.get<ClassTemplateDecl*>();
769}
770
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000771SourceRange
772ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000773 if (ExplicitInfo) {
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000774 SourceLocation Begin = getTemplateKeywordLoc();
775 if (Begin.isValid()) {
776 // Here we have an explicit (partial) specialization or instantiation.
777 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
778 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
779 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
780 if (getExternLoc().isValid())
781 Begin = getExternLoc();
782 SourceLocation End = getRBraceLoc();
783 if (End.isInvalid())
784 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
785 return SourceRange(Begin, End);
786 }
787 // An implicit instantiation of a class template partial specialization
788 // uses ExplicitInfo to record the TypeAsWritten, but the source
789 // locations should be retrieved from the instantiation pattern.
790 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
791 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
792 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
Craig Topper36250ad2014-05-12 05:36:57 +0000793 assert(inst_from != nullptr);
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000794 return inst_from->getSourceRange();
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000795 }
796 else {
797 // No explicit info available.
798 llvm::PointerUnion<ClassTemplateDecl *,
799 ClassTemplatePartialSpecializationDecl *>
800 inst_from = getInstantiatedFrom();
801 if (inst_from.isNull())
802 return getSpecializedTemplate()->getSourceRange();
803 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
804 return ctd->getSourceRange();
805 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
806 ->getSourceRange();
807 }
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000808}
809
Douglas Gregor2373c592009-05-31 09:31:02 +0000810//===----------------------------------------------------------------------===//
811// ClassTemplatePartialSpecializationDecl Implementation
812//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000813void ClassTemplatePartialSpecializationDecl::anchor() { }
814
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000815ClassTemplatePartialSpecializationDecl::
816ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000817 DeclContext *DC,
818 SourceLocation StartLoc,
819 SourceLocation IdLoc,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000820 TemplateParameterList *Params,
821 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000822 ArrayRef<TemplateArgument> Args,
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000823 const ASTTemplateArgumentListInfo *ArgInfos,
Richard Smithb2f61b42013-08-22 23:27:37 +0000824 ClassTemplatePartialSpecializationDecl *PrevDecl)
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000825 : ClassTemplateSpecializationDecl(Context,
826 ClassTemplatePartialSpecialization,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000827 TK, DC, StartLoc, IdLoc,
828 SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000829 Args, PrevDecl),
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000830 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +0000831 InstantiatedFromMember(nullptr, false)
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000832{
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000833 AdoptTemplateParameterList(Params, this);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000834}
835
Douglas Gregor2373c592009-05-31 09:31:02 +0000836ClassTemplatePartialSpecializationDecl *
837ClassTemplatePartialSpecializationDecl::
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000838Create(ASTContext &Context, TagKind TK,DeclContext *DC,
839 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregor2373c592009-05-31 09:31:02 +0000840 TemplateParameterList *Params,
841 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000842 ArrayRef<TemplateArgument> Args,
John McCall6b51f282009-11-23 01:53:49 +0000843 const TemplateArgumentListInfo &ArgInfos,
John McCalle78aac42010-03-10 03:28:59 +0000844 QualType CanonInjectedType,
Richard Smithb2f61b42013-08-22 23:27:37 +0000845 ClassTemplatePartialSpecializationDecl *PrevDecl) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000846 const ASTTemplateArgumentListInfo *ASTArgInfos =
847 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
John McCall0ad16662009-10-29 08:12:44 +0000848
Richard Smithf7981722013-11-22 09:01:48 +0000849 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
850 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
851 Params, SpecializedTemplate, Args,
David Majnemer8b622692016-07-03 21:17:51 +0000852 ASTArgInfos, PrevDecl);
Douglas Gregor2373c592009-05-31 09:31:02 +0000853 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000854 Result->MayHaveOutOfDateDef = false;
John McCalle78aac42010-03-10 03:28:59 +0000855
856 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregor2373c592009-05-31 09:31:02 +0000857 return Result;
858}
John McCall11083da2009-09-16 22:47:08 +0000859
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000860ClassTemplatePartialSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000861ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
862 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000863 ClassTemplatePartialSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000864 new (C, ID) ClassTemplatePartialSpecializationDecl(C);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000865 Result->MayHaveOutOfDateDef = false;
866 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000867}
868
John McCall11083da2009-09-16 22:47:08 +0000869//===----------------------------------------------------------------------===//
870// FriendTemplateDecl Implementation
871//===----------------------------------------------------------------------===//
872
David Blaikie68e081d2011-12-20 02:48:34 +0000873void FriendTemplateDecl::anchor() { }
874
David Majnemerdfecf1a2016-07-06 04:19:16 +0000875FriendTemplateDecl *
876FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
877 SourceLocation L,
878 MutableArrayRef<TemplateParameterList *> Params,
879 FriendUnion Friend, SourceLocation FLoc) {
880 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
John McCall11083da2009-09-16 22:47:08 +0000881}
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000882
Douglas Gregor72172e92012-01-05 21:55:30 +0000883FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
884 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000885 return new (C, ID) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000886}
Richard Smith3f1b5d02011-05-05 21:57:07 +0000887
888//===----------------------------------------------------------------------===//
889// TypeAliasTemplateDecl Implementation
890//===----------------------------------------------------------------------===//
891
892TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
893 DeclContext *DC,
894 SourceLocation L,
895 DeclarationName Name,
896 TemplateParameterList *Params,
897 NamedDecl *Decl) {
898 AdoptTemplateParameterList(Params, DC);
Richard Smith053f6c62014-05-16 23:01:30 +0000899 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000900}
901
Douglas Gregor72172e92012-01-05 21:55:30 +0000902TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
903 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000904 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000905 DeclarationName(), nullptr, nullptr);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000906}
907
908void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
909 static_cast<Common *>(Ptr)->~Common();
910}
911RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000912TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3f1b5d02011-05-05 21:57:07 +0000913 Common *CommonPtr = new (C) Common;
914 C.AddDeallocation(DeallocateCommon, CommonPtr);
915 return CommonPtr;
916}
917
David Blaikie68e081d2011-12-20 02:48:34 +0000918//===----------------------------------------------------------------------===//
919// ClassScopeFunctionSpecializationDecl Implementation
920//===----------------------------------------------------------------------===//
921
922void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor72172e92012-01-05 21:55:30 +0000923
924ClassScopeFunctionSpecializationDecl *
925ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
926 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000927 return new (C, ID) ClassScopeFunctionSpecializationDecl(
Craig Topper36250ad2014-05-12 05:36:57 +0000928 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
Douglas Gregor72172e92012-01-05 21:55:30 +0000929}
Larisse Voufo39a1e502013-08-06 01:03:05 +0000930
931//===----------------------------------------------------------------------===//
932// VarTemplateDecl Implementation
933//===----------------------------------------------------------------------===//
934
935void VarTemplateDecl::DeallocateCommon(void *Ptr) {
936 static_cast<Common *>(Ptr)->~Common();
937}
938
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000939VarTemplateDecl *VarTemplateDecl::getDefinition() {
940 VarTemplateDecl *CurD = this;
941 while (CurD) {
942 if (CurD->isThisDeclarationADefinition())
943 return CurD;
944 CurD = CurD->getPreviousDecl();
945 }
Craig Topper36250ad2014-05-12 05:36:57 +0000946 return nullptr;
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000947}
948
Larisse Voufo39a1e502013-08-06 01:03:05 +0000949VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
950 SourceLocation L, DeclarationName Name,
951 TemplateParameterList *Params,
Richard Smithbeef3452014-01-16 23:39:20 +0000952 VarDecl *Decl) {
Richard Smith053f6c62014-05-16 23:01:30 +0000953 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000954}
955
956VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
957 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000958 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
959 DeclarationName(), nullptr, nullptr);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000960}
961
Alp Tokerf6a24ce2013-12-05 16:25:25 +0000962// TODO: Unify across class, function and variable templates?
Larisse Voufo30616382013-08-23 22:21:36 +0000963// May require moving this and Common to RedeclarableTemplateDecl.
Larisse Voufo39a1e502013-08-06 01:03:05 +0000964void VarTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000965 // Grab the most recent declaration to ensure we've loaded any lazy
966 // redeclarations of this template.
967 //
968 // FIXME: Avoid walking the entire redeclaration chain here.
969 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Larisse Voufo39a1e502013-08-06 01:03:05 +0000970 if (CommonPtr->LazySpecializations) {
971 ASTContext &Context = getASTContext();
972 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000973 CommonPtr->LazySpecializations = nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +0000974 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
975 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
976 }
977}
978
979llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
980VarTemplateDecl::getSpecializations() const {
981 LoadLazySpecializations();
982 return getCommonPtr()->Specializations;
983}
984
985llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
986VarTemplateDecl::getPartialSpecializations() {
987 LoadLazySpecializations();
988 return getCommonPtr()->PartialSpecializations;
989}
990
991RedeclarableTemplateDecl::CommonBase *
992VarTemplateDecl::newCommon(ASTContext &C) const {
993 Common *CommonPtr = new (C) Common;
994 C.AddDeallocation(DeallocateCommon, CommonPtr);
995 return CommonPtr;
996}
997
998VarTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000999VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1000 void *&InsertPos) {
1001 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001002}
1003
1004void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1005 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +00001006 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001007}
1008
1009VarTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +00001010VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1011 void *&InsertPos) {
1012 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001013}
1014
1015void VarTemplateDecl::AddPartialSpecialization(
1016 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1017 if (InsertPos)
1018 getPartialSpecializations().InsertNode(D, InsertPos);
1019 else {
1020 VarTemplatePartialSpecializationDecl *Existing =
1021 getPartialSpecializations().GetOrInsertNode(D);
1022 (void)Existing;
1023 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1024 }
1025
1026 if (ASTMutationListener *L = getASTMutationListener())
1027 L->AddedCXXTemplateSpecialization(this, D);
1028}
1029
1030void VarTemplateDecl::getPartialSpecializations(
1031 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1032 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1033 getPartialSpecializations();
1034 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +00001035 PS.reserve(PartialSpecs.size());
David Majnemerdfecf1a2016-07-06 04:19:16 +00001036 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1037 PS.push_back(P.getMostRecentDecl());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001038}
1039
1040VarTemplatePartialSpecializationDecl *
1041VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1042 VarTemplatePartialSpecializationDecl *D) {
1043 Decl *DCanon = D->getCanonicalDecl();
David Majnemerdfecf1a2016-07-06 04:19:16 +00001044 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1045 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1046 return P.getMostRecentDecl();
Larisse Voufo39a1e502013-08-06 01:03:05 +00001047 }
1048
Craig Topper36250ad2014-05-12 05:36:57 +00001049 return nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +00001050}
1051
1052//===----------------------------------------------------------------------===//
1053// VarTemplateSpecializationDecl Implementation
1054//===----------------------------------------------------------------------===//
1055VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001056 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001057 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
David Majnemer8b622692016-07-03 21:17:51 +00001058 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
Richard Smith053f6c62014-05-16 23:01:30 +00001059 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1060 SpecializedTemplate->getIdentifier(), T, TInfo, S),
Craig Topper36250ad2014-05-12 05:36:57 +00001061 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
David Majnemer8b622692016-07-03 21:17:51 +00001062 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001063 SpecializationKind(TSK_Undeclared) {}
1064
Richard Smith053f6c62014-05-16 23:01:30 +00001065VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1066 ASTContext &C)
1067 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
Craig Topper36250ad2014-05-12 05:36:57 +00001068 QualType(), nullptr, SC_None),
1069 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Larisse Voufo39a1e502013-08-06 01:03:05 +00001070
1071VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1072 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1073 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
David Majnemer8b622692016-07-03 21:17:51 +00001074 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
Richard Smithf7981722013-11-22 09:01:48 +00001075 return new (Context, DC) VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001076 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
David Majnemer8b622692016-07-03 21:17:51 +00001077 SpecializedTemplate, T, TInfo, S, Args);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001078}
1079
1080VarTemplateSpecializationDecl *
1081VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001082 return new (C, ID)
1083 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001084}
1085
1086void VarTemplateSpecializationDecl::getNameForDiagnostic(
1087 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1088 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1089
1090 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1091 TemplateSpecializationType::PrintTemplateArgumentList(
1092 OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
1093}
1094
1095VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1096 if (SpecializedPartialSpecialization *PartialSpec =
1097 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1098 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1099 return SpecializedTemplate.get<VarTemplateDecl *>();
1100}
1101
1102void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1103 const TemplateArgumentListInfo &ArgsInfo) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001104 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1105 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
David Majnemerdfecf1a2016-07-06 04:19:16 +00001106 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1107 TemplateArgsInfo.addArgument(Loc);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001108}
1109
1110//===----------------------------------------------------------------------===//
1111// VarTemplatePartialSpecializationDecl Implementation
1112//===----------------------------------------------------------------------===//
1113void VarTemplatePartialSpecializationDecl::anchor() {}
1114
1115VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1116 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1117 SourceLocation IdLoc, TemplateParameterList *Params,
1118 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001119 StorageClass S, ArrayRef<TemplateArgument> Args,
Richard Smithb2f61b42013-08-22 23:27:37 +00001120 const ASTTemplateArgumentListInfo *ArgInfos)
Richard Smith053f6c62014-05-16 23:01:30 +00001121 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001122 DC, StartLoc, IdLoc, SpecializedTemplate, T,
David Majnemer8b622692016-07-03 21:17:51 +00001123 TInfo, S, Args),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001124 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +00001125 InstantiatedFromMember(nullptr, false) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001126 // TODO: The template parameters should be in DC by now. Verify.
1127 // AdoptTemplateParameterList(Params, DC);
1128}
1129
1130VarTemplatePartialSpecializationDecl *
1131VarTemplatePartialSpecializationDecl::Create(
1132 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1133 SourceLocation IdLoc, TemplateParameterList *Params,
1134 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001135 StorageClass S, ArrayRef<TemplateArgument> Args,
Richard Smithb2f61b42013-08-22 23:27:37 +00001136 const TemplateArgumentListInfo &ArgInfos) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +00001137 const ASTTemplateArgumentListInfo *ASTArgInfos
1138 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001139
1140 VarTemplatePartialSpecializationDecl *Result =
Richard Smithf7981722013-11-22 09:01:48 +00001141 new (Context, DC) VarTemplatePartialSpecializationDecl(
Larisse Voufo39a1e502013-08-06 01:03:05 +00001142 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001143 S, Args, ASTArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001144 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1145 return Result;
1146}
1147
1148VarTemplatePartialSpecializationDecl *
1149VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1150 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001151 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001152}
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001153
1154static TemplateParameterList *
1155createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1156 // typename T
1157 auto *T = TemplateTypeParmDecl::Create(
1158 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1159 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1160 T->setImplicit(true);
1161
1162 // T ...Ints
1163 TypeSourceInfo *TI =
1164 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1165 auto *N = NonTypeTemplateParmDecl::Create(
1166 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1167 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1168 N->setImplicit(true);
1169
1170 // <typename T, T ...Ints>
1171 NamedDecl *P[2] = {T, N};
1172 auto *TPL = TemplateParameterList::Create(
David Majnemer902f8c62015-12-27 07:16:27 +00001173 C, SourceLocation(), SourceLocation(), P, SourceLocation());
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001174
1175 // template <typename T, ...Ints> class IntSeq
1176 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1177 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1178 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1179 TemplateTemplateParm->setImplicit(true);
1180
1181 // typename T
1182 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1183 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1184 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1185 TemplateTypeParm->setImplicit(true);
1186
1187 // T N
1188 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1189 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1190 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1191 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1192 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1193 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1194 NonTypeTemplateParm};
1195
1196 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1197 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
David Majnemer902f8c62015-12-27 07:16:27 +00001198 Params, SourceLocation());
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001199}
1200
Eric Fiselier6ad68552016-07-01 01:24:09 +00001201static TemplateParameterList *
1202createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1203 // std::size_t Index
1204 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1205 auto *Index = NonTypeTemplateParmDecl::Create(
1206 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1207 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1208
1209 // typename ...T
1210 auto *Ts = TemplateTypeParmDecl::Create(
1211 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1212 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1213 Ts->setImplicit(true);
1214
1215 // template <std::size_t Index, typename ...T>
1216 NamedDecl *Params[] = {Index, Ts};
1217 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1218 llvm::makeArrayRef(Params),
1219 SourceLocation());
1220}
1221
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001222static TemplateParameterList *createBuiltinTemplateParameterList(
1223 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1224 switch (BTK) {
1225 case BTK__make_integer_seq:
1226 return createMakeIntegerSeqParameterList(C, DC);
Eric Fiselier6ad68552016-07-01 01:24:09 +00001227 case BTK__type_pack_element:
1228 return createTypePackElementParameterList(C, DC);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001229 }
1230
1231 llvm_unreachable("unhandled BuiltinTemplateKind!");
1232}
1233
1234void BuiltinTemplateDecl::anchor() {}
1235
1236BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1237 DeclarationName Name,
1238 BuiltinTemplateKind BTK)
1239 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1240 createBuiltinTemplateParameterList(C, DC, BTK)),
1241 BTK(BTK) {}