blob: 1b3cddbb10357de61150823763117f519eb43ac5 [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
Douglas Gregor1a809332010-05-23 18:26:36 +0000211void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
212 static_cast<Common *>(Ptr)->~Common();
213}
214
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000215FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
216 DeclContext *DC,
217 SourceLocation L,
218 DeclarationName Name,
Douglas Gregor8f5d4422009-06-29 20:59:39 +0000219 TemplateParameterList *Params,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000220 NamedDecl *Decl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000221 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Richard Smith053f6c62014-05-16 23:01:30 +0000222 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000223}
224
Douglas Gregor72172e92012-01-05 21:55:30 +0000225FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
226 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000227 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000228 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000229}
230
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000231RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000232FunctionTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000233 Common *CommonPtr = new (C) Common;
234 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000235 return CommonPtr;
236}
237
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000238void FunctionTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000239 // Grab the most recent declaration to ensure we've loaded any lazy
240 // redeclarations of this template.
241 //
242 // FIXME: Avoid walking the entire redeclaration chain here.
243 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000244 if (CommonPtr->LazySpecializations) {
245 ASTContext &Context = getASTContext();
246 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000247 CommonPtr->LazySpecializations = nullptr;
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000248 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
249 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
250 }
251}
252
253llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
254FunctionTemplateDecl::getSpecializations() const {
255 LoadLazySpecializations();
256 return getCommonPtr()->Specializations;
257}
258
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000259FunctionDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000260FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
261 void *&InsertPos) {
262 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000263}
264
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000265void FunctionTemplateDecl::addSpecialization(
266 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000267 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
268 InsertPos);
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000269}
270
Richard Smith841d8b22013-05-17 03:04:50 +0000271ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
Douglas Gregor43669f82011-03-05 17:54:25 +0000272 TemplateParameterList *Params = getTemplateParameters();
273 Common *CommonPtr = getCommonPtr();
274 if (!CommonPtr->InjectedArgs) {
Richard Smith43e14d22016-12-23 02:10:11 +0000275 auto &Context = getASTContext();
276 SmallVector<TemplateArgument, 16> TemplateArgs;
277 Context.getInjectedTemplateArgs(Params, TemplateArgs);
278 CommonPtr->InjectedArgs =
279 new (Context) TemplateArgument[TemplateArgs.size()];
280 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
281 CommonPtr->InjectedArgs);
Douglas Gregor43669f82011-03-05 17:54:25 +0000282 }
Richard Smith841d8b22013-05-17 03:04:50 +0000283
284 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
Douglas Gregor43669f82011-03-05 17:54:25 +0000285}
286
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000287//===----------------------------------------------------------------------===//
288// ClassTemplateDecl Implementation
289//===----------------------------------------------------------------------===//
290
Douglas Gregor1a809332010-05-23 18:26:36 +0000291void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
292 static_cast<Common *>(Ptr)->~Common();
293}
294
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000295ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
296 DeclContext *DC,
297 SourceLocation L,
298 DeclarationName Name,
299 TemplateParameterList *Params,
Douglas Gregor90a1a652009-03-19 17:26:29 +0000300 NamedDecl *Decl,
301 ClassTemplateDecl *PrevDecl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000302 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Richard Smith053f6c62014-05-16 23:01:30 +0000303 ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
304 Params, Decl);
Rafael Espindola8db352d2013-10-17 15:37:26 +0000305 New->setPreviousDecl(PrevDecl);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +0000306 return New;
Douglas Gregor90a1a652009-03-19 17:26:29 +0000307}
308
Richard Smith053f6c62014-05-16 23:01:30 +0000309ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000310 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000311 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
312 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000313}
314
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000315void ClassTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000316 // Grab the most recent declaration to ensure we've loaded any lazy
317 // redeclarations of this template.
318 //
319 // FIXME: Avoid walking the entire redeclaration chain here.
320 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000321 if (CommonPtr->LazySpecializations) {
322 ASTContext &Context = getASTContext();
323 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000324 CommonPtr->LazySpecializations = nullptr;
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000325 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
326 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
327 }
328}
329
Chandler Carruthb41171b2012-05-03 23:49:05 +0000330llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000331ClassTemplateDecl::getSpecializations() const {
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000332 LoadLazySpecializations();
333 return getCommonPtr()->Specializations;
334}
335
Chandler Carruthb41171b2012-05-03 23:49:05 +0000336llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000337ClassTemplateDecl::getPartialSpecializations() {
338 LoadLazySpecializations();
339 return getCommonPtr()->PartialSpecializations;
340}
341
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000342RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000343ClassTemplateDecl::newCommon(ASTContext &C) const {
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000344 Common *CommonPtr = new (C) Common;
345 C.AddDeallocation(DeallocateCommon, CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000346 return CommonPtr;
347}
348
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000349ClassTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000350ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
351 void *&InsertPos) {
352 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000353}
354
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000355void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
356 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000357 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000358}
359
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000360ClassTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000361ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000362 void *&InsertPos) {
Craig Topper7e0daca2014-06-26 04:58:53 +0000363 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000364}
365
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000366void ClassTemplateDecl::AddPartialSpecialization(
367 ClassTemplatePartialSpecializationDecl *D,
368 void *InsertPos) {
Douglas Gregorce9978f2012-03-28 14:34:23 +0000369 if (InsertPos)
370 getPartialSpecializations().InsertNode(D, InsertPos);
371 else {
372 ClassTemplatePartialSpecializationDecl *Existing
373 = getPartialSpecializations().GetOrInsertNode(D);
374 (void)Existing;
375 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
376 }
377
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000378 if (ASTMutationListener *L = getASTMutationListener())
379 L->AddedCXXTemplateSpecialization(this, D);
380}
381
Douglas Gregor407e9612010-04-30 05:56:50 +0000382void ClassTemplateDecl::getPartialSpecializations(
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000383 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
Chandler Carruthb41171b2012-05-03 23:49:05 +0000384 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000385 = getPartialSpecializations();
Douglas Gregor407e9612010-04-30 05:56:50 +0000386 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +0000387 PS.reserve(PartialSpecs.size());
David Majnemerdfecf1a2016-07-06 04:19:16 +0000388 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
389 PS.push_back(P.getMostRecentDecl());
Douglas Gregor407e9612010-04-30 05:56:50 +0000390}
391
Douglas Gregor15301382009-07-30 17:40:51 +0000392ClassTemplatePartialSpecializationDecl *
393ClassTemplateDecl::findPartialSpecialization(QualType T) {
394 ASTContext &Context = getASTContext();
David Majnemerdfecf1a2016-07-06 04:19:16 +0000395 for (ClassTemplatePartialSpecializationDecl &P :
396 getPartialSpecializations()) {
397 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
398 return P.getMostRecentDecl();
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000399 }
400
Craig Topper36250ad2014-05-12 05:36:57 +0000401 return nullptr;
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000402}
403
404ClassTemplatePartialSpecializationDecl *
405ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
406 ClassTemplatePartialSpecializationDecl *D) {
407 Decl *DCanon = D->getCanonicalDecl();
David Majnemerdfecf1a2016-07-06 04:19:16 +0000408 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
409 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
410 return P.getMostRecentDecl();
Douglas Gregor15301382009-07-30 17:40:51 +0000411 }
Mike Stump11289f42009-09-09 15:08:12 +0000412
Craig Topper36250ad2014-05-12 05:36:57 +0000413 return nullptr;
Douglas Gregor15301382009-07-30 17:40:51 +0000414}
415
John McCalle78aac42010-03-10 03:28:59 +0000416QualType
Douglas Gregor9961ce92010-07-08 18:37:38 +0000417ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000418 Common *CommonPtr = getCommonPtr();
Douglas Gregore362cea2009-05-10 22:57:19 +0000419 if (!CommonPtr->InjectedClassNameType.isNull())
420 return CommonPtr->InjectedClassNameType;
421
Douglas Gregor8092e802010-12-23 16:00:30 +0000422 // C++0x [temp.dep.type]p2:
423 // The template argument list of a primary template is a template argument
424 // list in which the nth template argument has the value of the nth template
425 // parameter of the class template. If the nth template parameter is a
426 // template parameter pack (14.5.3), the nth template argument is a pack
427 // expansion (14.5.3) whose pattern is the name of the template parameter
428 // pack.
Douglas Gregor9961ce92010-07-08 18:37:38 +0000429 ASTContext &Context = getASTContext();
Douglas Gregore362cea2009-05-10 22:57:19 +0000430 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000431 SmallVector<TemplateArgument, 16> TemplateArgs;
Richard Smith43e14d22016-12-23 02:10:11 +0000432 Context.getInjectedTemplateArgs(Params, TemplateArgs);
Douglas Gregore362cea2009-05-10 22:57:19 +0000433 CommonPtr->InjectedClassNameType
Douglas Gregora8e02e72009-07-28 23:00:59 +0000434 = Context.getTemplateSpecializationType(TemplateName(this),
David Majnemer6fbeee32016-07-07 04:43:07 +0000435 TemplateArgs);
Douglas Gregore362cea2009-05-10 22:57:19 +0000436 return CommonPtr->InjectedClassNameType;
437}
438
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000439//===----------------------------------------------------------------------===//
440// TemplateTypeParm Allocation/Deallocation Method Implementations
441//===----------------------------------------------------------------------===//
442
443TemplateTypeParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000444TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000445 SourceLocation KeyLoc, SourceLocation NameLoc,
446 unsigned D, unsigned P, IdentifierInfo *Id,
447 bool Typename, bool ParameterPack) {
Chandler Carruth08836322011-05-01 00:51:33 +0000448 TemplateTypeParmDecl *TTPDecl =
Richard Smithf7981722013-11-22 09:01:48 +0000449 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
Chandler Carruth08836322011-05-01 00:51:33 +0000450 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
Richard Smith5b21db82014-04-23 18:20:42 +0000451 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
Chandler Carruth08836322011-05-01 00:51:33 +0000452 return TTPDecl;
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000453}
454
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000455TemplateTypeParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000456TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000457 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
458 SourceLocation(), nullptr, false);
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000459}
460
John McCall0ad16662009-10-29 08:12:44 +0000461SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara23485e02011-03-04 12:42:03 +0000462 return hasDefaultArgument()
Richard Smith1469b912015-06-10 00:29:03 +0000463 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
464 : SourceLocation();
Abramo Bagnara23485e02011-03-04 12:42:03 +0000465}
466
467SourceRange TemplateTypeParmDecl::getSourceRange() const {
468 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000469 return SourceRange(getLocStart(),
Richard Smith1469b912015-06-10 00:29:03 +0000470 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
Abramo Bagnara23485e02011-03-04 12:42:03 +0000471 else
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000472 return TypeDecl::getSourceRange();
John McCall0ad16662009-10-29 08:12:44 +0000473}
474
Douglas Gregor21610382009-10-29 00:04:11 +0000475unsigned TemplateTypeParmDecl::getDepth() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000476 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
Douglas Gregor21610382009-10-29 00:04:11 +0000477}
478
479unsigned TemplateTypeParmDecl::getIndex() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000480 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
Douglas Gregor21610382009-10-29 00:04:11 +0000481}
482
Chandler Carruth08836322011-05-01 00:51:33 +0000483bool TemplateTypeParmDecl::isParameterPack() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000484 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
Chandler Carruth08836322011-05-01 00:51:33 +0000485}
486
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000487//===----------------------------------------------------------------------===//
488// NonTypeTemplateParmDecl Method Implementations
489//===----------------------------------------------------------------------===//
490
David Majnemerdfecf1a2016-07-06 04:19:16 +0000491NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
492 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
493 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
494 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
495 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
496 TemplateParmPosition(D, P), ParameterPack(true),
497 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
498 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
James Y Knight7a22b242015-08-06 20:26:32 +0000499 auto TypesAndInfos =
500 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000501 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
James Y Knight7a22b242015-08-06 20:26:32 +0000502 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
503 TypesAndInfos[I].second = ExpandedTInfos[I];
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000504 }
505 }
506}
507
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000508NonTypeTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000509NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000510 SourceLocation StartLoc, SourceLocation IdLoc,
511 unsigned D, unsigned P, IdentifierInfo *Id,
512 QualType T, bool ParameterPack,
513 TypeSourceInfo *TInfo) {
Richard Smithf7981722013-11-22 09:01:48 +0000514 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
515 T, ParameterPack, TInfo);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000516}
517
David Majnemerdfecf1a2016-07-06 04:19:16 +0000518NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
519 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
520 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
521 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
522 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
James Y Knight7a22b242015-08-06 20:26:32 +0000523 return new (C, DC,
524 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
David Majnemerdfecf1a2016-07-06 04:19:16 +0000525 ExpandedTypes.size()))
James Y Knight7a22b242015-08-06 20:26:32 +0000526 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000527 ExpandedTypes, ExpandedTInfos);
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000528}
529
Douglas Gregor72172e92012-01-05 21:55:30 +0000530NonTypeTemplateParmDecl *
531NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000532 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
533 SourceLocation(), 0, 0, nullptr,
534 QualType(), false, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000535}
536
537NonTypeTemplateParmDecl *
538NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
539 unsigned NumExpandedTypes) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000540 auto *NTTP =
541 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
542 NumExpandedTypes))
543 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
544 0, 0, nullptr, QualType(), nullptr, None,
545 None);
546 NTTP->NumExpandedTypes = NumExpandedTypes;
547 return NTTP;
Douglas Gregor72172e92012-01-05 21:55:30 +0000548}
549
John McCallf4cd4f92011-02-09 01:13:10 +0000550SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnarae15d5532011-03-04 11:03:48 +0000551 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraea947882011-03-08 16:41:52 +0000552 return SourceRange(getOuterLocStart(),
553 getDefaultArgument()->getSourceRange().getEnd());
554 return DeclaratorDecl::getSourceRange();
John McCallf4cd4f92011-02-09 01:13:10 +0000555}
556
Douglas Gregordba32632009-02-10 19:49:53 +0000557SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara656e3002010-06-09 09:26:05 +0000558 return hasDefaultArgument()
559 ? getDefaultArgument()->getSourceRange().getBegin()
560 : SourceLocation();
Douglas Gregordba32632009-02-10 19:49:53 +0000561}
562
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000563//===----------------------------------------------------------------------===//
564// TemplateTemplateParmDecl Method Implementations
565//===----------------------------------------------------------------------===//
566
David Blaikie68e081d2011-12-20 02:48:34 +0000567void TemplateTemplateParmDecl::anchor() { }
568
Richard Smith1fde8ec2012-09-07 02:06:42 +0000569TemplateTemplateParmDecl::TemplateTemplateParmDecl(
570 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
571 IdentifierInfo *Id, TemplateParameterList *Params,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000572 ArrayRef<TemplateParameterList *> Expansions)
573 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
574 TemplateParmPosition(D, P), ParameterPack(true),
575 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
576 if (!Expansions.empty())
577 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
James Y Knight7a22b242015-08-06 20:26:32 +0000578 getTrailingObjects<TemplateParameterList *>());
Richard Smith1fde8ec2012-09-07 02:06:42 +0000579}
580
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000581TemplateTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000582TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000583 SourceLocation L, unsigned D, unsigned P,
Douglas Gregorf5500772011-01-05 15:48:55 +0000584 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000585 TemplateParameterList *Params) {
Richard Smithf7981722013-11-22 09:01:48 +0000586 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
587 Params);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000588}
589
Douglas Gregor72172e92012-01-05 21:55:30 +0000590TemplateTemplateParmDecl *
Richard Smith1fde8ec2012-09-07 02:06:42 +0000591TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
592 SourceLocation L, unsigned D, unsigned P,
593 IdentifierInfo *Id,
594 TemplateParameterList *Params,
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000595 ArrayRef<TemplateParameterList *> Expansions) {
James Y Knight7a22b242015-08-06 20:26:32 +0000596 return new (C, DC,
597 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
David Majnemerdfecf1a2016-07-06 04:19:16 +0000598 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
Richard Smith1fde8ec2012-09-07 02:06:42 +0000599}
600
601TemplateTemplateParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000602TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000603 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
604 false, nullptr, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000605}
606
Richard Smith1fde8ec2012-09-07 02:06:42 +0000607TemplateTemplateParmDecl *
608TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
609 unsigned NumExpansions) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000610 auto *TTP =
611 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
612 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
613 nullptr, None);
614 TTP->NumExpandedParams = NumExpansions;
615 return TTP;
Richard Smith1fde8ec2012-09-07 02:06:42 +0000616}
617
Richard Smith35c1df52015-06-17 20:16:32 +0000618SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
619 return hasDefaultArgument() ? getDefaultArgument().getLocation()
620 : SourceLocation();
621}
622
Richard Smith1469b912015-06-10 00:29:03 +0000623void TemplateTemplateParmDecl::setDefaultArgument(
624 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
625 if (DefArg.getArgument().isNull())
626 DefaultArgument.set(nullptr);
627 else
628 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
629}
630
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000631//===----------------------------------------------------------------------===//
Douglas Gregord002c7b2009-05-11 23:53:27 +0000632// TemplateArgumentList Implementation
633//===----------------------------------------------------------------------===//
David Majnemer8b622692016-07-03 21:17:51 +0000634TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
635 : Arguments(getTrailingObjects<TemplateArgument>()),
636 NumArguments(Args.size()) {
637 std::uninitialized_copy(Args.begin(), Args.end(),
James Y Knight7a22b242015-08-06 20:26:32 +0000638 getTrailingObjects<TemplateArgument>());
639}
640
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000641TemplateArgumentList *
642TemplateArgumentList::CreateCopy(ASTContext &Context,
David Majnemer8b622692016-07-03 21:17:51 +0000643 ArrayRef<TemplateArgument> Args) {
644 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
645 return new (Mem) TemplateArgumentList(Args);
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000646}
647
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000648FunctionTemplateSpecializationInfo *
649FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
650 FunctionTemplateDecl *Template,
651 TemplateSpecializationKind TSK,
652 const TemplateArgumentList *TemplateArgs,
653 const TemplateArgumentListInfo *TemplateArgsAsWritten,
654 SourceLocation POI) {
Craig Topper36250ad2014-05-12 05:36:57 +0000655 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000656 if (TemplateArgsAsWritten)
657 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
658 *TemplateArgsAsWritten);
659
660 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
661 TemplateArgs,
662 ArgsAsWritten,
663 POI);
664}
665
Douglas Gregord002c7b2009-05-11 23:53:27 +0000666//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000667// TemplateDecl Implementation
668//===----------------------------------------------------------------------===//
669
670void TemplateDecl::anchor() { }
671
672//===----------------------------------------------------------------------===//
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000673// ClassTemplateSpecializationDecl Implementation
674//===----------------------------------------------------------------------===//
675ClassTemplateSpecializationDecl::
Douglas Gregore9029562010-05-06 00:28:52 +0000676ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000677 DeclContext *DC, SourceLocation StartLoc,
678 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000679 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000680 ArrayRef<TemplateArgument> Args,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000681 ClassTemplateSpecializationDecl *PrevDecl)
Richard Smith053f6c62014-05-16 23:01:30 +0000682 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000683 SpecializedTemplate->getIdentifier(),
684 PrevDecl),
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000685 SpecializedTemplate(SpecializedTemplate),
Craig Topper36250ad2014-05-12 05:36:57 +0000686 ExplicitInfo(nullptr),
David Majnemer8b622692016-07-03 21:17:51 +0000687 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
Douglas Gregord002c7b2009-05-11 23:53:27 +0000688 SpecializationKind(TSK_Undeclared) {
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000689}
Mike Stump11289f42009-09-09 15:08:12 +0000690
Richard Smith053f6c62014-05-16 23:01:30 +0000691ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
692 Kind DK)
693 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
694 SourceLocation(), nullptr, nullptr),
695 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000696
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000697ClassTemplateSpecializationDecl *
Douglas Gregore9029562010-05-06 00:28:52 +0000698ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000699 DeclContext *DC,
700 SourceLocation StartLoc,
701 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000702 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000703 ArrayRef<TemplateArgument> Args,
Douglas Gregor67a65642009-02-17 23:15:12 +0000704 ClassTemplateSpecializationDecl *PrevDecl) {
Richard Smithf7981722013-11-22 09:01:48 +0000705 ClassTemplateSpecializationDecl *Result =
706 new (Context, DC) ClassTemplateSpecializationDecl(
707 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
David Majnemer8b622692016-07-03 21:17:51 +0000708 SpecializedTemplate, Args, PrevDecl);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000709 Result->MayHaveOutOfDateDef = false;
710
Douglas Gregor67a65642009-02-17 23:15:12 +0000711 Context.getTypeDeclType(Result, PrevDecl);
712 return Result;
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000713}
Douglas Gregor2373c592009-05-31 09:31:02 +0000714
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000715ClassTemplateSpecializationDecl *
Richard Smithf7981722013-11-22 09:01:48 +0000716ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000717 unsigned ID) {
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000718 ClassTemplateSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000719 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000720 Result->MayHaveOutOfDateDef = false;
721 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000722}
723
Benjamin Kramer9170e912013-02-22 15:46:01 +0000724void ClassTemplateSpecializationDecl::getNameForDiagnostic(
725 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
726 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000727
728 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Benjamin Kramer9170e912013-02-22 15:46:01 +0000729 TemplateSpecializationType::PrintTemplateArgumentList(
David Majnemer6fbeee32016-07-07 04:43:07 +0000730 OS, TemplateArgs.asArray(), Policy);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000731}
732
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000733ClassTemplateDecl *
Mike Stump11289f42009-09-09 15:08:12 +0000734ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
735 if (SpecializedPartialSpecialization *PartialSpec
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000736 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
737 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
738 return SpecializedTemplate.get<ClassTemplateDecl*>();
739}
740
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000741SourceRange
742ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000743 if (ExplicitInfo) {
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000744 SourceLocation Begin = getTemplateKeywordLoc();
745 if (Begin.isValid()) {
746 // Here we have an explicit (partial) specialization or instantiation.
747 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
748 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
749 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
750 if (getExternLoc().isValid())
751 Begin = getExternLoc();
Argyrios Kyrtzidisd798c052016-07-15 18:11:33 +0000752 SourceLocation End = getBraceRange().getEnd();
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000753 if (End.isInvalid())
754 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
755 return SourceRange(Begin, End);
756 }
757 // An implicit instantiation of a class template partial specialization
758 // uses ExplicitInfo to record the TypeAsWritten, but the source
759 // locations should be retrieved from the instantiation pattern.
760 typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
761 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
762 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
Craig Topper36250ad2014-05-12 05:36:57 +0000763 assert(inst_from != nullptr);
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000764 return inst_from->getSourceRange();
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000765 }
766 else {
767 // No explicit info available.
768 llvm::PointerUnion<ClassTemplateDecl *,
769 ClassTemplatePartialSpecializationDecl *>
770 inst_from = getInstantiatedFrom();
771 if (inst_from.isNull())
772 return getSpecializedTemplate()->getSourceRange();
773 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
774 return ctd->getSourceRange();
775 return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
776 ->getSourceRange();
777 }
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000778}
779
Douglas Gregor2373c592009-05-31 09:31:02 +0000780//===----------------------------------------------------------------------===//
781// ClassTemplatePartialSpecializationDecl Implementation
782//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000783void ClassTemplatePartialSpecializationDecl::anchor() { }
784
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000785ClassTemplatePartialSpecializationDecl::
786ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000787 DeclContext *DC,
788 SourceLocation StartLoc,
789 SourceLocation IdLoc,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000790 TemplateParameterList *Params,
791 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000792 ArrayRef<TemplateArgument> Args,
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000793 const ASTTemplateArgumentListInfo *ArgInfos,
Richard Smithb2f61b42013-08-22 23:27:37 +0000794 ClassTemplatePartialSpecializationDecl *PrevDecl)
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000795 : ClassTemplateSpecializationDecl(Context,
796 ClassTemplatePartialSpecialization,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000797 TK, DC, StartLoc, IdLoc,
798 SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000799 Args, PrevDecl),
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000800 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +0000801 InstantiatedFromMember(nullptr, false)
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000802{
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000803 AdoptTemplateParameterList(Params, this);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000804}
805
Douglas Gregor2373c592009-05-31 09:31:02 +0000806ClassTemplatePartialSpecializationDecl *
807ClassTemplatePartialSpecializationDecl::
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000808Create(ASTContext &Context, TagKind TK,DeclContext *DC,
809 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregor2373c592009-05-31 09:31:02 +0000810 TemplateParameterList *Params,
811 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000812 ArrayRef<TemplateArgument> Args,
John McCall6b51f282009-11-23 01:53:49 +0000813 const TemplateArgumentListInfo &ArgInfos,
John McCalle78aac42010-03-10 03:28:59 +0000814 QualType CanonInjectedType,
Richard Smithb2f61b42013-08-22 23:27:37 +0000815 ClassTemplatePartialSpecializationDecl *PrevDecl) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000816 const ASTTemplateArgumentListInfo *ASTArgInfos =
817 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
John McCall0ad16662009-10-29 08:12:44 +0000818
Richard Smithf7981722013-11-22 09:01:48 +0000819 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
820 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
821 Params, SpecializedTemplate, Args,
David Majnemer8b622692016-07-03 21:17:51 +0000822 ASTArgInfos, PrevDecl);
Douglas Gregor2373c592009-05-31 09:31:02 +0000823 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000824 Result->MayHaveOutOfDateDef = false;
John McCalle78aac42010-03-10 03:28:59 +0000825
826 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregor2373c592009-05-31 09:31:02 +0000827 return Result;
828}
John McCall11083da2009-09-16 22:47:08 +0000829
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000830ClassTemplatePartialSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000831ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
832 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000833 ClassTemplatePartialSpecializationDecl *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000834 new (C, ID) ClassTemplatePartialSpecializationDecl(C);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000835 Result->MayHaveOutOfDateDef = false;
836 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000837}
838
John McCall11083da2009-09-16 22:47:08 +0000839//===----------------------------------------------------------------------===//
840// FriendTemplateDecl Implementation
841//===----------------------------------------------------------------------===//
842
David Blaikie68e081d2011-12-20 02:48:34 +0000843void FriendTemplateDecl::anchor() { }
844
David Majnemerdfecf1a2016-07-06 04:19:16 +0000845FriendTemplateDecl *
846FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
847 SourceLocation L,
848 MutableArrayRef<TemplateParameterList *> Params,
849 FriendUnion Friend, SourceLocation FLoc) {
850 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
John McCall11083da2009-09-16 22:47:08 +0000851}
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000852
Douglas Gregor72172e92012-01-05 21:55:30 +0000853FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
854 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000855 return new (C, ID) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000856}
Richard Smith3f1b5d02011-05-05 21:57:07 +0000857
858//===----------------------------------------------------------------------===//
859// TypeAliasTemplateDecl Implementation
860//===----------------------------------------------------------------------===//
861
862TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
863 DeclContext *DC,
864 SourceLocation L,
865 DeclarationName Name,
866 TemplateParameterList *Params,
867 NamedDecl *Decl) {
868 AdoptTemplateParameterList(Params, DC);
Richard Smith053f6c62014-05-16 23:01:30 +0000869 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000870}
871
Douglas Gregor72172e92012-01-05 21:55:30 +0000872TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
873 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000874 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000875 DeclarationName(), nullptr, nullptr);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000876}
877
878void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
879 static_cast<Common *>(Ptr)->~Common();
880}
881RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000882TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Richard Smith3f1b5d02011-05-05 21:57:07 +0000883 Common *CommonPtr = new (C) Common;
884 C.AddDeallocation(DeallocateCommon, CommonPtr);
885 return CommonPtr;
886}
887
David Blaikie68e081d2011-12-20 02:48:34 +0000888//===----------------------------------------------------------------------===//
889// ClassScopeFunctionSpecializationDecl Implementation
890//===----------------------------------------------------------------------===//
891
892void ClassScopeFunctionSpecializationDecl::anchor() { }
Douglas Gregor72172e92012-01-05 21:55:30 +0000893
894ClassScopeFunctionSpecializationDecl *
895ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
896 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000897 return new (C, ID) ClassScopeFunctionSpecializationDecl(
Craig Topper36250ad2014-05-12 05:36:57 +0000898 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
Douglas Gregor72172e92012-01-05 21:55:30 +0000899}
Larisse Voufo39a1e502013-08-06 01:03:05 +0000900
901//===----------------------------------------------------------------------===//
902// VarTemplateDecl Implementation
903//===----------------------------------------------------------------------===//
904
905void VarTemplateDecl::DeallocateCommon(void *Ptr) {
906 static_cast<Common *>(Ptr)->~Common();
907}
908
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000909VarTemplateDecl *VarTemplateDecl::getDefinition() {
910 VarTemplateDecl *CurD = this;
911 while (CurD) {
912 if (CurD->isThisDeclarationADefinition())
913 return CurD;
914 CurD = CurD->getPreviousDecl();
915 }
Craig Topper36250ad2014-05-12 05:36:57 +0000916 return nullptr;
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000917}
918
Larisse Voufo39a1e502013-08-06 01:03:05 +0000919VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
920 SourceLocation L, DeclarationName Name,
921 TemplateParameterList *Params,
Richard Smithbeef3452014-01-16 23:39:20 +0000922 VarDecl *Decl) {
Richard Smith053f6c62014-05-16 23:01:30 +0000923 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000924}
925
926VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
927 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000928 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
929 DeclarationName(), nullptr, nullptr);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000930}
931
Alp Tokerf6a24ce2013-12-05 16:25:25 +0000932// TODO: Unify across class, function and variable templates?
Larisse Voufo30616382013-08-23 22:21:36 +0000933// May require moving this and Common to RedeclarableTemplateDecl.
Larisse Voufo39a1e502013-08-06 01:03:05 +0000934void VarTemplateDecl::LoadLazySpecializations() const {
Richard Smithe3536dd2015-02-24 02:44:23 +0000935 // Grab the most recent declaration to ensure we've loaded any lazy
936 // redeclarations of this template.
937 //
938 // FIXME: Avoid walking the entire redeclaration chain here.
939 Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
Larisse Voufo39a1e502013-08-06 01:03:05 +0000940 if (CommonPtr->LazySpecializations) {
941 ASTContext &Context = getASTContext();
942 uint32_t *Specs = CommonPtr->LazySpecializations;
Craig Topper36250ad2014-05-12 05:36:57 +0000943 CommonPtr->LazySpecializations = nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +0000944 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
945 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
946 }
947}
948
949llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
950VarTemplateDecl::getSpecializations() const {
951 LoadLazySpecializations();
952 return getCommonPtr()->Specializations;
953}
954
955llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
956VarTemplateDecl::getPartialSpecializations() {
957 LoadLazySpecializations();
958 return getCommonPtr()->PartialSpecializations;
959}
960
961RedeclarableTemplateDecl::CommonBase *
962VarTemplateDecl::newCommon(ASTContext &C) const {
963 Common *CommonPtr = new (C) Common;
964 C.AddDeallocation(DeallocateCommon, CommonPtr);
965 return CommonPtr;
966}
967
968VarTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000969VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
970 void *&InsertPos) {
971 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000972}
973
974void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
975 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000976 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000977}
978
979VarTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000980VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
981 void *&InsertPos) {
982 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000983}
984
985void VarTemplateDecl::AddPartialSpecialization(
986 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
987 if (InsertPos)
988 getPartialSpecializations().InsertNode(D, InsertPos);
989 else {
990 VarTemplatePartialSpecializationDecl *Existing =
991 getPartialSpecializations().GetOrInsertNode(D);
992 (void)Existing;
993 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
994 }
995
996 if (ASTMutationListener *L = getASTMutationListener())
997 L->AddedCXXTemplateSpecialization(this, D);
998}
999
1000void VarTemplateDecl::getPartialSpecializations(
1001 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1002 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1003 getPartialSpecializations();
1004 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +00001005 PS.reserve(PartialSpecs.size());
David Majnemerdfecf1a2016-07-06 04:19:16 +00001006 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1007 PS.push_back(P.getMostRecentDecl());
Larisse Voufo39a1e502013-08-06 01:03:05 +00001008}
1009
1010VarTemplatePartialSpecializationDecl *
1011VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1012 VarTemplatePartialSpecializationDecl *D) {
1013 Decl *DCanon = D->getCanonicalDecl();
David Majnemerdfecf1a2016-07-06 04:19:16 +00001014 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1015 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1016 return P.getMostRecentDecl();
Larisse Voufo39a1e502013-08-06 01:03:05 +00001017 }
1018
Craig Topper36250ad2014-05-12 05:36:57 +00001019 return nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +00001020}
1021
1022//===----------------------------------------------------------------------===//
1023// VarTemplateSpecializationDecl Implementation
1024//===----------------------------------------------------------------------===//
1025VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001026 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001027 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
David Majnemer8b622692016-07-03 21:17:51 +00001028 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
Richard Smith053f6c62014-05-16 23:01:30 +00001029 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1030 SpecializedTemplate->getIdentifier(), T, TInfo, S),
Craig Topper36250ad2014-05-12 05:36:57 +00001031 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
David Majnemer8b622692016-07-03 21:17:51 +00001032 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001033 SpecializationKind(TSK_Undeclared) {}
1034
Richard Smith053f6c62014-05-16 23:01:30 +00001035VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1036 ASTContext &C)
1037 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
Craig Topper36250ad2014-05-12 05:36:57 +00001038 QualType(), nullptr, SC_None),
1039 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
Larisse Voufo39a1e502013-08-06 01:03:05 +00001040
1041VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1042 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1043 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
David Majnemer8b622692016-07-03 21:17:51 +00001044 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
Richard Smithf7981722013-11-22 09:01:48 +00001045 return new (Context, DC) VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001046 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
David Majnemer8b622692016-07-03 21:17:51 +00001047 SpecializedTemplate, T, TInfo, S, Args);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001048}
1049
1050VarTemplateSpecializationDecl *
1051VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001052 return new (C, ID)
1053 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001054}
1055
1056void VarTemplateSpecializationDecl::getNameForDiagnostic(
1057 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1058 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1059
1060 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1061 TemplateSpecializationType::PrintTemplateArgumentList(
David Majnemer6fbeee32016-07-07 04:43:07 +00001062 OS, TemplateArgs.asArray(), Policy);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001063}
1064
1065VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1066 if (SpecializedPartialSpecialization *PartialSpec =
1067 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1068 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1069 return SpecializedTemplate.get<VarTemplateDecl *>();
1070}
1071
1072void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1073 const TemplateArgumentListInfo &ArgsInfo) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001074 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1075 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
David Majnemerdfecf1a2016-07-06 04:19:16 +00001076 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1077 TemplateArgsInfo.addArgument(Loc);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001078}
1079
1080//===----------------------------------------------------------------------===//
1081// VarTemplatePartialSpecializationDecl Implementation
1082//===----------------------------------------------------------------------===//
1083void VarTemplatePartialSpecializationDecl::anchor() {}
1084
1085VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1086 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1087 SourceLocation IdLoc, TemplateParameterList *Params,
1088 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001089 StorageClass S, ArrayRef<TemplateArgument> Args,
Richard Smithb2f61b42013-08-22 23:27:37 +00001090 const ASTTemplateArgumentListInfo *ArgInfos)
Richard Smith053f6c62014-05-16 23:01:30 +00001091 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001092 DC, StartLoc, IdLoc, SpecializedTemplate, T,
David Majnemer8b622692016-07-03 21:17:51 +00001093 TInfo, S, Args),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001094 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +00001095 InstantiatedFromMember(nullptr, false) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001096 // TODO: The template parameters should be in DC by now. Verify.
1097 // AdoptTemplateParameterList(Params, DC);
1098}
1099
1100VarTemplatePartialSpecializationDecl *
1101VarTemplatePartialSpecializationDecl::Create(
1102 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1103 SourceLocation IdLoc, TemplateParameterList *Params,
1104 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001105 StorageClass S, ArrayRef<TemplateArgument> Args,
Richard Smithb2f61b42013-08-22 23:27:37 +00001106 const TemplateArgumentListInfo &ArgInfos) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +00001107 const ASTTemplateArgumentListInfo *ASTArgInfos
1108 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001109
1110 VarTemplatePartialSpecializationDecl *Result =
Richard Smithf7981722013-11-22 09:01:48 +00001111 new (Context, DC) VarTemplatePartialSpecializationDecl(
Larisse Voufo39a1e502013-08-06 01:03:05 +00001112 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001113 S, Args, ASTArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001114 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1115 return Result;
1116}
1117
1118VarTemplatePartialSpecializationDecl *
1119VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1120 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001121 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001122}
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001123
1124static TemplateParameterList *
1125createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1126 // typename T
1127 auto *T = TemplateTypeParmDecl::Create(
1128 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1129 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1130 T->setImplicit(true);
1131
1132 // T ...Ints
1133 TypeSourceInfo *TI =
1134 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1135 auto *N = NonTypeTemplateParmDecl::Create(
1136 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1137 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1138 N->setImplicit(true);
1139
1140 // <typename T, T ...Ints>
1141 NamedDecl *P[2] = {T, N};
1142 auto *TPL = TemplateParameterList::Create(
Hubert Tonge4a0c0e2016-07-30 22:33:34 +00001143 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001144
1145 // template <typename T, ...Ints> class IntSeq
1146 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1147 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1148 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1149 TemplateTemplateParm->setImplicit(true);
1150
1151 // typename T
1152 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1153 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1154 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1155 TemplateTypeParm->setImplicit(true);
1156
1157 // T N
1158 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1159 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1160 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1161 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1162 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1163 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1164 NonTypeTemplateParm};
1165
1166 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1167 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
Hubert Tonge4a0c0e2016-07-30 22:33:34 +00001168 Params, SourceLocation(), nullptr);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001169}
1170
Eric Fiselier6ad68552016-07-01 01:24:09 +00001171static TemplateParameterList *
1172createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1173 // std::size_t Index
1174 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1175 auto *Index = NonTypeTemplateParmDecl::Create(
1176 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1177 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1178
1179 // typename ...T
1180 auto *Ts = TemplateTypeParmDecl::Create(
1181 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1182 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1183 Ts->setImplicit(true);
1184
1185 // template <std::size_t Index, typename ...T>
1186 NamedDecl *Params[] = {Index, Ts};
1187 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1188 llvm::makeArrayRef(Params),
Hubert Tonge4a0c0e2016-07-30 22:33:34 +00001189 SourceLocation(), nullptr);
Eric Fiselier6ad68552016-07-01 01:24:09 +00001190}
1191
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001192static TemplateParameterList *createBuiltinTemplateParameterList(
1193 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1194 switch (BTK) {
1195 case BTK__make_integer_seq:
1196 return createMakeIntegerSeqParameterList(C, DC);
Eric Fiselier6ad68552016-07-01 01:24:09 +00001197 case BTK__type_pack_element:
1198 return createTypePackElementParameterList(C, DC);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001199 }
1200
1201 llvm_unreachable("unhandled BuiltinTemplateKind!");
1202}
1203
1204void BuiltinTemplateDecl::anchor() {}
1205
1206BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1207 DeclarationName Name,
1208 BuiltinTemplateKind BTK)
1209 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1210 createBuiltinTemplateParameterList(C, DC, BTK)),
1211 BTK(BTK) {}