blob: 5b4c0ec7ce3ea9441f1ea3f33cd0c76e59c2b81d [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//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer5f016e22007-07-11 17:01:13 +00007//
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"
Ted Kremenek91d1d7a2007-10-17 18:36:42 +000016#include "clang/AST/DeclObjC.h"
Ted Kremenek42a509f2007-08-31 21:30:12 +000017#include "clang/AST/PrettyPrinter.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000018#include "llvm/Support/Compiler.h"
Ted Kremenek51221ec2007-11-26 22:50:46 +000019#include "llvm/Support/Streams.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000020using namespace clang;
21
22//===----------------------------------------------------------------------===//
23// StmtPrinter Visitor
24//===----------------------------------------------------------------------===//
25
26namespace {
Chris Lattnerc5598cb2007-08-21 04:04:25 +000027 class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor<StmtPrinter> {
Reid Spencer5f016e22007-07-11 17:01:13 +000028 std::ostream &OS;
29 unsigned IndentLevel;
Ted Kremenek42a509f2007-08-31 21:30:12 +000030 clang::PrinterHelper* Helper;
Reid Spencer5f016e22007-07-11 17:01:13 +000031 public:
Ted Kremenek42a509f2007-08-31 21:30:12 +000032 StmtPrinter(std::ostream &os, PrinterHelper* helper) :
33 OS(os), IndentLevel(0), Helper(helper) {}
Reid Spencer5f016e22007-07-11 17:01:13 +000034
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
Ted Kremenek42a509f2007-08-31 21:30:12 +000070 void Visit(Stmt* S) {
71 if (Helper && Helper->handledStmt(S,OS))
72 return;
73 else StmtVisitor<StmtPrinter>::Visit(S);
74 }
75
Chris Lattnerc5598cb2007-08-21 04:04:25 +000076 void VisitStmt(Stmt *Node);
Reid Spencer5f016e22007-07-11 17:01:13 +000077#define STMT(N, CLASS, PARENT) \
Chris Lattnerc5598cb2007-08-21 04:04:25 +000078 void Visit##CLASS(CLASS *Node);
Reid Spencer5f016e22007-07-11 17:01:13 +000079#include "clang/AST/StmtNodes.def"
80 };
81}
82
83//===----------------------------------------------------------------------===//
84// Stmt printing methods.
85//===----------------------------------------------------------------------===//
86
87void StmtPrinter::VisitStmt(Stmt *Node) {
88 Indent() << "<<unknown stmt type>>\n";
89}
90
91/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
92/// with no newline after the }.
93void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
94 OS << "{\n";
95 for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
96 I != E; ++I)
97 PrintStmt(*I);
98
99 Indent() << "}";
100}
101
102void StmtPrinter::PrintRawDecl(Decl *D) {
103 // FIXME: Need to complete/beautify this... this code simply shows the
104 // nodes are where they need to be.
105 if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) {
106 OS << "typedef " << localType->getUnderlyingType().getAsString();
107 OS << " " << localType->getName();
108 } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
109 // Emit storage class for vardecls.
110 if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
111 switch (V->getStorageClass()) {
112 default: assert(0 && "Unknown storage class!");
113 case VarDecl::None: break;
114 case VarDecl::Extern: OS << "extern "; break;
115 case VarDecl::Static: OS << "static "; break;
116 case VarDecl::Auto: OS << "auto "; break;
117 case VarDecl::Register: OS << "register "; break;
118 }
119 }
120
121 std::string Name = VD->getName();
122 VD->getType().getAsStringInternal(Name);
123 OS << Name;
124
Chris Lattner24c39902007-07-12 00:36:32 +0000125 // If this is a vardecl with an initializer, emit it.
126 if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
127 if (V->getInit()) {
128 OS << " = ";
129 PrintExpr(V->getInit());
130 }
131 }
Steve Naroff91578f32007-11-17 21:21:01 +0000132 } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
133 // print a free standing tag decl (e.g. "struct x;").
134 OS << TD->getKindName();
135 OS << " ";
136 if (const IdentifierInfo *II = TD->getIdentifier())
137 OS << II->getName();
138 else
139 OS << "<anonymous>";
140 // FIXME: print tag bodies.
Reid Spencer5f016e22007-07-11 17:01:13 +0000141 } else {
Reid Spencer5f016e22007-07-11 17:01:13 +0000142 assert(0 && "Unexpected decl");
143 }
144}
145
146
147void StmtPrinter::VisitNullStmt(NullStmt *Node) {
148 Indent() << ";\n";
149}
150
151void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
Steve Naroff94745042007-09-13 23:52:58 +0000152 for (ScopedDecl *D = Node->getDecl(); D; D = D->getNextDeclarator()) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000153 Indent();
154 PrintRawDecl(D);
155 OS << ";\n";
156 }
157}
158
159void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
160 Indent();
161 PrintRawCompoundStmt(Node);
162 OS << "\n";
163}
164
165void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
166 Indent(-1) << "case ";
167 PrintExpr(Node->getLHS());
168 if (Node->getRHS()) {
169 OS << " ... ";
170 PrintExpr(Node->getRHS());
171 }
172 OS << ":\n";
173
174 PrintStmt(Node->getSubStmt(), 0);
175}
176
177void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
178 Indent(-1) << "default:\n";
179 PrintStmt(Node->getSubStmt(), 0);
180}
181
182void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
183 Indent(-1) << Node->getName() << ":\n";
184 PrintStmt(Node->getSubStmt(), 0);
185}
186
187void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
188 OS << "if ";
189 PrintExpr(If->getCond());
190
191 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) {
192 OS << ' ';
193 PrintRawCompoundStmt(CS);
194 OS << (If->getElse() ? ' ' : '\n');
195 } else {
196 OS << '\n';
197 PrintStmt(If->getThen());
198 if (If->getElse()) Indent();
199 }
200
201 if (Stmt *Else = If->getElse()) {
202 OS << "else";
203
204 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) {
205 OS << ' ';
206 PrintRawCompoundStmt(CS);
207 OS << '\n';
208 } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) {
209 OS << ' ';
210 PrintRawIfStmt(ElseIf);
211 } else {
212 OS << '\n';
213 PrintStmt(If->getElse());
214 }
215 }
216}
217
218void StmtPrinter::VisitIfStmt(IfStmt *If) {
219 Indent();
220 PrintRawIfStmt(If);
221}
222
223void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
224 Indent() << "switch (";
225 PrintExpr(Node->getCond());
226 OS << ")";
227
228 // Pretty print compoundstmt bodies (very common).
229 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
230 OS << " ";
231 PrintRawCompoundStmt(CS);
232 OS << "\n";
233 } else {
234 OS << "\n";
235 PrintStmt(Node->getBody());
236 }
237}
238
Anders Carlssonc1fcb772007-07-22 07:07:56 +0000239void StmtPrinter::VisitSwitchCase(SwitchCase*) {
240 assert(0 && "SwitchCase is an abstract class");
241}
242
Reid Spencer5f016e22007-07-11 17:01:13 +0000243void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
244 Indent() << "while (";
245 PrintExpr(Node->getCond());
246 OS << ")\n";
247 PrintStmt(Node->getBody());
248}
249
250void StmtPrinter::VisitDoStmt(DoStmt *Node) {
Chris Lattner8bdcc472007-09-15 21:49:37 +0000251 Indent() << "do ";
252 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
253 PrintRawCompoundStmt(CS);
254 OS << " ";
255 } else {
256 OS << "\n";
257 PrintStmt(Node->getBody());
258 Indent();
259 }
260
261 OS << "while ";
Reid Spencer5f016e22007-07-11 17:01:13 +0000262 PrintExpr(Node->getCond());
263 OS << ";\n";
264}
265
266void StmtPrinter::VisitForStmt(ForStmt *Node) {
267 Indent() << "for (";
268 if (Node->getInit()) {
269 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit()))
270 PrintRawDecl(DS->getDecl());
271 else
272 PrintExpr(cast<Expr>(Node->getInit()));
273 }
Chris Lattner8bdcc472007-09-15 21:49:37 +0000274 OS << ";";
275 if (Node->getCond()) {
276 OS << " ";
Reid Spencer5f016e22007-07-11 17:01:13 +0000277 PrintExpr(Node->getCond());
Chris Lattner8bdcc472007-09-15 21:49:37 +0000278 }
279 OS << ";";
280 if (Node->getInc()) {
281 OS << " ";
Reid Spencer5f016e22007-07-11 17:01:13 +0000282 PrintExpr(Node->getInc());
Chris Lattner8bdcc472007-09-15 21:49:37 +0000283 }
284 OS << ") ";
285
286 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
287 PrintRawCompoundStmt(CS);
288 OS << "\n";
289 } else {
290 OS << "\n";
291 PrintStmt(Node->getBody());
292 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000293}
294
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000295void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
Fariborz Jahanian0196cab2008-01-02 22:54:34 +0000296 Indent() << "for (";
297 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement()))
298 PrintRawDecl(DS->getDecl());
299 else
300 PrintExpr(cast<Expr>(Node->getElement()));
301 OS << " in ";
302 PrintExpr(Node->getCollection());
303 OS << ") ";
304
305 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
306 PrintRawCompoundStmt(CS);
307 OS << "\n";
308 } else {
309 OS << "\n";
310 PrintStmt(Node->getBody());
311 }
312}
313
Reid Spencer5f016e22007-07-11 17:01:13 +0000314void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
315 Indent() << "goto " << Node->getLabel()->getName() << ";\n";
316}
317
318void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
319 Indent() << "goto *";
320 PrintExpr(Node->getTarget());
321 OS << ";\n";
322}
323
324void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
325 Indent() << "continue;\n";
326}
327
328void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
329 Indent() << "break;\n";
330}
331
332
333void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
334 Indent() << "return";
335 if (Node->getRetValue()) {
336 OS << " ";
337 PrintExpr(Node->getRetValue());
338 }
339 OS << ";\n";
340}
341
Chris Lattnerfe795952007-10-29 04:04:16 +0000342
343void StmtPrinter::VisitAsmStmt(AsmStmt *Node) {
Anders Carlsson39c47b52007-11-23 23:12:25 +0000344 Indent() << "asm ";
345
346 if (Node->isVolatile())
347 OS << "volatile ";
348
349 OS << "(";
Anders Carlsson6a0ef4b2007-11-20 19:21:03 +0000350 VisitStringLiteral(Node->getAsmString());
Anders Carlssonb235fc22007-11-22 01:36:19 +0000351
352 // Outputs
353 if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
354 Node->getNumClobbers() != 0)
355 OS << " : ";
356
357 for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
358 if (i != 0)
359 OS << ", ";
360
361 if (!Node->getOutputName(i).empty()) {
362 OS << '[';
363 OS << Node->getOutputName(i);
364 OS << "] ";
365 }
366
367 VisitStringLiteral(Node->getOutputConstraint(i));
368 OS << " ";
369 Visit(Node->getOutputExpr(i));
370 }
371
372 // Inputs
373 if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
374 OS << " : ";
375
376 for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
377 if (i != 0)
378 OS << ", ";
379
380 if (!Node->getInputName(i).empty()) {
381 OS << '[';
382 OS << Node->getInputName(i);
383 OS << "] ";
384 }
385
386 VisitStringLiteral(Node->getInputConstraint(i));
387 OS << " ";
388 Visit(Node->getInputExpr(i));
389 }
390
391 // Clobbers
392 if (Node->getNumClobbers() != 0)
393 OS << " : ";
394
395 for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
396 if (i != 0)
397 OS << ", ";
398
399 VisitStringLiteral(Node->getClobber(i));
400 }
401
Anders Carlsson6a0ef4b2007-11-20 19:21:03 +0000402 OS << ");\n";
Chris Lattnerfe795952007-10-29 04:04:16 +0000403}
404
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000405void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
Fariborz Jahanian7794cb82007-11-02 18:16:07 +0000406 Indent() << "@try";
407 if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
408 PrintRawCompoundStmt(TS);
409 OS << "\n";
410 }
411
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000412 for (ObjCAtCatchStmt *catchStmt =
413 static_cast<ObjCAtCatchStmt *>(Node->getCatchStmts());
Fariborz Jahanian7794cb82007-11-02 18:16:07 +0000414 catchStmt;
415 catchStmt =
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000416 static_cast<ObjCAtCatchStmt *>(catchStmt->getNextCatchStmt())) {
Fariborz Jahanian7794cb82007-11-02 18:16:07 +0000417 Indent() << "@catch(";
418 if (catchStmt->getCatchParamStmt()) {
419 if (DeclStmt *DS = dyn_cast<DeclStmt>(catchStmt->getCatchParamStmt()))
420 PrintRawDecl(DS->getDecl());
421 }
422 OS << ")";
423 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody()))
424 {
425 PrintRawCompoundStmt(CS);
426 OS << "\n";
427 }
428 }
429
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000430 if (ObjCAtFinallyStmt *FS =static_cast<ObjCAtFinallyStmt *>(
Fariborz Jahanian1e7eab42007-11-07 00:46:42 +0000431 Node->getFinallyStmt())) {
432 Indent() << "@finally";
433 PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
Fariborz Jahanian7794cb82007-11-02 18:16:07 +0000434 OS << "\n";
435 }
Fariborz Jahanianb210bd02007-11-01 21:12:44 +0000436}
437
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000438void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
Fariborz Jahanianb210bd02007-11-01 21:12:44 +0000439}
440
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000441void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
Fariborz Jahanianb210bd02007-11-01 21:12:44 +0000442 Indent() << "@catch (...) { /* todo */ } \n";
443}
444
Fariborz Jahanian78a677b2008-01-30 17:38:29 +0000445void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
Fariborz Jahanian39f8f152007-11-07 02:00:49 +0000446 Indent() << "@throw";
447 if (Node->getThrowExpr()) {
448 OS << " ";
449 PrintExpr(Node->getThrowExpr());
450 }
451 OS << ";\n";
452}
453
Fariborz Jahanian78a677b2008-01-30 17:38:29 +0000454void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
Fariborz Jahanianc385c902008-01-29 18:21:32 +0000455 Indent() << "@synchronized (";
456 PrintExpr(Node->getSynchExpr());
457 OS << ")";
Fariborz Jahanian78a677b2008-01-30 17:38:29 +0000458 PrintRawCompoundStmt(Node->getSynchBody());
459 OS << "\n";
Fariborz Jahanianc385c902008-01-29 18:21:32 +0000460}
461
Reid Spencer5f016e22007-07-11 17:01:13 +0000462//===----------------------------------------------------------------------===//
463// Expr printing methods.
464//===----------------------------------------------------------------------===//
465
466void StmtPrinter::VisitExpr(Expr *Node) {
467 OS << "<<unknown expr type>>";
468}
469
470void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
471 OS << Node->getDecl()->getName();
472}
473
Steve Naroff7779db42007-11-12 14:29:37 +0000474void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
Fariborz Jahanian232220c2007-11-12 22:29:28 +0000475 if (Node->getBase()) {
476 PrintExpr(Node->getBase());
477 OS << (Node->isArrow() ? "->" : ".");
478 }
Steve Naroff7779db42007-11-12 14:29:37 +0000479 OS << Node->getDecl()->getName();
480}
481
Steve Naroffae784072008-05-30 00:40:33 +0000482void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
483 if (Node->getBase()) {
484 PrintExpr(Node->getBase());
485 OS << ".";
486 }
487 // FIXME: OS << Node->getDecl()->getName();
488}
489
Chris Lattnerd9f69102008-08-10 01:53:14 +0000490void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
Anders Carlsson22742662007-07-21 05:21:51 +0000491 switch (Node->getIdentType()) {
492 default:
493 assert(0 && "unknown case");
Chris Lattnerd9f69102008-08-10 01:53:14 +0000494 case PredefinedExpr::Func:
Anders Carlsson22742662007-07-21 05:21:51 +0000495 OS << "__func__";
496 break;
Chris Lattnerd9f69102008-08-10 01:53:14 +0000497 case PredefinedExpr::Function:
Anders Carlsson22742662007-07-21 05:21:51 +0000498 OS << "__FUNCTION__";
499 break;
Chris Lattnerd9f69102008-08-10 01:53:14 +0000500 case PredefinedExpr::PrettyFunction:
Anders Carlsson22742662007-07-21 05:21:51 +0000501 OS << "__PRETTY_FUNCTION__";
502 break;
Chris Lattnerd9f69102008-08-10 01:53:14 +0000503 case PredefinedExpr::ObjCSuper:
Chris Lattner0d17f6f2008-06-21 18:04:54 +0000504 OS << "super";
505 break;
Anders Carlsson22742662007-07-21 05:21:51 +0000506 }
507}
508
Reid Spencer5f016e22007-07-11 17:01:13 +0000509void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
Chris Lattnerb0a721a2007-07-13 05:18:11 +0000510 unsigned value = Node->getValue();
Chris Lattnerc250aae2008-06-07 22:35:38 +0000511 if (Node->isWide())
512 OS << "L";
Chris Lattner8bf9f072007-07-13 23:58:20 +0000513 switch (value) {
514 case '\\':
515 OS << "'\\\\'";
516 break;
517 case '\'':
518 OS << "'\\''";
519 break;
520 case '\a':
521 // TODO: K&R: the meaning of '\\a' is different in traditional C
522 OS << "'\\a'";
523 break;
524 case '\b':
525 OS << "'\\b'";
526 break;
527 // Nonstandard escape sequence.
528 /*case '\e':
529 OS << "'\\e'";
530 break;*/
531 case '\f':
532 OS << "'\\f'";
533 break;
534 case '\n':
535 OS << "'\\n'";
536 break;
537 case '\r':
538 OS << "'\\r'";
539 break;
540 case '\t':
541 OS << "'\\t'";
542 break;
543 case '\v':
544 OS << "'\\v'";
545 break;
546 default:
Ted Kremenek471733d2008-02-23 00:52:04 +0000547 if (value < 256 && isprint(value)) {
Chris Lattner8bf9f072007-07-13 23:58:20 +0000548 OS << "'" << (char)value << "'";
549 } else if (value < 256) {
550 OS << "'\\x" << std::hex << value << std::dec << "'";
551 } else {
552 // FIXME what to really do here?
553 OS << value;
554 }
Chris Lattnerb0a721a2007-07-13 05:18:11 +0000555 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000556}
557
558void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
559 bool isSigned = Node->getType()->isSignedIntegerType();
560 OS << Node->getValue().toString(10, isSigned);
561
562 // Emit suffixes. Integer literals are always a builtin integer type.
Chris Lattnerb77792e2008-07-26 22:17:49 +0000563 switch (Node->getType()->getAsBuiltinType()->getKind()) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000564 default: assert(0 && "Unexpected type for integer literal!");
565 case BuiltinType::Int: break; // no suffix.
566 case BuiltinType::UInt: OS << 'U'; break;
567 case BuiltinType::Long: OS << 'L'; break;
568 case BuiltinType::ULong: OS << "UL"; break;
569 case BuiltinType::LongLong: OS << "LL"; break;
570 case BuiltinType::ULongLong: OS << "ULL"; break;
571 }
572}
573void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
Chris Lattner86e499d2007-08-01 00:23:58 +0000574 // FIXME: print value more precisely.
Chris Lattnerda8249e2008-06-07 22:13:43 +0000575 OS << Node->getValueAsApproximateDouble();
Reid Spencer5f016e22007-07-11 17:01:13 +0000576}
Chris Lattner5d661452007-08-26 03:42:43 +0000577
578void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
579 PrintExpr(Node->getSubExpr());
580 OS << "i";
581}
582
Reid Spencer5f016e22007-07-11 17:01:13 +0000583void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
584 if (Str->isWide()) OS << 'L';
585 OS << '"';
Anders Carlssonee98ac52007-10-15 02:50:23 +0000586
Reid Spencer5f016e22007-07-11 17:01:13 +0000587 // FIXME: this doesn't print wstrings right.
588 for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
589 switch (Str->getStrData()[i]) {
590 default: OS << Str->getStrData()[i]; break;
591 // Handle some common ones to make dumps prettier.
592 case '\\': OS << "\\\\"; break;
593 case '"': OS << "\\\""; break;
594 case '\n': OS << "\\n"; break;
595 case '\t': OS << "\\t"; break;
596 case '\a': OS << "\\a"; break;
597 case '\b': OS << "\\b"; break;
598 }
599 }
600 OS << '"';
601}
602void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
603 OS << "(";
604 PrintExpr(Node->getSubExpr());
605 OS << ")";
606}
607void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
Chris Lattner296bf192007-08-23 21:46:40 +0000608 if (!Node->isPostfix()) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000609 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
Chris Lattner296bf192007-08-23 21:46:40 +0000610
611 // Print a space if this is an "identifier operator" like sizeof or __real.
612 switch (Node->getOpcode()) {
613 default: break;
614 case UnaryOperator::SizeOf:
615 case UnaryOperator::AlignOf:
616 case UnaryOperator::Real:
617 case UnaryOperator::Imag:
618 case UnaryOperator::Extension:
619 OS << ' ';
620 break;
621 }
622 }
Reid Spencer5f016e22007-07-11 17:01:13 +0000623 PrintExpr(Node->getSubExpr());
624
625 if (Node->isPostfix())
626 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
Reid Spencer5f016e22007-07-11 17:01:13 +0000627}
Chris Lattner704fe352007-08-30 17:59:59 +0000628
629bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) {
630 if (isa<CompoundLiteralExpr>(E)) {
631 // Base case, print the type and comma.
632 OS << E->getType().getAsString() << ", ";
633 return true;
634 } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
635 PrintOffsetOfDesignator(ASE->getLHS());
636 OS << "[";
637 PrintExpr(ASE->getRHS());
638 OS << "]";
639 return false;
640 } else {
641 MemberExpr *ME = cast<MemberExpr>(E);
642 bool IsFirst = PrintOffsetOfDesignator(ME->getBase());
643 OS << (IsFirst ? "" : ".") << ME->getMemberDecl()->getName();
644 return false;
645 }
646}
647
648void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) {
649 OS << "__builtin_offsetof(";
650 PrintOffsetOfDesignator(Node->getSubExpr());
651 OS << ")";
652}
653
Reid Spencer5f016e22007-07-11 17:01:13 +0000654void StmtPrinter::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node) {
655 OS << (Node->isSizeOf() ? "sizeof(" : "__alignof(");
656 OS << Node->getArgumentType().getAsString() << ")";
657}
658void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
Ted Kremenek23245122007-08-20 16:18:38 +0000659 PrintExpr(Node->getLHS());
Reid Spencer5f016e22007-07-11 17:01:13 +0000660 OS << "[";
Ted Kremenek23245122007-08-20 16:18:38 +0000661 PrintExpr(Node->getRHS());
Reid Spencer5f016e22007-07-11 17:01:13 +0000662 OS << "]";
663}
664
665void StmtPrinter::VisitCallExpr(CallExpr *Call) {
666 PrintExpr(Call->getCallee());
667 OS << "(";
668 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
Chris Lattner04421082008-04-08 04:40:51 +0000669 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
670 // Don't print any defaulted arguments
671 break;
672 }
673
Reid Spencer5f016e22007-07-11 17:01:13 +0000674 if (i) OS << ", ";
675 PrintExpr(Call->getArg(i));
676 }
677 OS << ")";
678}
679void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
680 PrintExpr(Node->getBase());
681 OS << (Node->isArrow() ? "->" : ".");
682
683 FieldDecl *Field = Node->getMemberDecl();
684 assert(Field && "MemberExpr should alway reference a field!");
685 OS << Field->getName();
686}
Nate Begeman213541a2008-04-18 23:10:10 +0000687void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
Steve Naroff31a45842007-07-28 23:10:27 +0000688 PrintExpr(Node->getBase());
689 OS << ".";
690 OS << Node->getAccessor().getName();
691}
Argyrios Kyrtzidis0835a3c2008-08-18 23:01:59 +0000692void StmtPrinter::VisitCastExpr(CastExpr *) {
693 assert(0 && "CastExpr is an abstract class");
694}
695void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *Node) {
Chris Lattner26dc7b32007-07-15 23:54:50 +0000696 OS << "(" << Node->getType().getAsString() << ")";
Reid Spencer5f016e22007-07-11 17:01:13 +0000697 PrintExpr(Node->getSubExpr());
698}
Steve Naroffaff1edd2007-07-19 21:32:11 +0000699void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
700 OS << "(" << Node->getType().getAsString() << ")";
701 PrintExpr(Node->getInitializer());
702}
Steve Naroff49b45262007-07-13 16:58:59 +0000703void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
Steve Naroff90045e82007-07-13 23:32:42 +0000704 // No need to print anything, simply forward to the sub expression.
705 PrintExpr(Node->getSubExpr());
Steve Naroff49b45262007-07-13 16:58:59 +0000706}
Reid Spencer5f016e22007-07-11 17:01:13 +0000707void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
708 PrintExpr(Node->getLHS());
709 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
710 PrintExpr(Node->getRHS());
711}
Chris Lattnereb14fe82007-08-25 02:00:02 +0000712void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
713 PrintExpr(Node->getLHS());
714 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
715 PrintExpr(Node->getRHS());
716}
Reid Spencer5f016e22007-07-11 17:01:13 +0000717void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
718 PrintExpr(Node->getCond());
Ted Kremenek8e911c42007-11-26 18:27:54 +0000719
720 if (Node->getLHS()) {
721 OS << " ? ";
722 PrintExpr(Node->getLHS());
723 OS << " : ";
724 }
725 else { // Handle GCC extention where LHS can be NULL.
726 OS << " ?: ";
727 }
728
Reid Spencer5f016e22007-07-11 17:01:13 +0000729 PrintExpr(Node->getRHS());
730}
731
732// GNU extensions.
733
Chris Lattner6481a572007-08-03 17:31:20 +0000734void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
Reid Spencer5f016e22007-07-11 17:01:13 +0000735 OS << "&&" << Node->getLabel()->getName();
Reid Spencer5f016e22007-07-11 17:01:13 +0000736}
737
Chris Lattnerab18c4c2007-07-24 16:58:17 +0000738void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
739 OS << "(";
740 PrintRawCompoundStmt(E->getSubStmt());
741 OS << ")";
742}
743
Steve Naroffd34e9152007-08-01 22:05:33 +0000744void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
745 OS << "__builtin_types_compatible_p(";
746 OS << Node->getArgType1().getAsString() << ",";
747 OS << Node->getArgType2().getAsString() << ")";
748}
749
Steve Naroffd04fdd52007-08-03 21:21:27 +0000750void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
751 OS << "__builtin_choose_expr(";
752 PrintExpr(Node->getCond());
Chris Lattner94f05e32007-08-04 00:20:15 +0000753 OS << ", ";
Steve Naroffd04fdd52007-08-03 21:21:27 +0000754 PrintExpr(Node->getLHS());
Chris Lattner94f05e32007-08-04 00:20:15 +0000755 OS << ", ";
Steve Naroffd04fdd52007-08-03 21:21:27 +0000756 PrintExpr(Node->getRHS());
757 OS << ")";
758}
Chris Lattnerab18c4c2007-07-24 16:58:17 +0000759
Nate Begemane2ce1d92008-01-17 17:46:27 +0000760void StmtPrinter::VisitOverloadExpr(OverloadExpr *Node) {
761 OS << "__builtin_overload(";
Nate Begeman67295d02008-01-30 20:50:20 +0000762 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
Nate Begemane2ce1d92008-01-17 17:46:27 +0000763 if (i) OS << ", ";
Nate Begeman67295d02008-01-30 20:50:20 +0000764 PrintExpr(Node->getExpr(i));
Nate Begemane2ce1d92008-01-17 17:46:27 +0000765 }
766 OS << ")";
767}
768
Eli Friedmand38617c2008-05-14 19:38:39 +0000769void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
770 OS << "__builtin_shufflevector(";
771 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
772 if (i) OS << ", ";
773 PrintExpr(Node->getExpr(i));
774 }
775 OS << ")";
776}
777
Anders Carlsson66b5a8a2007-08-31 04:56:16 +0000778void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
779 OS << "{ ";
780 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
781 if (i) OS << ", ";
782 PrintExpr(Node->getInit(i));
783 }
784 OS << " }";
785}
786
Anders Carlsson7c50aca2007-10-15 20:28:48 +0000787void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
788 OS << "va_arg(";
789 PrintExpr(Node->getSubExpr());
790 OS << ", ";
791 OS << Node->getType().getAsString();
792 OS << ")";
793}
794
Reid Spencer5f016e22007-07-11 17:01:13 +0000795// C++
796
797void StmtPrinter::VisitCXXCastExpr(CXXCastExpr *Node) {
Chris Lattner36460ee2007-08-09 17:34:19 +0000798 OS << CXXCastExpr::getOpcodeStr(Node->getOpcode()) << '<';
Reid Spencer5f016e22007-07-11 17:01:13 +0000799 OS << Node->getDestType().getAsString() << ">(";
800 PrintExpr(Node->getSubExpr());
801 OS << ")";
802}
803
804void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
805 OS << (Node->getValue() ? "true" : "false");
806}
807
Chris Lattner50dd2892008-02-26 00:51:44 +0000808void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
809 if (Node->getSubExpr() == 0)
810 OS << "throw";
811 else {
812 OS << "throw ";
813 PrintExpr(Node->getSubExpr());
814 }
815}
816
Chris Lattner04421082008-04-08 04:40:51 +0000817void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
818 // Nothing to print: we picked up the default argument
819}
820
Anders Carlsson55085182007-08-21 17:43:55 +0000821// Obj-C
822
823void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
824 OS << "@";
825 VisitStringLiteral(Node->getString());
826}
Reid Spencer5f016e22007-07-11 17:01:13 +0000827
Anders Carlssonf9bcf012007-08-22 15:14:15 +0000828void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
Chris Lattner994f9392007-10-18 00:39:29 +0000829 OS << "@encode(" << Node->getEncodedType().getAsString() << ")";
Anders Carlssonf9bcf012007-08-22 15:14:15 +0000830}
831
Fariborz Jahanianb62f6812007-10-16 20:40:23 +0000832void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
Chris Lattner994f9392007-10-18 00:39:29 +0000833 OS << "@selector(" << Node->getSelector().getName() << ")";
Fariborz Jahanianb62f6812007-10-16 20:40:23 +0000834}
835
Fariborz Jahanian390d50a2007-10-17 16:58:11 +0000836void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
Chris Lattner994f9392007-10-18 00:39:29 +0000837 OS << "@protocol(" << Node->getProtocol()->getName() << ")";
Fariborz Jahanian390d50a2007-10-17 16:58:11 +0000838}
839
Steve Naroff563477d2007-09-18 23:55:05 +0000840void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
841 OS << "[";
Steve Naroff6a8a9a42007-10-02 20:01:56 +0000842 Expr *receiver = Mess->getReceiver();
843 if (receiver) PrintExpr(receiver);
844 else OS << Mess->getClassName()->getName();
Ted Kremenekc29efd82008-05-02 17:32:38 +0000845 OS << ' ';
Ted Kremenek97b7f262008-04-16 04:30:16 +0000846 Selector selector = Mess->getSelector();
Steve Naroff6a8a9a42007-10-02 20:01:56 +0000847 if (selector.isUnarySelector()) {
Ted Kremenekc29efd82008-05-02 17:32:38 +0000848 OS << selector.getIdentifierInfoForSlot(0)->getName();
Steve Naroff6a8a9a42007-10-02 20:01:56 +0000849 } else {
850 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
Ted Kremenekc29efd82008-05-02 17:32:38 +0000851 if (i < selector.getNumArgs()) {
852 if (i > 0) OS << ' ';
853 if (selector.getIdentifierInfoForSlot(i))
854 OS << selector.getIdentifierInfoForSlot(i)->getName() << ":";
855 else
856 OS << ":";
857 }
858 else OS << ", "; // Handle variadic methods.
859
Steve Naroff6a8a9a42007-10-02 20:01:56 +0000860 PrintExpr(Mess->getArg(i));
861 }
Steve Naroff563477d2007-09-18 23:55:05 +0000862 }
863 OS << "]";
864}
865
Reid Spencer5f016e22007-07-11 17:01:13 +0000866//===----------------------------------------------------------------------===//
867// Stmt method implementations
868//===----------------------------------------------------------------------===//
869
Chris Lattner6000dac2007-08-08 22:51:59 +0000870void Stmt::dumpPretty() const {
Ted Kremenek51221ec2007-11-26 22:50:46 +0000871 printPretty(*llvm::cerr.stream());
Reid Spencer5f016e22007-07-11 17:01:13 +0000872}
873
Ted Kremenek42a509f2007-08-31 21:30:12 +0000874void Stmt::printPretty(std::ostream &OS, PrinterHelper* Helper) const {
Reid Spencer5f016e22007-07-11 17:01:13 +0000875 if (this == 0) {
876 OS << "<NULL>";
877 return;
878 }
879
Ted Kremenek42a509f2007-08-31 21:30:12 +0000880 StmtPrinter P(OS, Helper);
Chris Lattnerc5598cb2007-08-21 04:04:25 +0000881 P.Visit(const_cast<Stmt*>(this));
Reid Spencer5f016e22007-07-11 17:01:13 +0000882}
Ted Kremenek42a509f2007-08-31 21:30:12 +0000883
884//===----------------------------------------------------------------------===//
885// PrinterHelper
886//===----------------------------------------------------------------------===//
887
888// Implement virtual destructor.
Gabor Greif84675832007-09-11 15:32:40 +0000889PrinterHelper::~PrinterHelper() {}