TemplateBase.cpp revision e4b92761b43ced611c417ae478568610f1ad7b1e
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
28using 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.
35static void printIntegral(const TemplateArgument &TemplArg,
36                          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
57TemplateArgument 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
68bool TemplateArgument::isDependent() const {
69  switch (getKind()) {
70  case Null:
71    llvm_unreachable("Should not have a NULL template argument");
72
73  case Type:
74    return getAsType()->isDependentType();
75
76  case Template:
77    return getAsTemplate().isDependent();
78
79  case TemplateExpansion:
80    return true;
81
82  case Declaration:
83    if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
84      return DC->isDependentContext();
85    return getAsDecl()->getDeclContext()->isDependentContext();
86
87  case Integral:
88    // Never dependent
89    return false;
90
91  case Expression:
92    return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent());
93
94  case Pack:
95    for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
96      if (P->isDependent())
97        return true;
98    }
99
100    return false;
101  }
102
103  llvm_unreachable("Invalid TemplateArgument Kind!");
104}
105
106bool TemplateArgument::isInstantiationDependent() const {
107  switch (getKind()) {
108  case Null:
109    llvm_unreachable("Should not have a NULL template argument");
110
111  case Type:
112    return getAsType()->isInstantiationDependentType();
113
114  case Template:
115    return getAsTemplate().isInstantiationDependent();
116
117  case TemplateExpansion:
118    return true;
119
120  case Declaration:
121    if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
122      return DC->isDependentContext();
123    return getAsDecl()->getDeclContext()->isDependentContext();
124
125  case Integral:
126    // Never dependent
127    return false;
128
129  case Expression:
130    return getAsExpr()->isInstantiationDependent();
131
132  case Pack:
133    for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
134      if (P->isInstantiationDependent())
135        return true;
136    }
137
138    return false;
139  }
140
141  llvm_unreachable("Invalid TemplateArgument Kind!");
142}
143
144bool TemplateArgument::isPackExpansion() const {
145  switch (getKind()) {
146  case Null:
147  case Declaration:
148  case Integral:
149  case Pack:
150  case Template:
151    return false;
152
153  case TemplateExpansion:
154    return true;
155
156  case Type:
157    return isa<PackExpansionType>(getAsType());
158
159  case Expression:
160    return isa<PackExpansionExpr>(getAsExpr());
161  }
162
163  llvm_unreachable("Invalid TemplateArgument Kind!");
164}
165
166bool TemplateArgument::containsUnexpandedParameterPack() const {
167  switch (getKind()) {
168  case Null:
169  case Declaration:
170  case Integral:
171  case TemplateExpansion:
172    break;
173
174  case Type:
175    if (getAsType()->containsUnexpandedParameterPack())
176      return true;
177    break;
178
179  case Template:
180    if (getAsTemplate().containsUnexpandedParameterPack())
181      return true;
182    break;
183
184  case Expression:
185    if (getAsExpr()->containsUnexpandedParameterPack())
186      return true;
187    break;
188
189  case Pack:
190    for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P)
191      if (P->containsUnexpandedParameterPack())
192        return true;
193
194    break;
195  }
196
197  return false;
198}
199
200llvm::Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
201  assert(Kind == TemplateExpansion);
202  if (TemplateArg.NumExpansions)
203    return TemplateArg.NumExpansions - 1;
204
205  return llvm::Optional<unsigned>();
206}
207
208void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
209                               const ASTContext &Context) const {
210  ID.AddInteger(Kind);
211  switch (Kind) {
212  case Null:
213    break;
214
215  case Type:
216    getAsType().Profile(ID);
217    break;
218
219  case Declaration:
220    ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
221    break;
222
223  case Template:
224  case TemplateExpansion: {
225    TemplateName Template = getAsTemplateOrTemplatePattern();
226    if (TemplateTemplateParmDecl *TTP
227          = dyn_cast_or_null<TemplateTemplateParmDecl>(
228                                                Template.getAsTemplateDecl())) {
229      ID.AddBoolean(true);
230      ID.AddInteger(TTP->getDepth());
231      ID.AddInteger(TTP->getPosition());
232      ID.AddBoolean(TTP->isParameterPack());
233    } else {
234      ID.AddBoolean(false);
235      ID.AddPointer(Context.getCanonicalTemplateName(Template)
236                                                          .getAsVoidPointer());
237    }
238    break;
239  }
240
241  case Integral:
242    getAsIntegral()->Profile(ID);
243    getIntegralType().Profile(ID);
244    break;
245
246  case Expression:
247    getAsExpr()->Profile(ID, Context, true);
248    break;
249
250  case Pack:
251    ID.AddInteger(Args.NumArgs);
252    for (unsigned I = 0; I != Args.NumArgs; ++I)
253      Args.Args[I].Profile(ID, Context);
254  }
255}
256
257bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
258  if (getKind() != Other.getKind()) return false;
259
260  switch (getKind()) {
261  case Null:
262  case Type:
263  case Declaration:
264  case Expression:
265  case Template:
266  case TemplateExpansion:
267    return TypeOrValue == Other.TypeOrValue;
268
269  case Integral:
270    return getIntegralType() == Other.getIntegralType() &&
271           *getAsIntegral() == *Other.getAsIntegral();
272
273  case Pack:
274    if (Args.NumArgs != Other.Args.NumArgs) return false;
275    for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
276      if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
277        return false;
278    return true;
279  }
280
281  llvm_unreachable("Invalid TemplateArgument Kind!");
282}
283
284TemplateArgument TemplateArgument::getPackExpansionPattern() const {
285  assert(isPackExpansion());
286
287  switch (getKind()) {
288  case Type:
289    return getAsType()->getAs<PackExpansionType>()->getPattern();
290
291  case Expression:
292    return cast<PackExpansionExpr>(getAsExpr())->getPattern();
293
294  case TemplateExpansion:
295    return TemplateArgument(getAsTemplateOrTemplatePattern());
296
297  case Declaration:
298  case Integral:
299  case Pack:
300  case Null:
301  case Template:
302    return TemplateArgument();
303  }
304
305  llvm_unreachable("Invalid TemplateArgument Kind!");
306}
307
308void TemplateArgument::print(const PrintingPolicy &Policy,
309                             raw_ostream &Out) const {
310  switch (getKind()) {
311  case Null:
312    Out << "<no value>";
313    break;
314
315  case Type: {
316    PrintingPolicy SubPolicy(Policy);
317    SubPolicy.SuppressStrongLifetime = true;
318    std::string TypeStr;
319    getAsType().getAsStringInternal(TypeStr, SubPolicy);
320    Out << TypeStr;
321    break;
322  }
323
324  case Declaration: {
325    bool Unnamed = true;
326    if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getAsDecl())) {
327      if (ND->getDeclName()) {
328        Unnamed = false;
329        Out << ND->getNameAsString();
330      }
331    }
332
333    if (Unnamed) {
334      Out << "<anonymous>";
335    }
336    break;
337  }
338
339  case Template:
340    getAsTemplate().print(Out, Policy);
341    break;
342
343  case TemplateExpansion:
344    getAsTemplateOrTemplatePattern().print(Out, Policy);
345    Out << "...";
346    break;
347
348  case Integral: {
349    printIntegral(*this, Out);
350    break;
351  }
352
353  case Expression:
354    getAsExpr()->printPretty(Out, 0, Policy);
355    break;
356
357  case Pack:
358    Out << "<";
359    bool First = true;
360    for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end();
361         P != PEnd; ++P) {
362      if (First)
363        First = false;
364      else
365        Out << ", ";
366
367      P->print(Policy, Out);
368    }
369    Out << ">";
370    break;
371  }
372}
373
374//===----------------------------------------------------------------------===//
375// TemplateArgumentLoc Implementation
376//===----------------------------------------------------------------------===//
377
378TemplateArgumentLocInfo::TemplateArgumentLocInfo() {
379  memset((void*)this, 0, sizeof(TemplateArgumentLocInfo));
380}
381
382SourceRange TemplateArgumentLoc::getSourceRange() const {
383  switch (Argument.getKind()) {
384  case TemplateArgument::Expression:
385    return getSourceExpression()->getSourceRange();
386
387  case TemplateArgument::Declaration:
388    return getSourceDeclExpression()->getSourceRange();
389
390  case TemplateArgument::Type:
391    if (TypeSourceInfo *TSI = getTypeSourceInfo())
392      return TSI->getTypeLoc().getSourceRange();
393    else
394      return SourceRange();
395
396  case TemplateArgument::Template:
397    if (getTemplateQualifierLoc())
398      return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
399                         getTemplateNameLoc());
400    return SourceRange(getTemplateNameLoc());
401
402  case TemplateArgument::TemplateExpansion:
403    if (getTemplateQualifierLoc())
404      return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
405                         getTemplateEllipsisLoc());
406    return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
407
408  case TemplateArgument::Integral:
409  case TemplateArgument::Pack:
410  case TemplateArgument::Null:
411    return SourceRange();
412  }
413
414  llvm_unreachable("Invalid TemplateArgument Kind!");
415}
416
417TemplateArgumentLoc
418TemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis,
419                                       llvm::Optional<unsigned> &NumExpansions,
420                                             ASTContext &Context) const {
421  assert(Argument.isPackExpansion());
422
423  switch (Argument.getKind()) {
424  case TemplateArgument::Type: {
425    // FIXME: We shouldn't ever have to worry about missing
426    // type-source info!
427    TypeSourceInfo *ExpansionTSInfo = getTypeSourceInfo();
428    if (!ExpansionTSInfo)
429      ExpansionTSInfo = Context.getTrivialTypeSourceInfo(
430                                                     getArgument().getAsType(),
431                                                         Ellipsis);
432    PackExpansionTypeLoc Expansion
433      = cast<PackExpansionTypeLoc>(ExpansionTSInfo->getTypeLoc());
434    Ellipsis = Expansion.getEllipsisLoc();
435
436    TypeLoc Pattern = Expansion.getPatternLoc();
437    NumExpansions = Expansion.getTypePtr()->getNumExpansions();
438
439    // FIXME: This is horrible. We know where the source location data is for
440    // the pattern, and we have the pattern's type, but we are forced to copy
441    // them into an ASTContext because TypeSourceInfo bundles them together
442    // and TemplateArgumentLoc traffics in TypeSourceInfo pointers.
443    TypeSourceInfo *PatternTSInfo
444      = Context.CreateTypeSourceInfo(Pattern.getType(),
445                                     Pattern.getFullDataSize());
446    memcpy(PatternTSInfo->getTypeLoc().getOpaqueData(),
447           Pattern.getOpaqueData(), Pattern.getFullDataSize());
448    return TemplateArgumentLoc(TemplateArgument(Pattern.getType()),
449                               PatternTSInfo);
450  }
451
452  case TemplateArgument::Expression: {
453    PackExpansionExpr *Expansion
454      = cast<PackExpansionExpr>(Argument.getAsExpr());
455    Expr *Pattern = Expansion->getPattern();
456    Ellipsis = Expansion->getEllipsisLoc();
457    NumExpansions = Expansion->getNumExpansions();
458    return TemplateArgumentLoc(Pattern, Pattern);
459  }
460
461  case TemplateArgument::TemplateExpansion:
462    Ellipsis = getTemplateEllipsisLoc();
463    NumExpansions = Argument.getNumTemplateExpansions();
464    return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
465                               getTemplateQualifierLoc(),
466                               getTemplateNameLoc());
467
468  case TemplateArgument::Declaration:
469  case TemplateArgument::Template:
470  case TemplateArgument::Integral:
471  case TemplateArgument::Pack:
472  case TemplateArgument::Null:
473    return TemplateArgumentLoc();
474  }
475
476  llvm_unreachable("Invalid TemplateArgument Kind!");
477}
478
479const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
480                                           const TemplateArgument &Arg) {
481  switch (Arg.getKind()) {
482  case TemplateArgument::Null:
483    // This is bad, but not as bad as crashing because of argument
484    // count mismatches.
485    return DB << "(null template argument)";
486
487  case TemplateArgument::Type:
488    return DB << Arg.getAsType();
489
490  case TemplateArgument::Declaration:
491    return DB << Arg.getAsDecl();
492
493  case TemplateArgument::Integral:
494    return DB << Arg.getAsIntegral()->toString(10);
495
496  case TemplateArgument::Template:
497    return DB << Arg.getAsTemplate();
498
499  case TemplateArgument::TemplateExpansion:
500    return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
501
502  case TemplateArgument::Expression: {
503    // This shouldn't actually ever happen, so it's okay that we're
504    // regurgitating an expression here.
505    // FIXME: We're guessing at LangOptions!
506    llvm::SmallString<32> Str;
507    llvm::raw_svector_ostream OS(Str);
508    LangOptions LangOpts;
509    LangOpts.CPlusPlus = true;
510    PrintingPolicy Policy(LangOpts);
511    Arg.getAsExpr()->printPretty(OS, 0, Policy);
512    return DB << OS.str();
513  }
514
515  case TemplateArgument::Pack: {
516    // FIXME: We're guessing at LangOptions!
517    llvm::SmallString<32> Str;
518    llvm::raw_svector_ostream OS(Str);
519    LangOptions LangOpts;
520    LangOpts.CPlusPlus = true;
521    PrintingPolicy Policy(LangOpts);
522    Arg.print(Policy, OS);
523    return DB << OS.str();
524  }
525  }
526
527  llvm_unreachable("Invalid TemplateArgument Kind!");
528}
529
530const ASTTemplateArgumentListInfo *
531ASTTemplateArgumentListInfo::Create(ASTContext &C,
532                                    const TemplateArgumentListInfo &List) {
533  std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
534                     ASTTemplateArgumentListInfo::sizeFor(List.size());
535  void *Mem = C.Allocate(size, llvm::alignOf<ASTTemplateArgumentListInfo>());
536  ASTTemplateArgumentListInfo *TAI = new (Mem) ASTTemplateArgumentListInfo();
537  TAI->initializeFrom(List);
538  return TAI;
539}
540
541void ASTTemplateArgumentListInfo::initializeFrom(
542                                      const TemplateArgumentListInfo &Info) {
543  LAngleLoc = Info.getLAngleLoc();
544  RAngleLoc = Info.getRAngleLoc();
545  NumTemplateArgs = Info.size();
546
547  TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
548  for (unsigned i = 0; i != NumTemplateArgs; ++i)
549    new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
550}
551
552void ASTTemplateArgumentListInfo::initializeFrom(
553                                          const TemplateArgumentListInfo &Info,
554                                                  bool &Dependent,
555                                                  bool &InstantiationDependent,
556                                       bool &ContainsUnexpandedParameterPack) {
557  LAngleLoc = Info.getLAngleLoc();
558  RAngleLoc = Info.getRAngleLoc();
559  NumTemplateArgs = Info.size();
560
561  TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
562  for (unsigned i = 0; i != NumTemplateArgs; ++i) {
563    Dependent = Dependent || Info[i].getArgument().isDependent();
564    InstantiationDependent = InstantiationDependent ||
565                             Info[i].getArgument().isInstantiationDependent();
566    ContainsUnexpandedParameterPack
567      = ContainsUnexpandedParameterPack ||
568        Info[i].getArgument().containsUnexpandedParameterPack();
569
570    new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
571  }
572}
573
574void ASTTemplateArgumentListInfo::copyInto(
575                                      TemplateArgumentListInfo &Info) const {
576  Info.setLAngleLoc(LAngleLoc);
577  Info.setRAngleLoc(RAngleLoc);
578  for (unsigned I = 0; I != NumTemplateArgs; ++I)
579    Info.addArgument(getTemplateArgs()[I]);
580}
581
582std::size_t ASTTemplateArgumentListInfo::sizeFor(unsigned NumTemplateArgs) {
583  return sizeof(ASTTemplateArgumentListInfo) +
584         sizeof(TemplateArgumentLoc) * NumTemplateArgs;
585}
586
587void
588ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc,
589                                         const TemplateArgumentListInfo &Info) {
590  Base::initializeFrom(Info);
591  setTemplateKeywordLoc(TemplateKWLoc);
592}
593
594void
595ASTTemplateKWAndArgsInfo
596::initializeFrom(SourceLocation TemplateKWLoc,
597                 const TemplateArgumentListInfo &Info,
598                 bool &Dependent,
599                 bool &InstantiationDependent,
600                 bool &ContainsUnexpandedParameterPack) {
601  Base::initializeFrom(Info, Dependent, InstantiationDependent,
602                       ContainsUnexpandedParameterPack);
603  setTemplateKeywordLoc(TemplateKWLoc);
604}
605
606void
607ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
608  // No explicit template arguments, but template keyword loc is valid.
609  assert(TemplateKWLoc.isValid());
610  LAngleLoc = SourceLocation();
611  RAngleLoc = SourceLocation();
612  NumTemplateArgs = 0;
613  setTemplateKeywordLoc(TemplateKWLoc);
614}
615
616std::size_t
617ASTTemplateKWAndArgsInfo::sizeFor(unsigned NumTemplateArgs) {
618  // Add space for the template keyword location.
619  return Base::sizeFor(NumTemplateArgs) + sizeof(SourceLocation);
620}
621
622