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