StmtPrinter.cpp revision eb60edffa147e061278c436e513b0df9b4c4e7f6
1//===--- StmtPrinter.cpp - Printing implementation for Stmt ASTs ----------===//
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 the Stmt::dumpPretty/Stmt::printPretty methods, which
11// pretty print the AST back out to C code.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/AST/StmtVisitor.h"
16#include "clang/AST/DeclCXX.h"
17#include "clang/AST/DeclObjC.h"
18#include "clang/AST/PrettyPrinter.h"
19#include "llvm/Support/Format.h"
20using namespace clang;
21
22//===----------------------------------------------------------------------===//
23// StmtPrinter Visitor
24//===----------------------------------------------------------------------===//
25
26namespace  {
27  class StmtPrinter : public StmtVisitor<StmtPrinter> {
28    llvm::raw_ostream &OS;
29    ASTContext &Context;
30    unsigned IndentLevel;
31    clang::PrinterHelper* Helper;
32    PrintingPolicy Policy;
33
34  public:
35    StmtPrinter(llvm::raw_ostream &os, ASTContext &C, PrinterHelper* helper,
36                const PrintingPolicy &Policy,
37                unsigned Indentation = 0)
38      : OS(os), Context(C), IndentLevel(Indentation), Helper(helper),
39        Policy(Policy) {}
40
41    void PrintStmt(Stmt *S) {
42      PrintStmt(S, Policy.Indentation);
43    }
44
45    void PrintStmt(Stmt *S, int SubIndent) {
46      IndentLevel += SubIndent;
47      if (S && isa<Expr>(S)) {
48        // If this is an expr used in a stmt context, indent and newline it.
49        Indent();
50        Visit(S);
51        OS << ";\n";
52      } else if (S) {
53        Visit(S);
54      } else {
55        Indent() << "<<<NULL STATEMENT>>>\n";
56      }
57      IndentLevel -= SubIndent;
58    }
59
60    void PrintRawCompoundStmt(CompoundStmt *S);
61    void PrintRawDecl(Decl *D);
62    void PrintRawDeclStmt(DeclStmt *S);
63    void PrintRawIfStmt(IfStmt *If);
64    void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
65
66    void PrintExpr(Expr *E) {
67      if (E)
68        Visit(E);
69      else
70        OS << "<null expr>";
71    }
72
73    llvm::raw_ostream &Indent(int Delta = 0) {
74      for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
75        OS << "  ";
76      return OS;
77    }
78
79    bool PrintOffsetOfDesignator(Expr *E);
80    void VisitUnaryOffsetOf(UnaryOperator *Node);
81
82    void Visit(Stmt* S) {
83      if (Helper && Helper->handledStmt(S,OS))
84          return;
85      else StmtVisitor<StmtPrinter>::Visit(S);
86    }
87
88    void VisitStmt(Stmt *Node);
89#define STMT(CLASS, PARENT) \
90    void Visit##CLASS(CLASS *Node);
91#include "clang/AST/StmtNodes.def"
92  };
93}
94
95//===----------------------------------------------------------------------===//
96//  Stmt printing methods.
97//===----------------------------------------------------------------------===//
98
99void StmtPrinter::VisitStmt(Stmt *Node) {
100  Indent() << "<<unknown stmt type>>\n";
101}
102
103/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
104/// with no newline after the }.
105void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
106  OS << "{\n";
107  for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
108       I != E; ++I)
109    PrintStmt(*I);
110
111  Indent() << "}";
112}
113
114void StmtPrinter::PrintRawDecl(Decl *D) {
115  D->print(OS, Policy, IndentLevel);
116}
117
118void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
119  DeclStmt::decl_iterator Begin = S->decl_begin(), End = S->decl_end();
120  llvm::SmallVector<Decl*, 2> Decls;
121  for ( ; Begin != End; ++Begin)
122    Decls.push_back(*Begin);
123
124  Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
125}
126
127void StmtPrinter::VisitNullStmt(NullStmt *Node) {
128  Indent() << ";\n";
129}
130
131void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
132  Indent();
133  PrintRawDeclStmt(Node);
134  OS << ";\n";
135}
136
137void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
138  Indent();
139  PrintRawCompoundStmt(Node);
140  OS << "\n";
141}
142
143void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
144  Indent(-1) << "case ";
145  PrintExpr(Node->getLHS());
146  if (Node->getRHS()) {
147    OS << " ... ";
148    PrintExpr(Node->getRHS());
149  }
150  OS << ":\n";
151
152  PrintStmt(Node->getSubStmt(), 0);
153}
154
155void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
156  Indent(-1) << "default:\n";
157  PrintStmt(Node->getSubStmt(), 0);
158}
159
160void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
161  Indent(-1) << Node->getName() << ":\n";
162  PrintStmt(Node->getSubStmt(), 0);
163}
164
165void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
166  OS << "if (";
167  PrintExpr(If->getCond());
168  OS << ')';
169
170  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) {
171    OS << ' ';
172    PrintRawCompoundStmt(CS);
173    OS << (If->getElse() ? ' ' : '\n');
174  } else {
175    OS << '\n';
176    PrintStmt(If->getThen());
177    if (If->getElse()) Indent();
178  }
179
180  if (Stmt *Else = If->getElse()) {
181    OS << "else";
182
183    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) {
184      OS << ' ';
185      PrintRawCompoundStmt(CS);
186      OS << '\n';
187    } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) {
188      OS << ' ';
189      PrintRawIfStmt(ElseIf);
190    } else {
191      OS << '\n';
192      PrintStmt(If->getElse());
193    }
194  }
195}
196
197void StmtPrinter::VisitIfStmt(IfStmt *If) {
198  Indent();
199  PrintRawIfStmt(If);
200}
201
202void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
203  Indent() << "switch (";
204  PrintExpr(Node->getCond());
205  OS << ")";
206
207  // Pretty print compoundstmt bodies (very common).
208  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
209    OS << " ";
210    PrintRawCompoundStmt(CS);
211    OS << "\n";
212  } else {
213    OS << "\n";
214    PrintStmt(Node->getBody());
215  }
216}
217
218void StmtPrinter::VisitSwitchCase(SwitchCase*) {
219  assert(0 && "SwitchCase is an abstract class");
220}
221
222void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
223  Indent() << "while (";
224  PrintExpr(Node->getCond());
225  OS << ")\n";
226  PrintStmt(Node->getBody());
227}
228
229void StmtPrinter::VisitDoStmt(DoStmt *Node) {
230  Indent() << "do ";
231  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
232    PrintRawCompoundStmt(CS);
233    OS << " ";
234  } else {
235    OS << "\n";
236    PrintStmt(Node->getBody());
237    Indent();
238  }
239
240  OS << "while (";
241  PrintExpr(Node->getCond());
242  OS << ");\n";
243}
244
245void StmtPrinter::VisitForStmt(ForStmt *Node) {
246  Indent() << "for (";
247  if (Node->getInit()) {
248    if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit()))
249      PrintRawDeclStmt(DS);
250    else
251      PrintExpr(cast<Expr>(Node->getInit()));
252  }
253  OS << ";";
254  if (Node->getCond()) {
255    OS << " ";
256    PrintExpr(Node->getCond());
257  }
258  OS << ";";
259  if (Node->getInc()) {
260    OS << " ";
261    PrintExpr(Node->getInc());
262  }
263  OS << ") ";
264
265  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
266    PrintRawCompoundStmt(CS);
267    OS << "\n";
268  } else {
269    OS << "\n";
270    PrintStmt(Node->getBody());
271  }
272}
273
274void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
275  Indent() << "for (";
276  if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement()))
277    PrintRawDeclStmt(DS);
278  else
279    PrintExpr(cast<Expr>(Node->getElement()));
280  OS << " in ";
281  PrintExpr(Node->getCollection());
282  OS << ") ";
283
284  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
285    PrintRawCompoundStmt(CS);
286    OS << "\n";
287  } else {
288    OS << "\n";
289    PrintStmt(Node->getBody());
290  }
291}
292
293void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
294  Indent() << "goto " << Node->getLabel()->getName() << ";\n";
295}
296
297void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
298  Indent() << "goto *";
299  PrintExpr(Node->getTarget());
300  OS << ";\n";
301}
302
303void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
304  Indent() << "continue;\n";
305}
306
307void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
308  Indent() << "break;\n";
309}
310
311
312void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
313  Indent() << "return";
314  if (Node->getRetValue()) {
315    OS << " ";
316    PrintExpr(Node->getRetValue());
317  }
318  OS << ";\n";
319}
320
321
322void StmtPrinter::VisitAsmStmt(AsmStmt *Node) {
323  Indent() << "asm ";
324
325  if (Node->isVolatile())
326    OS << "volatile ";
327
328  OS << "(";
329  VisitStringLiteral(Node->getAsmString());
330
331  // Outputs
332  if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
333      Node->getNumClobbers() != 0)
334    OS << " : ";
335
336  for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
337    if (i != 0)
338      OS << ", ";
339
340    if (!Node->getOutputName(i).empty()) {
341      OS << '[';
342      OS << Node->getOutputName(i);
343      OS << "] ";
344    }
345
346    VisitStringLiteral(Node->getOutputConstraintLiteral(i));
347    OS << " ";
348    Visit(Node->getOutputExpr(i));
349  }
350
351  // Inputs
352  if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
353    OS << " : ";
354
355  for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
356    if (i != 0)
357      OS << ", ";
358
359    if (!Node->getInputName(i).empty()) {
360      OS << '[';
361      OS << Node->getInputName(i);
362      OS << "] ";
363    }
364
365    VisitStringLiteral(Node->getInputConstraintLiteral(i));
366    OS << " ";
367    Visit(Node->getInputExpr(i));
368  }
369
370  // Clobbers
371  if (Node->getNumClobbers() != 0)
372    OS << " : ";
373
374  for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
375    if (i != 0)
376      OS << ", ";
377
378    VisitStringLiteral(Node->getClobber(i));
379  }
380
381  OS << ");\n";
382}
383
384void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
385  Indent() << "@try";
386  if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
387    PrintRawCompoundStmt(TS);
388    OS << "\n";
389  }
390
391  for (ObjCAtCatchStmt *catchStmt =
392         static_cast<ObjCAtCatchStmt *>(Node->getCatchStmts());
393       catchStmt;
394       catchStmt =
395         static_cast<ObjCAtCatchStmt *>(catchStmt->getNextCatchStmt())) {
396    Indent() << "@catch(";
397    if (catchStmt->getCatchParamDecl()) {
398      if (Decl *DS = catchStmt->getCatchParamDecl())
399        PrintRawDecl(DS);
400    }
401    OS << ")";
402    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
403      PrintRawCompoundStmt(CS);
404      OS << "\n";
405    }
406  }
407
408  if (ObjCAtFinallyStmt *FS = static_cast<ObjCAtFinallyStmt *>(
409        Node->getFinallyStmt())) {
410    Indent() << "@finally";
411    PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
412    OS << "\n";
413  }
414}
415
416void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
417}
418
419void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
420  Indent() << "@catch (...) { /* todo */ } \n";
421}
422
423void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
424  Indent() << "@throw";
425  if (Node->getThrowExpr()) {
426    OS << " ";
427    PrintExpr(Node->getThrowExpr());
428  }
429  OS << ";\n";
430}
431
432void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
433  Indent() << "@synchronized (";
434  PrintExpr(Node->getSynchExpr());
435  OS << ")";
436  PrintRawCompoundStmt(Node->getSynchBody());
437  OS << "\n";
438}
439
440void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
441  OS << "catch (";
442  if (Decl *ExDecl = Node->getExceptionDecl())
443    PrintRawDecl(ExDecl);
444  else
445    OS << "...";
446  OS << ") ";
447  PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
448}
449
450void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
451  Indent();
452  PrintRawCXXCatchStmt(Node);
453  OS << "\n";
454}
455
456void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
457  Indent() << "try ";
458  PrintRawCompoundStmt(Node->getTryBlock());
459  for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
460    OS << " ";
461    PrintRawCXXCatchStmt(Node->getHandler(i));
462  }
463  OS << "\n";
464}
465
466//===----------------------------------------------------------------------===//
467//  Expr printing methods.
468//===----------------------------------------------------------------------===//
469
470void StmtPrinter::VisitExpr(Expr *Node) {
471  OS << "<<unknown expr type>>";
472}
473
474void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
475  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
476    Qualifier->print(OS, Policy);
477  OS << Node->getDecl()->getNameAsString();
478  if (Node->hasExplicitTemplateArgumentList())
479    OS << TemplateSpecializationType::PrintTemplateArgumentList(
480                                                    Node->getTemplateArgs(),
481                                                    Node->getNumTemplateArgs(),
482                                                    Policy);
483}
484
485void StmtPrinter::VisitDependentScopeDeclRefExpr(
486                                           DependentScopeDeclRefExpr *Node) {
487  Node->getQualifier()->print(OS, Policy);
488  OS << Node->getDeclName().getAsString();
489  if (Node->hasExplicitTemplateArgs())
490    OS << TemplateSpecializationType::PrintTemplateArgumentList(
491                                                   Node->getTemplateArgs(),
492                                                   Node->getNumTemplateArgs(),
493                                                   Policy);
494}
495
496void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
497  if (Node->getQualifier())
498    Node->getQualifier()->print(OS, Policy);
499  OS << Node->getName().getAsString();
500  if (Node->hasExplicitTemplateArgs())
501    OS << TemplateSpecializationType::PrintTemplateArgumentList(
502                                                   Node->getTemplateArgs(),
503                                                   Node->getNumTemplateArgs(),
504                                                   Policy);
505}
506
507void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
508  if (Node->getBase()) {
509    PrintExpr(Node->getBase());
510    OS << (Node->isArrow() ? "->" : ".");
511  }
512  OS << Node->getDecl()->getNameAsString();
513}
514
515void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
516  if (Node->getBase()) {
517    PrintExpr(Node->getBase());
518    OS << ".";
519  }
520  OS << Node->getProperty()->getNameAsCString();
521}
522
523void StmtPrinter::VisitObjCImplicitSetterGetterRefExpr(
524                                        ObjCImplicitSetterGetterRefExpr *Node) {
525  if (Node->getBase()) {
526    PrintExpr(Node->getBase());
527    OS << ".";
528  }
529  if (Node->getGetterMethod())
530    OS << Node->getGetterMethod()->getNameAsString();
531
532}
533
534void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
535  switch (Node->getIdentType()) {
536    default:
537      assert(0 && "unknown case");
538    case PredefinedExpr::Func:
539      OS << "__func__";
540      break;
541    case PredefinedExpr::Function:
542      OS << "__FUNCTION__";
543      break;
544    case PredefinedExpr::PrettyFunction:
545      OS << "__PRETTY_FUNCTION__";
546      break;
547  }
548}
549
550void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
551  unsigned value = Node->getValue();
552  if (Node->isWide())
553    OS << "L";
554  switch (value) {
555  case '\\':
556    OS << "'\\\\'";
557    break;
558  case '\'':
559    OS << "'\\''";
560    break;
561  case '\a':
562    // TODO: K&R: the meaning of '\\a' is different in traditional C
563    OS << "'\\a'";
564    break;
565  case '\b':
566    OS << "'\\b'";
567    break;
568  // Nonstandard escape sequence.
569  /*case '\e':
570    OS << "'\\e'";
571    break;*/
572  case '\f':
573    OS << "'\\f'";
574    break;
575  case '\n':
576    OS << "'\\n'";
577    break;
578  case '\r':
579    OS << "'\\r'";
580    break;
581  case '\t':
582    OS << "'\\t'";
583    break;
584  case '\v':
585    OS << "'\\v'";
586    break;
587  default:
588    if (value < 256 && isprint(value)) {
589      OS << "'" << (char)value << "'";
590    } else if (value < 256) {
591      OS << "'\\x" << llvm::format("%x", value) << "'";
592    } else {
593      // FIXME what to really do here?
594      OS << value;
595    }
596  }
597}
598
599void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
600  bool isSigned = Node->getType()->isSignedIntegerType();
601  OS << Node->getValue().toString(10, isSigned);
602
603  // Emit suffixes.  Integer literals are always a builtin integer type.
604  switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
605  default: assert(0 && "Unexpected type for integer literal!");
606  case BuiltinType::Int:       break; // no suffix.
607  case BuiltinType::UInt:      OS << 'U'; break;
608  case BuiltinType::Long:      OS << 'L'; break;
609  case BuiltinType::ULong:     OS << "UL"; break;
610  case BuiltinType::LongLong:  OS << "LL"; break;
611  case BuiltinType::ULongLong: OS << "ULL"; break;
612  }
613}
614void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
615  // FIXME: print value more precisely.
616  OS << Node->getValueAsApproximateDouble();
617}
618
619void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
620  PrintExpr(Node->getSubExpr());
621  OS << "i";
622}
623
624void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
625  if (Str->isWide()) OS << 'L';
626  OS << '"';
627
628  // FIXME: this doesn't print wstrings right.
629  for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
630    unsigned char Char = Str->getStrData()[i];
631
632    switch (Char) {
633    default:
634      if (isprint(Char))
635        OS << (char)Char;
636      else  // Output anything hard as an octal escape.
637        OS << '\\'
638        << (char)('0'+ ((Char >> 6) & 7))
639        << (char)('0'+ ((Char >> 3) & 7))
640        << (char)('0'+ ((Char >> 0) & 7));
641      break;
642    // Handle some common non-printable cases to make dumps prettier.
643    case '\\': OS << "\\\\"; break;
644    case '"': OS << "\\\""; break;
645    case '\n': OS << "\\n"; break;
646    case '\t': OS << "\\t"; break;
647    case '\a': OS << "\\a"; break;
648    case '\b': OS << "\\b"; break;
649    }
650  }
651  OS << '"';
652}
653void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
654  OS << "(";
655  PrintExpr(Node->getSubExpr());
656  OS << ")";
657}
658void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
659  if (!Node->isPostfix()) {
660    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
661
662    // Print a space if this is an "identifier operator" like __real, or if
663    // it might be concatenated incorrectly like '+'.
664    switch (Node->getOpcode()) {
665    default: break;
666    case UnaryOperator::Real:
667    case UnaryOperator::Imag:
668    case UnaryOperator::Extension:
669      OS << ' ';
670      break;
671    case UnaryOperator::Plus:
672    case UnaryOperator::Minus:
673      if (isa<UnaryOperator>(Node->getSubExpr()))
674        OS << ' ';
675      break;
676    }
677  }
678  PrintExpr(Node->getSubExpr());
679
680  if (Node->isPostfix())
681    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
682}
683
684bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) {
685  if (isa<UnaryOperator>(E)) {
686    // Base case, print the type and comma.
687    OS << E->getType().getAsString() << ", ";
688    return true;
689  } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
690    PrintOffsetOfDesignator(ASE->getLHS());
691    OS << "[";
692    PrintExpr(ASE->getRHS());
693    OS << "]";
694    return false;
695  } else {
696    MemberExpr *ME = cast<MemberExpr>(E);
697    bool IsFirst = PrintOffsetOfDesignator(ME->getBase());
698    OS << (IsFirst ? "" : ".") << ME->getMemberDecl()->getNameAsString();
699    return false;
700  }
701}
702
703void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) {
704  OS << "__builtin_offsetof(";
705  PrintOffsetOfDesignator(Node->getSubExpr());
706  OS << ")";
707}
708
709void StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
710  OS << (Node->isSizeOf() ? "sizeof" : "__alignof");
711  if (Node->isArgumentType())
712    OS << "(" << Node->getArgumentType().getAsString() << ")";
713  else {
714    OS << " ";
715    PrintExpr(Node->getArgumentExpr());
716  }
717}
718void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
719  PrintExpr(Node->getLHS());
720  OS << "[";
721  PrintExpr(Node->getRHS());
722  OS << "]";
723}
724
725void StmtPrinter::VisitCallExpr(CallExpr *Call) {
726  PrintExpr(Call->getCallee());
727  OS << "(";
728  for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
729    if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
730      // Don't print any defaulted arguments
731      break;
732    }
733
734    if (i) OS << ", ";
735    PrintExpr(Call->getArg(i));
736  }
737  OS << ")";
738}
739void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
740  // FIXME: Suppress printing implicit bases (like "this")
741  PrintExpr(Node->getBase());
742  if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
743    if (FD->isAnonymousStructOrUnion())
744      return;
745  OS << (Node->isArrow() ? "->" : ".");
746  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
747    Qualifier->print(OS, Policy);
748
749  OS << Node->getMemberDecl()->getNameAsString();
750
751  if (Node->hasExplicitTemplateArgumentList())
752    OS << TemplateSpecializationType::PrintTemplateArgumentList(
753                                                    Node->getTemplateArgs(),
754                                                    Node->getNumTemplateArgs(),
755                                                                Policy);
756}
757void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
758  PrintExpr(Node->getBase());
759  OS << (Node->isArrow() ? "->isa" : ".isa");
760}
761
762void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
763  PrintExpr(Node->getBase());
764  OS << ".";
765  OS << Node->getAccessor().getName();
766}
767void StmtPrinter::VisitCastExpr(CastExpr *) {
768  assert(0 && "CastExpr is an abstract class");
769}
770void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *) {
771  assert(0 && "ExplicitCastExpr is an abstract class");
772}
773void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
774  OS << "(" << Node->getType().getAsString() << ")";
775  PrintExpr(Node->getSubExpr());
776}
777void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
778  OS << "(" << Node->getType().getAsString() << ")";
779  PrintExpr(Node->getInitializer());
780}
781void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
782  // No need to print anything, simply forward to the sub expression.
783  PrintExpr(Node->getSubExpr());
784}
785void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
786  PrintExpr(Node->getLHS());
787  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
788  PrintExpr(Node->getRHS());
789}
790void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
791  PrintExpr(Node->getLHS());
792  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
793  PrintExpr(Node->getRHS());
794}
795void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
796  PrintExpr(Node->getCond());
797
798  if (Node->getLHS()) {
799    OS << " ? ";
800    PrintExpr(Node->getLHS());
801    OS << " : ";
802  }
803  else { // Handle GCC extension where LHS can be NULL.
804    OS << " ?: ";
805  }
806
807  PrintExpr(Node->getRHS());
808}
809
810// GNU extensions.
811
812void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
813  OS << "&&" << Node->getLabel()->getName();
814}
815
816void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
817  OS << "(";
818  PrintRawCompoundStmt(E->getSubStmt());
819  OS << ")";
820}
821
822void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
823  OS << "__builtin_types_compatible_p(";
824  OS << Node->getArgType1().getAsString() << ",";
825  OS << Node->getArgType2().getAsString() << ")";
826}
827
828void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
829  OS << "__builtin_choose_expr(";
830  PrintExpr(Node->getCond());
831  OS << ", ";
832  PrintExpr(Node->getLHS());
833  OS << ", ";
834  PrintExpr(Node->getRHS());
835  OS << ")";
836}
837
838void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
839  OS << "__null";
840}
841
842void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
843  OS << "__builtin_shufflevector(";
844  for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
845    if (i) OS << ", ";
846    PrintExpr(Node->getExpr(i));
847  }
848  OS << ")";
849}
850
851void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
852  if (Node->getSyntacticForm()) {
853    Visit(Node->getSyntacticForm());
854    return;
855  }
856
857  OS << "{ ";
858  for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
859    if (i) OS << ", ";
860    if (Node->getInit(i))
861      PrintExpr(Node->getInit(i));
862    else
863      OS << "0";
864  }
865  OS << " }";
866}
867
868void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
869  OS << "( ";
870  for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
871    if (i) OS << ", ";
872    PrintExpr(Node->getExpr(i));
873  }
874  OS << " )";
875}
876
877void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
878  for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(),
879                      DEnd = Node->designators_end();
880       D != DEnd; ++D) {
881    if (D->isFieldDesignator()) {
882      if (D->getDotLoc().isInvalid())
883        OS << D->getFieldName()->getName() << ":";
884      else
885        OS << "." << D->getFieldName()->getName();
886    } else {
887      OS << "[";
888      if (D->isArrayDesignator()) {
889        PrintExpr(Node->getArrayIndex(*D));
890      } else {
891        PrintExpr(Node->getArrayRangeStart(*D));
892        OS << " ... ";
893        PrintExpr(Node->getArrayRangeEnd(*D));
894      }
895      OS << "]";
896    }
897  }
898
899  OS << " = ";
900  PrintExpr(Node->getInit());
901}
902
903void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
904  if (Policy.LangOpts.CPlusPlus)
905    OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()";
906  else {
907    OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")";
908    if (Node->getType()->isRecordType())
909      OS << "{}";
910    else
911      OS << 0;
912  }
913}
914
915void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
916  OS << "__builtin_va_arg(";
917  PrintExpr(Node->getSubExpr());
918  OS << ", ";
919  OS << Node->getType().getAsString();
920  OS << ")";
921}
922
923// C++
924void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
925  const char *OpStrings[NUM_OVERLOADED_OPERATORS] = {
926    "",
927#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
928    Spelling,
929#include "clang/Basic/OperatorKinds.def"
930  };
931
932  OverloadedOperatorKind Kind = Node->getOperator();
933  if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
934    if (Node->getNumArgs() == 1) {
935      OS << OpStrings[Kind] << ' ';
936      PrintExpr(Node->getArg(0));
937    } else {
938      PrintExpr(Node->getArg(0));
939      OS << ' ' << OpStrings[Kind];
940    }
941  } else if (Kind == OO_Call) {
942    PrintExpr(Node->getArg(0));
943    OS << '(';
944    for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
945      if (ArgIdx > 1)
946        OS << ", ";
947      if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
948        PrintExpr(Node->getArg(ArgIdx));
949    }
950    OS << ')';
951  } else if (Kind == OO_Subscript) {
952    PrintExpr(Node->getArg(0));
953    OS << '[';
954    PrintExpr(Node->getArg(1));
955    OS << ']';
956  } else if (Node->getNumArgs() == 1) {
957    OS << OpStrings[Kind] << ' ';
958    PrintExpr(Node->getArg(0));
959  } else if (Node->getNumArgs() == 2) {
960    PrintExpr(Node->getArg(0));
961    OS << ' ' << OpStrings[Kind] << ' ';
962    PrintExpr(Node->getArg(1));
963  } else {
964    assert(false && "unknown overloaded operator");
965  }
966}
967
968void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
969  VisitCallExpr(cast<CallExpr>(Node));
970}
971
972void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
973  OS << Node->getCastName() << '<';
974  OS << Node->getTypeAsWritten().getAsString() << ">(";
975  PrintExpr(Node->getSubExpr());
976  OS << ")";
977}
978
979void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
980  VisitCXXNamedCastExpr(Node);
981}
982
983void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
984  VisitCXXNamedCastExpr(Node);
985}
986
987void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
988  VisitCXXNamedCastExpr(Node);
989}
990
991void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
992  VisitCXXNamedCastExpr(Node);
993}
994
995void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
996  OS << "typeid(";
997  if (Node->isTypeOperand()) {
998    OS << Node->getTypeOperand().getAsString();
999  } else {
1000    PrintExpr(Node->getExprOperand());
1001  }
1002  OS << ")";
1003}
1004
1005void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
1006  OS << (Node->getValue() ? "true" : "false");
1007}
1008
1009void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
1010  OS << "nullptr";
1011}
1012
1013void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
1014  OS << "this";
1015}
1016
1017void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
1018  if (Node->getSubExpr() == 0)
1019    OS << "throw";
1020  else {
1021    OS << "throw ";
1022    PrintExpr(Node->getSubExpr());
1023  }
1024}
1025
1026void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
1027  // Nothing to print: we picked up the default argument
1028}
1029
1030void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
1031  OS << Node->getType().getAsString();
1032  OS << "(";
1033  PrintExpr(Node->getSubExpr());
1034  OS << ")";
1035}
1036
1037void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
1038  PrintExpr(Node->getSubExpr());
1039}
1040
1041void StmtPrinter::VisitCXXBindReferenceExpr(CXXBindReferenceExpr *Node) {
1042  PrintExpr(Node->getSubExpr());
1043}
1044
1045void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
1046  OS << Node->getType().getAsString();
1047  OS << "(";
1048  for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
1049                                         ArgEnd = Node->arg_end();
1050       Arg != ArgEnd; ++Arg) {
1051    if (Arg != Node->arg_begin())
1052      OS << ", ";
1053    PrintExpr(*Arg);
1054  }
1055  OS << ")";
1056}
1057
1058void StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) {
1059  OS << Node->getType().getAsString() << "()";
1060}
1061
1062void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
1063  if (E->isGlobalNew())
1064    OS << "::";
1065  OS << "new ";
1066  unsigned NumPlace = E->getNumPlacementArgs();
1067  if (NumPlace > 0) {
1068    OS << "(";
1069    PrintExpr(E->getPlacementArg(0));
1070    for (unsigned i = 1; i < NumPlace; ++i) {
1071      OS << ", ";
1072      PrintExpr(E->getPlacementArg(i));
1073    }
1074    OS << ") ";
1075  }
1076  if (E->isParenTypeId())
1077    OS << "(";
1078  std::string TypeS;
1079  if (Expr *Size = E->getArraySize()) {
1080    llvm::raw_string_ostream s(TypeS);
1081    Size->printPretty(s, Context, Helper, Policy);
1082    s.flush();
1083    TypeS = "[" + TypeS + "]";
1084  }
1085  E->getAllocatedType().getAsStringInternal(TypeS, Policy);
1086  OS << TypeS;
1087  if (E->isParenTypeId())
1088    OS << ")";
1089
1090  if (E->hasInitializer()) {
1091    OS << "(";
1092    unsigned NumCons = E->getNumConstructorArgs();
1093    if (NumCons > 0) {
1094      PrintExpr(E->getConstructorArg(0));
1095      for (unsigned i = 1; i < NumCons; ++i) {
1096        OS << ", ";
1097        PrintExpr(E->getConstructorArg(i));
1098      }
1099    }
1100    OS << ")";
1101  }
1102}
1103
1104void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
1105  if (E->isGlobalDelete())
1106    OS << "::";
1107  OS << "delete ";
1108  if (E->isArrayForm())
1109    OS << "[] ";
1110  PrintExpr(E->getArgument());
1111}
1112
1113void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1114  PrintExpr(E->getBase());
1115  if (E->isArrow())
1116    OS << "->";
1117  else
1118    OS << '.';
1119  if (E->getQualifier())
1120    E->getQualifier()->print(OS, Policy);
1121
1122  std::string TypeS;
1123  E->getDestroyedType().getAsStringInternal(TypeS, Policy);
1124  OS << TypeS;
1125}
1126
1127void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
1128  // FIXME. For now we just print a trivial constructor call expression,
1129  // constructing its first argument object.
1130  if (E->getNumArgs() == 1) {
1131    CXXConstructorDecl *CD = E->getConstructor();
1132    if (CD->isTrivial())
1133      PrintExpr(E->getArg(0));
1134  }
1135  // Nothing to print.
1136}
1137
1138void StmtPrinter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
1139  // Just forward to the sub expression.
1140  PrintExpr(E->getSubExpr());
1141}
1142
1143void
1144StmtPrinter::VisitCXXUnresolvedConstructExpr(
1145                                           CXXUnresolvedConstructExpr *Node) {
1146  OS << Node->getTypeAsWritten().getAsString();
1147  OS << "(";
1148  for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(),
1149                                             ArgEnd = Node->arg_end();
1150       Arg != ArgEnd; ++Arg) {
1151    if (Arg != Node->arg_begin())
1152      OS << ", ";
1153    PrintExpr(*Arg);
1154  }
1155  OS << ")";
1156}
1157
1158void StmtPrinter::VisitCXXDependentScopeMemberExpr(
1159                                         CXXDependentScopeMemberExpr *Node) {
1160  if (!Node->isImplicitAccess()) {
1161    PrintExpr(Node->getBase());
1162    OS << (Node->isArrow() ? "->" : ".");
1163  }
1164  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1165    Qualifier->print(OS, Policy);
1166  else if (Node->hasExplicitTemplateArgs())
1167    // FIXME: Track use of "template" keyword explicitly?
1168    OS << "template ";
1169
1170  OS << Node->getMember().getAsString();
1171
1172  if (Node->hasExplicitTemplateArgs()) {
1173    OS << TemplateSpecializationType::PrintTemplateArgumentList(
1174                                                    Node->getTemplateArgs(),
1175                                                    Node->getNumTemplateArgs(),
1176                                                    Policy);
1177  }
1178}
1179
1180void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
1181  if (!Node->isImplicitAccess()) {
1182    PrintExpr(Node->getBase());
1183    OS << (Node->isArrow() ? "->" : ".");
1184  }
1185  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1186    Qualifier->print(OS, Policy);
1187
1188  // FIXME: this might originally have been written with 'template'
1189
1190  OS << Node->getMemberName().getAsString();
1191
1192  if (Node->hasExplicitTemplateArgs()) {
1193    OS << TemplateSpecializationType::PrintTemplateArgumentList(
1194                                                    Node->getTemplateArgs(),
1195                                                    Node->getNumTemplateArgs(),
1196                                                    Policy);
1197  }
1198}
1199
1200static const char *getTypeTraitName(UnaryTypeTrait UTT) {
1201  switch (UTT) {
1202  default: assert(false && "Unknown type trait");
1203  case UTT_HasNothrowAssign:      return "__has_nothrow_assign";
1204  case UTT_HasNothrowCopy:        return "__has_nothrow_copy";
1205  case UTT_HasNothrowConstructor: return "__has_nothrow_constructor";
1206  case UTT_HasTrivialAssign:      return "__has_trivial_assign";
1207  case UTT_HasTrivialCopy:        return "__has_trivial_copy";
1208  case UTT_HasTrivialConstructor: return "__has_trivial_constructor";
1209  case UTT_HasTrivialDestructor:  return "__has_trivial_destructor";
1210  case UTT_HasVirtualDestructor:  return "__has_virtual_destructor";
1211  case UTT_IsAbstract:            return "__is_abstract";
1212  case UTT_IsClass:               return "__is_class";
1213  case UTT_IsEmpty:               return "__is_empty";
1214  case UTT_IsEnum:                return "__is_enum";
1215  case UTT_IsPOD:                 return "__is_pod";
1216  case UTT_IsPolymorphic:         return "__is_polymorphic";
1217  case UTT_IsUnion:               return "__is_union";
1218  }
1219}
1220
1221void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
1222  OS << getTypeTraitName(E->getTrait()) << "("
1223     << E->getQueriedType().getAsString() << ")";
1224}
1225
1226// Obj-C
1227
1228void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
1229  OS << "@";
1230  VisitStringLiteral(Node->getString());
1231}
1232
1233void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
1234  OS << "@encode(" << Node->getEncodedType().getAsString() << ')';
1235}
1236
1237void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
1238  OS << "@selector(" << Node->getSelector().getAsString() << ')';
1239}
1240
1241void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
1242  OS << "@protocol(" << Node->getProtocol()->getNameAsString() << ')';
1243}
1244
1245void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
1246  OS << "[";
1247  Expr *receiver = Mess->getReceiver();
1248  if (receiver) PrintExpr(receiver);
1249  else OS << Mess->getClassName()->getName();
1250  OS << ' ';
1251  Selector selector = Mess->getSelector();
1252  if (selector.isUnarySelector()) {
1253    OS << selector.getIdentifierInfoForSlot(0)->getName();
1254  } else {
1255    for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
1256      if (i < selector.getNumArgs()) {
1257        if (i > 0) OS << ' ';
1258        if (selector.getIdentifierInfoForSlot(i))
1259          OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
1260        else
1261           OS << ":";
1262      }
1263      else OS << ", "; // Handle variadic methods.
1264
1265      PrintExpr(Mess->getArg(i));
1266    }
1267  }
1268  OS << "]";
1269}
1270
1271void StmtPrinter::VisitObjCSuperExpr(ObjCSuperExpr *) {
1272  OS << "super";
1273}
1274
1275void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
1276  BlockDecl *BD = Node->getBlockDecl();
1277  OS << "^";
1278
1279  const FunctionType *AFT = Node->getFunctionType();
1280
1281  if (isa<FunctionNoProtoType>(AFT)) {
1282    OS << "()";
1283  } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
1284    OS << '(';
1285    std::string ParamStr;
1286    for (BlockDecl::param_iterator AI = BD->param_begin(),
1287         E = BD->param_end(); AI != E; ++AI) {
1288      if (AI != BD->param_begin()) OS << ", ";
1289      ParamStr = (*AI)->getNameAsString();
1290      (*AI)->getType().getAsStringInternal(ParamStr, Policy);
1291      OS << ParamStr;
1292    }
1293
1294    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
1295    if (FT->isVariadic()) {
1296      if (!BD->param_empty()) OS << ", ";
1297      OS << "...";
1298    }
1299    OS << ')';
1300  }
1301}
1302
1303void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
1304  OS << Node->getDecl()->getNameAsString();
1305}
1306//===----------------------------------------------------------------------===//
1307// Stmt method implementations
1308//===----------------------------------------------------------------------===//
1309
1310void Stmt::dumpPretty(ASTContext& Context) const {
1311  printPretty(llvm::errs(), Context, 0,
1312              PrintingPolicy(Context.getLangOptions()));
1313}
1314
1315void Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context,
1316                       PrinterHelper* Helper,
1317                       const PrintingPolicy &Policy,
1318                       unsigned Indentation) const {
1319  if (this == 0) {
1320    OS << "<NULL>";
1321    return;
1322  }
1323
1324  if (Policy.Dump && &Context) {
1325    dump(Context.getSourceManager());
1326    return;
1327  }
1328
1329  StmtPrinter P(OS, Context, Helper, Policy, Indentation);
1330  P.Visit(const_cast<Stmt*>(this));
1331}
1332
1333//===----------------------------------------------------------------------===//
1334// PrinterHelper
1335//===----------------------------------------------------------------------===//
1336
1337// Implement virtual destructor.
1338PrinterHelper::~PrinterHelper() {}
1339