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