StmtPrinter.cpp revision 987a14bf5883ef6e5d07f1c83eb6d41a8212a78c
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/DeclObjC.h"
17#include "clang/AST/PrettyPrinter.h"
18#include "llvm/Support/Compiler.h"
19#include "llvm/Support/Streams.h"
20using namespace clang;
21
22//===----------------------------------------------------------------------===//
23// StmtPrinter Visitor
24//===----------------------------------------------------------------------===//
25
26namespace  {
27  class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor<StmtPrinter> {
28    std::ostream &OS;
29    unsigned IndentLevel;
30    clang::PrinterHelper* Helper;
31  public:
32    StmtPrinter(std::ostream &os, PrinterHelper* helper) :
33      OS(os), IndentLevel(0), Helper(helper) {}
34
35    void PrintStmt(Stmt *S, int SubIndent = 1) {
36      IndentLevel += SubIndent;
37      if (S && isa<Expr>(S)) {
38        // If this is an expr used in a stmt context, indent and newline it.
39        Indent();
40        Visit(S);
41        OS << ";\n";
42      } else if (S) {
43        Visit(S);
44      } else {
45        Indent() << "<<<NULL STATEMENT>>>\n";
46      }
47      IndentLevel -= SubIndent;
48    }
49
50    void PrintRawCompoundStmt(CompoundStmt *S);
51    void PrintRawDecl(Decl *D);
52    void PrintRawIfStmt(IfStmt *If);
53
54    void PrintExpr(Expr *E) {
55      if (E)
56        Visit(E);
57      else
58        OS << "<null expr>";
59    }
60
61    std::ostream &Indent(int Delta = 0) const {
62      for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
63        OS << "  ";
64      return OS;
65    }
66
67    bool PrintOffsetOfDesignator(Expr *E);
68    void VisitUnaryOffsetOf(UnaryOperator *Node);
69
70    void Visit(Stmt* S) {
71      if (Helper && Helper->handledStmt(S,OS))
72          return;
73      else StmtVisitor<StmtPrinter>::Visit(S);
74    }
75
76    void VisitStmt(Stmt *Node);
77#define STMT(N, CLASS, PARENT) \
78    void Visit##CLASS(CLASS *Node);
79#include "clang/AST/StmtNodes.def"
80  };
81}
82
83//===----------------------------------------------------------------------===//
84//  Stmt printing methods.
85//===----------------------------------------------------------------------===//
86
87void StmtPrinter::VisitStmt(Stmt *Node) {
88  Indent() << "<<unknown stmt type>>\n";
89}
90
91/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
92/// with no newline after the }.
93void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
94  OS << "{\n";
95  for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
96       I != E; ++I)
97    PrintStmt(*I);
98
99  Indent() << "}";
100}
101
102void StmtPrinter::PrintRawDecl(Decl *D) {
103  // FIXME: Need to complete/beautify this... this code simply shows the
104  // nodes are where they need to be.
105  if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) {
106    OS << "typedef " << localType->getUnderlyingType().getAsString();
107    OS << " " << localType->getName();
108  } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
109    // Emit storage class for vardecls.
110    if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
111      switch (V->getStorageClass()) {
112        default: assert(0 && "Unknown storage class!");
113        case VarDecl::None:     break;
114        case VarDecl::Extern:   OS << "extern "; break;
115        case VarDecl::Static:   OS << "static "; break;
116        case VarDecl::Auto:     OS << "auto "; break;
117        case VarDecl::Register: OS << "register "; break;
118      }
119    }
120
121    std::string Name = VD->getName();
122    VD->getType().getAsStringInternal(Name);
123    OS << Name;
124
125    // If this is a vardecl with an initializer, emit it.
126    if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
127      if (V->getInit()) {
128        OS << " = ";
129        PrintExpr(V->getInit());
130      }
131    }
132  } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
133    // print a free standing tag decl (e.g. "struct x;").
134    OS << TD->getKindName();
135    OS << " ";
136    if (const IdentifierInfo *II = TD->getIdentifier())
137      OS << II->getName();
138    else
139      OS << "<anonymous>";
140    // FIXME: print tag bodies.
141  } else {
142    assert(0 && "Unexpected decl");
143  }
144}
145
146
147void StmtPrinter::VisitNullStmt(NullStmt *Node) {
148  Indent() << ";\n";
149}
150
151void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
152  for (ScopedDecl *D = Node->getDecl(); D; D = D->getNextDeclarator()) {
153    Indent();
154    PrintRawDecl(D);
155    OS << ";\n";
156  }
157}
158
159void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
160  Indent();
161  PrintRawCompoundStmt(Node);
162  OS << "\n";
163}
164
165void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
166  Indent(-1) << "case ";
167  PrintExpr(Node->getLHS());
168  if (Node->getRHS()) {
169    OS << " ... ";
170    PrintExpr(Node->getRHS());
171  }
172  OS << ":\n";
173
174  PrintStmt(Node->getSubStmt(), 0);
175}
176
177void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
178  Indent(-1) << "default:\n";
179  PrintStmt(Node->getSubStmt(), 0);
180}
181
182void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
183  Indent(-1) << Node->getName() << ":\n";
184  PrintStmt(Node->getSubStmt(), 0);
185}
186
187void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
188  OS << "if ";
189  PrintExpr(If->getCond());
190
191  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) {
192    OS << ' ';
193    PrintRawCompoundStmt(CS);
194    OS << (If->getElse() ? ' ' : '\n');
195  } else {
196    OS << '\n';
197    PrintStmt(If->getThen());
198    if (If->getElse()) Indent();
199  }
200
201  if (Stmt *Else = If->getElse()) {
202    OS << "else";
203
204    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) {
205      OS << ' ';
206      PrintRawCompoundStmt(CS);
207      OS << '\n';
208    } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) {
209      OS << ' ';
210      PrintRawIfStmt(ElseIf);
211    } else {
212      OS << '\n';
213      PrintStmt(If->getElse());
214    }
215  }
216}
217
218void StmtPrinter::VisitIfStmt(IfStmt *If) {
219  Indent();
220  PrintRawIfStmt(If);
221}
222
223void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
224  Indent() << "switch (";
225  PrintExpr(Node->getCond());
226  OS << ")";
227
228  // Pretty print compoundstmt bodies (very common).
229  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
230    OS << " ";
231    PrintRawCompoundStmt(CS);
232    OS << "\n";
233  } else {
234    OS << "\n";
235    PrintStmt(Node->getBody());
236  }
237}
238
239void StmtPrinter::VisitSwitchCase(SwitchCase*) {
240  assert(0 && "SwitchCase is an abstract class");
241}
242
243void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
244  Indent() << "while (";
245  PrintExpr(Node->getCond());
246  OS << ")\n";
247  PrintStmt(Node->getBody());
248}
249
250void StmtPrinter::VisitDoStmt(DoStmt *Node) {
251  Indent() << "do ";
252  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
253    PrintRawCompoundStmt(CS);
254    OS << " ";
255  } else {
256    OS << "\n";
257    PrintStmt(Node->getBody());
258    Indent();
259  }
260
261  OS << "while ";
262  PrintExpr(Node->getCond());
263  OS << ";\n";
264}
265
266void StmtPrinter::VisitForStmt(ForStmt *Node) {
267  Indent() << "for (";
268  if (Node->getInit()) {
269    if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit()))
270      PrintRawDecl(DS->getDecl());
271    else
272      PrintExpr(cast<Expr>(Node->getInit()));
273  }
274  OS << ";";
275  if (Node->getCond()) {
276    OS << " ";
277    PrintExpr(Node->getCond());
278  }
279  OS << ";";
280  if (Node->getInc()) {
281    OS << " ";
282    PrintExpr(Node->getInc());
283  }
284  OS << ") ";
285
286  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
287    PrintRawCompoundStmt(CS);
288    OS << "\n";
289  } else {
290    OS << "\n";
291    PrintStmt(Node->getBody());
292  }
293}
294
295void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
296  Indent() << "for (";
297  if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement()))
298    PrintRawDecl(DS->getDecl());
299  else
300    PrintExpr(cast<Expr>(Node->getElement()));
301  OS << " in ";
302  PrintExpr(Node->getCollection());
303  OS << ") ";
304
305  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
306    PrintRawCompoundStmt(CS);
307    OS << "\n";
308  } else {
309    OS << "\n";
310    PrintStmt(Node->getBody());
311  }
312}
313
314void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
315  Indent() << "goto " << Node->getLabel()->getName() << ";\n";
316}
317
318void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
319  Indent() << "goto *";
320  PrintExpr(Node->getTarget());
321  OS << ";\n";
322}
323
324void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
325  Indent() << "continue;\n";
326}
327
328void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
329  Indent() << "break;\n";
330}
331
332
333void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
334  Indent() << "return";
335  if (Node->getRetValue()) {
336    OS << " ";
337    PrintExpr(Node->getRetValue());
338  }
339  OS << ";\n";
340}
341
342
343void StmtPrinter::VisitAsmStmt(AsmStmt *Node) {
344  Indent() << "asm ";
345
346  if (Node->isVolatile())
347    OS << "volatile ";
348
349  OS << "(";
350  VisitStringLiteral(Node->getAsmString());
351
352  // Outputs
353  if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
354      Node->getNumClobbers() != 0)
355    OS << " : ";
356
357  for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
358    if (i != 0)
359      OS << ", ";
360
361    if (!Node->getOutputName(i).empty()) {
362      OS << '[';
363      OS << Node->getOutputName(i);
364      OS << "] ";
365    }
366
367    VisitStringLiteral(Node->getOutputConstraint(i));
368    OS << " ";
369    Visit(Node->getOutputExpr(i));
370  }
371
372  // Inputs
373  if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
374    OS << " : ";
375
376  for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
377    if (i != 0)
378      OS << ", ";
379
380    if (!Node->getInputName(i).empty()) {
381      OS << '[';
382      OS << Node->getInputName(i);
383      OS << "] ";
384    }
385
386    VisitStringLiteral(Node->getInputConstraint(i));
387    OS << " ";
388    Visit(Node->getInputExpr(i));
389  }
390
391  // Clobbers
392  if (Node->getNumClobbers() != 0)
393    OS << " : ";
394
395  for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
396    if (i != 0)
397      OS << ", ";
398
399    VisitStringLiteral(Node->getClobber(i));
400  }
401
402  OS << ");\n";
403}
404
405void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
406  Indent() << "@try";
407  if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
408    PrintRawCompoundStmt(TS);
409    OS << "\n";
410  }
411
412  for (ObjCAtCatchStmt *catchStmt =
413         static_cast<ObjCAtCatchStmt *>(Node->getCatchStmts());
414       catchStmt;
415       catchStmt =
416         static_cast<ObjCAtCatchStmt *>(catchStmt->getNextCatchStmt())) {
417    Indent() << "@catch(";
418    if (catchStmt->getCatchParamStmt()) {
419      if (DeclStmt *DS = dyn_cast<DeclStmt>(catchStmt->getCatchParamStmt()))
420        PrintRawDecl(DS->getDecl());
421    }
422    OS << ")";
423    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody()))
424      {
425        PrintRawCompoundStmt(CS);
426        OS << "\n";
427      }
428  }
429
430  if (ObjCAtFinallyStmt *FS =static_cast<ObjCAtFinallyStmt *>(
431          Node->getFinallyStmt())) {
432    Indent() << "@finally";
433    PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
434    OS << "\n";
435  }
436}
437
438void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
439}
440
441void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
442  Indent() << "@catch (...) { /* todo */ } \n";
443}
444
445void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
446  Indent() << "@throw";
447  if (Node->getThrowExpr()) {
448    OS << " ";
449    PrintExpr(Node->getThrowExpr());
450  }
451  OS << ";\n";
452}
453
454void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
455  Indent() << "@synchronized (";
456  PrintExpr(Node->getSynchExpr());
457  OS << ")";
458  PrintRawCompoundStmt(Node->getSynchBody());
459  OS << "\n";
460}
461
462//===----------------------------------------------------------------------===//
463//  Expr printing methods.
464//===----------------------------------------------------------------------===//
465
466void StmtPrinter::VisitExpr(Expr *Node) {
467  OS << "<<unknown expr type>>";
468}
469
470void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
471  OS << Node->getDecl()->getName();
472}
473
474void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
475  if (Node->getBase()) {
476    PrintExpr(Node->getBase());
477    OS << (Node->isArrow() ? "->" : ".");
478  }
479  OS << Node->getDecl()->getName();
480}
481
482void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
483  if (Node->getBase()) {
484    PrintExpr(Node->getBase());
485    OS << ".";
486  }
487  // FIXME: OS << Node->getDecl()->getName();
488}
489
490void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
491  switch (Node->getIdentType()) {
492    default:
493      assert(0 && "unknown case");
494    case PredefinedExpr::Func:
495      OS << "__func__";
496      break;
497    case PredefinedExpr::Function:
498      OS << "__FUNCTION__";
499      break;
500    case PredefinedExpr::PrettyFunction:
501      OS << "__PRETTY_FUNCTION__";
502      break;
503    case PredefinedExpr::ObjCSuper:
504      OS << "super";
505      break;
506  }
507}
508
509void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
510  unsigned value = Node->getValue();
511  if (Node->isWide())
512    OS << "L";
513  switch (value) {
514  case '\\':
515    OS << "'\\\\'";
516    break;
517  case '\'':
518    OS << "'\\''";
519    break;
520  case '\a':
521    // TODO: K&R: the meaning of '\\a' is different in traditional C
522    OS << "'\\a'";
523    break;
524  case '\b':
525    OS << "'\\b'";
526    break;
527  // Nonstandard escape sequence.
528  /*case '\e':
529    OS << "'\\e'";
530    break;*/
531  case '\f':
532    OS << "'\\f'";
533    break;
534  case '\n':
535    OS << "'\\n'";
536    break;
537  case '\r':
538    OS << "'\\r'";
539    break;
540  case '\t':
541    OS << "'\\t'";
542    break;
543  case '\v':
544    OS << "'\\v'";
545    break;
546  default:
547    if (value < 256 && isprint(value)) {
548      OS << "'" << (char)value << "'";
549    } else if (value < 256) {
550      OS << "'\\x" << std::hex << value << std::dec << "'";
551    } else {
552      // FIXME what to really do here?
553      OS << value;
554    }
555  }
556}
557
558void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
559  bool isSigned = Node->getType()->isSignedIntegerType();
560  OS << Node->getValue().toString(10, isSigned);
561
562  // Emit suffixes.  Integer literals are always a builtin integer type.
563  switch (Node->getType()->getAsBuiltinType()->getKind()) {
564  default: assert(0 && "Unexpected type for integer literal!");
565  case BuiltinType::Int:       break; // no suffix.
566  case BuiltinType::UInt:      OS << 'U'; break;
567  case BuiltinType::Long:      OS << 'L'; break;
568  case BuiltinType::ULong:     OS << "UL"; break;
569  case BuiltinType::LongLong:  OS << "LL"; break;
570  case BuiltinType::ULongLong: OS << "ULL"; break;
571  }
572}
573void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
574  // FIXME: print value more precisely.
575  OS << Node->getValueAsApproximateDouble();
576}
577
578void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
579  PrintExpr(Node->getSubExpr());
580  OS << "i";
581}
582
583void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
584  if (Str->isWide()) OS << 'L';
585  OS << '"';
586
587  // FIXME: this doesn't print wstrings right.
588  for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
589    switch (Str->getStrData()[i]) {
590    default: OS << Str->getStrData()[i]; break;
591    // Handle some common ones to make dumps prettier.
592    case '\\': OS << "\\\\"; break;
593    case '"': OS << "\\\""; break;
594    case '\n': OS << "\\n"; break;
595    case '\t': OS << "\\t"; break;
596    case '\a': OS << "\\a"; break;
597    case '\b': OS << "\\b"; break;
598    }
599  }
600  OS << '"';
601}
602void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
603  OS << "(";
604  PrintExpr(Node->getSubExpr());
605  OS << ")";
606}
607void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
608  if (!Node->isPostfix()) {
609    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
610
611    // Print a space if this is an "identifier operator" like sizeof or __real.
612    switch (Node->getOpcode()) {
613    default: break;
614    case UnaryOperator::SizeOf:
615    case UnaryOperator::AlignOf:
616    case UnaryOperator::Real:
617    case UnaryOperator::Imag:
618    case UnaryOperator::Extension:
619      OS << ' ';
620      break;
621    }
622  }
623  PrintExpr(Node->getSubExpr());
624
625  if (Node->isPostfix())
626    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
627}
628
629bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) {
630  if (isa<CompoundLiteralExpr>(E)) {
631    // Base case, print the type and comma.
632    OS << E->getType().getAsString() << ", ";
633    return true;
634  } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
635    PrintOffsetOfDesignator(ASE->getLHS());
636    OS << "[";
637    PrintExpr(ASE->getRHS());
638    OS << "]";
639    return false;
640  } else {
641    MemberExpr *ME = cast<MemberExpr>(E);
642    bool IsFirst = PrintOffsetOfDesignator(ME->getBase());
643    OS << (IsFirst ? "" : ".") << ME->getMemberDecl()->getName();
644    return false;
645  }
646}
647
648void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) {
649  OS << "__builtin_offsetof(";
650  PrintOffsetOfDesignator(Node->getSubExpr());
651  OS << ")";
652}
653
654void StmtPrinter::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node) {
655  OS << (Node->isSizeOf() ? "sizeof(" : "__alignof(");
656  OS << Node->getArgumentType().getAsString() << ")";
657}
658void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
659  PrintExpr(Node->getLHS());
660  OS << "[";
661  PrintExpr(Node->getRHS());
662  OS << "]";
663}
664
665void StmtPrinter::VisitCallExpr(CallExpr *Call) {
666  PrintExpr(Call->getCallee());
667  OS << "(";
668  for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
669    if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
670      // Don't print any defaulted arguments
671      break;
672    }
673
674    if (i) OS << ", ";
675    PrintExpr(Call->getArg(i));
676  }
677  OS << ")";
678}
679void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
680  PrintExpr(Node->getBase());
681  OS << (Node->isArrow() ? "->" : ".");
682
683  FieldDecl *Field = Node->getMemberDecl();
684  assert(Field && "MemberExpr should alway reference a field!");
685  OS << Field->getName();
686}
687void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
688  PrintExpr(Node->getBase());
689  OS << ".";
690  OS << Node->getAccessor().getName();
691}
692void StmtPrinter::VisitCastExpr(CastExpr *) {
693  assert(0 && "CastExpr is an abstract class");
694}
695void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *Node) {
696  OS << "(" << Node->getType().getAsString() << ")";
697  PrintExpr(Node->getSubExpr());
698}
699void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
700  OS << "(" << Node->getType().getAsString() << ")";
701  PrintExpr(Node->getInitializer());
702}
703void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
704  // No need to print anything, simply forward to the sub expression.
705  PrintExpr(Node->getSubExpr());
706}
707void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
708  PrintExpr(Node->getLHS());
709  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
710  PrintExpr(Node->getRHS());
711}
712void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
713  PrintExpr(Node->getLHS());
714  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
715  PrintExpr(Node->getRHS());
716}
717void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
718  PrintExpr(Node->getCond());
719
720  if (Node->getLHS()) {
721    OS << " ? ";
722    PrintExpr(Node->getLHS());
723    OS << " : ";
724  }
725  else { // Handle GCC extention where LHS can be NULL.
726    OS << " ?: ";
727  }
728
729  PrintExpr(Node->getRHS());
730}
731
732// GNU extensions.
733
734void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
735  OS << "&&" << Node->getLabel()->getName();
736}
737
738void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
739  OS << "(";
740  PrintRawCompoundStmt(E->getSubStmt());
741  OS << ")";
742}
743
744void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
745  OS << "__builtin_types_compatible_p(";
746  OS << Node->getArgType1().getAsString() << ",";
747  OS << Node->getArgType2().getAsString() << ")";
748}
749
750void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
751  OS << "__builtin_choose_expr(";
752  PrintExpr(Node->getCond());
753  OS << ", ";
754  PrintExpr(Node->getLHS());
755  OS << ", ";
756  PrintExpr(Node->getRHS());
757  OS << ")";
758}
759
760void StmtPrinter::VisitOverloadExpr(OverloadExpr *Node) {
761  OS << "__builtin_overload(";
762  for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
763    if (i) OS << ", ";
764    PrintExpr(Node->getExpr(i));
765  }
766  OS << ")";
767}
768
769void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
770  OS << "__builtin_shufflevector(";
771  for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
772    if (i) OS << ", ";
773    PrintExpr(Node->getExpr(i));
774  }
775  OS << ")";
776}
777
778void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
779  OS << "{ ";
780  for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
781    if (i) OS << ", ";
782    PrintExpr(Node->getInit(i));
783  }
784  OS << " }";
785}
786
787void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
788  OS << "va_arg(";
789  PrintExpr(Node->getSubExpr());
790  OS << ", ";
791  OS << Node->getType().getAsString();
792  OS << ")";
793}
794
795// C++
796
797void StmtPrinter::VisitCXXCastExpr(CXXCastExpr *Node) {
798  OS << CXXCastExpr::getOpcodeStr(Node->getOpcode()) << '<';
799  OS << Node->getDestType().getAsString() << ">(";
800  PrintExpr(Node->getSubExpr());
801  OS << ")";
802}
803
804void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
805  OS << (Node->getValue() ? "true" : "false");
806}
807
808void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
809  if (Node->getSubExpr() == 0)
810    OS << "throw";
811  else {
812    OS << "throw ";
813    PrintExpr(Node->getSubExpr());
814  }
815}
816
817void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
818  // Nothing to print: we picked up the default argument
819}
820
821void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
822  OS << Node->getType().getAsString();
823  OS << "(";
824  PrintExpr(Node->getSubExpr());
825  OS << ")";
826}
827
828void StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) {
829  OS << Node->getType().getAsString() << "()";
830}
831
832// Obj-C
833
834void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
835  OS << "@";
836  VisitStringLiteral(Node->getString());
837}
838
839void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
840  OS << "@encode(" << Node->getEncodedType().getAsString() << ")";
841}
842
843void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
844  OS << "@selector(" << Node->getSelector().getName() << ")";
845}
846
847void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
848  OS << "@protocol(" << Node->getProtocol()->getName() << ")";
849}
850
851void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
852  OS << "[";
853  Expr *receiver = Mess->getReceiver();
854  if (receiver) PrintExpr(receiver);
855  else OS << Mess->getClassName()->getName();
856  OS << ' ';
857  Selector selector = Mess->getSelector();
858  if (selector.isUnarySelector()) {
859    OS << selector.getIdentifierInfoForSlot(0)->getName();
860  } else {
861    for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
862      if (i < selector.getNumArgs()) {
863        if (i > 0) OS << ' ';
864        if (selector.getIdentifierInfoForSlot(i))
865          OS << selector.getIdentifierInfoForSlot(i)->getName() << ":";
866        else
867           OS << ":";
868      }
869      else OS << ", "; // Handle variadic methods.
870
871      PrintExpr(Mess->getArg(i));
872    }
873  }
874  OS << "]";
875}
876
877//===----------------------------------------------------------------------===//
878// Stmt method implementations
879//===----------------------------------------------------------------------===//
880
881void Stmt::dumpPretty() const {
882  printPretty(*llvm::cerr.stream());
883}
884
885void Stmt::printPretty(std::ostream &OS, PrinterHelper* Helper) const {
886  if (this == 0) {
887    OS << "<NULL>";
888    return;
889  }
890
891  StmtPrinter P(OS, Helper);
892  P.Visit(const_cast<Stmt*>(this));
893}
894
895//===----------------------------------------------------------------------===//
896// PrinterHelper
897//===----------------------------------------------------------------------===//
898
899// Implement virtual destructor.
900PrinterHelper::~PrinterHelper() {}
901