StmtPrinter.cpp revision 97b7f26a92d87e514530a5b652460190ce48c974
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>
24using namespace clang;
25
26//===----------------------------------------------------------------------===//
27// StmtPrinter Visitor
28//===----------------------------------------------------------------------===//
29
30namespace  {
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
91void 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 }.
97void 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
106void 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
151void StmtPrinter::VisitNullStmt(NullStmt *Node) {
152  Indent() << ";\n";
153}
154
155void 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
163void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
164  Indent();
165  PrintRawCompoundStmt(Node);
166  OS << "\n";
167}
168
169void 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
181void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
182  Indent(-1) << "default:\n";
183  PrintStmt(Node->getSubStmt(), 0);
184}
185
186void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
187  Indent(-1) << Node->getName() << ":\n";
188  PrintStmt(Node->getSubStmt(), 0);
189}
190
191void 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
222void StmtPrinter::VisitIfStmt(IfStmt *If) {
223  Indent();
224  PrintRawIfStmt(If);
225}
226
227void 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
243void StmtPrinter::VisitSwitchCase(SwitchCase*) {
244  assert(0 && "SwitchCase is an abstract class");
245}
246
247void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
248  Indent() << "while (";
249  PrintExpr(Node->getCond());
250  OS << ")\n";
251  PrintStmt(Node->getBody());
252}
253
254void 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
270void 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
299void 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
318void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
319  Indent() << "goto " << Node->getLabel()->getName() << ";\n";
320}
321
322void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
323  Indent() << "goto *";
324  PrintExpr(Node->getTarget());
325  OS << ";\n";
326}
327
328void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
329  Indent() << "continue;\n";
330}
331
332void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
333  Indent() << "break;\n";
334}
335
336
337void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
338  Indent() << "return";
339  if (Node->getRetValue()) {
340    OS << " ";
341    PrintExpr(Node->getRetValue());
342  }
343  OS << ";\n";
344}
345
346
347void 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
409void 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
442void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
443}
444
445void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
446  Indent() << "@catch (...) { /* todo */ } \n";
447}
448
449void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
450  Indent() << "@throw";
451  if (Node->getThrowExpr()) {
452    OS << " ";
453    PrintExpr(Node->getThrowExpr());
454  }
455  OS << ";\n";
456}
457
458void 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
470void StmtPrinter::VisitExpr(Expr *Node) {
471  OS << "<<unknown expr type>>";
472}
473
474void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
475  OS << Node->getDecl()->getName();
476}
477
478void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
479  if (Node->getBase()) {
480    PrintExpr(Node->getBase());
481    OS << (Node->isArrow() ? "->" : ".");
482  }
483  OS << Node->getDecl()->getName();
484}
485
486void 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
502void 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
550void 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}
565void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
566  // FIXME: print value more precisely.
567  OS << Node->getValueAsDouble();
568}
569
570void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
571  PrintExpr(Node->getSubExpr());
572  OS << "i";
573}
574
575void 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}
594void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
595  OS << "(";
596  PrintExpr(Node->getSubExpr());
597  OS << ")";
598}
599void 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
621bool 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
640void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) {
641  OS << "__builtin_offsetof(";
642  PrintOffsetOfDesignator(Node->getSubExpr());
643  OS << ")";
644}
645
646void StmtPrinter::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node) {
647  OS << (Node->isSizeOf() ? "sizeof(" : "__alignof(");
648  OS << Node->getArgumentType().getAsString() << ")";
649}
650void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
651  PrintExpr(Node->getLHS());
652  OS << "[";
653  PrintExpr(Node->getRHS());
654  OS << "]";
655}
656
657void StmtPrinter::VisitCallExpr(CallExpr *Call) {
658  PrintExpr(Call->getCallee());
659  OS << "(";
660  for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
661    if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
662      // Don't print any defaulted arguments
663      break;
664    }
665
666    if (i) OS << ", ";
667    PrintExpr(Call->getArg(i));
668  }
669  OS << ")";
670}
671void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
672  PrintExpr(Node->getBase());
673  OS << (Node->isArrow() ? "->" : ".");
674
675  FieldDecl *Field = Node->getMemberDecl();
676  assert(Field && "MemberExpr should alway reference a field!");
677  OS << Field->getName();
678}
679void StmtPrinter::VisitOCUVectorElementExpr(OCUVectorElementExpr *Node) {
680  PrintExpr(Node->getBase());
681  OS << ".";
682  OS << Node->getAccessor().getName();
683}
684void StmtPrinter::VisitCastExpr(CastExpr *Node) {
685  OS << "(" << Node->getType().getAsString() << ")";
686  PrintExpr(Node->getSubExpr());
687}
688void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
689  OS << "(" << Node->getType().getAsString() << ")";
690  PrintExpr(Node->getInitializer());
691}
692void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
693  // No need to print anything, simply forward to the sub expression.
694  PrintExpr(Node->getSubExpr());
695}
696void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
697  PrintExpr(Node->getLHS());
698  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
699  PrintExpr(Node->getRHS());
700}
701void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
702  PrintExpr(Node->getLHS());
703  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
704  PrintExpr(Node->getRHS());
705}
706void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
707  PrintExpr(Node->getCond());
708
709  if (Node->getLHS()) {
710    OS << " ? ";
711    PrintExpr(Node->getLHS());
712    OS << " : ";
713  }
714  else { // Handle GCC extention where LHS can be NULL.
715    OS << " ?: ";
716  }
717
718  PrintExpr(Node->getRHS());
719}
720
721// GNU extensions.
722
723void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
724  OS << "&&" << Node->getLabel()->getName();
725}
726
727void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
728  OS << "(";
729  PrintRawCompoundStmt(E->getSubStmt());
730  OS << ")";
731}
732
733void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
734  OS << "__builtin_types_compatible_p(";
735  OS << Node->getArgType1().getAsString() << ",";
736  OS << Node->getArgType2().getAsString() << ")";
737}
738
739void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
740  OS << "__builtin_choose_expr(";
741  PrintExpr(Node->getCond());
742  OS << ", ";
743  PrintExpr(Node->getLHS());
744  OS << ", ";
745  PrintExpr(Node->getRHS());
746  OS << ")";
747}
748
749void StmtPrinter::VisitOverloadExpr(OverloadExpr *Node) {
750  OS << "__builtin_overload(";
751  for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
752    if (i) OS << ", ";
753    PrintExpr(Node->getExpr(i));
754  }
755  OS << ")";
756}
757
758void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
759  OS << "{ ";
760  for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
761    if (i) OS << ", ";
762    PrintExpr(Node->getInit(i));
763  }
764  OS << " }";
765}
766
767void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
768  OS << "va_arg(";
769  PrintExpr(Node->getSubExpr());
770  OS << ", ";
771  OS << Node->getType().getAsString();
772  OS << ")";
773}
774
775// C++
776
777void StmtPrinter::VisitCXXCastExpr(CXXCastExpr *Node) {
778  OS << CXXCastExpr::getOpcodeStr(Node->getOpcode()) << '<';
779  OS << Node->getDestType().getAsString() << ">(";
780  PrintExpr(Node->getSubExpr());
781  OS << ")";
782}
783
784void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
785  OS << (Node->getValue() ? "true" : "false");
786}
787
788void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
789  if (Node->getSubExpr() == 0)
790    OS << "throw";
791  else {
792    OS << "throw ";
793    PrintExpr(Node->getSubExpr());
794  }
795}
796
797void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
798  // Nothing to print: we picked up the default argument
799}
800
801// Obj-C
802
803void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
804  OS << "@";
805  VisitStringLiteral(Node->getString());
806}
807
808void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
809  OS << "@encode(" << Node->getEncodedType().getAsString() << ")";
810}
811
812void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
813  OS << "@selector(" << Node->getSelector().getName() << ")";
814}
815
816void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
817  OS << "@protocol(" << Node->getProtocol()->getName() << ")";
818}
819
820void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
821  OS << "[";
822  Expr *receiver = Mess->getReceiver();
823  if (receiver) PrintExpr(receiver);
824  else OS << Mess->getClassName()->getName();
825  Selector selector = Mess->getSelector();
826  if (selector.isUnarySelector()) {
827    OS << " " << selector.getIdentifierInfoForSlot(0)->getName();
828  } else {
829    for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
830      if (selector.getIdentifierInfoForSlot(i))
831        OS << selector.getIdentifierInfoForSlot(i)->getName() << ":";
832      else
833         OS << ":";
834      PrintExpr(Mess->getArg(i));
835    }
836  }
837  OS << "]";
838}
839
840//===----------------------------------------------------------------------===//
841// Stmt method implementations
842//===----------------------------------------------------------------------===//
843
844void Stmt::dumpPretty() const {
845  printPretty(*llvm::cerr.stream());
846}
847
848void Stmt::printPretty(std::ostream &OS, PrinterHelper* Helper) const {
849  if (this == 0) {
850    OS << "<NULL>";
851    return;
852  }
853
854  StmtPrinter P(OS, Helper);
855  P.Visit(const_cast<Stmt*>(this));
856}
857
858//===----------------------------------------------------------------------===//
859// PrinterHelper
860//===----------------------------------------------------------------------===//
861
862// Implement virtual destructor.
863PrinterHelper::~PrinterHelper() {}
864