blob: c90c397769b5c23087e3c4950a3ae993d5f69f42 [file] [log] [blame]
Chris Lattnera3bcb7a2006-11-04 07:16:25 +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//
10// This file implements the Stmt::dump/Stmt::print methods.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/StmtVisitor.h"
15#include "clang/AST/Expr.h"
Chris Lattner6c0ff132006-11-05 00:19:50 +000016#include "clang/Lex/IdentifierTable.h"
Chris Lattnera3bcb7a2006-11-04 07:16:25 +000017#include "llvm/Support/Compiler.h"
18#include <iostream>
19using namespace llvm;
20using namespace clang;
21
Chris Lattner882f7882006-11-04 18:52:07 +000022namespace {
23 struct VISIBILITY_HIDDEN IsExprStmtVisitor : public StmtVisitor {
24 bool &Result;
25 IsExprStmtVisitor(bool &R) : Result(R) { Result = false; }
26
27 virtual void VisitExpr(Expr *Node) {
28 Result = true;
29 }
30 };
31}
32
33static bool isExpr(Stmt *S) {
34 bool Val = false;
35 IsExprStmtVisitor V(Val);
36 S->visit(V);
37 return Val;
38}
39
Chris Lattnera3bcb7a2006-11-04 07:16:25 +000040//===----------------------------------------------------------------------===//
41// StmtPrinter Visitor
42//===----------------------------------------------------------------------===//
43
44namespace {
45 class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor {
46 std::ostream &OS;
47 unsigned IndentLevel;
48 public:
49 StmtPrinter(std::ostream &os) : OS(os), IndentLevel(0) {}
50
Chris Lattner882f7882006-11-04 18:52:07 +000051 void PrintStmt(Stmt *S) {
52 ++IndentLevel;
53 if (S && isExpr(S)) {
54 // If this is an expr used in a stmt context, indent and newline it.
55 Indent();
Chris Lattnera3bcb7a2006-11-04 07:16:25 +000056 S->visit(*this);
Chris Lattner882f7882006-11-04 18:52:07 +000057 OS << "\n";
58 } else if (S) {
59 S->visit(*this);
60 } else {
Chris Lattner85ed8732006-11-04 20:40:44 +000061 Indent() << ";\n";
Chris Lattner882f7882006-11-04 18:52:07 +000062 }
63 --IndentLevel;
64 }
65
66 void PrintExpr(Expr *E) {
67 if (E)
68 E->visit(*this);
Chris Lattnera3bcb7a2006-11-04 07:16:25 +000069 else
Chris Lattner882f7882006-11-04 18:52:07 +000070 OS << "<null expr>";
Chris Lattnera3bcb7a2006-11-04 07:16:25 +000071 }
72
73 std::ostream &Indent() const {
74 for (unsigned i = 0, e = IndentLevel; i != e; ++i)
75 OS << " ";
76 return OS;
77 }
78
Chris Lattner882f7882006-11-04 18:52:07 +000079 virtual void VisitStmt(Stmt *Node);
Chris Lattnerf2174b62006-11-04 20:59:27 +000080#define STMT(CLASS, PARENT) \
81 virtual void Visit##CLASS(CLASS *Node);
82#include "clang/AST/StmtNodes.def"
Chris Lattner71e23ce2006-11-04 20:18:38 +000083 };
Chris Lattnera3bcb7a2006-11-04 07:16:25 +000084}
85
Chris Lattner71e23ce2006-11-04 20:18:38 +000086//===----------------------------------------------------------------------===//
87// Stmt printing methods.
88//===----------------------------------------------------------------------===//
89
Chris Lattner882f7882006-11-04 18:52:07 +000090void StmtPrinter::VisitStmt(Stmt *Node) {
91 Indent() << "<<unknown stmt type>>\n";
Chris Lattnera3bcb7a2006-11-04 07:16:25 +000092}
93
Chris Lattnera3bcb7a2006-11-04 07:16:25 +000094void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
95 Indent() << "{\n";
Chris Lattnera3bcb7a2006-11-04 07:16:25 +000096
97 for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
Chris Lattner882f7882006-11-04 18:52:07 +000098 I != E; ++I)
99 PrintStmt(*I);
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000100
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000101 Indent() << "}\n";
102}
103
Chris Lattner6c0ff132006-11-05 00:19:50 +0000104void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
105 Indent() << "case ";
106 PrintExpr(Node->getLHS());
107 if (Node->getRHS()) {
108 OS << " ... ";
109 PrintExpr(Node->getRHS());
110 }
111 OS << ":\n";
112
113 // FIXME: This recursively indents consequtive cases.
114 PrintStmt(Node->getSubStmt());
115}
116
117void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
118 Indent() << "default:\n";
119 // FIXME: This recursively indents consequtive cases.
120 PrintStmt(Node->getSubStmt());
121}
122
123void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
124 Indent() << Node->getLabel()->getName() << ":\n";
125 // FIXME: This recursively indents consequtive cases.
126 PrintStmt(Node->getSubStmt());
127}
128
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000129void StmtPrinter::VisitIfStmt(IfStmt *If) {
Chris Lattner85ed8732006-11-04 20:40:44 +0000130 Indent() << "if (";
Chris Lattner882f7882006-11-04 18:52:07 +0000131 PrintExpr(If->getCond());
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000132
Chris Lattner85ed8732006-11-04 20:40:44 +0000133 OS << ")\n";
Chris Lattner882f7882006-11-04 18:52:07 +0000134 PrintStmt(If->getThen());
135 if (If->getElse()) {
136 Indent() << "else\n";
137 PrintStmt(If->getElse());
138 }
Chris Lattner85ed8732006-11-04 20:40:44 +0000139}
140
Chris Lattnerf2174b62006-11-04 20:59:27 +0000141void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
142 Indent() << "switch (";
143 PrintExpr(Node->getCond());
144 OS << ")\n";
145 PrintStmt(Node->getBody());
146}
147
Chris Lattner85ed8732006-11-04 20:40:44 +0000148void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
149 Indent() << "while (";
150 PrintExpr(Node->getCond());
151 OS << ")\n";
152 PrintStmt(Node->getBody());
153}
154
155void StmtPrinter::VisitDoStmt(DoStmt *Node) {
156 Indent() << "do\n";
157 PrintStmt(Node->getBody());
158 Indent() << "while (";
159 PrintExpr(Node->getCond());
160 OS << ")\n";
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000161}
162
Chris Lattner71e23ce2006-11-04 20:18:38 +0000163void StmtPrinter::VisitForStmt(ForStmt *Node) {
164 Indent() << "for (";
165 if (Node->getFirst())
166 PrintExpr((Expr*)Node->getFirst());
167 OS << "; ";
168 if (Node->getSecond())
169 PrintExpr(Node->getSecond());
170 OS << "; ";
171 if (Node->getThird())
172 PrintExpr(Node->getThird());
173 OS << ")\n";
Chris Lattner85ed8732006-11-04 20:40:44 +0000174 PrintStmt(Node->getBody());
Chris Lattner71e23ce2006-11-04 20:18:38 +0000175}
176
Chris Lattner16976d32006-11-05 01:46:01 +0000177void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
178 Indent() << "goto " << Node->getLabel()->getName() << "\n";
179}
180
181void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
Chris Lattner36ad1232006-11-05 01:51:06 +0000182 Indent() << "goto *";
Chris Lattner16976d32006-11-05 01:46:01 +0000183 PrintExpr(Node->getTarget());
184 OS << "\n";
185}
186
187void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
188 Indent() << "continue\n";
189}
190
191void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
192 Indent() << "break\n";
193}
194
195
Chris Lattner882f7882006-11-04 18:52:07 +0000196void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
197 Indent() << "return";
198 if (Node->getRetValue()) {
199 OS << " ";
200 PrintExpr(Node->getRetValue());
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000201 }
Chris Lattner882f7882006-11-04 18:52:07 +0000202 OS << "\n";
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000203}
204
Chris Lattner71e23ce2006-11-04 20:18:38 +0000205//===----------------------------------------------------------------------===//
206// Expr printing methods.
207//===----------------------------------------------------------------------===//
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000208
Chris Lattner882f7882006-11-04 18:52:07 +0000209void StmtPrinter::VisitExpr(Expr *Node) {
210 OS << "<<unknown expr type>>";
211}
212
213void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
214 // FIXME: print name.
215 OS << "x";
216}
217
218void StmtPrinter::VisitIntegerConstant(IntegerConstant *Node) {
219 // FIXME: print value.
220 OS << "1";
221}
222void StmtPrinter::VisitFloatingConstant(FloatingConstant *Node) {
223 // FIXME: print value.
224 OS << "1.0";
225}
226void StmtPrinter::VisitStringExpr(StringExpr *Str) {
227 if (Str->isWide()) OS << 'L';
Chris Lattner5d8f4942006-11-04 20:29:31 +0000228 OS << '"';
229
230 // FIXME: this doesn't print wstrings right.
231 for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
232 switch (Str->getStrData()[i]) {
233 default: OS << Str->getStrData()[i]; break;
234 // Handle some common ones to make dumps prettier.
235 case '\\': OS << "\\\\"; break;
236 case '"': OS << "\\\""; break;
237 case '\n': OS << "\\n"; break;
238 case '\t': OS << "\\t"; break;
239 case '\a': OS << "\\a"; break;
240 case '\b': OS << "\\b"; break;
241 }
242 }
243 OS << '"';
Chris Lattner882f7882006-11-04 18:52:07 +0000244}
245void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
246 OS << "(";
247 PrintExpr(Node->getSubExpr());
248 OS << ")'";
249}
250void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
251 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
252 PrintExpr(Node->getSubExpr());
253}
254void StmtPrinter::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node) {
255 OS << (Node->isSizeOf() ? "sizeof(" : "alignof(");
256 // FIXME: print type.
257 OS << "ty)";
258}
259void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
260 PrintExpr(Node->getBase());
261 OS << "[";
262 PrintExpr(Node->getIdx());
263 OS << "]";
264}
265
266void StmtPrinter::VisitCallExpr(CallExpr *Call) {
267 PrintExpr(Call->getCallee());
268 OS << "(";
269 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
270 if (i) OS << ", ";
271 PrintExpr(Call->getArg(i));
272 }
273 OS << ")";
274}
275void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
276 PrintExpr(Node->getBase());
277 OS << (Node->isArrow() ? "->" : ".");
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000278
Chris Lattner882f7882006-11-04 18:52:07 +0000279 if (Node->getMemberDecl())
280 assert(0 && "TODO: should print member decl!");
281 OS << "member";
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000282}
Chris Lattner882f7882006-11-04 18:52:07 +0000283void StmtPrinter::VisitCastExpr(CastExpr *Node) {
284 OS << "(";
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000285 // TODO PRINT TYPE
Chris Lattner882f7882006-11-04 18:52:07 +0000286 OS << "<type>";
287 OS << ")";
288 PrintExpr(Node->getSubExpr());
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000289}
Chris Lattner882f7882006-11-04 18:52:07 +0000290void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
291 PrintExpr(Node->getLHS());
292 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
293 PrintExpr(Node->getRHS());
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000294}
Chris Lattner882f7882006-11-04 18:52:07 +0000295void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
296 PrintExpr(Node->getCond());
297 OS << " ? ";
298 PrintExpr(Node->getLHS());
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000299 std::cerr << " : ";
Chris Lattner882f7882006-11-04 18:52:07 +0000300 PrintExpr(Node->getRHS());
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000301}
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000302
303//===----------------------------------------------------------------------===//
304// Stmt method implementations
305//===----------------------------------------------------------------------===//
306
307void Stmt::dump() const {
308 print(std::cerr);
309}
310
311void Stmt::print(std::ostream &OS) const {
Chris Lattner882f7882006-11-04 18:52:07 +0000312 if (this == 0) {
313 OS << "<NULL>";
314 return;
315 }
316
Chris Lattnera3bcb7a2006-11-04 07:16:25 +0000317 StmtPrinter P(OS);
318 const_cast<Stmt*>(this)->visit(P);
319}