blob: c861881486b3b3a93cd2527d0bfd71f91b7adca7 [file] [log] [blame]
Douglas Gregoree75c052009-05-21 20:55:50 +00001//===--- StmtXML.cpp - XML 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::dumpXML methods, which dump out the
11// AST to an XML document.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/Frontend/DocumentXML.h"
16#include "clang/AST/StmtVisitor.h"
17#include "clang/AST/DeclObjC.h"
18#include "clang/AST/DeclCXX.h"
19#include "clang/Basic/SourceManager.h"
20#include "llvm/Support/Compiler.h"
21using namespace clang;
22
23//===----------------------------------------------------------------------===//
24// StmtXML Visitor
25//===----------------------------------------------------------------------===//
26
27namespace {
28 class VISIBILITY_HIDDEN StmtXML : public StmtVisitor<StmtXML> {
29 DocumentXML& Doc;
30
31 static const char *getOpcodeStr(UnaryOperator::Opcode Op);
32 static const char *getOpcodeStr(BinaryOperator::Opcode Op);
33
34 public:
35 StmtXML(DocumentXML& doc)
36 : Doc(doc) {
37 }
38
39 void DumpSubTree(Stmt *S) {
40 if (S)
41 {
42 Doc.addSubNode(S->getStmtClassName());
43 Doc.addLocationRange(S->getSourceRange());
44 if (DeclStmt* DS = dyn_cast<DeclStmt>(S)) {
45 VisitDeclStmt(DS);
46 } else {
47 Visit(S);
48 for (Stmt::child_iterator i = S->child_begin(), e = S->child_end(); i != e; ++i)
49 {
50 DumpSubTree(*i);
51 }
52 }
53 Doc.toParent();
54 } else {
55 Doc.addSubNode("NULL").toParent();
56 }
57 }
58
59 void DumpTypeExpr(const QualType& T)
60 {
61 Doc.addSubNode("TypeExpr");
62 Doc.addTypeAttribute(T);
63 Doc.toParent();
64 }
65
66 void DumpExpr(const Expr *Node) {
67 Doc.addTypeAttribute(Node->getType());
68 }
69
70 // Stmts.
71 void VisitStmt(Stmt *Node);
72 void VisitDeclStmt(DeclStmt *Node);
73 void VisitLabelStmt(LabelStmt *Node);
74 void VisitGotoStmt(GotoStmt *Node);
75
76 // Exprs
77 void VisitExpr(Expr *Node);
78 void VisitDeclRefExpr(DeclRefExpr *Node);
79 void VisitPredefinedExpr(PredefinedExpr *Node);
80 void VisitCharacterLiteral(CharacterLiteral *Node);
81 void VisitIntegerLiteral(IntegerLiteral *Node);
82 void VisitFloatingLiteral(FloatingLiteral *Node);
83 void VisitStringLiteral(StringLiteral *Str);
84 void VisitUnaryOperator(UnaryOperator *Node);
85 void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node);
86 void VisitMemberExpr(MemberExpr *Node);
87 void VisitExtVectorElementExpr(ExtVectorElementExpr *Node);
88 void VisitBinaryOperator(BinaryOperator *Node);
89 void VisitCompoundAssignOperator(CompoundAssignOperator *Node);
90 void VisitAddrLabelExpr(AddrLabelExpr *Node);
91 void VisitTypesCompatibleExpr(TypesCompatibleExpr *Node);
92
93 // C++
94 void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
95 void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node);
96 void VisitCXXThisExpr(CXXThisExpr *Node);
97 void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node);
98
99 // ObjC
100 void VisitObjCEncodeExpr(ObjCEncodeExpr *Node);
101 void VisitObjCMessageExpr(ObjCMessageExpr* Node);
102 void VisitObjCSelectorExpr(ObjCSelectorExpr *Node);
103 void VisitObjCProtocolExpr(ObjCProtocolExpr *Node);
104 void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node);
105 void VisitObjCKVCRefExpr(ObjCKVCRefExpr *Node);
106 void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
107 void VisitObjCSuperExpr(ObjCSuperExpr *Node);
108 };
109}
110
111//===----------------------------------------------------------------------===//
112// Stmt printing methods.
113//===----------------------------------------------------------------------===//
114
115void StmtXML::VisitStmt(Stmt *Node)
116{
117 // nothing special to do
118}
119
120void StmtXML::VisitDeclStmt(DeclStmt *Node)
121{
122 for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end();
123 DI != DE; ++DI)
124 {
125 Doc.PrintDecl(*DI);
126 }
127}
128
129void StmtXML::VisitLabelStmt(LabelStmt *Node)
130{
131 Doc.addAttribute("name", Node->getName());
132}
133
134void StmtXML::VisitGotoStmt(GotoStmt *Node)
135{
136 Doc.addAttribute("name", Node->getLabel()->getName());
137}
138
139//===----------------------------------------------------------------------===//
140// Expr printing methods.
141//===----------------------------------------------------------------------===//
142
143void StmtXML::VisitExpr(Expr *Node) {
144 DumpExpr(Node);
145}
146
147void StmtXML::VisitDeclRefExpr(DeclRefExpr *Node) {
148 DumpExpr(Node);
149
150 const char* pKind;
151 switch (Node->getDecl()->getKind()) {
152 case Decl::Function: pKind = "FunctionDecl"; break;
153 case Decl::Var: pKind = "Var"; break;
154 case Decl::ParmVar: pKind = "ParmVar"; break;
155 case Decl::EnumConstant: pKind = "EnumConstant"; break;
156 case Decl::Typedef: pKind = "Typedef"; break;
157 case Decl::Record: pKind = "Record"; break;
158 case Decl::Enum: pKind = "Enum"; break;
159 case Decl::CXXRecord: pKind = "CXXRecord"; break;
160 case Decl::ObjCInterface: pKind = "ObjCInterface"; break;
161 case Decl::ObjCClass: pKind = "ObjCClass"; break;
162 default: pKind = "Decl"; break;
163 }
164
165 Doc.addAttribute("kind", pKind);
166 Doc.addAttribute("name", Node->getDecl()->getNameAsString());
167 Doc.addRefAttribute(Node->getDecl());
168}
169
170void StmtXML::VisitPredefinedExpr(PredefinedExpr *Node) {
171 DumpExpr(Node);
172 switch (Node->getIdentType()) {
173 default: assert(0 && "unknown case");
174 case PredefinedExpr::Func: Doc.addAttribute("predefined", " __func__"); break;
175 case PredefinedExpr::Function: Doc.addAttribute("predefined", " __FUNCTION__"); break;
176 case PredefinedExpr::PrettyFunction: Doc.addAttribute("predefined", " __PRETTY_FUNCTION__");break;
177 }
178}
179
180void StmtXML::VisitCharacterLiteral(CharacterLiteral *Node) {
181 DumpExpr(Node);
182 Doc.addAttribute("value", Node->getValue());
183}
184
185void StmtXML::VisitIntegerLiteral(IntegerLiteral *Node) {
186 DumpExpr(Node);
187 bool isSigned = Node->getType()->isSignedIntegerType();
188 Doc.addAttribute("value", Node->getValue().toString(10, isSigned));
189}
190
191void StmtXML::VisitFloatingLiteral(FloatingLiteral *Node) {
192 DumpExpr(Node);
193 // FIXME: output float as written in source (no approximation or the like)
194 //Doc.addAttribute("value", Node->getValueAsApproximateDouble()));
195 Doc.addAttribute("value", "FIXME");
196}
197
198void StmtXML::VisitStringLiteral(StringLiteral *Str) {
199 DumpExpr(Str);
200 if (Str->isWide())
201 Doc.addAttribute("is_wide", "1");
202
203 Doc.addAttribute("value", Doc.escapeString(Str->getStrData(), Str->getByteLength()));
204}
205
206
207const char *StmtXML::getOpcodeStr(UnaryOperator::Opcode Op) {
208 switch (Op) {
209 default: assert(0 && "Unknown unary operator");
210 case UnaryOperator::PostInc: return "postinc";
211 case UnaryOperator::PostDec: return "postdec";
212 case UnaryOperator::PreInc: return "preinc";
213 case UnaryOperator::PreDec: return "predec";
214 case UnaryOperator::AddrOf: return "addrof";
215 case UnaryOperator::Deref: return "deref";
216 case UnaryOperator::Plus: return "plus";
217 case UnaryOperator::Minus: return "minus";
218 case UnaryOperator::Not: return "not";
219 case UnaryOperator::LNot: return "lnot";
220 case UnaryOperator::Real: return "__real";
221 case UnaryOperator::Imag: return "__imag";
222 case UnaryOperator::Extension: return "__extension__";
223 case UnaryOperator::OffsetOf: return "__builtin_offsetof";
224 }
225}
226
227
228const char *StmtXML::getOpcodeStr(BinaryOperator::Opcode Op) {
229 switch (Op) {
230 default: assert(0 && "Unknown binary operator");
231 case BinaryOperator::PtrMemD: return "ptrmemd";
232 case BinaryOperator::PtrMemI: return "ptrmemi";
233 case BinaryOperator::Mul: return "mul";
234 case BinaryOperator::Div: return "div";
235 case BinaryOperator::Rem: return "rem";
236 case BinaryOperator::Add: return "add";
237 case BinaryOperator::Sub: return "sub";
238 case BinaryOperator::Shl: return "shl";
239 case BinaryOperator::Shr: return "shr";
240 case BinaryOperator::LT: return "lt";
241 case BinaryOperator::GT: return "gt";
242 case BinaryOperator::LE: return "le";
243 case BinaryOperator::GE: return "ge";
244 case BinaryOperator::EQ: return "eq";
245 case BinaryOperator::NE: return "ne";
246 case BinaryOperator::And: return "and";
247 case BinaryOperator::Xor: return "xor";
248 case BinaryOperator::Or: return "or";
249 case BinaryOperator::LAnd: return "land";
250 case BinaryOperator::LOr: return "lor";
251 case BinaryOperator::Assign: return "assign";
252 case BinaryOperator::MulAssign: return "mulassign";
253 case BinaryOperator::DivAssign: return "divassign";
254 case BinaryOperator::RemAssign: return "remassign";
255 case BinaryOperator::AddAssign: return "addassign";
256 case BinaryOperator::SubAssign: return "subassign";
257 case BinaryOperator::ShlAssign: return "shlassign";
258 case BinaryOperator::ShrAssign: return "shrassign";
259 case BinaryOperator::AndAssign: return "andassign";
260 case BinaryOperator::XorAssign: return "xorassign";
261 case BinaryOperator::OrAssign: return "orassign";
262 case BinaryOperator::Comma: return "comma";
263 }
264}
265
266void StmtXML::VisitUnaryOperator(UnaryOperator *Node) {
267 DumpExpr(Node);
268 Doc.addAttribute("op_code", getOpcodeStr(Node->getOpcode()));
269}
270
271void StmtXML::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
272 DumpExpr(Node);
273 Doc.addAttribute("is_sizeof", Node->isSizeOf() ? "sizeof" : "alignof");
274 Doc.addAttribute("is_type", Node->isArgumentType() ? "1" : "0");
275 if (Node->isArgumentType())
276 {
277 DumpTypeExpr(Node->getArgumentType());
278 }
279}
280
281void StmtXML::VisitMemberExpr(MemberExpr *Node) {
282 DumpExpr(Node);
283 Doc.addAttribute("is_deref", Node->isArrow() ? "1" : "0");
284 Doc.addAttribute("name", Node->getMemberDecl()->getNameAsString());
285 Doc.addRefAttribute(Node->getMemberDecl());
286}
287
288void StmtXML::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
289 DumpExpr(Node);
290 Doc.addAttribute("name", Node->getAccessor().getName());
291}
292
293void StmtXML::VisitBinaryOperator(BinaryOperator *Node) {
294 DumpExpr(Node);
295 Doc.addAttribute("op_code", getOpcodeStr(Node->getOpcode()));
296}
297
298void StmtXML::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
299 VisitBinaryOperator(Node);
300/* FIXME: is this needed in the AST?
301 DumpExpr(Node);
302 CurrentNode = CurrentNode->addSubNode("ComputeLHSTy");
303 DumpType(Node->getComputationLHSType());
304 CurrentNode = CurrentNode->Parent->addSubNode("ComputeResultTy");
305 DumpType(Node->getComputationResultType());
306 Doc.toParent();
307*/
308}
309
310// GNU extensions.
311
312void StmtXML::VisitAddrLabelExpr(AddrLabelExpr *Node) {
313 DumpExpr(Node);
314 Doc.addAttribute("name", Node->getLabel()->getName());
315}
316
317void StmtXML::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
318 DumpExpr(Node);
319 DumpTypeExpr(Node->getArgType1());
320 DumpTypeExpr(Node->getArgType2());
321}
322
323//===----------------------------------------------------------------------===//
324// C++ Expressions
325//===----------------------------------------------------------------------===//
326
327void StmtXML::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
328 DumpExpr(Node);
329 Doc.addAttribute("kind", Node->getCastName());
330 DumpTypeExpr(Node->getTypeAsWritten());
331}
332
333void StmtXML::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
334 DumpExpr(Node);
335 Doc.addAttribute("value", Node->getValue() ? "true" : "false");
336}
337
338void StmtXML::VisitCXXThisExpr(CXXThisExpr *Node) {
339 DumpExpr(Node);
340}
341
342void StmtXML::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
343 DumpExpr(Node);
344 DumpTypeExpr(Node->getTypeAsWritten());
345}
346
347//===----------------------------------------------------------------------===//
348// Obj-C Expressions
349//===----------------------------------------------------------------------===//
350
351void StmtXML::VisitObjCMessageExpr(ObjCMessageExpr* Node) {
352 DumpExpr(Node);
353 Doc.addAttribute("selector", Node->getSelector().getAsString());
354 IdentifierInfo* clsName = Node->getClassName();
355 if (clsName)
356 Doc.addAttribute("class", clsName->getName());
357}
358
359void StmtXML::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
360 DumpExpr(Node);
361 DumpTypeExpr(Node->getEncodedType());
362}
363
364void StmtXML::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
365 DumpExpr(Node);
366 Doc.addAttribute("selector", Node->getSelector().getAsString());
367}
368
369void StmtXML::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
370 DumpExpr(Node);
371 Doc.addAttribute("protocol", Node->getProtocol()->getNameAsString());
372}
373
374void StmtXML::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
375 DumpExpr(Node);
376 Doc.addAttribute("property", Node->getProperty()->getNameAsString());
377}
378
379void StmtXML::VisitObjCKVCRefExpr(ObjCKVCRefExpr *Node) {
380 DumpExpr(Node);
381 ObjCMethodDecl *Getter = Node->getGetterMethod();
382 ObjCMethodDecl *Setter = Node->getSetterMethod();
383 Doc.addAttribute("Getter", Getter->getSelector().getAsString());
384 Doc.addAttribute("Setter", Setter ? Setter->getSelector().getAsString().c_str() : "(null)");
385}
386
387void StmtXML::VisitObjCSuperExpr(ObjCSuperExpr *Node) {
388 DumpExpr(Node);
389 Doc.addAttribute("super", "1");
390}
391
392void StmtXML::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
393 DumpExpr(Node);
394 Doc.addAttribute("kind", Node->getDecl()->getDeclKindName());
395 Doc.addAttribute("decl", Node->getDecl()->getNameAsString());
396 if (Node->isFreeIvar())
397 Doc.addAttribute("isFreeIvar", "1");
398}
399
400//===----------------------------------------------------------------------===//
401// Stmt method implementations
402//===----------------------------------------------------------------------===//
403
404/// dumpAll - This does a dump of the specified AST fragment and all subtrees.
405void DocumentXML::PrintStmt(const Stmt *S) {
406 StmtXML P(*this);
407 P.DumpSubTree(const_cast<Stmt*>(S));
408}
409