StmtPrinter.cpp revision 2e156225a29407a50dd19041aa5750171ad44ea3
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"
21#include "clang/AST/ExprCXX.h"
22using namespace clang;
23
24//===----------------------------------------------------------------------===//
25// StmtPrinter Visitor
26//===----------------------------------------------------------------------===//
27
28namespace  {
29  class StmtPrinter : public StmtVisitor<StmtPrinter> {
30    llvm::raw_ostream &OS;
31    ASTContext &Context;
32    unsigned IndentLevel;
33    clang::PrinterHelper* Helper;
34    PrintingPolicy Policy;
35
36  public:
37    StmtPrinter(llvm::raw_ostream &os, ASTContext &C, PrinterHelper* helper,
38                const PrintingPolicy &Policy,
39                unsigned Indentation = 0)
40      : OS(os), Context(C), IndentLevel(Indentation), Helper(helper),
41        Policy(Policy) {}
42
43    void PrintStmt(Stmt *S) {
44      PrintStmt(S, Policy.Indentation);
45    }
46
47    void PrintStmt(Stmt *S, int SubIndent) {
48      IndentLevel += SubIndent;
49      if (S && isa<Expr>(S)) {
50        // If this is an expr used in a stmt context, indent and newline it.
51        Indent();
52        Visit(S);
53        OS << ";\n";
54      } else if (S) {
55        Visit(S);
56      } else {
57        Indent() << "<<<NULL STATEMENT>>>\n";
58      }
59      IndentLevel -= SubIndent;
60    }
61
62    void PrintRawCompoundStmt(CompoundStmt *S);
63    void PrintRawDecl(Decl *D);
64    void PrintRawDeclStmt(DeclStmt *S);
65    void PrintRawIfStmt(IfStmt *If);
66    void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
67
68    void PrintExpr(Expr *E) {
69      if (E)
70        Visit(E);
71      else
72        OS << "<null expr>";
73    }
74
75    llvm::raw_ostream &Indent(int Delta = 0) {
76      for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
77        OS << "  ";
78      return OS;
79    }
80
81    void Visit(Stmt* S) {
82      if (Helper && Helper->handledStmt(S,OS))
83          return;
84      else StmtVisitor<StmtPrinter>::Visit(S);
85    }
86
87    void VisitStmt(Stmt *Node) ATTRIBUTE_UNUSED {
88      Indent() << "<<unknown stmt type>>\n";
89    }
90    void VisitExpr(Expr *Node) ATTRIBUTE_UNUSED {
91      OS << "<<unknown expr type>>";
92    }
93    void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
94
95#define ABSTRACT_STMT(CLASS)
96#define STMT(CLASS, PARENT) \
97    void Visit##CLASS(CLASS *Node);
98#include "clang/AST/StmtNodes.inc"
99  };
100}
101
102//===----------------------------------------------------------------------===//
103//  Stmt printing methods.
104//===----------------------------------------------------------------------===//
105
106/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
107/// with no newline after the }.
108void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
109  OS << "{\n";
110  for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
111       I != E; ++I)
112    PrintStmt(*I);
113
114  Indent() << "}";
115}
116
117void StmtPrinter::PrintRawDecl(Decl *D) {
118  D->print(OS, Policy, IndentLevel);
119}
120
121void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
122  DeclStmt::decl_iterator Begin = S->decl_begin(), End = S->decl_end();
123  llvm::SmallVector<Decl*, 2> Decls;
124  for ( ; Begin != End; ++Begin)
125    Decls.push_back(*Begin);
126
127  Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
128}
129
130void StmtPrinter::VisitNullStmt(NullStmt *Node) {
131  Indent() << ";\n";
132}
133
134void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
135  Indent();
136  PrintRawDeclStmt(Node);
137  OS << ";\n";
138}
139
140void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
141  Indent();
142  PrintRawCompoundStmt(Node);
143  OS << "\n";
144}
145
146void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
147  Indent(-1) << "case ";
148  PrintExpr(Node->getLHS());
149  if (Node->getRHS()) {
150    OS << " ... ";
151    PrintExpr(Node->getRHS());
152  }
153  OS << ":\n";
154
155  PrintStmt(Node->getSubStmt(), 0);
156}
157
158void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
159  Indent(-1) << "default:\n";
160  PrintStmt(Node->getSubStmt(), 0);
161}
162
163void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
164  Indent(-1) << Node->getName() << ":\n";
165  PrintStmt(Node->getSubStmt(), 0);
166}
167
168void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
169  OS << "if (";
170  PrintExpr(If->getCond());
171  OS << ')';
172
173  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) {
174    OS << ' ';
175    PrintRawCompoundStmt(CS);
176    OS << (If->getElse() ? ' ' : '\n');
177  } else {
178    OS << '\n';
179    PrintStmt(If->getThen());
180    if (If->getElse()) Indent();
181  }
182
183  if (Stmt *Else = If->getElse()) {
184    OS << "else";
185
186    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) {
187      OS << ' ';
188      PrintRawCompoundStmt(CS);
189      OS << '\n';
190    } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) {
191      OS << ' ';
192      PrintRawIfStmt(ElseIf);
193    } else {
194      OS << '\n';
195      PrintStmt(If->getElse());
196    }
197  }
198}
199
200void StmtPrinter::VisitIfStmt(IfStmt *If) {
201  Indent();
202  PrintRawIfStmt(If);
203}
204
205void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
206  Indent() << "switch (";
207  PrintExpr(Node->getCond());
208  OS << ")";
209
210  // Pretty print compoundstmt bodies (very common).
211  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
212    OS << " ";
213    PrintRawCompoundStmt(CS);
214    OS << "\n";
215  } else {
216    OS << "\n";
217    PrintStmt(Node->getBody());
218  }
219}
220
221void StmtPrinter::VisitSwitchCase(SwitchCase*) {
222  assert(0 && "SwitchCase is an abstract class");
223}
224
225void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
226  Indent() << "while (";
227  PrintExpr(Node->getCond());
228  OS << ")\n";
229  PrintStmt(Node->getBody());
230}
231
232void StmtPrinter::VisitDoStmt(DoStmt *Node) {
233  Indent() << "do ";
234  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
235    PrintRawCompoundStmt(CS);
236    OS << " ";
237  } else {
238    OS << "\n";
239    PrintStmt(Node->getBody());
240    Indent();
241  }
242
243  OS << "while (";
244  PrintExpr(Node->getCond());
245  OS << ");\n";
246}
247
248void StmtPrinter::VisitForStmt(ForStmt *Node) {
249  Indent() << "for (";
250  if (Node->getInit()) {
251    if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit()))
252      PrintRawDeclStmt(DS);
253    else
254      PrintExpr(cast<Expr>(Node->getInit()));
255  }
256  OS << ";";
257  if (Node->getCond()) {
258    OS << " ";
259    PrintExpr(Node->getCond());
260  }
261  OS << ";";
262  if (Node->getInc()) {
263    OS << " ";
264    PrintExpr(Node->getInc());
265  }
266  OS << ") ";
267
268  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
269    PrintRawCompoundStmt(CS);
270    OS << "\n";
271  } else {
272    OS << "\n";
273    PrintStmt(Node->getBody());
274  }
275}
276
277void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
278  Indent() << "for (";
279  if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement()))
280    PrintRawDeclStmt(DS);
281  else
282    PrintExpr(cast<Expr>(Node->getElement()));
283  OS << " in ";
284  PrintExpr(Node->getCollection());
285  OS << ") ";
286
287  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
288    PrintRawCompoundStmt(CS);
289    OS << "\n";
290  } else {
291    OS << "\n";
292    PrintStmt(Node->getBody());
293  }
294}
295
296void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
297  Indent() << "goto " << Node->getLabel()->getName() << ";\n";
298}
299
300void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
301  Indent() << "goto *";
302  PrintExpr(Node->getTarget());
303  OS << ";\n";
304}
305
306void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
307  Indent() << "continue;\n";
308}
309
310void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
311  Indent() << "break;\n";
312}
313
314
315void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
316  Indent() << "return";
317  if (Node->getRetValue()) {
318    OS << " ";
319    PrintExpr(Node->getRetValue());
320  }
321  OS << ";\n";
322}
323
324
325void StmtPrinter::VisitAsmStmt(AsmStmt *Node) {
326  Indent() << "asm ";
327
328  if (Node->isVolatile())
329    OS << "volatile ";
330
331  OS << "(";
332  VisitStringLiteral(Node->getAsmString());
333
334  // Outputs
335  if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
336      Node->getNumClobbers() != 0)
337    OS << " : ";
338
339  for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
340    if (i != 0)
341      OS << ", ";
342
343    if (!Node->getOutputName(i).empty()) {
344      OS << '[';
345      OS << Node->getOutputName(i);
346      OS << "] ";
347    }
348
349    VisitStringLiteral(Node->getOutputConstraintLiteral(i));
350    OS << " ";
351    Visit(Node->getOutputExpr(i));
352  }
353
354  // Inputs
355  if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
356    OS << " : ";
357
358  for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
359    if (i != 0)
360      OS << ", ";
361
362    if (!Node->getInputName(i).empty()) {
363      OS << '[';
364      OS << Node->getInputName(i);
365      OS << "] ";
366    }
367
368    VisitStringLiteral(Node->getInputConstraintLiteral(i));
369    OS << " ";
370    Visit(Node->getInputExpr(i));
371  }
372
373  // Clobbers
374  if (Node->getNumClobbers() != 0)
375    OS << " : ";
376
377  for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
378    if (i != 0)
379      OS << ", ";
380
381    VisitStringLiteral(Node->getClobber(i));
382  }
383
384  OS << ");\n";
385}
386
387void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
388  Indent() << "@try";
389  if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
390    PrintRawCompoundStmt(TS);
391    OS << "\n";
392  }
393
394  for (unsigned I = 0, N = Node->getNumCatchStmts(); I != N; ++I) {
395    ObjCAtCatchStmt *catchStmt = Node->getCatchStmt(I);
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::VisitDeclRefExpr(DeclRefExpr *Node) {
471  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
472    Qualifier->print(OS, Policy);
473  OS << Node->getNameInfo();
474  if (Node->hasExplicitTemplateArgs())
475    OS << TemplateSpecializationType::PrintTemplateArgumentList(
476                                                    Node->getTemplateArgs(),
477                                                    Node->getNumTemplateArgs(),
478                                                    Policy);
479}
480
481void StmtPrinter::VisitDependentScopeDeclRefExpr(
482                                           DependentScopeDeclRefExpr *Node) {
483  Node->getQualifier()->print(OS, Policy);
484  OS << Node->getNameInfo();
485  if (Node->hasExplicitTemplateArgs())
486    OS << TemplateSpecializationType::PrintTemplateArgumentList(
487                                                   Node->getTemplateArgs(),
488                                                   Node->getNumTemplateArgs(),
489                                                   Policy);
490}
491
492void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
493  if (Node->getQualifier())
494    Node->getQualifier()->print(OS, Policy);
495  OS << Node->getNameInfo();
496  if (Node->hasExplicitTemplateArgs())
497    OS << TemplateSpecializationType::PrintTemplateArgumentList(
498                                                   Node->getTemplateArgs(),
499                                                   Node->getNumTemplateArgs(),
500                                                   Policy);
501}
502
503void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
504  if (Node->getBase()) {
505    PrintExpr(Node->getBase());
506    OS << (Node->isArrow() ? "->" : ".");
507  }
508  OS << Node->getDecl();
509}
510
511void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
512  if (Node->getBase()) {
513    PrintExpr(Node->getBase());
514    OS << ".";
515  }
516  OS << Node->getProperty()->getName();
517}
518
519void StmtPrinter::VisitObjCImplicitSetterGetterRefExpr(
520                                        ObjCImplicitSetterGetterRefExpr *Node) {
521  if (Node->getBase()) {
522    PrintExpr(Node->getBase());
523    OS << ".";
524  }
525  if (Node->getGetterMethod())
526    OS << Node->getGetterMethod();
527
528}
529
530void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
531  switch (Node->getIdentType()) {
532    default:
533      assert(0 && "unknown case");
534    case PredefinedExpr::Func:
535      OS << "__func__";
536      break;
537    case PredefinedExpr::Function:
538      OS << "__FUNCTION__";
539      break;
540    case PredefinedExpr::PrettyFunction:
541      OS << "__PRETTY_FUNCTION__";
542      break;
543  }
544}
545
546void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
547  unsigned value = Node->getValue();
548  if (Node->isWide())
549    OS << "L";
550  switch (value) {
551  case '\\':
552    OS << "'\\\\'";
553    break;
554  case '\'':
555    OS << "'\\''";
556    break;
557  case '\a':
558    // TODO: K&R: the meaning of '\\a' is different in traditional C
559    OS << "'\\a'";
560    break;
561  case '\b':
562    OS << "'\\b'";
563    break;
564  // Nonstandard escape sequence.
565  /*case '\e':
566    OS << "'\\e'";
567    break;*/
568  case '\f':
569    OS << "'\\f'";
570    break;
571  case '\n':
572    OS << "'\\n'";
573    break;
574  case '\r':
575    OS << "'\\r'";
576    break;
577  case '\t':
578    OS << "'\\t'";
579    break;
580  case '\v':
581    OS << "'\\v'";
582    break;
583  default:
584    if (value < 256 && isprint(value)) {
585      OS << "'" << (char)value << "'";
586    } else if (value < 256) {
587      OS << "'\\x" << llvm::format("%x", value) << "'";
588    } else {
589      // FIXME what to really do here?
590      OS << value;
591    }
592  }
593}
594
595void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
596  bool isSigned = Node->getType()->isSignedIntegerType();
597  OS << Node->getValue().toString(10, isSigned);
598
599  // Emit suffixes.  Integer literals are always a builtin integer type.
600  switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
601  default: assert(0 && "Unexpected type for integer literal!");
602  case BuiltinType::Int:       break; // no suffix.
603  case BuiltinType::UInt:      OS << 'U'; break;
604  case BuiltinType::Long:      OS << 'L'; break;
605  case BuiltinType::ULong:     OS << "UL"; break;
606  case BuiltinType::LongLong:  OS << "LL"; break;
607  case BuiltinType::ULongLong: OS << "ULL"; break;
608  }
609}
610void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
611  // FIXME: print value more precisely.
612  OS << Node->getValueAsApproximateDouble();
613}
614
615void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
616  PrintExpr(Node->getSubExpr());
617  OS << "i";
618}
619
620void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
621  if (Str->isWide()) OS << 'L';
622  OS << '"';
623
624  // FIXME: this doesn't print wstrings right.
625  llvm::StringRef StrData = Str->getString();
626  for (llvm::StringRef::iterator I = StrData.begin(), E = StrData.end();
627                                                             I != E; ++I) {
628    unsigned char Char = *I;
629
630    switch (Char) {
631    default:
632      if (isprint(Char))
633        OS << (char)Char;
634      else  // Output anything hard as an octal escape.
635        OS << '\\'
636        << (char)('0'+ ((Char >> 6) & 7))
637        << (char)('0'+ ((Char >> 3) & 7))
638        << (char)('0'+ ((Char >> 0) & 7));
639      break;
640    // Handle some common non-printable cases to make dumps prettier.
641    case '\\': OS << "\\\\"; break;
642    case '"': OS << "\\\""; break;
643    case '\n': OS << "\\n"; break;
644    case '\t': OS << "\\t"; break;
645    case '\a': OS << "\\a"; break;
646    case '\b': OS << "\\b"; break;
647    }
648  }
649  OS << '"';
650}
651void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
652  OS << "(";
653  PrintExpr(Node->getSubExpr());
654  OS << ")";
655}
656void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
657  if (!Node->isPostfix()) {
658    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
659
660    // Print a space if this is an "identifier operator" like __real, or if
661    // it might be concatenated incorrectly like '+'.
662    switch (Node->getOpcode()) {
663    default: break;
664    case UO_Real:
665    case UO_Imag:
666    case UO_Extension:
667      OS << ' ';
668      break;
669    case UO_Plus:
670    case UO_Minus:
671      if (isa<UnaryOperator>(Node->getSubExpr()))
672        OS << ' ';
673      break;
674    }
675  }
676  PrintExpr(Node->getSubExpr());
677
678  if (Node->isPostfix())
679    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
680}
681
682void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
683  OS << "__builtin_offsetof(";
684  OS << Node->getTypeSourceInfo()->getType().getAsString(Policy) << ", ";
685  bool PrintedSomething = false;
686  for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
687    OffsetOfExpr::OffsetOfNode ON = Node->getComponent(i);
688    if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Array) {
689      // Array node
690      OS << "[";
691      PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
692      OS << "]";
693      PrintedSomething = true;
694      continue;
695    }
696
697    // Skip implicit base indirections.
698    if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Base)
699      continue;
700
701    // Field or identifier node.
702    IdentifierInfo *Id = ON.getFieldName();
703    if (!Id)
704      continue;
705
706    if (PrintedSomething)
707      OS << ".";
708    else
709      PrintedSomething = true;
710    OS << Id->getName();
711  }
712  OS << ")";
713}
714
715void StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
716  OS << (Node->isSizeOf() ? "sizeof" : "__alignof");
717  if (Node->isArgumentType())
718    OS << "(" << Node->getArgumentType().getAsString(Policy) << ")";
719  else {
720    OS << " ";
721    PrintExpr(Node->getArgumentExpr());
722  }
723}
724void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
725  PrintExpr(Node->getLHS());
726  OS << "[";
727  PrintExpr(Node->getRHS());
728  OS << "]";
729}
730
731void StmtPrinter::VisitCallExpr(CallExpr *Call) {
732  PrintExpr(Call->getCallee());
733  OS << "(";
734  for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
735    if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
736      // Don't print any defaulted arguments
737      break;
738    }
739
740    if (i) OS << ", ";
741    PrintExpr(Call->getArg(i));
742  }
743  OS << ")";
744}
745void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
746  // FIXME: Suppress printing implicit bases (like "this")
747  PrintExpr(Node->getBase());
748  if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
749    if (FD->isAnonymousStructOrUnion())
750      return;
751  OS << (Node->isArrow() ? "->" : ".");
752  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
753    Qualifier->print(OS, Policy);
754
755  OS << Node->getMemberNameInfo();
756
757  if (Node->hasExplicitTemplateArgs())
758    OS << TemplateSpecializationType::PrintTemplateArgumentList(
759                                                    Node->getTemplateArgs(),
760                                                    Node->getNumTemplateArgs(),
761                                                                Policy);
762}
763void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
764  PrintExpr(Node->getBase());
765  OS << (Node->isArrow() ? "->isa" : ".isa");
766}
767
768void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
769  PrintExpr(Node->getBase());
770  OS << ".";
771  OS << Node->getAccessor().getName();
772}
773void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
774  OS << "(" << Node->getType().getAsString(Policy) << ")";
775  PrintExpr(Node->getSubExpr());
776}
777void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
778  OS << "(" << Node->getType().getAsString(Policy) << ")";
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(Policy) << ",";
825  OS << Node->getArgType2().getAsString(Policy) << ")";
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(Policy);
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(Policy) << ">(";
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(Policy);
999  } else {
1000    PrintExpr(Node->getExprOperand());
1001  }
1002  OS << ")";
1003}
1004
1005void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
1006  OS << "__uuidof(";
1007  if (Node->isTypeOperand()) {
1008    OS << Node->getTypeOperand().getAsString(Policy);
1009  } else {
1010    PrintExpr(Node->getExprOperand());
1011  }
1012  OS << ")";
1013}
1014
1015void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
1016  OS << (Node->getValue() ? "true" : "false");
1017}
1018
1019void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
1020  OS << "nullptr";
1021}
1022
1023void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
1024  OS << "this";
1025}
1026
1027void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
1028  if (Node->getSubExpr() == 0)
1029    OS << "throw";
1030  else {
1031    OS << "throw ";
1032    PrintExpr(Node->getSubExpr());
1033  }
1034}
1035
1036void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
1037  // Nothing to print: we picked up the default argument
1038}
1039
1040void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
1041  OS << Node->getType().getAsString(Policy);
1042  OS << "(";
1043  PrintExpr(Node->getSubExpr());
1044  OS << ")";
1045}
1046
1047void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
1048  PrintExpr(Node->getSubExpr());
1049}
1050
1051void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
1052  OS << Node->getType().getAsString(Policy);
1053  OS << "(";
1054  for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
1055                                         ArgEnd = Node->arg_end();
1056       Arg != ArgEnd; ++Arg) {
1057    if (Arg != Node->arg_begin())
1058      OS << ", ";
1059    PrintExpr(*Arg);
1060  }
1061  OS << ")";
1062}
1063
1064void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
1065  if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
1066    OS << TSInfo->getType().getAsString(Policy) << "()";
1067  else
1068    OS << Node->getType().getAsString(Policy) << "()";
1069}
1070
1071void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
1072  if (E->isGlobalNew())
1073    OS << "::";
1074  OS << "new ";
1075  unsigned NumPlace = E->getNumPlacementArgs();
1076  if (NumPlace > 0) {
1077    OS << "(";
1078    PrintExpr(E->getPlacementArg(0));
1079    for (unsigned i = 1; i < NumPlace; ++i) {
1080      OS << ", ";
1081      PrintExpr(E->getPlacementArg(i));
1082    }
1083    OS << ") ";
1084  }
1085  if (E->isParenTypeId())
1086    OS << "(";
1087  std::string TypeS;
1088  if (Expr *Size = E->getArraySize()) {
1089    llvm::raw_string_ostream s(TypeS);
1090    Size->printPretty(s, Context, Helper, Policy);
1091    s.flush();
1092    TypeS = "[" + TypeS + "]";
1093  }
1094  E->getAllocatedType().getAsStringInternal(TypeS, Policy);
1095  OS << TypeS;
1096  if (E->isParenTypeId())
1097    OS << ")";
1098
1099  if (E->hasInitializer()) {
1100    OS << "(";
1101    unsigned NumCons = E->getNumConstructorArgs();
1102    if (NumCons > 0) {
1103      PrintExpr(E->getConstructorArg(0));
1104      for (unsigned i = 1; i < NumCons; ++i) {
1105        OS << ", ";
1106        PrintExpr(E->getConstructorArg(i));
1107      }
1108    }
1109    OS << ")";
1110  }
1111}
1112
1113void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
1114  if (E->isGlobalDelete())
1115    OS << "::";
1116  OS << "delete ";
1117  if (E->isArrayForm())
1118    OS << "[] ";
1119  PrintExpr(E->getArgument());
1120}
1121
1122void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1123  PrintExpr(E->getBase());
1124  if (E->isArrow())
1125    OS << "->";
1126  else
1127    OS << '.';
1128  if (E->getQualifier())
1129    E->getQualifier()->print(OS, Policy);
1130
1131  std::string TypeS;
1132  if (IdentifierInfo *II = E->getDestroyedTypeIdentifier())
1133    OS << II->getName();
1134  else
1135    E->getDestroyedType().getAsStringInternal(TypeS, Policy);
1136  OS << TypeS;
1137}
1138
1139void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
1140  // FIXME. For now we just print a trivial constructor call expression,
1141  // constructing its first argument object.
1142  if (E->getNumArgs() == 1) {
1143    CXXConstructorDecl *CD = E->getConstructor();
1144    if (CD->isTrivial())
1145      PrintExpr(E->getArg(0));
1146  }
1147  // Nothing to print.
1148}
1149
1150void StmtPrinter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
1151  // Just forward to the sub expression.
1152  PrintExpr(E->getSubExpr());
1153}
1154
1155void
1156StmtPrinter::VisitCXXUnresolvedConstructExpr(
1157                                           CXXUnresolvedConstructExpr *Node) {
1158  OS << Node->getTypeAsWritten().getAsString(Policy);
1159  OS << "(";
1160  for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(),
1161                                             ArgEnd = Node->arg_end();
1162       Arg != ArgEnd; ++Arg) {
1163    if (Arg != Node->arg_begin())
1164      OS << ", ";
1165    PrintExpr(*Arg);
1166  }
1167  OS << ")";
1168}
1169
1170void StmtPrinter::VisitCXXDependentScopeMemberExpr(
1171                                         CXXDependentScopeMemberExpr *Node) {
1172  if (!Node->isImplicitAccess()) {
1173    PrintExpr(Node->getBase());
1174    OS << (Node->isArrow() ? "->" : ".");
1175  }
1176  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1177    Qualifier->print(OS, Policy);
1178  else if (Node->hasExplicitTemplateArgs())
1179    // FIXME: Track use of "template" keyword explicitly?
1180    OS << "template ";
1181
1182  OS << Node->getMemberNameInfo();
1183
1184  if (Node->hasExplicitTemplateArgs()) {
1185    OS << TemplateSpecializationType::PrintTemplateArgumentList(
1186                                                    Node->getTemplateArgs(),
1187                                                    Node->getNumTemplateArgs(),
1188                                                    Policy);
1189  }
1190}
1191
1192void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
1193  if (!Node->isImplicitAccess()) {
1194    PrintExpr(Node->getBase());
1195    OS << (Node->isArrow() ? "->" : ".");
1196  }
1197  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1198    Qualifier->print(OS, Policy);
1199
1200  // FIXME: this might originally have been written with 'template'
1201
1202  OS << Node->getMemberNameInfo();
1203
1204  if (Node->hasExplicitTemplateArgs()) {
1205    OS << TemplateSpecializationType::PrintTemplateArgumentList(
1206                                                    Node->getTemplateArgs(),
1207                                                    Node->getNumTemplateArgs(),
1208                                                    Policy);
1209  }
1210}
1211
1212static const char *getTypeTraitName(UnaryTypeTrait UTT) {
1213  switch (UTT) {
1214  default: assert(false && "Unknown type trait");
1215  case UTT_HasNothrowAssign:      return "__has_nothrow_assign";
1216  case UTT_HasNothrowCopy:        return "__has_nothrow_copy";
1217  case UTT_HasNothrowConstructor: return "__has_nothrow_constructor";
1218  case UTT_HasTrivialAssign:      return "__has_trivial_assign";
1219  case UTT_HasTrivialCopy:        return "__has_trivial_copy";
1220  case UTT_HasTrivialConstructor: return "__has_trivial_constructor";
1221  case UTT_HasTrivialDestructor:  return "__has_trivial_destructor";
1222  case UTT_HasVirtualDestructor:  return "__has_virtual_destructor";
1223  case UTT_IsAbstract:            return "__is_abstract";
1224  case UTT_IsClass:               return "__is_class";
1225  case UTT_IsEmpty:               return "__is_empty";
1226  case UTT_IsEnum:                return "__is_enum";
1227  case UTT_IsPOD:                 return "__is_pod";
1228  case UTT_IsPolymorphic:         return "__is_polymorphic";
1229  case UTT_IsUnion:               return "__is_union";
1230  }
1231}
1232
1233void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
1234  OS << getTypeTraitName(E->getTrait()) << "("
1235     << E->getQueriedType().getAsString(Policy) << ")";
1236}
1237
1238void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
1239  OS << "noexcept(";
1240  PrintExpr(E->getOperand());
1241  OS << ")";
1242}
1243
1244// Obj-C
1245
1246void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
1247  OS << "@";
1248  VisitStringLiteral(Node->getString());
1249}
1250
1251void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
1252  OS << "@encode(" << Node->getEncodedType().getAsString(Policy) << ')';
1253}
1254
1255void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
1256  OS << "@selector(" << Node->getSelector().getAsString() << ')';
1257}
1258
1259void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
1260  OS << "@protocol(" << Node->getProtocol() << ')';
1261}
1262
1263void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
1264  OS << "[";
1265  switch (Mess->getReceiverKind()) {
1266  case ObjCMessageExpr::Instance:
1267    PrintExpr(Mess->getInstanceReceiver());
1268    break;
1269
1270  case ObjCMessageExpr::Class:
1271    OS << Mess->getClassReceiver().getAsString(Policy);
1272    break;
1273
1274  case ObjCMessageExpr::SuperInstance:
1275  case ObjCMessageExpr::SuperClass:
1276    OS << "Super";
1277    break;
1278  }
1279
1280  OS << ' ';
1281  Selector selector = Mess->getSelector();
1282  if (selector.isUnarySelector()) {
1283    OS << selector.getIdentifierInfoForSlot(0)->getName();
1284  } else {
1285    for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
1286      if (i < selector.getNumArgs()) {
1287        if (i > 0) OS << ' ';
1288        if (selector.getIdentifierInfoForSlot(i))
1289          OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
1290        else
1291           OS << ":";
1292      }
1293      else OS << ", "; // Handle variadic methods.
1294
1295      PrintExpr(Mess->getArg(i));
1296    }
1297  }
1298  OS << "]";
1299}
1300
1301void StmtPrinter::VisitObjCSuperExpr(ObjCSuperExpr *) {
1302  OS << "super";
1303}
1304
1305void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
1306  BlockDecl *BD = Node->getBlockDecl();
1307  OS << "^";
1308
1309  const FunctionType *AFT = Node->getFunctionType();
1310
1311  if (isa<FunctionNoProtoType>(AFT)) {
1312    OS << "()";
1313  } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
1314    OS << '(';
1315    std::string ParamStr;
1316    for (BlockDecl::param_iterator AI = BD->param_begin(),
1317         E = BD->param_end(); AI != E; ++AI) {
1318      if (AI != BD->param_begin()) OS << ", ";
1319      ParamStr = (*AI)->getNameAsString();
1320      (*AI)->getType().getAsStringInternal(ParamStr, Policy);
1321      OS << ParamStr;
1322    }
1323
1324    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
1325    if (FT->isVariadic()) {
1326      if (!BD->param_empty()) OS << ", ";
1327      OS << "...";
1328    }
1329    OS << ')';
1330  }
1331}
1332
1333void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
1334  OS << Node->getDecl();
1335}
1336//===----------------------------------------------------------------------===//
1337// Stmt method implementations
1338//===----------------------------------------------------------------------===//
1339
1340void Stmt::dumpPretty(ASTContext& Context) const {
1341  printPretty(llvm::errs(), Context, 0,
1342              PrintingPolicy(Context.getLangOptions()));
1343}
1344
1345void Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context,
1346                       PrinterHelper* Helper,
1347                       const PrintingPolicy &Policy,
1348                       unsigned Indentation) const {
1349  if (this == 0) {
1350    OS << "<NULL>";
1351    return;
1352  }
1353
1354  if (Policy.Dump && &Context) {
1355    dump(OS, Context.getSourceManager());
1356    return;
1357  }
1358
1359  StmtPrinter P(OS, Context, Helper, Policy, Indentation);
1360  P.Visit(const_cast<Stmt*>(this));
1361}
1362
1363//===----------------------------------------------------------------------===//
1364// PrinterHelper
1365//===----------------------------------------------------------------------===//
1366
1367// Implement virtual destructor.
1368PrinterHelper::~PrinterHelper() {}
1369