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/SmallVector.h"
43 #include "llvm/ADT/StringRef.h"
44
45 using namespace clang;
46
47 #ifndef NDEBUG
48
49 namespace {
50
51 enum NodeState {
52 NS_Attrs, NS_LazyChildren, NS_Children
53 };
54
55 struct Node {
56 llvm::StringRef Name;
57 NodeState State;
Node__anone37c897d0111::Node58 Node(llvm::StringRef name) : Name(name), State(NS_Attrs) {}
59
isDoneWithAttrs__anone37c897d0111::Node60 bool isDoneWithAttrs() const { return State != NS_Attrs; }
61 };
62
63 template <class Impl> struct XMLDeclVisitor {
64 #define DISPATCH(NAME, CLASS) \
65 static_cast<Impl*>(this)->NAME(static_cast<CLASS*>(D))
66
dispatch__anone37c897d0111::XMLDeclVisitor67 void dispatch(Decl *D) {
68 switch (D->getKind()) {
69 default: llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
70 #define DECL(DERIVED, BASE) \
71 case Decl::DERIVED: \
72 DISPATCH(dispatch##DERIVED##DeclAttrs, DERIVED##Decl); \
73 static_cast<Impl*>(this)->completeAttrs(); \
74 DISPATCH(dispatch##DERIVED##DeclChildren, DERIVED##Decl); \
75 DISPATCH(dispatch##DERIVED##DeclAsContext, DERIVED##Decl); \
76 break;
77 #define ABSTRACT_DECL(DECL)
78 #include "clang/AST/DeclNodes.inc"
79 }
80 }
81
82 #define DECL(DERIVED, BASE) \
83 void dispatch##DERIVED##DeclAttrs(DERIVED##Decl *D) { \
84 DISPATCH(dispatch##BASE##Attrs, BASE); \
85 DISPATCH(visit##DERIVED##DeclAttrs, DERIVED##Decl); \
86 } \
87 void visit##DERIVED##DeclAttrs(DERIVED##Decl *D) {} \
88 void dispatch##DERIVED##DeclChildren(DERIVED##Decl *D) { \
89 DISPATCH(dispatch##BASE##Children, BASE); \
90 DISPATCH(visit##DERIVED##DeclChildren, DERIVED##Decl); \
91 } \
92 void visit##DERIVED##DeclChildren(DERIVED##Decl *D) {} \
93 void dispatch##DERIVED##DeclAsContext(DERIVED##Decl *D) { \
94 DISPATCH(dispatch##BASE##AsContext, BASE); \
95 DISPATCH(visit##DERIVED##DeclAsContext, DERIVED##Decl); \
96 } \
97 void visit##DERIVED##DeclAsContext(DERIVED##Decl *D) {}
98 #include "clang/AST/DeclNodes.inc"
99
dispatchDeclAttrs__anone37c897d0111::XMLDeclVisitor100 void dispatchDeclAttrs(Decl *D) {
101 DISPATCH(visitDeclAttrs, Decl);
102 }
visitDeclAttrs__anone37c897d0111::XMLDeclVisitor103 void visitDeclAttrs(Decl *D) {}
104
dispatchDeclChildren__anone37c897d0111::XMLDeclVisitor105 void dispatchDeclChildren(Decl *D) {
106 DISPATCH(visitDeclChildren, Decl);
107 }
visitDeclChildren__anone37c897d0111::XMLDeclVisitor108 void visitDeclChildren(Decl *D) {}
109
dispatchDeclAsContext__anone37c897d0111::XMLDeclVisitor110 void dispatchDeclAsContext(Decl *D) {
111 DISPATCH(visitDeclAsContext, Decl);
112 }
visitDeclAsContext__anone37c897d0111::XMLDeclVisitor113 void visitDeclAsContext(Decl *D) {}
114
115 #undef DISPATCH
116 };
117
118 template <class Impl> struct XMLTypeVisitor {
119 #define DISPATCH(NAME, CLASS) \
120 static_cast<Impl*>(this)->NAME(static_cast<CLASS*>(T))
121
dispatch__anone37c897d0111::XMLTypeVisitor122 void dispatch(Type *T) {
123 switch (T->getTypeClass()) {
124 default: llvm_unreachable("Type that isn't part of TypeNodes.inc!");
125 #define TYPE(DERIVED, BASE) \
126 case Type::DERIVED: \
127 DISPATCH(dispatch##DERIVED##TypeAttrs, DERIVED##Type); \
128 static_cast<Impl*>(this)->completeAttrs(); \
129 DISPATCH(dispatch##DERIVED##TypeChildren, DERIVED##Type); \
130 break;
131 #define ABSTRACT_TYPE(DERIVED, BASE)
132 #include "clang/AST/TypeNodes.def"
133 }
134 }
135
136 #define TYPE(DERIVED, BASE) \
137 void dispatch##DERIVED##TypeAttrs(DERIVED##Type *T) { \
138 DISPATCH(dispatch##BASE##Attrs, BASE); \
139 DISPATCH(visit##DERIVED##TypeAttrs, DERIVED##Type); \
140 } \
141 void visit##DERIVED##TypeAttrs(DERIVED##Type *T) {} \
142 void dispatch##DERIVED##TypeChildren(DERIVED##Type *T) { \
143 DISPATCH(dispatch##BASE##Children, BASE); \
144 DISPATCH(visit##DERIVED##TypeChildren, DERIVED##Type); \
145 } \
146 void visit##DERIVED##TypeChildren(DERIVED##Type *T) {}
147 #include "clang/AST/TypeNodes.def"
148
dispatchTypeAttrs__anone37c897d0111::XMLTypeVisitor149 void dispatchTypeAttrs(Type *T) {
150 DISPATCH(visitTypeAttrs, Type);
151 }
visitTypeAttrs__anone37c897d0111::XMLTypeVisitor152 void visitTypeAttrs(Type *T) {}
153
dispatchTypeChildren__anone37c897d0111::XMLTypeVisitor154 void dispatchTypeChildren(Type *T) {
155 DISPATCH(visitTypeChildren, Type);
156 }
visitTypeChildren__anone37c897d0111::XMLTypeVisitor157 void visitTypeChildren(Type *T) {}
158
159 #undef DISPATCH
160 };
161
getTypeKindName(Type * T)162 static llvm::StringRef getTypeKindName(Type *T) {
163 switch (T->getTypeClass()) {
164 #define TYPE(DERIVED, BASE) case Type::DERIVED: return #DERIVED "Type";
165 #define ABSTRACT_TYPE(DERIVED, BASE)
166 #include "clang/AST/TypeNodes.def"
167 }
168
169 llvm_unreachable("unknown type kind!");
170 return "unknown_type";
171 }
172
173 struct XMLDumper : public XMLDeclVisitor<XMLDumper>,
174 public XMLTypeVisitor<XMLDumper> {
175 llvm::raw_ostream &out;
176 ASTContext &Context;
177 llvm::SmallVector<Node, 16> Stack;
178 unsigned Indent;
XMLDumper__anone37c897d0111::XMLDumper179 explicit XMLDumper(llvm::raw_ostream &OS, ASTContext &context)
180 : out(OS), Context(context), Indent(0) {}
181
indent__anone37c897d0111::XMLDumper182 void indent() {
183 for (unsigned I = Indent; I; --I)
184 out << ' ';
185 }
186
187 /// Push a new node on the stack.
push__anone37c897d0111::XMLDumper188 void push(llvm::StringRef name) {
189 if (!Stack.empty()) {
190 assert(Stack.back().isDoneWithAttrs());
191 if (Stack.back().State == NS_LazyChildren) {
192 Stack.back().State = NS_Children;
193 out << ">\n";
194 }
195 Indent++;
196 indent();
197 }
198 Stack.push_back(Node(name));
199 out << '<' << name;
200 }
201
202 /// Set the given attribute to the given value.
set__anone37c897d0111::XMLDumper203 void set(llvm::StringRef attr, llvm::StringRef value) {
204 assert(!Stack.empty() && !Stack.back().isDoneWithAttrs());
205 out << ' ' << attr << '=' << '"' << value << '"'; // TODO: quotation
206 }
207
208 /// Finish attributes.
completeAttrs__anone37c897d0111::XMLDumper209 void completeAttrs() {
210 assert(!Stack.empty() && !Stack.back().isDoneWithAttrs());
211 Stack.back().State = NS_LazyChildren;
212 }
213
214 /// Pop a node.
pop__anone37c897d0111::XMLDumper215 void pop() {
216 assert(!Stack.empty() && Stack.back().isDoneWithAttrs());
217 if (Stack.back().State == NS_LazyChildren) {
218 out << "/>\n";
219 } else {
220 indent();
221 out << "</" << Stack.back().Name << ">\n";
222 }
223 if (Stack.size() > 1) Indent--;
224 Stack.pop_back();
225 }
226
227 //---- General utilities -------------------------------------------//
228
setPointer__anone37c897d0111::XMLDumper229 void setPointer(llvm::StringRef prop, const void *p) {
230 llvm::SmallString<10> buffer;
231 llvm::raw_svector_ostream os(buffer);
232 os << p;
233 os.flush();
234 set(prop, buffer);
235 }
236
setPointer__anone37c897d0111::XMLDumper237 void setPointer(void *p) {
238 setPointer("ptr", p);
239 }
240
setInteger__anone37c897d0111::XMLDumper241 void setInteger(llvm::StringRef prop, const llvm::APSInt &v) {
242 set(prop, v.toString(10));
243 }
244
setInteger__anone37c897d0111::XMLDumper245 void setInteger(llvm::StringRef prop, unsigned n) {
246 llvm::SmallString<10> buffer;
247 llvm::raw_svector_ostream os(buffer);
248 os << n;
249 os.flush();
250 set(prop, buffer);
251 }
252
setFlag__anone37c897d0111::XMLDumper253 void setFlag(llvm::StringRef prop, bool flag) {
254 if (flag) set(prop, "true");
255 }
256
setName__anone37c897d0111::XMLDumper257 void setName(DeclarationName Name) {
258 if (!Name)
259 return set("name", "");
260
261 // Common case.
262 if (Name.isIdentifier())
263 return set("name", Name.getAsIdentifierInfo()->getName());
264
265 set("name", Name.getAsString());
266 }
267
268 class TemporaryContainer {
269 XMLDumper &Dumper;
270 public:
TemporaryContainer(XMLDumper & dumper,llvm::StringRef name)271 TemporaryContainer(XMLDumper &dumper, llvm::StringRef name)
272 : Dumper(dumper) {
273 Dumper.push(name);
274 Dumper.completeAttrs();
275 }
276
~TemporaryContainer()277 ~TemporaryContainer() {
278 Dumper.pop();
279 }
280 };
281
visitTemplateParameters__anone37c897d0111::XMLDumper282 void visitTemplateParameters(TemplateParameterList *L) {
283 push("template_parameters");
284 completeAttrs();
285 for (TemplateParameterList::iterator
286 I = L->begin(), E = L->end(); I != E; ++I)
287 dispatch(*I);
288 pop();
289 }
290
visitTemplateArguments__anone37c897d0111::XMLDumper291 void visitTemplateArguments(const TemplateArgumentList &L) {
292 push("template_arguments");
293 completeAttrs();
294 for (unsigned I = 0, E = L.size(); I != E; ++I)
295 dispatch(L[I]);
296 pop();
297 }
298
299 /// Visits a reference to the given declaration.
visitDeclRef__anone37c897d0111::XMLDumper300 void visitDeclRef(Decl *D) {
301 push(D->getDeclKindName());
302 setPointer("ref", D);
303 completeAttrs();
304 pop();
305 }
visitDeclRef__anone37c897d0111::XMLDumper306 void visitDeclRef(llvm::StringRef Name, Decl *D) {
307 TemporaryContainer C(*this, Name);
308 if (D) visitDeclRef(D);
309 }
310
dispatch__anone37c897d0111::XMLDumper311 void dispatch(const TemplateArgument &A) {
312 switch (A.getKind()) {
313 case TemplateArgument::Null: {
314 TemporaryContainer C(*this, "null");
315 break;
316 }
317 case TemplateArgument::Type: {
318 dispatch(A.getAsType());
319 break;
320 }
321 case TemplateArgument::Template:
322 case TemplateArgument::TemplateExpansion:
323 // FIXME: Implement!
324 break;
325
326 case TemplateArgument::Declaration: {
327 visitDeclRef(A.getAsDecl());
328 break;
329 }
330 case TemplateArgument::Integral: {
331 push("integer");
332 setInteger("value", *A.getAsIntegral());
333 completeAttrs();
334 pop();
335 break;
336 }
337 case TemplateArgument::Expression: {
338 dispatch(A.getAsExpr());
339 break;
340 }
341 case TemplateArgument::Pack: {
342 for (TemplateArgument::pack_iterator P = A.pack_begin(),
343 PEnd = A.pack_end();
344 P != PEnd; ++P)
345 dispatch(*P);
346 break;
347 }
348 }
349 }
350
dispatch__anone37c897d0111::XMLDumper351 void dispatch(const TemplateArgumentLoc &A) {
352 dispatch(A.getArgument());
353 }
354
355 //---- Declarations ------------------------------------------------//
356 // Calls are made in this order:
357 // # Enter a new node.
358 // push("FieldDecl")
359 //
360 // # In this phase, attributes are set on the node.
361 // visitDeclAttrs(D)
362 // visitNamedDeclAttrs(D)
363 // ...
364 // visitFieldDeclAttrs(D)
365 //
366 // # No more attributes after this point.
367 // completeAttrs()
368 //
369 // # Create "header" child nodes, i.e. those which logically
370 // # belong to the declaration itself.
371 // visitDeclChildren(D)
372 // visitNamedDeclChildren(D)
373 // ...
374 // visitFieldDeclChildren(D)
375 //
376 // # Create nodes for the lexical children.
377 // visitDeclAsContext(D)
378 // visitNamedDeclAsContext(D)
379 // ...
380 // visitFieldDeclAsContext(D)
381 //
382 // # Finish the node.
383 // pop();
dispatch__anone37c897d0111::XMLDumper384 void dispatch(Decl *D) {
385 push(D->getDeclKindName());
386 XMLDeclVisitor<XMLDumper>::dispatch(D);
387 pop();
388 }
visitDeclAttrs__anone37c897d0111::XMLDumper389 void visitDeclAttrs(Decl *D) {
390 setPointer(D);
391 }
392
393 /// Visit all the lexical decls in the given context.
visitDeclContext__anone37c897d0111::XMLDumper394 void visitDeclContext(DeclContext *DC) {
395 for (DeclContext::decl_iterator
396 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
397 dispatch(*I);
398
399 // FIXME: point out visible declarations not in lexical context?
400 }
401
402 /// Set the "access" attribute on the current node according to the
403 /// given specifier.
setAccess__anone37c897d0111::XMLDumper404 void setAccess(AccessSpecifier AS) {
405 switch (AS) {
406 case AS_public: return set("access", "public");
407 case AS_protected: return set("access", "protected");
408 case AS_private: return set("access", "private");
409 case AS_none: llvm_unreachable("explicit forbidden access");
410 }
411 }
412
visitRedeclarableAttrs__anone37c897d0111::XMLDumper413 template <class T> void visitRedeclarableAttrs(T *D) {
414 if (T *Prev = D->getPreviousDeclaration())
415 setPointer("previous", Prev);
416 }
417
418
419 // TranslationUnitDecl
visitTranslationUnitDeclAsContext__anone37c897d0111::XMLDumper420 void visitTranslationUnitDeclAsContext(TranslationUnitDecl *D) {
421 visitDeclContext(D);
422 }
423
424 // LinkageSpecDecl
visitLinkageSpecDeclAttrs__anone37c897d0111::XMLDumper425 void visitLinkageSpecDeclAttrs(LinkageSpecDecl *D) {
426 llvm::StringRef lang = "";
427 switch (D->getLanguage()) {
428 case LinkageSpecDecl::lang_c: lang = "C"; break;
429 case LinkageSpecDecl::lang_cxx: lang = "C++"; break;
430 }
431 set("lang", lang);
432 }
visitLinkageSpecDeclAsContext__anone37c897d0111::XMLDumper433 void visitLinkageSpecDeclAsContext(LinkageSpecDecl *D) {
434 visitDeclContext(D);
435 }
436
437 // NamespaceDecl
visitNamespaceDeclAttrs__anone37c897d0111::XMLDumper438 void visitNamespaceDeclAttrs(NamespaceDecl *D) {
439 setFlag("inline", D->isInline());
440 if (!D->isOriginalNamespace())
441 setPointer("original", D->getOriginalNamespace());
442 }
visitNamespaceDeclAsContext__anone37c897d0111::XMLDumper443 void visitNamespaceDeclAsContext(NamespaceDecl *D) {
444 visitDeclContext(D);
445 }
446
447 // NamedDecl
visitNamedDeclAttrs__anone37c897d0111::XMLDumper448 void visitNamedDeclAttrs(NamedDecl *D) {
449 setName(D->getDeclName());
450 }
451
452 // ValueDecl
visitValueDeclChildren__anone37c897d0111::XMLDumper453 void visitValueDeclChildren(ValueDecl *D) {
454 dispatch(D->getType());
455 }
456
457 // DeclaratorDecl
visitDeclaratorDeclChildren__anone37c897d0111::XMLDumper458 void visitDeclaratorDeclChildren(DeclaratorDecl *D) {
459 //dispatch(D->getTypeSourceInfo()->getTypeLoc());
460 }
461
462 // VarDecl
visitVarDeclAttrs__anone37c897d0111::XMLDumper463 void visitVarDeclAttrs(VarDecl *D) {
464 visitRedeclarableAttrs(D);
465 if (D->getStorageClass() != SC_None)
466 set("storage",
467 VarDecl::getStorageClassSpecifierString(D->getStorageClass()));
468 setFlag("directinit", D->hasCXXDirectInitializer());
469 setFlag("nrvo", D->isNRVOVariable());
470 // TODO: instantiation, etc.
471 }
visitVarDeclChildren__anone37c897d0111::XMLDumper472 void visitVarDeclChildren(VarDecl *D) {
473 if (D->hasInit()) dispatch(D->getInit());
474 }
475
476 // ParmVarDecl?
477
478 // FunctionDecl
visitFunctionDeclAttrs__anone37c897d0111::XMLDumper479 void visitFunctionDeclAttrs(FunctionDecl *D) {
480 visitRedeclarableAttrs(D);
481 setFlag("pure", D->isPure());
482 setFlag("trivial", D->isTrivial());
483 setFlag("returnzero", D->hasImplicitReturnZero());
484 setFlag("prototype", D->hasWrittenPrototype());
485 setFlag("deleted", D->isDeletedAsWritten());
486 if (D->getStorageClass() != SC_None)
487 set("storage",
488 VarDecl::getStorageClassSpecifierString(D->getStorageClass()));
489 setFlag("inline", D->isInlineSpecified());
490 if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>())
491 set("asmlabel", ALA->getLabel());
492 // TODO: instantiation, etc.
493 }
visitFunctionDeclChildren__anone37c897d0111::XMLDumper494 void visitFunctionDeclChildren(FunctionDecl *D) {
495 for (FunctionDecl::param_iterator
496 I = D->param_begin(), E = D->param_end(); I != E; ++I)
497 dispatch(*I);
498 if (D->doesThisDeclarationHaveABody())
499 dispatch(D->getBody());
500 }
501
502 // CXXMethodDecl ?
503 // CXXConstructorDecl ?
504 // CXXDestructorDecl ?
505 // CXXConversionDecl ?
506
dispatch__anone37c897d0111::XMLDumper507 void dispatch(CXXCtorInitializer *Init) {
508 // TODO
509 }
510
511 // FieldDecl
visitFieldDeclAttrs__anone37c897d0111::XMLDumper512 void visitFieldDeclAttrs(FieldDecl *D) {
513 setFlag("mutable", D->isMutable());
514 }
visitFieldDeclChildren__anone37c897d0111::XMLDumper515 void visitFieldDeclChildren(FieldDecl *D) {
516 if (D->isBitField()) {
517 TemporaryContainer C(*this, "bitwidth");
518 dispatch(D->getBitWidth());
519 }
520 // TODO: C++0x member initializer
521 }
522
523 // EnumConstantDecl
visitEnumConstantDeclChildren__anone37c897d0111::XMLDumper524 void visitEnumConstantDeclChildren(EnumConstantDecl *D) {
525 // value in any case?
526 if (D->getInitExpr()) dispatch(D->getInitExpr());
527 }
528
529 // IndirectFieldDecl
visitIndirectFieldDeclChildren__anone37c897d0111::XMLDumper530 void visitIndirectFieldDeclChildren(IndirectFieldDecl *D) {
531 for (IndirectFieldDecl::chain_iterator
532 I = D->chain_begin(), E = D->chain_end(); I != E; ++I) {
533 NamedDecl *VD = const_cast<NamedDecl*>(*I);
534 push(isa<VarDecl>(VD) ? "variable" : "field");
535 setPointer("ptr", VD);
536 completeAttrs();
537 pop();
538 }
539 }
540
541 // TypeDecl
visitTypeDeclAttrs__anone37c897d0111::XMLDumper542 void visitTypeDeclAttrs(TypeDecl *D) {
543 setPointer("typeptr", D->getTypeForDecl());
544 }
545
546 // TypedefDecl
visitTypedefDeclAttrs__anone37c897d0111::XMLDumper547 void visitTypedefDeclAttrs(TypedefDecl *D) {
548 visitRedeclarableAttrs<TypedefNameDecl>(D);
549 }
visitTypedefDeclChildren__anone37c897d0111::XMLDumper550 void visitTypedefDeclChildren(TypedefDecl *D) {
551 dispatch(D->getTypeSourceInfo()->getTypeLoc());
552 }
553
554 // TypeAliasDecl
visitTypeAliasDeclAttrs__anone37c897d0111::XMLDumper555 void visitTypeAliasDeclAttrs(TypeAliasDecl *D) {
556 visitRedeclarableAttrs<TypedefNameDecl>(D);
557 }
visitTypeAliasDeclChildren__anone37c897d0111::XMLDumper558 void visitTypeAliasDeclChildren(TypeAliasDecl *D) {
559 dispatch(D->getTypeSourceInfo()->getTypeLoc());
560 }
561
562 // TagDecl
visitTagDeclAttrs__anone37c897d0111::XMLDumper563 void visitTagDeclAttrs(TagDecl *D) {
564 visitRedeclarableAttrs(D);
565 }
visitTagDeclAsContext__anone37c897d0111::XMLDumper566 void visitTagDeclAsContext(TagDecl *D) {
567 visitDeclContext(D);
568 }
569
570 // EnumDecl
visitEnumDeclAttrs__anone37c897d0111::XMLDumper571 void visitEnumDeclAttrs(EnumDecl *D) {
572 setFlag("scoped", D->isScoped());
573 setFlag("fixed", D->isFixed());
574 }
visitEnumDeclChildren__anone37c897d0111::XMLDumper575 void visitEnumDeclChildren(EnumDecl *D) {
576 {
577 TemporaryContainer C(*this, "promotion_type");
578 dispatch(D->getPromotionType());
579 }
580 {
581 TemporaryContainer C(*this, "integer_type");
582 dispatch(D->getIntegerType());
583 }
584 }
585
586 // RecordDecl ?
587
visitCXXRecordDeclChildren__anone37c897d0111::XMLDumper588 void visitCXXRecordDeclChildren(CXXRecordDecl *D) {
589 if (!D->isThisDeclarationADefinition()) return;
590
591 for (CXXRecordDecl::base_class_iterator
592 I = D->bases_begin(), E = D->bases_end(); I != E; ++I) {
593 push("base");
594 setAccess(I->getAccessSpecifier());
595 completeAttrs();
596 dispatch(I->getTypeSourceInfo()->getTypeLoc());
597 pop();
598 }
599 }
600
601 // ClassTemplateSpecializationDecl ?
602
603 // FileScopeAsmDecl ?
604
605 // BlockDecl
visitBlockDeclAttrs__anone37c897d0111::XMLDumper606 void visitBlockDeclAttrs(BlockDecl *D) {
607 setFlag("variadic", D->isVariadic());
608 }
visitBlockDeclChildren__anone37c897d0111::XMLDumper609 void visitBlockDeclChildren(BlockDecl *D) {
610 for (FunctionDecl::param_iterator
611 I = D->param_begin(), E = D->param_end(); I != E; ++I)
612 dispatch(*I);
613 dispatch(D->getBody());
614 }
615
616 // AccessSpecDecl
visitAccessSpecDeclAttrs__anone37c897d0111::XMLDumper617 void visitAccessSpecDeclAttrs(AccessSpecDecl *D) {
618 setAccess(D->getAccess());
619 }
620
621 // TemplateDecl
visitTemplateDeclChildren__anone37c897d0111::XMLDumper622 void visitTemplateDeclChildren(TemplateDecl *D) {
623 visitTemplateParameters(D->getTemplateParameters());
624 if (D->getTemplatedDecl())
625 dispatch(D->getTemplatedDecl());
626 }
627
628 // FunctionTemplateDecl
visitFunctionTemplateDeclAttrs__anone37c897d0111::XMLDumper629 void visitFunctionTemplateDeclAttrs(FunctionTemplateDecl *D) {
630 visitRedeclarableAttrs(D);
631 }
visitFunctionTemplateDeclChildren__anone37c897d0111::XMLDumper632 void visitFunctionTemplateDeclChildren(FunctionTemplateDecl *D) {
633 // Mention all the specializations which don't have explicit
634 // declarations elsewhere.
635 for (FunctionTemplateDecl::spec_iterator
636 I = D->spec_begin(), E = D->spec_end(); I != E; ++I) {
637 FunctionTemplateSpecializationInfo *Info
638 = I->getTemplateSpecializationInfo();
639
640 bool Unknown = false;
641 switch (Info->getTemplateSpecializationKind()) {
642 case TSK_ImplicitInstantiation: Unknown = false; break;
643 case TSK_Undeclared: Unknown = true; break;
644
645 // These will be covered at their respective sites.
646 case TSK_ExplicitSpecialization: continue;
647 case TSK_ExplicitInstantiationDeclaration: continue;
648 case TSK_ExplicitInstantiationDefinition: continue;
649 }
650
651 TemporaryContainer C(*this,
652 Unknown ? "uninstantiated" : "instantiation");
653 visitTemplateArguments(*Info->TemplateArguments);
654 dispatch(Info->Function);
655 }
656 }
657
658 // ClasTemplateDecl
visitClassTemplateDeclAttrs__anone37c897d0111::XMLDumper659 void visitClassTemplateDeclAttrs(ClassTemplateDecl *D) {
660 visitRedeclarableAttrs(D);
661 }
visitClassTemplateDeclChildren__anone37c897d0111::XMLDumper662 void visitClassTemplateDeclChildren(ClassTemplateDecl *D) {
663 // Mention all the specializations which don't have explicit
664 // declarations elsewhere.
665 for (ClassTemplateDecl::spec_iterator
666 I = D->spec_begin(), E = D->spec_end(); I != E; ++I) {
667
668 bool Unknown = false;
669 switch (I->getTemplateSpecializationKind()) {
670 case TSK_ImplicitInstantiation: Unknown = false; break;
671 case TSK_Undeclared: Unknown = true; break;
672
673 // These will be covered at their respective sites.
674 case TSK_ExplicitSpecialization: continue;
675 case TSK_ExplicitInstantiationDeclaration: continue;
676 case TSK_ExplicitInstantiationDefinition: continue;
677 }
678
679 TemporaryContainer C(*this,
680 Unknown ? "uninstantiated" : "instantiation");
681 visitTemplateArguments(I->getTemplateArgs());
682 dispatch(*I);
683 }
684 }
685
686 // TemplateTypeParmDecl
visitTemplateTypeParmDeclAttrs__anone37c897d0111::XMLDumper687 void visitTemplateTypeParmDeclAttrs(TemplateTypeParmDecl *D) {
688 setInteger("depth", D->getDepth());
689 setInteger("index", D->getIndex());
690 }
visitTemplateTypeParmDeclChildren__anone37c897d0111::XMLDumper691 void visitTemplateTypeParmDeclChildren(TemplateTypeParmDecl *D) {
692 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
693 dispatch(D->getDefaultArgumentInfo()->getTypeLoc());
694 // parameter pack?
695 }
696
697 // NonTypeTemplateParmDecl
visitNonTypeTemplateParmDeclAttrs__anone37c897d0111::XMLDumper698 void visitNonTypeTemplateParmDeclAttrs(NonTypeTemplateParmDecl *D) {
699 setInteger("depth", D->getDepth());
700 setInteger("index", D->getIndex());
701 }
visitNonTypeTemplateParmDeclChildren__anone37c897d0111::XMLDumper702 void visitNonTypeTemplateParmDeclChildren(NonTypeTemplateParmDecl *D) {
703 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
704 dispatch(D->getDefaultArgument());
705 // parameter pack?
706 }
707
708 // TemplateTemplateParmDecl
visitTemplateTemplateParmDeclAttrs__anone37c897d0111::XMLDumper709 void visitTemplateTemplateParmDeclAttrs(TemplateTemplateParmDecl *D) {
710 setInteger("depth", D->getDepth());
711 setInteger("index", D->getIndex());
712 }
visitTemplateTemplateParmDeclChildren__anone37c897d0111::XMLDumper713 void visitTemplateTemplateParmDeclChildren(TemplateTemplateParmDecl *D) {
714 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
715 dispatch(D->getDefaultArgument());
716 // parameter pack?
717 }
718
719 // FriendDecl
visitFriendDeclChildren__anone37c897d0111::XMLDumper720 void visitFriendDeclChildren(FriendDecl *D) {
721 if (TypeSourceInfo *T = D->getFriendType())
722 dispatch(T->getTypeLoc());
723 else
724 dispatch(D->getFriendDecl());
725 }
726
727 // UsingDirectiveDecl ?
728 // UsingDecl ?
729 // UsingShadowDecl ?
730 // NamespaceAliasDecl ?
731 // UnresolvedUsingValueDecl ?
732 // UnresolvedUsingTypenameDecl ?
733 // StaticAssertDecl ?
734
735 // ObjCImplDecl
visitObjCImplDeclChildren__anone37c897d0111::XMLDumper736 void visitObjCImplDeclChildren(ObjCImplDecl *D) {
737 visitDeclRef(D->getClassInterface());
738 }
visitObjCImplDeclAsContext__anone37c897d0111::XMLDumper739 void visitObjCImplDeclAsContext(ObjCImplDecl *D) {
740 visitDeclContext(D);
741 }
742
743 // ObjCClassDecl
visitObjCClassDeclChildren__anone37c897d0111::XMLDumper744 void visitObjCClassDeclChildren(ObjCClassDecl *D) {
745 for (ObjCClassDecl::iterator I = D->begin(), E = D->end(); I != E; ++I)
746 visitDeclRef(I->getInterface());
747 }
748
749 // ObjCInterfaceDecl
visitCategoryList__anone37c897d0111::XMLDumper750 void visitCategoryList(ObjCCategoryDecl *D) {
751 if (!D) return;
752
753 TemporaryContainer C(*this, "categories");
754 for (; D; D = D->getNextClassCategory())
755 visitDeclRef(D);
756 }
visitObjCInterfaceDeclAttrs__anone37c897d0111::XMLDumper757 void visitObjCInterfaceDeclAttrs(ObjCInterfaceDecl *D) {
758 setPointer("typeptr", D->getTypeForDecl());
759 setFlag("forward_decl", D->isForwardDecl());
760 setFlag("implicit_interface", D->isImplicitInterfaceDecl());
761 }
visitObjCInterfaceDeclChildren__anone37c897d0111::XMLDumper762 void visitObjCInterfaceDeclChildren(ObjCInterfaceDecl *D) {
763 visitDeclRef("super", D->getSuperClass());
764 visitDeclRef("implementation", D->getImplementation());
765 if (D->protocol_begin() != D->protocol_end()) {
766 TemporaryContainer C(*this, "protocols");
767 for (ObjCInterfaceDecl::protocol_iterator
768 I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
769 visitDeclRef(*I);
770 }
771 visitCategoryList(D->getCategoryList());
772 }
visitObjCInterfaceDeclAsContext__anone37c897d0111::XMLDumper773 void visitObjCInterfaceDeclAsContext(ObjCInterfaceDecl *D) {
774 visitDeclContext(D);
775 }
776
777 // ObjCCategoryDecl
visitObjCCategoryDeclAttrs__anone37c897d0111::XMLDumper778 void visitObjCCategoryDeclAttrs(ObjCCategoryDecl *D) {
779 setFlag("extension", D->IsClassExtension());
780 setFlag("synth_bitfield", D->hasSynthBitfield());
781 }
visitObjCCategoryDeclChildren__anone37c897d0111::XMLDumper782 void visitObjCCategoryDeclChildren(ObjCCategoryDecl *D) {
783 visitDeclRef("interface", D->getClassInterface());
784 visitDeclRef("implementation", D->getImplementation());
785 if (D->protocol_begin() != D->protocol_end()) {
786 TemporaryContainer C(*this, "protocols");
787 for (ObjCCategoryDecl::protocol_iterator
788 I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
789 visitDeclRef(*I);
790 }
791 }
visitObjCCategoryDeclAsContext__anone37c897d0111::XMLDumper792 void visitObjCCategoryDeclAsContext(ObjCCategoryDecl *D) {
793 visitDeclContext(D);
794 }
795
796 // ObjCCategoryImplDecl
visitObjCCategoryImplDeclAttrs__anone37c897d0111::XMLDumper797 void visitObjCCategoryImplDeclAttrs(ObjCCategoryImplDecl *D) {
798 set("identifier", D->getName());
799 }
visitObjCCategoryImplDeclChildren__anone37c897d0111::XMLDumper800 void visitObjCCategoryImplDeclChildren(ObjCCategoryImplDecl *D) {
801 visitDeclRef(D->getCategoryDecl());
802 }
803
804 // ObjCImplementationDecl
visitObjCImplementationDeclAttrs__anone37c897d0111::XMLDumper805 void visitObjCImplementationDeclAttrs(ObjCImplementationDecl *D) {
806 setFlag("synth_bitfield", D->hasSynthBitfield());
807 set("identifier", D->getName());
808 }
visitObjCImplementationDeclChildren__anone37c897d0111::XMLDumper809 void visitObjCImplementationDeclChildren(ObjCImplementationDecl *D) {
810 visitDeclRef("super", D->getSuperClass());
811 if (D->init_begin() != D->init_end()) {
812 TemporaryContainer C(*this, "initializers");
813 for (ObjCImplementationDecl::init_iterator
814 I = D->init_begin(), E = D->init_end(); I != E; ++I)
815 dispatch(*I);
816 }
817 }
818
819 // ObjCForwardProtocolDecl
visitObjCForwardProtocolDeclChildren__anone37c897d0111::XMLDumper820 void visitObjCForwardProtocolDeclChildren(ObjCForwardProtocolDecl *D) {
821 for (ObjCForwardProtocolDecl::protocol_iterator
822 I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
823 visitDeclRef(*I);
824 }
825
826 // ObjCProtocolDecl
visitObjCProtocolDeclAttrs__anone37c897d0111::XMLDumper827 void visitObjCProtocolDeclAttrs(ObjCProtocolDecl *D) {
828 setFlag("forward_decl", D->isForwardDecl());
829 }
visitObjCProtocolDeclChildren__anone37c897d0111::XMLDumper830 void visitObjCProtocolDeclChildren(ObjCProtocolDecl *D) {
831 if (D->protocol_begin() != D->protocol_end()) {
832 TemporaryContainer C(*this, "protocols");
833 for (ObjCInterfaceDecl::protocol_iterator
834 I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
835 visitDeclRef(*I);
836 }
837 }
visitObjCProtocolDeclAsContext__anone37c897d0111::XMLDumper838 void visitObjCProtocolDeclAsContext(ObjCProtocolDecl *D) {
839 visitDeclContext(D);
840 }
841
842 // ObjCMethodDecl
visitObjCMethodDeclAttrs__anone37c897d0111::XMLDumper843 void visitObjCMethodDeclAttrs(ObjCMethodDecl *D) {
844 // decl qualifier?
845 // implementation control?
846
847 setFlag("instance", D->isInstanceMethod());
848 setFlag("variadic", D->isVariadic());
849 setFlag("synthesized", D->isSynthesized());
850 setFlag("defined", D->isDefined());
851 setFlag("related_result_type", D->hasRelatedResultType());
852 }
visitObjCMethodDeclChildren__anone37c897d0111::XMLDumper853 void visitObjCMethodDeclChildren(ObjCMethodDecl *D) {
854 dispatch(D->getResultType());
855 for (ObjCMethodDecl::param_iterator
856 I = D->param_begin(), E = D->param_end(); I != E; ++I)
857 dispatch(*I);
858 if (D->isThisDeclarationADefinition())
859 dispatch(D->getBody());
860 }
861
862 // ObjCIvarDecl
setAccessControl__anone37c897d0111::XMLDumper863 void setAccessControl(llvm::StringRef prop, ObjCIvarDecl::AccessControl AC) {
864 switch (AC) {
865 case ObjCIvarDecl::None: return set(prop, "none");
866 case ObjCIvarDecl::Private: return set(prop, "private");
867 case ObjCIvarDecl::Protected: return set(prop, "protected");
868 case ObjCIvarDecl::Public: return set(prop, "public");
869 case ObjCIvarDecl::Package: return set(prop, "package");
870 }
871 }
visitObjCIvarDeclAttrs__anone37c897d0111::XMLDumper872 void visitObjCIvarDeclAttrs(ObjCIvarDecl *D) {
873 setFlag("synthesize", D->getSynthesize());
874 setAccessControl("access", D->getAccessControl());
875 }
876
877 // ObjCCompatibleAliasDecl
visitObjCCompatibleAliasDeclChildren__anone37c897d0111::XMLDumper878 void visitObjCCompatibleAliasDeclChildren(ObjCCompatibleAliasDecl *D) {
879 visitDeclRef(D->getClassInterface());
880 }
881
882 // FIXME: ObjCPropertyDecl
883 // FIXME: ObjCPropertyImplDecl
884
885 //---- Types -----------------------------------------------------//
dispatch__anone37c897d0111::XMLDumper886 void dispatch(TypeLoc TL) {
887 dispatch(TL.getType()); // for now
888 }
889
dispatch__anone37c897d0111::XMLDumper890 void dispatch(QualType T) {
891 if (T.hasLocalQualifiers()) {
892 push("QualType");
893 Qualifiers Qs = T.getLocalQualifiers();
894 setFlag("const", Qs.hasConst());
895 setFlag("volatile", Qs.hasVolatile());
896 setFlag("restrict", Qs.hasRestrict());
897 if (Qs.hasAddressSpace()) setInteger("addrspace", Qs.getAddressSpace());
898 if (Qs.hasObjCGCAttr()) {
899 switch (Qs.getObjCGCAttr()) {
900 case Qualifiers::Weak: set("gc", "weak"); break;
901 case Qualifiers::Strong: set("gc", "strong"); break;
902 case Qualifiers::GCNone: llvm_unreachable("explicit none");
903 }
904 }
905
906 completeAttrs();
907 dispatch(QualType(T.getTypePtr(), 0));
908 pop();
909 return;
910 }
911
912 Type *Ty = const_cast<Type*>(T.getTypePtr());
913 push(getTypeKindName(Ty));
914 XMLTypeVisitor<XMLDumper>::dispatch(const_cast<Type*>(T.getTypePtr()));
915 pop();
916 }
917
setCallingConv__anone37c897d0111::XMLDumper918 void setCallingConv(CallingConv CC) {
919 switch (CC) {
920 case CC_Default: return;
921 case CC_C: return set("cc", "cdecl");
922 case CC_X86FastCall: return set("cc", "x86_fastcall");
923 case CC_X86StdCall: return set("cc", "x86_stdcall");
924 case CC_X86ThisCall: return set("cc", "x86_thiscall");
925 case CC_X86Pascal: return set("cc", "x86_pascal");
926 case CC_AAPCS: return set("cc", "aapcs");
927 case CC_AAPCS_VFP: return set("cc", "aapcs_vfp");
928 }
929 }
930
visitTypeAttrs__anone37c897d0111::XMLDumper931 void visitTypeAttrs(Type *D) {
932 setPointer(D);
933 setFlag("dependent", D->isDependentType());
934 setFlag("variably_modified", D->isVariablyModifiedType());
935
936 setPointer("canonical", D->getCanonicalTypeInternal().getAsOpaquePtr());
937 }
938
visitPointerTypeChildren__anone37c897d0111::XMLDumper939 void visitPointerTypeChildren(PointerType *T) {
940 dispatch(T->getPointeeType());
941 }
visitReferenceTypeChildren__anone37c897d0111::XMLDumper942 void visitReferenceTypeChildren(ReferenceType *T) {
943 dispatch(T->getPointeeType());
944 }
visitObjCObjectPointerTypeChildren__anone37c897d0111::XMLDumper945 void visitObjCObjectPointerTypeChildren(ObjCObjectPointerType *T) {
946 dispatch(T->getPointeeType());
947 }
visitBlockPointerTypeChildren__anone37c897d0111::XMLDumper948 void visitBlockPointerTypeChildren(BlockPointerType *T) {
949 dispatch(T->getPointeeType());
950 }
951
952 // Types that just wrap declarations.
visitTagTypeChildren__anone37c897d0111::XMLDumper953 void visitTagTypeChildren(TagType *T) {
954 visitDeclRef(T->getDecl());
955 }
visitTypedefTypeChildren__anone37c897d0111::XMLDumper956 void visitTypedefTypeChildren(TypedefType *T) {
957 visitDeclRef(T->getDecl());
958 }
visitObjCInterfaceTypeChildren__anone37c897d0111::XMLDumper959 void visitObjCInterfaceTypeChildren(ObjCInterfaceType *T) {
960 visitDeclRef(T->getDecl());
961 }
visitUnresolvedUsingTypeChildren__anone37c897d0111::XMLDumper962 void visitUnresolvedUsingTypeChildren(UnresolvedUsingType *T) {
963 visitDeclRef(T->getDecl());
964 }
visitInjectedClassNameTypeChildren__anone37c897d0111::XMLDumper965 void visitInjectedClassNameTypeChildren(InjectedClassNameType *T) {
966 visitDeclRef(T->getDecl());
967 }
968
visitFunctionTypeAttrs__anone37c897d0111::XMLDumper969 void visitFunctionTypeAttrs(FunctionType *T) {
970 setFlag("noreturn", T->getNoReturnAttr());
971 setCallingConv(T->getCallConv());
972 if (T->getHasRegParm()) setInteger("regparm", T->getRegParmType());
973 }
visitFunctionTypeChildren__anone37c897d0111::XMLDumper974 void visitFunctionTypeChildren(FunctionType *T) {
975 dispatch(T->getResultType());
976 }
977
visitFunctionProtoTypeAttrs__anone37c897d0111::XMLDumper978 void visitFunctionProtoTypeAttrs(FunctionProtoType *T) {
979 setFlag("const", T->getTypeQuals() & Qualifiers::Const);
980 setFlag("volatile", T->getTypeQuals() & Qualifiers::Volatile);
981 setFlag("restrict", T->getTypeQuals() & Qualifiers::Restrict);
982 }
visitFunctionProtoTypeChildren__anone37c897d0111::XMLDumper983 void visitFunctionProtoTypeChildren(FunctionProtoType *T) {
984 push("parameters");
985 setFlag("variadic", T->isVariadic());
986 completeAttrs();
987 for (FunctionProtoType::arg_type_iterator
988 I = T->arg_type_begin(), E = T->arg_type_end(); I != E; ++I)
989 dispatch(*I);
990 pop();
991
992 if (T->hasDynamicExceptionSpec()) {
993 push("exception_specifiers");
994 setFlag("any", T->getExceptionSpecType() == EST_MSAny);
995 completeAttrs();
996 for (FunctionProtoType::exception_iterator
997 I = T->exception_begin(), E = T->exception_end(); I != E; ++I)
998 dispatch(*I);
999 pop();
1000 }
1001 // FIXME: noexcept specifier
1002 }
1003
visitTemplateSpecializationTypeChildren__anone37c897d0111::XMLDumper1004 void visitTemplateSpecializationTypeChildren(TemplateSpecializationType *T) {
1005 if (const RecordType *RT = T->getAs<RecordType>())
1006 visitDeclRef(RT->getDecl());
1007
1008 // TODO: TemplateName
1009
1010 push("template_arguments");
1011 completeAttrs();
1012 for (unsigned I = 0, E = T->getNumArgs(); I != E; ++I)
1013 dispatch(T->getArg(I));
1014 pop();
1015 }
1016
1017 //---- Statements ------------------------------------------------//
dispatch__anone37c897d0111::XMLDumper1018 void dispatch(Stmt *S) {
1019 // FIXME: this is not really XML at all
1020 push("Stmt");
1021 out << ">\n";
1022 Stack.back().State = NS_Children; // explicitly become non-lazy
1023 S->dump(out, Context.getSourceManager());
1024 out << '\n';
1025 pop();
1026 }
1027 };
1028 }
1029
dumpXML() const1030 void Decl::dumpXML() const {
1031 dumpXML(llvm::errs());
1032 }
1033
dumpXML(llvm::raw_ostream & out) const1034 void Decl::dumpXML(llvm::raw_ostream &out) const {
1035 XMLDumper(out, getASTContext()).dispatch(const_cast<Decl*>(this));
1036 }
1037
1038 #else /* ifndef NDEBUG */
1039
dumpXML() const1040 void Decl::dumpXML() const {}
dumpXML(llvm::raw_ostream & out) const1041 void Decl::dumpXML(llvm::raw_ostream &out) const {}
1042
1043 #endif
1044