1 //===--- StmtXML.cpp - XML implementation for Stmt ASTs ------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the Stmt::dumpXML methods, which dump out the
11 // AST to an XML document.
13 //===----------------------------------------------------------------------===//
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 using namespace clang
;
22 //===----------------------------------------------------------------------===//
24 //===----------------------------------------------------------------------===//
27 class StmtXML
: public StmtVisitor
<StmtXML
> {
30 //static const char *getOpcodeStr(UnaryOperator::Opcode Op);
31 //static const char *getOpcodeStr(BinaryOperator::Opcode Op);
34 void addSpecialAttribute(const char* pName
, StringLiteral
* Str
) {
35 Doc
.addAttribute(pName
, Doc
.escapeString(Str
->getString().data(),
36 Str
->getString().size()));
39 void addSpecialAttribute(const char* pName
, SizeOfAlignOfExpr
* S
) {
40 if (S
->isArgumentType())
41 Doc
.addAttribute(pName
, S
->getArgumentType());
44 void addSpecialAttribute(const char* pName
, CXXTypeidExpr
* S
) {
45 if (S
->isTypeOperand())
46 Doc
.addAttribute(pName
, S
->getTypeOperand());
51 StmtXML(DocumentXML
& doc
)
55 void DumpSubTree(Stmt
*S
) {
58 if (DeclStmt
* DS
= dyn_cast
<DeclStmt
>(S
)) {
59 for (DeclStmt::decl_iterator DI
= DS
->decl_begin(),
60 DE
= DS
->decl_end(); DI
!= DE
; ++DI
) {
64 for (Stmt::child_range i
= S
->children(); i
; ++i
)
69 Doc
.addSubNode("NULL").toParent();
74 #define NODE_XML( CLASS, NAME ) \
75 void Visit##CLASS(CLASS* S) \
77 typedef CLASS tStmtType; \
80 #define ATTRIBUTE_XML( FN, NAME ) Doc.addAttribute(NAME, S->FN);
81 #define TYPE_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "type")
82 #define ATTRIBUTE_OPT_XML( FN, NAME ) Doc.addAttributeOptional(NAME, S->FN);
83 #define ATTRIBUTE_SPECIAL_XML( FN, NAME ) addSpecialAttribute(NAME, S);
84 #define ATTRIBUTE_FILE_LOCATION_XML Doc.addLocationRange(S->getSourceRange());
87 #define ATTRIBUTE_ENUM_XML( FN, NAME ) \
89 const char* pAttributeName = NAME; \
90 const bool optional = false; \
92 default: assert(0 && "unknown enum value");
94 #define ATTRIBUTE_ENUM_OPT_XML( FN, NAME ) \
96 const char* pAttributeName = NAME; \
97 const bool optional = true; \
99 default: assert(0 && "unknown enum value");
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 }
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 )
110 #include "clang/Frontend/StmtXML.def"
114 void VisitStmt(Stmt
*Node
);
115 void VisitDeclStmt(DeclStmt
*Node
);
116 void VisitLabelStmt(LabelStmt
*Node
);
117 void VisitGotoStmt(GotoStmt
*Node
);
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
);
128 void VisitOffsetOfExpr(OffsetOfExpr
*Node
);
129 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
);
137 void VisitCXXNamedCastExpr(CXXNamedCastExpr
*Node
);
138 void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr
*Node
);
139 void VisitCXXThisExpr(CXXThisExpr
*Node
);
140 void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr
*Node
);
143 void VisitObjCEncodeExpr(ObjCEncodeExpr
*Node
);
144 void VisitObjCMessageExpr(ObjCMessageExpr
* Node
);
145 void VisitObjCSelectorExpr(ObjCSelectorExpr
*Node
);
146 void VisitObjCProtocolExpr(ObjCProtocolExpr
*Node
);
147 void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr
*Node
);
148 void VisitObjCImplicitSetterGetterRefExpr(
149 ObjCImplicitSetterGetterRefExpr
*Node
);
150 void VisitObjCIvarRefExpr(ObjCIvarRefExpr
*Node
);
155 //===----------------------------------------------------------------------===//
156 // Stmt printing methods.
157 //===----------------------------------------------------------------------===//
159 void StmtXML::VisitStmt(Stmt
*Node
) {
160 // nothing special to do
163 void StmtXML::VisitDeclStmt(DeclStmt
*Node
) {
164 for (DeclStmt::decl_iterator DI
= Node
->decl_begin(), DE
= Node
->decl_end();
170 void StmtXML::VisitLabelStmt(LabelStmt
*Node
) {
171 Doc
.addAttribute("name", Node
->getName());
174 void StmtXML::VisitGotoStmt(GotoStmt
*Node
) {
175 Doc
.addAttribute("name", Node
->getLabel()->getName());
178 //===----------------------------------------------------------------------===//
179 // Expr printing methods.
180 //===----------------------------------------------------------------------===//
182 void StmtXML::VisitExpr(Expr
*Node
) {
186 void StmtXML::VisitDeclRefExpr(DeclRefExpr
*Node
) {
190 switch (Node
->getDecl()->getKind()) {
191 case Decl::Function
: pKind
= "FunctionDecl"; break;
192 case Decl::Var
: pKind
= "Var"; break;
193 case Decl::ParmVar
: pKind
= "ParmVar"; break;
194 case Decl::EnumConstant
: pKind
= "EnumConstant"; break;
195 case Decl::Typedef
: pKind
= "Typedef"; break;
196 case Decl::Record
: pKind
= "Record"; break;
197 case Decl::Enum
: pKind
= "Enum"; break;
198 case Decl::CXXRecord
: pKind
= "CXXRecord"; break;
199 case Decl::ObjCInterface
: pKind
= "ObjCInterface"; break;
200 case Decl::ObjCClass
: pKind
= "ObjCClass"; break;
201 default: pKind
= "Decl"; break;
204 Doc
.addAttribute("kind", pKind
);
205 Doc
.addAttribute("name", Node
->getDecl()->getNameAsString());
206 Doc
.addRefAttribute(Node
->getDecl());
209 void StmtXML::VisitPredefinedExpr(PredefinedExpr
*Node
) {
211 switch (Node
->getIdentType()) {
212 default: assert(0 && "unknown case");
213 case PredefinedExpr::Func
: Doc
.addAttribute("predefined", " __func__"); break;
214 case PredefinedExpr::Function
: Doc
.addAttribute("predefined", " __FUNCTION__"); break;
215 case PredefinedExpr::PrettyFunction
: Doc
.addAttribute("predefined", " __PRETTY_FUNCTION__");break;
219 void StmtXML::VisitCharacterLiteral(CharacterLiteral
*Node
) {
221 Doc
.addAttribute("value", Node
->getValue());
224 void StmtXML::VisitIntegerLiteral(IntegerLiteral
*Node
) {
226 bool isSigned
= Node
->getType()->isSignedIntegerType();
227 Doc
.addAttribute("value", Node
->getValue().toString(10, isSigned
));
230 void StmtXML::VisitFloatingLiteral(FloatingLiteral
*Node
) {
232 // FIXME: output float as written in source (no approximation or the like)
233 //Doc.addAttribute("value", Node->getValueAsApproximateDouble()));
234 Doc
.addAttribute("value", "FIXME");
237 void StmtXML::VisitStringLiteral(StringLiteral
*Str
) {
240 Doc
.addAttribute("is_wide", "1");
242 Doc
.addAttribute("value", Doc
.escapeString(Str
->getStrData(), Str
->getByteLength()));
246 const char *StmtXML::getOpcodeStr(UnaryOperator::Opcode Op
) {
248 default: assert(0 && "Unknown unary operator");
249 case UnaryOperator::PostInc
: return "postinc";
250 case UnaryOperator::PostDec
: return "postdec";
251 case UnaryOperator::PreInc
: return "preinc";
252 case UnaryOperator::PreDec
: return "predec";
253 case UnaryOperator::AddrOf
: return "addrof";
254 case UnaryOperator::Deref
: return "deref";
255 case UnaryOperator::Plus
: return "plus";
256 case UnaryOperator::Minus
: return "minus";
257 case UnaryOperator::Not
: return "not";
258 case UnaryOperator::LNot
: return "lnot";
259 case UnaryOperator::Real
: return "__real";
260 case UnaryOperator::Imag
: return "__imag";
261 case UnaryOperator::Extension
: return "__extension__";
266 const char *StmtXML::getOpcodeStr(BinaryOperator::Opcode Op
) {
268 default: assert(0 && "Unknown binary operator");
269 case BinaryOperator::PtrMemD
: return "ptrmemd";
270 case BinaryOperator::PtrMemI
: return "ptrmemi";
271 case BinaryOperator::Mul
: return "mul";
272 case BinaryOperator::Div
: return "div";
273 case BinaryOperator::Rem
: return "rem";
274 case BinaryOperator::Add
: return "add";
275 case BinaryOperator::Sub
: return "sub";
276 case BinaryOperator::Shl
: return "shl";
277 case BinaryOperator::Shr
: return "shr";
278 case BinaryOperator::LT
: return "lt";
279 case BinaryOperator::GT
: return "gt";
280 case BinaryOperator::LE
: return "le";
281 case BinaryOperator::GE
: return "ge";
282 case BinaryOperator::EQ
: return "eq";
283 case BinaryOperator::NE
: return "ne";
284 case BinaryOperator::And
: return "and";
285 case BinaryOperator::Xor
: return "xor";
286 case BinaryOperator::Or
: return "or";
287 case BinaryOperator::LAnd
: return "land";
288 case BinaryOperator::LOr
: return "lor";
289 case BinaryOperator::Assign
: return "assign";
290 case BinaryOperator::MulAssign
: return "mulassign";
291 case BinaryOperator::DivAssign
: return "divassign";
292 case BinaryOperator::RemAssign
: return "remassign";
293 case BinaryOperator::AddAssign
: return "addassign";
294 case BinaryOperator::SubAssign
: return "subassign";
295 case BinaryOperator::ShlAssign
: return "shlassign";
296 case BinaryOperator::ShrAssign
: return "shrassign";
297 case BinaryOperator::AndAssign
: return "andassign";
298 case BinaryOperator::XorAssign
: return "xorassign";
299 case BinaryOperator::OrAssign
: return "orassign";
300 case BinaryOperator::Comma
: return "comma";
304 void StmtXML::VisitUnaryOperator(UnaryOperator
*Node
) {
306 Doc
.addAttribute("op_code", getOpcodeStr(Node
->getOpcode()));
309 void StmtXML::OffsetOfExpr(OffsetOfExpr
*Node
) {
313 void StmtXML::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr
*Node
) {
315 Doc
.addAttribute("is_sizeof", Node
->isSizeOf() ? "sizeof" : "alignof");
316 Doc
.addAttribute("is_type", Node
->isArgumentType() ? "1" : "0");
317 if (Node
->isArgumentType())
318 DumpTypeExpr(Node
->getArgumentType());
321 void StmtXML::VisitMemberExpr(MemberExpr
*Node
) {
323 Doc
.addAttribute("is_deref", Node
->isArrow() ? "1" : "0");
324 Doc
.addAttribute("name", Node
->getMemberDecl()->getNameAsString());
325 Doc
.addRefAttribute(Node
->getMemberDecl());
328 void StmtXML::VisitExtVectorElementExpr(ExtVectorElementExpr
*Node
) {
330 Doc
.addAttribute("name", Node
->getAccessor().getName());
333 void StmtXML::VisitBinaryOperator(BinaryOperator
*Node
) {
335 Doc
.addAttribute("op_code", getOpcodeStr(Node
->getOpcode()));
338 void StmtXML::VisitCompoundAssignOperator(CompoundAssignOperator
*Node
) {
339 VisitBinaryOperator(Node
);
340 /* FIXME: is this needed in the AST?
342 CurrentNode = CurrentNode->addSubNode("ComputeLHSTy");
343 DumpType(Node->getComputationLHSType());
344 CurrentNode = CurrentNode->Parent->addSubNode("ComputeResultTy");
345 DumpType(Node->getComputationResultType());
352 void StmtXML::VisitAddrLabelExpr(AddrLabelExpr
*Node
) {
354 Doc
.addAttribute("name", Node
->getLabel()->getName());
357 //===----------------------------------------------------------------------===//
359 //===----------------------------------------------------------------------===//
361 void StmtXML::VisitCXXNamedCastExpr(CXXNamedCastExpr
*Node
) {
363 Doc
.addAttribute("kind", Node
->getCastName());
364 DumpTypeExpr(Node
->getTypeAsWritten());
367 void StmtXML::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr
*Node
) {
369 Doc
.addAttribute("value", Node
->getValue() ? "true" : "false");
372 void StmtXML::VisitCXXThisExpr(CXXThisExpr
*Node
) {
376 void StmtXML::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr
*Node
) {
378 DumpTypeExpr(Node
->getTypeAsWritten());
381 //===----------------------------------------------------------------------===//
383 //===----------------------------------------------------------------------===//
385 void StmtXML::VisitObjCMessageExpr(ObjCMessageExpr
* Node
) {
387 Doc
.addAttribute("selector", Node
->getSelector().getAsString());
388 IdentifierInfo
* clsName
= Node
->getClassName();
390 Doc
.addAttribute("class", clsName
->getName());
393 void StmtXML::VisitObjCEncodeExpr(ObjCEncodeExpr
*Node
) {
395 DumpTypeExpr(Node
->getEncodedType());
398 void StmtXML::VisitObjCSelectorExpr(ObjCSelectorExpr
*Node
) {
400 Doc
.addAttribute("selector", Node
->getSelector().getAsString());
403 void StmtXML::VisitObjCProtocolExpr(ObjCProtocolExpr
*Node
) {
405 Doc
.addAttribute("protocol", Node
->getProtocol()->getNameAsString());
408 void StmtXML::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr
*Node
) {
410 Doc
.addAttribute("property", Node
->getProperty()->getNameAsString());
413 void StmtXML::VisitObjCImplicitSetterGetterRefExpr(
414 ObjCImplicitSetterGetterRefExpr
*Node
) {
416 ObjCMethodDecl
*Getter
= Node
->getGetterMethod();
417 ObjCMethodDecl
*Setter
= Node
->getSetterMethod();
418 Doc
.addAttribute("Getter", Getter
->getSelector().getAsString());
419 Doc
.addAttribute("Setter", Setter
? Setter
->getSelector().getAsString().c_str() : "(null)");
422 void StmtXML::VisitObjCIvarRefExpr(ObjCIvarRefExpr
*Node
) {
424 Doc
.addAttribute("kind", Node
->getDecl()->getDeclKindName());
425 Doc
.addAttribute("decl", Node
->getDecl()->getNameAsString());
426 if (Node
->isFreeIvar())
427 Doc
.addAttribute("isFreeIvar", "1");
430 //===----------------------------------------------------------------------===//
431 // Stmt method implementations
432 //===----------------------------------------------------------------------===//
434 /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
435 void DocumentXML::PrintStmt(const Stmt
*S
) {
437 P
.DumpSubTree(const_cast<Stmt
*>(S
));