blob: 00a6739478bd4ee1a82aea6131c3681fb97df6f2 [file] [log] [blame]
Sebastian Redle2530ec2009-10-23 22:13:42 +00001//===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
Douglas Gregorded2d7b2009-02-04 19:02:06 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the C++ related Decl classes for templates.
11//
12//===----------------------------------------------------------------------===//
13
Douglas Gregorded2d7b2009-02-04 19:02:06 +000014#include "clang/AST/DeclTemplate.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000015#include "clang/AST/ASTContext.h"
16#include "clang/AST/ASTMutationListener.h"
17#include "clang/AST/DeclCXX.h"
Douglas Gregor8bf42052009-02-09 18:46:07 +000018#include "clang/AST/Expr.h"
Douglas Gregor85759112011-01-04 02:33:52 +000019#include "clang/AST/ExprCXX.h"
John McCall0ad16662009-10-29 08:12:44 +000020#include "clang/AST/TypeLoc.h"
David Majnemerd9b1a4f2015-11-04 03:40:30 +000021#include "clang/Basic/Builtins.h"
Douglas Gregorded2d7b2009-02-04 19:02:06 +000022#include "clang/Basic/IdentifierTable.h"
23#include "llvm/ADT/STLExtras.h"
Douglas Gregor1ccc8412010-11-07 23:05:16 +000024#include <memory>
Douglas Gregorded2d7b2009-02-04 19:02:06 +000025using namespace clang;
26
27//===----------------------------------------------------------------------===//
28// TemplateParameterList Implementation
29//===----------------------------------------------------------------------===//
30
Douglas Gregorcd72ba92009-02-06 22:42:48 +000031TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
32 SourceLocation LAngleLoc,
David Majnemer902f8c62015-12-27 07:16:27 +000033 ArrayRef<NamedDecl *> Params,
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000034 SourceLocation RAngleLoc,
35 Expr *RequiresClause)
Douglas Gregorcd72ba92009-02-06 22:42:48 +000036 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000037 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
38 HasRequiresClause(static_cast<bool>(RequiresClause)) {
Richard Smith1fde8ec2012-09-07 02:06:42 +000039 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
40 NamedDecl *P = Params[Idx];
41 begin()[Idx] = P;
42
43 if (!P->isTemplateParameterPack()) {
44 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
45 if (NTTP->getType()->containsUnexpandedParameterPack())
46 ContainsUnexpandedParameterPack = true;
47
48 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
49 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
50 ContainsUnexpandedParameterPack = true;
51
52 // FIXME: If a default argument contains an unexpanded parameter pack, the
53 // template parameter list does too.
54 }
55 }
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000056 if (RequiresClause) {
57 *getTrailingObjects<Expr *>() = RequiresClause;
58 }
Douglas Gregorded2d7b2009-02-04 19:02:06 +000059}
60
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000061TemplateParameterList *
62TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
63 SourceLocation LAngleLoc,
64 ArrayRef<NamedDecl *> Params,
65 SourceLocation RAngleLoc, Expr *RequiresClause) {
66 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
67 Params.size(), RequiresClause ? 1u : 0u),
Benjamin Kramerc3f89252016-10-20 14:27:22 +000068 alignof(TemplateParameterList));
Mike Stump11289f42009-09-09 15:08:12 +000069 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000070 RAngleLoc, RequiresClause);
Douglas Gregorded2d7b2009-02-04 19:02:06 +000071}
72
Douglas Gregorf8f86832009-02-11 18:16:40 +000073unsigned TemplateParameterList::getMinRequiredArguments() const {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000074 unsigned NumRequiredArgs = 0;
David Majnemerdfecf1a2016-07-06 04:19:16 +000075 for (const NamedDecl *P : asArray()) {
76 if (P->isTemplateParameterPack()) {
77 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
Douglas Gregor0231d8d2011-01-19 20:10:05 +000078 if (NTTP->isExpandedParameterPack()) {
79 NumRequiredArgs += NTTP->getNumExpansionTypes();
80 continue;
81 }
David Majnemerdfecf1a2016-07-06 04:19:16 +000082
Douglas Gregorf8f86832009-02-11 18:16:40 +000083 break;
Douglas Gregor0231d8d2011-01-19 20:10:05 +000084 }
David Majnemerdfecf1a2016-07-06 04:19:16 +000085
86 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000087 if (TTP->hasDefaultArgument())
88 break;
David Majnemerdfecf1a2016-07-06 04:19:16 +000089 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000090 if (NTTP->hasDefaultArgument())
91 break;
David Majnemerdfecf1a2016-07-06 04:19:16 +000092 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
Douglas Gregor0231d8d2011-01-19 20:10:05 +000093 break;
David Majnemerdfecf1a2016-07-06 04:19:16 +000094
Douglas Gregor0231d8d2011-01-19 20:10:05 +000095 ++NumRequiredArgs;
Douglas Gregorf8f86832009-02-11 18:16:40 +000096 }
David Majnemerdfecf1a2016-07-06 04:19:16 +000097
Douglas Gregorf8f86832009-02-11 18:16:40 +000098 return NumRequiredArgs;
99}
100
Douglas Gregor21610382009-10-29 00:04:11 +0000101unsigned TemplateParameterList::getDepth() const {
102 if (size() == 0)
103 return 0;
104
105 const NamedDecl *FirstParm = getParam(0);
106 if (const TemplateTypeParmDecl *TTP
107 = dyn_cast<TemplateTypeParmDecl>(FirstParm))
108 return TTP->getDepth();
109 else if (const NonTypeTemplateParmDecl *NTTP
110 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
111 return NTTP->getDepth();
112 else
113 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
114}
115
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000116static void AdoptTemplateParameterList(TemplateParameterList *Params,
117 DeclContext *Owner) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000118 for (NamedDecl *P : *Params) {
119 P->setDeclContext(Owner);
120
121 if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000122 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
123 }
124}
125
Richard Smithe7bd6de2015-06-10 20:30:23 +0000126namespace clang {
127void *allocateDefaultArgStorageChain(const ASTContext &C) {
128 return new (C) char[sizeof(void*) * 2];
129}
130}
131
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000132//===----------------------------------------------------------------------===//
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000133// RedeclarableTemplateDecl Implementation
134//===----------------------------------------------------------------------===//
135
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000136RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000137 if (Common)
138 return Common;
139
140 // Walk the previous-declaration chain until we either find a declaration
141 // with a common pointer or we run out of previous declarations.
142 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
143 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
144 Prev = Prev->getPreviousDecl()) {
145 if (Prev->Common) {
146 Common = Prev->Common;
147 break;
Douglas Gregor68444de2012-01-14 15:13:49 +0000148 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000149
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000150 PrevDecls.push_back(Prev);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000151 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000152
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000153 // If we never found a common pointer, allocate one now.
154 if (!Common) {
155 // FIXME: If any of the declarations is from an AST file, we probably
156 // need an update record to add the common data.
157
158 Common = newCommon(getASTContext());
159 }
160
161 // Update any previous declarations we saw with the common pointer.
David Majnemerdfecf1a2016-07-06 04:19:16 +0000162 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
163 Prev->Common = Common;
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000164
Douglas Gregor68444de2012-01-14 15:13:49 +0000165 return Common;
Peter Collingbourne029fd692010-07-29 16:12:09 +0000166}
167
Richard Smithe977e512015-02-24 01:23:23 +0000168template<class EntryType>
169typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000170RedeclarableTemplateDecl::findSpecializationImpl(
Richard Smithe977e512015-02-24 01:23:23 +0000171 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
172 void *&InsertPos) {
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000173 typedef SpecEntryTraits<EntryType> SETraits;
174 llvm::FoldingSetNodeID ID;
Craig Topper7e0daca2014-06-26 04:58:53 +0000175 EntryType::Profile(ID,Args, getASTContext());
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000176 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
Richard Smithe977e512015-02-24 01:23:23 +0000177 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
178}
179
180template<class Derived, class EntryType>
181void RedeclarableTemplateDecl::addSpecializationImpl(
182 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
183 void *InsertPos) {
184 typedef SpecEntryTraits<EntryType> SETraits;
185 if (InsertPos) {
186#ifndef NDEBUG
187 void *CorrectInsertPos;
188 assert(!findSpecializationImpl(Specializations,
189 SETraits::getTemplateArgs(Entry),
190 CorrectInsertPos) &&
191 InsertPos == CorrectInsertPos &&
192 "given incorrect InsertPos for specialization");
193#endif
194 Specializations.InsertNode(Entry, InsertPos);
195 } else {
196 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
197 (void)Existing;
198 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
199 "non-canonical specialization?");
200 }
201
202 if (ASTMutationListener *L = getASTMutationListener())
203 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
204 SETraits::getDecl(Entry));
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000205}
206
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000207//===----------------------------------------------------------------------===//
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000208// FunctionTemplateDecl Implementation
209//===----------------------------------------------------------------------===//
210
211FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
212 DeclContext *DC,
213 SourceLocation L,
214 DeclarationName Name,
Douglas Gregor8f5d4422009-06-29 20:59:39 +0000215 TemplateParameterList *Params,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000216 NamedDecl *Decl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000217 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Richard Smith053f6c62014-05-16 23:01:30 +0000218 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000219}
220
Douglas Gregor72172e92012-01-05 21:55:30 +0000221FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
222 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000223 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000224 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000225}
226
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000227RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000228FunctionTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000229 Common *CommonPtr = new (C) Common;
George Burgess IVb61bfbd2017-02-14 05:37:36 +0000230 C.addDestruction(CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000231 return CommonPtr;
232}
233
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000234void FunctionTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000235 // Grab the most recent declaration to ensure we've loaded any lazy
236 // redeclarations of this template.
237 //
238 // FIXME: Avoid walking the entire redeclaration chain here.
239 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000240 if (CommonPtr->LazySpecializations) {
241 ASTContext &Context = getASTContext();
242 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000243 CommonPtr->LazySpecializations = nullptr;
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000244 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
245 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
246 }
247}
248
249llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
250FunctionTemplateDecl::getSpecializations() const {
251 LoadLazySpecializations();
252 return getCommonPtr()->Specializations;
253}
254
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000255FunctionDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000256FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
257 void *&InsertPos) {
258 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000259}
260
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000261void FunctionTemplateDecl::addSpecialization(
262 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000263 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
264 InsertPos);
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000265}
266
Richard Smith841d8b22013-05-17 03:04:50 +0000267ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
Douglas Gregor43669f82011-03-05 17:54:25 +0000268 TemplateParameterList *Params = getTemplateParameters();
269 Common *CommonPtr = getCommonPtr();
270 if (!CommonPtr->InjectedArgs) {
Richard Smith43e14d22016-12-23 02:10:11 +0000271 auto &Context = getASTContext();
272 SmallVector<TemplateArgument, 16> TemplateArgs;
273 Context.getInjectedTemplateArgs(Params, TemplateArgs);
274 CommonPtr->InjectedArgs =
275 new (Context) TemplateArgument[TemplateArgs.size()];
276 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
277 CommonPtr->InjectedArgs);
Douglas Gregor43669f82011-03-05 17:54:25 +0000278 }
Richard Smith841d8b22013-05-17 03:04:50 +0000279
280 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
Douglas Gregor43669f82011-03-05 17:54:25 +0000281}
282
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000283//===----------------------------------------------------------------------===//
284// ClassTemplateDecl Implementation
285//===----------------------------------------------------------------------===//
286
287ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
288 DeclContext *DC,
289 SourceLocation L,
290 DeclarationName Name,
291 TemplateParameterList *Params,
Hubert Tong5a8ec4e2017-02-10 02:46:19 +0000292 NamedDecl *Decl,
293 Expr *AssociatedConstraints) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000294 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Hubert Tong5a8ec4e2017-02-10 02:46:19 +0000295
296 if (!AssociatedConstraints) {
297 return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
298 }
299
300 ConstrainedTemplateDeclInfo *const CTDI = new (C) ConstrainedTemplateDeclInfo;
301 ClassTemplateDecl *const New =
302 new (C, DC) ClassTemplateDecl(CTDI, C, DC, L, Name, Params, Decl);
303 New->setAssociatedConstraints(AssociatedConstraints);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +0000304 return New;
Douglas Gregor90a1a652009-03-19 17:26:29 +0000305}
306
Richard Smith053f6c62014-05-16 23:01:30 +0000307ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000308 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000309 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
310 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000311}
312
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000313void ClassTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000314 // Grab the most recent declaration to ensure we've loaded any lazy
315 // redeclarations of this template.
316 //
317 // FIXME: Avoid walking the entire redeclaration chain here.
318 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000319 if (CommonPtr->LazySpecializations) {
320 ASTContext &Context = getASTContext();
321 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000322 CommonPtr->LazySpecializations = nullptr;
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000323 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
324 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
325 }
326}
327
Chandler Carruthb41171b2012-05-03 23:49:05 +0000328llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000329ClassTemplateDecl::getSpecializations() const {
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000330 LoadLazySpecializations();
331 return getCommonPtr()->Specializations;
332}
333
Chandler Carruthb41171b2012-05-03 23:49:05 +0000334llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000335ClassTemplateDecl::getPartialSpecializations() {
336 LoadLazySpecializations();
337 return getCommonPtr()->PartialSpecializations;
338}
339
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000340RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000341ClassTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000342 Common *CommonPtr = new (C) Common;
George Burgess IVb61bfbd2017-02-14 05:37:36 +0000343 C.addDestruction(CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000344 return CommonPtr;
345}
346
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000347ClassTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000348ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
349 void *&InsertPos) {
350 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000351}
352
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000353void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
354 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000355 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000356}
357
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000358ClassTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000359ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000360 void *&InsertPos) {
Craig Topper7e0daca2014-06-26 04:58:53 +0000361 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000362}
363
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000364void ClassTemplateDecl::AddPartialSpecialization(
365 ClassTemplatePartialSpecializationDecl *D,
366 void *InsertPos) {
Douglas Gregorce9978f2012-03-28 14:34:23 +0000367 if (InsertPos)
368 getPartialSpecializations().InsertNode(D, InsertPos);
369 else {
370 ClassTemplatePartialSpecializationDecl *Existing
371 = getPartialSpecializations().GetOrInsertNode(D);
372 (void)Existing;
373 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
374 }
375
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000376 if (ASTMutationListener *L = getASTMutationListener())
377 L->AddedCXXTemplateSpecialization(this, D);
378}
379
Douglas Gregor407e9612010-04-30 05:56:50 +0000380void ClassTemplateDecl::getPartialSpecializations(
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000381 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
Chandler Carruthb41171b2012-05-03 23:49:05 +0000382 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000383 = getPartialSpecializations();
Douglas Gregor407e9612010-04-30 05:56:50 +0000384 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +0000385 PS.reserve(PartialSpecs.size());
David Majnemerdfecf1a2016-07-06 04:19:16 +0000386 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
387 PS.push_back(P.getMostRecentDecl());
Douglas Gregor407e9612010-04-30 05:56:50 +0000388}
389
Douglas Gregor15301382009-07-30 17:40:51 +0000390ClassTemplatePartialSpecializationDecl *
391ClassTemplateDecl::findPartialSpecialization(QualType T) {
392 ASTContext &Context = getASTContext();
David Majnemerdfecf1a2016-07-06 04:19:16 +0000393 for (ClassTemplatePartialSpecializationDecl &P :
394 getPartialSpecializations()) {
395 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
396 return P.getMostRecentDecl();
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000397 }
398
Craig Topper36250ad2014-05-12 05:36:57 +0000399 return nullptr;
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000400}
401
402ClassTemplatePartialSpecializationDecl *
403ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
404 ClassTemplatePartialSpecializationDecl *D) {
405 Decl *DCanon = D->getCanonicalDecl();
David Majnemerdfecf1a2016-07-06 04:19:16 +0000406 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
407 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
408 return P.getMostRecentDecl();
Douglas Gregor15301382009-07-30 17:40:51 +0000409 }
Mike Stump11289f42009-09-09 15:08:12 +0000410
Craig Topper36250ad2014-05-12 05:36:57 +0000411 return nullptr;
Douglas Gregor15301382009-07-30 17:40:51 +0000412}
413
John McCalle78aac42010-03-10 03:28:59 +0000414QualType
Douglas Gregor9961ce92010-07-08 18:37:38 +0000415ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000416 Common *CommonPtr = getCommonPtr();
Douglas Gregore362cea2009-05-10 22:57:19 +0000417 if (!CommonPtr->InjectedClassNameType.isNull())
418 return CommonPtr->InjectedClassNameType;
419
Douglas Gregor8092e802010-12-23 16:00:30 +0000420 // C++0x [temp.dep.type]p2:
421 // The template argument list of a primary template is a template argument
422 // list in which the nth template argument has the value of the nth template
423 // parameter of the class template. If the nth template parameter is a
424 // template parameter pack (14.5.3), the nth template argument is a pack
425 // expansion (14.5.3) whose pattern is the name of the template parameter
426 // pack.
Douglas Gregor9961ce92010-07-08 18:37:38 +0000427 ASTContext &Context = getASTContext();
Douglas Gregore362cea2009-05-10 22:57:19 +0000428 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000429 SmallVector<TemplateArgument, 16> TemplateArgs;
Richard Smith43e14d22016-12-23 02:10:11 +0000430 Context.getInjectedTemplateArgs(Params, TemplateArgs);
Douglas Gregore362cea2009-05-10 22:57:19 +0000431 CommonPtr->InjectedClassNameType
Douglas Gregora8e02e72009-07-28 23:00:59 +0000432 = Context.getTemplateSpecializationType(TemplateName(this),
David Majnemer6fbeee32016-07-07 04:43:07 +0000433 TemplateArgs);
Douglas Gregore362cea2009-05-10 22:57:19 +0000434 return CommonPtr->InjectedClassNameType;
435}
436
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000437//===----------------------------------------------------------------------===//
438// TemplateTypeParm Allocation/Deallocation Method Implementations
439//===----------------------------------------------------------------------===//
440
441TemplateTypeParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000442TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000443 SourceLocation KeyLoc, SourceLocation NameLoc,
444 unsigned D, unsigned P, IdentifierInfo *Id,
445 bool Typename, bool ParameterPack) {
Chandler Carruth08836322011-05-01 00:51:33 +0000446 TemplateTypeParmDecl *TTPDecl =
Richard Smithf7981722013-11-22 09:01:48 +0000447 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
Chandler Carruth08836322011-05-01 00:51:33 +0000448 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
Richard Smith5b21db82014-04-23 18:20:42 +0000449 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
Chandler Carruth08836322011-05-01 00:51:33 +0000450 return TTPDecl;
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000451}
452
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000453TemplateTypeParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000454TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000455 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
456 SourceLocation(), nullptr, false);
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000457}
458
John McCall0ad16662009-10-29 08:12:44 +0000459SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara23485e02011-03-04 12:42:03 +0000460 return hasDefaultArgument()
Richard Smith1469b912015-06-10 00:29:03 +0000461 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
462 : SourceLocation();
Abramo Bagnara23485e02011-03-04 12:42:03 +0000463}
464
465SourceRange TemplateTypeParmDecl::getSourceRange() const {
466 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000467 return SourceRange(getLocStart(),
Richard Smith1469b912015-06-10 00:29:03 +0000468 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
Abramo Bagnara23485e02011-03-04 12:42:03 +0000469 else
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000470 return TypeDecl::getSourceRange();
John McCall0ad16662009-10-29 08:12:44 +0000471}
472
Douglas Gregor21610382009-10-29 00:04:11 +0000473unsigned TemplateTypeParmDecl::getDepth() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000474 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
Douglas Gregor21610382009-10-29 00:04:11 +0000475}
476
477unsigned TemplateTypeParmDecl::getIndex() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000478 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
Douglas Gregor21610382009-10-29 00:04:11 +0000479}
480
Chandler Carruth08836322011-05-01 00:51:33 +0000481bool TemplateTypeParmDecl::isParameterPack() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000482 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
Chandler Carruth08836322011-05-01 00:51:33 +0000483}
484
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000485//===----------------------------------------------------------------------===//
486// NonTypeTemplateParmDecl Method Implementations
487//===----------------------------------------------------------------------===//
488
David Majnemerdfecf1a2016-07-06 04:19:16 +0000489NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
490 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
491 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
492 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
493 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
494 TemplateParmPosition(D, P), ParameterPack(true),
495 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
496 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
James Y Knight7a22b242015-08-06 20:26:32 +0000497 auto TypesAndInfos =
498 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000499 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
James Y Knight7a22b242015-08-06 20:26:32 +0000500 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
501 TypesAndInfos[I].second = ExpandedTInfos[I];
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000502 }
503 }
504}
505
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000506NonTypeTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000507NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000508 SourceLocation StartLoc, SourceLocation IdLoc,
509 unsigned D, unsigned P, IdentifierInfo *Id,
510 QualType T, bool ParameterPack,
511 TypeSourceInfo *TInfo) {
Richard Smithf7981722013-11-22 09:01:48 +0000512 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
513 T, ParameterPack, TInfo);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000514}
515
David Majnemerdfecf1a2016-07-06 04:19:16 +0000516NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
517 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
518 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
519 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
520 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
James Y Knight7a22b242015-08-06 20:26:32 +0000521 return new (C, DC,
522 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
David Majnemerdfecf1a2016-07-06 04:19:16 +0000523 ExpandedTypes.size()))
James Y Knight7a22b242015-08-06 20:26:32 +0000524 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000525 ExpandedTypes, ExpandedTInfos);
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000526}
527
Douglas Gregor72172e92012-01-05 21:55:30 +0000528NonTypeTemplateParmDecl *
529NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000530 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
531 SourceLocation(), 0, 0, nullptr,
532 QualType(), false, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000533}
534
535NonTypeTemplateParmDecl *
536NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
537 unsigned NumExpandedTypes) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000538 auto *NTTP =
539 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
540 NumExpandedTypes))
541 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
542 0, 0, nullptr, QualType(), nullptr, None,
543 None);
544 NTTP->NumExpandedTypes = NumExpandedTypes;
545 return NTTP;
Douglas Gregor72172e92012-01-05 21:55:30 +0000546}
547
John McCallf4cd4f92011-02-09 01:13:10 +0000548SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnarae15d5532011-03-04 11:03:48 +0000549 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraea947882011-03-08 16:41:52 +0000550 return SourceRange(getOuterLocStart(),
551 getDefaultArgument()->getSourceRange().getEnd());
552 return DeclaratorDecl::getSourceRange();
John McCallf4cd4f92011-02-09 01:13:10 +0000553}
554
Douglas Gregordba32632009-02-10 19:49:53 +0000555SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara656e3002010-06-09 09:26:05 +0000556 return hasDefaultArgument()
557 ? getDefaultArgument()->getSourceRange().getBegin()
558 : SourceLocation();
Douglas Gregordba32632009-02-10 19:49:53 +0000559}
560
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000561//===----------------------------------------------------------------------===//
562// TemplateTemplateParmDecl Method Implementations
563//===----------------------------------------------------------------------===//
564
David Blaikie68e081d2011-12-20 02:48:34 +0000565void TemplateTemplateParmDecl::anchor() { }
566
Richard Smith1fde8ec2012-09-07 02:06:42 +0000567TemplateTemplateParmDecl::TemplateTemplateParmDecl(
568 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
569 IdentifierInfo *Id, TemplateParameterList *Params,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000570 ArrayRef<TemplateParameterList *> Expansions)
571 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
572 TemplateParmPosition(D, P), ParameterPack(true),
573 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
574 if (!Expansions.empty())
575 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
James Y Knight7a22b242015-08-06 20:26:32 +0000576 getTrailingObjects<TemplateParameterList *>());
Richard Smith1fde8ec2012-09-07 02:06:42 +0000577}
578
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000579TemplateTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000580TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000581 SourceLocation L, unsigned D, unsigned P,
Douglas Gregorf5500772011-01-05 15:48:55 +0000582 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000583 TemplateParameterList *Params) {
Richard Smithf7981722013-11-22 09:01:48 +0000584 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
585 Params);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000586}
587
Douglas Gregor72172e92012-01-05 21:55:30 +0000588TemplateTemplateParmDecl *
Richard Smith1fde8ec2012-09-07 02:06:42 +0000589TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
590 SourceLocation L, unsigned D, unsigned P,
591 IdentifierInfo *Id,
592 TemplateParameterList *Params,
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000593 ArrayRef<TemplateParameterList *> Expansions) {
James Y Knight7a22b242015-08-06 20:26:32 +0000594 return new (C, DC,
595 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
David Majnemerdfecf1a2016-07-06 04:19:16 +0000596 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
Richard Smith1fde8ec2012-09-07 02:06:42 +0000597}
598
599TemplateTemplateParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000600TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000601 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
602 false, nullptr, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000603}
604
Richard Smith1fde8ec2012-09-07 02:06:42 +0000605TemplateTemplateParmDecl *
606TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
607 unsigned NumExpansions) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000608 auto *TTP =
609 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
610 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
611 nullptr, None);
612 TTP->NumExpandedParams = NumExpansions;
613 return TTP;
Richard Smith1fde8ec2012-09-07 02:06:42 +0000614}
615
Richard Smith35c1df52015-06-17 20:16:32 +0000616SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
617 return hasDefaultArgument() ? getDefaultArgument().getLocation()
618 : SourceLocation();
619}
620
Richard Smith1469b912015-06-10 00:29:03 +0000621void TemplateTemplateParmDecl::setDefaultArgument(
622 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
623 if (DefArg.getArgument().isNull())
624 DefaultArgument.set(nullptr);
625 else
626 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
627}
628
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000629//===----------------------------------------------------------------------===//
Douglas Gregord002c7b2009-05-11 23:53:27 +0000630// TemplateArgumentList Implementation
631//===----------------------------------------------------------------------===//
David Majnemer8b622692016-07-03 21:17:51 +0000632TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
633 : Arguments(getTrailingObjects<TemplateArgument>()),
634 NumArguments(Args.size()) {
635 std::uninitialized_copy(Args.begin(), Args.end(),
James Y Knight7a22b242015-08-06 20:26:32 +0000636 getTrailingObjects<TemplateArgument>());
637}
638
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000639TemplateArgumentList *
640TemplateArgumentList::CreateCopy(ASTContext &Context,
David Majnemer8b622692016-07-03 21:17:51 +0000641 ArrayRef<TemplateArgument> Args) {
642 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
643 return new (Mem) TemplateArgumentList(Args);
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000644}
645
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000646FunctionTemplateSpecializationInfo *
647FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
648 FunctionTemplateDecl *Template,
649 TemplateSpecializationKind TSK,
650 const TemplateArgumentList *TemplateArgs,
651 const TemplateArgumentListInfo *TemplateArgsAsWritten,
652 SourceLocation POI) {
Craig Topper36250ad2014-05-12 05:36:57 +0000653 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000654 if (TemplateArgsAsWritten)
655 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
656 *TemplateArgsAsWritten);
657
658 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
659 TemplateArgs,
660 ArgsAsWritten,
661 POI);
662}
663
Douglas Gregord002c7b2009-05-11 23:53:27 +0000664//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000665// TemplateDecl Implementation
666//===----------------------------------------------------------------------===//
667
668void TemplateDecl::anchor() { }
669
670//===----------------------------------------------------------------------===//
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000671// ClassTemplateSpecializationDecl Implementation
672//===----------------------------------------------------------------------===//
673ClassTemplateSpecializationDecl::
Douglas Gregore9029562010-05-06 00:28:52 +0000674ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000675 DeclContext *DC, SourceLocation StartLoc,
676 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000677 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000678 ArrayRef<TemplateArgument> Args,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000679 ClassTemplateSpecializationDecl *PrevDecl)
Richard Smith053f6c62014-05-16 23:01:30 +0000680 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000681 SpecializedTemplate->getIdentifier(),
682 PrevDecl),
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000683 SpecializedTemplate(SpecializedTemplate),
Craig Topper36250ad2014-05-12 05:36:57 +0000684 ExplicitInfo(nullptr),
David Majnemer8b622692016-07-03 21:17:51 +0000685 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
Douglas Gregord002c7b2009-05-11 23:53:27 +0000686 SpecializationKind(TSK_Undeclared) {
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000687}
Mike Stump11289f42009-09-09 15:08:12 +0000688
Richard Smith053f6c62014-05-16 23:01:30 +0000689ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
690 Kind DK)
691 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
692 SourceLocation(), nullptr, nullptr),
693 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000694
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000695ClassTemplateSpecializationDecl *
Douglas Gregore9029562010-05-06 00:28:52 +0000696ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000697 DeclContext *DC,
698 SourceLocation StartLoc,
699 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000700 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000701 ArrayRef<TemplateArgument> Args,
Douglas Gregor67a65642009-02-17 23:15:12 +0000702 ClassTemplateSpecializationDecl *PrevDecl) {
Richard Smithf7981722013-11-22 09:01:48 +0000703 ClassTemplateSpecializationDecl *Result =
704 new (Context, DC) ClassTemplateSpecializationDecl(
705 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
David Majnemer8b622692016-07-03 21:17:51 +0000706 SpecializedTemplate, Args, PrevDecl);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000707 Result->MayHaveOutOfDateDef = false;
708
Douglas Gregor67a65642009-02-17 23:15:12 +0000709 Context.getTypeDeclType(Result, PrevDecl);
710 return Result;
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000711}
Douglas Gregor2373c592009-05-31 09:31:02 +0000712
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000713ClassTemplateSpecializationDecl *
Richard Smithf7981722013-11-22 09:01:48 +0000714ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000715 unsigned ID) {
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000716 ClassTemplateSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000717 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000718 Result->MayHaveOutOfDateDef = false;
719 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000720}
721
Benjamin Kramer9170e912013-02-22 15:46:01 +0000722void ClassTemplateSpecializationDecl::getNameForDiagnostic(
723 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
724 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000725
Richard Smith792c22d2016-12-24 04:09:05 +0000726 auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
727 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
728 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
729 TemplateSpecializationType::PrintTemplateArgumentList(
730 OS, ArgsAsWritten->arguments(), Policy);
731 } else {
732 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
733 TemplateSpecializationType::PrintTemplateArgumentList(
734 OS, TemplateArgs.asArray(), Policy);
735 }
Douglas Gregorb11aad82011-02-19 18:51:44 +0000736}
737
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000738ClassTemplateDecl *
Mike Stump11289f42009-09-09 15:08:12 +0000739ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
740 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000741 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
742 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
743 return SpecializedTemplate.get<ClassTemplateDecl*>();
744}
745
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000746SourceRange
747ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000748 if (ExplicitInfo) {
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000749 SourceLocation Begin = getTemplateKeywordLoc();
750 if (Begin.isValid()) {
751 // Here we have an explicit (partial) specialization or instantiation.
752 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
753 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
754 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
755 if (getExternLoc().isValid())
756 Begin = getExternLoc();
Argyrios Kyrtzidisd798c052016-07-15 18:11:33 +0000757 SourceLocation End = getBraceRange().getEnd();
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000758 if (End.isInvalid())
759 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
760 return SourceRange(Begin, End);
761 }
762 // An implicit instantiation of a class template partial specialization
763 // uses ExplicitInfo to record the TypeAsWritten, but the source
764 // locations should be retrieved from the instantiation pattern.
765 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
766 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
767 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
Craig Topper36250ad2014-05-12 05:36:57 +0000768 assert(inst_from != nullptr);
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000769 return inst_from->getSourceRange();
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000770 }
771 else {
772 // No explicit info available.
773 llvm::PointerUnion<ClassTemplateDecl *,
774 ClassTemplatePartialSpecializationDecl *>
775 inst_from = getInstantiatedFrom();
776 if (inst_from.isNull())
777 return getSpecializedTemplate()->getSourceRange();
778 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
779 return ctd->getSourceRange();
780 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
781 ->getSourceRange();
782 }
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000783}
784
Douglas Gregor2373c592009-05-31 09:31:02 +0000785//===----------------------------------------------------------------------===//
786// ClassTemplatePartialSpecializationDecl Implementation
787//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000788void ClassTemplatePartialSpecializationDecl::anchor() { }
789
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000790ClassTemplatePartialSpecializationDecl::
791ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000792 DeclContext *DC,
793 SourceLocation StartLoc,
794 SourceLocation IdLoc,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000795 TemplateParameterList *Params,
796 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000797 ArrayRef<TemplateArgument> Args,
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000798 const ASTTemplateArgumentListInfo *ArgInfos,
Richard Smithb2f61b42013-08-22 23:27:37 +0000799 ClassTemplatePartialSpecializationDecl *PrevDecl)
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000800 : ClassTemplateSpecializationDecl(Context,
801 ClassTemplatePartialSpecialization,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000802 TK, DC, StartLoc, IdLoc,
803 SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000804 Args, PrevDecl),
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000805 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +0000806 InstantiatedFromMember(nullptr, false)
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000807{
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000808 AdoptTemplateParameterList(Params, this);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000809}
810
Douglas Gregor2373c592009-05-31 09:31:02 +0000811ClassTemplatePartialSpecializationDecl *
812ClassTemplatePartialSpecializationDecl::
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000813Create(ASTContext &Context, TagKind TK,DeclContext *DC,
814 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregor2373c592009-05-31 09:31:02 +0000815 TemplateParameterList *Params,
816 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000817 ArrayRef<TemplateArgument> Args,
John McCall6b51f282009-11-23 01:53:49 +0000818 const TemplateArgumentListInfo &ArgInfos,
John McCalle78aac42010-03-10 03:28:59 +0000819 QualType CanonInjectedType,
Richard Smithb2f61b42013-08-22 23:27:37 +0000820 ClassTemplatePartialSpecializationDecl *PrevDecl) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000821 const ASTTemplateArgumentListInfo *ASTArgInfos =
822 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
John McCall0ad16662009-10-29 08:12:44 +0000823
Richard Smithf7981722013-11-22 09:01:48 +0000824 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
825 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
826 Params, SpecializedTemplate, Args,
David Majnemer8b622692016-07-03 21:17:51 +0000827 ASTArgInfos, PrevDecl);
Douglas Gregor2373c592009-05-31 09:31:02 +0000828 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000829 Result->MayHaveOutOfDateDef = false;
John McCalle78aac42010-03-10 03:28:59 +0000830
831 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregor2373c592009-05-31 09:31:02 +0000832 return Result;
833}
John McCall11083da2009-09-16 22:47:08 +0000834
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000835ClassTemplatePartialSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000836ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
837 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000838 ClassTemplatePartialSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000839 new (C, ID) ClassTemplatePartialSpecializationDecl(C);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000840 Result->MayHaveOutOfDateDef = false;
841 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000842}
843
John McCall11083da2009-09-16 22:47:08 +0000844//===----------------------------------------------------------------------===//
845// FriendTemplateDecl Implementation
846//===----------------------------------------------------------------------===//
847
David Blaikie68e081d2011-12-20 02:48:34 +0000848void FriendTemplateDecl::anchor() { }
849
David Majnemerdfecf1a2016-07-06 04:19:16 +0000850FriendTemplateDecl *
851FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
852 SourceLocation L,
853 MutableArrayRef<TemplateParameterList *> Params,
854 FriendUnion Friend, SourceLocation FLoc) {
855 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
John McCall11083da2009-09-16 22:47:08 +0000856}
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000857
Douglas Gregor72172e92012-01-05 21:55:30 +0000858FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
859 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000860 return new (C, ID) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000861}
Richard Smith3f1b5d02011-05-05 21:57:07 +0000862
863//===----------------------------------------------------------------------===//
864// TypeAliasTemplateDecl Implementation
865//===----------------------------------------------------------------------===//
866
867TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
868 DeclContext *DC,
869 SourceLocation L,
870 DeclarationName Name,
871 TemplateParameterList *Params,
872 NamedDecl *Decl) {
873 AdoptTemplateParameterList(Params, DC);
Richard Smith053f6c62014-05-16 23:01:30 +0000874 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000875}
876
Douglas Gregor72172e92012-01-05 21:55:30 +0000877TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
878 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000879 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000880 DeclarationName(), nullptr, nullptr);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000881}
882
Richard Smith3f1b5d02011-05-05 21:57:07 +0000883RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000884TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3f1b5d02011-05-05 21:57:07 +0000885 Common *CommonPtr = new (C) Common;
George Burgess IVb61bfbd2017-02-14 05:37:36 +0000886 C.addDestruction(CommonPtr);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000887 return CommonPtr;
888}
889
David Blaikie68e081d2011-12-20 02:48:34 +0000890//===----------------------------------------------------------------------===//
891// ClassScopeFunctionSpecializationDecl Implementation
892//===----------------------------------------------------------------------===//
893
894void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor72172e92012-01-05 21:55:30 +0000895
896ClassScopeFunctionSpecializationDecl *
897ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
898 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000899 return new (C, ID) ClassScopeFunctionSpecializationDecl(
Craig Topper36250ad2014-05-12 05:36:57 +0000900 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
Douglas Gregor72172e92012-01-05 21:55:30 +0000901}
Larisse Voufo39a1e502013-08-06 01:03:05 +0000902
903//===----------------------------------------------------------------------===//
904// VarTemplateDecl Implementation
905//===----------------------------------------------------------------------===//
906
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000907VarTemplateDecl *VarTemplateDecl::getDefinition() {
908 VarTemplateDecl *CurD = this;
909 while (CurD) {
910 if (CurD->isThisDeclarationADefinition())
911 return CurD;
912 CurD = CurD->getPreviousDecl();
913 }
Craig Topper36250ad2014-05-12 05:36:57 +0000914 return nullptr;
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000915}
916
Larisse Voufo39a1e502013-08-06 01:03:05 +0000917VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
918 SourceLocation L, DeclarationName Name,
919 TemplateParameterList *Params,
Richard Smithbeef3452014-01-16 23:39:20 +0000920 VarDecl *Decl) {
Richard Smith053f6c62014-05-16 23:01:30 +0000921 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000922}
923
924VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
925 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000926 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
927 DeclarationName(), nullptr, nullptr);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000928}
929
Alp Tokerf6a24ce2013-12-05 16:25:25 +0000930// TODO: Unify across class, function and variable templates?
Larisse Voufo30616382013-08-23 22:21:36 +0000931// May require moving this and Common to RedeclarableTemplateDecl.
Larisse Voufo39a1e502013-08-06 01:03:05 +0000932void VarTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000933 // Grab the most recent declaration to ensure we've loaded any lazy
934 // redeclarations of this template.
935 //
936 // FIXME: Avoid walking the entire redeclaration chain here.
937 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Larisse Voufo39a1e502013-08-06 01:03:05 +0000938 if (CommonPtr->LazySpecializations) {
939 ASTContext &Context = getASTContext();
940 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000941 CommonPtr->LazySpecializations = nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +0000942 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
943 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
944 }
945}
946
947llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
948VarTemplateDecl::getSpecializations() const {
949 LoadLazySpecializations();
950 return getCommonPtr()->Specializations;
951}
952
953llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
954VarTemplateDecl::getPartialSpecializations() {
955 LoadLazySpecializations();
956 return getCommonPtr()->PartialSpecializations;
957}
958
959RedeclarableTemplateDecl::CommonBase *
960VarTemplateDecl::newCommon(ASTContext &C) const {
961 Common *CommonPtr = new (C) Common;
George Burgess IVb61bfbd2017-02-14 05:37:36 +0000962 C.addDestruction(CommonPtr);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000963 return CommonPtr;
964}
965
966VarTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000967VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
968 void *&InsertPos) {
969 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000970}
971
972void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
973 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000974 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000975}
976
977VarTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000978VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
979 void *&InsertPos) {
980 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000981}
982
983void VarTemplateDecl::AddPartialSpecialization(
984 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
985 if (InsertPos)
986 getPartialSpecializations().InsertNode(D, InsertPos);
987 else {
988 VarTemplatePartialSpecializationDecl *Existing =
989 getPartialSpecializations().GetOrInsertNode(D);
990 (void)Existing;
991 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
992 }
993
994 if (ASTMutationListener *L = getASTMutationListener())
995 L->AddedCXXTemplateSpecialization(this, D);
996}
997
998void VarTemplateDecl::getPartialSpecializations(
999 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1000 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1001 getPartialSpecializations();
1002 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +00001003 PS.reserve(PartialSpecs.size());
David Majnemerdfecf1a2016-07-06 04:19:16 +00001004 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1005 PS.push_back(P.getMostRecentDecl());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001006}
1007
1008VarTemplatePartialSpecializationDecl *
1009VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1010 VarTemplatePartialSpecializationDecl *D) {
1011 Decl *DCanon = D->getCanonicalDecl();
David Majnemerdfecf1a2016-07-06 04:19:16 +00001012 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1013 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1014 return P.getMostRecentDecl();
Larisse Voufo39a1e502013-08-06 01:03:05 +00001015 }
1016
Craig Topper36250ad2014-05-12 05:36:57 +00001017 return nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +00001018}
1019
1020//===----------------------------------------------------------------------===//
1021// VarTemplateSpecializationDecl Implementation
1022//===----------------------------------------------------------------------===//
1023VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001024 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001025 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
David Majnemer8b622692016-07-03 21:17:51 +00001026 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
Richard Smith053f6c62014-05-16 23:01:30 +00001027 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1028 SpecializedTemplate->getIdentifier(), T, TInfo, S),
Craig Topper36250ad2014-05-12 05:36:57 +00001029 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
David Majnemer8b622692016-07-03 21:17:51 +00001030 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001031 SpecializationKind(TSK_Undeclared) {}
1032
Richard Smith053f6c62014-05-16 23:01:30 +00001033VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1034 ASTContext &C)
1035 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
Craig Topper36250ad2014-05-12 05:36:57 +00001036 QualType(), nullptr, SC_None),
1037 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Larisse Voufo39a1e502013-08-06 01:03:05 +00001038
1039VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1040 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1041 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
David Majnemer8b622692016-07-03 21:17:51 +00001042 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
Richard Smithf7981722013-11-22 09:01:48 +00001043 return new (Context, DC) VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001044 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
David Majnemer8b622692016-07-03 21:17:51 +00001045 SpecializedTemplate, T, TInfo, S, Args);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001046}
1047
1048VarTemplateSpecializationDecl *
1049VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001050 return new (C, ID)
1051 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001052}
1053
1054void VarTemplateSpecializationDecl::getNameForDiagnostic(
1055 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1056 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1057
Richard Smith792c22d2016-12-24 04:09:05 +00001058 auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1059 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1060 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1061 TemplateSpecializationType::PrintTemplateArgumentList(
1062 OS, ArgsAsWritten->arguments(), Policy);
1063 } else {
1064 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1065 TemplateSpecializationType::PrintTemplateArgumentList(
1066 OS, TemplateArgs.asArray(), Policy);
1067 }
Larisse Voufo39a1e502013-08-06 01:03:05 +00001068}
1069
1070VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1071 if (SpecializedPartialSpecialization *PartialSpec =
1072 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1073 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1074 return SpecializedTemplate.get<VarTemplateDecl *>();
1075}
1076
1077void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1078 const TemplateArgumentListInfo &ArgsInfo) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001079 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1080 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
David Majnemerdfecf1a2016-07-06 04:19:16 +00001081 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1082 TemplateArgsInfo.addArgument(Loc);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001083}
1084
1085//===----------------------------------------------------------------------===//
1086// VarTemplatePartialSpecializationDecl Implementation
1087//===----------------------------------------------------------------------===//
1088void VarTemplatePartialSpecializationDecl::anchor() {}
1089
1090VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1091 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1092 SourceLocation IdLoc, TemplateParameterList *Params,
1093 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001094 StorageClass S, ArrayRef<TemplateArgument> Args,
Richard Smithb2f61b42013-08-22 23:27:37 +00001095 const ASTTemplateArgumentListInfo *ArgInfos)
Richard Smith053f6c62014-05-16 23:01:30 +00001096 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001097 DC, StartLoc, IdLoc, SpecializedTemplate, T,
David Majnemer8b622692016-07-03 21:17:51 +00001098 TInfo, S, Args),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001099 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +00001100 InstantiatedFromMember(nullptr, false) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001101 // TODO: The template parameters should be in DC by now. Verify.
1102 // AdoptTemplateParameterList(Params, DC);
1103}
1104
1105VarTemplatePartialSpecializationDecl *
1106VarTemplatePartialSpecializationDecl::Create(
1107 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1108 SourceLocation IdLoc, TemplateParameterList *Params,
1109 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001110 StorageClass S, ArrayRef<TemplateArgument> Args,
Richard Smithb2f61b42013-08-22 23:27:37 +00001111 const TemplateArgumentListInfo &ArgInfos) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +00001112 const ASTTemplateArgumentListInfo *ASTArgInfos
1113 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001114
1115 VarTemplatePartialSpecializationDecl *Result =
Richard Smithf7981722013-11-22 09:01:48 +00001116 new (Context, DC) VarTemplatePartialSpecializationDecl(
Larisse Voufo39a1e502013-08-06 01:03:05 +00001117 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001118 S, Args, ASTArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001119 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1120 return Result;
1121}
1122
1123VarTemplatePartialSpecializationDecl *
1124VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1125 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001126 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001127}
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001128
1129static TemplateParameterList *
1130createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1131 // typename T
1132 auto *T = TemplateTypeParmDecl::Create(
1133 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1134 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1135 T->setImplicit(true);
1136
1137 // T ...Ints
1138 TypeSourceInfo *TI =
1139 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1140 auto *N = NonTypeTemplateParmDecl::Create(
1141 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1142 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1143 N->setImplicit(true);
1144
1145 // <typename T, T ...Ints>
1146 NamedDecl *P[2] = {T, N};
1147 auto *TPL = TemplateParameterList::Create(
Hubert Tonge4a0c0e2016-07-30 22:33:34 +00001148 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001149
1150 // template <typename T, ...Ints> class IntSeq
1151 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1152 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1153 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1154 TemplateTemplateParm->setImplicit(true);
1155
1156 // typename T
1157 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1158 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1159 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1160 TemplateTypeParm->setImplicit(true);
1161
1162 // T N
1163 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1164 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1165 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1166 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1167 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1168 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1169 NonTypeTemplateParm};
1170
1171 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1172 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
Hubert Tonge4a0c0e2016-07-30 22:33:34 +00001173 Params, SourceLocation(), nullptr);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001174}
1175
Eric Fiselier6ad68552016-07-01 01:24:09 +00001176static TemplateParameterList *
1177createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1178 // std::size_t Index
1179 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1180 auto *Index = NonTypeTemplateParmDecl::Create(
1181 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1182 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1183
1184 // typename ...T
1185 auto *Ts = TemplateTypeParmDecl::Create(
1186 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1187 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1188 Ts->setImplicit(true);
1189
1190 // template <std::size_t Index, typename ...T>
1191 NamedDecl *Params[] = {Index, Ts};
1192 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1193 llvm::makeArrayRef(Params),
Hubert Tonge4a0c0e2016-07-30 22:33:34 +00001194 SourceLocation(), nullptr);
Eric Fiselier6ad68552016-07-01 01:24:09 +00001195}
1196
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001197static TemplateParameterList *createBuiltinTemplateParameterList(
1198 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1199 switch (BTK) {
1200 case BTK__make_integer_seq:
1201 return createMakeIntegerSeqParameterList(C, DC);
Eric Fiselier6ad68552016-07-01 01:24:09 +00001202 case BTK__type_pack_element:
1203 return createTypePackElementParameterList(C, DC);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001204 }
1205
1206 llvm_unreachable("unhandled BuiltinTemplateKind!");
1207}
1208
1209void BuiltinTemplateDecl::anchor() {}
1210
1211BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1212 DeclarationName Name,
1213 BuiltinTemplateKind BTK)
1214 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1215 createBuiltinTemplateParameterList(C, DC, BTK)),
1216 BTK(BTK) {}