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