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