StmtPrinter.cpp revision ae7840776d6cd31b4d7a4a345b61bcbb3744df6c
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/ExprObjC.h"
20#include "clang/AST/PrettyPrinter.h"
21#include "clang/Basic/IdentifierTable.h"
22#include "llvm/Support/Compiler.h"
23#include "llvm/Support/Streams.h"
24#include <iomanip>
25using namespace clang;
26
27//===----------------------------------------------------------------------===//
28// StmtPrinter Visitor
29//===----------------------------------------------------------------------===//
30
31namespace  {
32  class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor<StmtPrinter> {
33    std::ostream &OS;
34    unsigned IndentLevel;
35    clang::PrinterHelper* Helper;
36  public:
37    StmtPrinter(std::ostream &os, PrinterHelper* helper) :
38      OS(os), IndentLevel(0), Helper(helper) {}
39
40    void PrintStmt(Stmt *S, int SubIndent = 1) {
41      IndentLevel += SubIndent;
42      if (S && isa<Expr>(S)) {
43        // If this is an expr used in a stmt context, indent and newline it.
44        Indent();
45        Visit(S);
46        OS << ";\n";
47      } else if (S) {
48        Visit(S);
49      } else {
50        Indent() << "<<<NULL STATEMENT>>>\n";
51      }
52      IndentLevel -= SubIndent;
53    }
54
55    void PrintRawCompoundStmt(CompoundStmt *S);
56    void PrintRawDecl(Decl *D);
57    void PrintRawIfStmt(IfStmt *If);
58
59    void PrintExpr(Expr *E) {
60      if (E)
61        Visit(E);
62      else
63        OS << "<null expr>";
64    }
65
66    std::ostream &Indent(int Delta = 0) const {
67      for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
68        OS << "  ";
69      return OS;
70    }
71
72    bool PrintOffsetOfDesignator(Expr *E);
73    void VisitUnaryOffsetOf(UnaryOperator *Node);
74
75    void Visit(Stmt* S) {
76      if (Helper && Helper->handledStmt(S,OS))
77          return;
78      else StmtVisitor<StmtPrinter>::Visit(S);
79    }
80
81    void VisitStmt(Stmt *Node);
82#define STMT(N, CLASS, PARENT) \
83    void Visit##CLASS(CLASS *Node);
84#include "clang/AST/StmtNodes.def"
85  };
86}
87
88//===----------------------------------------------------------------------===//
89//  Stmt printing methods.
90//===----------------------------------------------------------------------===//
91
92void StmtPrinter::VisitStmt(Stmt *Node) {
93  Indent() << "<<unknown stmt type>>\n";
94}
95
96/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
97/// with no newline after the }.
98void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
99  OS << "{\n";
100  for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
101       I != E; ++I)
102    PrintStmt(*I);
103
104  Indent() << "}";
105}
106
107void StmtPrinter::PrintRawDecl(Decl *D) {
108  // FIXME: Need to complete/beautify this... this code simply shows the
109  // nodes are where they need to be.
110  if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) {
111    OS << "typedef " << localType->getUnderlyingType().getAsString();
112    OS << " " << localType->getName();
113  } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
114    // Emit storage class for vardecls.
115    if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
116      switch (V->getStorageClass()) {
117        default: assert(0 && "Unknown storage class!");
118        case VarDecl::None:     break;
119        case VarDecl::Extern:   OS << "extern "; break;
120        case VarDecl::Static:   OS << "static "; break;
121        case VarDecl::Auto:     OS << "auto "; break;
122        case VarDecl::Register: OS << "register "; break;
123      }
124    }
125
126    std::string Name = VD->getName();
127    VD->getType().getAsStringInternal(Name);
128    OS << Name;
129
130    // If this is a vardecl with an initializer, emit it.
131    if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
132      if (V->getInit()) {
133        OS << " = ";
134        PrintExpr(V->getInit());
135      }
136    }
137  } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
138    // print a free standing tag decl (e.g. "struct x;").
139    OS << TD->getKindName();
140    OS << " ";
141    if (const IdentifierInfo *II = TD->getIdentifier())
142      OS << II->getName();
143    else
144      OS << "<anonymous>";
145    // FIXME: print tag bodies.
146  } else {
147    assert(0 && "Unexpected decl");
148  }
149}
150
151
152void StmtPrinter::VisitNullStmt(NullStmt *Node) {
153  Indent() << ";\n";
154}
155
156void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
157  for (ScopedDecl *D = Node->getDecl(); D; D = D->getNextDeclarator()) {
158    Indent();
159    PrintRawDecl(D);
160    OS << ";\n";
161  }
162}
163
164void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
165  Indent();
166  PrintRawCompoundStmt(Node);
167  OS << "\n";
168}
169
170void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
171  Indent(-1) << "case ";
172  PrintExpr(Node->getLHS());
173  if (Node->getRHS()) {
174    OS << " ... ";
175    PrintExpr(Node->getRHS());
176  }
177  OS << ":\n";
178
179  PrintStmt(Node->getSubStmt(), 0);
180}
181
182void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
183  Indent(-1) << "default:\n";
184  PrintStmt(Node->getSubStmt(), 0);
185}
186
187void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
188  Indent(-1) << Node->getName() << ":\n";
189  PrintStmt(Node->getSubStmt(), 0);
190}
191
192void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
193  OS << "if ";
194  PrintExpr(If->getCond());
195
196  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) {
197    OS << ' ';
198    PrintRawCompoundStmt(CS);
199    OS << (If->getElse() ? ' ' : '\n');
200  } else {
201    OS << '\n';
202    PrintStmt(If->getThen());
203    if (If->getElse()) Indent();
204  }
205
206  if (Stmt *Else = If->getElse()) {
207    OS << "else";
208
209    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) {
210      OS << ' ';
211      PrintRawCompoundStmt(CS);
212      OS << '\n';
213    } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) {
214      OS << ' ';
215      PrintRawIfStmt(ElseIf);
216    } else {
217      OS << '\n';
218      PrintStmt(If->getElse());
219    }
220  }
221}
222
223void StmtPrinter::VisitIfStmt(IfStmt *If) {
224  Indent();
225  PrintRawIfStmt(If);
226}
227
228void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
229  Indent() << "switch (";
230  PrintExpr(Node->getCond());
231  OS << ")";
232
233  // Pretty print compoundstmt bodies (very common).
234  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
235    OS << " ";
236    PrintRawCompoundStmt(CS);
237    OS << "\n";
238  } else {
239    OS << "\n";
240    PrintStmt(Node->getBody());
241  }
242}
243
244void StmtPrinter::VisitSwitchCase(SwitchCase*) {
245  assert(0 && "SwitchCase is an abstract class");
246}
247
248void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
249  Indent() << "while (";
250  PrintExpr(Node->getCond());
251  OS << ")\n";
252  PrintStmt(Node->getBody());
253}
254
255void StmtPrinter::VisitDoStmt(DoStmt *Node) {
256  Indent() << "do ";
257  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
258    PrintRawCompoundStmt(CS);
259    OS << " ";
260  } else {
261    OS << "\n";
262    PrintStmt(Node->getBody());
263    Indent();
264  }
265
266  OS << "while ";
267  PrintExpr(Node->getCond());
268  OS << ";\n";
269}
270
271void StmtPrinter::VisitForStmt(ForStmt *Node) {
272  Indent() << "for (";
273  if (Node->getInit()) {
274    if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit()))
275      PrintRawDecl(DS->getDecl());
276    else
277      PrintExpr(cast<Expr>(Node->getInit()));
278  }
279  OS << ";";
280  if (Node->getCond()) {
281    OS << " ";
282    PrintExpr(Node->getCond());
283  }
284  OS << ";";
285  if (Node->getInc()) {
286    OS << " ";
287    PrintExpr(Node->getInc());
288  }
289  OS << ") ";
290
291  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
292    PrintRawCompoundStmt(CS);
293    OS << "\n";
294  } else {
295    OS << "\n";
296    PrintStmt(Node->getBody());
297  }
298}
299
300void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
301  Indent() << "for (";
302  if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement()))
303    PrintRawDecl(DS->getDecl());
304  else
305    PrintExpr(cast<Expr>(Node->getElement()));
306  OS << " in ";
307  PrintExpr(Node->getCollection());
308  OS << ") ";
309
310  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
311    PrintRawCompoundStmt(CS);
312    OS << "\n";
313  } else {
314    OS << "\n";
315    PrintStmt(Node->getBody());
316  }
317}
318
319void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
320  Indent() << "goto " << Node->getLabel()->getName() << ";\n";
321}
322
323void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
324  Indent() << "goto *";
325  PrintExpr(Node->getTarget());
326  OS << ";\n";
327}
328
329void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
330  Indent() << "continue;\n";
331}
332
333void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
334  Indent() << "break;\n";
335}
336
337
338void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
339  Indent() << "return";
340  if (Node->getRetValue()) {
341    OS << " ";
342    PrintExpr(Node->getRetValue());
343  }
344  OS << ";\n";
345}
346
347
348void StmtPrinter::VisitAsmStmt(AsmStmt *Node) {
349  Indent() << "asm ";
350
351  if (Node->isVolatile())
352    OS << "volatile ";
353
354  OS << "(";
355  VisitStringLiteral(Node->getAsmString());
356
357  // Outputs
358  if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
359      Node->getNumClobbers() != 0)
360    OS << " : ";
361
362  for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
363    if (i != 0)
364      OS << ", ";
365
366    if (!Node->getOutputName(i).empty()) {
367      OS << '[';
368      OS << Node->getOutputName(i);
369      OS << "] ";
370    }
371
372    VisitStringLiteral(Node->getOutputConstraint(i));
373    OS << " ";
374    Visit(Node->getOutputExpr(i));
375  }
376
377  // Inputs
378  if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
379    OS << " : ";
380
381  for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
382    if (i != 0)
383      OS << ", ";
384
385    if (!Node->getInputName(i).empty()) {
386      OS << '[';
387      OS << Node->getInputName(i);
388      OS << "] ";
389    }
390
391    VisitStringLiteral(Node->getInputConstraint(i));
392    OS << " ";
393    Visit(Node->getInputExpr(i));
394  }
395
396  // Clobbers
397  if (Node->getNumClobbers() != 0)
398    OS << " : ";
399
400  for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
401    if (i != 0)
402      OS << ", ";
403
404    VisitStringLiteral(Node->getClobber(i));
405  }
406
407  OS << ");\n";
408}
409
410void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
411  Indent() << "@try";
412  if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
413    PrintRawCompoundStmt(TS);
414    OS << "\n";
415  }
416
417  for (ObjCAtCatchStmt *catchStmt =
418         static_cast<ObjCAtCatchStmt *>(Node->getCatchStmts());
419       catchStmt;
420       catchStmt =
421         static_cast<ObjCAtCatchStmt *>(catchStmt->getNextCatchStmt())) {
422    Indent() << "@catch(";
423    if (catchStmt->getCatchParamStmt()) {
424      if (DeclStmt *DS = dyn_cast<DeclStmt>(catchStmt->getCatchParamStmt()))
425        PrintRawDecl(DS->getDecl());
426    }
427    OS << ")";
428    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody()))
429      {
430        PrintRawCompoundStmt(CS);
431        OS << "\n";
432      }
433  }
434
435  if (ObjCAtFinallyStmt *FS =static_cast<ObjCAtFinallyStmt *>(
436          Node->getFinallyStmt())) {
437    Indent() << "@finally";
438    PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
439    OS << "\n";
440  }
441}
442
443void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
444}
445
446void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
447  Indent() << "@catch (...) { /* todo */ } \n";
448}
449
450void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
451  Indent() << "@throw";
452  if (Node->getThrowExpr()) {
453    OS << " ";
454    PrintExpr(Node->getThrowExpr());
455  }
456  OS << ";\n";
457}
458
459void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
460  Indent() << "@synchronized (";
461  PrintExpr(Node->getSynchExpr());
462  OS << ")";
463  PrintRawCompoundStmt(Node->getSynchBody());
464  OS << "\n";
465}
466
467//===----------------------------------------------------------------------===//
468//  Expr printing methods.
469//===----------------------------------------------------------------------===//
470
471void StmtPrinter::VisitExpr(Expr *Node) {
472  OS << "<<unknown expr type>>";
473}
474
475void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
476  OS << Node->getDecl()->getName();
477}
478
479void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
480  if (Node->getBase()) {
481    PrintExpr(Node->getBase());
482    OS << (Node->isArrow() ? "->" : ".");
483  }
484  OS << Node->getDecl()->getName();
485}
486
487void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
488  if (Node->getBase()) {
489    PrintExpr(Node->getBase());
490    OS << ".";
491  }
492  // FIXME: OS << Node->getDecl()->getName();
493}
494
495void StmtPrinter::VisitPreDefinedExpr(PreDefinedExpr *Node) {
496  switch (Node->getIdentType()) {
497    default:
498      assert(0 && "unknown case");
499    case PreDefinedExpr::Func:
500      OS << "__func__";
501      break;
502    case PreDefinedExpr::Function:
503      OS << "__FUNCTION__";
504      break;
505    case PreDefinedExpr::PrettyFunction:
506      OS << "__PRETTY_FUNCTION__";
507      break;
508  }
509}
510
511void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
512  // FIXME should print an L for wchar_t constants
513  unsigned value = Node->getValue();
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" << std::hex << value << std::dec << "'";
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 (cast<BuiltinType>(Node->getType().getCanonicalType())->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->getValueAsDouble();
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 *Node) {
694  OS << "(" << Node->getType().getAsString() << ")";
695  PrintExpr(Node->getSubExpr());
696}
697void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
698  OS << "(" << Node->getType().getAsString() << ")";
699  PrintExpr(Node->getInitializer());
700}
701void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
702  // No need to print anything, simply forward to the sub expression.
703  PrintExpr(Node->getSubExpr());
704}
705void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
706  PrintExpr(Node->getLHS());
707  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
708  PrintExpr(Node->getRHS());
709}
710void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
711  PrintExpr(Node->getLHS());
712  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
713  PrintExpr(Node->getRHS());
714}
715void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
716  PrintExpr(Node->getCond());
717
718  if (Node->getLHS()) {
719    OS << " ? ";
720    PrintExpr(Node->getLHS());
721    OS << " : ";
722  }
723  else { // Handle GCC extention where LHS can be NULL.
724    OS << " ?: ";
725  }
726
727  PrintExpr(Node->getRHS());
728}
729
730// GNU extensions.
731
732void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
733  OS << "&&" << Node->getLabel()->getName();
734}
735
736void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
737  OS << "(";
738  PrintRawCompoundStmt(E->getSubStmt());
739  OS << ")";
740}
741
742void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
743  OS << "__builtin_types_compatible_p(";
744  OS << Node->getArgType1().getAsString() << ",";
745  OS << Node->getArgType2().getAsString() << ")";
746}
747
748void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
749  OS << "__builtin_choose_expr(";
750  PrintExpr(Node->getCond());
751  OS << ", ";
752  PrintExpr(Node->getLHS());
753  OS << ", ";
754  PrintExpr(Node->getRHS());
755  OS << ")";
756}
757
758void StmtPrinter::VisitOverloadExpr(OverloadExpr *Node) {
759  OS << "__builtin_overload(";
760  for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
761    if (i) OS << ", ";
762    PrintExpr(Node->getExpr(i));
763  }
764  OS << ")";
765}
766
767void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
768  OS << "__builtin_shufflevector(";
769  for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
770    if (i) OS << ", ";
771    PrintExpr(Node->getExpr(i));
772  }
773  OS << ")";
774}
775
776void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
777  OS << "{ ";
778  for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
779    if (i) OS << ", ";
780    PrintExpr(Node->getInit(i));
781  }
782  OS << " }";
783}
784
785void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
786  OS << "va_arg(";
787  PrintExpr(Node->getSubExpr());
788  OS << ", ";
789  OS << Node->getType().getAsString();
790  OS << ")";
791}
792
793// C++
794
795void StmtPrinter::VisitCXXCastExpr(CXXCastExpr *Node) {
796  OS << CXXCastExpr::getOpcodeStr(Node->getOpcode()) << '<';
797  OS << Node->getDestType().getAsString() << ">(";
798  PrintExpr(Node->getSubExpr());
799  OS << ")";
800}
801
802void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
803  OS << (Node->getValue() ? "true" : "false");
804}
805
806void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
807  if (Node->getSubExpr() == 0)
808    OS << "throw";
809  else {
810    OS << "throw ";
811    PrintExpr(Node->getSubExpr());
812  }
813}
814
815void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
816  // Nothing to print: we picked up the default argument
817}
818
819// Obj-C
820
821void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
822  OS << "@";
823  VisitStringLiteral(Node->getString());
824}
825
826void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
827  OS << "@encode(" << Node->getEncodedType().getAsString() << ")";
828}
829
830void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
831  OS << "@selector(" << Node->getSelector().getName() << ")";
832}
833
834void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
835  OS << "@protocol(" << Node->getProtocol()->getName() << ")";
836}
837
838void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
839  OS << "[";
840  Expr *receiver = Mess->getReceiver();
841  if (receiver) PrintExpr(receiver);
842  else OS << Mess->getClassName()->getName();
843  OS << ' ';
844  Selector selector = Mess->getSelector();
845  if (selector.isUnarySelector()) {
846    OS << selector.getIdentifierInfoForSlot(0)->getName();
847  } else {
848    for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
849      if (i < selector.getNumArgs()) {
850        if (i > 0) OS << ' ';
851        if (selector.getIdentifierInfoForSlot(i))
852          OS << selector.getIdentifierInfoForSlot(i)->getName() << ":";
853        else
854           OS << ":";
855      }
856      else OS << ", "; // Handle variadic methods.
857
858      PrintExpr(Mess->getArg(i));
859    }
860  }
861  OS << "]";
862}
863
864//===----------------------------------------------------------------------===//
865// Stmt method implementations
866//===----------------------------------------------------------------------===//
867
868void Stmt::dumpPretty() const {
869  printPretty(*llvm::cerr.stream());
870}
871
872void Stmt::printPretty(std::ostream &OS, PrinterHelper* Helper) const {
873  if (this == 0) {
874    OS << "<NULL>";
875    return;
876  }
877
878  StmtPrinter P(OS, Helper);
879  P.Visit(const_cast<Stmt*>(this));
880}
881
882//===----------------------------------------------------------------------===//
883// PrinterHelper
884//===----------------------------------------------------------------------===//
885
886// Implement virtual destructor.
887PrinterHelper::~PrinterHelper() {}
888