blob: a771b4ce1a72120c0b7261bbe707e8708684ccc5 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- StmtPrinter.cpp - Printing implementation for Stmt ASTs ----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Chris Lattner6000dac2007-08-08 22:51:59 +000010// This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which
11// pretty print the AST back out to C code.
Reid Spencer5f016e22007-07-11 17:01:13 +000012//
13//===----------------------------------------------------------------------===//
14
15#include "clang/AST/StmtVisitor.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/ExprCXX.h"
18#include "clang/Lex/IdentifierTable.h"
19#include "llvm/Support/Compiler.h"
20#include <iostream>
Chris Lattnerb0a721a2007-07-13 05:18:11 +000021#include <iomanip>
Reid Spencer5f016e22007-07-11 17:01:13 +000022using namespace clang;
23
24//===----------------------------------------------------------------------===//
25// StmtPrinter Visitor
26//===----------------------------------------------------------------------===//
27
28namespace {
Chris Lattnerc5598cb2007-08-21 04:04:25 +000029 class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor<StmtPrinter> {
Reid Spencer5f016e22007-07-11 17:01:13 +000030 std::ostream &OS;
31 unsigned IndentLevel;
32 public:
33 StmtPrinter(std::ostream &os) : OS(os), IndentLevel(0) {}
34
35 void PrintStmt(Stmt *S, int SubIndent = 1) {
36 IndentLevel += SubIndent;
37 if (S && isa<Expr>(S)) {
38 // If this is an expr used in a stmt context, indent and newline it.
39 Indent();
Chris Lattnerc5598cb2007-08-21 04:04:25 +000040 Visit(S);
Reid Spencer5f016e22007-07-11 17:01:13 +000041 OS << ";\n";
42 } else if (S) {
Chris Lattnerc5598cb2007-08-21 04:04:25 +000043 Visit(S);
Reid Spencer5f016e22007-07-11 17:01:13 +000044 } else {
45 Indent() << "<<<NULL STATEMENT>>>\n";
46 }
47 IndentLevel -= SubIndent;
48 }
49
50 void PrintRawCompoundStmt(CompoundStmt *S);
51 void PrintRawDecl(Decl *D);
52 void PrintRawIfStmt(IfStmt *If);
53
54 void PrintExpr(Expr *E) {
55 if (E)
Chris Lattnerc5598cb2007-08-21 04:04:25 +000056 Visit(E);
Reid Spencer5f016e22007-07-11 17:01:13 +000057 else
58 OS << "<null expr>";
59 }
60
61 std::ostream &Indent(int Delta = 0) const {
62 for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
63 OS << " ";
64 return OS;
65 }
66
Chris Lattner704fe352007-08-30 17:59:59 +000067 bool PrintOffsetOfDesignator(Expr *E);
68 void VisitUnaryOffsetOf(UnaryOperator *Node);
69
Chris Lattnerc5598cb2007-08-21 04:04:25 +000070 void VisitStmt(Stmt *Node);
Reid Spencer5f016e22007-07-11 17:01:13 +000071#define STMT(N, CLASS, PARENT) \
Chris Lattnerc5598cb2007-08-21 04:04:25 +000072 void Visit##CLASS(CLASS *Node);
Reid Spencer5f016e22007-07-11 17:01:13 +000073#include "clang/AST/StmtNodes.def"
74 };
75}
76
77//===----------------------------------------------------------------------===//
78// Stmt printing methods.
79//===----------------------------------------------------------------------===//
80
81void StmtPrinter::VisitStmt(Stmt *Node) {
82 Indent() << "<<unknown stmt type>>\n";
83}
84
85/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
86/// with no newline after the }.
87void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
88 OS << "{\n";
89 for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
90 I != E; ++I)
91 PrintStmt(*I);
92
93 Indent() << "}";
94}
95
96void StmtPrinter::PrintRawDecl(Decl *D) {
97 // FIXME: Need to complete/beautify this... this code simply shows the
98 // nodes are where they need to be.
99 if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) {
100 OS << "typedef " << localType->getUnderlyingType().getAsString();
101 OS << " " << localType->getName();
102 } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
103 // Emit storage class for vardecls.
104 if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
105 switch (V->getStorageClass()) {
106 default: assert(0 && "Unknown storage class!");
107 case VarDecl::None: break;
108 case VarDecl::Extern: OS << "extern "; break;
109 case VarDecl::Static: OS << "static "; break;
110 case VarDecl::Auto: OS << "auto "; break;
111 case VarDecl::Register: OS << "register "; break;
112 }
113 }
114
115 std::string Name = VD->getName();
116 VD->getType().getAsStringInternal(Name);
117 OS << Name;
118
Chris Lattner24c39902007-07-12 00:36:32 +0000119 // If this is a vardecl with an initializer, emit it.
120 if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
121 if (V->getInit()) {
122 OS << " = ";
123 PrintExpr(V->getInit());
124 }
125 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000126 } else {
127 // FIXME: "struct x;"
128 assert(0 && "Unexpected decl");
129 }
130}
131
132
133void StmtPrinter::VisitNullStmt(NullStmt *Node) {
134 Indent() << ";\n";
135}
136
137void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
138 for (Decl *D = Node->getDecl(); D; D = D->getNextDeclarator()) {
139 Indent();
140 PrintRawDecl(D);
141 OS << ";\n";
142 }
143}
144
145void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
146 Indent();
147 PrintRawCompoundStmt(Node);
148 OS << "\n";
149}
150
151void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
152 Indent(-1) << "case ";
153 PrintExpr(Node->getLHS());
154 if (Node->getRHS()) {
155 OS << " ... ";
156 PrintExpr(Node->getRHS());
157 }
158 OS << ":\n";
159
160 PrintStmt(Node->getSubStmt(), 0);
161}
162
163void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
164 Indent(-1) << "default:\n";
165 PrintStmt(Node->getSubStmt(), 0);
166}
167
168void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
169 Indent(-1) << Node->getName() << ":\n";
170 PrintStmt(Node->getSubStmt(), 0);
171}
172
173void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
174 OS << "if ";
175 PrintExpr(If->getCond());
176
177 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) {
178 OS << ' ';
179 PrintRawCompoundStmt(CS);
180 OS << (If->getElse() ? ' ' : '\n');
181 } else {
182 OS << '\n';
183 PrintStmt(If->getThen());
184 if (If->getElse()) Indent();
185 }
186
187 if (Stmt *Else = If->getElse()) {
188 OS << "else";
189
190 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) {
191 OS << ' ';
192 PrintRawCompoundStmt(CS);
193 OS << '\n';
194 } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) {
195 OS << ' ';
196 PrintRawIfStmt(ElseIf);
197 } else {
198 OS << '\n';
199 PrintStmt(If->getElse());
200 }
201 }
202}
203
204void StmtPrinter::VisitIfStmt(IfStmt *If) {
205 Indent();
206 PrintRawIfStmt(If);
207}
208
209void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
210 Indent() << "switch (";
211 PrintExpr(Node->getCond());
212 OS << ")";
213
214 // Pretty print compoundstmt bodies (very common).
215 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
216 OS << " ";
217 PrintRawCompoundStmt(CS);
218 OS << "\n";
219 } else {
220 OS << "\n";
221 PrintStmt(Node->getBody());
222 }
223}
224
Anders Carlssonc1fcb772007-07-22 07:07:56 +0000225void StmtPrinter::VisitSwitchCase(SwitchCase*) {
226 assert(0 && "SwitchCase is an abstract class");
227}
228
Reid Spencer5f016e22007-07-11 17:01:13 +0000229void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
230 Indent() << "while (";
231 PrintExpr(Node->getCond());
232 OS << ")\n";
233 PrintStmt(Node->getBody());
234}
235
236void StmtPrinter::VisitDoStmt(DoStmt *Node) {
237 Indent() << "do\n";
238 PrintStmt(Node->getBody());
239 Indent() << "while ";
240 PrintExpr(Node->getCond());
241 OS << ";\n";
242}
243
244void StmtPrinter::VisitForStmt(ForStmt *Node) {
245 Indent() << "for (";
246 if (Node->getInit()) {
247 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit()))
248 PrintRawDecl(DS->getDecl());
249 else
250 PrintExpr(cast<Expr>(Node->getInit()));
251 }
252 OS << "; ";
253 if (Node->getCond())
254 PrintExpr(Node->getCond());
255 OS << "; ";
256 if (Node->getInc())
257 PrintExpr(Node->getInc());
258 OS << ")\n";
259 PrintStmt(Node->getBody());
260}
261
262void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
263 Indent() << "goto " << Node->getLabel()->getName() << ";\n";
264}
265
266void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
267 Indent() << "goto *";
268 PrintExpr(Node->getTarget());
269 OS << ";\n";
270}
271
272void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
273 Indent() << "continue;\n";
274}
275
276void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
277 Indent() << "break;\n";
278}
279
280
281void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
282 Indent() << "return";
283 if (Node->getRetValue()) {
284 OS << " ";
285 PrintExpr(Node->getRetValue());
286 }
287 OS << ";\n";
288}
289
290//===----------------------------------------------------------------------===//
291// Expr printing methods.
292//===----------------------------------------------------------------------===//
293
294void StmtPrinter::VisitExpr(Expr *Node) {
295 OS << "<<unknown expr type>>";
296}
297
298void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
299 OS << Node->getDecl()->getName();
300}
301
Anders Carlsson22742662007-07-21 05:21:51 +0000302void StmtPrinter::VisitPreDefinedExpr(PreDefinedExpr *Node) {
303 switch (Node->getIdentType()) {
304 default:
305 assert(0 && "unknown case");
306 case PreDefinedExpr::Func:
307 OS << "__func__";
308 break;
309 case PreDefinedExpr::Function:
310 OS << "__FUNCTION__";
311 break;
312 case PreDefinedExpr::PrettyFunction:
313 OS << "__PRETTY_FUNCTION__";
314 break;
315 }
316}
317
Reid Spencer5f016e22007-07-11 17:01:13 +0000318void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
Chris Lattner8bf9f072007-07-13 23:58:20 +0000319 // FIXME should print an L for wchar_t constants
Chris Lattnerb0a721a2007-07-13 05:18:11 +0000320 unsigned value = Node->getValue();
Chris Lattner8bf9f072007-07-13 23:58:20 +0000321 switch (value) {
322 case '\\':
323 OS << "'\\\\'";
324 break;
325 case '\'':
326 OS << "'\\''";
327 break;
328 case '\a':
329 // TODO: K&R: the meaning of '\\a' is different in traditional C
330 OS << "'\\a'";
331 break;
332 case '\b':
333 OS << "'\\b'";
334 break;
335 // Nonstandard escape sequence.
336 /*case '\e':
337 OS << "'\\e'";
338 break;*/
339 case '\f':
340 OS << "'\\f'";
341 break;
342 case '\n':
343 OS << "'\\n'";
344 break;
345 case '\r':
346 OS << "'\\r'";
347 break;
348 case '\t':
349 OS << "'\\t'";
350 break;
351 case '\v':
352 OS << "'\\v'";
353 break;
354 default:
355 if (isprint(value) && value < 256) {
356 OS << "'" << (char)value << "'";
357 } else if (value < 256) {
358 OS << "'\\x" << std::hex << value << std::dec << "'";
359 } else {
360 // FIXME what to really do here?
361 OS << value;
362 }
Chris Lattnerb0a721a2007-07-13 05:18:11 +0000363 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000364}
365
366void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
367 bool isSigned = Node->getType()->isSignedIntegerType();
368 OS << Node->getValue().toString(10, isSigned);
369
370 // Emit suffixes. Integer literals are always a builtin integer type.
371 switch (cast<BuiltinType>(Node->getType().getCanonicalType())->getKind()) {
372 default: assert(0 && "Unexpected type for integer literal!");
373 case BuiltinType::Int: break; // no suffix.
374 case BuiltinType::UInt: OS << 'U'; break;
375 case BuiltinType::Long: OS << 'L'; break;
376 case BuiltinType::ULong: OS << "UL"; break;
377 case BuiltinType::LongLong: OS << "LL"; break;
378 case BuiltinType::ULongLong: OS << "ULL"; break;
379 }
380}
381void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
Chris Lattner86e499d2007-08-01 00:23:58 +0000382 // FIXME: print value more precisely.
383 OS << Node->getValue();
Reid Spencer5f016e22007-07-11 17:01:13 +0000384}
Chris Lattner5d661452007-08-26 03:42:43 +0000385
386void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
387 PrintExpr(Node->getSubExpr());
388 OS << "i";
389}
390
Reid Spencer5f016e22007-07-11 17:01:13 +0000391void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
392 if (Str->isWide()) OS << 'L';
393 OS << '"';
394
395 // FIXME: this doesn't print wstrings right.
396 for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
397 switch (Str->getStrData()[i]) {
398 default: OS << Str->getStrData()[i]; break;
399 // Handle some common ones to make dumps prettier.
400 case '\\': OS << "\\\\"; break;
401 case '"': OS << "\\\""; break;
402 case '\n': OS << "\\n"; break;
403 case '\t': OS << "\\t"; break;
404 case '\a': OS << "\\a"; break;
405 case '\b': OS << "\\b"; break;
406 }
407 }
408 OS << '"';
409}
410void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
411 OS << "(";
412 PrintExpr(Node->getSubExpr());
413 OS << ")";
414}
415void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
Chris Lattner296bf192007-08-23 21:46:40 +0000416 if (!Node->isPostfix()) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000417 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
Chris Lattner296bf192007-08-23 21:46:40 +0000418
419 // Print a space if this is an "identifier operator" like sizeof or __real.
420 switch (Node->getOpcode()) {
421 default: break;
422 case UnaryOperator::SizeOf:
423 case UnaryOperator::AlignOf:
424 case UnaryOperator::Real:
425 case UnaryOperator::Imag:
426 case UnaryOperator::Extension:
427 OS << ' ';
428 break;
429 }
430 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000431 PrintExpr(Node->getSubExpr());
432
433 if (Node->isPostfix())
434 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
Reid Spencer5f016e22007-07-11 17:01:13 +0000435}
Chris Lattner704fe352007-08-30 17:59:59 +0000436
437bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) {
438 if (isa<CompoundLiteralExpr>(E)) {
439 // Base case, print the type and comma.
440 OS << E->getType().getAsString() << ", ";
441 return true;
442 } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
443 PrintOffsetOfDesignator(ASE->getLHS());
444 OS << "[";
445 PrintExpr(ASE->getRHS());
446 OS << "]";
447 return false;
448 } else {
449 MemberExpr *ME = cast<MemberExpr>(E);
450 bool IsFirst = PrintOffsetOfDesignator(ME->getBase());
451 OS << (IsFirst ? "" : ".") << ME->getMemberDecl()->getName();
452 return false;
453 }
454}
455
456void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) {
457 OS << "__builtin_offsetof(";
458 PrintOffsetOfDesignator(Node->getSubExpr());
459 OS << ")";
460}
461
Reid Spencer5f016e22007-07-11 17:01:13 +0000462void StmtPrinter::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node) {
463 OS << (Node->isSizeOf() ? "sizeof(" : "__alignof(");
464 OS << Node->getArgumentType().getAsString() << ")";
465}
466void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
Ted Kremenek23245122007-08-20 16:18:38 +0000467 PrintExpr(Node->getLHS());
Reid Spencer5f016e22007-07-11 17:01:13 +0000468 OS << "[";
Ted Kremenek23245122007-08-20 16:18:38 +0000469 PrintExpr(Node->getRHS());
Reid Spencer5f016e22007-07-11 17:01:13 +0000470 OS << "]";
471}
472
473void StmtPrinter::VisitCallExpr(CallExpr *Call) {
474 PrintExpr(Call->getCallee());
475 OS << "(";
476 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
477 if (i) OS << ", ";
478 PrintExpr(Call->getArg(i));
479 }
480 OS << ")";
481}
482void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
483 PrintExpr(Node->getBase());
484 OS << (Node->isArrow() ? "->" : ".");
485
486 FieldDecl *Field = Node->getMemberDecl();
487 assert(Field && "MemberExpr should alway reference a field!");
488 OS << Field->getName();
489}
Chris Lattner6481a572007-08-03 17:31:20 +0000490void StmtPrinter::VisitOCUVectorElementExpr(OCUVectorElementExpr *Node) {
Steve Naroff31a45842007-07-28 23:10:27 +0000491 PrintExpr(Node->getBase());
492 OS << ".";
493 OS << Node->getAccessor().getName();
494}
Reid Spencer5f016e22007-07-11 17:01:13 +0000495void StmtPrinter::VisitCastExpr(CastExpr *Node) {
Chris Lattner26dc7b32007-07-15 23:54:50 +0000496 OS << "(" << Node->getType().getAsString() << ")";
Reid Spencer5f016e22007-07-11 17:01:13 +0000497 PrintExpr(Node->getSubExpr());
498}
Steve Naroffaff1edd2007-07-19 21:32:11 +0000499void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
500 OS << "(" << Node->getType().getAsString() << ")";
501 PrintExpr(Node->getInitializer());
502}
Steve Naroff49b45262007-07-13 16:58:59 +0000503void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
Steve Naroff90045e82007-07-13 23:32:42 +0000504 // No need to print anything, simply forward to the sub expression.
505 PrintExpr(Node->getSubExpr());
Steve Naroff49b45262007-07-13 16:58:59 +0000506}
Reid Spencer5f016e22007-07-11 17:01:13 +0000507void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
508 PrintExpr(Node->getLHS());
509 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
510 PrintExpr(Node->getRHS());
511}
Chris Lattnereb14fe82007-08-25 02:00:02 +0000512void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
513 PrintExpr(Node->getLHS());
514 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
515 PrintExpr(Node->getRHS());
516}
Reid Spencer5f016e22007-07-11 17:01:13 +0000517void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
518 PrintExpr(Node->getCond());
519 OS << " ? ";
520 PrintExpr(Node->getLHS());
521 OS << " : ";
522 PrintExpr(Node->getRHS());
523}
524
525// GNU extensions.
526
Chris Lattner6481a572007-08-03 17:31:20 +0000527void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000528 OS << "&&" << Node->getLabel()->getName();
Reid Spencer5f016e22007-07-11 17:01:13 +0000529}
530
Chris Lattnerab18c4c2007-07-24 16:58:17 +0000531void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
532 OS << "(";
533 PrintRawCompoundStmt(E->getSubStmt());
534 OS << ")";
535}
536
Steve Naroffd34e9152007-08-01 22:05:33 +0000537void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
538 OS << "__builtin_types_compatible_p(";
539 OS << Node->getArgType1().getAsString() << ",";
540 OS << Node->getArgType2().getAsString() << ")";
541}
542
Steve Naroffd04fdd52007-08-03 21:21:27 +0000543void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
544 OS << "__builtin_choose_expr(";
545 PrintExpr(Node->getCond());
Chris Lattner94f05e32007-08-04 00:20:15 +0000546 OS << ", ";
Steve Naroffd04fdd52007-08-03 21:21:27 +0000547 PrintExpr(Node->getLHS());
Chris Lattner94f05e32007-08-04 00:20:15 +0000548 OS << ", ";
Steve Naroffd04fdd52007-08-03 21:21:27 +0000549 PrintExpr(Node->getRHS());
550 OS << ")";
551}
Chris Lattnerab18c4c2007-07-24 16:58:17 +0000552
Reid Spencer5f016e22007-07-11 17:01:13 +0000553// C++
554
555void StmtPrinter::VisitCXXCastExpr(CXXCastExpr *Node) {
Chris Lattner36460ee2007-08-09 17:34:19 +0000556 OS << CXXCastExpr::getOpcodeStr(Node->getOpcode()) << '<';
Reid Spencer5f016e22007-07-11 17:01:13 +0000557 OS << Node->getDestType().getAsString() << ">(";
558 PrintExpr(Node->getSubExpr());
559 OS << ")";
560}
561
562void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
563 OS << (Node->getValue() ? "true" : "false");
564}
565
Anders Carlsson55085182007-08-21 17:43:55 +0000566// Obj-C
567
568void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
569 OS << "@";
570 VisitStringLiteral(Node->getString());
571}
Reid Spencer5f016e22007-07-11 17:01:13 +0000572
Anders Carlssonf9bcf012007-08-22 15:14:15 +0000573void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
574 OS << "@encode(";
575 OS << Node->getEncodedType().getAsString() << ")";
576}
577
Reid Spencer5f016e22007-07-11 17:01:13 +0000578//===----------------------------------------------------------------------===//
579// Stmt method implementations
580//===----------------------------------------------------------------------===//
581
Chris Lattner6000dac2007-08-08 22:51:59 +0000582void Stmt::dumpPretty() const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000583 // FIXME: eliminate use of <iostream>
Chris Lattner6000dac2007-08-08 22:51:59 +0000584 printPretty(std::cerr);
Reid Spencer5f016e22007-07-11 17:01:13 +0000585}
586
Chris Lattner6000dac2007-08-08 22:51:59 +0000587void Stmt::printPretty(std::ostream &OS) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000588 if (this == 0) {
589 OS << "<NULL>";
590 return;
591 }
592
593 StmtPrinter P(OS);
Chris Lattnerc5598cb2007-08-21 04:04:25 +0000594 P.Visit(const_cast<Stmt*>(this));
Reid Spencer5f016e22007-07-11 17:01:13 +0000595}