StmtPrinter.cpp revision d9f6910f4ef37c0e8eeee2a01287d9572c3176ef
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::VisitObjCSuperRefExpr(ObjCSuperRefExpr *Node) {
480  OS << "super";
481}
482
483void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
484  if (Node->getBase()) {
485    PrintExpr(Node->getBase());
486    OS << (Node->isArrow() ? "->" : ".");
487  }
488  OS << Node->getDecl()->getName();
489}
490
491void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
492  if (Node->getBase()) {
493    PrintExpr(Node->getBase());
494    OS << ".";
495  }
496  // FIXME: OS << Node->getDecl()->getName();
497}
498
499void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
500  switch (Node->getIdentType()) {
501    default:
502      assert(0 && "unknown case");
503    case PredefinedExpr::Func:
504      OS << "__func__";
505      break;
506    case PredefinedExpr::Function:
507      OS << "__FUNCTION__";
508      break;
509    case PredefinedExpr::PrettyFunction:
510      OS << "__PRETTY_FUNCTION__";
511      break;
512    case PredefinedExpr::ObjCSuper:
513      OS << "super";
514      break;
515  }
516}
517
518void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
519  unsigned value = Node->getValue();
520  if (Node->isWide())
521    OS << "L";
522  switch (value) {
523  case '\\':
524    OS << "'\\\\'";
525    break;
526  case '\'':
527    OS << "'\\''";
528    break;
529  case '\a':
530    // TODO: K&R: the meaning of '\\a' is different in traditional C
531    OS << "'\\a'";
532    break;
533  case '\b':
534    OS << "'\\b'";
535    break;
536  // Nonstandard escape sequence.
537  /*case '\e':
538    OS << "'\\e'";
539    break;*/
540  case '\f':
541    OS << "'\\f'";
542    break;
543  case '\n':
544    OS << "'\\n'";
545    break;
546  case '\r':
547    OS << "'\\r'";
548    break;
549  case '\t':
550    OS << "'\\t'";
551    break;
552  case '\v':
553    OS << "'\\v'";
554    break;
555  default:
556    if (value < 256 && isprint(value)) {
557      OS << "'" << (char)value << "'";
558    } else if (value < 256) {
559      OS << "'\\x" << std::hex << value << std::dec << "'";
560    } else {
561      // FIXME what to really do here?
562      OS << value;
563    }
564  }
565}
566
567void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
568  bool isSigned = Node->getType()->isSignedIntegerType();
569  OS << Node->getValue().toString(10, isSigned);
570
571  // Emit suffixes.  Integer literals are always a builtin integer type.
572  switch (Node->getType()->getAsBuiltinType()->getKind()) {
573  default: assert(0 && "Unexpected type for integer literal!");
574  case BuiltinType::Int:       break; // no suffix.
575  case BuiltinType::UInt:      OS << 'U'; break;
576  case BuiltinType::Long:      OS << 'L'; break;
577  case BuiltinType::ULong:     OS << "UL"; break;
578  case BuiltinType::LongLong:  OS << "LL"; break;
579  case BuiltinType::ULongLong: OS << "ULL"; break;
580  }
581}
582void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
583  // FIXME: print value more precisely.
584  OS << Node->getValueAsApproximateDouble();
585}
586
587void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
588  PrintExpr(Node->getSubExpr());
589  OS << "i";
590}
591
592void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
593  if (Str->isWide()) OS << 'L';
594  OS << '"';
595
596  // FIXME: this doesn't print wstrings right.
597  for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
598    switch (Str->getStrData()[i]) {
599    default: OS << Str->getStrData()[i]; break;
600    // Handle some common ones to make dumps prettier.
601    case '\\': OS << "\\\\"; break;
602    case '"': OS << "\\\""; break;
603    case '\n': OS << "\\n"; break;
604    case '\t': OS << "\\t"; break;
605    case '\a': OS << "\\a"; break;
606    case '\b': OS << "\\b"; break;
607    }
608  }
609  OS << '"';
610}
611void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
612  OS << "(";
613  PrintExpr(Node->getSubExpr());
614  OS << ")";
615}
616void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
617  if (!Node->isPostfix()) {
618    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
619
620    // Print a space if this is an "identifier operator" like sizeof or __real.
621    switch (Node->getOpcode()) {
622    default: break;
623    case UnaryOperator::SizeOf:
624    case UnaryOperator::AlignOf:
625    case UnaryOperator::Real:
626    case UnaryOperator::Imag:
627    case UnaryOperator::Extension:
628      OS << ' ';
629      break;
630    }
631  }
632  PrintExpr(Node->getSubExpr());
633
634  if (Node->isPostfix())
635    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
636}
637
638bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) {
639  if (isa<CompoundLiteralExpr>(E)) {
640    // Base case, print the type and comma.
641    OS << E->getType().getAsString() << ", ";
642    return true;
643  } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
644    PrintOffsetOfDesignator(ASE->getLHS());
645    OS << "[";
646    PrintExpr(ASE->getRHS());
647    OS << "]";
648    return false;
649  } else {
650    MemberExpr *ME = cast<MemberExpr>(E);
651    bool IsFirst = PrintOffsetOfDesignator(ME->getBase());
652    OS << (IsFirst ? "" : ".") << ME->getMemberDecl()->getName();
653    return false;
654  }
655}
656
657void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) {
658  OS << "__builtin_offsetof(";
659  PrintOffsetOfDesignator(Node->getSubExpr());
660  OS << ")";
661}
662
663void StmtPrinter::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node) {
664  OS << (Node->isSizeOf() ? "sizeof(" : "__alignof(");
665  OS << Node->getArgumentType().getAsString() << ")";
666}
667void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
668  PrintExpr(Node->getLHS());
669  OS << "[";
670  PrintExpr(Node->getRHS());
671  OS << "]";
672}
673
674void StmtPrinter::VisitCallExpr(CallExpr *Call) {
675  PrintExpr(Call->getCallee());
676  OS << "(";
677  for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
678    if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
679      // Don't print any defaulted arguments
680      break;
681    }
682
683    if (i) OS << ", ";
684    PrintExpr(Call->getArg(i));
685  }
686  OS << ")";
687}
688void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
689  PrintExpr(Node->getBase());
690  OS << (Node->isArrow() ? "->" : ".");
691
692  FieldDecl *Field = Node->getMemberDecl();
693  assert(Field && "MemberExpr should alway reference a field!");
694  OS << Field->getName();
695}
696void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
697  PrintExpr(Node->getBase());
698  OS << ".";
699  OS << Node->getAccessor().getName();
700}
701void StmtPrinter::VisitCastExpr(CastExpr *Node) {
702  OS << "(" << Node->getType().getAsString() << ")";
703  PrintExpr(Node->getSubExpr());
704}
705void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
706  OS << "(" << Node->getType().getAsString() << ")";
707  PrintExpr(Node->getInitializer());
708}
709void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
710  // No need to print anything, simply forward to the sub expression.
711  PrintExpr(Node->getSubExpr());
712}
713void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
714  PrintExpr(Node->getLHS());
715  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
716  PrintExpr(Node->getRHS());
717}
718void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
719  PrintExpr(Node->getLHS());
720  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
721  PrintExpr(Node->getRHS());
722}
723void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
724  PrintExpr(Node->getCond());
725
726  if (Node->getLHS()) {
727    OS << " ? ";
728    PrintExpr(Node->getLHS());
729    OS << " : ";
730  }
731  else { // Handle GCC extention where LHS can be NULL.
732    OS << " ?: ";
733  }
734
735  PrintExpr(Node->getRHS());
736}
737
738// GNU extensions.
739
740void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
741  OS << "&&" << Node->getLabel()->getName();
742}
743
744void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
745  OS << "(";
746  PrintRawCompoundStmt(E->getSubStmt());
747  OS << ")";
748}
749
750void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
751  OS << "__builtin_types_compatible_p(";
752  OS << Node->getArgType1().getAsString() << ",";
753  OS << Node->getArgType2().getAsString() << ")";
754}
755
756void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
757  OS << "__builtin_choose_expr(";
758  PrintExpr(Node->getCond());
759  OS << ", ";
760  PrintExpr(Node->getLHS());
761  OS << ", ";
762  PrintExpr(Node->getRHS());
763  OS << ")";
764}
765
766void StmtPrinter::VisitOverloadExpr(OverloadExpr *Node) {
767  OS << "__builtin_overload(";
768  for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
769    if (i) OS << ", ";
770    PrintExpr(Node->getExpr(i));
771  }
772  OS << ")";
773}
774
775void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
776  OS << "__builtin_shufflevector(";
777  for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
778    if (i) OS << ", ";
779    PrintExpr(Node->getExpr(i));
780  }
781  OS << ")";
782}
783
784void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
785  OS << "{ ";
786  for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
787    if (i) OS << ", ";
788    PrintExpr(Node->getInit(i));
789  }
790  OS << " }";
791}
792
793void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
794  OS << "va_arg(";
795  PrintExpr(Node->getSubExpr());
796  OS << ", ";
797  OS << Node->getType().getAsString();
798  OS << ")";
799}
800
801// C++
802
803void StmtPrinter::VisitCXXCastExpr(CXXCastExpr *Node) {
804  OS << CXXCastExpr::getOpcodeStr(Node->getOpcode()) << '<';
805  OS << Node->getDestType().getAsString() << ">(";
806  PrintExpr(Node->getSubExpr());
807  OS << ")";
808}
809
810void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
811  OS << (Node->getValue() ? "true" : "false");
812}
813
814void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
815  if (Node->getSubExpr() == 0)
816    OS << "throw";
817  else {
818    OS << "throw ";
819    PrintExpr(Node->getSubExpr());
820  }
821}
822
823void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
824  // Nothing to print: we picked up the default argument
825}
826
827// Obj-C
828
829void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
830  OS << "@";
831  VisitStringLiteral(Node->getString());
832}
833
834void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
835  OS << "@encode(" << Node->getEncodedType().getAsString() << ")";
836}
837
838void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
839  OS << "@selector(" << Node->getSelector().getName() << ")";
840}
841
842void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
843  OS << "@protocol(" << Node->getProtocol()->getName() << ")";
844}
845
846void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
847  OS << "[";
848  Expr *receiver = Mess->getReceiver();
849  if (receiver) PrintExpr(receiver);
850  else OS << Mess->getClassName()->getName();
851  OS << ' ';
852  Selector selector = Mess->getSelector();
853  if (selector.isUnarySelector()) {
854    OS << selector.getIdentifierInfoForSlot(0)->getName();
855  } else {
856    for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
857      if (i < selector.getNumArgs()) {
858        if (i > 0) OS << ' ';
859        if (selector.getIdentifierInfoForSlot(i))
860          OS << selector.getIdentifierInfoForSlot(i)->getName() << ":";
861        else
862           OS << ":";
863      }
864      else OS << ", "; // Handle variadic methods.
865
866      PrintExpr(Mess->getArg(i));
867    }
868  }
869  OS << "]";
870}
871
872//===----------------------------------------------------------------------===//
873// Stmt method implementations
874//===----------------------------------------------------------------------===//
875
876void Stmt::dumpPretty() const {
877  printPretty(*llvm::cerr.stream());
878}
879
880void Stmt::printPretty(std::ostream &OS, PrinterHelper* Helper) const {
881  if (this == 0) {
882    OS << "<NULL>";
883    return;
884  }
885
886  StmtPrinter P(OS, Helper);
887  P.Visit(const_cast<Stmt*>(this));
888}
889
890//===----------------------------------------------------------------------===//
891// PrinterHelper
892//===----------------------------------------------------------------------===//
893
894// Implement virtual destructor.
895PrinterHelper::~PrinterHelper() {}
896