blob: 8854f7879ac6937455285d0a7f9f8e13442e978e [file] [log] [blame]
Eugene Zelenko421e8902017-11-29 22:39:22 +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"
Eugene Zelenko421e8902017-11-29 22:39:22 +000018#include "clang/AST/DeclarationName.h"
Douglas Gregor8bf42052009-02-09 18:46:07 +000019#include "clang/AST/Expr.h"
Eugene Zelenko309e29d2018-03-29 20:51:59 +000020#include "clang/AST/ExternalASTSource.h"
Eugene Zelenko421e8902017-11-29 22:39:22 +000021#include "clang/AST/TemplateBase.h"
22#include "clang/AST/TemplateName.h"
23#include "clang/AST/Type.h"
John McCall0ad16662009-10-29 08:12:44 +000024#include "clang/AST/TypeLoc.h"
David Majnemerd9b1a4f2015-11-04 03:40:30 +000025#include "clang/Basic/Builtins.h"
Eugene Zelenko421e8902017-11-29 22:39:22 +000026#include "clang/Basic/LLVM.h"
27#include "clang/Basic/SourceLocation.h"
28#include "llvm/ADT/ArrayRef.h"
29#include "llvm/ADT/FoldingSet.h"
30#include "llvm/ADT/None.h"
31#include "llvm/ADT/PointerUnion.h"
32#include "llvm/ADT/SmallVector.h"
33#include "llvm/Support/Casting.h"
34#include "llvm/Support/ErrorHandling.h"
35#include <algorithm>
36#include <cassert>
37#include <cstdint>
Douglas Gregor1ccc8412010-11-07 23:05:16 +000038#include <memory>
Eugene Zelenko421e8902017-11-29 22:39:22 +000039#include <utility>
40
Douglas Gregorded2d7b2009-02-04 19:02:06 +000041using namespace clang;
42
43//===----------------------------------------------------------------------===//
44// TemplateParameterList Implementation
45//===----------------------------------------------------------------------===//
46
Douglas Gregorcd72ba92009-02-06 22:42:48 +000047TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
48 SourceLocation LAngleLoc,
David Majnemer902f8c62015-12-27 07:16:27 +000049 ArrayRef<NamedDecl *> Params,
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000050 SourceLocation RAngleLoc,
51 Expr *RequiresClause)
Eugene Zelenko421e8902017-11-29 22:39:22 +000052 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
53 NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
54 HasRequiresClause(static_cast<bool>(RequiresClause)) {
Richard Smith1fde8ec2012-09-07 02:06:42 +000055 for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
56 NamedDecl *P = Params[Idx];
57 begin()[Idx] = P;
58
59 if (!P->isTemplateParameterPack()) {
Eugene Zelenko309e29d2018-03-29 20:51:59 +000060 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
Richard Smith1fde8ec2012-09-07 02:06:42 +000061 if (NTTP->getType()->containsUnexpandedParameterPack())
62 ContainsUnexpandedParameterPack = true;
63
Eugene Zelenko309e29d2018-03-29 20:51:59 +000064 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
Richard Smith1fde8ec2012-09-07 02:06:42 +000065 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
66 ContainsUnexpandedParameterPack = true;
67
68 // FIXME: If a default argument contains an unexpanded parameter pack, the
69 // template parameter list does too.
70 }
71 }
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000072 if (RequiresClause) {
73 *getTrailingObjects<Expr *>() = RequiresClause;
74 }
Douglas Gregorded2d7b2009-02-04 19:02:06 +000075}
76
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000077TemplateParameterList *
78TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
79 SourceLocation LAngleLoc,
80 ArrayRef<NamedDecl *> Params,
81 SourceLocation RAngleLoc, Expr *RequiresClause) {
82 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
83 Params.size(), RequiresClause ? 1u : 0u),
Benjamin Kramerc3f89252016-10-20 14:27:22 +000084 alignof(TemplateParameterList));
Mike Stump11289f42009-09-09 15:08:12 +000085 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
Hubert Tonge4a0c0e2016-07-30 22:33:34 +000086 RAngleLoc, RequiresClause);
Douglas Gregorded2d7b2009-02-04 19:02:06 +000087}
88
Douglas Gregorf8f86832009-02-11 18:16:40 +000089unsigned TemplateParameterList::getMinRequiredArguments() const {
Douglas Gregor0231d8d2011-01-19 20:10:05 +000090 unsigned NumRequiredArgs = 0;
David Majnemerdfecf1a2016-07-06 04:19:16 +000091 for (const NamedDecl *P : asArray()) {
92 if (P->isTemplateParameterPack()) {
93 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
Douglas Gregor0231d8d2011-01-19 20:10:05 +000094 if (NTTP->isExpandedParameterPack()) {
95 NumRequiredArgs += NTTP->getNumExpansionTypes();
96 continue;
97 }
David Majnemerdfecf1a2016-07-06 04:19:16 +000098
Douglas Gregorf8f86832009-02-11 18:16:40 +000099 break;
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000100 }
David Majnemerdfecf1a2016-07-06 04:19:16 +0000101
102 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000103 if (TTP->hasDefaultArgument())
104 break;
David Majnemerdfecf1a2016-07-06 04:19:16 +0000105 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000106 if (NTTP->hasDefaultArgument())
107 break;
David Majnemerdfecf1a2016-07-06 04:19:16 +0000108 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000109 break;
David Majnemerdfecf1a2016-07-06 04:19:16 +0000110
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000111 ++NumRequiredArgs;
Douglas Gregorf8f86832009-02-11 18:16:40 +0000112 }
David Majnemerdfecf1a2016-07-06 04:19:16 +0000113
Douglas Gregorf8f86832009-02-11 18:16:40 +0000114 return NumRequiredArgs;
115}
116
Douglas Gregor21610382009-10-29 00:04:11 +0000117unsigned TemplateParameterList::getDepth() const {
118 if (size() == 0)
119 return 0;
120
121 const NamedDecl *FirstParm = getParam(0);
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000122 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
Douglas Gregor21610382009-10-29 00:04:11 +0000123 return TTP->getDepth();
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000124 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
Douglas Gregor21610382009-10-29 00:04:11 +0000125 return NTTP->getDepth();
126 else
127 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
128}
129
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000130static void AdoptTemplateParameterList(TemplateParameterList *Params,
131 DeclContext *Owner) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000132 for (NamedDecl *P : *Params) {
133 P->setDeclContext(Owner);
134
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000135 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000136 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
137 }
138}
139
Richard Smithe7bd6de2015-06-10 20:30:23 +0000140namespace clang {
Eugene Zelenko421e8902017-11-29 22:39:22 +0000141
Richard Smithe7bd6de2015-06-10 20:30:23 +0000142void *allocateDefaultArgStorageChain(const ASTContext &C) {
143 return new (C) char[sizeof(void*) * 2];
144}
Eugene Zelenko421e8902017-11-29 22:39:22 +0000145
146} // namespace clang
Richard Smithe7bd6de2015-06-10 20:30:23 +0000147
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000148//===----------------------------------------------------------------------===//
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000149// RedeclarableTemplateDecl Implementation
150//===----------------------------------------------------------------------===//
151
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000152RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000153 if (Common)
154 return Common;
155
156 // Walk the previous-declaration chain until we either find a declaration
157 // with a common pointer or we run out of previous declarations.
158 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
159 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
160 Prev = Prev->getPreviousDecl()) {
161 if (Prev->Common) {
162 Common = Prev->Common;
163 break;
Douglas Gregor68444de2012-01-14 15:13:49 +0000164 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000165
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000166 PrevDecls.push_back(Prev);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000167 }
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000168
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000169 // If we never found a common pointer, allocate one now.
170 if (!Common) {
171 // FIXME: If any of the declarations is from an AST file, we probably
172 // need an update record to add the common data.
173
174 Common = newCommon(getASTContext());
175 }
176
177 // Update any previous declarations we saw with the common pointer.
David Majnemerdfecf1a2016-07-06 04:19:16 +0000178 for (const RedeclarableTemplateDecl *Prev : PrevDecls)
179 Prev->Common = Common;
Rafael Espindolacb444fe2013-10-19 02:28:17 +0000180
Douglas Gregor68444de2012-01-14 15:13:49 +0000181 return Common;
Peter Collingbourne029fd692010-07-29 16:12:09 +0000182}
183
Vassil Vassilev61f64292017-12-14 23:30:18 +0000184void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
185 // Grab the most recent declaration to ensure we've loaded any lazy
186 // redeclarations of this template.
187 CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
188 if (CommonBasePtr->LazySpecializations) {
189 ASTContext &Context = getASTContext();
190 uint32_t *Specs = CommonBasePtr->LazySpecializations;
191 CommonBasePtr->LazySpecializations = nullptr;
192 for (uint32_t I = 0, N = *Specs++; I != N; ++I)
193 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
194 }
195}
196
Richard Smithe977e512015-02-24 01:23:23 +0000197template<class EntryType>
198typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000199RedeclarableTemplateDecl::findSpecializationImpl(
Richard Smithe977e512015-02-24 01:23:23 +0000200 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
201 void *&InsertPos) {
Eugene Zelenko421e8902017-11-29 22:39:22 +0000202 using SETraits = SpecEntryTraits<EntryType>;
203
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000204 llvm::FoldingSetNodeID ID;
Vassil Vassilev61f64292017-12-14 23:30:18 +0000205 EntryType::Profile(ID, Args, getASTContext());
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000206 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
Richard Smithe977e512015-02-24 01:23:23 +0000207 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
208}
209
210template<class Derived, class EntryType>
211void RedeclarableTemplateDecl::addSpecializationImpl(
212 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
213 void *InsertPos) {
Eugene Zelenko421e8902017-11-29 22:39:22 +0000214 using SETraits = SpecEntryTraits<EntryType>;
215
Richard Smithe977e512015-02-24 01:23:23 +0000216 if (InsertPos) {
217#ifndef NDEBUG
218 void *CorrectInsertPos;
219 assert(!findSpecializationImpl(Specializations,
220 SETraits::getTemplateArgs(Entry),
221 CorrectInsertPos) &&
222 InsertPos == CorrectInsertPos &&
223 "given incorrect InsertPos for specialization");
224#endif
225 Specializations.InsertNode(Entry, InsertPos);
226 } else {
227 EntryType *Existing = Specializations.GetOrInsertNode(Entry);
228 (void)Existing;
229 assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
230 "non-canonical specialization?");
231 }
232
233 if (ASTMutationListener *L = getASTMutationListener())
234 L->AddedCXXTemplateSpecialization(cast<Derived>(this),
235 SETraits::getDecl(Entry));
Peter Collingbourneb498ed62010-07-30 17:09:04 +0000236}
237
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000238//===----------------------------------------------------------------------===//
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000239// FunctionTemplateDecl Implementation
240//===----------------------------------------------------------------------===//
241
242FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
243 DeclContext *DC,
244 SourceLocation L,
245 DeclarationName Name,
Douglas Gregor8f5d4422009-06-29 20:59:39 +0000246 TemplateParameterList *Params,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000247 NamedDecl *Decl) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000248 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Richard Smith053f6c62014-05-16 23:01:30 +0000249 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000250}
251
Douglas Gregor72172e92012-01-05 21:55:30 +0000252FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
253 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000254 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000255 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000256}
257
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000258RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000259FunctionTemplateDecl::newCommon(ASTContext &C) const {
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000260 auto *CommonPtr = new (C) Common;
George Burgess IVb61bfbd2017-02-14 05:37:36 +0000261 C.addDestruction(CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000262 return CommonPtr;
263}
264
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000265void FunctionTemplateDecl::LoadLazySpecializations() const {
Vassil Vassilev61f64292017-12-14 23:30:18 +0000266 loadLazySpecializationsImpl();
Richard Smithfeb3e1a2013-06-28 04:37:53 +0000267}
268
269llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
270FunctionTemplateDecl::getSpecializations() const {
271 LoadLazySpecializations();
272 return getCommonPtr()->Specializations;
273}
274
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000275FunctionDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000276FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
277 void *&InsertPos) {
278 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidisdde57902010-07-20 13:59:58 +0000279}
280
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000281void FunctionTemplateDecl::addSpecialization(
282 FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000283 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
284 InsertPos);
Sebastian Redl9ab988f2011-04-14 14:07:59 +0000285}
286
Richard Smith841d8b22013-05-17 03:04:50 +0000287ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
Douglas Gregor43669f82011-03-05 17:54:25 +0000288 TemplateParameterList *Params = getTemplateParameters();
289 Common *CommonPtr = getCommonPtr();
290 if (!CommonPtr->InjectedArgs) {
Richard Smith43e14d22016-12-23 02:10:11 +0000291 auto &Context = getASTContext();
292 SmallVector<TemplateArgument, 16> TemplateArgs;
293 Context.getInjectedTemplateArgs(Params, TemplateArgs);
294 CommonPtr->InjectedArgs =
295 new (Context) TemplateArgument[TemplateArgs.size()];
296 std::copy(TemplateArgs.begin(), TemplateArgs.end(),
297 CommonPtr->InjectedArgs);
Douglas Gregor43669f82011-03-05 17:54:25 +0000298 }
Richard Smith841d8b22013-05-17 03:04:50 +0000299
300 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
Douglas Gregor43669f82011-03-05 17:54:25 +0000301}
302
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000303//===----------------------------------------------------------------------===//
304// ClassTemplateDecl Implementation
305//===----------------------------------------------------------------------===//
306
307ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
308 DeclContext *DC,
309 SourceLocation L,
310 DeclarationName Name,
311 TemplateParameterList *Params,
Hubert Tong5a8ec4e2017-02-10 02:46:19 +0000312 NamedDecl *Decl,
313 Expr *AssociatedConstraints) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000314 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
Hubert Tong5a8ec4e2017-02-10 02:46:19 +0000315
316 if (!AssociatedConstraints) {
317 return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
318 }
319
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000320 auto *const CTDI = new (C) ConstrainedTemplateDeclInfo;
321 auto *const New =
Hubert Tong5a8ec4e2017-02-10 02:46:19 +0000322 new (C, DC) ClassTemplateDecl(CTDI, C, DC, L, Name, Params, Decl);
323 New->setAssociatedConstraints(AssociatedConstraints);
Argyrios Kyrtzidis95c04ca2010-06-19 19:29:09 +0000324 return New;
Douglas Gregor90a1a652009-03-19 17:26:29 +0000325}
326
Richard Smith053f6c62014-05-16 23:01:30 +0000327ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000328 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000329 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
330 DeclarationName(), nullptr, nullptr);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000331}
332
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000333void ClassTemplateDecl::LoadLazySpecializations() const {
Vassil Vassilev61f64292017-12-14 23:30:18 +0000334 loadLazySpecializationsImpl();
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000335}
336
Chandler Carruthb41171b2012-05-03 23:49:05 +0000337llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
Dmitri Gribenko81f25752013-02-14 13:20:36 +0000338ClassTemplateDecl::getSpecializations() const {
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000339 LoadLazySpecializations();
340 return getCommonPtr()->Specializations;
341}
342
Chandler Carruthb41171b2012-05-03 23:49:05 +0000343llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
Douglas Gregor7e8c4e02010-10-27 22:21:36 +0000344ClassTemplateDecl::getPartialSpecializations() {
345 LoadLazySpecializations();
346 return getCommonPtr()->PartialSpecializations;
347}
348
Argyrios Kyrtzidisf4bc0d82010-09-08 19:31:22 +0000349RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000350ClassTemplateDecl::newCommon(ASTContext &C) const {
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000351 auto *CommonPtr = new (C) Common;
George Burgess IVb61bfbd2017-02-14 05:37:36 +0000352 C.addDestruction(CommonPtr);
Peter Collingbourne91b25b72010-07-29 16:11:51 +0000353 return CommonPtr;
354}
355
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000356ClassTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000357ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
358 void *&InsertPos) {
359 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000360}
361
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000362void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
363 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000364 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000365}
366
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000367ClassTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000368ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000369 void *&InsertPos) {
Craig Topper7e0daca2014-06-26 04:58:53 +0000370 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000371}
372
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000373void ClassTemplateDecl::AddPartialSpecialization(
374 ClassTemplatePartialSpecializationDecl *D,
375 void *InsertPos) {
Douglas Gregorce9978f2012-03-28 14:34:23 +0000376 if (InsertPos)
377 getPartialSpecializations().InsertNode(D, InsertPos);
378 else {
379 ClassTemplatePartialSpecializationDecl *Existing
380 = getPartialSpecializations().GetOrInsertNode(D);
381 (void)Existing;
382 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
383 }
384
Argyrios Kyrtzidis402dbbb2010-10-28 07:38:42 +0000385 if (ASTMutationListener *L = getASTMutationListener())
386 L->AddedCXXTemplateSpecialization(this, D);
387}
388
Douglas Gregor407e9612010-04-30 05:56:50 +0000389void ClassTemplateDecl::getPartialSpecializations(
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000390 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
Chandler Carruthb41171b2012-05-03 23:49:05 +0000391 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000392 = getPartialSpecializations();
Douglas Gregor407e9612010-04-30 05:56:50 +0000393 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +0000394 PS.reserve(PartialSpecs.size());
David Majnemerdfecf1a2016-07-06 04:19:16 +0000395 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
396 PS.push_back(P.getMostRecentDecl());
Douglas Gregor407e9612010-04-30 05:56:50 +0000397}
398
Douglas Gregor15301382009-07-30 17:40:51 +0000399ClassTemplatePartialSpecializationDecl *
400ClassTemplateDecl::findPartialSpecialization(QualType T) {
401 ASTContext &Context = getASTContext();
David Majnemerdfecf1a2016-07-06 04:19:16 +0000402 for (ClassTemplatePartialSpecializationDecl &P :
403 getPartialSpecializations()) {
404 if (Context.hasSameType(P.getInjectedSpecializationType(), T))
405 return P.getMostRecentDecl();
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000406 }
407
Craig Topper36250ad2014-05-12 05:36:57 +0000408 return nullptr;
Argyrios Kyrtzidis47470f22010-07-20 13:59:28 +0000409}
410
411ClassTemplatePartialSpecializationDecl *
412ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
413 ClassTemplatePartialSpecializationDecl *D) {
414 Decl *DCanon = D->getCanonicalDecl();
David Majnemerdfecf1a2016-07-06 04:19:16 +0000415 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
416 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
417 return P.getMostRecentDecl();
Douglas Gregor15301382009-07-30 17:40:51 +0000418 }
Mike Stump11289f42009-09-09 15:08:12 +0000419
Craig Topper36250ad2014-05-12 05:36:57 +0000420 return nullptr;
Douglas Gregor15301382009-07-30 17:40:51 +0000421}
422
John McCalle78aac42010-03-10 03:28:59 +0000423QualType
Douglas Gregor9961ce92010-07-08 18:37:38 +0000424ClassTemplateDecl::getInjectedClassNameSpecialization() {
Argyrios Kyrtzidisa35c8e42010-06-21 10:57:41 +0000425 Common *CommonPtr = getCommonPtr();
Douglas Gregore362cea2009-05-10 22:57:19 +0000426 if (!CommonPtr->InjectedClassNameType.isNull())
427 return CommonPtr->InjectedClassNameType;
428
Douglas Gregor8092e802010-12-23 16:00:30 +0000429 // C++0x [temp.dep.type]p2:
430 // The template argument list of a primary template is a template argument
431 // list in which the nth template argument has the value of the nth template
432 // parameter of the class template. If the nth template parameter is a
433 // template parameter pack (14.5.3), the nth template argument is a pack
434 // expansion (14.5.3) whose pattern is the name of the template parameter
435 // pack.
Douglas Gregor9961ce92010-07-08 18:37:38 +0000436 ASTContext &Context = getASTContext();
Douglas Gregore362cea2009-05-10 22:57:19 +0000437 TemplateParameterList *Params = getTemplateParameters();
Chris Lattner0e62c1c2011-07-23 10:55:15 +0000438 SmallVector<TemplateArgument, 16> TemplateArgs;
Richard Smith43e14d22016-12-23 02:10:11 +0000439 Context.getInjectedTemplateArgs(Params, TemplateArgs);
Douglas Gregore362cea2009-05-10 22:57:19 +0000440 CommonPtr->InjectedClassNameType
Douglas Gregora8e02e72009-07-28 23:00:59 +0000441 = Context.getTemplateSpecializationType(TemplateName(this),
David Majnemer6fbeee32016-07-07 04:43:07 +0000442 TemplateArgs);
Douglas Gregore362cea2009-05-10 22:57:19 +0000443 return CommonPtr->InjectedClassNameType;
444}
445
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000446//===----------------------------------------------------------------------===//
447// TemplateTypeParm Allocation/Deallocation Method Implementations
448//===----------------------------------------------------------------------===//
449
450TemplateTypeParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000451TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000452 SourceLocation KeyLoc, SourceLocation NameLoc,
453 unsigned D, unsigned P, IdentifierInfo *Id,
454 bool Typename, bool ParameterPack) {
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000455 auto *TTPDecl =
456 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
Chandler Carruth08836322011-05-01 00:51:33 +0000457 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
Richard Smith5b21db82014-04-23 18:20:42 +0000458 TTPDecl->setTypeForDecl(TTPType.getTypePtr());
Chandler Carruth08836322011-05-01 00:51:33 +0000459 return TTPDecl;
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000460}
461
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000462TemplateTypeParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000463TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000464 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
465 SourceLocation(), nullptr, false);
Argyrios Kyrtzidis39f0e302010-07-02 11:54:55 +0000466}
467
John McCall0ad16662009-10-29 08:12:44 +0000468SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara23485e02011-03-04 12:42:03 +0000469 return hasDefaultArgument()
Richard Smith1469b912015-06-10 00:29:03 +0000470 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
471 : SourceLocation();
Abramo Bagnara23485e02011-03-04 12:42:03 +0000472}
473
474SourceRange TemplateTypeParmDecl::getSourceRange() const {
475 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000476 return SourceRange(getLocStart(),
Richard Smith1469b912015-06-10 00:29:03 +0000477 getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
Abramo Bagnara23485e02011-03-04 12:42:03 +0000478 else
Abramo Bagnarab3185b02011-03-06 15:48:19 +0000479 return TypeDecl::getSourceRange();
John McCall0ad16662009-10-29 08:12:44 +0000480}
481
Douglas Gregor21610382009-10-29 00:04:11 +0000482unsigned TemplateTypeParmDecl::getDepth() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000483 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
Douglas Gregor21610382009-10-29 00:04:11 +0000484}
485
486unsigned TemplateTypeParmDecl::getIndex() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000487 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
Douglas Gregor21610382009-10-29 00:04:11 +0000488}
489
Chandler Carruth08836322011-05-01 00:51:33 +0000490bool TemplateTypeParmDecl::isParameterPack() const {
Richard Smith5b21db82014-04-23 18:20:42 +0000491 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
Chandler Carruth08836322011-05-01 00:51:33 +0000492}
493
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000494//===----------------------------------------------------------------------===//
495// NonTypeTemplateParmDecl Method Implementations
496//===----------------------------------------------------------------------===//
497
David Majnemerdfecf1a2016-07-06 04:19:16 +0000498NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
499 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
500 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
501 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
502 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
503 TemplateParmPosition(D, P), ParameterPack(true),
504 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
505 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
James Y Knight7a22b242015-08-06 20:26:32 +0000506 auto TypesAndInfos =
507 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000508 for (unsigned I = 0; I != NumExpandedTypes; ++I) {
James Y Knight7a22b242015-08-06 20:26:32 +0000509 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
510 TypesAndInfos[I].second = ExpandedTInfos[I];
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000511 }
512 }
513}
514
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000515NonTypeTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000516NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Abramo Bagnaradff19302011-03-08 08:55:46 +0000517 SourceLocation StartLoc, SourceLocation IdLoc,
518 unsigned D, unsigned P, IdentifierInfo *Id,
519 QualType T, bool ParameterPack,
520 TypeSourceInfo *TInfo) {
Richard Smithf7981722013-11-22 09:01:48 +0000521 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
522 T, ParameterPack, TInfo);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000523}
524
David Majnemerdfecf1a2016-07-06 04:19:16 +0000525NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
526 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
527 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
528 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
529 ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
James Y Knight7a22b242015-08-06 20:26:32 +0000530 return new (C, DC,
531 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
David Majnemerdfecf1a2016-07-06 04:19:16 +0000532 ExpandedTypes.size()))
James Y Knight7a22b242015-08-06 20:26:32 +0000533 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000534 ExpandedTypes, ExpandedTInfos);
Douglas Gregor0231d8d2011-01-19 20:10:05 +0000535}
536
Douglas Gregor72172e92012-01-05 21:55:30 +0000537NonTypeTemplateParmDecl *
538NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000539 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
540 SourceLocation(), 0, 0, nullptr,
541 QualType(), false, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000542}
543
544NonTypeTemplateParmDecl *
545NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
546 unsigned NumExpandedTypes) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000547 auto *NTTP =
548 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
549 NumExpandedTypes))
550 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
551 0, 0, nullptr, QualType(), nullptr, None,
552 None);
553 NTTP->NumExpandedTypes = NumExpandedTypes;
554 return NTTP;
Douglas Gregor72172e92012-01-05 21:55:30 +0000555}
556
John McCallf4cd4f92011-02-09 01:13:10 +0000557SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
Abramo Bagnarae15d5532011-03-04 11:03:48 +0000558 if (hasDefaultArgument() && !defaultArgumentWasInherited())
Abramo Bagnaraea947882011-03-08 16:41:52 +0000559 return SourceRange(getOuterLocStart(),
560 getDefaultArgument()->getSourceRange().getEnd());
561 return DeclaratorDecl::getSourceRange();
John McCallf4cd4f92011-02-09 01:13:10 +0000562}
563
Douglas Gregordba32632009-02-10 19:49:53 +0000564SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
Abramo Bagnara656e3002010-06-09 09:26:05 +0000565 return hasDefaultArgument()
566 ? getDefaultArgument()->getSourceRange().getBegin()
567 : SourceLocation();
Douglas Gregordba32632009-02-10 19:49:53 +0000568}
569
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000570//===----------------------------------------------------------------------===//
571// TemplateTemplateParmDecl Method Implementations
572//===----------------------------------------------------------------------===//
573
Eugene Zelenko421e8902017-11-29 22:39:22 +0000574void TemplateTemplateParmDecl::anchor() {}
David Blaikie68e081d2011-12-20 02:48:34 +0000575
Richard Smith1fde8ec2012-09-07 02:06:42 +0000576TemplateTemplateParmDecl::TemplateTemplateParmDecl(
577 DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
578 IdentifierInfo *Id, TemplateParameterList *Params,
David Majnemerdfecf1a2016-07-06 04:19:16 +0000579 ArrayRef<TemplateParameterList *> Expansions)
580 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
581 TemplateParmPosition(D, P), ParameterPack(true),
582 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
583 if (!Expansions.empty())
584 std::uninitialized_copy(Expansions.begin(), Expansions.end(),
James Y Knight7a22b242015-08-06 20:26:32 +0000585 getTrailingObjects<TemplateParameterList *>());
Richard Smith1fde8ec2012-09-07 02:06:42 +0000586}
587
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000588TemplateTemplateParmDecl *
Jay Foad39c79802011-01-12 09:06:06 +0000589TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000590 SourceLocation L, unsigned D, unsigned P,
Douglas Gregorf5500772011-01-05 15:48:55 +0000591 bool ParameterPack, IdentifierInfo *Id,
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000592 TemplateParameterList *Params) {
Richard Smithf7981722013-11-22 09:01:48 +0000593 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
594 Params);
Douglas Gregorded2d7b2009-02-04 19:02:06 +0000595}
596
Douglas Gregor72172e92012-01-05 21:55:30 +0000597TemplateTemplateParmDecl *
Richard Smith1fde8ec2012-09-07 02:06:42 +0000598TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
599 SourceLocation L, unsigned D, unsigned P,
600 IdentifierInfo *Id,
601 TemplateParameterList *Params,
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000602 ArrayRef<TemplateParameterList *> Expansions) {
James Y Knight7a22b242015-08-06 20:26:32 +0000603 return new (C, DC,
604 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
David Majnemerdfecf1a2016-07-06 04:19:16 +0000605 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
Richard Smith1fde8ec2012-09-07 02:06:42 +0000606}
607
608TemplateTemplateParmDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000609TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Craig Topper36250ad2014-05-12 05:36:57 +0000610 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
611 false, nullptr, nullptr);
Douglas Gregor72172e92012-01-05 21:55:30 +0000612}
613
Richard Smith1fde8ec2012-09-07 02:06:42 +0000614TemplateTemplateParmDecl *
615TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
616 unsigned NumExpansions) {
David Majnemerdfecf1a2016-07-06 04:19:16 +0000617 auto *TTP =
618 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
619 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
620 nullptr, None);
621 TTP->NumExpandedParams = NumExpansions;
622 return TTP;
Richard Smith1fde8ec2012-09-07 02:06:42 +0000623}
624
Richard Smith35c1df52015-06-17 20:16:32 +0000625SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
626 return hasDefaultArgument() ? getDefaultArgument().getLocation()
627 : SourceLocation();
628}
629
Richard Smith1469b912015-06-10 00:29:03 +0000630void TemplateTemplateParmDecl::setDefaultArgument(
631 const ASTContext &C, const TemplateArgumentLoc &DefArg) {
632 if (DefArg.getArgument().isNull())
633 DefaultArgument.set(nullptr);
634 else
635 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
636}
637
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000638//===----------------------------------------------------------------------===//
Douglas Gregord002c7b2009-05-11 23:53:27 +0000639// TemplateArgumentList Implementation
640//===----------------------------------------------------------------------===//
David Majnemer8b622692016-07-03 21:17:51 +0000641TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
642 : Arguments(getTrailingObjects<TemplateArgument>()),
643 NumArguments(Args.size()) {
644 std::uninitialized_copy(Args.begin(), Args.end(),
James Y Knight7a22b242015-08-06 20:26:32 +0000645 getTrailingObjects<TemplateArgument>());
646}
647
Douglas Gregor1ccc8412010-11-07 23:05:16 +0000648TemplateArgumentList *
649TemplateArgumentList::CreateCopy(ASTContext &Context,
David Majnemer8b622692016-07-03 21:17:51 +0000650 ArrayRef<TemplateArgument> Args) {
651 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
652 return new (Mem) TemplateArgumentList(Args);
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000653}
654
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000655FunctionTemplateSpecializationInfo *
656FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
657 FunctionTemplateDecl *Template,
658 TemplateSpecializationKind TSK,
659 const TemplateArgumentList *TemplateArgs,
660 const TemplateArgumentListInfo *TemplateArgsAsWritten,
661 SourceLocation POI) {
Craig Topper36250ad2014-05-12 05:36:57 +0000662 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
Argyrios Kyrtzidise9a24432011-09-22 20:07:09 +0000663 if (TemplateArgsAsWritten)
664 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
665 *TemplateArgsAsWritten);
666
667 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
668 TemplateArgs,
669 ArgsAsWritten,
670 POI);
671}
672
Douglas Gregord002c7b2009-05-11 23:53:27 +0000673//===----------------------------------------------------------------------===//
David Blaikie68e081d2011-12-20 02:48:34 +0000674// TemplateDecl Implementation
675//===----------------------------------------------------------------------===//
676
Eugene Zelenko421e8902017-11-29 22:39:22 +0000677void TemplateDecl::anchor() {}
David Blaikie68e081d2011-12-20 02:48:34 +0000678
679//===----------------------------------------------------------------------===//
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000680// ClassTemplateSpecializationDecl Implementation
681//===----------------------------------------------------------------------===//
Eugene Zelenko421e8902017-11-29 22:39:22 +0000682
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000683ClassTemplateSpecializationDecl::
Douglas Gregore9029562010-05-06 00:28:52 +0000684ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000685 DeclContext *DC, SourceLocation StartLoc,
686 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000687 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000688 ArrayRef<TemplateArgument> Args,
Douglas Gregorb6b8f9e2009-07-29 23:36:44 +0000689 ClassTemplateSpecializationDecl *PrevDecl)
Eugene Zelenko421e8902017-11-29 22:39:22 +0000690 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
691 SpecializedTemplate->getIdentifier(), PrevDecl),
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000692 SpecializedTemplate(SpecializedTemplate),
David Majnemer8b622692016-07-03 21:17:51 +0000693 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
Douglas Gregord002c7b2009-05-11 23:53:27 +0000694 SpecializationKind(TSK_Undeclared) {
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000695}
Mike Stump11289f42009-09-09 15:08:12 +0000696
Richard Smith053f6c62014-05-16 23:01:30 +0000697ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
698 Kind DK)
699 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
700 SourceLocation(), nullptr, nullptr),
Eugene Zelenko421e8902017-11-29 22:39:22 +0000701 SpecializationKind(TSK_Undeclared) {}
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000702
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000703ClassTemplateSpecializationDecl *
Douglas Gregore9029562010-05-06 00:28:52 +0000704ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000705 DeclContext *DC,
706 SourceLocation StartLoc,
707 SourceLocation IdLoc,
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000708 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000709 ArrayRef<TemplateArgument> Args,
Douglas Gregor67a65642009-02-17 23:15:12 +0000710 ClassTemplateSpecializationDecl *PrevDecl) {
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000711 auto *Result =
Richard Smithf7981722013-11-22 09:01:48 +0000712 new (Context, DC) ClassTemplateSpecializationDecl(
713 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
David Majnemer8b622692016-07-03 21:17:51 +0000714 SpecializedTemplate, Args, PrevDecl);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000715 Result->MayHaveOutOfDateDef = false;
716
Douglas Gregor67a65642009-02-17 23:15:12 +0000717 Context.getTypeDeclType(Result, PrevDecl);
718 return Result;
Douglas Gregor264ec4f2009-02-17 01:05:43 +0000719}
Douglas Gregor2373c592009-05-31 09:31:02 +0000720
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000721ClassTemplateSpecializationDecl *
Richard Smithf7981722013-11-22 09:01:48 +0000722ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
Douglas Gregor72172e92012-01-05 21:55:30 +0000723 unsigned ID) {
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000724 auto *Result =
Richard Smith053f6c62014-05-16 23:01:30 +0000725 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000726 Result->MayHaveOutOfDateDef = false;
727 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000728}
729
Benjamin Kramer9170e912013-02-22 15:46:01 +0000730void ClassTemplateSpecializationDecl::getNameForDiagnostic(
731 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
732 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
Douglas Gregorb11aad82011-02-19 18:51:44 +0000733
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000734 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
Richard Smith792c22d2016-12-24 04:09:05 +0000735 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
736 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
Serge Pavlov03e672c2017-11-28 16:14:14 +0000737 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
Richard Smith792c22d2016-12-24 04:09:05 +0000738 } else {
739 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Serge Pavlov03e672c2017-11-28 16:14:14 +0000740 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
Richard Smith792c22d2016-12-24 04:09:05 +0000741 }
Douglas Gregorb11aad82011-02-19 18:51:44 +0000742}
743
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000744ClassTemplateDecl *
Mike Stump11289f42009-09-09 15:08:12 +0000745ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000746 if (const auto *PartialSpec =
747 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
Douglas Gregor9dc8bd32009-08-02 23:24:31 +0000748 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
749 return SpecializedTemplate.get<ClassTemplateDecl*>();
750}
751
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000752SourceRange
753ClassTemplateSpecializationDecl::getSourceRange() const {
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000754 if (ExplicitInfo) {
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000755 SourceLocation Begin = getTemplateKeywordLoc();
756 if (Begin.isValid()) {
757 // Here we have an explicit (partial) specialization or instantiation.
758 assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
759 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
760 getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
761 if (getExternLoc().isValid())
762 Begin = getExternLoc();
Argyrios Kyrtzidisd798c052016-07-15 18:11:33 +0000763 SourceLocation End = getBraceRange().getEnd();
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000764 if (End.isInvalid())
765 End = getTypeAsWritten()->getTypeLoc().getEndLoc();
766 return SourceRange(Begin, End);
767 }
768 // An implicit instantiation of a class template partial specialization
769 // uses ExplicitInfo to record the TypeAsWritten, but the source
770 // locations should be retrieved from the instantiation pattern.
Eugene Zelenko421e8902017-11-29 22:39:22 +0000771 using CTPSDecl = ClassTemplatePartialSpecializationDecl;
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000772 auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000773 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
Craig Topper36250ad2014-05-12 05:36:57 +0000774 assert(inst_from != nullptr);
Abramo Bagnarac76dcbd2012-10-15 21:06:42 +0000775 return inst_from->getSourceRange();
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000776 }
777 else {
778 // No explicit info available.
779 llvm::PointerUnion<ClassTemplateDecl *,
780 ClassTemplatePartialSpecializationDecl *>
781 inst_from = getInstantiatedFrom();
782 if (inst_from.isNull())
783 return getSpecializedTemplate()->getSourceRange();
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000784 if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000785 return ctd->getSourceRange();
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000786 return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
Abramo Bagnarafd3a4552011-10-03 20:34:03 +0000787 ->getSourceRange();
788 }
Abramo Bagnaraa0935262011-03-04 14:20:30 +0000789}
790
Douglas Gregor2373c592009-05-31 09:31:02 +0000791//===----------------------------------------------------------------------===//
792// ClassTemplatePartialSpecializationDecl Implementation
793//===----------------------------------------------------------------------===//
Eugene Zelenko421e8902017-11-29 22:39:22 +0000794void ClassTemplatePartialSpecializationDecl::anchor() {}
David Blaikie68e081d2011-12-20 02:48:34 +0000795
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000796ClassTemplatePartialSpecializationDecl::
797ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000798 DeclContext *DC,
799 SourceLocation StartLoc,
800 SourceLocation IdLoc,
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000801 TemplateParameterList *Params,
802 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000803 ArrayRef<TemplateArgument> Args,
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000804 const ASTTemplateArgumentListInfo *ArgInfos,
Richard Smithb2f61b42013-08-22 23:27:37 +0000805 ClassTemplatePartialSpecializationDecl *PrevDecl)
Eugene Zelenko421e8902017-11-29 22:39:22 +0000806 : ClassTemplateSpecializationDecl(Context,
807 ClassTemplatePartialSpecialization,
808 TK, DC, StartLoc, IdLoc,
809 SpecializedTemplate, Args, PrevDecl),
810 TemplateParams(Params), ArgsAsWritten(ArgInfos),
811 InstantiatedFromMember(nullptr, false) {
Douglas Gregor3c41bf72011-03-04 18:32:38 +0000812 AdoptTemplateParameterList(Params, this);
Douglas Gregorfd7c2252011-03-04 17:52:15 +0000813}
814
Douglas Gregor2373c592009-05-31 09:31:02 +0000815ClassTemplatePartialSpecializationDecl *
816ClassTemplatePartialSpecializationDecl::
Abramo Bagnara29c2d462011-03-09 14:09:51 +0000817Create(ASTContext &Context, TagKind TK,DeclContext *DC,
818 SourceLocation StartLoc, SourceLocation IdLoc,
Douglas Gregor2373c592009-05-31 09:31:02 +0000819 TemplateParameterList *Params,
820 ClassTemplateDecl *SpecializedTemplate,
David Majnemer8b622692016-07-03 21:17:51 +0000821 ArrayRef<TemplateArgument> Args,
John McCall6b51f282009-11-23 01:53:49 +0000822 const TemplateArgumentListInfo &ArgInfos,
John McCalle78aac42010-03-10 03:28:59 +0000823 QualType CanonInjectedType,
Richard Smithb2f61b42013-08-22 23:27:37 +0000824 ClassTemplatePartialSpecializationDecl *PrevDecl) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000825 const ASTTemplateArgumentListInfo *ASTArgInfos =
826 ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
John McCall0ad16662009-10-29 08:12:44 +0000827
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000828 auto *Result = new (Context, DC)
Richard Smithf7981722013-11-22 09:01:48 +0000829 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
830 Params, SpecializedTemplate, Args,
David Majnemer8b622692016-07-03 21:17:51 +0000831 ASTArgInfos, PrevDecl);
Douglas Gregor2373c592009-05-31 09:31:02 +0000832 Result->setSpecializationKind(TSK_ExplicitSpecialization);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000833 Result->MayHaveOutOfDateDef = false;
John McCalle78aac42010-03-10 03:28:59 +0000834
835 Context.getInjectedClassNameType(Result, CanonInjectedType);
Douglas Gregor2373c592009-05-31 09:31:02 +0000836 return Result;
837}
John McCall11083da2009-09-16 22:47:08 +0000838
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000839ClassTemplatePartialSpecializationDecl *
Douglas Gregor72172e92012-01-05 21:55:30 +0000840ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
841 unsigned ID) {
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000842 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
Douglas Gregor7dab26b2013-02-09 01:35:03 +0000843 Result->MayHaveOutOfDateDef = false;
844 return Result;
Argyrios Kyrtzidisfe6ba882010-06-23 13:48:23 +0000845}
846
John McCall11083da2009-09-16 22:47:08 +0000847//===----------------------------------------------------------------------===//
848// FriendTemplateDecl Implementation
849//===----------------------------------------------------------------------===//
850
Eugene Zelenko421e8902017-11-29 22:39:22 +0000851void FriendTemplateDecl::anchor() {}
David Blaikie68e081d2011-12-20 02:48:34 +0000852
David Majnemerdfecf1a2016-07-06 04:19:16 +0000853FriendTemplateDecl *
854FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
855 SourceLocation L,
856 MutableArrayRef<TemplateParameterList *> Params,
857 FriendUnion Friend, SourceLocation FLoc) {
858 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
John McCall11083da2009-09-16 22:47:08 +0000859}
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000860
Douglas Gregor72172e92012-01-05 21:55:30 +0000861FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
862 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000863 return new (C, ID) FriendTemplateDecl(EmptyShell());
Argyrios Kyrtzidis165b5812010-07-22 16:04:10 +0000864}
Richard Smith3f1b5d02011-05-05 21:57:07 +0000865
866//===----------------------------------------------------------------------===//
867// TypeAliasTemplateDecl Implementation
868//===----------------------------------------------------------------------===//
869
870TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
871 DeclContext *DC,
872 SourceLocation L,
873 DeclarationName Name,
874 TemplateParameterList *Params,
875 NamedDecl *Decl) {
876 AdoptTemplateParameterList(Params, DC);
Richard Smith053f6c62014-05-16 23:01:30 +0000877 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000878}
879
Douglas Gregor72172e92012-01-05 21:55:30 +0000880TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
881 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000882 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
Craig Topper36250ad2014-05-12 05:36:57 +0000883 DeclarationName(), nullptr, nullptr);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000884}
885
Richard Smith3f1b5d02011-05-05 21:57:07 +0000886RedeclarableTemplateDecl::CommonBase *
Dmitri Gribenkob53f37c2013-01-23 16:52:57 +0000887TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000888 auto *CommonPtr = new (C) Common;
George Burgess IVb61bfbd2017-02-14 05:37:36 +0000889 C.addDestruction(CommonPtr);
Richard Smith3f1b5d02011-05-05 21:57:07 +0000890 return CommonPtr;
891}
892
David Blaikie68e081d2011-12-20 02:48:34 +0000893//===----------------------------------------------------------------------===//
894// ClassScopeFunctionSpecializationDecl Implementation
895//===----------------------------------------------------------------------===//
896
Eugene Zelenko421e8902017-11-29 22:39:22 +0000897void ClassScopeFunctionSpecializationDecl::anchor() {}
Douglas Gregor72172e92012-01-05 21:55:30 +0000898
899ClassScopeFunctionSpecializationDecl *
900ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
901 unsigned ID) {
Richard Smithf7981722013-11-22 09:01:48 +0000902 return new (C, ID) ClassScopeFunctionSpecializationDecl(
Craig Topper36250ad2014-05-12 05:36:57 +0000903 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
Douglas Gregor72172e92012-01-05 21:55:30 +0000904}
Larisse Voufo39a1e502013-08-06 01:03:05 +0000905
906//===----------------------------------------------------------------------===//
907// VarTemplateDecl Implementation
908//===----------------------------------------------------------------------===//
909
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000910VarTemplateDecl *VarTemplateDecl::getDefinition() {
911 VarTemplateDecl *CurD = this;
912 while (CurD) {
913 if (CurD->isThisDeclarationADefinition())
914 return CurD;
915 CurD = CurD->getPreviousDecl();
916 }
Craig Topper36250ad2014-05-12 05:36:57 +0000917 return nullptr;
Larisse Voufoa11bd8a2013-08-13 02:02:26 +0000918}
919
Larisse Voufo39a1e502013-08-06 01:03:05 +0000920VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
921 SourceLocation L, DeclarationName Name,
922 TemplateParameterList *Params,
Richard Smithbeef3452014-01-16 23:39:20 +0000923 VarDecl *Decl) {
Richard Smith053f6c62014-05-16 23:01:30 +0000924 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000925}
926
927VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
928 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +0000929 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
930 DeclarationName(), nullptr, nullptr);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000931}
932
Larisse Voufo39a1e502013-08-06 01:03:05 +0000933void VarTemplateDecl::LoadLazySpecializations() const {
Vassil Vassilev61f64292017-12-14 23:30:18 +0000934 loadLazySpecializationsImpl();
Larisse Voufo39a1e502013-08-06 01:03:05 +0000935}
936
937llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
938VarTemplateDecl::getSpecializations() const {
939 LoadLazySpecializations();
940 return getCommonPtr()->Specializations;
941}
942
943llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
944VarTemplateDecl::getPartialSpecializations() {
945 LoadLazySpecializations();
946 return getCommonPtr()->PartialSpecializations;
947}
948
949RedeclarableTemplateDecl::CommonBase *
950VarTemplateDecl::newCommon(ASTContext &C) const {
Eugene Zelenko309e29d2018-03-29 20:51:59 +0000951 auto *CommonPtr = new (C) Common;
George Burgess IVb61bfbd2017-02-14 05:37:36 +0000952 C.addDestruction(CommonPtr);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000953 return CommonPtr;
954}
955
956VarTemplateSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000957VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
958 void *&InsertPos) {
959 return findSpecializationImpl(getSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000960}
961
962void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
963 void *InsertPos) {
Richard Smithe977e512015-02-24 01:23:23 +0000964 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000965}
966
967VarTemplatePartialSpecializationDecl *
Craig Topper7e0daca2014-06-26 04:58:53 +0000968VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
969 void *&InsertPos) {
970 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
Larisse Voufo39a1e502013-08-06 01:03:05 +0000971}
972
973void VarTemplateDecl::AddPartialSpecialization(
974 VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
975 if (InsertPos)
976 getPartialSpecializations().InsertNode(D, InsertPos);
977 else {
978 VarTemplatePartialSpecializationDecl *Existing =
979 getPartialSpecializations().GetOrInsertNode(D);
980 (void)Existing;
981 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
982 }
983
984 if (ASTMutationListener *L = getASTMutationListener())
985 L->AddedCXXTemplateSpecialization(this, D);
986}
987
988void VarTemplateDecl::getPartialSpecializations(
989 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
990 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
991 getPartialSpecializations();
992 PS.clear();
Richard Smithb2f61b42013-08-22 23:27:37 +0000993 PS.reserve(PartialSpecs.size());
David Majnemerdfecf1a2016-07-06 04:19:16 +0000994 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
995 PS.push_back(P.getMostRecentDecl());
Larisse Voufo39a1e502013-08-06 01:03:05 +0000996}
997
998VarTemplatePartialSpecializationDecl *
999VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1000 VarTemplatePartialSpecializationDecl *D) {
1001 Decl *DCanon = D->getCanonicalDecl();
David Majnemerdfecf1a2016-07-06 04:19:16 +00001002 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1003 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1004 return P.getMostRecentDecl();
Larisse Voufo39a1e502013-08-06 01:03:05 +00001005 }
1006
Craig Topper36250ad2014-05-12 05:36:57 +00001007 return nullptr;
Larisse Voufo39a1e502013-08-06 01:03:05 +00001008}
1009
1010//===----------------------------------------------------------------------===//
1011// VarTemplateSpecializationDecl Implementation
1012//===----------------------------------------------------------------------===//
Eugene Zelenko421e8902017-11-29 22:39:22 +00001013
Larisse Voufo39a1e502013-08-06 01:03:05 +00001014VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001015 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001016 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
David Majnemer8b622692016-07-03 21:17:51 +00001017 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
Richard Smith053f6c62014-05-16 23:01:30 +00001018 : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1019 SpecializedTemplate->getIdentifier(), T, TInfo, S),
Eugene Zelenko421e8902017-11-29 22:39:22 +00001020 SpecializedTemplate(SpecializedTemplate),
David Majnemer8b622692016-07-03 21:17:51 +00001021 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
Richard Smith435e6472017-12-02 02:48:42 +00001022 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
Larisse Voufo39a1e502013-08-06 01:03:05 +00001023
Richard Smith053f6c62014-05-16 23:01:30 +00001024VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1025 ASTContext &C)
1026 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
Craig Topper36250ad2014-05-12 05:36:57 +00001027 QualType(), nullptr, SC_None),
Richard Smith435e6472017-12-02 02:48:42 +00001028 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
Larisse Voufo39a1e502013-08-06 01:03:05 +00001029
1030VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1031 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1032 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
David Majnemer8b622692016-07-03 21:17:51 +00001033 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
Richard Smithf7981722013-11-22 09:01:48 +00001034 return new (Context, DC) VarTemplateSpecializationDecl(
Richard Smith053f6c62014-05-16 23:01:30 +00001035 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
David Majnemer8b622692016-07-03 21:17:51 +00001036 SpecializedTemplate, T, TInfo, S, Args);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001037}
1038
1039VarTemplateSpecializationDecl *
1040VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001041 return new (C, ID)
1042 VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001043}
1044
1045void VarTemplateSpecializationDecl::getNameForDiagnostic(
1046 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1047 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1048
Eugene Zelenko309e29d2018-03-29 20:51:59 +00001049 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
Richard Smith792c22d2016-12-24 04:09:05 +00001050 if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1051 PS ? PS->getTemplateArgsAsWritten() : nullptr) {
Serge Pavlov03e672c2017-11-28 16:14:14 +00001052 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
Richard Smith792c22d2016-12-24 04:09:05 +00001053 } else {
1054 const TemplateArgumentList &TemplateArgs = getTemplateArgs();
Serge Pavlov03e672c2017-11-28 16:14:14 +00001055 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
Richard Smith792c22d2016-12-24 04:09:05 +00001056 }
Larisse Voufo39a1e502013-08-06 01:03:05 +00001057}
1058
1059VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
Eugene Zelenko309e29d2018-03-29 20:51:59 +00001060 if (const auto *PartialSpec =
Larisse Voufo39a1e502013-08-06 01:03:05 +00001061 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1062 return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1063 return SpecializedTemplate.get<VarTemplateDecl *>();
1064}
1065
1066void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1067 const TemplateArgumentListInfo &ArgsInfo) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001068 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1069 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
David Majnemerdfecf1a2016-07-06 04:19:16 +00001070 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1071 TemplateArgsInfo.addArgument(Loc);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001072}
1073
1074//===----------------------------------------------------------------------===//
1075// VarTemplatePartialSpecializationDecl Implementation
1076//===----------------------------------------------------------------------===//
Eugene Zelenko421e8902017-11-29 22:39:22 +00001077
Larisse Voufo39a1e502013-08-06 01:03:05 +00001078void VarTemplatePartialSpecializationDecl::anchor() {}
1079
1080VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1081 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1082 SourceLocation IdLoc, TemplateParameterList *Params,
1083 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001084 StorageClass S, ArrayRef<TemplateArgument> Args,
Richard Smithb2f61b42013-08-22 23:27:37 +00001085 const ASTTemplateArgumentListInfo *ArgInfos)
Richard Smith053f6c62014-05-16 23:01:30 +00001086 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
Larisse Voufo39a1e502013-08-06 01:03:05 +00001087 DC, StartLoc, IdLoc, SpecializedTemplate, T,
David Majnemer8b622692016-07-03 21:17:51 +00001088 TInfo, S, Args),
Larisse Voufo39a1e502013-08-06 01:03:05 +00001089 TemplateParams(Params), ArgsAsWritten(ArgInfos),
Craig Topper36250ad2014-05-12 05:36:57 +00001090 InstantiatedFromMember(nullptr, false) {
Larisse Voufo39a1e502013-08-06 01:03:05 +00001091 // TODO: The template parameters should be in DC by now. Verify.
1092 // AdoptTemplateParameterList(Params, DC);
1093}
1094
1095VarTemplatePartialSpecializationDecl *
1096VarTemplatePartialSpecializationDecl::Create(
1097 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1098 SourceLocation IdLoc, TemplateParameterList *Params,
1099 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001100 StorageClass S, ArrayRef<TemplateArgument> Args,
Richard Smithb2f61b42013-08-22 23:27:37 +00001101 const TemplateArgumentListInfo &ArgInfos) {
Enea Zaffanella6dbe1872013-08-10 07:24:53 +00001102 const ASTTemplateArgumentListInfo *ASTArgInfos
1103 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001104
Eugene Zelenko309e29d2018-03-29 20:51:59 +00001105 auto *Result =
Richard Smithf7981722013-11-22 09:01:48 +00001106 new (Context, DC) VarTemplatePartialSpecializationDecl(
Larisse Voufo39a1e502013-08-06 01:03:05 +00001107 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
David Majnemer8b622692016-07-03 21:17:51 +00001108 S, Args, ASTArgInfos);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001109 Result->setSpecializationKind(TSK_ExplicitSpecialization);
1110 return Result;
1111}
1112
1113VarTemplatePartialSpecializationDecl *
1114VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1115 unsigned ID) {
Richard Smith053f6c62014-05-16 23:01:30 +00001116 return new (C, ID) VarTemplatePartialSpecializationDecl(C);
Larisse Voufo39a1e502013-08-06 01:03:05 +00001117}
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001118
1119static TemplateParameterList *
1120createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1121 // typename T
1122 auto *T = TemplateTypeParmDecl::Create(
1123 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1124 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1125 T->setImplicit(true);
1126
1127 // T ...Ints
1128 TypeSourceInfo *TI =
1129 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1130 auto *N = NonTypeTemplateParmDecl::Create(
1131 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1132 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1133 N->setImplicit(true);
1134
1135 // <typename T, T ...Ints>
1136 NamedDecl *P[2] = {T, N};
1137 auto *TPL = TemplateParameterList::Create(
Hubert Tonge4a0c0e2016-07-30 22:33:34 +00001138 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001139
1140 // template <typename T, ...Ints> class IntSeq
1141 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1142 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1143 /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1144 TemplateTemplateParm->setImplicit(true);
1145
1146 // typename T
1147 auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1148 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1149 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1150 TemplateTypeParm->setImplicit(true);
1151
1152 // T N
1153 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1154 QualType(TemplateTypeParm->getTypeForDecl(), 0));
1155 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1156 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1157 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1158 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1159 NonTypeTemplateParm};
1160
1161 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1162 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
Hubert Tonge4a0c0e2016-07-30 22:33:34 +00001163 Params, SourceLocation(), nullptr);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001164}
1165
Eric Fiselier6ad68552016-07-01 01:24:09 +00001166static TemplateParameterList *
1167createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1168 // std::size_t Index
1169 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1170 auto *Index = NonTypeTemplateParmDecl::Create(
1171 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1172 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1173
1174 // typename ...T
1175 auto *Ts = TemplateTypeParmDecl::Create(
1176 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1177 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1178 Ts->setImplicit(true);
1179
1180 // template <std::size_t Index, typename ...T>
1181 NamedDecl *Params[] = {Index, Ts};
1182 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1183 llvm::makeArrayRef(Params),
Hubert Tonge4a0c0e2016-07-30 22:33:34 +00001184 SourceLocation(), nullptr);
Eric Fiselier6ad68552016-07-01 01:24:09 +00001185}
1186
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001187static TemplateParameterList *createBuiltinTemplateParameterList(
1188 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1189 switch (BTK) {
1190 case BTK__make_integer_seq:
1191 return createMakeIntegerSeqParameterList(C, DC);
Eric Fiselier6ad68552016-07-01 01:24:09 +00001192 case BTK__type_pack_element:
1193 return createTypePackElementParameterList(C, DC);
David Majnemerd9b1a4f2015-11-04 03:40:30 +00001194 }
1195
1196 llvm_unreachable("unhandled BuiltinTemplateKind!");
1197}
1198
1199void BuiltinTemplateDecl::anchor() {}
1200
1201BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1202 DeclarationName Name,
1203 BuiltinTemplateKind BTK)
1204 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1205 createBuiltinTemplateParameterList(C, DC, BTK)),
1206 BTK(BTK) {}