blob: 4a3c0bf1c60f019c3732dc0d32a1938ccb69ef46 [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
Douglas Gregor038f75a2009-06-15 19:02:54 +000031 //static const char *getOpcodeStr(UnaryOperator::Opcode Op);
32 //static const char *getOpcodeStr(BinaryOperator::Opcode Op);
33
34
Mike Stump1eb44332009-09-09 15:08:12 +000035 void addSpecialAttribute(const char* pName, StringLiteral* Str) {
Douglas Gregor038f75a2009-06-15 19:02:54 +000036 Doc.addAttribute(pName, Doc.escapeString(Str->getStrData(), Str->getByteLength()));
37 }
38
Mike Stump1eb44332009-09-09 15:08:12 +000039 void addSpecialAttribute(const char* pName, SizeOfAlignOfExpr* S) {
Douglas Gregor038f75a2009-06-15 19:02:54 +000040 if (S->isArgumentType())
Douglas Gregor038f75a2009-06-15 19:02:54 +000041 Doc.addAttribute(pName, S->getArgumentType());
Douglas Gregor038f75a2009-06-15 19:02:54 +000042 }
43
Mike Stump1eb44332009-09-09 15:08:12 +000044 void addSpecialAttribute(const char* pName, CXXTypeidExpr* S) {
Douglas Gregor038f75a2009-06-15 19:02:54 +000045 if (S->isTypeOperand())
Douglas Gregor038f75a2009-06-15 19:02:54 +000046 Doc.addAttribute(pName, S->getTypeOperand());
Douglas Gregor038f75a2009-06-15 19:02:54 +000047 }
48
Douglas Gregoree75c052009-05-21 20:55:50 +000049
50 public:
51 StmtXML(DocumentXML& doc)
52 : Doc(doc) {
53 }
Mike Stump1eb44332009-09-09 15:08:12 +000054
Douglas Gregoree75c052009-05-21 20:55:50 +000055 void DumpSubTree(Stmt *S) {
Mike Stump1eb44332009-09-09 15:08:12 +000056 if (S) {
Douglas Gregor038f75a2009-06-15 19:02:54 +000057 Visit(S);
Mike Stump1eb44332009-09-09 15:08:12 +000058 if (DeclStmt* DS = dyn_cast<DeclStmt>(S)) {
59 for (DeclStmt::decl_iterator DI = DS->decl_begin(),
60 DE = DS->decl_end(); DI != DE; ++DI) {
Douglas Gregor038f75a2009-06-15 19:02:54 +000061 Doc.PrintDecl(*DI);
62 }
Mike Stump1eb44332009-09-09 15:08:12 +000063 } else {
Douglas Gregor038f75a2009-06-15 19:02:54 +000064 if (CXXConditionDeclExpr* CCDE = dyn_cast<CXXConditionDeclExpr>(S))
Douglas Gregor038f75a2009-06-15 19:02:54 +000065 Doc.PrintDecl(CCDE->getVarDecl());
Mike Stump1eb44332009-09-09 15:08:12 +000066 for (Stmt::child_iterator i = S->child_begin(), e = S->child_end();
67 i != e; ++i)
Douglas Gregoree75c052009-05-21 20:55:50 +000068 DumpSubTree(*i);
Douglas Gregoree75c052009-05-21 20:55:50 +000069 }
70 Doc.toParent();
71 } else {
72 Doc.addSubNode("NULL").toParent();
73 }
74 }
75
Douglas Gregoree75c052009-05-21 20:55:50 +000076
Douglas Gregor038f75a2009-06-15 19:02:54 +000077#define NODE_XML( CLASS, NAME ) \
78 void Visit##CLASS(CLASS* S) \
79 { \
80 typedef CLASS tStmtType; \
Mike Stump1eb44332009-09-09 15:08:12 +000081 Doc.addSubNode(NAME);
Douglas Gregoree75c052009-05-21 20:55:50 +000082
Mike Stump1eb44332009-09-09 15:08:12 +000083#define ATTRIBUTE_XML( FN, NAME ) Doc.addAttribute(NAME, S->FN);
Douglas Gregor038f75a2009-06-15 19:02:54 +000084#define TYPE_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "type")
Mike Stump1eb44332009-09-09 15:08:12 +000085#define ATTRIBUTE_OPT_XML( FN, NAME ) Doc.addAttributeOptional(NAME, S->FN);
86#define ATTRIBUTE_SPECIAL_XML( FN, NAME ) addSpecialAttribute(NAME, S);
Douglas Gregor038f75a2009-06-15 19:02:54 +000087#define ATTRIBUTE_FILE_LOCATION_XML Doc.addLocationRange(S->getSourceRange());
88
89
90#define ATTRIBUTE_ENUM_XML( FN, NAME ) \
91 { \
92 const char* pAttributeName = NAME; \
93 const bool optional = false; \
94 switch (S->FN) { \
Mike Stump1eb44332009-09-09 15:08:12 +000095 default: assert(0 && "unknown enum value");
Douglas Gregor038f75a2009-06-15 19:02:54 +000096
97#define ATTRIBUTE_ENUM_OPT_XML( FN, NAME ) \
98 { \
99 const char* pAttributeName = NAME; \
100 const bool optional = true; \
101 switch (S->FN) { \
Mike Stump1eb44332009-09-09 15:08:12 +0000102 default: assert(0 && "unknown enum value");
Douglas Gregor038f75a2009-06-15 19:02:54 +0000103
104#define ENUM_XML( VALUE, NAME ) case VALUE: if ((!optional) || NAME[0]) Doc.addAttribute(pAttributeName, NAME); break;
105#define END_ENUM_XML } }
106#define END_NODE_XML }
107
108#define ID_ATTRIBUTE_XML Doc.addAttribute("id", S);
109#define SUB_NODE_XML( CLASS )
110#define SUB_NODE_SEQUENCE_XML( CLASS )
111#define SUB_NODE_OPT_XML( CLASS )
112
113#include "clang/Frontend/StmtXML.def"
114
115#if (0)
Douglas Gregoree75c052009-05-21 20:55:50 +0000116 // Stmts.
117 void VisitStmt(Stmt *Node);
118 void VisitDeclStmt(DeclStmt *Node);
119 void VisitLabelStmt(LabelStmt *Node);
120 void VisitGotoStmt(GotoStmt *Node);
Mike Stump1eb44332009-09-09 15:08:12 +0000121
Douglas Gregoree75c052009-05-21 20:55:50 +0000122 // Exprs
123 void VisitExpr(Expr *Node);
124 void VisitDeclRefExpr(DeclRefExpr *Node);
125 void VisitPredefinedExpr(PredefinedExpr *Node);
126 void VisitCharacterLiteral(CharacterLiteral *Node);
127 void VisitIntegerLiteral(IntegerLiteral *Node);
128 void VisitFloatingLiteral(FloatingLiteral *Node);
129 void VisitStringLiteral(StringLiteral *Str);
130 void VisitUnaryOperator(UnaryOperator *Node);
131 void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node);
132 void VisitMemberExpr(MemberExpr *Node);
133 void VisitExtVectorElementExpr(ExtVectorElementExpr *Node);
134 void VisitBinaryOperator(BinaryOperator *Node);
135 void VisitCompoundAssignOperator(CompoundAssignOperator *Node);
136 void VisitAddrLabelExpr(AddrLabelExpr *Node);
137 void VisitTypesCompatibleExpr(TypesCompatibleExpr *Node);
138
139 // C++
140 void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
141 void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node);
142 void VisitCXXThisExpr(CXXThisExpr *Node);
143 void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node);
Mike Stump1eb44332009-09-09 15:08:12 +0000144
Douglas Gregoree75c052009-05-21 20:55:50 +0000145 // ObjC
146 void VisitObjCEncodeExpr(ObjCEncodeExpr *Node);
147 void VisitObjCMessageExpr(ObjCMessageExpr* Node);
148 void VisitObjCSelectorExpr(ObjCSelectorExpr *Node);
149 void VisitObjCProtocolExpr(ObjCProtocolExpr *Node);
150 void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node);
Fariborz Jahanian09105f52009-08-20 17:02:02 +0000151 void VisitObjCImplicitSetterGetterRefExpr(
152 ObjCImplicitSetterGetterRefExpr *Node);
Douglas Gregoree75c052009-05-21 20:55:50 +0000153 void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
154 void VisitObjCSuperExpr(ObjCSuperExpr *Node);
Douglas Gregor038f75a2009-06-15 19:02:54 +0000155#endif
Douglas Gregoree75c052009-05-21 20:55:50 +0000156 };
157}
158
159//===----------------------------------------------------------------------===//
160// Stmt printing methods.
161//===----------------------------------------------------------------------===//
Douglas Gregor038f75a2009-06-15 19:02:54 +0000162#if (0)
Mike Stump1eb44332009-09-09 15:08:12 +0000163void StmtXML::VisitStmt(Stmt *Node) {
Douglas Gregoree75c052009-05-21 20:55:50 +0000164 // nothing special to do
165}
166
Mike Stump1eb44332009-09-09 15:08:12 +0000167void StmtXML::VisitDeclStmt(DeclStmt *Node) {
Douglas Gregoree75c052009-05-21 20:55:50 +0000168 for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end();
Mike Stump1eb44332009-09-09 15:08:12 +0000169 DI != DE; ++DI) {
Douglas Gregoree75c052009-05-21 20:55:50 +0000170 Doc.PrintDecl(*DI);
171 }
172}
173
Mike Stump1eb44332009-09-09 15:08:12 +0000174void StmtXML::VisitLabelStmt(LabelStmt *Node) {
Douglas Gregoree75c052009-05-21 20:55:50 +0000175 Doc.addAttribute("name", Node->getName());
176}
177
Mike Stump1eb44332009-09-09 15:08:12 +0000178void StmtXML::VisitGotoStmt(GotoStmt *Node) {
Douglas Gregoree75c052009-05-21 20:55:50 +0000179 Doc.addAttribute("name", Node->getLabel()->getName());
180}
181
182//===----------------------------------------------------------------------===//
183// Expr printing methods.
184//===----------------------------------------------------------------------===//
185
186void StmtXML::VisitExpr(Expr *Node) {
187 DumpExpr(Node);
188}
189
190void StmtXML::VisitDeclRefExpr(DeclRefExpr *Node) {
191 DumpExpr(Node);
192
193 const char* pKind;
194 switch (Node->getDecl()->getKind()) {
195 case Decl::Function: pKind = "FunctionDecl"; break;
196 case Decl::Var: pKind = "Var"; break;
197 case Decl::ParmVar: pKind = "ParmVar"; break;
198 case Decl::EnumConstant: pKind = "EnumConstant"; break;
199 case Decl::Typedef: pKind = "Typedef"; break;
200 case Decl::Record: pKind = "Record"; break;
201 case Decl::Enum: pKind = "Enum"; break;
202 case Decl::CXXRecord: pKind = "CXXRecord"; break;
203 case Decl::ObjCInterface: pKind = "ObjCInterface"; break;
204 case Decl::ObjCClass: pKind = "ObjCClass"; break;
205 default: pKind = "Decl"; break;
206 }
207
208 Doc.addAttribute("kind", pKind);
209 Doc.addAttribute("name", Node->getDecl()->getNameAsString());
210 Doc.addRefAttribute(Node->getDecl());
211}
212
213void StmtXML::VisitPredefinedExpr(PredefinedExpr *Node) {
214 DumpExpr(Node);
215 switch (Node->getIdentType()) {
216 default: assert(0 && "unknown case");
217 case PredefinedExpr::Func: Doc.addAttribute("predefined", " __func__"); break;
218 case PredefinedExpr::Function: Doc.addAttribute("predefined", " __FUNCTION__"); break;
219 case PredefinedExpr::PrettyFunction: Doc.addAttribute("predefined", " __PRETTY_FUNCTION__");break;
220 }
221}
222
223void StmtXML::VisitCharacterLiteral(CharacterLiteral *Node) {
224 DumpExpr(Node);
225 Doc.addAttribute("value", Node->getValue());
226}
227
228void StmtXML::VisitIntegerLiteral(IntegerLiteral *Node) {
229 DumpExpr(Node);
230 bool isSigned = Node->getType()->isSignedIntegerType();
231 Doc.addAttribute("value", Node->getValue().toString(10, isSigned));
232}
233
234void StmtXML::VisitFloatingLiteral(FloatingLiteral *Node) {
235 DumpExpr(Node);
236 // FIXME: output float as written in source (no approximation or the like)
237 //Doc.addAttribute("value", Node->getValueAsApproximateDouble()));
238 Doc.addAttribute("value", "FIXME");
239}
240
241void StmtXML::VisitStringLiteral(StringLiteral *Str) {
242 DumpExpr(Str);
243 if (Str->isWide())
244 Doc.addAttribute("is_wide", "1");
245
246 Doc.addAttribute("value", Doc.escapeString(Str->getStrData(), Str->getByteLength()));
247}
248
249
250const char *StmtXML::getOpcodeStr(UnaryOperator::Opcode Op) {
251 switch (Op) {
252 default: assert(0 && "Unknown unary operator");
253 case UnaryOperator::PostInc: return "postinc";
254 case UnaryOperator::PostDec: return "postdec";
255 case UnaryOperator::PreInc: return "preinc";
256 case UnaryOperator::PreDec: return "predec";
257 case UnaryOperator::AddrOf: return "addrof";
258 case UnaryOperator::Deref: return "deref";
259 case UnaryOperator::Plus: return "plus";
260 case UnaryOperator::Minus: return "minus";
261 case UnaryOperator::Not: return "not";
262 case UnaryOperator::LNot: return "lnot";
263 case UnaryOperator::Real: return "__real";
264 case UnaryOperator::Imag: return "__imag";
265 case UnaryOperator::Extension: return "__extension__";
266 case UnaryOperator::OffsetOf: return "__builtin_offsetof";
267 }
268}
269
270
271const char *StmtXML::getOpcodeStr(BinaryOperator::Opcode Op) {
272 switch (Op) {
273 default: assert(0 && "Unknown binary operator");
274 case BinaryOperator::PtrMemD: return "ptrmemd";
275 case BinaryOperator::PtrMemI: return "ptrmemi";
276 case BinaryOperator::Mul: return "mul";
277 case BinaryOperator::Div: return "div";
278 case BinaryOperator::Rem: return "rem";
279 case BinaryOperator::Add: return "add";
280 case BinaryOperator::Sub: return "sub";
281 case BinaryOperator::Shl: return "shl";
282 case BinaryOperator::Shr: return "shr";
283 case BinaryOperator::LT: return "lt";
284 case BinaryOperator::GT: return "gt";
285 case BinaryOperator::LE: return "le";
286 case BinaryOperator::GE: return "ge";
287 case BinaryOperator::EQ: return "eq";
288 case BinaryOperator::NE: return "ne";
289 case BinaryOperator::And: return "and";
290 case BinaryOperator::Xor: return "xor";
291 case BinaryOperator::Or: return "or";
292 case BinaryOperator::LAnd: return "land";
293 case BinaryOperator::LOr: return "lor";
294 case BinaryOperator::Assign: return "assign";
295 case BinaryOperator::MulAssign: return "mulassign";
296 case BinaryOperator::DivAssign: return "divassign";
297 case BinaryOperator::RemAssign: return "remassign";
298 case BinaryOperator::AddAssign: return "addassign";
299 case BinaryOperator::SubAssign: return "subassign";
300 case BinaryOperator::ShlAssign: return "shlassign";
301 case BinaryOperator::ShrAssign: return "shrassign";
302 case BinaryOperator::AndAssign: return "andassign";
303 case BinaryOperator::XorAssign: return "xorassign";
304 case BinaryOperator::OrAssign: return "orassign";
305 case BinaryOperator::Comma: return "comma";
306 }
307}
308
309void StmtXML::VisitUnaryOperator(UnaryOperator *Node) {
310 DumpExpr(Node);
311 Doc.addAttribute("op_code", getOpcodeStr(Node->getOpcode()));
312}
313
314void StmtXML::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
315 DumpExpr(Node);
316 Doc.addAttribute("is_sizeof", Node->isSizeOf() ? "sizeof" : "alignof");
317 Doc.addAttribute("is_type", Node->isArgumentType() ? "1" : "0");
318 if (Node->isArgumentType())
Douglas Gregoree75c052009-05-21 20:55:50 +0000319 DumpTypeExpr(Node->getArgumentType());
Douglas Gregoree75c052009-05-21 20:55:50 +0000320}
321
322void StmtXML::VisitMemberExpr(MemberExpr *Node) {
323 DumpExpr(Node);
324 Doc.addAttribute("is_deref", Node->isArrow() ? "1" : "0");
325 Doc.addAttribute("name", Node->getMemberDecl()->getNameAsString());
326 Doc.addRefAttribute(Node->getMemberDecl());
327}
328
329void StmtXML::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
330 DumpExpr(Node);
331 Doc.addAttribute("name", Node->getAccessor().getName());
332}
333
334void StmtXML::VisitBinaryOperator(BinaryOperator *Node) {
335 DumpExpr(Node);
336 Doc.addAttribute("op_code", getOpcodeStr(Node->getOpcode()));
337}
338
339void StmtXML::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
340 VisitBinaryOperator(Node);
341/* FIXME: is this needed in the AST?
342 DumpExpr(Node);
343 CurrentNode = CurrentNode->addSubNode("ComputeLHSTy");
344 DumpType(Node->getComputationLHSType());
345 CurrentNode = CurrentNode->Parent->addSubNode("ComputeResultTy");
346 DumpType(Node->getComputationResultType());
347 Doc.toParent();
348*/
349}
350
351// GNU extensions.
352
353void StmtXML::VisitAddrLabelExpr(AddrLabelExpr *Node) {
354 DumpExpr(Node);
355 Doc.addAttribute("name", Node->getLabel()->getName());
356}
357
358void StmtXML::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
359 DumpExpr(Node);
360 DumpTypeExpr(Node->getArgType1());
361 DumpTypeExpr(Node->getArgType2());
362}
363
364//===----------------------------------------------------------------------===//
365// C++ Expressions
366//===----------------------------------------------------------------------===//
367
368void StmtXML::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
369 DumpExpr(Node);
370 Doc.addAttribute("kind", Node->getCastName());
371 DumpTypeExpr(Node->getTypeAsWritten());
372}
373
374void StmtXML::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
375 DumpExpr(Node);
376 Doc.addAttribute("value", Node->getValue() ? "true" : "false");
377}
378
379void StmtXML::VisitCXXThisExpr(CXXThisExpr *Node) {
380 DumpExpr(Node);
381}
382
383void StmtXML::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
384 DumpExpr(Node);
385 DumpTypeExpr(Node->getTypeAsWritten());
386}
387
388//===----------------------------------------------------------------------===//
389// Obj-C Expressions
390//===----------------------------------------------------------------------===//
391
392void StmtXML::VisitObjCMessageExpr(ObjCMessageExpr* Node) {
393 DumpExpr(Node);
394 Doc.addAttribute("selector", Node->getSelector().getAsString());
395 IdentifierInfo* clsName = Node->getClassName();
Mike Stump1eb44332009-09-09 15:08:12 +0000396 if (clsName)
Douglas Gregoree75c052009-05-21 20:55:50 +0000397 Doc.addAttribute("class", clsName->getName());
398}
399
400void StmtXML::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
401 DumpExpr(Node);
402 DumpTypeExpr(Node->getEncodedType());
403}
404
405void StmtXML::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
406 DumpExpr(Node);
407 Doc.addAttribute("selector", Node->getSelector().getAsString());
408}
409
410void StmtXML::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
411 DumpExpr(Node);
412 Doc.addAttribute("protocol", Node->getProtocol()->getNameAsString());
413}
414
415void StmtXML::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
416 DumpExpr(Node);
417 Doc.addAttribute("property", Node->getProperty()->getNameAsString());
418}
419
Fariborz Jahanian09105f52009-08-20 17:02:02 +0000420void StmtXML::VisitObjCImplicitSetterGetterRefExpr(
421 ObjCImplicitSetterGetterRefExpr *Node) {
Douglas Gregoree75c052009-05-21 20:55:50 +0000422 DumpExpr(Node);
423 ObjCMethodDecl *Getter = Node->getGetterMethod();
424 ObjCMethodDecl *Setter = Node->getSetterMethod();
425 Doc.addAttribute("Getter", Getter->getSelector().getAsString());
426 Doc.addAttribute("Setter", Setter ? Setter->getSelector().getAsString().c_str() : "(null)");
427}
428
429void StmtXML::VisitObjCSuperExpr(ObjCSuperExpr *Node) {
430 DumpExpr(Node);
431 Doc.addAttribute("super", "1");
432}
433
434void StmtXML::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
435 DumpExpr(Node);
436 Doc.addAttribute("kind", Node->getDecl()->getDeclKindName());
437 Doc.addAttribute("decl", Node->getDecl()->getNameAsString());
438 if (Node->isFreeIvar())
439 Doc.addAttribute("isFreeIvar", "1");
440}
Douglas Gregor038f75a2009-06-15 19:02:54 +0000441#endif
Douglas Gregoree75c052009-05-21 20:55:50 +0000442//===----------------------------------------------------------------------===//
443// Stmt method implementations
444//===----------------------------------------------------------------------===//
445
446/// dumpAll - This does a dump of the specified AST fragment and all subtrees.
447void DocumentXML::PrintStmt(const Stmt *S) {
448 StmtXML P(*this);
449 P.DumpSubTree(const_cast<Stmt*>(S));
450}
451