1 //===--- 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
15 #include "clang/AST/TemplateBase.h"
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/DeclBase.h"
18 #include "clang/AST/DeclTemplate.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/AST/ExprCXX.h"
21 #include "clang/AST/Type.h"
22 #include "clang/AST/TypeLoc.h"
23 #include "clang/Basic/Diagnostic.h"
24 #include "llvm/ADT/FoldingSet.h"
25 #include <algorithm>
26 #include <cctype>
27
28 using namespace clang;
29
30 /// \brief Print a template integral argument value.
31 ///
32 /// \param TemplArg the TemplateArgument instance to print.
33 ///
34 /// \param Out the raw_ostream instance to use for printing.
printIntegral(const TemplateArgument & TemplArg,llvm::raw_ostream & Out)35 static void printIntegral(const TemplateArgument &TemplArg,
36 llvm::raw_ostream &Out) {
37 const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr();
38 const llvm::APSInt *Val = TemplArg.getAsIntegral();
39
40 if (T->isBooleanType()) {
41 Out << (Val->getBoolValue() ? "true" : "false");
42 } else if (T->isCharType()) {
43 const unsigned char Ch = Val->getZExtValue();
44 const std::string Str(1, Ch);
45 Out << ((Ch == '\'') ? "'\\" : "'");
46 Out.write_escaped(Str, /*UseHexEscapes=*/ true);
47 Out << "'";
48 } else {
49 Out << Val->toString(10);
50 }
51 }
52
53 //===----------------------------------------------------------------------===//
54 // TemplateArgument Implementation
55 //===----------------------------------------------------------------------===//
56
CreatePackCopy(ASTContext & Context,const TemplateArgument * Args,unsigned NumArgs)57 TemplateArgument TemplateArgument::CreatePackCopy(ASTContext &Context,
58 const TemplateArgument *Args,
59 unsigned NumArgs) {
60 if (NumArgs == 0)
61 return TemplateArgument(0, 0);
62
63 TemplateArgument *Storage = new (Context) TemplateArgument [NumArgs];
64 std::copy(Args, Args + NumArgs, Storage);
65 return TemplateArgument(Storage, NumArgs);
66 }
67
isDependent() const68 bool TemplateArgument::isDependent() const {
69 switch (getKind()) {
70 case Null:
71 assert(false && "Should not have a NULL template argument");
72 return false;
73
74 case Type:
75 return getAsType()->isDependentType();
76
77 case Template:
78 return getAsTemplate().isDependent();
79
80 case TemplateExpansion:
81 return true;
82
83 case Declaration:
84 if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
85 return DC->isDependentContext();
86 return getAsDecl()->getDeclContext()->isDependentContext();
87
88 case Integral:
89 // Never dependent
90 return false;
91
92 case Expression:
93 return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent());
94
95 case Pack:
96 for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
97 if (P->isDependent())
98 return true;
99 }
100
101 return false;
102 }
103
104 return false;
105 }
106
isInstantiationDependent() const107 bool TemplateArgument::isInstantiationDependent() const {
108 switch (getKind()) {
109 case Null:
110 assert(false && "Should not have a NULL template argument");
111 return false;
112
113 case Type:
114 return getAsType()->isInstantiationDependentType();
115
116 case Template:
117 return getAsTemplate().isInstantiationDependent();
118
119 case TemplateExpansion:
120 return true;
121
122 case Declaration:
123 if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
124 return DC->isDependentContext();
125 return getAsDecl()->getDeclContext()->isDependentContext();
126
127 case Integral:
128 // Never dependent
129 return false;
130
131 case Expression:
132 return getAsExpr()->isInstantiationDependent();
133
134 case Pack:
135 for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
136 if (P->isInstantiationDependent())
137 return true;
138 }
139
140 return false;
141 }
142
143 return false;
144 }
145
isPackExpansion() const146 bool TemplateArgument::isPackExpansion() const {
147 switch (getKind()) {
148 case Null:
149 case Declaration:
150 case Integral:
151 case Pack:
152 case Template:
153 return false;
154
155 case TemplateExpansion:
156 return true;
157
158 case Type:
159 return isa<PackExpansionType>(getAsType());
160
161 case Expression:
162 return isa<PackExpansionExpr>(getAsExpr());
163 }
164
165 return false;
166 }
167
containsUnexpandedParameterPack() const168 bool TemplateArgument::containsUnexpandedParameterPack() const {
169 switch (getKind()) {
170 case Null:
171 case Declaration:
172 case Integral:
173 case TemplateExpansion:
174 break;
175
176 case Type:
177 if (getAsType()->containsUnexpandedParameterPack())
178 return true;
179 break;
180
181 case Template:
182 if (getAsTemplate().containsUnexpandedParameterPack())
183 return true;
184 break;
185
186 case Expression:
187 if (getAsExpr()->containsUnexpandedParameterPack())
188 return true;
189 break;
190
191 case Pack:
192 for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P)
193 if (P->containsUnexpandedParameterPack())
194 return true;
195
196 break;
197 }
198
199 return false;
200 }
201
getNumTemplateExpansions() const202 llvm::Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
203 assert(Kind == TemplateExpansion);
204 if (TemplateArg.NumExpansions)
205 return TemplateArg.NumExpansions - 1;
206
207 return llvm::Optional<unsigned>();
208 }
209
Profile(llvm::FoldingSetNodeID & ID,const ASTContext & Context) const210 void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
211 const ASTContext &Context) const {
212 ID.AddInteger(Kind);
213 switch (Kind) {
214 case Null:
215 break;
216
217 case Type:
218 getAsType().Profile(ID);
219 break;
220
221 case Declaration:
222 ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
223 break;
224
225 case Template:
226 case TemplateExpansion: {
227 TemplateName Template = getAsTemplateOrTemplatePattern();
228 if (TemplateTemplateParmDecl *TTP
229 = dyn_cast_or_null<TemplateTemplateParmDecl>(
230 Template.getAsTemplateDecl())) {
231 ID.AddBoolean(true);
232 ID.AddInteger(TTP->getDepth());
233 ID.AddInteger(TTP->getPosition());
234 ID.AddBoolean(TTP->isParameterPack());
235 } else {
236 ID.AddBoolean(false);
237 ID.AddPointer(Context.getCanonicalTemplateName(Template)
238 .getAsVoidPointer());
239 }
240 break;
241 }
242
243 case Integral:
244 getAsIntegral()->Profile(ID);
245 getIntegralType().Profile(ID);
246 break;
247
248 case Expression:
249 getAsExpr()->Profile(ID, Context, true);
250 break;
251
252 case Pack:
253 ID.AddInteger(Args.NumArgs);
254 for (unsigned I = 0; I != Args.NumArgs; ++I)
255 Args.Args[I].Profile(ID, Context);
256 }
257 }
258
structurallyEquals(const TemplateArgument & Other) const259 bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
260 if (getKind() != Other.getKind()) return false;
261
262 switch (getKind()) {
263 case Null:
264 case Type:
265 case Declaration:
266 case Expression:
267 case Template:
268 case TemplateExpansion:
269 return TypeOrValue == Other.TypeOrValue;
270
271 case Integral:
272 return getIntegralType() == Other.getIntegralType() &&
273 *getAsIntegral() == *Other.getAsIntegral();
274
275 case Pack:
276 if (Args.NumArgs != Other.Args.NumArgs) return false;
277 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
278 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
279 return false;
280 return true;
281 }
282
283 // Suppress warnings.
284 return false;
285 }
286
getPackExpansionPattern() const287 TemplateArgument TemplateArgument::getPackExpansionPattern() const {
288 assert(isPackExpansion());
289
290 switch (getKind()) {
291 case Type:
292 return getAsType()->getAs<PackExpansionType>()->getPattern();
293
294 case Expression:
295 return cast<PackExpansionExpr>(getAsExpr())->getPattern();
296
297 case TemplateExpansion:
298 return TemplateArgument(getAsTemplateOrTemplatePattern());
299
300 case Declaration:
301 case Integral:
302 case Pack:
303 case Null:
304 case Template:
305 return TemplateArgument();
306 }
307
308 return TemplateArgument();
309 }
310
print(const PrintingPolicy & Policy,llvm::raw_ostream & Out) const311 void TemplateArgument::print(const PrintingPolicy &Policy,
312 llvm::raw_ostream &Out) const {
313 switch (getKind()) {
314 case Null:
315 Out << "<no value>";
316 break;
317
318 case Type: {
319 PrintingPolicy SubPolicy(Policy);
320 SubPolicy.SuppressStrongLifetime = true;
321 std::string TypeStr;
322 getAsType().getAsStringInternal(TypeStr, SubPolicy);
323 Out << TypeStr;
324 break;
325 }
326
327 case Declaration: {
328 bool Unnamed = true;
329 if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getAsDecl())) {
330 if (ND->getDeclName()) {
331 Unnamed = false;
332 Out << ND->getNameAsString();
333 }
334 }
335
336 if (Unnamed) {
337 Out << "<anonymous>";
338 }
339 break;
340 }
341
342 case Template:
343 getAsTemplate().print(Out, Policy);
344 break;
345
346 case TemplateExpansion:
347 getAsTemplateOrTemplatePattern().print(Out, Policy);
348 Out << "...";
349 break;
350
351 case Integral: {
352 printIntegral(*this, Out);
353 break;
354 }
355
356 case Expression:
357 getAsExpr()->printPretty(Out, 0, Policy);
358 break;
359
360 case Pack:
361 Out << "<";
362 bool First = true;
363 for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end();
364 P != PEnd; ++P) {
365 if (First)
366 First = false;
367 else
368 Out << ", ";
369
370 P->print(Policy, Out);
371 }
372 Out << ">";
373 break;
374 }
375 }
376
377 //===----------------------------------------------------------------------===//
378 // TemplateArgumentLoc Implementation
379 //===----------------------------------------------------------------------===//
380
TemplateArgumentLocInfo()381 TemplateArgumentLocInfo::TemplateArgumentLocInfo() {
382 memset((void*)this, 0, sizeof(TemplateArgumentLocInfo));
383 }
384
getSourceRange() const385 SourceRange TemplateArgumentLoc::getSourceRange() const {
386 switch (Argument.getKind()) {
387 case TemplateArgument::Expression:
388 return getSourceExpression()->getSourceRange();
389
390 case TemplateArgument::Declaration:
391 return getSourceDeclExpression()->getSourceRange();
392
393 case TemplateArgument::Type:
394 if (TypeSourceInfo *TSI = getTypeSourceInfo())
395 return TSI->getTypeLoc().getSourceRange();
396 else
397 return SourceRange();
398
399 case TemplateArgument::Template:
400 if (getTemplateQualifierLoc())
401 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
402 getTemplateNameLoc());
403 return SourceRange(getTemplateNameLoc());
404
405 case TemplateArgument::TemplateExpansion:
406 if (getTemplateQualifierLoc())
407 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
408 getTemplateEllipsisLoc());
409 return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
410
411 case TemplateArgument::Integral:
412 case TemplateArgument::Pack:
413 case TemplateArgument::Null:
414 return SourceRange();
415 }
416
417 // Silence bonus gcc warning.
418 return SourceRange();
419 }
420
421 TemplateArgumentLoc
getPackExpansionPattern(SourceLocation & Ellipsis,llvm::Optional<unsigned> & NumExpansions,ASTContext & Context) const422 TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis,
423 llvm::Optional<unsigned> &NumExpansions,
424 ASTContext &Context) const {
425 assert(Argument.isPackExpansion());
426
427 switch (Argument.getKind()) {
428 case TemplateArgument::Type: {
429 // FIXME: We shouldn't ever have to worry about missing
430 // type-source info!
431 TypeSourceInfo *ExpansionTSInfo = getTypeSourceInfo();
432 if (!ExpansionTSInfo)
433 ExpansionTSInfo = Context.getTrivialTypeSourceInfo(
434 getArgument().getAsType(),
435 Ellipsis);
436 PackExpansionTypeLoc Expansion
437 = cast<PackExpansionTypeLoc>(ExpansionTSInfo->getTypeLoc());
438 Ellipsis = Expansion.getEllipsisLoc();
439
440 TypeLoc Pattern = Expansion.getPatternLoc();
441 NumExpansions = Expansion.getTypePtr()->getNumExpansions();
442
443 // FIXME: This is horrible. We know where the source location data is for
444 // the pattern, and we have the pattern's type, but we are forced to copy
445 // them into an ASTContext because TypeSourceInfo bundles them together
446 // and TemplateArgumentLoc traffics in TypeSourceInfo pointers.
447 TypeSourceInfo *PatternTSInfo
448 = Context.CreateTypeSourceInfo(Pattern.getType(),
449 Pattern.getFullDataSize());
450 memcpy(PatternTSInfo->getTypeLoc().getOpaqueData(),
451 Pattern.getOpaqueData(), Pattern.getFullDataSize());
452 return TemplateArgumentLoc(TemplateArgument(Pattern.getType()),
453 PatternTSInfo);
454 }
455
456 case TemplateArgument::Expression: {
457 PackExpansionExpr *Expansion
458 = cast<PackExpansionExpr>(Argument.getAsExpr());
459 Expr *Pattern = Expansion->getPattern();
460 Ellipsis = Expansion->getEllipsisLoc();
461 NumExpansions = Expansion->getNumExpansions();
462 return TemplateArgumentLoc(Pattern, Pattern);
463 }
464
465 case TemplateArgument::TemplateExpansion:
466 Ellipsis = getTemplateEllipsisLoc();
467 NumExpansions = Argument.getNumTemplateExpansions();
468 return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
469 getTemplateQualifierLoc(),
470 getTemplateNameLoc());
471
472 case TemplateArgument::Declaration:
473 case TemplateArgument::Template:
474 case TemplateArgument::Integral:
475 case TemplateArgument::Pack:
476 case TemplateArgument::Null:
477 return TemplateArgumentLoc();
478 }
479
480 return TemplateArgumentLoc();
481 }
482
operator <<(const DiagnosticBuilder & DB,const TemplateArgument & Arg)483 const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
484 const TemplateArgument &Arg) {
485 switch (Arg.getKind()) {
486 case TemplateArgument::Null:
487 // This is bad, but not as bad as crashing because of argument
488 // count mismatches.
489 return DB << "(null template argument)";
490
491 case TemplateArgument::Type:
492 return DB << Arg.getAsType();
493
494 case TemplateArgument::Declaration:
495 return DB << Arg.getAsDecl();
496
497 case TemplateArgument::Integral:
498 return DB << Arg.getAsIntegral()->toString(10);
499
500 case TemplateArgument::Template:
501 return DB << Arg.getAsTemplate();
502
503 case TemplateArgument::TemplateExpansion:
504 return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
505
506 case TemplateArgument::Expression: {
507 // This shouldn't actually ever happen, so it's okay that we're
508 // regurgitating an expression here.
509 // FIXME: We're guessing at LangOptions!
510 llvm::SmallString<32> Str;
511 llvm::raw_svector_ostream OS(Str);
512 LangOptions LangOpts;
513 LangOpts.CPlusPlus = true;
514 PrintingPolicy Policy(LangOpts);
515 Arg.getAsExpr()->printPretty(OS, 0, Policy);
516 return DB << OS.str();
517 }
518
519 case TemplateArgument::Pack: {
520 // FIXME: We're guessing at LangOptions!
521 llvm::SmallString<32> Str;
522 llvm::raw_svector_ostream OS(Str);
523 LangOptions LangOpts;
524 LangOpts.CPlusPlus = true;
525 PrintingPolicy Policy(LangOpts);
526 Arg.print(Policy, OS);
527 return DB << OS.str();
528 }
529 }
530
531 return DB;
532 }
533