blob: 8e6a7128de12b02f76658c3724f1038c3f9441ab [file] [log] [blame]
Chris Lattner6000dac2007-08-08 22:51:59 +00001//===--- StmtDumper.cpp - Dumping 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, which dump out the
11// AST in a form that exposes type details and other fields.
12//
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 <cstdio>
21using namespace clang;
22
23//===----------------------------------------------------------------------===//
24// StmtDumper Visitor
25//===----------------------------------------------------------------------===//
26
27namespace {
Chris Lattnerc5598cb2007-08-21 04:04:25 +000028 class VISIBILITY_HIDDEN StmtDumper : public StmtVisitor<StmtDumper> {
Chris Lattner0c727a32007-08-30 00:40:08 +000029 const SourceManager *SM;
Chris Lattner6000dac2007-08-08 22:51:59 +000030 FILE *F;
31 unsigned IndentLevel;
32
33 /// MaxDepth - When doing a normal dump (not dumpAll) we only want to dump
34 /// the first few levels of an AST. This keeps track of how many ast levels
35 /// are left.
36 unsigned MaxDepth;
37 public:
Chris Lattner0c727a32007-08-30 00:40:08 +000038 StmtDumper(const SourceManager *sm, FILE *f, unsigned maxDepth)
Chris Lattnerb3938792007-08-30 00:53:54 +000039 : SM(sm), F(f), IndentLevel(0-1), MaxDepth(maxDepth) {}
Chris Lattner6000dac2007-08-08 22:51:59 +000040
Chris Lattnerf9e05812007-08-09 18:03:18 +000041 void DumpSubTree(Stmt *S) {
Chris Lattner6000dac2007-08-08 22:51:59 +000042 // Prune the recursion if not using dump all.
43 if (MaxDepth == 0) return;
44
Chris Lattnerf9e05812007-08-09 18:03:18 +000045 ++IndentLevel;
Chris Lattner6000dac2007-08-08 22:51:59 +000046 if (S) {
Chris Lattnerc5598cb2007-08-21 04:04:25 +000047 Visit(S);
Chris Lattnerb3938792007-08-30 00:53:54 +000048
49 // Print out children.
50 Stmt::child_iterator CI = S->child_begin(), CE = S->child_end();
51 if (CI != CE) {
52 while (CI != CE) {
53 fprintf(F, "\n");
54 DumpSubTree(*CI++);
55 }
56 }
57 fprintf(F, ")");
Chris Lattner6000dac2007-08-08 22:51:59 +000058 } else {
59 Indent();
Chris Lattner4a70adb2007-08-26 03:53:29 +000060 fprintf(F, "<<<NULL>>>");
Chris Lattner6000dac2007-08-08 22:51:59 +000061 }
Chris Lattnerf9e05812007-08-09 18:03:18 +000062 --IndentLevel;
Chris Lattner6000dac2007-08-08 22:51:59 +000063 }
64
Chris Lattnerf9e05812007-08-09 18:03:18 +000065 void DumpDeclarator(Decl *D);
Chris Lattner6000dac2007-08-08 22:51:59 +000066
67 void Indent() const {
68 for (int i = 0, e = IndentLevel; i < e; ++i)
69 fprintf(F, " ");
70 }
71
Chris Lattnerfd8f7da2007-08-09 00:36:22 +000072 void DumpType(QualType T) const {
73 fprintf(F, "'%s'", T.getAsString().c_str());
74
75 // If the type is directly a typedef, strip off typedefness to give at
76 // least one level of concreteness.
77 if (TypedefType *TDT = dyn_cast<TypedefType>(T))
78 fprintf(F, ":'%s'", TDT->LookThroughTypedefs().getAsString().c_str());
79 }
80
Chris Lattner6000dac2007-08-08 22:51:59 +000081 void DumpStmt(const Stmt *Node) const {
82 Indent();
83 fprintf(F, "(%s %p", Node->getStmtClassName(), (void*)Node);
84 }
85
86 void DumpExpr(Expr *Node) const {
87 DumpStmt(Node);
Chris Lattnerfd8f7da2007-08-09 00:36:22 +000088 fprintf(F, " ");
89 DumpType(Node->getType());
Chris Lattner6000dac2007-08-08 22:51:59 +000090 }
91
Chris Lattner17a1a722007-08-30 01:00:35 +000092 // Stmts.
Chris Lattnerc5598cb2007-08-21 04:04:25 +000093 void VisitStmt(Stmt *Node);
Chris Lattner17a1a722007-08-30 01:00:35 +000094 void VisitDeclStmt(DeclStmt *Node);
95 void VisitLabelStmt(LabelStmt *Node);
96 void VisitGotoStmt(GotoStmt *Node);
97
98 // Exprs
99 void VisitExpr(Expr *Node);
100 void VisitDeclRefExpr(DeclRefExpr *Node);
101 void VisitPreDefinedExpr(PreDefinedExpr *Node);
102 void VisitCharacterLiteral(CharacterLiteral *Node);
103 void VisitIntegerLiteral(IntegerLiteral *Node);
104 void VisitFloatingLiteral(FloatingLiteral *Node);
105 void VisitStringLiteral(StringLiteral *Str);
106 void VisitUnaryOperator(UnaryOperator *Node);
107 void VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node);
108 void VisitMemberExpr(MemberExpr *Node);
109 void VisitOCUVectorElementExpr(OCUVectorElementExpr *Node);
110 void VisitBinaryOperator(BinaryOperator *Node);
111 void VisitCompoundAssignOperator(CompoundAssignOperator *Node);
112 void VisitAddrLabelExpr(AddrLabelExpr *Node);
113 void VisitTypesCompatibleExpr(TypesCompatibleExpr *Node);
114
115 // C++
116 void VisitCXXCastExpr(CXXCastExpr *Node);
117 void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node);
118
119 // ObjC
120 void VisitObjCEncodeExpr(ObjCEncodeExpr *Node);
Chris Lattner6000dac2007-08-08 22:51:59 +0000121 };
122}
123
124//===----------------------------------------------------------------------===//
125// Stmt printing methods.
126//===----------------------------------------------------------------------===//
127
128void StmtDumper::VisitStmt(Stmt *Node) {
Chris Lattner17a1a722007-08-30 01:00:35 +0000129 DumpStmt(Node);
Chris Lattner6000dac2007-08-08 22:51:59 +0000130}
131
Chris Lattnerf9e05812007-08-09 18:03:18 +0000132void StmtDumper::DumpDeclarator(Decl *D) {
Chris Lattner6000dac2007-08-08 22:51:59 +0000133 // FIXME: Need to complete/beautify this... this code simply shows the
134 // nodes are where they need to be.
135 if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) {
Chris Lattnerf9e05812007-08-09 18:03:18 +0000136 fprintf(F, "\"typedef %s %s\"",
137 localType->getUnderlyingType().getAsString().c_str(),
138 localType->getName());
Chris Lattner6000dac2007-08-08 22:51:59 +0000139 } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
Chris Lattnerf9e05812007-08-09 18:03:18 +0000140 fprintf(F, "\"");
Chris Lattner6000dac2007-08-08 22:51:59 +0000141 // Emit storage class for vardecls.
142 if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
143 switch (V->getStorageClass()) {
Chris Lattnerf9e05812007-08-09 18:03:18 +0000144 default: assert(0 && "Unknown storage class!");
145 case VarDecl::None: break;
146 case VarDecl::Extern: fprintf(F, "extern "); break;
147 case VarDecl::Static: fprintf(F, "static "); break;
148 case VarDecl::Auto: fprintf(F, "auto "); break;
149 case VarDecl::Register: fprintf(F, "register "); break;
Chris Lattner6000dac2007-08-08 22:51:59 +0000150 }
151 }
152
153 std::string Name = VD->getName();
154 VD->getType().getAsStringInternal(Name);
Chris Lattnerf9e05812007-08-09 18:03:18 +0000155 fprintf(F, "%s", Name.c_str());
Chris Lattner6000dac2007-08-08 22:51:59 +0000156
157 // If this is a vardecl with an initializer, emit it.
158 if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
159 if (V->getInit()) {
Chris Lattnerf9e05812007-08-09 18:03:18 +0000160 fprintf(F, " =\n");
161 DumpSubTree(V->getInit());
Chris Lattner6000dac2007-08-08 22:51:59 +0000162 }
163 }
Chris Lattnerf9e05812007-08-09 18:03:18 +0000164 fprintf(F, "\"");
Chris Lattner6000dac2007-08-08 22:51:59 +0000165 } else {
166 // FIXME: "struct x;"
167 assert(0 && "Unexpected decl");
168 }
Chris Lattner6000dac2007-08-08 22:51:59 +0000169}
170
Chris Lattner6000dac2007-08-08 22:51:59 +0000171void StmtDumper::VisitDeclStmt(DeclStmt *Node) {
172 DumpStmt(Node);
Chris Lattnerf9e05812007-08-09 18:03:18 +0000173 fprintf(F, "\n");
Chris Lattner6000dac2007-08-08 22:51:59 +0000174 for (Decl *D = Node->getDecl(); D; D = D->getNextDeclarator()) {
Chris Lattnerf9e05812007-08-09 18:03:18 +0000175 ++IndentLevel;
Chris Lattner6000dac2007-08-08 22:51:59 +0000176 Indent();
Chris Lattnerf9e05812007-08-09 18:03:18 +0000177 fprintf(F, "%p ", (void*)D);
178 DumpDeclarator(D);
179 if (D->getNextDeclarator())
180 fprintf(F, "\n");
181 --IndentLevel;
Chris Lattner6000dac2007-08-08 22:51:59 +0000182 }
Chris Lattner6000dac2007-08-08 22:51:59 +0000183}
184
Chris Lattner6000dac2007-08-08 22:51:59 +0000185void StmtDumper::VisitLabelStmt(LabelStmt *Node) {
186 DumpStmt(Node);
187 fprintf(F, " '%s'\n", Node->getName());
Chris Lattner6000dac2007-08-08 22:51:59 +0000188}
189
Chris Lattner6000dac2007-08-08 22:51:59 +0000190void StmtDumper::VisitGotoStmt(GotoStmt *Node) {
191 DumpStmt(Node);
Chris Lattnerb3938792007-08-30 00:53:54 +0000192 fprintf(F, " '%s':%p", Node->getLabel()->getName(), (void*)Node->getLabel());
Chris Lattner6000dac2007-08-08 22:51:59 +0000193}
194
Chris Lattner6000dac2007-08-08 22:51:59 +0000195//===----------------------------------------------------------------------===//
196// Expr printing methods.
197//===----------------------------------------------------------------------===//
198
199void StmtDumper::VisitExpr(Expr *Node) {
200 DumpExpr(Node);
Chris Lattner6000dac2007-08-08 22:51:59 +0000201}
202
203void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) {
204 DumpExpr(Node);
Chris Lattnerb3938792007-08-30 00:53:54 +0000205 fprintf(F, " Decl='%s' %p", Node->getDecl()->getName(),
Chris Lattner6000dac2007-08-08 22:51:59 +0000206 (void*)Node->getDecl());
207}
208
209void StmtDumper::VisitPreDefinedExpr(PreDefinedExpr *Node) {
210 DumpExpr(Node);
211 switch (Node->getIdentType()) {
212 default:
213 assert(0 && "unknown case");
214 case PreDefinedExpr::Func:
Chris Lattnerb3938792007-08-30 00:53:54 +0000215 fprintf(F, " __func__");
Chris Lattner6000dac2007-08-08 22:51:59 +0000216 break;
217 case PreDefinedExpr::Function:
Chris Lattnerb3938792007-08-30 00:53:54 +0000218 fprintf(F, " __FUNCTION__");
Chris Lattner6000dac2007-08-08 22:51:59 +0000219 break;
220 case PreDefinedExpr::PrettyFunction:
Chris Lattnerb3938792007-08-30 00:53:54 +0000221 fprintf(F, " __PRETTY_FUNCTION__");
Chris Lattner6000dac2007-08-08 22:51:59 +0000222 break;
223 }
224}
225
226void StmtDumper::VisitCharacterLiteral(CharacterLiteral *Node) {
Chris Lattnera0df31a2007-08-09 01:04:32 +0000227 DumpExpr(Node);
Chris Lattnerb3938792007-08-30 00:53:54 +0000228 fprintf(F, " %d", Node->getValue());
Chris Lattner6000dac2007-08-08 22:51:59 +0000229}
230
231void StmtDumper::VisitIntegerLiteral(IntegerLiteral *Node) {
232 DumpExpr(Node);
233
234 bool isSigned = Node->getType()->isSignedIntegerType();
Chris Lattnerb3938792007-08-30 00:53:54 +0000235 fprintf(F, " %s", Node->getValue().toString(10, isSigned).c_str());
Chris Lattner6000dac2007-08-08 22:51:59 +0000236}
237void StmtDumper::VisitFloatingLiteral(FloatingLiteral *Node) {
238 DumpExpr(Node);
Chris Lattnerb3938792007-08-30 00:53:54 +0000239 fprintf(F, " %f", Node->getValue());
Chris Lattner6000dac2007-08-08 22:51:59 +0000240}
Chris Lattner5d661452007-08-26 03:42:43 +0000241
Chris Lattner6000dac2007-08-08 22:51:59 +0000242void StmtDumper::VisitStringLiteral(StringLiteral *Str) {
Chris Lattnera0df31a2007-08-09 01:04:32 +0000243 DumpExpr(Str);
244 // FIXME: this doesn't print wstrings right.
Chris Lattner5fc61072007-08-09 17:14:24 +0000245 fprintf(F, " %s\"", Str->isWide() ? "L" : "");
Chris Lattnera0df31a2007-08-09 01:04:32 +0000246
Chris Lattner6000dac2007-08-08 22:51:59 +0000247 for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
Chris Lattner5fc61072007-08-09 17:14:24 +0000248 switch (char C = Str->getStrData()[i]) {
249 default:
250 if (isprint(C))
251 fputc(C, F);
252 else
253 fprintf(F, "\\%03o", C);
254 break;
Chris Lattner6000dac2007-08-08 22:51:59 +0000255 // Handle some common ones to make dumps prettier.
Chris Lattner5fc61072007-08-09 17:14:24 +0000256 case '\\': fprintf(F, "\\\\"); break;
257 case '"': fprintf(F, "\\\""); break;
258 case '\n': fprintf(F, "\\n"); break;
259 case '\t': fprintf(F, "\\t"); break;
260 case '\a': fprintf(F, "\\a"); break;
261 case '\b': fprintf(F, "\\b"); break;
Chris Lattner6000dac2007-08-08 22:51:59 +0000262 }
263 }
Chris Lattnerb3938792007-08-30 00:53:54 +0000264 fprintf(F, "\"");
Chris Lattner6000dac2007-08-08 22:51:59 +0000265}
Chris Lattner17a1a722007-08-30 01:00:35 +0000266
Chris Lattner6000dac2007-08-08 22:51:59 +0000267void StmtDumper::VisitUnaryOperator(UnaryOperator *Node) {
Chris Lattner13cb21f2007-08-09 17:35:30 +0000268 DumpExpr(Node);
Chris Lattnerb3938792007-08-30 00:53:54 +0000269 fprintf(F, " %s '%s'", Node->isPostfix() ? "postfix" : "prefix",
Chris Lattner13cb21f2007-08-09 17:35:30 +0000270 UnaryOperator::getOpcodeStr(Node->getOpcode()));
Chris Lattner6000dac2007-08-08 22:51:59 +0000271}
272void StmtDumper::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node) {
Chris Lattner13cb21f2007-08-09 17:35:30 +0000273 DumpExpr(Node);
274 fprintf(F, " %s ", Node->isSizeOf() ? "sizeof" : "alignof");
275 DumpType(Node->getArgumentType());
Chris Lattner6000dac2007-08-08 22:51:59 +0000276}
Chris Lattner13cb21f2007-08-09 17:35:30 +0000277
Chris Lattner6000dac2007-08-08 22:51:59 +0000278void StmtDumper::VisitMemberExpr(MemberExpr *Node) {
Chris Lattner13cb21f2007-08-09 17:35:30 +0000279 DumpExpr(Node);
Chris Lattnerb3938792007-08-30 00:53:54 +0000280 fprintf(F, " %s%s %p", Node->isArrow() ? "->" : ".",
Chris Lattner13cb21f2007-08-09 17:35:30 +0000281 Node->getMemberDecl()->getName(), (void*)Node->getMemberDecl());
Chris Lattner6000dac2007-08-08 22:51:59 +0000282}
283void StmtDumper::VisitOCUVectorElementExpr(OCUVectorElementExpr *Node) {
Chris Lattner13cb21f2007-08-09 17:35:30 +0000284 DumpExpr(Node);
Chris Lattnerb3938792007-08-30 00:53:54 +0000285 fprintf(F, " %s", Node->getAccessor().getName());
Chris Lattner6000dac2007-08-08 22:51:59 +0000286}
Chris Lattner6000dac2007-08-08 22:51:59 +0000287void StmtDumper::VisitBinaryOperator(BinaryOperator *Node) {
288 DumpExpr(Node);
Chris Lattnerb3938792007-08-30 00:53:54 +0000289 fprintf(F, " '%s'", BinaryOperator::getOpcodeStr(Node->getOpcode()));
Chris Lattnereb14fe82007-08-25 02:00:02 +0000290}
291void StmtDumper::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
292 DumpExpr(Node);
293 fprintf(F, " '%s' ComputeTy=",
294 BinaryOperator::getOpcodeStr(Node->getOpcode()));
295 DumpType(Node->getComputationType());
Chris Lattner6000dac2007-08-08 22:51:59 +0000296}
Chris Lattner6000dac2007-08-08 22:51:59 +0000297
298// GNU extensions.
299
300void StmtDumper::VisitAddrLabelExpr(AddrLabelExpr *Node) {
Chris Lattner13cb21f2007-08-09 17:35:30 +0000301 DumpExpr(Node);
Chris Lattnerb3938792007-08-30 00:53:54 +0000302 fprintf(F, " %s %p", Node->getLabel()->getName(), (void*)Node->getLabel());
Chris Lattner6000dac2007-08-08 22:51:59 +0000303}
304
Chris Lattner6000dac2007-08-08 22:51:59 +0000305void StmtDumper::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
Chris Lattner13cb21f2007-08-09 17:35:30 +0000306 DumpExpr(Node);
307 fprintf(F, " ");
308 DumpType(Node->getArgType1());
309 fprintf(F, " ");
310 DumpType(Node->getArgType2());
Chris Lattner6000dac2007-08-08 22:51:59 +0000311}
312
Chris Lattnerf9e05812007-08-09 18:03:18 +0000313//===----------------------------------------------------------------------===//
314// C++ Expressions
315//===----------------------------------------------------------------------===//
Chris Lattner6000dac2007-08-08 22:51:59 +0000316
317void StmtDumper::VisitCXXCastExpr(CXXCastExpr *Node) {
Chris Lattner13cb21f2007-08-09 17:35:30 +0000318 DumpExpr(Node);
Chris Lattnerb3938792007-08-30 00:53:54 +0000319 fprintf(F, " %s", CXXCastExpr::getOpcodeStr(Node->getOpcode()));
Chris Lattner6000dac2007-08-08 22:51:59 +0000320}
321
322void StmtDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
Chris Lattner13cb21f2007-08-09 17:35:30 +0000323 DumpExpr(Node);
Chris Lattnerb3938792007-08-30 00:53:54 +0000324 fprintf(F, " %s", Node->getValue() ? "true" : "false");
Chris Lattner6000dac2007-08-08 22:51:59 +0000325}
326
Anders Carlsson55085182007-08-21 17:43:55 +0000327//===----------------------------------------------------------------------===//
328// Obj-C Expressions
329//===----------------------------------------------------------------------===//
330
Anders Carlssonf9bcf012007-08-22 15:14:15 +0000331void StmtDumper::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
332 DumpExpr(Node);
333
334 fprintf(F, " ");
335 DumpType(Node->getEncodedType());
Anders Carlssonf9bcf012007-08-22 15:14:15 +0000336}
337
Chris Lattner6000dac2007-08-08 22:51:59 +0000338//===----------------------------------------------------------------------===//
339// Stmt method implementations
340//===----------------------------------------------------------------------===//
341
342/// dump - This does a local dump of the specified AST fragment. It dumps the
343/// specified node and a few nodes underneath it, but not the whole subtree.
344/// This is useful in a debugger.
Chris Lattner0c727a32007-08-30 00:40:08 +0000345void Stmt::dump(const SourceManager &SM) const {
346 StmtDumper P(&SM, stderr, 4);
Chris Lattnerb3938792007-08-30 00:53:54 +0000347 P.DumpSubTree(const_cast<Stmt*>(this));
Chris Lattner0c727a32007-08-30 00:40:08 +0000348 fprintf(stderr, "\n");
349}
350
351/// dump - This does a local dump of the specified AST fragment. It dumps the
352/// specified node and a few nodes underneath it, but not the whole subtree.
353/// This is useful in a debugger.
Chris Lattner6000dac2007-08-08 22:51:59 +0000354void Stmt::dump() const {
Chris Lattner0c727a32007-08-30 00:40:08 +0000355 StmtDumper P(0, stderr, 4);
Chris Lattnerb3938792007-08-30 00:53:54 +0000356 P.DumpSubTree(const_cast<Stmt*>(this));
Chris Lattner0c727a32007-08-30 00:40:08 +0000357 fprintf(stderr, "\n");
358}
359
360/// dumpAll - This does a dump of the specified AST fragment and all subtrees.
361void Stmt::dumpAll(const SourceManager &SM) const {
362 StmtDumper P(&SM, stderr, ~0U);
Chris Lattnerb3938792007-08-30 00:53:54 +0000363 P.DumpSubTree(const_cast<Stmt*>(this));
Chris Lattneree41ce52007-08-10 21:51:12 +0000364 fprintf(stderr, "\n");
Chris Lattner6000dac2007-08-08 22:51:59 +0000365}
366
367/// dumpAll - This does a dump of the specified AST fragment and all subtrees.
368void Stmt::dumpAll() const {
Chris Lattner0c727a32007-08-30 00:40:08 +0000369 StmtDumper P(0, stderr, ~0U);
Chris Lattnerb3938792007-08-30 00:53:54 +0000370 P.DumpSubTree(const_cast<Stmt*>(this));
Chris Lattneree41ce52007-08-10 21:51:12 +0000371 fprintf(stderr, "\n");
Chris Lattner6000dac2007-08-08 22:51:59 +0000372}