StmtPrinter.cpp revision 8f5e3dd32e443768d9dbbad7191e123e6733750c
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 (unsigned I = 0, N = Node->getNumCatchStmts(); I != N; ++I) {
392    ObjCAtCatchStmt *catchStmt = Node->getCatchStmt(I);
393    Indent() << "@catch(";
394    if (catchStmt->getCatchParamDecl()) {
395      if (Decl *DS = catchStmt->getCatchParamDecl())
396        PrintRawDecl(DS);
397    }
398    OS << ")";
399    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
400      PrintRawCompoundStmt(CS);
401      OS << "\n";
402    }
403  }
404
405  if (ObjCAtFinallyStmt *FS = static_cast<ObjCAtFinallyStmt *>(
406        Node->getFinallyStmt())) {
407    Indent() << "@finally";
408    PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
409    OS << "\n";
410  }
411}
412
413void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
414}
415
416void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
417  Indent() << "@catch (...) { /* todo */ } \n";
418}
419
420void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
421  Indent() << "@throw";
422  if (Node->getThrowExpr()) {
423    OS << " ";
424    PrintExpr(Node->getThrowExpr());
425  }
426  OS << ";\n";
427}
428
429void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
430  Indent() << "@synchronized (";
431  PrintExpr(Node->getSynchExpr());
432  OS << ")";
433  PrintRawCompoundStmt(Node->getSynchBody());
434  OS << "\n";
435}
436
437void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
438  OS << "catch (";
439  if (Decl *ExDecl = Node->getExceptionDecl())
440    PrintRawDecl(ExDecl);
441  else
442    OS << "...";
443  OS << ") ";
444  PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
445}
446
447void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
448  Indent();
449  PrintRawCXXCatchStmt(Node);
450  OS << "\n";
451}
452
453void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
454  Indent() << "try ";
455  PrintRawCompoundStmt(Node->getTryBlock());
456  for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
457    OS << " ";
458    PrintRawCXXCatchStmt(Node->getHandler(i));
459  }
460  OS << "\n";
461}
462
463//===----------------------------------------------------------------------===//
464//  Expr printing methods.
465//===----------------------------------------------------------------------===//
466
467void StmtPrinter::VisitExpr(Expr *Node) {
468  OS << "<<unknown expr type>>";
469}
470
471void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
472  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
473    Qualifier->print(OS, Policy);
474  OS << Node->getDecl();
475  if (Node->hasExplicitTemplateArgumentList())
476    OS << TemplateSpecializationType::PrintTemplateArgumentList(
477                                                    Node->getTemplateArgs(),
478                                                    Node->getNumTemplateArgs(),
479                                                    Policy);
480}
481
482void StmtPrinter::VisitDependentScopeDeclRefExpr(
483                                           DependentScopeDeclRefExpr *Node) {
484  Node->getQualifier()->print(OS, Policy);
485  OS << Node->getDeclName().getAsString();
486  if (Node->hasExplicitTemplateArgs())
487    OS << TemplateSpecializationType::PrintTemplateArgumentList(
488                                                   Node->getTemplateArgs(),
489                                                   Node->getNumTemplateArgs(),
490                                                   Policy);
491}
492
493void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
494  if (Node->getQualifier())
495    Node->getQualifier()->print(OS, Policy);
496  OS << Node->getName().getAsString();
497  if (Node->hasExplicitTemplateArgs())
498    OS << TemplateSpecializationType::PrintTemplateArgumentList(
499                                                   Node->getTemplateArgs(),
500                                                   Node->getNumTemplateArgs(),
501                                                   Policy);
502}
503
504void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
505  if (Node->getBase()) {
506    PrintExpr(Node->getBase());
507    OS << (Node->isArrow() ? "->" : ".");
508  }
509  OS << Node->getDecl();
510}
511
512void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
513  if (Node->getBase()) {
514    PrintExpr(Node->getBase());
515    OS << ".";
516  }
517  OS << Node->getProperty()->getNameAsCString();
518}
519
520void StmtPrinter::VisitObjCImplicitSetterGetterRefExpr(
521                                        ObjCImplicitSetterGetterRefExpr *Node) {
522  if (Node->getBase()) {
523    PrintExpr(Node->getBase());
524    OS << ".";
525  }
526  if (Node->getGetterMethod())
527    OS << Node->getGetterMethod();
528
529}
530
531void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
532  switch (Node->getIdentType()) {
533    default:
534      assert(0 && "unknown case");
535    case PredefinedExpr::Func:
536      OS << "__func__";
537      break;
538    case PredefinedExpr::Function:
539      OS << "__FUNCTION__";
540      break;
541    case PredefinedExpr::PrettyFunction:
542      OS << "__PRETTY_FUNCTION__";
543      break;
544  }
545}
546
547void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
548  unsigned value = Node->getValue();
549  if (Node->isWide())
550    OS << "L";
551  switch (value) {
552  case '\\':
553    OS << "'\\\\'";
554    break;
555  case '\'':
556    OS << "'\\''";
557    break;
558  case '\a':
559    // TODO: K&R: the meaning of '\\a' is different in traditional C
560    OS << "'\\a'";
561    break;
562  case '\b':
563    OS << "'\\b'";
564    break;
565  // Nonstandard escape sequence.
566  /*case '\e':
567    OS << "'\\e'";
568    break;*/
569  case '\f':
570    OS << "'\\f'";
571    break;
572  case '\n':
573    OS << "'\\n'";
574    break;
575  case '\r':
576    OS << "'\\r'";
577    break;
578  case '\t':
579    OS << "'\\t'";
580    break;
581  case '\v':
582    OS << "'\\v'";
583    break;
584  default:
585    if (value < 256 && isprint(value)) {
586      OS << "'" << (char)value << "'";
587    } else if (value < 256) {
588      OS << "'\\x" << llvm::format("%x", value) << "'";
589    } else {
590      // FIXME what to really do here?
591      OS << value;
592    }
593  }
594}
595
596void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
597  bool isSigned = Node->getType()->isSignedIntegerType();
598  OS << Node->getValue().toString(10, isSigned);
599
600  // Emit suffixes.  Integer literals are always a builtin integer type.
601  switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
602  default: assert(0 && "Unexpected type for integer literal!");
603  case BuiltinType::Int:       break; // no suffix.
604  case BuiltinType::UInt:      OS << 'U'; break;
605  case BuiltinType::Long:      OS << 'L'; break;
606  case BuiltinType::ULong:     OS << "UL"; break;
607  case BuiltinType::LongLong:  OS << "LL"; break;
608  case BuiltinType::ULongLong: OS << "ULL"; break;
609  }
610}
611void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
612  // FIXME: print value more precisely.
613  OS << Node->getValueAsApproximateDouble();
614}
615
616void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
617  PrintExpr(Node->getSubExpr());
618  OS << "i";
619}
620
621void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
622  if (Str->isWide()) OS << 'L';
623  OS << '"';
624
625  // FIXME: this doesn't print wstrings right.
626  for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
627    unsigned char Char = Str->getStrData()[i];
628
629    switch (Char) {
630    default:
631      if (isprint(Char))
632        OS << (char)Char;
633      else  // Output anything hard as an octal escape.
634        OS << '\\'
635        << (char)('0'+ ((Char >> 6) & 7))
636        << (char)('0'+ ((Char >> 3) & 7))
637        << (char)('0'+ ((Char >> 0) & 7));
638      break;
639    // Handle some common non-printable cases to make dumps prettier.
640    case '\\': OS << "\\\\"; break;
641    case '"': OS << "\\\""; break;
642    case '\n': OS << "\\n"; break;
643    case '\t': OS << "\\t"; break;
644    case '\a': OS << "\\a"; break;
645    case '\b': OS << "\\b"; break;
646    }
647  }
648  OS << '"';
649}
650void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
651  OS << "(";
652  PrintExpr(Node->getSubExpr());
653  OS << ")";
654}
655void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
656  if (!Node->isPostfix()) {
657    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
658
659    // Print a space if this is an "identifier operator" like __real, or if
660    // it might be concatenated incorrectly like '+'.
661    switch (Node->getOpcode()) {
662    default: break;
663    case UnaryOperator::Real:
664    case UnaryOperator::Imag:
665    case UnaryOperator::Extension:
666      OS << ' ';
667      break;
668    case UnaryOperator::Plus:
669    case UnaryOperator::Minus:
670      if (isa<UnaryOperator>(Node->getSubExpr()))
671        OS << ' ';
672      break;
673    }
674  }
675  PrintExpr(Node->getSubExpr());
676
677  if (Node->isPostfix())
678    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
679}
680
681bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) {
682  if (isa<UnaryOperator>(E)) {
683    // Base case, print the type and comma.
684    OS << E->getType().getAsString() << ", ";
685    return true;
686  } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
687    PrintOffsetOfDesignator(ASE->getLHS());
688    OS << "[";
689    PrintExpr(ASE->getRHS());
690    OS << "]";
691    return false;
692  } else {
693    MemberExpr *ME = cast<MemberExpr>(E);
694    bool IsFirst = PrintOffsetOfDesignator(ME->getBase());
695    OS << (IsFirst ? "" : ".") << ME->getMemberDecl();
696    return false;
697  }
698}
699
700void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) {
701  OS << "__builtin_offsetof(";
702  PrintOffsetOfDesignator(Node->getSubExpr());
703  OS << ")";
704}
705
706void StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
707  OS << (Node->isSizeOf() ? "sizeof" : "__alignof");
708  if (Node->isArgumentType())
709    OS << "(" << Node->getArgumentType().getAsString() << ")";
710  else {
711    OS << " ";
712    PrintExpr(Node->getArgumentExpr());
713  }
714}
715void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
716  PrintExpr(Node->getLHS());
717  OS << "[";
718  PrintExpr(Node->getRHS());
719  OS << "]";
720}
721
722void StmtPrinter::VisitCallExpr(CallExpr *Call) {
723  PrintExpr(Call->getCallee());
724  OS << "(";
725  for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
726    if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
727      // Don't print any defaulted arguments
728      break;
729    }
730
731    if (i) OS << ", ";
732    PrintExpr(Call->getArg(i));
733  }
734  OS << ")";
735}
736void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
737  // FIXME: Suppress printing implicit bases (like "this")
738  PrintExpr(Node->getBase());
739  if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
740    if (FD->isAnonymousStructOrUnion())
741      return;
742  OS << (Node->isArrow() ? "->" : ".");
743  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
744    Qualifier->print(OS, Policy);
745
746  OS << Node->getMemberDecl();
747
748  if (Node->hasExplicitTemplateArgumentList())
749    OS << TemplateSpecializationType::PrintTemplateArgumentList(
750                                                    Node->getTemplateArgs(),
751                                                    Node->getNumTemplateArgs(),
752                                                                Policy);
753}
754void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
755  PrintExpr(Node->getBase());
756  OS << (Node->isArrow() ? "->isa" : ".isa");
757}
758
759void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
760  PrintExpr(Node->getBase());
761  OS << ".";
762  OS << Node->getAccessor().getName();
763}
764void StmtPrinter::VisitCastExpr(CastExpr *) {
765  assert(0 && "CastExpr is an abstract class");
766}
767void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *) {
768  assert(0 && "ExplicitCastExpr is an abstract class");
769}
770void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
771  OS << "(" << Node->getType().getAsString() << ")";
772  PrintExpr(Node->getSubExpr());
773}
774void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
775  OS << "(" << Node->getType().getAsString() << ")";
776  PrintExpr(Node->getInitializer());
777}
778void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
779  // No need to print anything, simply forward to the sub expression.
780  PrintExpr(Node->getSubExpr());
781}
782void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
783  PrintExpr(Node->getLHS());
784  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
785  PrintExpr(Node->getRHS());
786}
787void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
788  PrintExpr(Node->getLHS());
789  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
790  PrintExpr(Node->getRHS());
791}
792void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
793  PrintExpr(Node->getCond());
794
795  if (Node->getLHS()) {
796    OS << " ? ";
797    PrintExpr(Node->getLHS());
798    OS << " : ";
799  }
800  else { // Handle GCC extension where LHS can be NULL.
801    OS << " ?: ";
802  }
803
804  PrintExpr(Node->getRHS());
805}
806
807// GNU extensions.
808
809void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
810  OS << "&&" << Node->getLabel()->getName();
811}
812
813void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
814  OS << "(";
815  PrintRawCompoundStmt(E->getSubStmt());
816  OS << ")";
817}
818
819void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
820  OS << "__builtin_types_compatible_p(";
821  OS << Node->getArgType1().getAsString() << ",";
822  OS << Node->getArgType2().getAsString() << ")";
823}
824
825void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
826  OS << "__builtin_choose_expr(";
827  PrintExpr(Node->getCond());
828  OS << ", ";
829  PrintExpr(Node->getLHS());
830  OS << ", ";
831  PrintExpr(Node->getRHS());
832  OS << ")";
833}
834
835void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
836  OS << "__null";
837}
838
839void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
840  OS << "__builtin_shufflevector(";
841  for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
842    if (i) OS << ", ";
843    PrintExpr(Node->getExpr(i));
844  }
845  OS << ")";
846}
847
848void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
849  if (Node->getSyntacticForm()) {
850    Visit(Node->getSyntacticForm());
851    return;
852  }
853
854  OS << "{ ";
855  for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
856    if (i) OS << ", ";
857    if (Node->getInit(i))
858      PrintExpr(Node->getInit(i));
859    else
860      OS << "0";
861  }
862  OS << " }";
863}
864
865void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
866  OS << "( ";
867  for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
868    if (i) OS << ", ";
869    PrintExpr(Node->getExpr(i));
870  }
871  OS << " )";
872}
873
874void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
875  for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(),
876                      DEnd = Node->designators_end();
877       D != DEnd; ++D) {
878    if (D->isFieldDesignator()) {
879      if (D->getDotLoc().isInvalid())
880        OS << D->getFieldName()->getName() << ":";
881      else
882        OS << "." << D->getFieldName()->getName();
883    } else {
884      OS << "[";
885      if (D->isArrayDesignator()) {
886        PrintExpr(Node->getArrayIndex(*D));
887      } else {
888        PrintExpr(Node->getArrayRangeStart(*D));
889        OS << " ... ";
890        PrintExpr(Node->getArrayRangeEnd(*D));
891      }
892      OS << "]";
893    }
894  }
895
896  OS << " = ";
897  PrintExpr(Node->getInit());
898}
899
900void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
901  if (Policy.LangOpts.CPlusPlus)
902    OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()";
903  else {
904    OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")";
905    if (Node->getType()->isRecordType())
906      OS << "{}";
907    else
908      OS << 0;
909  }
910}
911
912void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
913  OS << "__builtin_va_arg(";
914  PrintExpr(Node->getSubExpr());
915  OS << ", ";
916  OS << Node->getType().getAsString();
917  OS << ")";
918}
919
920// C++
921void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
922  const char *OpStrings[NUM_OVERLOADED_OPERATORS] = {
923    "",
924#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
925    Spelling,
926#include "clang/Basic/OperatorKinds.def"
927  };
928
929  OverloadedOperatorKind Kind = Node->getOperator();
930  if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
931    if (Node->getNumArgs() == 1) {
932      OS << OpStrings[Kind] << ' ';
933      PrintExpr(Node->getArg(0));
934    } else {
935      PrintExpr(Node->getArg(0));
936      OS << ' ' << OpStrings[Kind];
937    }
938  } else if (Kind == OO_Call) {
939    PrintExpr(Node->getArg(0));
940    OS << '(';
941    for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
942      if (ArgIdx > 1)
943        OS << ", ";
944      if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
945        PrintExpr(Node->getArg(ArgIdx));
946    }
947    OS << ')';
948  } else if (Kind == OO_Subscript) {
949    PrintExpr(Node->getArg(0));
950    OS << '[';
951    PrintExpr(Node->getArg(1));
952    OS << ']';
953  } else if (Node->getNumArgs() == 1) {
954    OS << OpStrings[Kind] << ' ';
955    PrintExpr(Node->getArg(0));
956  } else if (Node->getNumArgs() == 2) {
957    PrintExpr(Node->getArg(0));
958    OS << ' ' << OpStrings[Kind] << ' ';
959    PrintExpr(Node->getArg(1));
960  } else {
961    assert(false && "unknown overloaded operator");
962  }
963}
964
965void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
966  VisitCallExpr(cast<CallExpr>(Node));
967}
968
969void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
970  OS << Node->getCastName() << '<';
971  OS << Node->getTypeAsWritten().getAsString() << ">(";
972  PrintExpr(Node->getSubExpr());
973  OS << ")";
974}
975
976void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
977  VisitCXXNamedCastExpr(Node);
978}
979
980void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
981  VisitCXXNamedCastExpr(Node);
982}
983
984void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
985  VisitCXXNamedCastExpr(Node);
986}
987
988void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
989  VisitCXXNamedCastExpr(Node);
990}
991
992void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
993  OS << "typeid(";
994  if (Node->isTypeOperand()) {
995    OS << Node->getTypeOperand().getAsString();
996  } else {
997    PrintExpr(Node->getExprOperand());
998  }
999  OS << ")";
1000}
1001
1002void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
1003  OS << (Node->getValue() ? "true" : "false");
1004}
1005
1006void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
1007  OS << "nullptr";
1008}
1009
1010void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
1011  OS << "this";
1012}
1013
1014void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
1015  if (Node->getSubExpr() == 0)
1016    OS << "throw";
1017  else {
1018    OS << "throw ";
1019    PrintExpr(Node->getSubExpr());
1020  }
1021}
1022
1023void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
1024  // Nothing to print: we picked up the default argument
1025}
1026
1027void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
1028  OS << Node->getType().getAsString();
1029  OS << "(";
1030  PrintExpr(Node->getSubExpr());
1031  OS << ")";
1032}
1033
1034void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
1035  PrintExpr(Node->getSubExpr());
1036}
1037
1038void StmtPrinter::VisitCXXBindReferenceExpr(CXXBindReferenceExpr *Node) {
1039  PrintExpr(Node->getSubExpr());
1040}
1041
1042void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
1043  OS << Node->getType().getAsString();
1044  OS << "(";
1045  for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
1046                                         ArgEnd = Node->arg_end();
1047       Arg != ArgEnd; ++Arg) {
1048    if (Arg != Node->arg_begin())
1049      OS << ", ";
1050    PrintExpr(*Arg);
1051  }
1052  OS << ")";
1053}
1054
1055void StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) {
1056  OS << Node->getType().getAsString() << "()";
1057}
1058
1059void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
1060  if (E->isGlobalNew())
1061    OS << "::";
1062  OS << "new ";
1063  unsigned NumPlace = E->getNumPlacementArgs();
1064  if (NumPlace > 0) {
1065    OS << "(";
1066    PrintExpr(E->getPlacementArg(0));
1067    for (unsigned i = 1; i < NumPlace; ++i) {
1068      OS << ", ";
1069      PrintExpr(E->getPlacementArg(i));
1070    }
1071    OS << ") ";
1072  }
1073  if (E->isParenTypeId())
1074    OS << "(";
1075  std::string TypeS;
1076  if (Expr *Size = E->getArraySize()) {
1077    llvm::raw_string_ostream s(TypeS);
1078    Size->printPretty(s, Context, Helper, Policy);
1079    s.flush();
1080    TypeS = "[" + TypeS + "]";
1081  }
1082  E->getAllocatedType().getAsStringInternal(TypeS, Policy);
1083  OS << TypeS;
1084  if (E->isParenTypeId())
1085    OS << ")";
1086
1087  if (E->hasInitializer()) {
1088    OS << "(";
1089    unsigned NumCons = E->getNumConstructorArgs();
1090    if (NumCons > 0) {
1091      PrintExpr(E->getConstructorArg(0));
1092      for (unsigned i = 1; i < NumCons; ++i) {
1093        OS << ", ";
1094        PrintExpr(E->getConstructorArg(i));
1095      }
1096    }
1097    OS << ")";
1098  }
1099}
1100
1101void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
1102  if (E->isGlobalDelete())
1103    OS << "::";
1104  OS << "delete ";
1105  if (E->isArrayForm())
1106    OS << "[] ";
1107  PrintExpr(E->getArgument());
1108}
1109
1110void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1111  PrintExpr(E->getBase());
1112  if (E->isArrow())
1113    OS << "->";
1114  else
1115    OS << '.';
1116  if (E->getQualifier())
1117    E->getQualifier()->print(OS, Policy);
1118
1119  std::string TypeS;
1120  if (IdentifierInfo *II = E->getDestroyedTypeIdentifier())
1121    OS << II->getName();
1122  else
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() << ')';
1243}
1244
1245void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
1246  OS << "[";
1247  switch (Mess->getReceiverKind()) {
1248  case ObjCMessageExpr::Instance:
1249    PrintExpr(Mess->getInstanceReceiver());
1250    break;
1251
1252  case ObjCMessageExpr::Class:
1253    OS << Mess->getClassReceiver().getAsString(Policy);
1254    break;
1255
1256  case ObjCMessageExpr::SuperInstance:
1257  case ObjCMessageExpr::SuperClass:
1258    OS << "Super";
1259    break;
1260  }
1261
1262  OS << ' ';
1263  Selector selector = Mess->getSelector();
1264  if (selector.isUnarySelector()) {
1265    OS << selector.getIdentifierInfoForSlot(0)->getName();
1266  } else {
1267    for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
1268      if (i < selector.getNumArgs()) {
1269        if (i > 0) OS << ' ';
1270        if (selector.getIdentifierInfoForSlot(i))
1271          OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
1272        else
1273           OS << ":";
1274      }
1275      else OS << ", "; // Handle variadic methods.
1276
1277      PrintExpr(Mess->getArg(i));
1278    }
1279  }
1280  OS << "]";
1281}
1282
1283void StmtPrinter::VisitObjCSuperExpr(ObjCSuperExpr *) {
1284  OS << "super";
1285}
1286
1287void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
1288  BlockDecl *BD = Node->getBlockDecl();
1289  OS << "^";
1290
1291  const FunctionType *AFT = Node->getFunctionType();
1292
1293  if (isa<FunctionNoProtoType>(AFT)) {
1294    OS << "()";
1295  } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
1296    OS << '(';
1297    std::string ParamStr;
1298    for (BlockDecl::param_iterator AI = BD->param_begin(),
1299         E = BD->param_end(); AI != E; ++AI) {
1300      if (AI != BD->param_begin()) OS << ", ";
1301      ParamStr = (*AI)->getNameAsString();
1302      (*AI)->getType().getAsStringInternal(ParamStr, Policy);
1303      OS << ParamStr;
1304    }
1305
1306    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
1307    if (FT->isVariadic()) {
1308      if (!BD->param_empty()) OS << ", ";
1309      OS << "...";
1310    }
1311    OS << ')';
1312  }
1313}
1314
1315void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
1316  OS << Node->getDecl();
1317}
1318//===----------------------------------------------------------------------===//
1319// Stmt method implementations
1320//===----------------------------------------------------------------------===//
1321
1322void Stmt::dumpPretty(ASTContext& Context) const {
1323  printPretty(llvm::errs(), Context, 0,
1324              PrintingPolicy(Context.getLangOptions()));
1325}
1326
1327void Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context,
1328                       PrinterHelper* Helper,
1329                       const PrintingPolicy &Policy,
1330                       unsigned Indentation) const {
1331  if (this == 0) {
1332    OS << "<NULL>";
1333    return;
1334  }
1335
1336  if (Policy.Dump && &Context) {
1337    dump(Context.getSourceManager());
1338    return;
1339  }
1340
1341  StmtPrinter P(OS, Context, Helper, Policy, Indentation);
1342  P.Visit(const_cast<Stmt*>(this));
1343}
1344
1345//===----------------------------------------------------------------------===//
1346// PrinterHelper
1347//===----------------------------------------------------------------------===//
1348
1349// Implement virtual destructor.
1350PrinterHelper::~PrinterHelper() {}
1351