blob: 21dc0ba0a18807f05936480df539c9ad96ca1f69 [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"
Douglas Gregoree75c052009-05-21 20:55:50 +000020using namespace clang;
21
22//===----------------------------------------------------------------------===//
23// StmtXML Visitor
24//===----------------------------------------------------------------------===//
25
26namespace {
Benjamin Kramerbd218282009-11-28 10:07:24 +000027 class StmtXML : public StmtVisitor<StmtXML> {
Douglas Gregoree75c052009-05-21 20:55:50 +000028 DocumentXML& Doc;
29
Douglas Gregor038f75a2009-06-15 19:02:54 +000030 //static const char *getOpcodeStr(UnaryOperator::Opcode Op);
31 //static const char *getOpcodeStr(BinaryOperator::Opcode Op);
32
33
Mike Stump1eb44332009-09-09 15:08:12 +000034 void addSpecialAttribute(const char* pName, StringLiteral* Str) {
Douglas Gregor038f75a2009-06-15 19:02:54 +000035 Doc.addAttribute(pName, Doc.escapeString(Str->getStrData(), Str->getByteLength()));
36 }
37
Mike Stump1eb44332009-09-09 15:08:12 +000038 void addSpecialAttribute(const char* pName, SizeOfAlignOfExpr* S) {
Douglas Gregor038f75a2009-06-15 19:02:54 +000039 if (S->isArgumentType())
Douglas Gregor038f75a2009-06-15 19:02:54 +000040 Doc.addAttribute(pName, S->getArgumentType());
Douglas Gregor038f75a2009-06-15 19:02:54 +000041 }
42
Mike Stump1eb44332009-09-09 15:08:12 +000043 void addSpecialAttribute(const char* pName, CXXTypeidExpr* S) {
Douglas Gregor038f75a2009-06-15 19:02:54 +000044 if (S->isTypeOperand())
Douglas Gregor038f75a2009-06-15 19:02:54 +000045 Doc.addAttribute(pName, S->getTypeOperand());
Douglas Gregor038f75a2009-06-15 19:02:54 +000046 }
47
Douglas Gregoree75c052009-05-21 20:55:50 +000048
49 public:
50 StmtXML(DocumentXML& doc)
51 : Doc(doc) {
52 }
Mike Stump1eb44332009-09-09 15:08:12 +000053
Douglas Gregoree75c052009-05-21 20:55:50 +000054 void DumpSubTree(Stmt *S) {
Mike Stump1eb44332009-09-09 15:08:12 +000055 if (S) {
Douglas Gregor038f75a2009-06-15 19:02:54 +000056 Visit(S);
Mike Stump1eb44332009-09-09 15:08:12 +000057 if (DeclStmt* DS = dyn_cast<DeclStmt>(S)) {
58 for (DeclStmt::decl_iterator DI = DS->decl_begin(),
59 DE = DS->decl_end(); DI != DE; ++DI) {
Douglas Gregor038f75a2009-06-15 19:02:54 +000060 Doc.PrintDecl(*DI);
61 }
Mike Stump1eb44332009-09-09 15:08:12 +000062 } else {
Mike Stump1eb44332009-09-09 15:08:12 +000063 for (Stmt::child_iterator i = S->child_begin(), e = S->child_end();
64 i != e; ++i)
Douglas Gregoree75c052009-05-21 20:55:50 +000065 DumpSubTree(*i);
Douglas Gregoree75c052009-05-21 20:55:50 +000066 }
67 Doc.toParent();
68 } else {
69 Doc.addSubNode("NULL").toParent();
70 }
71 }
72
Douglas Gregoree75c052009-05-21 20:55:50 +000073
Douglas Gregor038f75a2009-06-15 19:02:54 +000074#define NODE_XML( CLASS, NAME ) \
75 void Visit##CLASS(CLASS* S) \
76 { \
77 typedef CLASS tStmtType; \
Mike Stump1eb44332009-09-09 15:08:12 +000078 Doc.addSubNode(NAME);
Douglas Gregoree75c052009-05-21 20:55:50 +000079
Mike Stump1eb44332009-09-09 15:08:12 +000080#define ATTRIBUTE_XML( FN, NAME ) Doc.addAttribute(NAME, S->FN);
Douglas Gregor038f75a2009-06-15 19:02:54 +000081#define TYPE_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "type")
Mike Stump1eb44332009-09-09 15:08:12 +000082#define ATTRIBUTE_OPT_XML( FN, NAME ) Doc.addAttributeOptional(NAME, S->FN);
83#define ATTRIBUTE_SPECIAL_XML( FN, NAME ) addSpecialAttribute(NAME, S);
Douglas Gregor038f75a2009-06-15 19:02:54 +000084#define ATTRIBUTE_FILE_LOCATION_XML Doc.addLocationRange(S->getSourceRange());
85
86
87#define ATTRIBUTE_ENUM_XML( FN, NAME ) \
88 { \
89 const char* pAttributeName = NAME; \
90 const bool optional = false; \
91 switch (S->FN) { \
Mike Stumpb7166332010-01-20 02:03:14 +000092 default: assert(0 && "unknown enum value");
Douglas Gregor038f75a2009-06-15 19:02:54 +000093
94#define ATTRIBUTE_ENUM_OPT_XML( FN, NAME ) \
95 { \
96 const char* pAttributeName = NAME; \
97 const bool optional = true; \
98 switch (S->FN) { \
Mike Stumpb7166332010-01-20 02:03:14 +000099 default: assert(0 && "unknown enum value");
Douglas Gregor038f75a2009-06-15 19:02:54 +0000100
101#define ENUM_XML( VALUE, NAME ) case VALUE: if ((!optional) || NAME[0]) Doc.addAttribute(pAttributeName, NAME); break;
102#define END_ENUM_XML } }
103#define END_NODE_XML }
104
105#define ID_ATTRIBUTE_XML Doc.addAttribute("id", S);
106#define SUB_NODE_XML( CLASS )
107#define SUB_NODE_SEQUENCE_XML( CLASS )
108#define SUB_NODE_OPT_XML( CLASS )
109
110#include "clang/Frontend/StmtXML.def"
111
112#if (0)
Douglas Gregoree75c052009-05-21 20:55:50 +0000113 // Stmts.
114 void VisitStmt(Stmt *Node);
115 void VisitDeclStmt(DeclStmt *Node);
116 void VisitLabelStmt(LabelStmt *Node);
117 void VisitGotoStmt(GotoStmt *Node);
Mike Stump1eb44332009-09-09 15:08:12 +0000118
Douglas Gregoree75c052009-05-21 20:55:50 +0000119 // Exprs
120 void VisitExpr(Expr *Node);
121 void VisitDeclRefExpr(DeclRefExpr *Node);
122 void VisitPredefinedExpr(PredefinedExpr *Node);
123 void VisitCharacterLiteral(CharacterLiteral *Node);
124 void VisitIntegerLiteral(IntegerLiteral *Node);
125 void VisitFloatingLiteral(FloatingLiteral *Node);
126 void VisitStringLiteral(StringLiteral *Str);
127 void VisitUnaryOperator(UnaryOperator *Node);
Douglas Gregor8ecdb652010-04-28 22:16:22 +0000128 void VisitOffsetOfExpr(OffsetOfExpr *Node);
Douglas Gregoree75c052009-05-21 20:55:50 +0000129 void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node);
130 void VisitMemberExpr(MemberExpr *Node);
131 void VisitExtVectorElementExpr(ExtVectorElementExpr *Node);
132 void VisitBinaryOperator(BinaryOperator *Node);
133 void VisitCompoundAssignOperator(CompoundAssignOperator *Node);
134 void VisitAddrLabelExpr(AddrLabelExpr *Node);
135 void VisitTypesCompatibleExpr(TypesCompatibleExpr *Node);
136
137 // C++
138 void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
139 void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node);
140 void VisitCXXThisExpr(CXXThisExpr *Node);
141 void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node);
Mike Stump1eb44332009-09-09 15:08:12 +0000142
Douglas Gregoree75c052009-05-21 20:55:50 +0000143 // ObjC
144 void VisitObjCEncodeExpr(ObjCEncodeExpr *Node);
145 void VisitObjCMessageExpr(ObjCMessageExpr* Node);
146 void VisitObjCSelectorExpr(ObjCSelectorExpr *Node);
147 void VisitObjCProtocolExpr(ObjCProtocolExpr *Node);
148 void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node);
Fariborz Jahanian09105f52009-08-20 17:02:02 +0000149 void VisitObjCImplicitSetterGetterRefExpr(
150 ObjCImplicitSetterGetterRefExpr *Node);
Douglas Gregoree75c052009-05-21 20:55:50 +0000151 void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
152 void VisitObjCSuperExpr(ObjCSuperExpr *Node);
Douglas Gregor038f75a2009-06-15 19:02:54 +0000153#endif
Douglas Gregoree75c052009-05-21 20:55:50 +0000154 };
155}
156
157//===----------------------------------------------------------------------===//
158// Stmt printing methods.
159//===----------------------------------------------------------------------===//
Douglas Gregor038f75a2009-06-15 19:02:54 +0000160#if (0)
Mike Stump1eb44332009-09-09 15:08:12 +0000161void StmtXML::VisitStmt(Stmt *Node) {
Douglas Gregoree75c052009-05-21 20:55:50 +0000162 // nothing special to do
163}
164
Mike Stump1eb44332009-09-09 15:08:12 +0000165void StmtXML::VisitDeclStmt(DeclStmt *Node) {
Douglas Gregoree75c052009-05-21 20:55:50 +0000166 for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end();
Mike Stump1eb44332009-09-09 15:08:12 +0000167 DI != DE; ++DI) {
Douglas Gregoree75c052009-05-21 20:55:50 +0000168 Doc.PrintDecl(*DI);
169 }
170}
171
Mike Stump1eb44332009-09-09 15:08:12 +0000172void StmtXML::VisitLabelStmt(LabelStmt *Node) {
Douglas Gregoree75c052009-05-21 20:55:50 +0000173 Doc.addAttribute("name", Node->getName());
174}
175
Mike Stump1eb44332009-09-09 15:08:12 +0000176void StmtXML::VisitGotoStmt(GotoStmt *Node) {
Douglas Gregoree75c052009-05-21 20:55:50 +0000177 Doc.addAttribute("name", Node->getLabel()->getName());
178}
179
180//===----------------------------------------------------------------------===//
181// Expr printing methods.
182//===----------------------------------------------------------------------===//
183
184void StmtXML::VisitExpr(Expr *Node) {
185 DumpExpr(Node);
186}
187
188void StmtXML::VisitDeclRefExpr(DeclRefExpr *Node) {
189 DumpExpr(Node);
190
191 const char* pKind;
192 switch (Node->getDecl()->getKind()) {
Mike Stumpb7166332010-01-20 02:03:14 +0000193 case Decl::Function: pKind = "FunctionDecl"; break;
194 case Decl::Var: pKind = "Var"; break;
195 case Decl::ParmVar: pKind = "ParmVar"; break;
196 case Decl::EnumConstant: pKind = "EnumConstant"; break;
197 case Decl::Typedef: pKind = "Typedef"; break;
198 case Decl::Record: pKind = "Record"; break;
199 case Decl::Enum: pKind = "Enum"; break;
200 case Decl::CXXRecord: pKind = "CXXRecord"; break;
201 case Decl::ObjCInterface: pKind = "ObjCInterface"; break;
202 case Decl::ObjCClass: pKind = "ObjCClass"; break;
203 default: pKind = "Decl"; break;
Douglas Gregoree75c052009-05-21 20:55:50 +0000204 }
205
206 Doc.addAttribute("kind", pKind);
207 Doc.addAttribute("name", Node->getDecl()->getNameAsString());
208 Doc.addRefAttribute(Node->getDecl());
209}
210
211void StmtXML::VisitPredefinedExpr(PredefinedExpr *Node) {
212 DumpExpr(Node);
213 switch (Node->getIdentType()) {
Mike Stumpb7166332010-01-20 02:03:14 +0000214 default: assert(0 && "unknown case");
215 case PredefinedExpr::Func: Doc.addAttribute("predefined", " __func__"); break;
216 case PredefinedExpr::Function: Doc.addAttribute("predefined", " __FUNCTION__"); break;
217 case PredefinedExpr::PrettyFunction: Doc.addAttribute("predefined", " __PRETTY_FUNCTION__");break;
Douglas Gregoree75c052009-05-21 20:55:50 +0000218 }
219}
220
221void StmtXML::VisitCharacterLiteral(CharacterLiteral *Node) {
222 DumpExpr(Node);
223 Doc.addAttribute("value", Node->getValue());
224}
225
226void StmtXML::VisitIntegerLiteral(IntegerLiteral *Node) {
227 DumpExpr(Node);
228 bool isSigned = Node->getType()->isSignedIntegerType();
229 Doc.addAttribute("value", Node->getValue().toString(10, isSigned));
230}
231
232void StmtXML::VisitFloatingLiteral(FloatingLiteral *Node) {
233 DumpExpr(Node);
234 // FIXME: output float as written in source (no approximation or the like)
235 //Doc.addAttribute("value", Node->getValueAsApproximateDouble()));
236 Doc.addAttribute("value", "FIXME");
237}
238
239void StmtXML::VisitStringLiteral(StringLiteral *Str) {
240 DumpExpr(Str);
241 if (Str->isWide())
242 Doc.addAttribute("is_wide", "1");
243
244 Doc.addAttribute("value", Doc.escapeString(Str->getStrData(), Str->getByteLength()));
245}
246
247
248const char *StmtXML::getOpcodeStr(UnaryOperator::Opcode Op) {
249 switch (Op) {
250 default: assert(0 && "Unknown unary operator");
251 case UnaryOperator::PostInc: return "postinc";
252 case UnaryOperator::PostDec: return "postdec";
253 case UnaryOperator::PreInc: return "preinc";
254 case UnaryOperator::PreDec: return "predec";
255 case UnaryOperator::AddrOf: return "addrof";
256 case UnaryOperator::Deref: return "deref";
257 case UnaryOperator::Plus: return "plus";
258 case UnaryOperator::Minus: return "minus";
259 case UnaryOperator::Not: return "not";
260 case UnaryOperator::LNot: return "lnot";
261 case UnaryOperator::Real: return "__real";
262 case UnaryOperator::Imag: return "__imag";
263 case UnaryOperator::Extension: return "__extension__";
264 case UnaryOperator::OffsetOf: return "__builtin_offsetof";
265 }
266}
267
268
269const char *StmtXML::getOpcodeStr(BinaryOperator::Opcode Op) {
270 switch (Op) {
271 default: assert(0 && "Unknown binary operator");
272 case BinaryOperator::PtrMemD: return "ptrmemd";
273 case BinaryOperator::PtrMemI: return "ptrmemi";
274 case BinaryOperator::Mul: return "mul";
275 case BinaryOperator::Div: return "div";
276 case BinaryOperator::Rem: return "rem";
277 case BinaryOperator::Add: return "add";
278 case BinaryOperator::Sub: return "sub";
279 case BinaryOperator::Shl: return "shl";
280 case BinaryOperator::Shr: return "shr";
281 case BinaryOperator::LT: return "lt";
282 case BinaryOperator::GT: return "gt";
283 case BinaryOperator::LE: return "le";
284 case BinaryOperator::GE: return "ge";
285 case BinaryOperator::EQ: return "eq";
286 case BinaryOperator::NE: return "ne";
287 case BinaryOperator::And: return "and";
288 case BinaryOperator::Xor: return "xor";
289 case BinaryOperator::Or: return "or";
290 case BinaryOperator::LAnd: return "land";
291 case BinaryOperator::LOr: return "lor";
292 case BinaryOperator::Assign: return "assign";
293 case BinaryOperator::MulAssign: return "mulassign";
294 case BinaryOperator::DivAssign: return "divassign";
295 case BinaryOperator::RemAssign: return "remassign";
296 case BinaryOperator::AddAssign: return "addassign";
297 case BinaryOperator::SubAssign: return "subassign";
298 case BinaryOperator::ShlAssign: return "shlassign";
299 case BinaryOperator::ShrAssign: return "shrassign";
300 case BinaryOperator::AndAssign: return "andassign";
301 case BinaryOperator::XorAssign: return "xorassign";
302 case BinaryOperator::OrAssign: return "orassign";
303 case BinaryOperator::Comma: return "comma";
304 }
305}
306
307void StmtXML::VisitUnaryOperator(UnaryOperator *Node) {
308 DumpExpr(Node);
309 Doc.addAttribute("op_code", getOpcodeStr(Node->getOpcode()));
310}
311
Douglas Gregor8ecdb652010-04-28 22:16:22 +0000312void StmtXML::OffsetOfExpr(OffsetOfExpr *Node) {
313 DumpExpr(Node);
314}
315
Douglas Gregoree75c052009-05-21 20:55:50 +0000316void StmtXML::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
317 DumpExpr(Node);
318 Doc.addAttribute("is_sizeof", Node->isSizeOf() ? "sizeof" : "alignof");
319 Doc.addAttribute("is_type", Node->isArgumentType() ? "1" : "0");
320 if (Node->isArgumentType())
Douglas Gregoree75c052009-05-21 20:55:50 +0000321 DumpTypeExpr(Node->getArgumentType());
Douglas Gregoree75c052009-05-21 20:55:50 +0000322}
323
324void StmtXML::VisitMemberExpr(MemberExpr *Node) {
325 DumpExpr(Node);
326 Doc.addAttribute("is_deref", Node->isArrow() ? "1" : "0");
327 Doc.addAttribute("name", Node->getMemberDecl()->getNameAsString());
328 Doc.addRefAttribute(Node->getMemberDecl());
329}
330
331void StmtXML::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
332 DumpExpr(Node);
333 Doc.addAttribute("name", Node->getAccessor().getName());
334}
335
336void StmtXML::VisitBinaryOperator(BinaryOperator *Node) {
337 DumpExpr(Node);
338 Doc.addAttribute("op_code", getOpcodeStr(Node->getOpcode()));
339}
340
341void StmtXML::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
342 VisitBinaryOperator(Node);
343/* FIXME: is this needed in the AST?
344 DumpExpr(Node);
345 CurrentNode = CurrentNode->addSubNode("ComputeLHSTy");
346 DumpType(Node->getComputationLHSType());
347 CurrentNode = CurrentNode->Parent->addSubNode("ComputeResultTy");
348 DumpType(Node->getComputationResultType());
349 Doc.toParent();
350*/
351}
352
353// GNU extensions.
354
355void StmtXML::VisitAddrLabelExpr(AddrLabelExpr *Node) {
356 DumpExpr(Node);
357 Doc.addAttribute("name", Node->getLabel()->getName());
358}
359
360void StmtXML::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
361 DumpExpr(Node);
362 DumpTypeExpr(Node->getArgType1());
363 DumpTypeExpr(Node->getArgType2());
364}
365
366//===----------------------------------------------------------------------===//
367// C++ Expressions
368//===----------------------------------------------------------------------===//
369
370void StmtXML::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
371 DumpExpr(Node);
372 Doc.addAttribute("kind", Node->getCastName());
373 DumpTypeExpr(Node->getTypeAsWritten());
374}
375
376void StmtXML::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
377 DumpExpr(Node);
378 Doc.addAttribute("value", Node->getValue() ? "true" : "false");
379}
380
381void StmtXML::VisitCXXThisExpr(CXXThisExpr *Node) {
382 DumpExpr(Node);
383}
384
385void StmtXML::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
386 DumpExpr(Node);
387 DumpTypeExpr(Node->getTypeAsWritten());
388}
389
390//===----------------------------------------------------------------------===//
391// Obj-C Expressions
392//===----------------------------------------------------------------------===//
393
394void StmtXML::VisitObjCMessageExpr(ObjCMessageExpr* Node) {
395 DumpExpr(Node);
396 Doc.addAttribute("selector", Node->getSelector().getAsString());
397 IdentifierInfo* clsName = Node->getClassName();
Mike Stump1eb44332009-09-09 15:08:12 +0000398 if (clsName)
Douglas Gregoree75c052009-05-21 20:55:50 +0000399 Doc.addAttribute("class", clsName->getName());
400}
401
402void StmtXML::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
403 DumpExpr(Node);
404 DumpTypeExpr(Node->getEncodedType());
405}
406
407void StmtXML::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
408 DumpExpr(Node);
409 Doc.addAttribute("selector", Node->getSelector().getAsString());
410}
411
412void StmtXML::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
413 DumpExpr(Node);
414 Doc.addAttribute("protocol", Node->getProtocol()->getNameAsString());
415}
416
417void StmtXML::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
418 DumpExpr(Node);
419 Doc.addAttribute("property", Node->getProperty()->getNameAsString());
420}
421
Fariborz Jahanian09105f52009-08-20 17:02:02 +0000422void StmtXML::VisitObjCImplicitSetterGetterRefExpr(
423 ObjCImplicitSetterGetterRefExpr *Node) {
Douglas Gregoree75c052009-05-21 20:55:50 +0000424 DumpExpr(Node);
425 ObjCMethodDecl *Getter = Node->getGetterMethod();
426 ObjCMethodDecl *Setter = Node->getSetterMethod();
427 Doc.addAttribute("Getter", Getter->getSelector().getAsString());
428 Doc.addAttribute("Setter", Setter ? Setter->getSelector().getAsString().c_str() : "(null)");
429}
430
431void StmtXML::VisitObjCSuperExpr(ObjCSuperExpr *Node) {
432 DumpExpr(Node);
433 Doc.addAttribute("super", "1");
434}
435
436void StmtXML::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
437 DumpExpr(Node);
438 Doc.addAttribute("kind", Node->getDecl()->getDeclKindName());
439 Doc.addAttribute("decl", Node->getDecl()->getNameAsString());
440 if (Node->isFreeIvar())
441 Doc.addAttribute("isFreeIvar", "1");
442}
Douglas Gregor038f75a2009-06-15 19:02:54 +0000443#endif
Douglas Gregoree75c052009-05-21 20:55:50 +0000444//===----------------------------------------------------------------------===//
445// Stmt method implementations
446//===----------------------------------------------------------------------===//
447
448/// dumpAll - This does a dump of the specified AST fragment and all subtrees.
449void DocumentXML::PrintStmt(const Stmt *S) {
450 StmtXML P(*this);
451 P.DumpSubTree(const_cast<Stmt*>(S));
452}
453