blob: 37943cdd5b7b3e1defe33519cf450620aa21b9a6 [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),
David Majnemer6fbeee32016-07-07 04:43:07 +0000464 TemplateArgs);
Douglas Gregore362cea2009-05-10 22:57:19 +0000465 return CommonPtr->InjectedClassNameType;
466}
467
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000468//===----------------------------------------------------------------------===//
469// TemplateTypeParm Allocation/Deallocation Method Implementations
470//===----------------------------------------------------------------------===//
471
472TemplateTypeParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000473TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000474 SourceLocation KeyLoc, SourceLocation NameLoc,
475 unsigned D, unsigned P, IdentifierInfo *Id,
476 bool Typename, bool ParameterPack) {
Chandler Carruth08836322011-05-01 00:51:33 +0000477 TemplateTypeParmDecl *TTPDecl =
Richard Smithf7981722013-11-22 09:01:48 +0000478 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
Chandler Carruth08836322011-05-01 00:51:33 +0000479 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
Richard Smith5b21db82014-04-23 18:20:42 +0000480 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
Chandler Carruth08836322011-05-01 00:51:33 +0000481 return TTPDecl;
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000482}
483
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000484TemplateTypeParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000485TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000486 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
487 SourceLocation(), nullptr, false);
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000488}
489
John McCall0ad16662009-10-29 08:12:44 +0000490SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara23485e02011-03-04 12:42:03 +0000491 return hasDefaultArgument()
Richard Smith1469b912015-06-10 00:29:03 +0000492 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
493 : SourceLocation();
Abramo Bagnara23485e02011-03-04 12:42:03 +0000494}
495
496SourceRange TemplateTypeParmDecl::getSourceRange() const {
497 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000498 return SourceRange(getLocStart(),
Richard Smith1469b912015-06-10 00:29:03 +0000499 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
Abramo Bagnara23485e02011-03-04 12:42:03 +0000500 else
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000501 return TypeDecl::getSourceRange();
John McCall0ad16662009-10-29 08:12:44 +0000502}
503
Douglas Gregor21610382009-10-29 00:04:11 +0000504unsigned TemplateTypeParmDecl::getDepth() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000505 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
Douglas Gregor21610382009-10-29 00:04:11 +0000506}
507
508unsigned TemplateTypeParmDecl::getIndex() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000509 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
Douglas Gregor21610382009-10-29 00:04:11 +0000510}
511
Chandler Carruth08836322011-05-01 00:51:33 +0000512bool TemplateTypeParmDecl::isParameterPack() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000513 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
Chandler Carruth08836322011-05-01 00:51:33 +0000514}
515
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000516//===----------------------------------------------------------------------===//
517// NonTypeTemplateParmDecl Method Implementations
518//===----------------------------------------------------------------------===//
519
David Majnemerdfecf1a2016-07-06 04:19:16 +0000520NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
521 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
522 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
523 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
524 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
525 TemplateParmPosition(D, P), ParameterPack(true),
526 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
527 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
James Y Knight7a22b242015-08-06 20:26:32 +0000528 auto TypesAndInfos =
529 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000530 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
James Y Knight7a22b242015-08-06 20:26:32 +0000531 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
532 TypesAndInfos[I].second = ExpandedTInfos[I];
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000533 }
534 }
535}
536
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000537NonTypeTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000538NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000539 SourceLocation StartLoc, SourceLocation IdLoc,
540 unsigned D, unsigned P, IdentifierInfo *Id,
541 QualType T, bool ParameterPack,
542 TypeSourceInfo *TInfo) {
Richard Smithf7981722013-11-22 09:01:48 +0000543 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
544 T, ParameterPack, TInfo);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000545}
546
David Majnemerdfecf1a2016-07-06 04:19:16 +0000547NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
548 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
549 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
550 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
551 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
James Y Knight7a22b242015-08-06 20:26:32 +0000552 return new (C, DC,
553 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
David Majnemerdfecf1a2016-07-06 04:19:16 +0000554 ExpandedTypes.size()))
James Y Knight7a22b242015-08-06 20:26:32 +0000555 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000556 ExpandedTypes, ExpandedTInfos);
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000557}
558
Douglas Gregor72172e92012-01-05 21:55:30 +0000559NonTypeTemplateParmDecl *
560NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000561 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
562 SourceLocation(), 0, 0, nullptr,
563 QualType(), false, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000564}
565
566NonTypeTemplateParmDecl *
567NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
568 unsigned NumExpandedTypes) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000569 auto *NTTP =
570 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
571 NumExpandedTypes))
572 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
573 0, 0, nullptr, QualType(), nullptr, None,
574 None);
575 NTTP->NumExpandedTypes = NumExpandedTypes;
576 return NTTP;
Douglas Gregor72172e92012-01-05 21:55:30 +0000577}
578
John McCallf4cd4f92011-02-09 01:13:10 +0000579SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnarae15d5532011-03-04 11:03:48 +0000580 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraea947882011-03-08 16:41:52 +0000581 return SourceRange(getOuterLocStart(),
582 getDefaultArgument()->getSourceRange().getEnd());
583 return DeclaratorDecl::getSourceRange();
John McCallf4cd4f92011-02-09 01:13:10 +0000584}
585
Douglas Gregordba32632009-02-10 19:49:53 +0000586SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara656e3002010-06-09 09:26:05 +0000587 return hasDefaultArgument()
588 ? getDefaultArgument()->getSourceRange().getBegin()
589 : SourceLocation();
Douglas Gregordba32632009-02-10 19:49:53 +0000590}
591
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000592//===----------------------------------------------------------------------===//
593// TemplateTemplateParmDecl Method Implementations
594//===----------------------------------------------------------------------===//
595
David Blaikie68e081d2011-12-20 02:48:34 +0000596void TemplateTemplateParmDecl::anchor() { }
597
Richard Smith1fde8ec2012-09-07 02:06:42 +0000598TemplateTemplateParmDecl::TemplateTemplateParmDecl(
599 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
600 IdentifierInfo *Id, TemplateParameterList *Params,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000601 ArrayRef<TemplateParameterList *> Expansions)
602 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
603 TemplateParmPosition(D, P), ParameterPack(true),
604 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
605 if (!Expansions.empty())
606 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
James Y Knight7a22b242015-08-06 20:26:32 +0000607 getTrailingObjects<TemplateParameterList *>());
Richard Smith1fde8ec2012-09-07 02:06:42 +0000608}
609
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000610TemplateTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000611TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000612 SourceLocation L, unsigned D, unsigned P,
Douglas Gregorf5500772011-01-05 15:48:55 +0000613 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000614 TemplateParameterList *Params) {
Richard Smithf7981722013-11-22 09:01:48 +0000615 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
616 Params);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000617}
618
Douglas Gregor72172e92012-01-05 21:55:30 +0000619TemplateTemplateParmDecl *
Richard Smith1fde8ec2012-09-07 02:06:42 +0000620TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
621 SourceLocation L, unsigned D, unsigned P,
622 IdentifierInfo *Id,
623 TemplateParameterList *Params,
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000624 ArrayRef<TemplateParameterList *> Expansions) {
James Y Knight7a22b242015-08-06 20:26:32 +0000625 return new (C, DC,
626 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
David Majnemerdfecf1a2016-07-06 04:19:16 +0000627 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
Richard Smith1fde8ec2012-09-07 02:06:42 +0000628}
629
630TemplateTemplateParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000631TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000632 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
633 false, nullptr, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000634}
635
Richard Smith1fde8ec2012-09-07 02:06:42 +0000636TemplateTemplateParmDecl *
637TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
638 unsigned NumExpansions) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000639 auto *TTP =
640 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
641 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
642 nullptr, None);
643 TTP->NumExpandedParams = NumExpansions;
644 return TTP;
Richard Smith1fde8ec2012-09-07 02:06:42 +0000645}
646
Richard Smith35c1df52015-06-17 20:16:32 +0000647SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
648 return hasDefaultArgument() ? getDefaultArgument().getLocation()
649 : SourceLocation();
650}
651
Richard Smith1469b912015-06-10 00:29:03 +0000652void TemplateTemplateParmDecl::setDefaultArgument(
653 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
654 if (DefArg.getArgument().isNull())
655 DefaultArgument.set(nullptr);
656 else
657 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
658}
659
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000660//===----------------------------------------------------------------------===//
Douglas Gregord002c7b2009-05-11 23:53:27 +0000661// TemplateArgumentList Implementation
662//===----------------------------------------------------------------------===//
David Majnemer8b622692016-07-03 21:17:51 +0000663TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
664 : Arguments(getTrailingObjects<TemplateArgument>()),
665 NumArguments(Args.size()) {
666 std::uninitialized_copy(Args.begin(), Args.end(),
James Y Knight7a22b242015-08-06 20:26:32 +0000667 getTrailingObjects<TemplateArgument>());
668}
669
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000670TemplateArgumentList *
671TemplateArgumentList::CreateCopy(ASTContext &Context,
David Majnemer8b622692016-07-03 21:17:51 +0000672 ArrayRef<TemplateArgument> Args) {
673 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
674 return new (Mem) TemplateArgumentList(Args);
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000675}
676
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000677FunctionTemplateSpecializationInfo *
678FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
679 FunctionTemplateDecl *Template,
680 TemplateSpecializationKind TSK,
681 const TemplateArgumentList *TemplateArgs,
682 const TemplateArgumentListInfo *TemplateArgsAsWritten,
683 SourceLocation POI) {
Craig Topper36250ad2014-05-12 05:36:57 +0000684 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000685 if (TemplateArgsAsWritten)
686 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
687 *TemplateArgsAsWritten);
688
689 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
690 TemplateArgs,
691 ArgsAsWritten,
692 POI);
693}
694
Douglas Gregord002c7b2009-05-11 23:53:27 +0000695//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000696// TemplateDecl Implementation
697//===----------------------------------------------------------------------===//
698
699void TemplateDecl::anchor() { }
700
701//===----------------------------------------------------------------------===//
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000702// ClassTemplateSpecializationDecl Implementation
703//===----------------------------------------------------------------------===//
704ClassTemplateSpecializationDecl::
Douglas Gregore9029562010-05-06 00:28:52 +0000705ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000706 DeclContext *DC, SourceLocation StartLoc,
707 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000708 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000709 ArrayRef<TemplateArgument> Args,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000710 ClassTemplateSpecializationDecl *PrevDecl)
Richard Smith053f6c62014-05-16 23:01:30 +0000711 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000712 SpecializedTemplate->getIdentifier(),
713 PrevDecl),
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000714 SpecializedTemplate(SpecializedTemplate),
Craig Topper36250ad2014-05-12 05:36:57 +0000715 ExplicitInfo(nullptr),
David Majnemer8b622692016-07-03 21:17:51 +0000716 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
Douglas Gregord002c7b2009-05-11 23:53:27 +0000717 SpecializationKind(TSK_Undeclared) {
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000718}
Mike Stump11289f42009-09-09 15:08:12 +0000719
Richard Smith053f6c62014-05-16 23:01:30 +0000720ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
721 Kind DK)
722 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
723 SourceLocation(), nullptr, nullptr),
724 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000725
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000726ClassTemplateSpecializationDecl *
Douglas Gregore9029562010-05-06 00:28:52 +0000727ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000728 DeclContext *DC,
729 SourceLocation StartLoc,
730 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000731 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000732 ArrayRef<TemplateArgument> Args,
Douglas Gregor67a65642009-02-17 23:15:12 +0000733 ClassTemplateSpecializationDecl *PrevDecl) {
Richard Smithf7981722013-11-22 09:01:48 +0000734 ClassTemplateSpecializationDecl *Result =
735 new (Context, DC) ClassTemplateSpecializationDecl(
736 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
David Majnemer8b622692016-07-03 21:17:51 +0000737 SpecializedTemplate, Args, PrevDecl);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000738 Result->MayHaveOutOfDateDef = false;
739
Douglas Gregor67a65642009-02-17 23:15:12 +0000740 Context.getTypeDeclType(Result, PrevDecl);
741 return Result;
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000742}
Douglas Gregor2373c592009-05-31 09:31:02 +0000743
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000744ClassTemplateSpecializationDecl *
Richard Smithf7981722013-11-22 09:01:48 +0000745ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000746 unsigned ID) {
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000747 ClassTemplateSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000748 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000749 Result->MayHaveOutOfDateDef = false;
750 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000751}
752
Benjamin Kramer9170e912013-02-22 15:46:01 +0000753void ClassTemplateSpecializationDecl::getNameForDiagnostic(
754 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
755 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000756
757 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Benjamin Kramer9170e912013-02-22 15:46:01 +0000758 TemplateSpecializationType::PrintTemplateArgumentList(
David Majnemer6fbeee32016-07-07 04:43:07 +0000759 OS, TemplateArgs.asArray(), Policy);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000760}
761
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000762ClassTemplateDecl *
Mike Stump11289f42009-09-09 15:08:12 +0000763ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
764 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000765 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
766 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
767 return SpecializedTemplate.get<ClassTemplateDecl*>();
768}
769
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000770SourceRange
771ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000772 if (ExplicitInfo) {
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000773 SourceLocation Begin = getTemplateKeywordLoc();
774 if (Begin.isValid()) {
775 // Here we have an explicit (partial) specialization or instantiation.
776 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
777 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
778 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
779 if (getExternLoc().isValid())
780 Begin = getExternLoc();
Argyrios Kyrtzidisd798c052016-07-15 18:11:33 +0000781 SourceLocation End = getBraceRange().getEnd();
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000782 if (End.isInvalid())
783 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
784 return SourceRange(Begin, End);
785 }
786 // An implicit instantiation of a class template partial specialization
787 // uses ExplicitInfo to record the TypeAsWritten, but the source
788 // locations should be retrieved from the instantiation pattern.
789 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
790 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
791 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
Craig Topper36250ad2014-05-12 05:36:57 +0000792 assert(inst_from != nullptr);
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000793 return inst_from->getSourceRange();
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000794 }
795 else {
796 // No explicit info available.
797 llvm::PointerUnion<ClassTemplateDecl *,
798 ClassTemplatePartialSpecializationDecl *>
799 inst_from = getInstantiatedFrom();
800 if (inst_from.isNull())
801 return getSpecializedTemplate()->getSourceRange();
802 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
803 return ctd->getSourceRange();
804 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
805 ->getSourceRange();
806 }
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000807}
808
Douglas Gregor2373c592009-05-31 09:31:02 +0000809//===----------------------------------------------------------------------===//
810// ClassTemplatePartialSpecializationDecl Implementation
811//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000812void ClassTemplatePartialSpecializationDecl::anchor() { }
813
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000814ClassTemplatePartialSpecializationDecl::
815ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000816 DeclContext *DC,
817 SourceLocation StartLoc,
818 SourceLocation IdLoc,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000819 TemplateParameterList *Params,
820 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000821 ArrayRef<TemplateArgument> Args,
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000822 const ASTTemplateArgumentListInfo *ArgInfos,
Richard Smithb2f61b42013-08-22 23:27:37 +0000823 ClassTemplatePartialSpecializationDecl *PrevDecl)
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000824 : ClassTemplateSpecializationDecl(Context,
825 ClassTemplatePartialSpecialization,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000826 TK, DC, StartLoc, IdLoc,
827 SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000828 Args, PrevDecl),
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000829 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +0000830 InstantiatedFromMember(nullptr, false)
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000831{
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000832 AdoptTemplateParameterList(Params, this);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000833}
834
Douglas Gregor2373c592009-05-31 09:31:02 +0000835ClassTemplatePartialSpecializationDecl *
836ClassTemplatePartialSpecializationDecl::
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000837Create(ASTContext &Context, TagKind TK,DeclContext *DC,
838 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregor2373c592009-05-31 09:31:02 +0000839 TemplateParameterList *Params,
840 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000841 ArrayRef<TemplateArgument> Args,
John McCall6b51f282009-11-23 01:53:49 +0000842 const TemplateArgumentListInfo &ArgInfos,
John McCalle78aac42010-03-10 03:28:59 +0000843 QualType CanonInjectedType,
Richard Smithb2f61b42013-08-22 23:27:37 +0000844 ClassTemplatePartialSpecializationDecl *PrevDecl) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000845 const ASTTemplateArgumentListInfo *ASTArgInfos =
846 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
John McCall0ad16662009-10-29 08:12:44 +0000847
Richard Smithf7981722013-11-22 09:01:48 +0000848 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
849 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
850 Params, SpecializedTemplate, Args,
David Majnemer8b622692016-07-03 21:17:51 +0000851 ASTArgInfos, PrevDecl);
Douglas Gregor2373c592009-05-31 09:31:02 +0000852 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000853 Result->MayHaveOutOfDateDef = false;
John McCalle78aac42010-03-10 03:28:59 +0000854
855 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregor2373c592009-05-31 09:31:02 +0000856 return Result;
857}
John McCall11083da2009-09-16 22:47:08 +0000858
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000859ClassTemplatePartialSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000860ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
861 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000862 ClassTemplatePartialSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000863 new (C, ID) ClassTemplatePartialSpecializationDecl(C);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000864 Result->MayHaveOutOfDateDef = false;
865 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000866}
867
John McCall11083da2009-09-16 22:47:08 +0000868//===----------------------------------------------------------------------===//
869// FriendTemplateDecl Implementation
870//===----------------------------------------------------------------------===//
871
David Blaikie68e081d2011-12-20 02:48:34 +0000872void FriendTemplateDecl::anchor() { }
873
David Majnemerdfecf1a2016-07-06 04:19:16 +0000874FriendTemplateDecl *
875FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
876 SourceLocation L,
877 MutableArrayRef<TemplateParameterList *> Params,
878 FriendUnion Friend, SourceLocation FLoc) {
879 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
John McCall11083da2009-09-16 22:47:08 +0000880}
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000881
Douglas Gregor72172e92012-01-05 21:55:30 +0000882FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
883 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000884 return new (C, ID) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000885}
Richard Smith3f1b5d02011-05-05 21:57:07 +0000886
887//===----------------------------------------------------------------------===//
888// TypeAliasTemplateDecl Implementation
889//===----------------------------------------------------------------------===//
890
891TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
892 DeclContext *DC,
893 SourceLocation L,
894 DeclarationName Name,
895 TemplateParameterList *Params,
896 NamedDecl *Decl) {
897 AdoptTemplateParameterList(Params, DC);
Richard Smith053f6c62014-05-16 23:01:30 +0000898 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000899}
900
Douglas Gregor72172e92012-01-05 21:55:30 +0000901TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
902 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000903 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000904 DeclarationName(), nullptr, nullptr);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000905}
906
907void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
908 static_cast<Common *>(Ptr)->~Common();
909}
910RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000911TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3f1b5d02011-05-05 21:57:07 +0000912 Common *CommonPtr = new (C) Common;
913 C.AddDeallocation(DeallocateCommon, CommonPtr);
914 return CommonPtr;
915}
916
David Blaikie68e081d2011-12-20 02:48:34 +0000917//===----------------------------------------------------------------------===//
918// ClassScopeFunctionSpecializationDecl Implementation
919//===----------------------------------------------------------------------===//
920
921void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor72172e92012-01-05 21:55:30 +0000922
923ClassScopeFunctionSpecializationDecl *
924ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
925 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000926 return new (C, ID) ClassScopeFunctionSpecializationDecl(
Craig Topper36250ad2014-05-12 05:36:57 +0000927 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
Douglas Gregor72172e92012-01-05 21:55:30 +0000928}
Larisse Voufo39a1e502013-08-06 01:03:05 +0000929
930//===----------------------------------------------------------------------===//
931// VarTemplateDecl Implementation
932//===----------------------------------------------------------------------===//
933
934void VarTemplateDecl::DeallocateCommon(void *Ptr) {
935 static_cast<Common *>(Ptr)->~Common();
936}
937
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000938VarTemplateDecl *VarTemplateDecl::getDefinition() {
939 VarTemplateDecl *CurD = this;
940 while (CurD) {
941 if (CurD->isThisDeclarationADefinition())
942 return CurD;
943 CurD = CurD->getPreviousDecl();
944 }
Craig Topper36250ad2014-05-12 05:36:57 +0000945 return nullptr;
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000946}
947
Larisse Voufo39a1e502013-08-06 01:03:05 +0000948VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
949 SourceLocation L, DeclarationName Name,
950 TemplateParameterList *Params,
Richard Smithbeef3452014-01-16 23:39:20 +0000951 VarDecl *Decl) {
Richard Smith053f6c62014-05-16 23:01:30 +0000952 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000953}
954
955VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
956 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000957 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
958 DeclarationName(), nullptr, nullptr);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000959}
960
Alp Tokerf6a24ce2013-12-05 16:25:25 +0000961// TODO: Unify across class, function and variable templates?
Larisse Voufo30616382013-08-23 22:21:36 +0000962// May require moving this and Common to RedeclarableTemplateDecl.
Larisse Voufo39a1e502013-08-06 01:03:05 +0000963void VarTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000964 // Grab the most recent declaration to ensure we've loaded any lazy
965 // redeclarations of this template.
966 //
967 // FIXME: Avoid walking the entire redeclaration chain here.
968 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Larisse Voufo39a1e502013-08-06 01:03:05 +0000969 if (CommonPtr->LazySpecializations) {
970 ASTContext &Context = getASTContext();
971 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000972 CommonPtr->LazySpecializations = nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +0000973 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
974 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
975 }
976}
977
978llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
979VarTemplateDecl::getSpecializations() const {
980 LoadLazySpecializations();
981 return getCommonPtr()->Specializations;
982}
983
984llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
985VarTemplateDecl::getPartialSpecializations() {
986 LoadLazySpecializations();
987 return getCommonPtr()->PartialSpecializations;
988}
989
990RedeclarableTemplateDecl::CommonBase *
991VarTemplateDecl::newCommon(ASTContext &C) const {
992 Common *CommonPtr = new (C) Common;
993 C.AddDeallocation(DeallocateCommon, CommonPtr);
994 return CommonPtr;
995}
996
997VarTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000998VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
999 void *&InsertPos) {
1000 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001001}
1002
1003void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1004 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +00001005 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001006}
1007
1008VarTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +00001009VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1010 void *&InsertPos) {
1011 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001012}
1013
1014void VarTemplateDecl::AddPartialSpecialization(
1015 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1016 if (InsertPos)
1017 getPartialSpecializations().InsertNode(D, InsertPos);
1018 else {
1019 VarTemplatePartialSpecializationDecl *Existing =
1020 getPartialSpecializations().GetOrInsertNode(D);
1021 (void)Existing;
1022 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1023 }
1024
1025 if (ASTMutationListener *L = getASTMutationListener())
1026 L->AddedCXXTemplateSpecialization(this, D);
1027}
1028
1029void VarTemplateDecl::getPartialSpecializations(
1030 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1031 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1032 getPartialSpecializations();
1033 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +00001034 PS.reserve(PartialSpecs.size());
David Majnemerdfecf1a2016-07-06 04:19:16 +00001035 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1036 PS.push_back(P.getMostRecentDecl());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001037}
1038
1039VarTemplatePartialSpecializationDecl *
1040VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1041 VarTemplatePartialSpecializationDecl *D) {
1042 Decl *DCanon = D->getCanonicalDecl();
David Majnemerdfecf1a2016-07-06 04:19:16 +00001043 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1044 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1045 return P.getMostRecentDecl();
Larisse Voufo39a1e502013-08-06 01:03:05 +00001046 }
1047
Craig Topper36250ad2014-05-12 05:36:57 +00001048 return nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +00001049}
1050
1051//===----------------------------------------------------------------------===//
1052// VarTemplateSpecializationDecl Implementation
1053//===----------------------------------------------------------------------===//
1054VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001055 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001056 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
David Majnemer8b622692016-07-03 21:17:51 +00001057 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
Richard Smith053f6c62014-05-16 23:01:30 +00001058 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1059 SpecializedTemplate->getIdentifier(), T, TInfo, S),
Craig Topper36250ad2014-05-12 05:36:57 +00001060 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
David Majnemer8b622692016-07-03 21:17:51 +00001061 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001062 SpecializationKind(TSK_Undeclared) {}
1063
Richard Smith053f6c62014-05-16 23:01:30 +00001064VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1065 ASTContext &C)
1066 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
Craig Topper36250ad2014-05-12 05:36:57 +00001067 QualType(), nullptr, SC_None),
1068 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Larisse Voufo39a1e502013-08-06 01:03:05 +00001069
1070VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1071 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1072 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
David Majnemer8b622692016-07-03 21:17:51 +00001073 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
Richard Smithf7981722013-11-22 09:01:48 +00001074 return new (Context, DC) VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001075 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
David Majnemer8b622692016-07-03 21:17:51 +00001076 SpecializedTemplate, T, TInfo, S, Args);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001077}
1078
1079VarTemplateSpecializationDecl *
1080VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001081 return new (C, ID)
1082 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001083}
1084
1085void VarTemplateSpecializationDecl::getNameForDiagnostic(
1086 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1087 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1088
1089 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1090 TemplateSpecializationType::PrintTemplateArgumentList(
David Majnemer6fbeee32016-07-07 04:43:07 +00001091 OS, TemplateArgs.asArray(), Policy);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001092}
1093
1094VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1095 if (SpecializedPartialSpecialization *PartialSpec =
1096 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1097 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1098 return SpecializedTemplate.get<VarTemplateDecl *>();
1099}
1100
1101void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1102 const TemplateArgumentListInfo &ArgsInfo) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001103 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1104 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
David Majnemerdfecf1a2016-07-06 04:19:16 +00001105 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1106 TemplateArgsInfo.addArgument(Loc);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001107}
1108
1109//===----------------------------------------------------------------------===//
1110// VarTemplatePartialSpecializationDecl Implementation
1111//===----------------------------------------------------------------------===//
1112void VarTemplatePartialSpecializationDecl::anchor() {}
1113
1114VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1115 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1116 SourceLocation IdLoc, TemplateParameterList *Params,
1117 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001118 StorageClass S, ArrayRef<TemplateArgument> Args,
Richard Smithb2f61b42013-08-22 23:27:37 +00001119 const ASTTemplateArgumentListInfo *ArgInfos)
Richard Smith053f6c62014-05-16 23:01:30 +00001120 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001121 DC, StartLoc, IdLoc, SpecializedTemplate, T,
David Majnemer8b622692016-07-03 21:17:51 +00001122 TInfo, S, Args),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001123 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +00001124 InstantiatedFromMember(nullptr, false) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001125 // TODO: The template parameters should be in DC by now. Verify.
1126 // AdoptTemplateParameterList(Params, DC);
1127}
1128
1129VarTemplatePartialSpecializationDecl *
1130VarTemplatePartialSpecializationDecl::Create(
1131 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1132 SourceLocation IdLoc, TemplateParameterList *Params,
1133 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001134 StorageClass S, ArrayRef<TemplateArgument> Args,
Richard Smithb2f61b42013-08-22 23:27:37 +00001135 const TemplateArgumentListInfo &ArgInfos) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +00001136 const ASTTemplateArgumentListInfo *ASTArgInfos
1137 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001138
1139 VarTemplatePartialSpecializationDecl *Result =
Richard Smithf7981722013-11-22 09:01:48 +00001140 new (Context, DC) VarTemplatePartialSpecializationDecl(
Larisse Voufo39a1e502013-08-06 01:03:05 +00001141 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001142 S, Args, ASTArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001143 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1144 return Result;
1145}
1146
1147VarTemplatePartialSpecializationDecl *
1148VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1149 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001150 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001151}
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001152
1153static TemplateParameterList *
1154createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1155 // typename T
1156 auto *T = TemplateTypeParmDecl::Create(
1157 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1158 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1159 T->setImplicit(true);
1160
1161 // T ...Ints
1162 TypeSourceInfo *TI =
1163 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1164 auto *N = NonTypeTemplateParmDecl::Create(
1165 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1166 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1167 N->setImplicit(true);
1168
1169 // <typename T, T ...Ints>
1170 NamedDecl *P[2] = {T, N};
1171 auto *TPL = TemplateParameterList::Create(
David Majnemer902f8c62015-12-27 07:16:27 +00001172 C, SourceLocation(), SourceLocation(), P, SourceLocation());
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001173
1174 // template <typename T, ...Ints> class IntSeq
1175 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1176 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1177 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1178 TemplateTemplateParm->setImplicit(true);
1179
1180 // typename T
1181 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1182 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1183 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1184 TemplateTypeParm->setImplicit(true);
1185
1186 // T N
1187 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1188 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1189 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1190 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1191 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1192 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1193 NonTypeTemplateParm};
1194
1195 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1196 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
David Majnemer902f8c62015-12-27 07:16:27 +00001197 Params, SourceLocation());
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001198}
1199
Eric Fiselier6ad68552016-07-01 01:24:09 +00001200static TemplateParameterList *
1201createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1202 // std::size_t Index
1203 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1204 auto *Index = NonTypeTemplateParmDecl::Create(
1205 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1206 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1207
1208 // typename ...T
1209 auto *Ts = TemplateTypeParmDecl::Create(
1210 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1211 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1212 Ts->setImplicit(true);
1213
1214 // template <std::size_t Index, typename ...T>
1215 NamedDecl *Params[] = {Index, Ts};
1216 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1217 llvm::makeArrayRef(Params),
1218 SourceLocation());
1219}
1220
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001221static TemplateParameterList *createBuiltinTemplateParameterList(
1222 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1223 switch (BTK) {
1224 case BTK__make_integer_seq:
1225 return createMakeIntegerSeqParameterList(C, DC);
Eric Fiselier6ad68552016-07-01 01:24:09 +00001226 case BTK__type_pack_element:
1227 return createTypePackElementParameterList(C, DC);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001228 }
1229
1230 llvm_unreachable("unhandled BuiltinTemplateKind!");
1231}
1232
1233void BuiltinTemplateDecl::anchor() {}
1234
1235BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1236 DeclarationName Name,
1237 BuiltinTemplateKind BTK)
1238 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1239 createBuiltinTemplateParameterList(C, DC, BTK)),
1240 BTK(BTK) {}