StmtPrinter.cpp revision 63c00d7f35fa060c0a446c9df3a4402d9c7757fe
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/DeclCXX.h"
17#include "clang/AST/DeclObjC.h"
18#include "clang/AST/DeclTemplate.h"
19#include "clang/AST/PrettyPrinter.h"
20#include "llvm/Support/Format.h"
21#include "clang/AST/Expr.h"
22#include "clang/AST/ExprCXX.h"
23using namespace clang;
24
25//===----------------------------------------------------------------------===//
26// StmtPrinter Visitor
27//===----------------------------------------------------------------------===//
28
29namespace  {
30  class StmtPrinter : public StmtVisitor<StmtPrinter> {
31    llvm::raw_ostream &OS;
32    ASTContext &Context;
33    unsigned IndentLevel;
34    clang::PrinterHelper* Helper;
35    PrintingPolicy Policy;
36
37  public:
38    StmtPrinter(llvm::raw_ostream &os, ASTContext &C, PrinterHelper* helper,
39                const PrintingPolicy &Policy,
40                unsigned Indentation = 0)
41      : OS(os), Context(C), IndentLevel(Indentation), Helper(helper),
42        Policy(Policy) {}
43
44    void PrintStmt(Stmt *S) {
45      PrintStmt(S, Policy.Indentation);
46    }
47
48    void PrintStmt(Stmt *S, int SubIndent) {
49      IndentLevel += SubIndent;
50      if (S && isa<Expr>(S)) {
51        // If this is an expr used in a stmt context, indent and newline it.
52        Indent();
53        Visit(S);
54        OS << ";\n";
55      } else if (S) {
56        Visit(S);
57      } else {
58        Indent() << "<<<NULL STATEMENT>>>\n";
59      }
60      IndentLevel -= SubIndent;
61    }
62
63    void PrintRawCompoundStmt(CompoundStmt *S);
64    void PrintRawDecl(Decl *D);
65    void PrintRawDeclStmt(DeclStmt *S);
66    void PrintRawIfStmt(IfStmt *If);
67    void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
68    void PrintCallArgs(CallExpr *E);
69
70    void PrintExpr(Expr *E) {
71      if (E)
72        Visit(E);
73      else
74        OS << "<null expr>";
75    }
76
77    llvm::raw_ostream &Indent(int Delta = 0) {
78      for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
79        OS << "  ";
80      return OS;
81    }
82
83    void Visit(Stmt* S) {
84      if (Helper && Helper->handledStmt(S,OS))
85          return;
86      else StmtVisitor<StmtPrinter>::Visit(S);
87    }
88
89    void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED {
90      Indent() << "<<unknown stmt type>>\n";
91    }
92    void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED {
93      OS << "<<unknown expr type>>";
94    }
95    void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
96
97#define ABSTRACT_STMT(CLASS)
98#define STMT(CLASS, PARENT) \
99    void Visit##CLASS(CLASS *Node);
100#include "clang/AST/StmtNodes.inc"
101  };
102}
103
104//===----------------------------------------------------------------------===//
105//  Stmt printing methods.
106//===----------------------------------------------------------------------===//
107
108/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
109/// with no newline after the }.
110void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
111  OS << "{\n";
112  for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
113       I != E; ++I)
114    PrintStmt(*I);
115
116  Indent() << "}";
117}
118
119void StmtPrinter::PrintRawDecl(Decl *D) {
120  D->print(OS, Policy, IndentLevel);
121}
122
123void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
124  DeclStmt::decl_iterator Begin = S->decl_begin(), End = S->decl_end();
125  llvm::SmallVector<Decl*, 2> Decls;
126  for ( ; Begin != End; ++Begin)
127    Decls.push_back(*Begin);
128
129  Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
130}
131
132void StmtPrinter::VisitNullStmt(NullStmt *Node) {
133  Indent() << ";\n";
134}
135
136void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
137  Indent();
138  PrintRawDeclStmt(Node);
139  OS << ";\n";
140}
141
142void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
143  Indent();
144  PrintRawCompoundStmt(Node);
145  OS << "\n";
146}
147
148void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
149  Indent(-1) << "case ";
150  PrintExpr(Node->getLHS());
151  if (Node->getRHS()) {
152    OS << " ... ";
153    PrintExpr(Node->getRHS());
154  }
155  OS << ":\n";
156
157  PrintStmt(Node->getSubStmt(), 0);
158}
159
160void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
161  Indent(-1) << "default:\n";
162  PrintStmt(Node->getSubStmt(), 0);
163}
164
165void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
166  Indent(-1) << Node->getName() << ":\n";
167  PrintStmt(Node->getSubStmt(), 0);
168}
169
170void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
171  OS << "if (";
172  PrintExpr(If->getCond());
173  OS << ')';
174
175  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) {
176    OS << ' ';
177    PrintRawCompoundStmt(CS);
178    OS << (If->getElse() ? ' ' : '\n');
179  } else {
180    OS << '\n';
181    PrintStmt(If->getThen());
182    if (If->getElse()) Indent();
183  }
184
185  if (Stmt *Else = If->getElse()) {
186    OS << "else";
187
188    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) {
189      OS << ' ';
190      PrintRawCompoundStmt(CS);
191      OS << '\n';
192    } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) {
193      OS << ' ';
194      PrintRawIfStmt(ElseIf);
195    } else {
196      OS << '\n';
197      PrintStmt(If->getElse());
198    }
199  }
200}
201
202void StmtPrinter::VisitIfStmt(IfStmt *If) {
203  Indent();
204  PrintRawIfStmt(If);
205}
206
207void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
208  Indent() << "switch (";
209  PrintExpr(Node->getCond());
210  OS << ")";
211
212  // Pretty print compoundstmt bodies (very common).
213  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
214    OS << " ";
215    PrintRawCompoundStmt(CS);
216    OS << "\n";
217  } else {
218    OS << "\n";
219    PrintStmt(Node->getBody());
220  }
221}
222
223void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
224  Indent() << "while (";
225  PrintExpr(Node->getCond());
226  OS << ")\n";
227  PrintStmt(Node->getBody());
228}
229
230void StmtPrinter::VisitDoStmt(DoStmt *Node) {
231  Indent() << "do ";
232  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
233    PrintRawCompoundStmt(CS);
234    OS << " ";
235  } else {
236    OS << "\n";
237    PrintStmt(Node->getBody());
238    Indent();
239  }
240
241  OS << "while (";
242  PrintExpr(Node->getCond());
243  OS << ");\n";
244}
245
246void StmtPrinter::VisitForStmt(ForStmt *Node) {
247  Indent() << "for (";
248  if (Node->getInit()) {
249    if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit()))
250      PrintRawDeclStmt(DS);
251    else
252      PrintExpr(cast<Expr>(Node->getInit()));
253  }
254  OS << ";";
255  if (Node->getCond()) {
256    OS << " ";
257    PrintExpr(Node->getCond());
258  }
259  OS << ";";
260  if (Node->getInc()) {
261    OS << " ";
262    PrintExpr(Node->getInc());
263  }
264  OS << ") ";
265
266  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
267    PrintRawCompoundStmt(CS);
268    OS << "\n";
269  } else {
270    OS << "\n";
271    PrintStmt(Node->getBody());
272  }
273}
274
275void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
276  Indent() << "for (";
277  if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement()))
278    PrintRawDeclStmt(DS);
279  else
280    PrintExpr(cast<Expr>(Node->getElement()));
281  OS << " in ";
282  PrintExpr(Node->getCollection());
283  OS << ") ";
284
285  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
286    PrintRawCompoundStmt(CS);
287    OS << "\n";
288  } else {
289    OS << "\n";
290    PrintStmt(Node->getBody());
291  }
292}
293
294void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
295  Indent() << "goto " << Node->getLabel()->getName() << ";\n";
296}
297
298void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
299  Indent() << "goto *";
300  PrintExpr(Node->getTarget());
301  OS << ";\n";
302}
303
304void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
305  Indent() << "continue;\n";
306}
307
308void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
309  Indent() << "break;\n";
310}
311
312
313void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
314  Indent() << "return";
315  if (Node->getRetValue()) {
316    OS << " ";
317    PrintExpr(Node->getRetValue());
318  }
319  OS << ";\n";
320}
321
322
323void StmtPrinter::VisitAsmStmt(AsmStmt *Node) {
324  Indent() << "asm ";
325
326  if (Node->isVolatile())
327    OS << "volatile ";
328
329  OS << "(";
330  VisitStringLiteral(Node->getAsmString());
331
332  // Outputs
333  if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
334      Node->getNumClobbers() != 0)
335    OS << " : ";
336
337  for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
338    if (i != 0)
339      OS << ", ";
340
341    if (!Node->getOutputName(i).empty()) {
342      OS << '[';
343      OS << Node->getOutputName(i);
344      OS << "] ";
345    }
346
347    VisitStringLiteral(Node->getOutputConstraintLiteral(i));
348    OS << " ";
349    Visit(Node->getOutputExpr(i));
350  }
351
352  // Inputs
353  if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
354    OS << " : ";
355
356  for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
357    if (i != 0)
358      OS << ", ";
359
360    if (!Node->getInputName(i).empty()) {
361      OS << '[';
362      OS << Node->getInputName(i);
363      OS << "] ";
364    }
365
366    VisitStringLiteral(Node->getInputConstraintLiteral(i));
367    OS << " ";
368    Visit(Node->getInputExpr(i));
369  }
370
371  // Clobbers
372  if (Node->getNumClobbers() != 0)
373    OS << " : ";
374
375  for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
376    if (i != 0)
377      OS << ", ";
378
379    VisitStringLiteral(Node->getClobber(i));
380  }
381
382  OS << ");\n";
383}
384
385void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
386  Indent() << "@try";
387  if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
388    PrintRawCompoundStmt(TS);
389    OS << "\n";
390  }
391
392  for (unsigned I = 0, N = Node->getNumCatchStmts(); I != N; ++I) {
393    ObjCAtCatchStmt *catchStmt = Node->getCatchStmt(I);
394    Indent() << "@catch(";
395    if (catchStmt->getCatchParamDecl()) {
396      if (Decl *DS = catchStmt->getCatchParamDecl())
397        PrintRawDecl(DS);
398    }
399    OS << ")";
400    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
401      PrintRawCompoundStmt(CS);
402      OS << "\n";
403    }
404  }
405
406  if (ObjCAtFinallyStmt *FS = static_cast<ObjCAtFinallyStmt *>(
407        Node->getFinallyStmt())) {
408    Indent() << "@finally";
409    PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
410    OS << "\n";
411  }
412}
413
414void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
415}
416
417void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
418  Indent() << "@catch (...) { /* todo */ } \n";
419}
420
421void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
422  Indent() << "@throw";
423  if (Node->getThrowExpr()) {
424    OS << " ";
425    PrintExpr(Node->getThrowExpr());
426  }
427  OS << ";\n";
428}
429
430void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
431  Indent() << "@synchronized (";
432  PrintExpr(Node->getSynchExpr());
433  OS << ")";
434  PrintRawCompoundStmt(Node->getSynchBody());
435  OS << "\n";
436}
437
438void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
439  OS << "catch (";
440  if (Decl *ExDecl = Node->getExceptionDecl())
441    PrintRawDecl(ExDecl);
442  else
443    OS << "...";
444  OS << ") ";
445  PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
446}
447
448void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
449  Indent();
450  PrintRawCXXCatchStmt(Node);
451  OS << "\n";
452}
453
454void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
455  Indent() << "try ";
456  PrintRawCompoundStmt(Node->getTryBlock());
457  for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
458    OS << " ";
459    PrintRawCXXCatchStmt(Node->getHandler(i));
460  }
461  OS << "\n";
462}
463
464//===----------------------------------------------------------------------===//
465//  Expr printing methods.
466//===----------------------------------------------------------------------===//
467
468void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
469  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
470    Qualifier->print(OS, Policy);
471  OS << Node->getNameInfo();
472  if (Node->hasExplicitTemplateArgs())
473    OS << TemplateSpecializationType::PrintTemplateArgumentList(
474                                                    Node->getTemplateArgs(),
475                                                    Node->getNumTemplateArgs(),
476                                                    Policy);
477}
478
479void StmtPrinter::VisitDependentScopeDeclRefExpr(
480                                           DependentScopeDeclRefExpr *Node) {
481  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
482    Qualifier->print(OS, Policy);
483  OS << Node->getNameInfo();
484  if (Node->hasExplicitTemplateArgs())
485    OS << TemplateSpecializationType::PrintTemplateArgumentList(
486                                                   Node->getTemplateArgs(),
487                                                   Node->getNumTemplateArgs(),
488                                                   Policy);
489}
490
491void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
492  if (Node->getQualifier())
493    Node->getQualifier()->print(OS, Policy);
494  OS << Node->getNameInfo();
495  if (Node->hasExplicitTemplateArgs())
496    OS << TemplateSpecializationType::PrintTemplateArgumentList(
497                                                   Node->getTemplateArgs(),
498                                                   Node->getNumTemplateArgs(),
499                                                   Policy);
500}
501
502void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
503  if (Node->getBase()) {
504    PrintExpr(Node->getBase());
505    OS << (Node->isArrow() ? "->" : ".");
506  }
507  OS << Node->getDecl();
508}
509
510void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
511  if (Node->isSuperReceiver())
512    OS << "super.";
513  else if (Node->getBase()) {
514    PrintExpr(Node->getBase());
515    OS << ".";
516  }
517
518  if (Node->isImplicitProperty())
519    OS << Node->getImplicitPropertyGetter()->getSelector().getAsString();
520  else
521    OS << Node->getExplicitProperty()->getName();
522}
523
524void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
525  switch (Node->getIdentType()) {
526    default:
527      assert(0 && "unknown case");
528    case PredefinedExpr::Func:
529      OS << "__func__";
530      break;
531    case PredefinedExpr::Function:
532      OS << "__FUNCTION__";
533      break;
534    case PredefinedExpr::PrettyFunction:
535      OS << "__PRETTY_FUNCTION__";
536      break;
537  }
538}
539
540void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
541  unsigned value = Node->getValue();
542  if (Node->isWide())
543    OS << "L";
544  switch (value) {
545  case '\\':
546    OS << "'\\\\'";
547    break;
548  case '\'':
549    OS << "'\\''";
550    break;
551  case '\a':
552    // TODO: K&R: the meaning of '\\a' is different in traditional C
553    OS << "'\\a'";
554    break;
555  case '\b':
556    OS << "'\\b'";
557    break;
558  // Nonstandard escape sequence.
559  /*case '\e':
560    OS << "'\\e'";
561    break;*/
562  case '\f':
563    OS << "'\\f'";
564    break;
565  case '\n':
566    OS << "'\\n'";
567    break;
568  case '\r':
569    OS << "'\\r'";
570    break;
571  case '\t':
572    OS << "'\\t'";
573    break;
574  case '\v':
575    OS << "'\\v'";
576    break;
577  default:
578    if (value < 256 && isprint(value)) {
579      OS << "'" << (char)value << "'";
580    } else if (value < 256) {
581      OS << "'\\x" << llvm::format("%x", value) << "'";
582    } else {
583      // FIXME what to really do here?
584      OS << value;
585    }
586  }
587}
588
589void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
590  bool isSigned = Node->getType()->isSignedIntegerType();
591  OS << Node->getValue().toString(10, isSigned);
592
593  // Emit suffixes.  Integer literals are always a builtin integer type.
594  switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
595  default: assert(0 && "Unexpected type for integer literal!");
596  case BuiltinType::Int:       break; // no suffix.
597  case BuiltinType::UInt:      OS << 'U'; break;
598  case BuiltinType::Long:      OS << 'L'; break;
599  case BuiltinType::ULong:     OS << "UL"; break;
600  case BuiltinType::LongLong:  OS << "LL"; break;
601  case BuiltinType::ULongLong: OS << "ULL"; break;
602  }
603}
604void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
605  // FIXME: print value more precisely.
606  OS << Node->getValueAsApproximateDouble();
607}
608
609void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
610  PrintExpr(Node->getSubExpr());
611  OS << "i";
612}
613
614void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
615  if (Str->isWide()) OS << 'L';
616  OS << '"';
617
618  // FIXME: this doesn't print wstrings right.
619  llvm::StringRef StrData = Str->getString();
620  for (llvm::StringRef::iterator I = StrData.begin(), E = StrData.end();
621                                                             I != E; ++I) {
622    unsigned char Char = *I;
623
624    switch (Char) {
625    default:
626      if (isprint(Char))
627        OS << (char)Char;
628      else  // Output anything hard as an octal escape.
629        OS << '\\'
630        << (char)('0'+ ((Char >> 6) & 7))
631        << (char)('0'+ ((Char >> 3) & 7))
632        << (char)('0'+ ((Char >> 0) & 7));
633      break;
634    // Handle some common non-printable cases to make dumps prettier.
635    case '\\': OS << "\\\\"; break;
636    case '"': OS << "\\\""; break;
637    case '\n': OS << "\\n"; break;
638    case '\t': OS << "\\t"; break;
639    case '\a': OS << "\\a"; break;
640    case '\b': OS << "\\b"; break;
641    }
642  }
643  OS << '"';
644}
645void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
646  OS << "(";
647  PrintExpr(Node->getSubExpr());
648  OS << ")";
649}
650void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
651  if (!Node->isPostfix()) {
652    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
653
654    // Print a space if this is an "identifier operator" like __real, or if
655    // it might be concatenated incorrectly like '+'.
656    switch (Node->getOpcode()) {
657    default: break;
658    case UO_Real:
659    case UO_Imag:
660    case UO_Extension:
661      OS << ' ';
662      break;
663    case UO_Plus:
664    case UO_Minus:
665      if (isa<UnaryOperator>(Node->getSubExpr()))
666        OS << ' ';
667      break;
668    }
669  }
670  PrintExpr(Node->getSubExpr());
671
672  if (Node->isPostfix())
673    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
674}
675
676void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
677  OS << "__builtin_offsetof(";
678  OS << Node->getTypeSourceInfo()->getType().getAsString(Policy) << ", ";
679  bool PrintedSomething = false;
680  for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
681    OffsetOfExpr::OffsetOfNode ON = Node->getComponent(i);
682    if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Array) {
683      // Array node
684      OS << "[";
685      PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
686      OS << "]";
687      PrintedSomething = true;
688      continue;
689    }
690
691    // Skip implicit base indirections.
692    if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Base)
693      continue;
694
695    // Field or identifier node.
696    IdentifierInfo *Id = ON.getFieldName();
697    if (!Id)
698      continue;
699
700    if (PrintedSomething)
701      OS << ".";
702    else
703      PrintedSomething = true;
704    OS << Id->getName();
705  }
706  OS << ")";
707}
708
709void StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
710  OS << (Node->isSizeOf() ? "sizeof" : "__alignof");
711  if (Node->isArgumentType())
712    OS << "(" << Node->getArgumentType().getAsString(Policy) << ")";
713  else {
714    OS << " ";
715    PrintExpr(Node->getArgumentExpr());
716  }
717}
718void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
719  PrintExpr(Node->getLHS());
720  OS << "[";
721  PrintExpr(Node->getRHS());
722  OS << "]";
723}
724
725void StmtPrinter::PrintCallArgs(CallExpr *Call) {
726  for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
727    if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
728      // Don't print any defaulted arguments
729      break;
730    }
731
732    if (i) OS << ", ";
733    PrintExpr(Call->getArg(i));
734  }
735}
736
737void StmtPrinter::VisitCallExpr(CallExpr *Call) {
738  PrintExpr(Call->getCallee());
739  OS << "(";
740  PrintCallArgs(Call);
741  OS << ")";
742}
743void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
744  // FIXME: Suppress printing implicit bases (like "this")
745  PrintExpr(Node->getBase());
746  if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
747    if (FD->isAnonymousStructOrUnion())
748      return;
749  OS << (Node->isArrow() ? "->" : ".");
750  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
751    Qualifier->print(OS, Policy);
752
753  OS << Node->getMemberNameInfo();
754
755  if (Node->hasExplicitTemplateArgs())
756    OS << TemplateSpecializationType::PrintTemplateArgumentList(
757                                                    Node->getTemplateArgs(),
758                                                    Node->getNumTemplateArgs(),
759                                                                Policy);
760}
761void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
762  PrintExpr(Node->getBase());
763  OS << (Node->isArrow() ? "->isa" : ".isa");
764}
765
766void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
767  PrintExpr(Node->getBase());
768  OS << ".";
769  OS << Node->getAccessor().getName();
770}
771void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
772  OS << "(" << Node->getType().getAsString(Policy) << ")";
773  PrintExpr(Node->getSubExpr());
774}
775void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
776  OS << "(" << Node->getType().getAsString(Policy) << ")";
777  PrintExpr(Node->getInitializer());
778}
779void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
780  // No need to print anything, simply forward to the sub expression.
781  PrintExpr(Node->getSubExpr());
782}
783void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
784  PrintExpr(Node->getLHS());
785  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
786  PrintExpr(Node->getRHS());
787}
788void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
789  PrintExpr(Node->getLHS());
790  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
791  PrintExpr(Node->getRHS());
792}
793void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
794  PrintExpr(Node->getCond());
795
796  if (Node->getLHS()) {
797    OS << " ? ";
798    PrintExpr(Node->getLHS());
799    OS << " : ";
800  }
801  else { // Handle GCC extension where LHS can be NULL.
802    OS << " ?: ";
803  }
804
805  PrintExpr(Node->getRHS());
806}
807
808// GNU extensions.
809
810void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
811  OS << "&&" << Node->getLabel()->getName();
812}
813
814void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
815  OS << "(";
816  PrintRawCompoundStmt(E->getSubStmt());
817  OS << ")";
818}
819
820void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
821  OS << "__builtin_choose_expr(";
822  PrintExpr(Node->getCond());
823  OS << ", ";
824  PrintExpr(Node->getLHS());
825  OS << ", ";
826  PrintExpr(Node->getRHS());
827  OS << ")";
828}
829
830void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
831  OS << "__null";
832}
833
834void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
835  OS << "__builtin_shufflevector(";
836  for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
837    if (i) OS << ", ";
838    PrintExpr(Node->getExpr(i));
839  }
840  OS << ")";
841}
842
843void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
844  if (Node->getSyntacticForm()) {
845    Visit(Node->getSyntacticForm());
846    return;
847  }
848
849  OS << "{ ";
850  for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
851    if (i) OS << ", ";
852    if (Node->getInit(i))
853      PrintExpr(Node->getInit(i));
854    else
855      OS << "0";
856  }
857  OS << " }";
858}
859
860void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
861  OS << "( ";
862  for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
863    if (i) OS << ", ";
864    PrintExpr(Node->getExpr(i));
865  }
866  OS << " )";
867}
868
869void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
870  for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(),
871                      DEnd = Node->designators_end();
872       D != DEnd; ++D) {
873    if (D->isFieldDesignator()) {
874      if (D->getDotLoc().isInvalid())
875        OS << D->getFieldName()->getName() << ":";
876      else
877        OS << "." << D->getFieldName()->getName();
878    } else {
879      OS << "[";
880      if (D->isArrayDesignator()) {
881        PrintExpr(Node->getArrayIndex(*D));
882      } else {
883        PrintExpr(Node->getArrayRangeStart(*D));
884        OS << " ... ";
885        PrintExpr(Node->getArrayRangeEnd(*D));
886      }
887      OS << "]";
888    }
889  }
890
891  OS << " = ";
892  PrintExpr(Node->getInit());
893}
894
895void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
896  if (Policy.LangOpts.CPlusPlus)
897    OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()";
898  else {
899    OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")";
900    if (Node->getType()->isRecordType())
901      OS << "{}";
902    else
903      OS << 0;
904  }
905}
906
907void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
908  OS << "__builtin_va_arg(";
909  PrintExpr(Node->getSubExpr());
910  OS << ", ";
911  OS << Node->getType().getAsString(Policy);
912  OS << ")";
913}
914
915// C++
916void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
917  const char *OpStrings[NUM_OVERLOADED_OPERATORS] = {
918    "",
919#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
920    Spelling,
921#include "clang/Basic/OperatorKinds.def"
922  };
923
924  OverloadedOperatorKind Kind = Node->getOperator();
925  if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
926    if (Node->getNumArgs() == 1) {
927      OS << OpStrings[Kind] << ' ';
928      PrintExpr(Node->getArg(0));
929    } else {
930      PrintExpr(Node->getArg(0));
931      OS << ' ' << OpStrings[Kind];
932    }
933  } else if (Kind == OO_Call) {
934    PrintExpr(Node->getArg(0));
935    OS << '(';
936    for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
937      if (ArgIdx > 1)
938        OS << ", ";
939      if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
940        PrintExpr(Node->getArg(ArgIdx));
941    }
942    OS << ')';
943  } else if (Kind == OO_Subscript) {
944    PrintExpr(Node->getArg(0));
945    OS << '[';
946    PrintExpr(Node->getArg(1));
947    OS << ']';
948  } else if (Node->getNumArgs() == 1) {
949    OS << OpStrings[Kind] << ' ';
950    PrintExpr(Node->getArg(0));
951  } else if (Node->getNumArgs() == 2) {
952    PrintExpr(Node->getArg(0));
953    OS << ' ' << OpStrings[Kind] << ' ';
954    PrintExpr(Node->getArg(1));
955  } else {
956    assert(false && "unknown overloaded operator");
957  }
958}
959
960void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
961  VisitCallExpr(cast<CallExpr>(Node));
962}
963
964void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
965  OS << Node->getCastName() << '<';
966  OS << Node->getTypeAsWritten().getAsString(Policy) << ">(";
967  PrintExpr(Node->getSubExpr());
968  OS << ")";
969}
970
971void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
972  VisitCXXNamedCastExpr(Node);
973}
974
975void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
976  VisitCXXNamedCastExpr(Node);
977}
978
979void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
980  VisitCXXNamedCastExpr(Node);
981}
982
983void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
984  VisitCXXNamedCastExpr(Node);
985}
986
987void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
988  OS << "typeid(";
989  if (Node->isTypeOperand()) {
990    OS << Node->getTypeOperand().getAsString(Policy);
991  } else {
992    PrintExpr(Node->getExprOperand());
993  }
994  OS << ")";
995}
996
997void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
998  OS << "__uuidof(";
999  if (Node->isTypeOperand()) {
1000    OS << Node->getTypeOperand().getAsString(Policy);
1001  } else {
1002    PrintExpr(Node->getExprOperand());
1003  }
1004  OS << ")";
1005}
1006
1007void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
1008  OS << (Node->getValue() ? "true" : "false");
1009}
1010
1011void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
1012  OS << "nullptr";
1013}
1014
1015void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
1016  OS << "this";
1017}
1018
1019void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
1020  if (Node->getSubExpr() == 0)
1021    OS << "throw";
1022  else {
1023    OS << "throw ";
1024    PrintExpr(Node->getSubExpr());
1025  }
1026}
1027
1028void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
1029  // Nothing to print: we picked up the default argument
1030}
1031
1032void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
1033  OS << Node->getType().getAsString(Policy);
1034  OS << "(";
1035  PrintExpr(Node->getSubExpr());
1036  OS << ")";
1037}
1038
1039void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
1040  PrintExpr(Node->getSubExpr());
1041}
1042
1043void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
1044  OS << Node->getType().getAsString(Policy);
1045  OS << "(";
1046  for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
1047                                         ArgEnd = Node->arg_end();
1048       Arg != ArgEnd; ++Arg) {
1049    if (Arg != Node->arg_begin())
1050      OS << ", ";
1051    PrintExpr(*Arg);
1052  }
1053  OS << ")";
1054}
1055
1056void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
1057  if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
1058    OS << TSInfo->getType().getAsString(Policy) << "()";
1059  else
1060    OS << Node->getType().getAsString(Policy) << "()";
1061}
1062
1063void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
1064  if (E->isGlobalNew())
1065    OS << "::";
1066  OS << "new ";
1067  unsigned NumPlace = E->getNumPlacementArgs();
1068  if (NumPlace > 0) {
1069    OS << "(";
1070    PrintExpr(E->getPlacementArg(0));
1071    for (unsigned i = 1; i < NumPlace; ++i) {
1072      OS << ", ";
1073      PrintExpr(E->getPlacementArg(i));
1074    }
1075    OS << ") ";
1076  }
1077  if (E->isParenTypeId())
1078    OS << "(";
1079  std::string TypeS;
1080  if (Expr *Size = E->getArraySize()) {
1081    llvm::raw_string_ostream s(TypeS);
1082    Size->printPretty(s, Context, Helper, Policy);
1083    s.flush();
1084    TypeS = "[" + TypeS + "]";
1085  }
1086  E->getAllocatedType().getAsStringInternal(TypeS, Policy);
1087  OS << TypeS;
1088  if (E->isParenTypeId())
1089    OS << ")";
1090
1091  if (E->hasInitializer()) {
1092    OS << "(";
1093    unsigned NumCons = E->getNumConstructorArgs();
1094    if (NumCons > 0) {
1095      PrintExpr(E->getConstructorArg(0));
1096      for (unsigned i = 1; i < NumCons; ++i) {
1097        OS << ", ";
1098        PrintExpr(E->getConstructorArg(i));
1099      }
1100    }
1101    OS << ")";
1102  }
1103}
1104
1105void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
1106  if (E->isGlobalDelete())
1107    OS << "::";
1108  OS << "delete ";
1109  if (E->isArrayForm())
1110    OS << "[] ";
1111  PrintExpr(E->getArgument());
1112}
1113
1114void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1115  PrintExpr(E->getBase());
1116  if (E->isArrow())
1117    OS << "->";
1118  else
1119    OS << '.';
1120  if (E->getQualifier())
1121    E->getQualifier()->print(OS, Policy);
1122
1123  std::string TypeS;
1124  if (IdentifierInfo *II = E->getDestroyedTypeIdentifier())
1125    OS << II->getName();
1126  else
1127    E->getDestroyedType().getAsStringInternal(TypeS, Policy);
1128  OS << TypeS;
1129}
1130
1131void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
1132  for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
1133    if (isa<CXXDefaultArgExpr>(E->getArg(i))) {
1134      // Don't print any defaulted arguments
1135      break;
1136    }
1137
1138    if (i) OS << ", ";
1139    PrintExpr(E->getArg(i));
1140  }
1141}
1142
1143void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
1144  // Just forward to the sub expression.
1145  PrintExpr(E->getSubExpr());
1146}
1147
1148void
1149StmtPrinter::VisitCXXUnresolvedConstructExpr(
1150                                           CXXUnresolvedConstructExpr *Node) {
1151  OS << Node->getTypeAsWritten().getAsString(Policy);
1152  OS << "(";
1153  for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(),
1154                                             ArgEnd = Node->arg_end();
1155       Arg != ArgEnd; ++Arg) {
1156    if (Arg != Node->arg_begin())
1157      OS << ", ";
1158    PrintExpr(*Arg);
1159  }
1160  OS << ")";
1161}
1162
1163void StmtPrinter::VisitCXXDependentScopeMemberExpr(
1164                                         CXXDependentScopeMemberExpr *Node) {
1165  if (!Node->isImplicitAccess()) {
1166    PrintExpr(Node->getBase());
1167    OS << (Node->isArrow() ? "->" : ".");
1168  }
1169  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1170    Qualifier->print(OS, Policy);
1171  else if (Node->hasExplicitTemplateArgs())
1172    // FIXME: Track use of "template" keyword explicitly?
1173    OS << "template ";
1174
1175  OS << Node->getMemberNameInfo();
1176
1177  if (Node->hasExplicitTemplateArgs()) {
1178    OS << TemplateSpecializationType::PrintTemplateArgumentList(
1179                                                    Node->getTemplateArgs(),
1180                                                    Node->getNumTemplateArgs(),
1181                                                    Policy);
1182  }
1183}
1184
1185void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
1186  if (!Node->isImplicitAccess()) {
1187    PrintExpr(Node->getBase());
1188    OS << (Node->isArrow() ? "->" : ".");
1189  }
1190  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1191    Qualifier->print(OS, Policy);
1192
1193  // FIXME: this might originally have been written with 'template'
1194
1195  OS << Node->getMemberNameInfo();
1196
1197  if (Node->hasExplicitTemplateArgs()) {
1198    OS << TemplateSpecializationType::PrintTemplateArgumentList(
1199                                                    Node->getTemplateArgs(),
1200                                                    Node->getNumTemplateArgs(),
1201                                                    Policy);
1202  }
1203}
1204
1205static const char *getTypeTraitName(UnaryTypeTrait UTT) {
1206  switch (UTT) {
1207  default: llvm_unreachable("Unknown unary type trait");
1208  case UTT_HasNothrowAssign:      return "__has_nothrow_assign";
1209  case UTT_HasNothrowCopy:        return "__has_nothrow_copy";
1210  case UTT_HasNothrowConstructor: return "__has_nothrow_constructor";
1211  case UTT_HasTrivialAssign:      return "__has_trivial_assign";
1212  case UTT_HasTrivialCopy:        return "__has_trivial_copy";
1213  case UTT_HasTrivialConstructor: return "__has_trivial_constructor";
1214  case UTT_HasTrivialDestructor:  return "__has_trivial_destructor";
1215  case UTT_HasVirtualDestructor:  return "__has_virtual_destructor";
1216  case UTT_IsAbstract:            return "__is_abstract";
1217  case UTT_IsClass:               return "__is_class";
1218  case UTT_IsEmpty:               return "__is_empty";
1219  case UTT_IsEnum:                return "__is_enum";
1220  case UTT_IsPOD:                 return "__is_pod";
1221  case UTT_IsPolymorphic:         return "__is_polymorphic";
1222  case UTT_IsUnion:               return "__is_union";
1223  }
1224  return "";
1225}
1226
1227static const char *getTypeTraitName(BinaryTypeTrait BTT) {
1228  switch (BTT) {
1229  case BTT_IsBaseOf:         return "__is_base_of";
1230  case BTT_TypeCompatible:   return "__builtin_types_compatible_p";
1231  case BTT_IsConvertibleTo:  return "__is_convertible_to";
1232  }
1233  return "";
1234}
1235
1236void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
1237  OS << getTypeTraitName(E->getTrait()) << "("
1238     << E->getQueriedType().getAsString(Policy) << ")";
1239}
1240
1241void StmtPrinter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
1242  OS << getTypeTraitName(E->getTrait()) << "("
1243     << E->getLhsType().getAsString(Policy) << ","
1244     << E->getRhsType().getAsString(Policy) << ")";
1245}
1246
1247void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
1248  OS << "noexcept(";
1249  PrintExpr(E->getOperand());
1250  OS << ")";
1251}
1252
1253void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
1254  PrintExpr(E->getPattern());
1255  OS << "...";
1256}
1257
1258void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
1259  OS << "sizeof...(" << E->getPack()->getNameAsString() << ")";
1260}
1261
1262void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
1263                                       SubstNonTypeTemplateParmPackExpr *Node) {
1264  OS << Node->getParameterPack()->getNameAsString();
1265}
1266
1267// Obj-C
1268
1269void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
1270  OS << "@";
1271  VisitStringLiteral(Node->getString());
1272}
1273
1274void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
1275  OS << "@encode(" << Node->getEncodedType().getAsString(Policy) << ')';
1276}
1277
1278void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
1279  OS << "@selector(" << Node->getSelector().getAsString() << ')';
1280}
1281
1282void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
1283  OS << "@protocol(" << Node->getProtocol() << ')';
1284}
1285
1286void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
1287  OS << "[";
1288  switch (Mess->getReceiverKind()) {
1289  case ObjCMessageExpr::Instance:
1290    PrintExpr(Mess->getInstanceReceiver());
1291    break;
1292
1293  case ObjCMessageExpr::Class:
1294    OS << Mess->getClassReceiver().getAsString(Policy);
1295    break;
1296
1297  case ObjCMessageExpr::SuperInstance:
1298  case ObjCMessageExpr::SuperClass:
1299    OS << "Super";
1300    break;
1301  }
1302
1303  OS << ' ';
1304  Selector selector = Mess->getSelector();
1305  if (selector.isUnarySelector()) {
1306    OS << selector.getIdentifierInfoForSlot(0)->getName();
1307  } else {
1308    for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
1309      if (i < selector.getNumArgs()) {
1310        if (i > 0) OS << ' ';
1311        if (selector.getIdentifierInfoForSlot(i))
1312          OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
1313        else
1314           OS << ":";
1315      }
1316      else OS << ", "; // Handle variadic methods.
1317
1318      PrintExpr(Mess->getArg(i));
1319    }
1320  }
1321  OS << "]";
1322}
1323
1324
1325void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
1326  BlockDecl *BD = Node->getBlockDecl();
1327  OS << "^";
1328
1329  const FunctionType *AFT = Node->getFunctionType();
1330
1331  if (isa<FunctionNoProtoType>(AFT)) {
1332    OS << "()";
1333  } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
1334    OS << '(';
1335    std::string ParamStr;
1336    for (BlockDecl::param_iterator AI = BD->param_begin(),
1337         E = BD->param_end(); AI != E; ++AI) {
1338      if (AI != BD->param_begin()) OS << ", ";
1339      ParamStr = (*AI)->getNameAsString();
1340      (*AI)->getType().getAsStringInternal(ParamStr, Policy);
1341      OS << ParamStr;
1342    }
1343
1344    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
1345    if (FT->isVariadic()) {
1346      if (!BD->param_empty()) OS << ", ";
1347      OS << "...";
1348    }
1349    OS << ')';
1350  }
1351}
1352
1353void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
1354  OS << Node->getDecl();
1355}
1356
1357void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {}
1358
1359//===----------------------------------------------------------------------===//
1360// Stmt method implementations
1361//===----------------------------------------------------------------------===//
1362
1363void Stmt::dumpPretty(ASTContext& Context) const {
1364  printPretty(llvm::errs(), Context, 0,
1365              PrintingPolicy(Context.getLangOptions()));
1366}
1367
1368void Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context,
1369                       PrinterHelper* Helper,
1370                       const PrintingPolicy &Policy,
1371                       unsigned Indentation) const {
1372  if (this == 0) {
1373    OS << "<NULL>";
1374    return;
1375  }
1376
1377  if (Policy.Dump && &Context) {
1378    dump(OS, Context.getSourceManager());
1379    return;
1380  }
1381
1382  StmtPrinter P(OS, Context, Helper, Policy, Indentation);
1383  P.Visit(const_cast<Stmt*>(this));
1384}
1385
1386//===----------------------------------------------------------------------===//
1387// PrinterHelper
1388//===----------------------------------------------------------------------===//
1389
1390// Implement virtual destructor.
1391PrinterHelper::~PrinterHelper() {}
1392