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