blob: 284c1b5baae019f161d963d451bfc3f7a9a58c73 [file] [log] [blame]
John McCall275c10a2009-10-29 07:48:15 +00001//===--- TemplateBase.cpp - Common template AST class implementation ------===//
2//
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 common classes used throughout C++ template
11// representations.
12//
13//===----------------------------------------------------------------------===//
14
John McCall275c10a2009-10-29 07:48:15 +000015#include "clang/AST/TemplateBase.h"
Douglas Gregor87dd6972010-12-20 16:52:59 +000016#include "clang/AST/ASTContext.h"
John McCall275c10a2009-10-29 07:48:15 +000017#include "clang/AST/DeclBase.h"
Douglas Gregor74295b32009-11-23 12:52:47 +000018#include "clang/AST/DeclTemplate.h"
John McCall275c10a2009-10-29 07:48:15 +000019#include "clang/AST/Expr.h"
Douglas Gregorbe230c32011-01-03 17:17:50 +000020#include "clang/AST/ExprCXX.h"
Chandler Carruth781701c2011-02-19 00:21:00 +000021#include "clang/AST/Type.h"
John McCall833ca992009-10-29 08:12:44 +000022#include "clang/AST/TypeLoc.h"
Douglas Gregora9333192010-05-08 17:41:32 +000023#include "clang/Basic/Diagnostic.h"
Douglas Gregor87dd6972010-12-20 16:52:59 +000024#include "llvm/ADT/FoldingSet.h"
Benjamin Kramer8fe83e12012-02-04 13:45:25 +000025#include "llvm/ADT/SmallString.h"
Douglas Gregor203e6a32011-01-11 23:09:57 +000026#include <algorithm>
Chandler Carruth781701c2011-02-19 00:21:00 +000027#include <cctype>
John McCall275c10a2009-10-29 07:48:15 +000028
29using namespace clang;
30
Chandler Carruth781701c2011-02-19 00:21:00 +000031/// \brief Print a template integral argument value.
32///
33/// \param TemplArg the TemplateArgument instance to print.
34///
35/// \param Out the raw_ostream instance to use for printing.
36static void printIntegral(const TemplateArgument &TemplArg,
Chris Lattner5f9e2722011-07-23 10:55:15 +000037 raw_ostream &Out) {
Chandler Carruth781701c2011-02-19 00:21:00 +000038 const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr();
Benjamin Kramer85524372012-06-07 15:09:51 +000039 const llvm::APSInt &Val = TemplArg.getAsIntegral();
Chandler Carruth781701c2011-02-19 00:21:00 +000040
41 if (T->isBooleanType()) {
Benjamin Kramer85524372012-06-07 15:09:51 +000042 Out << (Val.getBoolValue() ? "true" : "false");
Chandler Carruth781701c2011-02-19 00:21:00 +000043 } else if (T->isCharType()) {
Benjamin Kramer85524372012-06-07 15:09:51 +000044 const char Ch = Val.getZExtValue();
Chandler Carruth774e2b42011-02-25 20:09:13 +000045 Out << ((Ch == '\'') ? "'\\" : "'");
Benjamin Kramer8fe83e12012-02-04 13:45:25 +000046 Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
Chandler Carruth774e2b42011-02-25 20:09:13 +000047 Out << "'";
Chandler Carruth781701c2011-02-19 00:21:00 +000048 } else {
Benjamin Kramer85524372012-06-07 15:09:51 +000049 Out << Val;
Chandler Carruth781701c2011-02-19 00:21:00 +000050 }
51}
52
John McCall275c10a2009-10-29 07:48:15 +000053//===----------------------------------------------------------------------===//
54// TemplateArgument Implementation
55//===----------------------------------------------------------------------===//
56
Benjamin Kramer85524372012-06-07 15:09:51 +000057TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
58 QualType Type)
59 : Kind(Integral) {
60 // Copy the APSInt value into our decomposed form.
61 Integer.BitWidth = Value.getBitWidth();
62 Integer.IsUnsigned = Value.isUnsigned();
63 // If the value is large, we have to get additional memory from the ASTContext
64 if (Integer.BitWidth > 64) {
65 void *Mem = Ctx.Allocate(Integer.BitWidth / 8);
66 std::memcpy(Mem, Value.getRawData(), Integer.BitWidth / 8);
67 Integer.pVal = static_cast<uint64_t *>(Mem);
68 } else {
69 Integer.VAL = Value.getZExtValue();
70 }
71
72 Integer.Type = Type.getAsOpaquePtr();
73}
74
Douglas Gregor203e6a32011-01-11 23:09:57 +000075TemplateArgument TemplateArgument::CreatePackCopy(ASTContext &Context,
76 const TemplateArgument *Args,
77 unsigned NumArgs) {
78 if (NumArgs == 0)
79 return TemplateArgument(0, 0);
80
81 TemplateArgument *Storage = new (Context) TemplateArgument [NumArgs];
82 std::copy(Args, Args + NumArgs, Storage);
83 return TemplateArgument(Storage, NumArgs);
84}
85
Douglas Gregorbebbe0d2010-12-15 01:34:56 +000086bool TemplateArgument::isDependent() const {
87 switch (getKind()) {
88 case Null:
David Blaikieb219cfc2011-09-23 05:06:16 +000089 llvm_unreachable("Should not have a NULL template argument");
Douglas Gregorbebbe0d2010-12-15 01:34:56 +000090
91 case Type:
92 return getAsType()->isDependentType();
93
94 case Template:
95 return getAsTemplate().isDependent();
Douglas Gregora7fc9012011-01-05 18:58:31 +000096
97 case TemplateExpansion:
98 return true;
99
Douglas Gregorbebbe0d2010-12-15 01:34:56 +0000100 case Declaration:
Douglas Gregord2008e22012-04-06 22:40:38 +0000101 if (Decl *D = getAsDecl()) {
102 if (DeclContext *DC = dyn_cast<DeclContext>(D))
103 return DC->isDependentContext();
104 return D->getDeclContext()->isDependentContext();
105 }
106
107 return false;
Douglas Gregorbebbe0d2010-12-15 01:34:56 +0000108
109 case Integral:
110 // Never dependent
111 return false;
112
113 case Expression:
114 return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent());
115
116 case Pack:
117 for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
118 if (P->isDependent())
119 return true;
120 }
121
122 return false;
123 }
124
David Blaikie30263482012-01-20 21:50:17 +0000125 llvm_unreachable("Invalid TemplateArgument Kind!");
Douglas Gregorbebbe0d2010-12-15 01:34:56 +0000126}
127
Douglas Gregor561f8122011-07-01 01:22:09 +0000128bool TemplateArgument::isInstantiationDependent() const {
129 switch (getKind()) {
130 case Null:
David Blaikieb219cfc2011-09-23 05:06:16 +0000131 llvm_unreachable("Should not have a NULL template argument");
Douglas Gregor561f8122011-07-01 01:22:09 +0000132
133 case Type:
134 return getAsType()->isInstantiationDependentType();
135
136 case Template:
137 return getAsTemplate().isInstantiationDependent();
138
139 case TemplateExpansion:
140 return true;
141
142 case Declaration:
Douglas Gregord2008e22012-04-06 22:40:38 +0000143 if (Decl *D = getAsDecl()) {
144 if (DeclContext *DC = dyn_cast<DeclContext>(D))
145 return DC->isDependentContext();
146 return D->getDeclContext()->isDependentContext();
147 }
148 return false;
149
Douglas Gregor561f8122011-07-01 01:22:09 +0000150 case Integral:
151 // Never dependent
152 return false;
153
154 case Expression:
155 return getAsExpr()->isInstantiationDependent();
156
157 case Pack:
158 for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
159 if (P->isInstantiationDependent())
160 return true;
161 }
162
163 return false;
164 }
David Blaikie30263482012-01-20 21:50:17 +0000165
166 llvm_unreachable("Invalid TemplateArgument Kind!");
Douglas Gregor561f8122011-07-01 01:22:09 +0000167}
168
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000169bool TemplateArgument::isPackExpansion() const {
170 switch (getKind()) {
171 case Null:
172 case Declaration:
173 case Integral:
174 case Pack:
Douglas Gregora7fc9012011-01-05 18:58:31 +0000175 case Template:
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000176 return false;
177
Douglas Gregora7fc9012011-01-05 18:58:31 +0000178 case TemplateExpansion:
179 return true;
180
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000181 case Type:
Douglas Gregorbe230c32011-01-03 17:17:50 +0000182 return isa<PackExpansionType>(getAsType());
Douglas Gregora7fc9012011-01-05 18:58:31 +0000183
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000184 case Expression:
Douglas Gregorbe230c32011-01-03 17:17:50 +0000185 return isa<PackExpansionExpr>(getAsExpr());
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000186 }
David Blaikie30263482012-01-20 21:50:17 +0000187
188 llvm_unreachable("Invalid TemplateArgument Kind!");
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000189}
190
Douglas Gregord0937222010-12-13 22:49:22 +0000191bool TemplateArgument::containsUnexpandedParameterPack() const {
192 switch (getKind()) {
193 case Null:
194 case Declaration:
195 case Integral:
Douglas Gregora7fc9012011-01-05 18:58:31 +0000196 case TemplateExpansion:
Douglas Gregord0937222010-12-13 22:49:22 +0000197 break;
198
199 case Type:
200 if (getAsType()->containsUnexpandedParameterPack())
201 return true;
202 break;
203
204 case Template:
Douglas Gregora7fc9012011-01-05 18:58:31 +0000205 if (getAsTemplate().containsUnexpandedParameterPack())
Douglas Gregord0937222010-12-13 22:49:22 +0000206 return true;
207 break;
208
209 case Expression:
210 if (getAsExpr()->containsUnexpandedParameterPack())
211 return true;
212 break;
213
214 case Pack:
215 for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P)
216 if (P->containsUnexpandedParameterPack())
217 return true;
218
219 break;
220 }
221
222 return false;
223}
224
Douglas Gregor2be29f42011-01-14 23:41:42 +0000225llvm::Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
226 assert(Kind == TemplateExpansion);
227 if (TemplateArg.NumExpansions)
228 return TemplateArg.NumExpansions - 1;
229
230 return llvm::Optional<unsigned>();
231}
232
John McCall275c10a2009-10-29 07:48:15 +0000233void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
Jay Foad4ba2a172011-01-12 09:06:06 +0000234 const ASTContext &Context) const {
John McCall275c10a2009-10-29 07:48:15 +0000235 ID.AddInteger(Kind);
236 switch (Kind) {
237 case Null:
238 break;
239
240 case Type:
241 getAsType().Profile(ID);
242 break;
243
244 case Declaration:
245 ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
246 break;
247
Douglas Gregor788cd062009-11-11 01:00:40 +0000248 case Template:
Douglas Gregora7fc9012011-01-05 18:58:31 +0000249 case TemplateExpansion: {
250 TemplateName Template = getAsTemplateOrTemplatePattern();
Douglas Gregor74295b32009-11-23 12:52:47 +0000251 if (TemplateTemplateParmDecl *TTP
252 = dyn_cast_or_null<TemplateTemplateParmDecl>(
Douglas Gregora7fc9012011-01-05 18:58:31 +0000253 Template.getAsTemplateDecl())) {
Douglas Gregor74295b32009-11-23 12:52:47 +0000254 ID.AddBoolean(true);
255 ID.AddInteger(TTP->getDepth());
256 ID.AddInteger(TTP->getPosition());
Douglas Gregorba68eca2011-01-05 17:40:24 +0000257 ID.AddBoolean(TTP->isParameterPack());
Douglas Gregor74295b32009-11-23 12:52:47 +0000258 } else {
259 ID.AddBoolean(false);
Douglas Gregora7fc9012011-01-05 18:58:31 +0000260 ID.AddPointer(Context.getCanonicalTemplateName(Template)
261 .getAsVoidPointer());
Douglas Gregor74295b32009-11-23 12:52:47 +0000262 }
Douglas Gregor788cd062009-11-11 01:00:40 +0000263 break;
Douglas Gregora7fc9012011-01-05 18:58:31 +0000264 }
Douglas Gregor788cd062009-11-11 01:00:40 +0000265
John McCall275c10a2009-10-29 07:48:15 +0000266 case Integral:
Benjamin Kramer85524372012-06-07 15:09:51 +0000267 getAsIntegral().Profile(ID);
John McCall275c10a2009-10-29 07:48:15 +0000268 getIntegralType().Profile(ID);
269 break;
270
271 case Expression:
272 getAsExpr()->Profile(ID, Context, true);
273 break;
274
275 case Pack:
276 ID.AddInteger(Args.NumArgs);
277 for (unsigned I = 0; I != Args.NumArgs; ++I)
278 Args.Args[I].Profile(ID, Context);
279 }
280}
John McCall833ca992009-10-29 08:12:44 +0000281
John McCall33500952010-06-11 00:33:02 +0000282bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
283 if (getKind() != Other.getKind()) return false;
284
285 switch (getKind()) {
286 case Null:
287 case Type:
288 case Declaration:
Douglas Gregora7fc9012011-01-05 18:58:31 +0000289 case Expression:
290 case Template:
291 case TemplateExpansion:
John McCall33500952010-06-11 00:33:02 +0000292 return TypeOrValue == Other.TypeOrValue;
293
294 case Integral:
295 return getIntegralType() == Other.getIntegralType() &&
Benjamin Kramer85524372012-06-07 15:09:51 +0000296 getAsIntegral() == Other.getAsIntegral();
John McCall33500952010-06-11 00:33:02 +0000297
298 case Pack:
299 if (Args.NumArgs != Other.Args.NumArgs) return false;
300 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
301 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
302 return false;
303 return true;
304 }
305
David Blaikie30263482012-01-20 21:50:17 +0000306 llvm_unreachable("Invalid TemplateArgument Kind!");
John McCall33500952010-06-11 00:33:02 +0000307}
308
Douglas Gregore02e2622010-12-22 21:19:48 +0000309TemplateArgument TemplateArgument::getPackExpansionPattern() const {
310 assert(isPackExpansion());
311
312 switch (getKind()) {
Douglas Gregorba68eca2011-01-05 17:40:24 +0000313 case Type:
314 return getAsType()->getAs<PackExpansionType>()->getPattern();
315
316 case Expression:
317 return cast<PackExpansionExpr>(getAsExpr())->getPattern();
318
Douglas Gregora7fc9012011-01-05 18:58:31 +0000319 case TemplateExpansion:
Douglas Gregor2be29f42011-01-14 23:41:42 +0000320 return TemplateArgument(getAsTemplateOrTemplatePattern());
Douglas Gregorba68eca2011-01-05 17:40:24 +0000321
322 case Declaration:
323 case Integral:
324 case Pack:
325 case Null:
Douglas Gregora7fc9012011-01-05 18:58:31 +0000326 case Template:
Douglas Gregorba68eca2011-01-05 17:40:24 +0000327 return TemplateArgument();
Douglas Gregore02e2622010-12-22 21:19:48 +0000328 }
David Blaikie30263482012-01-20 21:50:17 +0000329
330 llvm_unreachable("Invalid TemplateArgument Kind!");
Douglas Gregore02e2622010-12-22 21:19:48 +0000331}
332
Douglas Gregor87dd6972010-12-20 16:52:59 +0000333void TemplateArgument::print(const PrintingPolicy &Policy,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000334 raw_ostream &Out) const {
Douglas Gregor87dd6972010-12-20 16:52:59 +0000335 switch (getKind()) {
336 case Null:
337 Out << "<no value>";
338 break;
339
340 case Type: {
Douglas Gregore559ca12011-06-17 22:11:49 +0000341 PrintingPolicy SubPolicy(Policy);
342 SubPolicy.SuppressStrongLifetime = true;
Douglas Gregor87dd6972010-12-20 16:52:59 +0000343 std::string TypeStr;
Douglas Gregore559ca12011-06-17 22:11:49 +0000344 getAsType().getAsStringInternal(TypeStr, SubPolicy);
Douglas Gregor87dd6972010-12-20 16:52:59 +0000345 Out << TypeStr;
346 break;
347 }
348
349 case Declaration: {
Douglas Gregor87dd6972010-12-20 16:52:59 +0000350 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getAsDecl())) {
351 if (ND->getDeclName()) {
Benjamin Kramera59d20b2012-02-07 11:57:57 +0000352 Out << *ND;
Douglas Gregord2008e22012-04-06 22:40:38 +0000353 } else {
354 Out << "<anonymous>";
Douglas Gregor87dd6972010-12-20 16:52:59 +0000355 }
Douglas Gregord2008e22012-04-06 22:40:38 +0000356 } else {
357 Out << "nullptr";
Douglas Gregor87dd6972010-12-20 16:52:59 +0000358 }
359 break;
360 }
361
Douglas Gregora7fc9012011-01-05 18:58:31 +0000362 case Template:
Douglas Gregor87dd6972010-12-20 16:52:59 +0000363 getAsTemplate().print(Out, Policy);
364 break;
Douglas Gregora7fc9012011-01-05 18:58:31 +0000365
366 case TemplateExpansion:
367 getAsTemplateOrTemplatePattern().print(Out, Policy);
368 Out << "...";
369 break;
370
Douglas Gregor87dd6972010-12-20 16:52:59 +0000371 case Integral: {
Chandler Carruth781701c2011-02-19 00:21:00 +0000372 printIntegral(*this, Out);
Douglas Gregor87dd6972010-12-20 16:52:59 +0000373 break;
374 }
375
Douglas Gregorba68eca2011-01-05 17:40:24 +0000376 case Expression:
Douglas Gregor87dd6972010-12-20 16:52:59 +0000377 getAsExpr()->printPretty(Out, 0, Policy);
378 break;
Douglas Gregor87dd6972010-12-20 16:52:59 +0000379
380 case Pack:
381 Out << "<";
382 bool First = true;
383 for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end();
384 P != PEnd; ++P) {
385 if (First)
386 First = false;
387 else
388 Out << ", ";
389
390 P->print(Policy, Out);
391 }
392 Out << ">";
393 break;
394 }
395}
396
John McCall833ca992009-10-29 08:12:44 +0000397//===----------------------------------------------------------------------===//
398// TemplateArgumentLoc Implementation
399//===----------------------------------------------------------------------===//
400
Douglas Gregorb0ddf3a2011-01-06 00:33:28 +0000401TemplateArgumentLocInfo::TemplateArgumentLocInfo() {
Chandler Carruth75c40642011-04-28 08:19:45 +0000402 memset((void*)this, 0, sizeof(TemplateArgumentLocInfo));
Douglas Gregorb0ddf3a2011-01-06 00:33:28 +0000403}
404
John McCall828bff22009-10-29 18:45:58 +0000405SourceRange TemplateArgumentLoc::getSourceRange() const {
John McCall833ca992009-10-29 08:12:44 +0000406 switch (Argument.getKind()) {
407 case TemplateArgument::Expression:
John McCall828bff22009-10-29 18:45:58 +0000408 return getSourceExpression()->getSourceRange();
Zhanyong Wanf38ef0c2010-09-03 23:50:56 +0000409
John McCall833ca992009-10-29 08:12:44 +0000410 case TemplateArgument::Declaration:
John McCall828bff22009-10-29 18:45:58 +0000411 return getSourceDeclExpression()->getSourceRange();
Zhanyong Wanf38ef0c2010-09-03 23:50:56 +0000412
John McCall828bff22009-10-29 18:45:58 +0000413 case TemplateArgument::Type:
Zhanyong Wanf38ef0c2010-09-03 23:50:56 +0000414 if (TypeSourceInfo *TSI = getTypeSourceInfo())
415 return TSI->getTypeLoc().getSourceRange();
416 else
417 return SourceRange();
418
Douglas Gregora7fc9012011-01-05 18:58:31 +0000419 case TemplateArgument::Template:
Douglas Gregorb6744ef2011-03-02 17:09:35 +0000420 if (getTemplateQualifierLoc())
421 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
Douglas Gregora7fc9012011-01-05 18:58:31 +0000422 getTemplateNameLoc());
423 return SourceRange(getTemplateNameLoc());
424
425 case TemplateArgument::TemplateExpansion:
Douglas Gregorb6744ef2011-03-02 17:09:35 +0000426 if (getTemplateQualifierLoc())
427 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
Douglas Gregora7fc9012011-01-05 18:58:31 +0000428 getTemplateEllipsisLoc());
429 return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
430
John McCall833ca992009-10-29 08:12:44 +0000431 case TemplateArgument::Integral:
432 case TemplateArgument::Pack:
433 case TemplateArgument::Null:
John McCall828bff22009-10-29 18:45:58 +0000434 return SourceRange();
John McCall833ca992009-10-29 08:12:44 +0000435 }
436
David Blaikie30263482012-01-20 21:50:17 +0000437 llvm_unreachable("Invalid TemplateArgument Kind!");
John McCall833ca992009-10-29 08:12:44 +0000438}
Douglas Gregora9333192010-05-08 17:41:32 +0000439
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000440TemplateArgumentLoc
441TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis,
Douglas Gregorcded4f62011-01-14 17:04:44 +0000442 llvm::Optional<unsigned> &NumExpansions,
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000443 ASTContext &Context) const {
444 assert(Argument.isPackExpansion());
445
446 switch (Argument.getKind()) {
447 case TemplateArgument::Type: {
Douglas Gregor03491de2010-12-21 22:10:26 +0000448 // FIXME: We shouldn't ever have to worry about missing
449 // type-source info!
450 TypeSourceInfo *ExpansionTSInfo = getTypeSourceInfo();
451 if (!ExpansionTSInfo)
452 ExpansionTSInfo = Context.getTrivialTypeSourceInfo(
453 getArgument().getAsType(),
454 Ellipsis);
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000455 PackExpansionTypeLoc Expansion
Douglas Gregor03491de2010-12-21 22:10:26 +0000456 = cast<PackExpansionTypeLoc>(ExpansionTSInfo->getTypeLoc());
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000457 Ellipsis = Expansion.getEllipsisLoc();
458
459 TypeLoc Pattern = Expansion.getPatternLoc();
Douglas Gregorcded4f62011-01-14 17:04:44 +0000460 NumExpansions = Expansion.getTypePtr()->getNumExpansions();
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000461
462 // FIXME: This is horrible. We know where the source location data is for
463 // the pattern, and we have the pattern's type, but we are forced to copy
464 // them into an ASTContext because TypeSourceInfo bundles them together
465 // and TemplateArgumentLoc traffics in TypeSourceInfo pointers.
466 TypeSourceInfo *PatternTSInfo
467 = Context.CreateTypeSourceInfo(Pattern.getType(),
468 Pattern.getFullDataSize());
469 memcpy(PatternTSInfo->getTypeLoc().getOpaqueData(),
470 Pattern.getOpaqueData(), Pattern.getFullDataSize());
471 return TemplateArgumentLoc(TemplateArgument(Pattern.getType()),
472 PatternTSInfo);
473 }
474
Douglas Gregorbe230c32011-01-03 17:17:50 +0000475 case TemplateArgument::Expression: {
Douglas Gregorb0ddf3a2011-01-06 00:33:28 +0000476 PackExpansionExpr *Expansion
477 = cast<PackExpansionExpr>(Argument.getAsExpr());
478 Expr *Pattern = Expansion->getPattern();
479 Ellipsis = Expansion->getEllipsisLoc();
Douglas Gregor67fd1252011-01-14 21:20:45 +0000480 NumExpansions = Expansion->getNumExpansions();
Douglas Gregorbe230c32011-01-03 17:17:50 +0000481 return TemplateArgumentLoc(Pattern, Pattern);
482 }
Douglas Gregora7fc9012011-01-05 18:58:31 +0000483
484 case TemplateArgument::TemplateExpansion:
Douglas Gregorb0ddf3a2011-01-06 00:33:28 +0000485 Ellipsis = getTemplateEllipsisLoc();
Douglas Gregor2be29f42011-01-14 23:41:42 +0000486 NumExpansions = Argument.getNumTemplateExpansions();
Douglas Gregorba68eca2011-01-05 17:40:24 +0000487 return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
Douglas Gregorb6744ef2011-03-02 17:09:35 +0000488 getTemplateQualifierLoc(),
Douglas Gregorba68eca2011-01-05 17:40:24 +0000489 getTemplateNameLoc());
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000490
491 case TemplateArgument::Declaration:
Douglas Gregora7fc9012011-01-05 18:58:31 +0000492 case TemplateArgument::Template:
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000493 case TemplateArgument::Integral:
494 case TemplateArgument::Pack:
495 case TemplateArgument::Null:
496 return TemplateArgumentLoc();
497 }
David Blaikie30263482012-01-20 21:50:17 +0000498
499 llvm_unreachable("Invalid TemplateArgument Kind!");
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000500}
501
Douglas Gregora9333192010-05-08 17:41:32 +0000502const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
503 const TemplateArgument &Arg) {
504 switch (Arg.getKind()) {
505 case TemplateArgument::Null:
John McCall67c4a0c2010-08-05 04:58:04 +0000506 // This is bad, but not as bad as crashing because of argument
507 // count mismatches.
508 return DB << "(null template argument)";
Douglas Gregora9333192010-05-08 17:41:32 +0000509
510 case TemplateArgument::Type:
511 return DB << Arg.getAsType();
512
513 case TemplateArgument::Declaration:
Douglas Gregord2008e22012-04-06 22:40:38 +0000514 if (Decl *D = Arg.getAsDecl())
515 return DB << D;
516 return DB << "nullptr";
Douglas Gregora9333192010-05-08 17:41:32 +0000517
518 case TemplateArgument::Integral:
Benjamin Kramer85524372012-06-07 15:09:51 +0000519 return DB << Arg.getAsIntegral().toString(10);
Douglas Gregora9333192010-05-08 17:41:32 +0000520
521 case TemplateArgument::Template:
Douglas Gregora7fc9012011-01-05 18:58:31 +0000522 return DB << Arg.getAsTemplate();
523
524 case TemplateArgument::TemplateExpansion:
525 return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
526
Douglas Gregora9333192010-05-08 17:41:32 +0000527 case TemplateArgument::Expression: {
528 // This shouldn't actually ever happen, so it's okay that we're
529 // regurgitating an expression here.
530 // FIXME: We're guessing at LangOptions!
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000531 SmallString<32> Str;
Douglas Gregora9333192010-05-08 17:41:32 +0000532 llvm::raw_svector_ostream OS(Str);
533 LangOptions LangOpts;
534 LangOpts.CPlusPlus = true;
535 PrintingPolicy Policy(LangOpts);
536 Arg.getAsExpr()->printPretty(OS, 0, Policy);
537 return DB << OS.str();
538 }
539
Douglas Gregor87dd6972010-12-20 16:52:59 +0000540 case TemplateArgument::Pack: {
541 // FIXME: We're guessing at LangOptions!
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +0000542 SmallString<32> Str;
Douglas Gregor87dd6972010-12-20 16:52:59 +0000543 llvm::raw_svector_ostream OS(Str);
544 LangOptions LangOpts;
545 LangOpts.CPlusPlus = true;
546 PrintingPolicy Policy(LangOpts);
547 Arg.print(Policy, OS);
548 return DB << OS.str();
549 }
Douglas Gregora9333192010-05-08 17:41:32 +0000550 }
David Blaikie30263482012-01-20 21:50:17 +0000551
552 llvm_unreachable("Invalid TemplateArgument Kind!");
Douglas Gregora9333192010-05-08 17:41:32 +0000553}
Argyrios Kyrtzidis71a76052011-09-22 20:07:09 +0000554
555const ASTTemplateArgumentListInfo *
556ASTTemplateArgumentListInfo::Create(ASTContext &C,
557 const TemplateArgumentListInfo &List) {
558 std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
Abramo Bagnarae4b92762012-01-27 09:46:47 +0000559 ASTTemplateArgumentListInfo::sizeFor(List.size());
Argyrios Kyrtzidis71a76052011-09-22 20:07:09 +0000560 void *Mem = C.Allocate(size, llvm::alignOf<ASTTemplateArgumentListInfo>());
561 ASTTemplateArgumentListInfo *TAI = new (Mem) ASTTemplateArgumentListInfo();
562 TAI->initializeFrom(List);
563 return TAI;
564}
565
566void ASTTemplateArgumentListInfo::initializeFrom(
567 const TemplateArgumentListInfo &Info) {
568 LAngleLoc = Info.getLAngleLoc();
569 RAngleLoc = Info.getRAngleLoc();
570 NumTemplateArgs = Info.size();
571
572 TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
573 for (unsigned i = 0; i != NumTemplateArgs; ++i)
574 new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
575}
576
577void ASTTemplateArgumentListInfo::initializeFrom(
578 const TemplateArgumentListInfo &Info,
579 bool &Dependent,
580 bool &InstantiationDependent,
581 bool &ContainsUnexpandedParameterPack) {
582 LAngleLoc = Info.getLAngleLoc();
583 RAngleLoc = Info.getRAngleLoc();
584 NumTemplateArgs = Info.size();
585
586 TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
587 for (unsigned i = 0; i != NumTemplateArgs; ++i) {
588 Dependent = Dependent || Info[i].getArgument().isDependent();
589 InstantiationDependent = InstantiationDependent ||
590 Info[i].getArgument().isInstantiationDependent();
591 ContainsUnexpandedParameterPack
592 = ContainsUnexpandedParameterPack ||
593 Info[i].getArgument().containsUnexpandedParameterPack();
594
595 new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
596 }
597}
598
599void ASTTemplateArgumentListInfo::copyInto(
600 TemplateArgumentListInfo &Info) const {
601 Info.setLAngleLoc(LAngleLoc);
602 Info.setRAngleLoc(RAngleLoc);
603 for (unsigned I = 0; I != NumTemplateArgs; ++I)
604 Info.addArgument(getTemplateArgs()[I]);
605}
606
607std::size_t ASTTemplateArgumentListInfo::sizeFor(unsigned NumTemplateArgs) {
608 return sizeof(ASTTemplateArgumentListInfo) +
609 sizeof(TemplateArgumentLoc) * NumTemplateArgs;
610}
611
Abramo Bagnarae4b92762012-01-27 09:46:47 +0000612void
613ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc,
614 const TemplateArgumentListInfo &Info) {
615 Base::initializeFrom(Info);
616 setTemplateKeywordLoc(TemplateKWLoc);
Argyrios Kyrtzidis71a76052011-09-22 20:07:09 +0000617}
Abramo Bagnarae4b92762012-01-27 09:46:47 +0000618
619void
620ASTTemplateKWAndArgsInfo
621::initializeFrom(SourceLocation TemplateKWLoc,
622 const TemplateArgumentListInfo &Info,
623 bool &Dependent,
624 bool &InstantiationDependent,
625 bool &ContainsUnexpandedParameterPack) {
626 Base::initializeFrom(Info, Dependent, InstantiationDependent,
627 ContainsUnexpandedParameterPack);
628 setTemplateKeywordLoc(TemplateKWLoc);
629}
630
631void
632ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
633 // No explicit template arguments, but template keyword loc is valid.
634 assert(TemplateKWLoc.isValid());
635 LAngleLoc = SourceLocation();
636 RAngleLoc = SourceLocation();
637 NumTemplateArgs = 0;
638 setTemplateKeywordLoc(TemplateKWLoc);
639}
640
641std::size_t
642ASTTemplateKWAndArgsInfo::sizeFor(unsigned NumTemplateArgs) {
643 // Add space for the template keyword location.
644 return Base::sizeFor(NumTemplateArgs) + sizeof(SourceLocation);
645}
646