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