1 //===--- DumpXML.cpp - Detailed XML dumping ---------------------*- C++ -*-===//
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 defines the Decl::dumpXML() method, a debugging tool to
11 // print a detailed graph of an AST in an unspecified XML format.
12 //
13 // There is no guarantee of stability for this format.
14 //
15 //===----------------------------------------------------------------------===//
16
17 // Only pay for this in code size in assertions-enabled builds.
18
19 #include "clang/AST/ASTContext.h"
20 #include "clang/AST/Decl.h"
21 #include "clang/AST/DeclCXX.h"
22 #include "clang/AST/DeclFriend.h"
23 #include "clang/AST/DeclObjC.h"
24 #include "clang/AST/DeclTemplate.h"
25 #include "clang/AST/DeclVisitor.h"
26 #include "clang/AST/Expr.h"
27 #include "clang/AST/ExprCXX.h"
28 #include "clang/AST/ExprObjC.h"
29 #include "clang/AST/NestedNameSpecifier.h"
30 #include "clang/AST/Stmt.h"
31 #include "clang/AST/StmtCXX.h"
32 #include "clang/AST/StmtObjC.h"
33 #include "clang/AST/StmtVisitor.h"
34 #include "clang/AST/TemplateBase.h"
35 #include "clang/AST/TemplateName.h"
36 #include "clang/AST/Type.h"
37 #include "clang/AST/TypeLoc.h"
38 #include "clang/AST/TypeLocVisitor.h"
39 #include "clang/AST/TypeVisitor.h"
40 #include "clang/AST/Expr.h"
41 #include "clang/AST/ExprCXX.h"
42 #include "llvm/ADT/SmallString.h"
43
44 using namespace clang;
45
46 #ifndef NDEBUG
47
48 namespace {
49
50 enum NodeState {
51 NS_Attrs, NS_LazyChildren, NS_Children
52 };
53
54 struct Node {
55 StringRef Name;
56 NodeState State;
Node__anonf6b4be7e0111::Node57 Node(StringRef name) : Name(name), State(NS_Attrs) {}
58
isDoneWithAttrs__anonf6b4be7e0111::Node59 bool isDoneWithAttrs() const { return State != NS_Attrs; }
60 };
61
62 template <class Impl> struct XMLDeclVisitor {
63 #define DISPATCH(NAME, CLASS) \
64 static_cast<Impl*>(this)->NAME(static_cast<CLASS*>(D))
65
dispatch__anonf6b4be7e0111::XMLDeclVisitor66 void dispatch(Decl *D) {
67 switch (D->getKind()) {
68 #define DECL(DERIVED, BASE) \
69 case Decl::DERIVED: \
70 DISPATCH(dispatch##DERIVED##DeclAttrs, DERIVED##Decl); \
71 static_cast<Impl*>(this)->completeAttrs(); \
72 DISPATCH(dispatch##DERIVED##DeclChildren, DERIVED##Decl); \
73 DISPATCH(dispatch##DERIVED##DeclAsContext, DERIVED##Decl); \
74 break;
75 #define ABSTRACT_DECL(DECL)
76 #include "clang/AST/DeclNodes.inc"
77 }
78 }
79
80 #define DECL(DERIVED, BASE) \
81 void dispatch##DERIVED##DeclAttrs(DERIVED##Decl *D) { \
82 DISPATCH(dispatch##BASE##Attrs, BASE); \
83 DISPATCH(visit##DERIVED##DeclAttrs, DERIVED##Decl); \
84 } \
85 void visit##DERIVED##DeclAttrs(DERIVED##Decl *D) {} \
86 void dispatch##DERIVED##DeclChildren(DERIVED##Decl *D) { \
87 DISPATCH(dispatch##BASE##Children, BASE); \
88 DISPATCH(visit##DERIVED##DeclChildren, DERIVED##Decl); \
89 } \
90 void visit##DERIVED##DeclChildren(DERIVED##Decl *D) {} \
91 void dispatch##DERIVED##DeclAsContext(DERIVED##Decl *D) { \
92 DISPATCH(dispatch##BASE##AsContext, BASE); \
93 DISPATCH(visit##DERIVED##DeclAsContext, DERIVED##Decl); \
94 } \
95 void visit##DERIVED##DeclAsContext(DERIVED##Decl *D) {}
96 #include "clang/AST/DeclNodes.inc"
97
dispatchDeclAttrs__anonf6b4be7e0111::XMLDeclVisitor98 void dispatchDeclAttrs(Decl *D) {
99 DISPATCH(visitDeclAttrs, Decl);
100 }
visitDeclAttrs__anonf6b4be7e0111::XMLDeclVisitor101 void visitDeclAttrs(Decl *D) {}
102
dispatchDeclChildren__anonf6b4be7e0111::XMLDeclVisitor103 void dispatchDeclChildren(Decl *D) {
104 DISPATCH(visitDeclChildren, Decl);
105 }
visitDeclChildren__anonf6b4be7e0111::XMLDeclVisitor106 void visitDeclChildren(Decl *D) {}
107
dispatchDeclAsContext__anonf6b4be7e0111::XMLDeclVisitor108 void dispatchDeclAsContext(Decl *D) {
109 DISPATCH(visitDeclAsContext, Decl);
110 }
visitDeclAsContext__anonf6b4be7e0111::XMLDeclVisitor111 void visitDeclAsContext(Decl *D) {}
112
113 #undef DISPATCH
114 };
115
116 template <class Impl> struct XMLTypeVisitor {
117 #define DISPATCH(NAME, CLASS) \
118 static_cast<Impl*>(this)->NAME(static_cast<CLASS*>(T))
119
dispatch__anonf6b4be7e0111::XMLTypeVisitor120 void dispatch(Type *T) {
121 switch (T->getTypeClass()) {
122 #define TYPE(DERIVED, BASE) \
123 case Type::DERIVED: \
124 DISPATCH(dispatch##DERIVED##TypeAttrs, DERIVED##Type); \
125 static_cast<Impl*>(this)->completeAttrs(); \
126 DISPATCH(dispatch##DERIVED##TypeChildren, DERIVED##Type); \
127 break;
128 #define ABSTRACT_TYPE(DERIVED, BASE)
129 #include "clang/AST/TypeNodes.def"
130 }
131 }
132
133 #define TYPE(DERIVED, BASE) \
134 void dispatch##DERIVED##TypeAttrs(DERIVED##Type *T) { \
135 DISPATCH(dispatch##BASE##Attrs, BASE); \
136 DISPATCH(visit##DERIVED##TypeAttrs, DERIVED##Type); \
137 } \
138 void visit##DERIVED##TypeAttrs(DERIVED##Type *T) {} \
139 void dispatch##DERIVED##TypeChildren(DERIVED##Type *T) { \
140 DISPATCH(dispatch##BASE##Children, BASE); \
141 DISPATCH(visit##DERIVED##TypeChildren, DERIVED##Type); \
142 } \
143 void visit##DERIVED##TypeChildren(DERIVED##Type *T) {}
144 #include "clang/AST/TypeNodes.def"
145
dispatchTypeAttrs__anonf6b4be7e0111::XMLTypeVisitor146 void dispatchTypeAttrs(Type *T) {
147 DISPATCH(visitTypeAttrs, Type);
148 }
visitTypeAttrs__anonf6b4be7e0111::XMLTypeVisitor149 void visitTypeAttrs(Type *T) {}
150
dispatchTypeChildren__anonf6b4be7e0111::XMLTypeVisitor151 void dispatchTypeChildren(Type *T) {
152 DISPATCH(visitTypeChildren, Type);
153 }
visitTypeChildren__anonf6b4be7e0111::XMLTypeVisitor154 void visitTypeChildren(Type *T) {}
155
156 #undef DISPATCH
157 };
158
getTypeKindName(Type * T)159 static StringRef getTypeKindName(Type *T) {
160 switch (T->getTypeClass()) {
161 #define TYPE(DERIVED, BASE) case Type::DERIVED: return #DERIVED "Type";
162 #define ABSTRACT_TYPE(DERIVED, BASE)
163 #include "clang/AST/TypeNodes.def"
164 }
165
166 llvm_unreachable("unknown type kind!");
167 }
168
169 struct XMLDumper : public XMLDeclVisitor<XMLDumper>,
170 public XMLTypeVisitor<XMLDumper> {
171 raw_ostream &out;
172 ASTContext &Context;
173 SmallVector<Node, 16> Stack;
174 unsigned Indent;
XMLDumper__anonf6b4be7e0111::XMLDumper175 explicit XMLDumper(raw_ostream &OS, ASTContext &context)
176 : out(OS), Context(context), Indent(0) {}
177
indent__anonf6b4be7e0111::XMLDumper178 void indent() {
179 for (unsigned I = Indent; I; --I)
180 out << ' ';
181 }
182
183 /// Push a new node on the stack.
push__anonf6b4be7e0111::XMLDumper184 void push(StringRef name) {
185 if (!Stack.empty()) {
186 assert(Stack.back().isDoneWithAttrs());
187 if (Stack.back().State == NS_LazyChildren) {
188 Stack.back().State = NS_Children;
189 out << ">\n";
190 }
191 Indent++;
192 indent();
193 }
194 Stack.push_back(Node(name));
195 out << '<' << name;
196 }
197
198 /// Set the given attribute to the given value.
set__anonf6b4be7e0111::XMLDumper199 void set(StringRef attr, StringRef value) {
200 assert(!Stack.empty() && !Stack.back().isDoneWithAttrs());
201 out << ' ' << attr << '=' << '"' << value << '"'; // TODO: quotation
202 }
203
204 /// Finish attributes.
completeAttrs__anonf6b4be7e0111::XMLDumper205 void completeAttrs() {
206 assert(!Stack.empty() && !Stack.back().isDoneWithAttrs());
207 Stack.back().State = NS_LazyChildren;
208 }
209
210 /// Pop a node.
pop__anonf6b4be7e0111::XMLDumper211 void pop() {
212 assert(!Stack.empty() && Stack.back().isDoneWithAttrs());
213 if (Stack.back().State == NS_LazyChildren) {
214 out << "/>\n";
215 } else {
216 indent();
217 out << "</" << Stack.back().Name << ">\n";
218 }
219 if (Stack.size() > 1) Indent--;
220 Stack.pop_back();
221 }
222
223 //---- General utilities -------------------------------------------//
224
setPointer__anonf6b4be7e0111::XMLDumper225 void setPointer(StringRef prop, const void *p) {
226 SmallString<10> buffer;
227 llvm::raw_svector_ostream os(buffer);
228 os << p;
229 os.flush();
230 set(prop, buffer);
231 }
232
setPointer__anonf6b4be7e0111::XMLDumper233 void setPointer(void *p) {
234 setPointer("ptr", p);
235 }
236
setInteger__anonf6b4be7e0111::XMLDumper237 void setInteger(StringRef prop, const llvm::APSInt &v) {
238 set(prop, v.toString(10));
239 }
240
setInteger__anonf6b4be7e0111::XMLDumper241 void setInteger(StringRef prop, unsigned n) {
242 SmallString<10> buffer;
243 llvm::raw_svector_ostream os(buffer);
244 os << n;
245 os.flush();
246 set(prop, buffer);
247 }
248
setFlag__anonf6b4be7e0111::XMLDumper249 void setFlag(StringRef prop, bool flag) {
250 if (flag) set(prop, "true");
251 }
252
setName__anonf6b4be7e0111::XMLDumper253 void setName(DeclarationName Name) {
254 if (!Name)
255 return set("name", "");
256
257 // Common case.
258 if (Name.isIdentifier())
259 return set("name", Name.getAsIdentifierInfo()->getName());
260
261 set("name", Name.getAsString());
262 }
263
264 class TemporaryContainer {
265 XMLDumper &Dumper;
266 public:
TemporaryContainer(XMLDumper & dumper,StringRef name)267 TemporaryContainer(XMLDumper &dumper, StringRef name)
268 : Dumper(dumper) {
269 Dumper.push(name);
270 Dumper.completeAttrs();
271 }
272
~TemporaryContainer()273 ~TemporaryContainer() {
274 Dumper.pop();
275 }
276 };
277
visitTemplateParameters__anonf6b4be7e0111::XMLDumper278 void visitTemplateParameters(TemplateParameterList *L) {
279 push("template_parameters");
280 completeAttrs();
281 for (TemplateParameterList::iterator
282 I = L->begin(), E = L->end(); I != E; ++I)
283 dispatch(*I);
284 pop();
285 }
286
visitTemplateArguments__anonf6b4be7e0111::XMLDumper287 void visitTemplateArguments(const TemplateArgumentList &L) {
288 push("template_arguments");
289 completeAttrs();
290 for (unsigned I = 0, E = L.size(); I != E; ++I)
291 dispatch(L[I]);
292 pop();
293 }
294
295 /// Visits a reference to the given declaration.
visitDeclRef__anonf6b4be7e0111::XMLDumper296 void visitDeclRef(Decl *D) {
297 push(D->getDeclKindName());
298 setPointer("ref", D);
299 completeAttrs();
300 pop();
301 }
visitDeclRef__anonf6b4be7e0111::XMLDumper302 void visitDeclRef(StringRef Name, Decl *D) {
303 TemporaryContainer C(*this, Name);
304 if (D) visitDeclRef(D);
305 }
306
dispatch__anonf6b4be7e0111::XMLDumper307 void dispatch(const TemplateArgument &A) {
308 switch (A.getKind()) {
309 case TemplateArgument::Null: {
310 TemporaryContainer C(*this, "null");
311 break;
312 }
313 case TemplateArgument::Type: {
314 dispatch(A.getAsType());
315 break;
316 }
317 case TemplateArgument::Template:
318 case TemplateArgument::TemplateExpansion:
319 // FIXME: Implement!
320 break;
321
322 case TemplateArgument::Declaration: {
323 if (Decl *D = A.getAsDecl())
324 visitDeclRef(D);
325 break;
326 }
327 case TemplateArgument::Integral: {
328 push("integer");
329 setInteger("value", *A.getAsIntegral());
330 completeAttrs();
331 pop();
332 break;
333 }
334 case TemplateArgument::Expression: {
335 dispatch(A.getAsExpr());
336 break;
337 }
338 case TemplateArgument::Pack: {
339 for (TemplateArgument::pack_iterator P = A.pack_begin(),
340 PEnd = A.pack_end();
341 P != PEnd; ++P)
342 dispatch(*P);
343 break;
344 }
345 }
346 }
347
dispatch__anonf6b4be7e0111::XMLDumper348 void dispatch(const TemplateArgumentLoc &A) {
349 dispatch(A.getArgument());
350 }
351
352 //---- Declarations ------------------------------------------------//
353 // Calls are made in this order:
354 // # Enter a new node.
355 // push("FieldDecl")
356 //
357 // # In this phase, attributes are set on the node.
358 // visitDeclAttrs(D)
359 // visitNamedDeclAttrs(D)
360 // ...
361 // visitFieldDeclAttrs(D)
362 //
363 // # No more attributes after this point.
364 // completeAttrs()
365 //
366 // # Create "header" child nodes, i.e. those which logically
367 // # belong to the declaration itself.
368 // visitDeclChildren(D)
369 // visitNamedDeclChildren(D)
370 // ...
371 // visitFieldDeclChildren(D)
372 //
373 // # Create nodes for the lexical children.
374 // visitDeclAsContext(D)
375 // visitNamedDeclAsContext(D)
376 // ...
377 // visitFieldDeclAsContext(D)
378 //
379 // # Finish the node.
380 // pop();
dispatch__anonf6b4be7e0111::XMLDumper381 void dispatch(Decl *D) {
382 push(D->getDeclKindName());
383 XMLDeclVisitor<XMLDumper>::dispatch(D);
384 pop();
385 }
visitDeclAttrs__anonf6b4be7e0111::XMLDumper386 void visitDeclAttrs(Decl *D) {
387 setPointer(D);
388 }
389
390 /// Visit all the lexical decls in the given context.
visitDeclContext__anonf6b4be7e0111::XMLDumper391 void visitDeclContext(DeclContext *DC) {
392 for (DeclContext::decl_iterator
393 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
394 dispatch(*I);
395
396 // FIXME: point out visible declarations not in lexical context?
397 }
398
399 /// Set the "access" attribute on the current node according to the
400 /// given specifier.
setAccess__anonf6b4be7e0111::XMLDumper401 void setAccess(AccessSpecifier AS) {
402 switch (AS) {
403 case AS_public: return set("access", "public");
404 case AS_protected: return set("access", "protected");
405 case AS_private: return set("access", "private");
406 case AS_none: llvm_unreachable("explicit forbidden access");
407 }
408 }
409
visitRedeclarableAttrs__anonf6b4be7e0111::XMLDumper410 template <class T> void visitRedeclarableAttrs(T *D) {
411 if (T *Prev = D->getPreviousDecl())
412 setPointer("previous", Prev);
413 }
414
415
416 // TranslationUnitDecl
visitTranslationUnitDeclAsContext__anonf6b4be7e0111::XMLDumper417 void visitTranslationUnitDeclAsContext(TranslationUnitDecl *D) {
418 visitDeclContext(D);
419 }
420
421 // LinkageSpecDecl
visitLinkageSpecDeclAttrs__anonf6b4be7e0111::XMLDumper422 void visitLinkageSpecDeclAttrs(LinkageSpecDecl *D) {
423 StringRef lang = "";
424 switch (D->getLanguage()) {
425 case LinkageSpecDecl::lang_c: lang = "C"; break;
426 case LinkageSpecDecl::lang_cxx: lang = "C++"; break;
427 }
428 set("lang", lang);
429 }
visitLinkageSpecDeclAsContext__anonf6b4be7e0111::XMLDumper430 void visitLinkageSpecDeclAsContext(LinkageSpecDecl *D) {
431 visitDeclContext(D);
432 }
433
434 // NamespaceDecl
visitNamespaceDeclAttrs__anonf6b4be7e0111::XMLDumper435 void visitNamespaceDeclAttrs(NamespaceDecl *D) {
436 setFlag("inline", D->isInline());
437 if (!D->isOriginalNamespace())
438 setPointer("original", D->getOriginalNamespace());
439 }
visitNamespaceDeclAsContext__anonf6b4be7e0111::XMLDumper440 void visitNamespaceDeclAsContext(NamespaceDecl *D) {
441 visitDeclContext(D);
442 }
443
444 // NamedDecl
visitNamedDeclAttrs__anonf6b4be7e0111::XMLDumper445 void visitNamedDeclAttrs(NamedDecl *D) {
446 setName(D->getDeclName());
447 }
448
449 // ValueDecl
visitValueDeclChildren__anonf6b4be7e0111::XMLDumper450 void visitValueDeclChildren(ValueDecl *D) {
451 dispatch(D->getType());
452 }
453
454 // DeclaratorDecl
visitDeclaratorDeclChildren__anonf6b4be7e0111::XMLDumper455 void visitDeclaratorDeclChildren(DeclaratorDecl *D) {
456 //dispatch(D->getTypeSourceInfo()->getTypeLoc());
457 }
458
459 // VarDecl
visitVarDeclAttrs__anonf6b4be7e0111::XMLDumper460 void visitVarDeclAttrs(VarDecl *D) {
461 visitRedeclarableAttrs(D);
462 if (D->getStorageClass() != SC_None)
463 set("storage",
464 VarDecl::getStorageClassSpecifierString(D->getStorageClass()));
465 StringRef initStyle = "";
466 switch (D->getInitStyle()) {
467 case VarDecl::CInit: initStyle = "c"; break;
468 case VarDecl::CallInit: initStyle = "call"; break;
469 case VarDecl::ListInit: initStyle = "list"; break;
470 }
471 set("initstyle", initStyle);
472 setFlag("nrvo", D->isNRVOVariable());
473 // TODO: instantiation, etc.
474 }
visitVarDeclChildren__anonf6b4be7e0111::XMLDumper475 void visitVarDeclChildren(VarDecl *D) {
476 if (D->hasInit()) dispatch(D->getInit());
477 }
478
479 // ParmVarDecl?
480
481 // FunctionDecl
visitFunctionDeclAttrs__anonf6b4be7e0111::XMLDumper482 void visitFunctionDeclAttrs(FunctionDecl *D) {
483 visitRedeclarableAttrs(D);
484 setFlag("pure", D->isPure());
485 setFlag("trivial", D->isTrivial());
486 setFlag("returnzero", D->hasImplicitReturnZero());
487 setFlag("prototype", D->hasWrittenPrototype());
488 setFlag("deleted", D->isDeletedAsWritten());
489 if (D->getStorageClass() != SC_None)
490 set("storage",
491 VarDecl::getStorageClassSpecifierString(D->getStorageClass()));
492 setFlag("inline", D->isInlineSpecified());
493 if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>())
494 set("asmlabel", ALA->getLabel());
495 // TODO: instantiation, etc.
496 }
visitFunctionDeclChildren__anonf6b4be7e0111::XMLDumper497 void visitFunctionDeclChildren(FunctionDecl *D) {
498 for (FunctionDecl::param_iterator
499 I = D->param_begin(), E = D->param_end(); I != E; ++I)
500 dispatch(*I);
501 for (llvm::ArrayRef<NamedDecl*>::iterator
502 I = D->getDeclsInPrototypeScope().begin(), E = D->getDeclsInPrototypeScope().end();
503 I != E; ++I)
504 dispatch(*I);
505 if (D->doesThisDeclarationHaveABody())
506 dispatch(D->getBody());
507 }
508
509 // CXXMethodDecl ?
510 // CXXConstructorDecl ?
511 // CXXDestructorDecl ?
512 // CXXConversionDecl ?
513
dispatch__anonf6b4be7e0111::XMLDumper514 void dispatch(CXXCtorInitializer *Init) {
515 // TODO
516 }
517
518 // FieldDecl
visitFieldDeclAttrs__anonf6b4be7e0111::XMLDumper519 void visitFieldDeclAttrs(FieldDecl *D) {
520 setFlag("mutable", D->isMutable());
521 }
visitFieldDeclChildren__anonf6b4be7e0111::XMLDumper522 void visitFieldDeclChildren(FieldDecl *D) {
523 if (D->isBitField()) {
524 TemporaryContainer C(*this, "bitwidth");
525 dispatch(D->getBitWidth());
526 }
527 // TODO: C++0x member initializer
528 }
529
530 // EnumConstantDecl
visitEnumConstantDeclChildren__anonf6b4be7e0111::XMLDumper531 void visitEnumConstantDeclChildren(EnumConstantDecl *D) {
532 // value in any case?
533 if (D->getInitExpr()) dispatch(D->getInitExpr());
534 }
535
536 // IndirectFieldDecl
visitIndirectFieldDeclChildren__anonf6b4be7e0111::XMLDumper537 void visitIndirectFieldDeclChildren(IndirectFieldDecl *D) {
538 for (IndirectFieldDecl::chain_iterator
539 I = D->chain_begin(), E = D->chain_end(); I != E; ++I) {
540 NamedDecl *VD = const_cast<NamedDecl*>(*I);
541 push(isa<VarDecl>(VD) ? "variable" : "field");
542 setPointer("ptr", VD);
543 completeAttrs();
544 pop();
545 }
546 }
547
548 // TypeDecl
visitTypeDeclAttrs__anonf6b4be7e0111::XMLDumper549 void visitTypeDeclAttrs(TypeDecl *D) {
550 setPointer("typeptr", D->getTypeForDecl());
551 }
552
553 // TypedefDecl
visitTypedefDeclAttrs__anonf6b4be7e0111::XMLDumper554 void visitTypedefDeclAttrs(TypedefDecl *D) {
555 visitRedeclarableAttrs<TypedefNameDecl>(D);
556 }
visitTypedefDeclChildren__anonf6b4be7e0111::XMLDumper557 void visitTypedefDeclChildren(TypedefDecl *D) {
558 dispatch(D->getTypeSourceInfo()->getTypeLoc());
559 }
560
561 // TypeAliasDecl
visitTypeAliasDeclAttrs__anonf6b4be7e0111::XMLDumper562 void visitTypeAliasDeclAttrs(TypeAliasDecl *D) {
563 visitRedeclarableAttrs<TypedefNameDecl>(D);
564 }
visitTypeAliasDeclChildren__anonf6b4be7e0111::XMLDumper565 void visitTypeAliasDeclChildren(TypeAliasDecl *D) {
566 dispatch(D->getTypeSourceInfo()->getTypeLoc());
567 }
568
569 // TagDecl
visitTagDeclAttrs__anonf6b4be7e0111::XMLDumper570 void visitTagDeclAttrs(TagDecl *D) {
571 visitRedeclarableAttrs(D);
572 }
visitTagDeclAsContext__anonf6b4be7e0111::XMLDumper573 void visitTagDeclAsContext(TagDecl *D) {
574 visitDeclContext(D);
575 }
576
577 // EnumDecl
visitEnumDeclAttrs__anonf6b4be7e0111::XMLDumper578 void visitEnumDeclAttrs(EnumDecl *D) {
579 setFlag("scoped", D->isScoped());
580 setFlag("fixed", D->isFixed());
581 }
visitEnumDeclChildren__anonf6b4be7e0111::XMLDumper582 void visitEnumDeclChildren(EnumDecl *D) {
583 {
584 TemporaryContainer C(*this, "promotion_type");
585 dispatch(D->getPromotionType());
586 }
587 {
588 TemporaryContainer C(*this, "integer_type");
589 dispatch(D->getIntegerType());
590 }
591 }
592
593 // RecordDecl ?
594
visitCXXRecordDeclChildren__anonf6b4be7e0111::XMLDumper595 void visitCXXRecordDeclChildren(CXXRecordDecl *D) {
596 if (!D->isThisDeclarationADefinition()) return;
597
598 for (CXXRecordDecl::base_class_iterator
599 I = D->bases_begin(), E = D->bases_end(); I != E; ++I) {
600 push("base");
601 setAccess(I->getAccessSpecifier());
602 completeAttrs();
603 dispatch(I->getTypeSourceInfo()->getTypeLoc());
604 pop();
605 }
606 }
607
608 // ClassTemplateSpecializationDecl ?
609
610 // FileScopeAsmDecl ?
611
612 // BlockDecl
visitBlockDeclAttrs__anonf6b4be7e0111::XMLDumper613 void visitBlockDeclAttrs(BlockDecl *D) {
614 setFlag("variadic", D->isVariadic());
615 }
visitBlockDeclChildren__anonf6b4be7e0111::XMLDumper616 void visitBlockDeclChildren(BlockDecl *D) {
617 for (FunctionDecl::param_iterator
618 I = D->param_begin(), E = D->param_end(); I != E; ++I)
619 dispatch(*I);
620 dispatch(D->getBody());
621 }
622
623 // AccessSpecDecl
visitAccessSpecDeclAttrs__anonf6b4be7e0111::XMLDumper624 void visitAccessSpecDeclAttrs(AccessSpecDecl *D) {
625 setAccess(D->getAccess());
626 }
627
628 // TemplateDecl
visitTemplateDeclChildren__anonf6b4be7e0111::XMLDumper629 void visitTemplateDeclChildren(TemplateDecl *D) {
630 visitTemplateParameters(D->getTemplateParameters());
631 if (D->getTemplatedDecl())
632 dispatch(D->getTemplatedDecl());
633 }
634
635 // FunctionTemplateDecl
visitFunctionTemplateDeclAttrs__anonf6b4be7e0111::XMLDumper636 void visitFunctionTemplateDeclAttrs(FunctionTemplateDecl *D) {
637 visitRedeclarableAttrs(D);
638 }
visitFunctionTemplateDeclChildren__anonf6b4be7e0111::XMLDumper639 void visitFunctionTemplateDeclChildren(FunctionTemplateDecl *D) {
640 // Mention all the specializations which don't have explicit
641 // declarations elsewhere.
642 for (FunctionTemplateDecl::spec_iterator
643 I = D->spec_begin(), E = D->spec_end(); I != E; ++I) {
644 FunctionTemplateSpecializationInfo *Info
645 = I->getTemplateSpecializationInfo();
646
647 bool Unknown = false;
648 switch (Info->getTemplateSpecializationKind()) {
649 case TSK_ImplicitInstantiation: Unknown = false; break;
650 case TSK_Undeclared: Unknown = true; break;
651
652 // These will be covered at their respective sites.
653 case TSK_ExplicitSpecialization: continue;
654 case TSK_ExplicitInstantiationDeclaration: continue;
655 case TSK_ExplicitInstantiationDefinition: continue;
656 }
657
658 TemporaryContainer C(*this,
659 Unknown ? "uninstantiated" : "instantiation");
660 visitTemplateArguments(*Info->TemplateArguments);
661 dispatch(Info->Function);
662 }
663 }
664
665 // ClasTemplateDecl
visitClassTemplateDeclAttrs__anonf6b4be7e0111::XMLDumper666 void visitClassTemplateDeclAttrs(ClassTemplateDecl *D) {
667 visitRedeclarableAttrs(D);
668 }
visitClassTemplateDeclChildren__anonf6b4be7e0111::XMLDumper669 void visitClassTemplateDeclChildren(ClassTemplateDecl *D) {
670 // Mention all the specializations which don't have explicit
671 // declarations elsewhere.
672 for (ClassTemplateDecl::spec_iterator
673 I = D->spec_begin(), E = D->spec_end(); I != E; ++I) {
674
675 bool Unknown = false;
676 switch (I->getTemplateSpecializationKind()) {
677 case TSK_ImplicitInstantiation: Unknown = false; break;
678 case TSK_Undeclared: Unknown = true; break;
679
680 // These will be covered at their respective sites.
681 case TSK_ExplicitSpecialization: continue;
682 case TSK_ExplicitInstantiationDeclaration: continue;
683 case TSK_ExplicitInstantiationDefinition: continue;
684 }
685
686 TemporaryContainer C(*this,
687 Unknown ? "uninstantiated" : "instantiation");
688 visitTemplateArguments(I->getTemplateArgs());
689 dispatch(*I);
690 }
691 }
692
693 // TemplateTypeParmDecl
visitTemplateTypeParmDeclAttrs__anonf6b4be7e0111::XMLDumper694 void visitTemplateTypeParmDeclAttrs(TemplateTypeParmDecl *D) {
695 setInteger("depth", D->getDepth());
696 setInteger("index", D->getIndex());
697 }
visitTemplateTypeParmDeclChildren__anonf6b4be7e0111::XMLDumper698 void visitTemplateTypeParmDeclChildren(TemplateTypeParmDecl *D) {
699 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
700 dispatch(D->getDefaultArgumentInfo()->getTypeLoc());
701 // parameter pack?
702 }
703
704 // NonTypeTemplateParmDecl
visitNonTypeTemplateParmDeclAttrs__anonf6b4be7e0111::XMLDumper705 void visitNonTypeTemplateParmDeclAttrs(NonTypeTemplateParmDecl *D) {
706 setInteger("depth", D->getDepth());
707 setInteger("index", D->getIndex());
708 }
visitNonTypeTemplateParmDeclChildren__anonf6b4be7e0111::XMLDumper709 void visitNonTypeTemplateParmDeclChildren(NonTypeTemplateParmDecl *D) {
710 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
711 dispatch(D->getDefaultArgument());
712 // parameter pack?
713 }
714
715 // TemplateTemplateParmDecl
visitTemplateTemplateParmDeclAttrs__anonf6b4be7e0111::XMLDumper716 void visitTemplateTemplateParmDeclAttrs(TemplateTemplateParmDecl *D) {
717 setInteger("depth", D->getDepth());
718 setInteger("index", D->getIndex());
719 }
visitTemplateTemplateParmDeclChildren__anonf6b4be7e0111::XMLDumper720 void visitTemplateTemplateParmDeclChildren(TemplateTemplateParmDecl *D) {
721 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
722 dispatch(D->getDefaultArgument());
723 // parameter pack?
724 }
725
726 // FriendDecl
visitFriendDeclChildren__anonf6b4be7e0111::XMLDumper727 void visitFriendDeclChildren(FriendDecl *D) {
728 if (TypeSourceInfo *T = D->getFriendType())
729 dispatch(T->getTypeLoc());
730 else
731 dispatch(D->getFriendDecl());
732 }
733
734 // UsingDirectiveDecl ?
735 // UsingDecl ?
736 // UsingShadowDecl ?
737 // NamespaceAliasDecl ?
738 // UnresolvedUsingValueDecl ?
739 // UnresolvedUsingTypenameDecl ?
740 // StaticAssertDecl ?
741
742 // ObjCImplDecl
visitObjCImplDeclChildren__anonf6b4be7e0111::XMLDumper743 void visitObjCImplDeclChildren(ObjCImplDecl *D) {
744 visitDeclRef(D->getClassInterface());
745 }
visitObjCImplDeclAsContext__anonf6b4be7e0111::XMLDumper746 void visitObjCImplDeclAsContext(ObjCImplDecl *D) {
747 visitDeclContext(D);
748 }
749
750 // ObjCInterfaceDecl
visitCategoryList__anonf6b4be7e0111::XMLDumper751 void visitCategoryList(ObjCCategoryDecl *D) {
752 if (!D) return;
753
754 TemporaryContainer C(*this, "categories");
755 for (; D; D = D->getNextClassCategory())
756 visitDeclRef(D);
757 }
visitObjCInterfaceDeclAttrs__anonf6b4be7e0111::XMLDumper758 void visitObjCInterfaceDeclAttrs(ObjCInterfaceDecl *D) {
759 setPointer("typeptr", D->getTypeForDecl());
760 setFlag("forward_decl", !D->isThisDeclarationADefinition());
761 setFlag("implicit_interface", D->isImplicitInterfaceDecl());
762 }
visitObjCInterfaceDeclChildren__anonf6b4be7e0111::XMLDumper763 void visitObjCInterfaceDeclChildren(ObjCInterfaceDecl *D) {
764 visitDeclRef("super", D->getSuperClass());
765 visitDeclRef("implementation", D->getImplementation());
766 if (D->protocol_begin() != D->protocol_end()) {
767 TemporaryContainer C(*this, "protocols");
768 for (ObjCInterfaceDecl::protocol_iterator
769 I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
770 visitDeclRef(*I);
771 }
772 visitCategoryList(D->getCategoryList());
773 }
visitObjCInterfaceDeclAsContext__anonf6b4be7e0111::XMLDumper774 void visitObjCInterfaceDeclAsContext(ObjCInterfaceDecl *D) {
775 visitDeclContext(D);
776 }
777
778 // ObjCCategoryDecl
visitObjCCategoryDeclAttrs__anonf6b4be7e0111::XMLDumper779 void visitObjCCategoryDeclAttrs(ObjCCategoryDecl *D) {
780 setFlag("extension", D->IsClassExtension());
781 setFlag("synth_bitfield", D->hasSynthBitfield());
782 }
visitObjCCategoryDeclChildren__anonf6b4be7e0111::XMLDumper783 void visitObjCCategoryDeclChildren(ObjCCategoryDecl *D) {
784 visitDeclRef("interface", D->getClassInterface());
785 visitDeclRef("implementation", D->getImplementation());
786 if (D->protocol_begin() != D->protocol_end()) {
787 TemporaryContainer C(*this, "protocols");
788 for (ObjCCategoryDecl::protocol_iterator
789 I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
790 visitDeclRef(*I);
791 }
792 }
visitObjCCategoryDeclAsContext__anonf6b4be7e0111::XMLDumper793 void visitObjCCategoryDeclAsContext(ObjCCategoryDecl *D) {
794 visitDeclContext(D);
795 }
796
797 // ObjCCategoryImplDecl
visitObjCCategoryImplDeclAttrs__anonf6b4be7e0111::XMLDumper798 void visitObjCCategoryImplDeclAttrs(ObjCCategoryImplDecl *D) {
799 set("identifier", D->getName());
800 }
visitObjCCategoryImplDeclChildren__anonf6b4be7e0111::XMLDumper801 void visitObjCCategoryImplDeclChildren(ObjCCategoryImplDecl *D) {
802 visitDeclRef(D->getCategoryDecl());
803 }
804
805 // ObjCImplementationDecl
visitObjCImplementationDeclAttrs__anonf6b4be7e0111::XMLDumper806 void visitObjCImplementationDeclAttrs(ObjCImplementationDecl *D) {
807 setFlag("synth_bitfield", D->hasSynthBitfield());
808 set("identifier", D->getName());
809 }
visitObjCImplementationDeclChildren__anonf6b4be7e0111::XMLDumper810 void visitObjCImplementationDeclChildren(ObjCImplementationDecl *D) {
811 visitDeclRef("super", D->getSuperClass());
812 if (D->init_begin() != D->init_end()) {
813 TemporaryContainer C(*this, "initializers");
814 for (ObjCImplementationDecl::init_iterator
815 I = D->init_begin(), E = D->init_end(); I != E; ++I)
816 dispatch(*I);
817 }
818 }
819
820 // ObjCProtocolDecl
visitObjCProtocolDeclChildren__anonf6b4be7e0111::XMLDumper821 void visitObjCProtocolDeclChildren(ObjCProtocolDecl *D) {
822 if (!D->isThisDeclarationADefinition())
823 return;
824
825 if (D->protocol_begin() != D->protocol_end()) {
826 TemporaryContainer C(*this, "protocols");
827 for (ObjCInterfaceDecl::protocol_iterator
828 I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
829 visitDeclRef(*I);
830 }
831 }
visitObjCProtocolDeclAsContext__anonf6b4be7e0111::XMLDumper832 void visitObjCProtocolDeclAsContext(ObjCProtocolDecl *D) {
833 if (!D->isThisDeclarationADefinition())
834 return;
835
836 visitDeclContext(D);
837 }
838
839 // ObjCMethodDecl
visitObjCMethodDeclAttrs__anonf6b4be7e0111::XMLDumper840 void visitObjCMethodDeclAttrs(ObjCMethodDecl *D) {
841 // decl qualifier?
842 // implementation control?
843
844 setFlag("instance", D->isInstanceMethod());
845 setFlag("variadic", D->isVariadic());
846 setFlag("synthesized", D->isSynthesized());
847 setFlag("defined", D->isDefined());
848 setFlag("related_result_type", D->hasRelatedResultType());
849 }
visitObjCMethodDeclChildren__anonf6b4be7e0111::XMLDumper850 void visitObjCMethodDeclChildren(ObjCMethodDecl *D) {
851 dispatch(D->getResultType());
852 for (ObjCMethodDecl::param_iterator
853 I = D->param_begin(), E = D->param_end(); I != E; ++I)
854 dispatch(*I);
855 if (D->isThisDeclarationADefinition())
856 dispatch(D->getBody());
857 }
858
859 // ObjCIvarDecl
setAccessControl__anonf6b4be7e0111::XMLDumper860 void setAccessControl(StringRef prop, ObjCIvarDecl::AccessControl AC) {
861 switch (AC) {
862 case ObjCIvarDecl::None: return set(prop, "none");
863 case ObjCIvarDecl::Private: return set(prop, "private");
864 case ObjCIvarDecl::Protected: return set(prop, "protected");
865 case ObjCIvarDecl::Public: return set(prop, "public");
866 case ObjCIvarDecl::Package: return set(prop, "package");
867 }
868 }
visitObjCIvarDeclAttrs__anonf6b4be7e0111::XMLDumper869 void visitObjCIvarDeclAttrs(ObjCIvarDecl *D) {
870 setFlag("synthesize", D->getSynthesize());
871 setAccessControl("access", D->getAccessControl());
872 }
873
874 // ObjCCompatibleAliasDecl
visitObjCCompatibleAliasDeclChildren__anonf6b4be7e0111::XMLDumper875 void visitObjCCompatibleAliasDeclChildren(ObjCCompatibleAliasDecl *D) {
876 visitDeclRef(D->getClassInterface());
877 }
878
879 // FIXME: ObjCPropertyDecl
880 // FIXME: ObjCPropertyImplDecl
881
882 //---- Types -----------------------------------------------------//
dispatch__anonf6b4be7e0111::XMLDumper883 void dispatch(TypeLoc TL) {
884 dispatch(TL.getType()); // for now
885 }
886
dispatch__anonf6b4be7e0111::XMLDumper887 void dispatch(QualType T) {
888 if (T.hasLocalQualifiers()) {
889 push("QualType");
890 Qualifiers Qs = T.getLocalQualifiers();
891 setFlag("const", Qs.hasConst());
892 setFlag("volatile", Qs.hasVolatile());
893 setFlag("restrict", Qs.hasRestrict());
894 if (Qs.hasAddressSpace()) setInteger("addrspace", Qs.getAddressSpace());
895 if (Qs.hasObjCGCAttr()) {
896 switch (Qs.getObjCGCAttr()) {
897 case Qualifiers::Weak: set("gc", "weak"); break;
898 case Qualifiers::Strong: set("gc", "strong"); break;
899 case Qualifiers::GCNone: llvm_unreachable("explicit none");
900 }
901 }
902
903 completeAttrs();
904 dispatch(QualType(T.getTypePtr(), 0));
905 pop();
906 return;
907 }
908
909 Type *Ty = const_cast<Type*>(T.getTypePtr());
910 push(getTypeKindName(Ty));
911 XMLTypeVisitor<XMLDumper>::dispatch(const_cast<Type*>(T.getTypePtr()));
912 pop();
913 }
914
setCallingConv__anonf6b4be7e0111::XMLDumper915 void setCallingConv(CallingConv CC) {
916 switch (CC) {
917 case CC_Default: return;
918 case CC_C: return set("cc", "cdecl");
919 case CC_X86FastCall: return set("cc", "x86_fastcall");
920 case CC_X86StdCall: return set("cc", "x86_stdcall");
921 case CC_X86ThisCall: return set("cc", "x86_thiscall");
922 case CC_X86Pascal: return set("cc", "x86_pascal");
923 case CC_AAPCS: return set("cc", "aapcs");
924 case CC_AAPCS_VFP: return set("cc", "aapcs_vfp");
925 }
926 }
927
visitTypeAttrs__anonf6b4be7e0111::XMLDumper928 void visitTypeAttrs(Type *D) {
929 setPointer(D);
930 setFlag("dependent", D->isDependentType());
931 setFlag("variably_modified", D->isVariablyModifiedType());
932
933 setPointer("canonical", D->getCanonicalTypeInternal().getAsOpaquePtr());
934 }
935
visitPointerTypeChildren__anonf6b4be7e0111::XMLDumper936 void visitPointerTypeChildren(PointerType *T) {
937 dispatch(T->getPointeeType());
938 }
visitReferenceTypeChildren__anonf6b4be7e0111::XMLDumper939 void visitReferenceTypeChildren(ReferenceType *T) {
940 dispatch(T->getPointeeType());
941 }
visitObjCObjectPointerTypeChildren__anonf6b4be7e0111::XMLDumper942 void visitObjCObjectPointerTypeChildren(ObjCObjectPointerType *T) {
943 dispatch(T->getPointeeType());
944 }
visitBlockPointerTypeChildren__anonf6b4be7e0111::XMLDumper945 void visitBlockPointerTypeChildren(BlockPointerType *T) {
946 dispatch(T->getPointeeType());
947 }
948
949 // Types that just wrap declarations.
visitTagTypeChildren__anonf6b4be7e0111::XMLDumper950 void visitTagTypeChildren(TagType *T) {
951 visitDeclRef(T->getDecl());
952 }
visitTypedefTypeChildren__anonf6b4be7e0111::XMLDumper953 void visitTypedefTypeChildren(TypedefType *T) {
954 visitDeclRef(T->getDecl());
955 }
visitObjCInterfaceTypeChildren__anonf6b4be7e0111::XMLDumper956 void visitObjCInterfaceTypeChildren(ObjCInterfaceType *T) {
957 visitDeclRef(T->getDecl());
958 }
visitUnresolvedUsingTypeChildren__anonf6b4be7e0111::XMLDumper959 void visitUnresolvedUsingTypeChildren(UnresolvedUsingType *T) {
960 visitDeclRef(T->getDecl());
961 }
visitInjectedClassNameTypeChildren__anonf6b4be7e0111::XMLDumper962 void visitInjectedClassNameTypeChildren(InjectedClassNameType *T) {
963 visitDeclRef(T->getDecl());
964 }
965
visitFunctionTypeAttrs__anonf6b4be7e0111::XMLDumper966 void visitFunctionTypeAttrs(FunctionType *T) {
967 setFlag("noreturn", T->getNoReturnAttr());
968 setCallingConv(T->getCallConv());
969 if (T->getHasRegParm()) setInteger("regparm", T->getRegParmType());
970 }
visitFunctionTypeChildren__anonf6b4be7e0111::XMLDumper971 void visitFunctionTypeChildren(FunctionType *T) {
972 dispatch(T->getResultType());
973 }
974
visitFunctionProtoTypeAttrs__anonf6b4be7e0111::XMLDumper975 void visitFunctionProtoTypeAttrs(FunctionProtoType *T) {
976 setFlag("const", T->getTypeQuals() & Qualifiers::Const);
977 setFlag("volatile", T->getTypeQuals() & Qualifiers::Volatile);
978 setFlag("restrict", T->getTypeQuals() & Qualifiers::Restrict);
979 }
visitFunctionProtoTypeChildren__anonf6b4be7e0111::XMLDumper980 void visitFunctionProtoTypeChildren(FunctionProtoType *T) {
981 push("parameters");
982 setFlag("variadic", T->isVariadic());
983 completeAttrs();
984 for (FunctionProtoType::arg_type_iterator
985 I = T->arg_type_begin(), E = T->arg_type_end(); I != E; ++I)
986 dispatch(*I);
987 pop();
988
989 if (T->hasDynamicExceptionSpec()) {
990 push("exception_specifiers");
991 setFlag("any", T->getExceptionSpecType() == EST_MSAny);
992 completeAttrs();
993 for (FunctionProtoType::exception_iterator
994 I = T->exception_begin(), E = T->exception_end(); I != E; ++I)
995 dispatch(*I);
996 pop();
997 }
998 // FIXME: noexcept specifier
999 }
1000
visitTemplateSpecializationTypeChildren__anonf6b4be7e0111::XMLDumper1001 void visitTemplateSpecializationTypeChildren(TemplateSpecializationType *T) {
1002 if (const RecordType *RT = T->getAs<RecordType>())
1003 visitDeclRef(RT->getDecl());
1004
1005 // TODO: TemplateName
1006
1007 push("template_arguments");
1008 completeAttrs();
1009 for (unsigned I = 0, E = T->getNumArgs(); I != E; ++I)
1010 dispatch(T->getArg(I));
1011 pop();
1012 }
1013
1014 //---- Statements ------------------------------------------------//
dispatch__anonf6b4be7e0111::XMLDumper1015 void dispatch(Stmt *S) {
1016 // FIXME: this is not really XML at all
1017 push("Stmt");
1018 out << ">\n";
1019 Stack.back().State = NS_Children; // explicitly become non-lazy
1020 S->dump(out, Context.getSourceManager());
1021 out << '\n';
1022 pop();
1023 }
1024 };
1025 }
1026
dumpXML() const1027 void Decl::dumpXML() const {
1028 dumpXML(llvm::errs());
1029 }
1030
dumpXML(raw_ostream & out) const1031 void Decl::dumpXML(raw_ostream &out) const {
1032 XMLDumper(out, getASTContext()).dispatch(const_cast<Decl*>(this));
1033 }
1034
1035 #else /* ifndef NDEBUG */
1036
dumpXML() const1037 void Decl::dumpXML() const {}
dumpXML(raw_ostream & out) const1038 void Decl::dumpXML(raw_ostream &out) const {}
1039
1040 #endif
1041