blob: 68e23323cef984f0b0d5b6cc8d3d606731f4663d [file] [log] [blame]
John McCall588d2d52009-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 McCall588d2d52009-10-29 07:48:15 +000015#include "clang/AST/TemplateBase.h"
Douglas Gregor0192c232010-12-20 16:52:59 +000016#include "clang/AST/ASTContext.h"
John McCall588d2d52009-10-29 07:48:15 +000017#include "clang/AST/DeclBase.h"
Douglas Gregorbd866c22009-11-23 12:52:47 +000018#include "clang/AST/DeclTemplate.h"
John McCall588d2d52009-10-29 07:48:15 +000019#include "clang/AST/Expr.h"
Douglas Gregore8e9dd62011-01-03 17:17:50 +000020#include "clang/AST/ExprCXX.h"
John McCall0ad16662009-10-29 08:12:44 +000021#include "clang/AST/TypeLoc.h"
Douglas Gregor3626a5c2010-05-08 17:41:32 +000022#include "clang/Basic/Diagnostic.h"
Douglas Gregor0192c232010-12-20 16:52:59 +000023#include "llvm/ADT/FoldingSet.h"
John McCall588d2d52009-10-29 07:48:15 +000024
25using namespace clang;
26
27//===----------------------------------------------------------------------===//
28// TemplateArgument Implementation
29//===----------------------------------------------------------------------===//
30
Douglas Gregora6e053e2010-12-15 01:34:56 +000031bool TemplateArgument::isDependent() const {
32 switch (getKind()) {
33 case Null:
34 assert(false && "Should not have a NULL template argument");
35 return false;
36
37 case Type:
38 return getAsType()->isDependentType();
39
40 case Template:
41 return getAsTemplate().isDependent();
Douglas Gregore4ff4b52011-01-05 18:58:31 +000042
43 case TemplateExpansion:
44 return true;
45
Douglas Gregora6e053e2010-12-15 01:34:56 +000046 case Declaration:
47 if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
48 return DC->isDependentContext();
49 return getAsDecl()->getDeclContext()->isDependentContext();
50
51 case Integral:
52 // Never dependent
53 return false;
54
55 case Expression:
56 return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent());
57
58 case Pack:
59 for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
60 if (P->isDependent())
61 return true;
62 }
63
64 return false;
65 }
66
67 return false;
68}
69
Douglas Gregor840bd6c2010-12-20 22:05:00 +000070bool TemplateArgument::isPackExpansion() const {
71 switch (getKind()) {
72 case Null:
73 case Declaration:
74 case Integral:
75 case Pack:
Douglas Gregore4ff4b52011-01-05 18:58:31 +000076 case Template:
Douglas Gregor840bd6c2010-12-20 22:05:00 +000077 return false;
78
Douglas Gregore4ff4b52011-01-05 18:58:31 +000079 case TemplateExpansion:
80 return true;
81
Douglas Gregor840bd6c2010-12-20 22:05:00 +000082 case Type:
Douglas Gregore8e9dd62011-01-03 17:17:50 +000083 return isa<PackExpansionType>(getAsType());
Douglas Gregore4ff4b52011-01-05 18:58:31 +000084
Douglas Gregor840bd6c2010-12-20 22:05:00 +000085 case Expression:
Douglas Gregore8e9dd62011-01-03 17:17:50 +000086 return isa<PackExpansionExpr>(getAsExpr());
Douglas Gregor840bd6c2010-12-20 22:05:00 +000087 }
88
89 return false;
90}
91
Douglas Gregor506bd562010-12-13 22:49:22 +000092bool TemplateArgument::containsUnexpandedParameterPack() const {
93 switch (getKind()) {
94 case Null:
95 case Declaration:
96 case Integral:
Douglas Gregore4ff4b52011-01-05 18:58:31 +000097 case TemplateExpansion:
Douglas Gregor506bd562010-12-13 22:49:22 +000098 break;
99
100 case Type:
101 if (getAsType()->containsUnexpandedParameterPack())
102 return true;
103 break;
104
105 case Template:
Douglas Gregore4ff4b52011-01-05 18:58:31 +0000106 if (getAsTemplate().containsUnexpandedParameterPack())
Douglas Gregor506bd562010-12-13 22:49:22 +0000107 return true;
108 break;
109
110 case Expression:
111 if (getAsExpr()->containsUnexpandedParameterPack())
112 return true;
113 break;
114
115 case Pack:
116 for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P)
117 if (P->containsUnexpandedParameterPack())
118 return true;
119
120 break;
121 }
122
123 return false;
124}
125
John McCall588d2d52009-10-29 07:48:15 +0000126void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
127 ASTContext &Context) const {
128 ID.AddInteger(Kind);
129 switch (Kind) {
130 case Null:
131 break;
132
133 case Type:
134 getAsType().Profile(ID);
135 break;
136
137 case Declaration:
138 ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
139 break;
140
Douglas Gregor9167f8b2009-11-11 01:00:40 +0000141 case Template:
Douglas Gregore4ff4b52011-01-05 18:58:31 +0000142 case TemplateExpansion: {
143 TemplateName Template = getAsTemplateOrTemplatePattern();
Douglas Gregorbd866c22009-11-23 12:52:47 +0000144 if (TemplateTemplateParmDecl *TTP
145 = dyn_cast_or_null<TemplateTemplateParmDecl>(
Douglas Gregore4ff4b52011-01-05 18:58:31 +0000146 Template.getAsTemplateDecl())) {
Douglas Gregorbd866c22009-11-23 12:52:47 +0000147 ID.AddBoolean(true);
148 ID.AddInteger(TTP->getDepth());
149 ID.AddInteger(TTP->getPosition());
Douglas Gregoreb29d182011-01-05 17:40:24 +0000150 ID.AddBoolean(TTP->isParameterPack());
Douglas Gregorbd866c22009-11-23 12:52:47 +0000151 } else {
152 ID.AddBoolean(false);
Douglas Gregore4ff4b52011-01-05 18:58:31 +0000153 ID.AddPointer(Context.getCanonicalTemplateName(Template)
154 .getAsVoidPointer());
Douglas Gregorbd866c22009-11-23 12:52:47 +0000155 }
Douglas Gregor9167f8b2009-11-11 01:00:40 +0000156 break;
Douglas Gregore4ff4b52011-01-05 18:58:31 +0000157 }
Douglas Gregor9167f8b2009-11-11 01:00:40 +0000158
John McCall588d2d52009-10-29 07:48:15 +0000159 case Integral:
160 getAsIntegral()->Profile(ID);
161 getIntegralType().Profile(ID);
162 break;
163
164 case Expression:
165 getAsExpr()->Profile(ID, Context, true);
166 break;
167
168 case Pack:
169 ID.AddInteger(Args.NumArgs);
170 for (unsigned I = 0; I != Args.NumArgs; ++I)
171 Args.Args[I].Profile(ID, Context);
172 }
173}
John McCall0ad16662009-10-29 08:12:44 +0000174
John McCallc392f372010-06-11 00:33:02 +0000175bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
176 if (getKind() != Other.getKind()) return false;
177
178 switch (getKind()) {
179 case Null:
180 case Type:
181 case Declaration:
Douglas Gregore4ff4b52011-01-05 18:58:31 +0000182 case Expression:
183 case Template:
184 case TemplateExpansion:
John McCallc392f372010-06-11 00:33:02 +0000185 return TypeOrValue == Other.TypeOrValue;
186
187 case Integral:
188 return getIntegralType() == Other.getIntegralType() &&
189 *getAsIntegral() == *Other.getAsIntegral();
190
191 case Pack:
192 if (Args.NumArgs != Other.Args.NumArgs) return false;
193 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
194 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
195 return false;
196 return true;
197 }
198
199 // Suppress warnings.
200 return false;
201}
202
Douglas Gregor0f3feb42010-12-22 21:19:48 +0000203TemplateArgument TemplateArgument::getPackExpansionPattern() const {
204 assert(isPackExpansion());
205
206 switch (getKind()) {
Douglas Gregoreb29d182011-01-05 17:40:24 +0000207 case Type:
208 return getAsType()->getAs<PackExpansionType>()->getPattern();
209
210 case Expression:
211 return cast<PackExpansionExpr>(getAsExpr())->getPattern();
212
Douglas Gregore4ff4b52011-01-05 18:58:31 +0000213 case TemplateExpansion:
214 return TemplateArgument(getAsTemplateOrTemplatePattern(), false);
Douglas Gregoreb29d182011-01-05 17:40:24 +0000215
216 case Declaration:
217 case Integral:
218 case Pack:
219 case Null:
Douglas Gregore4ff4b52011-01-05 18:58:31 +0000220 case Template:
Douglas Gregoreb29d182011-01-05 17:40:24 +0000221 return TemplateArgument();
Douglas Gregor0f3feb42010-12-22 21:19:48 +0000222 }
223
224 return TemplateArgument();
225}
226
Douglas Gregor0192c232010-12-20 16:52:59 +0000227void TemplateArgument::print(const PrintingPolicy &Policy,
228 llvm::raw_ostream &Out) const {
229 switch (getKind()) {
230 case Null:
231 Out << "<no value>";
232 break;
233
234 case Type: {
235 std::string TypeStr;
236 getAsType().getAsStringInternal(TypeStr, Policy);
237 Out << TypeStr;
238 break;
239 }
240
241 case Declaration: {
242 bool Unnamed = true;
243 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getAsDecl())) {
244 if (ND->getDeclName()) {
245 Unnamed = false;
246 Out << ND->getNameAsString();
247 }
248 }
249
250 if (Unnamed) {
251 Out << "<anonymous>";
252 }
253 break;
254 }
255
Douglas Gregore4ff4b52011-01-05 18:58:31 +0000256 case Template:
Douglas Gregor0192c232010-12-20 16:52:59 +0000257 getAsTemplate().print(Out, Policy);
258 break;
Douglas Gregore4ff4b52011-01-05 18:58:31 +0000259
260 case TemplateExpansion:
261 getAsTemplateOrTemplatePattern().print(Out, Policy);
262 Out << "...";
263 break;
264
Douglas Gregor0192c232010-12-20 16:52:59 +0000265 case Integral: {
266 Out << getAsIntegral()->toString(10);
267 break;
268 }
269
Douglas Gregoreb29d182011-01-05 17:40:24 +0000270 case Expression:
Douglas Gregor0192c232010-12-20 16:52:59 +0000271 getAsExpr()->printPretty(Out, 0, Policy);
272 break;
Douglas Gregor0192c232010-12-20 16:52:59 +0000273
274 case Pack:
275 Out << "<";
276 bool First = true;
277 for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end();
278 P != PEnd; ++P) {
279 if (First)
280 First = false;
281 else
282 Out << ", ";
283
284 P->print(Policy, Out);
285 }
286 Out << ">";
287 break;
288 }
289}
290
John McCall0ad16662009-10-29 08:12:44 +0000291//===----------------------------------------------------------------------===//
292// TemplateArgumentLoc Implementation
293//===----------------------------------------------------------------------===//
294
Douglas Gregordf50b842011-01-06 00:33:28 +0000295TemplateArgumentLocInfo::TemplateArgumentLocInfo() {
296 memset(this, 0, sizeof(TemplateArgumentLocInfo));
297}
298
John McCall0d07eb32009-10-29 18:45:58 +0000299SourceRange TemplateArgumentLoc::getSourceRange() const {
John McCall0ad16662009-10-29 08:12:44 +0000300 switch (Argument.getKind()) {
301 case TemplateArgument::Expression:
John McCall0d07eb32009-10-29 18:45:58 +0000302 return getSourceExpression()->getSourceRange();
Zhanyong Wan18ca8bf2010-09-03 23:50:56 +0000303
John McCall0ad16662009-10-29 08:12:44 +0000304 case TemplateArgument::Declaration:
John McCall0d07eb32009-10-29 18:45:58 +0000305 return getSourceDeclExpression()->getSourceRange();
Zhanyong Wan18ca8bf2010-09-03 23:50:56 +0000306
John McCall0d07eb32009-10-29 18:45:58 +0000307 case TemplateArgument::Type:
Zhanyong Wan18ca8bf2010-09-03 23:50:56 +0000308 if (TypeSourceInfo *TSI = getTypeSourceInfo())
309 return TSI->getTypeLoc().getSourceRange();
310 else
311 return SourceRange();
312
Douglas Gregore4ff4b52011-01-05 18:58:31 +0000313 case TemplateArgument::Template:
Douglas Gregor9167f8b2009-11-11 01:00:40 +0000314 if (getTemplateQualifierRange().isValid())
Douglas Gregore4ff4b52011-01-05 18:58:31 +0000315 return SourceRange(getTemplateQualifierRange().getBegin(),
316 getTemplateNameLoc());
317 return SourceRange(getTemplateNameLoc());
318
319 case TemplateArgument::TemplateExpansion:
320 if (getTemplateQualifierRange().isValid())
321 return SourceRange(getTemplateQualifierRange().getBegin(),
322 getTemplateEllipsisLoc());
323 return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
324
John McCall0ad16662009-10-29 08:12:44 +0000325 case TemplateArgument::Integral:
326 case TemplateArgument::Pack:
327 case TemplateArgument::Null:
John McCall0d07eb32009-10-29 18:45:58 +0000328 return SourceRange();
John McCall0ad16662009-10-29 08:12:44 +0000329 }
330
331 // Silence bonus gcc warning.
John McCall0d07eb32009-10-29 18:45:58 +0000332 return SourceRange();
John McCall0ad16662009-10-29 08:12:44 +0000333}
Douglas Gregor3626a5c2010-05-08 17:41:32 +0000334
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000335TemplateArgumentLoc
336TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis,
337 ASTContext &Context) const {
338 assert(Argument.isPackExpansion());
339
340 switch (Argument.getKind()) {
341 case TemplateArgument::Type: {
Douglas Gregor08f4e802010-12-21 22:10:26 +0000342 // FIXME: We shouldn't ever have to worry about missing
343 // type-source info!
344 TypeSourceInfo *ExpansionTSInfo = getTypeSourceInfo();
345 if (!ExpansionTSInfo)
346 ExpansionTSInfo = Context.getTrivialTypeSourceInfo(
347 getArgument().getAsType(),
348 Ellipsis);
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000349 PackExpansionTypeLoc Expansion
Douglas Gregor08f4e802010-12-21 22:10:26 +0000350 = cast<PackExpansionTypeLoc>(ExpansionTSInfo->getTypeLoc());
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000351 Ellipsis = Expansion.getEllipsisLoc();
352
353 TypeLoc Pattern = Expansion.getPatternLoc();
354
355 // FIXME: This is horrible. We know where the source location data is for
356 // the pattern, and we have the pattern's type, but we are forced to copy
357 // them into an ASTContext because TypeSourceInfo bundles them together
358 // and TemplateArgumentLoc traffics in TypeSourceInfo pointers.
359 TypeSourceInfo *PatternTSInfo
360 = Context.CreateTypeSourceInfo(Pattern.getType(),
361 Pattern.getFullDataSize());
362 memcpy(PatternTSInfo->getTypeLoc().getOpaqueData(),
363 Pattern.getOpaqueData(), Pattern.getFullDataSize());
364 return TemplateArgumentLoc(TemplateArgument(Pattern.getType()),
365 PatternTSInfo);
366 }
367
Douglas Gregore8e9dd62011-01-03 17:17:50 +0000368 case TemplateArgument::Expression: {
Douglas Gregordf50b842011-01-06 00:33:28 +0000369 PackExpansionExpr *Expansion
370 = cast<PackExpansionExpr>(Argument.getAsExpr());
371 Expr *Pattern = Expansion->getPattern();
372 Ellipsis = Expansion->getEllipsisLoc();
Douglas Gregore8e9dd62011-01-03 17:17:50 +0000373 return TemplateArgumentLoc(Pattern, Pattern);
374 }
Douglas Gregore4ff4b52011-01-05 18:58:31 +0000375
376 case TemplateArgument::TemplateExpansion:
Douglas Gregordf50b842011-01-06 00:33:28 +0000377 Ellipsis = getTemplateEllipsisLoc();
Douglas Gregoreb29d182011-01-05 17:40:24 +0000378 return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
379 getTemplateQualifierRange(),
380 getTemplateNameLoc());
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000381
382 case TemplateArgument::Declaration:
Douglas Gregore4ff4b52011-01-05 18:58:31 +0000383 case TemplateArgument::Template:
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000384 case TemplateArgument::Integral:
385 case TemplateArgument::Pack:
386 case TemplateArgument::Null:
387 return TemplateArgumentLoc();
388 }
389
390 return TemplateArgumentLoc();
391}
392
Douglas Gregor3626a5c2010-05-08 17:41:32 +0000393const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
394 const TemplateArgument &Arg) {
395 switch (Arg.getKind()) {
396 case TemplateArgument::Null:
John McCall3b3a5ed2010-08-05 04:58:04 +0000397 // This is bad, but not as bad as crashing because of argument
398 // count mismatches.
399 return DB << "(null template argument)";
Douglas Gregor3626a5c2010-05-08 17:41:32 +0000400
401 case TemplateArgument::Type:
402 return DB << Arg.getAsType();
403
404 case TemplateArgument::Declaration:
405 return DB << Arg.getAsDecl();
406
407 case TemplateArgument::Integral:
408 return DB << Arg.getAsIntegral()->toString(10);
409
410 case TemplateArgument::Template:
Douglas Gregore4ff4b52011-01-05 18:58:31 +0000411 return DB << Arg.getAsTemplate();
412
413 case TemplateArgument::TemplateExpansion:
414 return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
415
Douglas Gregor3626a5c2010-05-08 17:41:32 +0000416 case TemplateArgument::Expression: {
417 // This shouldn't actually ever happen, so it's okay that we're
418 // regurgitating an expression here.
419 // FIXME: We're guessing at LangOptions!
420 llvm::SmallString<32> Str;
421 llvm::raw_svector_ostream OS(Str);
422 LangOptions LangOpts;
423 LangOpts.CPlusPlus = true;
424 PrintingPolicy Policy(LangOpts);
425 Arg.getAsExpr()->printPretty(OS, 0, Policy);
426 return DB << OS.str();
427 }
428
Douglas Gregor0192c232010-12-20 16:52:59 +0000429 case TemplateArgument::Pack: {
430 // FIXME: We're guessing at LangOptions!
431 llvm::SmallString<32> Str;
432 llvm::raw_svector_ostream OS(Str);
433 LangOptions LangOpts;
434 LangOpts.CPlusPlus = true;
435 PrintingPolicy Policy(LangOpts);
436 Arg.print(Policy, OS);
437 return DB << OS.str();
438 }
Douglas Gregor3626a5c2010-05-08 17:41:32 +0000439 }
440
441 return DB;
442}