1 //===--- DumpXML.cpp - Detailed XML dumping -------------------------------===//
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/Attr.h"
21 #include "clang/AST/Decl.h"
22 #include "clang/AST/DeclCXX.h"
23 #include "clang/AST/DeclFriend.h"
24 #include "clang/AST/DeclObjC.h"
25 #include "clang/AST/DeclTemplate.h"
26 #include "clang/AST/DeclVisitor.h"
27 #include "clang/AST/Expr.h"
28 #include "clang/AST/ExprCXX.h"
29 #include "clang/AST/ExprObjC.h"
30 #include "clang/AST/NestedNameSpecifier.h"
31 #include "clang/AST/Stmt.h"
32 #include "clang/AST/StmtCXX.h"
33 #include "clang/AST/StmtObjC.h"
34 #include "clang/AST/StmtVisitor.h"
35 #include "clang/AST/TemplateBase.h"
36 #include "clang/AST/TemplateName.h"
37 #include "clang/AST/Type.h"
38 #include "clang/AST/TypeLoc.h"
39 #include "clang/AST/TypeLocVisitor.h"
40 #include "clang/AST/TypeVisitor.h"
41 #include "llvm/ADT/SmallString.h"
42
43 using namespace clang;
44
45 #ifndef NDEBUG
46
47 namespace {
48
49 enum NodeState {
50 NS_Attrs, NS_LazyChildren, NS_Children
51 };
52
53 struct Node {
54 StringRef Name;
55 NodeState State;
Node__anone86805600111::Node56 Node(StringRef name) : Name(name), State(NS_Attrs) {}
57
isDoneWithAttrs__anone86805600111::Node58 bool isDoneWithAttrs() const { return State != NS_Attrs; }
59 };
60
61 template <class Impl> struct XMLDeclVisitor {
62 #define DISPATCH(NAME, CLASS) \
63 static_cast<Impl*>(this)->NAME(static_cast<CLASS*>(D))
64
dispatch__anone86805600111::XMLDeclVisitor65 void dispatch(Decl *D) {
66 if (D->isUsed())
67 static_cast<Impl*>(this)->set("used", "1");
68 switch (D->getKind()) {
69 #define DECL(DERIVED, BASE) \
70 case Decl::DERIVED: \
71 DISPATCH(dispatch##DERIVED##DeclAttrs, DERIVED##Decl); \
72 static_cast<Impl*>(this)->completeAttrs(); \
73 DISPATCH(dispatch##DERIVED##DeclChildren, DERIVED##Decl); \
74 DISPATCH(dispatch##DERIVED##DeclAsContext, DERIVED##Decl); \
75 break;
76 #define ABSTRACT_DECL(DECL)
77 #include "clang/AST/DeclNodes.inc"
78 }
79 }
80
81 #define DECL(DERIVED, BASE) \
82 void dispatch##DERIVED##DeclAttrs(DERIVED##Decl *D) { \
83 DISPATCH(dispatch##BASE##Attrs, BASE); \
84 DISPATCH(visit##DERIVED##DeclAttrs, DERIVED##Decl); \
85 } \
86 void visit##DERIVED##DeclAttrs(DERIVED##Decl *D) {} \
87 void dispatch##DERIVED##DeclChildren(DERIVED##Decl *D) { \
88 DISPATCH(dispatch##BASE##Children, BASE); \
89 DISPATCH(visit##DERIVED##DeclChildren, DERIVED##Decl); \
90 } \
91 void visit##DERIVED##DeclChildren(DERIVED##Decl *D) {} \
92 void dispatch##DERIVED##DeclAsContext(DERIVED##Decl *D) { \
93 DISPATCH(dispatch##BASE##AsContext, BASE); \
94 DISPATCH(visit##DERIVED##DeclAsContext, DERIVED##Decl); \
95 } \
96 void visit##DERIVED##DeclAsContext(DERIVED##Decl *D) {}
97 #include "clang/AST/DeclNodes.inc"
98
dispatchDeclAttrs__anone86805600111::XMLDeclVisitor99 void dispatchDeclAttrs(Decl *D) {
100 DISPATCH(visitDeclAttrs, Decl);
101 }
visitDeclAttrs__anone86805600111::XMLDeclVisitor102 void visitDeclAttrs(Decl *D) {}
103
dispatchDeclChildren__anone86805600111::XMLDeclVisitor104 void dispatchDeclChildren(Decl *D) {
105 DISPATCH(visitDeclChildren, Decl);
106 }
visitDeclChildren__anone86805600111::XMLDeclVisitor107 void visitDeclChildren(Decl *D) {}
108
dispatchDeclAsContext__anone86805600111::XMLDeclVisitor109 void dispatchDeclAsContext(Decl *D) {
110 DISPATCH(visitDeclAsContext, Decl);
111 }
visitDeclAsContext__anone86805600111::XMLDeclVisitor112 void visitDeclAsContext(Decl *D) {}
113
114 #undef DISPATCH
115 };
116
117 template <class Impl> struct XMLTypeVisitor {
118 #define DISPATCH(NAME, CLASS) \
119 static_cast<Impl*>(this)->NAME(static_cast<CLASS*>(T))
120
dispatch__anone86805600111::XMLTypeVisitor121 void dispatch(Type *T) {
122 switch (T->getTypeClass()) {
123 #define TYPE(DERIVED, BASE) \
124 case Type::DERIVED: \
125 DISPATCH(dispatch##DERIVED##TypeAttrs, DERIVED##Type); \
126 static_cast<Impl*>(this)->completeAttrs(); \
127 DISPATCH(dispatch##DERIVED##TypeChildren, DERIVED##Type); \
128 break;
129 #define ABSTRACT_TYPE(DERIVED, BASE)
130 #include "clang/AST/TypeNodes.def"
131 }
132 }
133
134 #define TYPE(DERIVED, BASE) \
135 void dispatch##DERIVED##TypeAttrs(DERIVED##Type *T) { \
136 DISPATCH(dispatch##BASE##Attrs, BASE); \
137 DISPATCH(visit##DERIVED##TypeAttrs, DERIVED##Type); \
138 } \
139 void visit##DERIVED##TypeAttrs(DERIVED##Type *T) {} \
140 void dispatch##DERIVED##TypeChildren(DERIVED##Type *T) { \
141 DISPATCH(dispatch##BASE##Children, BASE); \
142 DISPATCH(visit##DERIVED##TypeChildren, DERIVED##Type); \
143 } \
144 void visit##DERIVED##TypeChildren(DERIVED##Type *T) {}
145 #include "clang/AST/TypeNodes.def"
146
dispatchTypeAttrs__anone86805600111::XMLTypeVisitor147 void dispatchTypeAttrs(Type *T) {
148 DISPATCH(visitTypeAttrs, Type);
149 }
visitTypeAttrs__anone86805600111::XMLTypeVisitor150 void visitTypeAttrs(Type *T) {}
151
dispatchTypeChildren__anone86805600111::XMLTypeVisitor152 void dispatchTypeChildren(Type *T) {
153 DISPATCH(visitTypeChildren, Type);
154 }
visitTypeChildren__anone86805600111::XMLTypeVisitor155 void visitTypeChildren(Type *T) {}
156
157 #undef DISPATCH
158 };
159
getTypeKindName(Type * T)160 static StringRef getTypeKindName(Type *T) {
161 switch (T->getTypeClass()) {
162 #define TYPE(DERIVED, BASE) case Type::DERIVED: return #DERIVED "Type";
163 #define ABSTRACT_TYPE(DERIVED, BASE)
164 #include "clang/AST/TypeNodes.def"
165 }
166
167 llvm_unreachable("unknown type kind!");
168 }
169
170 struct XMLDumper : public XMLDeclVisitor<XMLDumper>,
171 public XMLTypeVisitor<XMLDumper> {
172 raw_ostream &out;
173 ASTContext &Context;
174 SmallVector<Node, 16> Stack;
175 unsigned Indent;
XMLDumper__anone86805600111::XMLDumper176 explicit XMLDumper(raw_ostream &OS, ASTContext &context)
177 : out(OS), Context(context), Indent(0) {}
178
indent__anone86805600111::XMLDumper179 void indent() {
180 for (unsigned I = Indent; I; --I)
181 out << ' ';
182 }
183
184 /// Push a new node on the stack.
push__anone86805600111::XMLDumper185 void push(StringRef name) {
186 if (!Stack.empty()) {
187 assert(Stack.back().isDoneWithAttrs());
188 if (Stack.back().State == NS_LazyChildren) {
189 Stack.back().State = NS_Children;
190 out << ">\n";
191 }
192 Indent++;
193 indent();
194 }
195 Stack.push_back(Node(name));
196 out << '<' << name;
197 }
198
199 /// Set the given attribute to the given value.
set__anone86805600111::XMLDumper200 void set(StringRef attr, StringRef value) {
201 assert(!Stack.empty() && !Stack.back().isDoneWithAttrs());
202 out << ' ' << attr << '=' << '"' << value << '"'; // TODO: quotation
203 }
204
205 /// Finish attributes.
completeAttrs__anone86805600111::XMLDumper206 void completeAttrs() {
207 assert(!Stack.empty() && !Stack.back().isDoneWithAttrs());
208 Stack.back().State = NS_LazyChildren;
209 }
210
211 /// Pop a node.
pop__anone86805600111::XMLDumper212 void pop() {
213 assert(!Stack.empty() && Stack.back().isDoneWithAttrs());
214 if (Stack.back().State == NS_LazyChildren) {
215 out << "/>\n";
216 } else {
217 indent();
218 out << "</" << Stack.back().Name << ">\n";
219 }
220 if (Stack.size() > 1) Indent--;
221 Stack.pop_back();
222 }
223
224 //---- General utilities -------------------------------------------//
225
setPointer__anone86805600111::XMLDumper226 void setPointer(StringRef prop, const void *p) {
227 SmallString<10> buffer;
228 llvm::raw_svector_ostream os(buffer);
229 os << p;
230 os.flush();
231 set(prop, buffer);
232 }
233
setPointer__anone86805600111::XMLDumper234 void setPointer(void *p) {
235 setPointer("ptr", p);
236 }
237
setInteger__anone86805600111::XMLDumper238 void setInteger(StringRef prop, const llvm::APSInt &v) {
239 set(prop, v.toString(10));
240 }
241
setInteger__anone86805600111::XMLDumper242 void setInteger(StringRef prop, unsigned n) {
243 SmallString<10> buffer;
244 llvm::raw_svector_ostream os(buffer);
245 os << n;
246 os.flush();
247 set(prop, buffer);
248 }
249
setFlag__anone86805600111::XMLDumper250 void setFlag(StringRef prop, bool flag) {
251 if (flag) set(prop, "true");
252 }
253
setName__anone86805600111::XMLDumper254 void setName(DeclarationName Name) {
255 if (!Name)
256 return set("name", "");
257
258 // Common case.
259 if (Name.isIdentifier())
260 return set("name", Name.getAsIdentifierInfo()->getName());
261
262 set("name", Name.getAsString());
263 }
264
265 class TemporaryContainer {
266 XMLDumper &Dumper;
267 public:
TemporaryContainer(XMLDumper & dumper,StringRef name)268 TemporaryContainer(XMLDumper &dumper, StringRef name)
269 : Dumper(dumper) {
270 Dumper.push(name);
271 Dumper.completeAttrs();
272 }
273
~TemporaryContainer()274 ~TemporaryContainer() {
275 Dumper.pop();
276 }
277 };
278
visitTemplateParameters__anone86805600111::XMLDumper279 void visitTemplateParameters(TemplateParameterList *L) {
280 push("template_parameters");
281 completeAttrs();
282 for (TemplateParameterList::iterator
283 I = L->begin(), E = L->end(); I != E; ++I)
284 dispatch(*I);
285 pop();
286 }
287
visitTemplateArguments__anone86805600111::XMLDumper288 void visitTemplateArguments(const TemplateArgumentList &L) {
289 push("template_arguments");
290 completeAttrs();
291 for (unsigned I = 0, E = L.size(); I != E; ++I)
292 dispatch(L[I]);
293 pop();
294 }
295
296 /// Visits a reference to the given declaration.
visitDeclRef__anone86805600111::XMLDumper297 void visitDeclRef(Decl *D) {
298 push(D->getDeclKindName());
299 setPointer("ref", D);
300 completeAttrs();
301 pop();
302 }
visitDeclRef__anone86805600111::XMLDumper303 void visitDeclRef(StringRef Name, Decl *D) {
304 TemporaryContainer C(*this, Name);
305 if (D) visitDeclRef(D);
306 }
307
dispatch__anone86805600111::XMLDumper308 void dispatch(const TemplateArgument &A) {
309 switch (A.getKind()) {
310 case TemplateArgument::Null: {
311 TemporaryContainer C(*this, "null");
312 break;
313 }
314 case TemplateArgument::Type: {
315 dispatch(A.getAsType());
316 break;
317 }
318 case TemplateArgument::Template:
319 case TemplateArgument::TemplateExpansion:
320 case TemplateArgument::NullPtr:
321 // FIXME: Implement!
322 break;
323
324 case TemplateArgument::Declaration: {
325 visitDeclRef(A.getAsDecl());
326 break;
327 }
328 case TemplateArgument::Integral: {
329 push("integer");
330 setInteger("value", A.getAsIntegral());
331 completeAttrs();
332 pop();
333 break;
334 }
335 case TemplateArgument::Expression: {
336 dispatch(A.getAsExpr());
337 break;
338 }
339 case TemplateArgument::Pack: {
340 for (TemplateArgument::pack_iterator P = A.pack_begin(),
341 PEnd = A.pack_end();
342 P != PEnd; ++P)
343 dispatch(*P);
344 break;
345 }
346 }
347 }
348
dispatch__anone86805600111::XMLDumper349 void dispatch(const TemplateArgumentLoc &A) {
350 dispatch(A.getArgument());
351 }
352
353 //---- Declarations ------------------------------------------------//
354 // Calls are made in this order:
355 // # Enter a new node.
356 // push("FieldDecl")
357 //
358 // # In this phase, attributes are set on the node.
359 // visitDeclAttrs(D)
360 // visitNamedDeclAttrs(D)
361 // ...
362 // visitFieldDeclAttrs(D)
363 //
364 // # No more attributes after this point.
365 // completeAttrs()
366 //
367 // # Create "header" child nodes, i.e. those which logically
368 // # belong to the declaration itself.
369 // visitDeclChildren(D)
370 // visitNamedDeclChildren(D)
371 // ...
372 // visitFieldDeclChildren(D)
373 //
374 // # Create nodes for the lexical children.
375 // visitDeclAsContext(D)
376 // visitNamedDeclAsContext(D)
377 // ...
378 // visitFieldDeclAsContext(D)
379 //
380 // # Finish the node.
381 // pop();
dispatch__anone86805600111::XMLDumper382 void dispatch(Decl *D) {
383 push(D->getDeclKindName());
384 XMLDeclVisitor<XMLDumper>::dispatch(D);
385 pop();
386 }
visitDeclAttrs__anone86805600111::XMLDumper387 void visitDeclAttrs(Decl *D) {
388 setPointer(D);
389 }
390
391 /// Visit all the lexical decls in the given context.
visitDeclContext__anone86805600111::XMLDumper392 void visitDeclContext(DeclContext *DC) {
393 for (DeclContext::decl_iterator
394 I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
395 dispatch(*I);
396
397 // FIXME: point out visible declarations not in lexical context?
398 }
399
400 /// Set the "access" attribute on the current node according to the
401 /// given specifier.
setAccess__anone86805600111::XMLDumper402 void setAccess(AccessSpecifier AS) {
403 switch (AS) {
404 case AS_public: return set("access", "public");
405 case AS_protected: return set("access", "protected");
406 case AS_private: return set("access", "private");
407 case AS_none: llvm_unreachable("explicit forbidden access");
408 }
409 }
410
visitRedeclarableAttrs__anone86805600111::XMLDumper411 template <class T> void visitRedeclarableAttrs(T *D) {
412 if (T *Prev = D->getPreviousDecl())
413 setPointer("previous", Prev);
414 }
415
416
417 // TranslationUnitDecl
visitTranslationUnitDeclAsContext__anone86805600111::XMLDumper418 void visitTranslationUnitDeclAsContext(TranslationUnitDecl *D) {
419 visitDeclContext(D);
420 }
421
422 // LinkageSpecDecl
visitLinkageSpecDeclAttrs__anone86805600111::XMLDumper423 void visitLinkageSpecDeclAttrs(LinkageSpecDecl *D) {
424 StringRef lang = "";
425 switch (D->getLanguage()) {
426 case LinkageSpecDecl::lang_c: lang = "C"; break;
427 case LinkageSpecDecl::lang_cxx: lang = "C++"; break;
428 }
429 set("lang", lang);
430 }
visitLinkageSpecDeclAsContext__anone86805600111::XMLDumper431 void visitLinkageSpecDeclAsContext(LinkageSpecDecl *D) {
432 visitDeclContext(D);
433 }
434
435 // NamespaceDecl
visitNamespaceDeclAttrs__anone86805600111::XMLDumper436 void visitNamespaceDeclAttrs(NamespaceDecl *D) {
437 setFlag("inline", D->isInline());
438 if (!D->isOriginalNamespace())
439 setPointer("original", D->getOriginalNamespace());
440 }
visitNamespaceDeclAsContext__anone86805600111::XMLDumper441 void visitNamespaceDeclAsContext(NamespaceDecl *D) {
442 visitDeclContext(D);
443 }
444
445 // NamedDecl
visitNamedDeclAttrs__anone86805600111::XMLDumper446 void visitNamedDeclAttrs(NamedDecl *D) {
447 setName(D->getDeclName());
448 }
449
450 // ValueDecl
visitValueDeclChildren__anone86805600111::XMLDumper451 void visitValueDeclChildren(ValueDecl *D) {
452 dispatch(D->getType());
453 }
454
455 // DeclaratorDecl
visitDeclaratorDeclChildren__anone86805600111::XMLDumper456 void visitDeclaratorDeclChildren(DeclaratorDecl *D) {
457 //dispatch(D->getTypeSourceInfo()->getTypeLoc());
458 }
459
460 // VarDecl
visitVarDeclAttrs__anone86805600111::XMLDumper461 void visitVarDeclAttrs(VarDecl *D) {
462 visitRedeclarableAttrs(D);
463 if (D->getStorageClass() != SC_None)
464 set("storage",
465 VarDecl::getStorageClassSpecifierString(D->getStorageClass()));
466 StringRef initStyle = "";
467 switch (D->getInitStyle()) {
468 case VarDecl::CInit: initStyle = "c"; break;
469 case VarDecl::CallInit: initStyle = "call"; break;
470 case VarDecl::ListInit: initStyle = "list"; break;
471 }
472 set("initstyle", initStyle);
473 setFlag("nrvo", D->isNRVOVariable());
474 // TODO: instantiation, etc.
475 }
visitVarDeclChildren__anone86805600111::XMLDumper476 void visitVarDeclChildren(VarDecl *D) {
477 if (D->hasInit()) dispatch(D->getInit());
478 }
479
480 // ParmVarDecl?
481
482 // FunctionDecl
visitFunctionDeclAttrs__anone86805600111::XMLDumper483 void visitFunctionDeclAttrs(FunctionDecl *D) {
484 visitRedeclarableAttrs(D);
485 setFlag("pure", D->isPure());
486 setFlag("trivial", D->isTrivial());
487 setFlag("returnzero", D->hasImplicitReturnZero());
488 setFlag("prototype", D->hasWrittenPrototype());
489 setFlag("deleted", D->isDeletedAsWritten());
490 if (D->getStorageClass() != SC_None)
491 set("storage",
492 VarDecl::getStorageClassSpecifierString(D->getStorageClass()));
493 setFlag("inline", D->isInlineSpecified());
494 if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>())
495 set("asmlabel", ALA->getLabel());
496 // TODO: instantiation, etc.
497 }
visitFunctionDeclChildren__anone86805600111::XMLDumper498 void visitFunctionDeclChildren(FunctionDecl *D) {
499 for (FunctionDecl::param_iterator
500 I = D->param_begin(), E = D->param_end(); I != E; ++I)
501 dispatch(*I);
502 for (ArrayRef<NamedDecl *>::iterator I = D->getDeclsInPrototypeScope().begin(),
503 E = D->getDeclsInPrototypeScope().end();
504 I != E; ++I)
505 dispatch(*I);
506 if (D->doesThisDeclarationHaveABody())
507 dispatch(D->getBody());
508 }
509
510 // CXXMethodDecl ?
511 // CXXConstructorDecl ?
512 // CXXDestructorDecl ?
513 // CXXConversionDecl ?
514
dispatch__anone86805600111::XMLDumper515 void dispatch(CXXCtorInitializer *Init) {
516 // TODO
517 }
518
519 // FieldDecl
visitFieldDeclAttrs__anone86805600111::XMLDumper520 void visitFieldDeclAttrs(FieldDecl *D) {
521 setFlag("mutable", D->isMutable());
522 }
visitFieldDeclChildren__anone86805600111::XMLDumper523 void visitFieldDeclChildren(FieldDecl *D) {
524 if (D->isBitField()) {
525 TemporaryContainer C(*this, "bitwidth");
526 dispatch(D->getBitWidth());
527 }
528 // TODO: C++0x member initializer
529 }
530
531 // EnumConstantDecl
visitEnumConstantDeclChildren__anone86805600111::XMLDumper532 void visitEnumConstantDeclChildren(EnumConstantDecl *D) {
533 // value in any case?
534 if (D->getInitExpr()) dispatch(D->getInitExpr());
535 }
536
537 // IndirectFieldDecl
visitIndirectFieldDeclChildren__anone86805600111::XMLDumper538 void visitIndirectFieldDeclChildren(IndirectFieldDecl *D) {
539 for (IndirectFieldDecl::chain_iterator
540 I = D->chain_begin(), E = D->chain_end(); I != E; ++I) {
541 NamedDecl *VD = const_cast<NamedDecl*>(*I);
542 push(isa<VarDecl>(VD) ? "variable" : "field");
543 setPointer("ptr", VD);
544 completeAttrs();
545 pop();
546 }
547 }
548
549 // TypeDecl
visitTypeDeclAttrs__anone86805600111::XMLDumper550 void visitTypeDeclAttrs(TypeDecl *D) {
551 setPointer("typeptr", D->getTypeForDecl());
552 }
553
554 // TypedefDecl
visitTypedefDeclAttrs__anone86805600111::XMLDumper555 void visitTypedefDeclAttrs(TypedefDecl *D) {
556 visitRedeclarableAttrs<TypedefNameDecl>(D);
557 }
visitTypedefDeclChildren__anone86805600111::XMLDumper558 void visitTypedefDeclChildren(TypedefDecl *D) {
559 dispatch(D->getTypeSourceInfo()->getTypeLoc());
560 }
561
562 // TypeAliasDecl
visitTypeAliasDeclAttrs__anone86805600111::XMLDumper563 void visitTypeAliasDeclAttrs(TypeAliasDecl *D) {
564 visitRedeclarableAttrs<TypedefNameDecl>(D);
565 }
visitTypeAliasDeclChildren__anone86805600111::XMLDumper566 void visitTypeAliasDeclChildren(TypeAliasDecl *D) {
567 dispatch(D->getTypeSourceInfo()->getTypeLoc());
568 }
569
570 // TagDecl
visitTagDeclAttrs__anone86805600111::XMLDumper571 void visitTagDeclAttrs(TagDecl *D) {
572 visitRedeclarableAttrs(D);
573 }
visitTagDeclAsContext__anone86805600111::XMLDumper574 void visitTagDeclAsContext(TagDecl *D) {
575 visitDeclContext(D);
576 }
577
578 // EnumDecl
visitEnumDeclAttrs__anone86805600111::XMLDumper579 void visitEnumDeclAttrs(EnumDecl *D) {
580 setFlag("scoped", D->isScoped());
581 setFlag("fixed", D->isFixed());
582 }
visitEnumDeclChildren__anone86805600111::XMLDumper583 void visitEnumDeclChildren(EnumDecl *D) {
584 {
585 TemporaryContainer C(*this, "promotion_type");
586 dispatch(D->getPromotionType());
587 }
588 {
589 TemporaryContainer C(*this, "integer_type");
590 dispatch(D->getIntegerType());
591 }
592 }
593
594 // RecordDecl ?
595
visitCXXRecordDeclChildren__anone86805600111::XMLDumper596 void visitCXXRecordDeclChildren(CXXRecordDecl *D) {
597 if (!D->isThisDeclarationADefinition()) return;
598
599 for (CXXRecordDecl::base_class_iterator
600 I = D->bases_begin(), E = D->bases_end(); I != E; ++I) {
601 push("base");
602 setAccess(I->getAccessSpecifier());
603 completeAttrs();
604 dispatch(I->getTypeSourceInfo()->getTypeLoc());
605 pop();
606 }
607 }
608
609 // ClassTemplateSpecializationDecl ?
610
611 // FileScopeAsmDecl ?
612
613 // BlockDecl
visitBlockDeclAttrs__anone86805600111::XMLDumper614 void visitBlockDeclAttrs(BlockDecl *D) {
615 setFlag("variadic", D->isVariadic());
616 }
visitBlockDeclChildren__anone86805600111::XMLDumper617 void visitBlockDeclChildren(BlockDecl *D) {
618 for (FunctionDecl::param_iterator
619 I = D->param_begin(), E = D->param_end(); I != E; ++I)
620 dispatch(*I);
621 dispatch(D->getBody());
622 }
623
624 // AccessSpecDecl
visitAccessSpecDeclAttrs__anone86805600111::XMLDumper625 void visitAccessSpecDeclAttrs(AccessSpecDecl *D) {
626 setAccess(D->getAccess());
627 }
628
629 // TemplateDecl
visitTemplateDeclChildren__anone86805600111::XMLDumper630 void visitTemplateDeclChildren(TemplateDecl *D) {
631 visitTemplateParameters(D->getTemplateParameters());
632 if (D->getTemplatedDecl())
633 dispatch(D->getTemplatedDecl());
634 }
635
636 // FunctionTemplateDecl
visitFunctionTemplateDeclAttrs__anone86805600111::XMLDumper637 void visitFunctionTemplateDeclAttrs(FunctionTemplateDecl *D) {
638 visitRedeclarableAttrs(D);
639 }
visitFunctionTemplateDeclChildren__anone86805600111::XMLDumper640 void visitFunctionTemplateDeclChildren(FunctionTemplateDecl *D) {
641 // Mention all the specializations which don't have explicit
642 // declarations elsewhere.
643 for (FunctionTemplateDecl::spec_iterator
644 I = D->spec_begin(), E = D->spec_end(); I != E; ++I) {
645 FunctionTemplateSpecializationInfo *Info
646 = I->getTemplateSpecializationInfo();
647
648 bool Unknown = false;
649 switch (Info->getTemplateSpecializationKind()) {
650 case TSK_ImplicitInstantiation: Unknown = false; break;
651 case TSK_Undeclared: Unknown = true; break;
652
653 // These will be covered at their respective sites.
654 case TSK_ExplicitSpecialization: continue;
655 case TSK_ExplicitInstantiationDeclaration: continue;
656 case TSK_ExplicitInstantiationDefinition: continue;
657 }
658
659 TemporaryContainer C(*this,
660 Unknown ? "uninstantiated" : "instantiation");
661 visitTemplateArguments(*Info->TemplateArguments);
662 dispatch(Info->Function);
663 }
664 }
665
666 // ClasTemplateDecl
visitClassTemplateDeclAttrs__anone86805600111::XMLDumper667 void visitClassTemplateDeclAttrs(ClassTemplateDecl *D) {
668 visitRedeclarableAttrs(D);
669 }
visitClassTemplateDeclChildren__anone86805600111::XMLDumper670 void visitClassTemplateDeclChildren(ClassTemplateDecl *D) {
671 // Mention all the specializations which don't have explicit
672 // declarations elsewhere.
673 for (ClassTemplateDecl::spec_iterator
674 I = D->spec_begin(), E = D->spec_end(); I != E; ++I) {
675
676 bool Unknown = false;
677 switch (I->getTemplateSpecializationKind()) {
678 case TSK_ImplicitInstantiation: Unknown = false; break;
679 case TSK_Undeclared: Unknown = true; break;
680
681 // These will be covered at their respective sites.
682 case TSK_ExplicitSpecialization: continue;
683 case TSK_ExplicitInstantiationDeclaration: continue;
684 case TSK_ExplicitInstantiationDefinition: continue;
685 }
686
687 TemporaryContainer C(*this,
688 Unknown ? "uninstantiated" : "instantiation");
689 visitTemplateArguments(I->getTemplateArgs());
690 dispatch(*I);
691 }
692 }
693
694 // TemplateTypeParmDecl
visitTemplateTypeParmDeclAttrs__anone86805600111::XMLDumper695 void visitTemplateTypeParmDeclAttrs(TemplateTypeParmDecl *D) {
696 setInteger("depth", D->getDepth());
697 setInteger("index", D->getIndex());
698 }
visitTemplateTypeParmDeclChildren__anone86805600111::XMLDumper699 void visitTemplateTypeParmDeclChildren(TemplateTypeParmDecl *D) {
700 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
701 dispatch(D->getDefaultArgumentInfo()->getTypeLoc());
702 // parameter pack?
703 }
704
705 // NonTypeTemplateParmDecl
visitNonTypeTemplateParmDeclAttrs__anone86805600111::XMLDumper706 void visitNonTypeTemplateParmDeclAttrs(NonTypeTemplateParmDecl *D) {
707 setInteger("depth", D->getDepth());
708 setInteger("index", D->getIndex());
709 }
visitNonTypeTemplateParmDeclChildren__anone86805600111::XMLDumper710 void visitNonTypeTemplateParmDeclChildren(NonTypeTemplateParmDecl *D) {
711 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
712 dispatch(D->getDefaultArgument());
713 // parameter pack?
714 }
715
716 // TemplateTemplateParmDecl
visitTemplateTemplateParmDeclAttrs__anone86805600111::XMLDumper717 void visitTemplateTemplateParmDeclAttrs(TemplateTemplateParmDecl *D) {
718 setInteger("depth", D->getDepth());
719 setInteger("index", D->getIndex());
720 }
visitTemplateTemplateParmDeclChildren__anone86805600111::XMLDumper721 void visitTemplateTemplateParmDeclChildren(TemplateTemplateParmDecl *D) {
722 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
723 dispatch(D->getDefaultArgument());
724 // parameter pack?
725 }
726
727 // FriendDecl
visitFriendDeclChildren__anone86805600111::XMLDumper728 void visitFriendDeclChildren(FriendDecl *D) {
729 if (TypeSourceInfo *T = D->getFriendType())
730 dispatch(T->getTypeLoc());
731 else
732 dispatch(D->getFriendDecl());
733 }
734
735 // UsingDirectiveDecl ?
736 // UsingDecl ?
737 // UsingShadowDecl ?
738 // NamespaceAliasDecl ?
739 // UnresolvedUsingValueDecl ?
740 // UnresolvedUsingTypenameDecl ?
741 // StaticAssertDecl ?
742
743 // ObjCImplDecl
visitObjCImplDeclChildren__anone86805600111::XMLDumper744 void visitObjCImplDeclChildren(ObjCImplDecl *D) {
745 visitDeclRef(D->getClassInterface());
746 }
visitObjCImplDeclAsContext__anone86805600111::XMLDumper747 void visitObjCImplDeclAsContext(ObjCImplDecl *D) {
748 visitDeclContext(D);
749 }
750
visitObjCInterfaceDeclAttrs__anone86805600111::XMLDumper751 void visitObjCInterfaceDeclAttrs(ObjCInterfaceDecl *D) {
752 setPointer("typeptr", D->getTypeForDecl());
753 setFlag("forward_decl", !D->isThisDeclarationADefinition());
754 setFlag("implicit_interface", D->isImplicitInterfaceDecl());
755 }
visitObjCInterfaceDeclChildren__anone86805600111::XMLDumper756 void visitObjCInterfaceDeclChildren(ObjCInterfaceDecl *D) {
757 visitDeclRef("super", D->getSuperClass());
758 visitDeclRef("implementation", D->getImplementation());
759 if (D->protocol_begin() != D->protocol_end()) {
760 TemporaryContainer C(*this, "protocols");
761 for (ObjCInterfaceDecl::protocol_iterator
762 I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
763 visitDeclRef(*I);
764 }
765
766 if (!D->visible_categories_empty()) {
767 TemporaryContainer C(*this, "categories");
768
769 for (ObjCInterfaceDecl::visible_categories_iterator
770 Cat = D->visible_categories_begin(),
771 CatEnd = D->visible_categories_end();
772 Cat != CatEnd; ++Cat) {
773 visitDeclRef(*Cat);
774 }
775 }
776 }
visitObjCInterfaceDeclAsContext__anone86805600111::XMLDumper777 void visitObjCInterfaceDeclAsContext(ObjCInterfaceDecl *D) {
778 visitDeclContext(D);
779 }
780
781 // ObjCCategoryDecl
visitObjCCategoryDeclAttrs__anone86805600111::XMLDumper782 void visitObjCCategoryDeclAttrs(ObjCCategoryDecl *D) {
783 setFlag("extension", D->IsClassExtension());
784 }
visitObjCCategoryDeclChildren__anone86805600111::XMLDumper785 void visitObjCCategoryDeclChildren(ObjCCategoryDecl *D) {
786 visitDeclRef("interface", D->getClassInterface());
787 visitDeclRef("implementation", D->getImplementation());
788 if (D->protocol_begin() != D->protocol_end()) {
789 TemporaryContainer C(*this, "protocols");
790 for (ObjCCategoryDecl::protocol_iterator
791 I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
792 visitDeclRef(*I);
793 }
794 }
visitObjCCategoryDeclAsContext__anone86805600111::XMLDumper795 void visitObjCCategoryDeclAsContext(ObjCCategoryDecl *D) {
796 visitDeclContext(D);
797 }
798
799 // ObjCCategoryImplDecl
visitObjCCategoryImplDeclAttrs__anone86805600111::XMLDumper800 void visitObjCCategoryImplDeclAttrs(ObjCCategoryImplDecl *D) {
801 set("identifier", D->getName());
802 }
visitObjCCategoryImplDeclChildren__anone86805600111::XMLDumper803 void visitObjCCategoryImplDeclChildren(ObjCCategoryImplDecl *D) {
804 visitDeclRef(D->getCategoryDecl());
805 }
806
807 // ObjCImplementationDecl
visitObjCImplementationDeclAttrs__anone86805600111::XMLDumper808 void visitObjCImplementationDeclAttrs(ObjCImplementationDecl *D) {
809 set("identifier", D->getName());
810 }
visitObjCImplementationDeclChildren__anone86805600111::XMLDumper811 void visitObjCImplementationDeclChildren(ObjCImplementationDecl *D) {
812 visitDeclRef("super", D->getSuperClass());
813 if (D->init_begin() != D->init_end()) {
814 TemporaryContainer C(*this, "initializers");
815 for (ObjCImplementationDecl::init_iterator
816 I = D->init_begin(), E = D->init_end(); I != E; ++I)
817 dispatch(*I);
818 }
819 }
820
821 // ObjCProtocolDecl
visitObjCProtocolDeclChildren__anone86805600111::XMLDumper822 void visitObjCProtocolDeclChildren(ObjCProtocolDecl *D) {
823 if (!D->isThisDeclarationADefinition())
824 return;
825
826 if (D->protocol_begin() != D->protocol_end()) {
827 TemporaryContainer C(*this, "protocols");
828 for (ObjCInterfaceDecl::protocol_iterator
829 I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
830 visitDeclRef(*I);
831 }
832 }
visitObjCProtocolDeclAsContext__anone86805600111::XMLDumper833 void visitObjCProtocolDeclAsContext(ObjCProtocolDecl *D) {
834 if (!D->isThisDeclarationADefinition())
835 return;
836
837 visitDeclContext(D);
838 }
839
840 // ObjCMethodDecl
visitObjCMethodDeclAttrs__anone86805600111::XMLDumper841 void visitObjCMethodDeclAttrs(ObjCMethodDecl *D) {
842 // decl qualifier?
843 // implementation control?
844
845 setFlag("instance", D->isInstanceMethod());
846 setFlag("variadic", D->isVariadic());
847 setFlag("property_accessor", D->isPropertyAccessor());
848 setFlag("defined", D->isDefined());
849 setFlag("related_result_type", D->hasRelatedResultType());
850 }
visitObjCMethodDeclChildren__anone86805600111::XMLDumper851 void visitObjCMethodDeclChildren(ObjCMethodDecl *D) {
852 dispatch(D->getResultType());
853 for (ObjCMethodDecl::param_iterator
854 I = D->param_begin(), E = D->param_end(); I != E; ++I)
855 dispatch(*I);
856 if (D->isThisDeclarationADefinition())
857 dispatch(D->getBody());
858 }
859
860 // ObjCIvarDecl
setAccessControl__anone86805600111::XMLDumper861 void setAccessControl(StringRef prop, ObjCIvarDecl::AccessControl AC) {
862 switch (AC) {
863 case ObjCIvarDecl::None: return set(prop, "none");
864 case ObjCIvarDecl::Private: return set(prop, "private");
865 case ObjCIvarDecl::Protected: return set(prop, "protected");
866 case ObjCIvarDecl::Public: return set(prop, "public");
867 case ObjCIvarDecl::Package: return set(prop, "package");
868 }
869 }
visitObjCIvarDeclAttrs__anone86805600111::XMLDumper870 void visitObjCIvarDeclAttrs(ObjCIvarDecl *D) {
871 setFlag("synthesize", D->getSynthesize());
872 setAccessControl("access", D->getAccessControl());
873 }
874
875 // ObjCCompatibleAliasDecl
visitObjCCompatibleAliasDeclChildren__anone86805600111::XMLDumper876 void visitObjCCompatibleAliasDeclChildren(ObjCCompatibleAliasDecl *D) {
877 visitDeclRef(D->getClassInterface());
878 }
879
880 // FIXME: ObjCPropertyDecl
881 // FIXME: ObjCPropertyImplDecl
882
883 //---- Types -----------------------------------------------------//
dispatch__anone86805600111::XMLDumper884 void dispatch(TypeLoc TL) {
885 dispatch(TL.getType()); // for now
886 }
887
dispatch__anone86805600111::XMLDumper888 void dispatch(QualType T) {
889 if (T.hasLocalQualifiers()) {
890 push("QualType");
891 Qualifiers Qs = T.getLocalQualifiers();
892 setFlag("const", Qs.hasConst());
893 setFlag("volatile", Qs.hasVolatile());
894 setFlag("restrict", Qs.hasRestrict());
895 if (Qs.hasAddressSpace()) setInteger("addrspace", Qs.getAddressSpace());
896 if (Qs.hasObjCGCAttr()) {
897 switch (Qs.getObjCGCAttr()) {
898 case Qualifiers::Weak: set("gc", "weak"); break;
899 case Qualifiers::Strong: set("gc", "strong"); break;
900 case Qualifiers::GCNone: llvm_unreachable("explicit none");
901 }
902 }
903
904 completeAttrs();
905 dispatch(QualType(T.getTypePtr(), 0));
906 pop();
907 return;
908 }
909
910 Type *Ty = const_cast<Type*>(T.getTypePtr());
911 push(getTypeKindName(Ty));
912 XMLTypeVisitor<XMLDumper>::dispatch(const_cast<Type*>(T.getTypePtr()));
913 pop();
914 }
915
setCallingConv__anone86805600111::XMLDumper916 void setCallingConv(CallingConv CC) {
917 switch (CC) {
918 case CC_Default: return;
919 case CC_C: return set("cc", "cdecl");
920 case CC_X86FastCall: return set("cc", "x86_fastcall");
921 case CC_X86StdCall: return set("cc", "x86_stdcall");
922 case CC_X86ThisCall: return set("cc", "x86_thiscall");
923 case CC_X86Pascal: return set("cc", "x86_pascal");
924 case CC_AAPCS: return set("cc", "aapcs");
925 case CC_AAPCS_VFP: return set("cc", "aapcs_vfp");
926 case CC_PnaclCall: return set("cc", "pnaclcall");
927 case CC_IntelOclBicc: return set("cc", "intel_ocl_bicc");
928 }
929 }
930
visitTypeAttrs__anone86805600111::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__anone86805600111::XMLDumper939 void visitPointerTypeChildren(PointerType *T) {
940 dispatch(T->getPointeeType());
941 }
visitReferenceTypeChildren__anone86805600111::XMLDumper942 void visitReferenceTypeChildren(ReferenceType *T) {
943 dispatch(T->getPointeeType());
944 }
visitObjCObjectPointerTypeChildren__anone86805600111::XMLDumper945 void visitObjCObjectPointerTypeChildren(ObjCObjectPointerType *T) {
946 dispatch(T->getPointeeType());
947 }
visitBlockPointerTypeChildren__anone86805600111::XMLDumper948 void visitBlockPointerTypeChildren(BlockPointerType *T) {
949 dispatch(T->getPointeeType());
950 }
951
952 // Types that just wrap declarations.
visitTagTypeChildren__anone86805600111::XMLDumper953 void visitTagTypeChildren(TagType *T) {
954 visitDeclRef(T->getDecl());
955 }
visitTypedefTypeChildren__anone86805600111::XMLDumper956 void visitTypedefTypeChildren(TypedefType *T) {
957 visitDeclRef(T->getDecl());
958 }
visitObjCInterfaceTypeChildren__anone86805600111::XMLDumper959 void visitObjCInterfaceTypeChildren(ObjCInterfaceType *T) {
960 visitDeclRef(T->getDecl());
961 }
visitUnresolvedUsingTypeChildren__anone86805600111::XMLDumper962 void visitUnresolvedUsingTypeChildren(UnresolvedUsingType *T) {
963 visitDeclRef(T->getDecl());
964 }
visitInjectedClassNameTypeChildren__anone86805600111::XMLDumper965 void visitInjectedClassNameTypeChildren(InjectedClassNameType *T) {
966 visitDeclRef(T->getDecl());
967 }
968
visitFunctionTypeAttrs__anone86805600111::XMLDumper969 void visitFunctionTypeAttrs(FunctionType *T) {
970 setFlag("noreturn", T->getNoReturnAttr());
971 setCallingConv(T->getCallConv());
972 if (T->getHasRegParm()) setInteger("regparm", T->getRegParmType());
973 }
visitFunctionTypeChildren__anone86805600111::XMLDumper974 void visitFunctionTypeChildren(FunctionType *T) {
975 dispatch(T->getResultType());
976 }
977
visitFunctionProtoTypeAttrs__anone86805600111::XMLDumper978 void visitFunctionProtoTypeAttrs(FunctionProtoType *T) {
979 setFlag("const", T->isConst());
980 setFlag("volatile", T->isVolatile());
981 setFlag("restrict", T->isRestrict());
982 switch (T->getExceptionSpecType()) {
983 case EST_None: break;
984 case EST_DynamicNone: set("exception_spec", "throw()"); break;
985 case EST_Dynamic: set("exception_spec", "throw(T)"); break;
986 case EST_MSAny: set("exception_spec", "throw(...)"); break;
987 case EST_BasicNoexcept: set("exception_spec", "noexcept"); break;
988 case EST_ComputedNoexcept: set("exception_spec", "noexcept(expr)"); break;
989 case EST_Unevaluated: set("exception_spec", "unevaluated"); break;
990 case EST_Uninstantiated: set("exception_spec", "uninstantiated"); break;
991 }
992 }
visitFunctionProtoTypeChildren__anone86805600111::XMLDumper993 void visitFunctionProtoTypeChildren(FunctionProtoType *T) {
994 push("parameters");
995 setFlag("variadic", T->isVariadic());
996 completeAttrs();
997 for (FunctionProtoType::arg_type_iterator
998 I = T->arg_type_begin(), E = T->arg_type_end(); I != E; ++I)
999 dispatch(*I);
1000 pop();
1001
1002 if (T->hasDynamicExceptionSpec()) {
1003 push("exception_specifiers");
1004 setFlag("any", T->getExceptionSpecType() == EST_MSAny);
1005 completeAttrs();
1006 for (FunctionProtoType::exception_iterator
1007 I = T->exception_begin(), E = T->exception_end(); I != E; ++I)
1008 dispatch(*I);
1009 pop();
1010 }
1011 // FIXME: noexcept specifier
1012 }
1013
visitTemplateSpecializationTypeChildren__anone86805600111::XMLDumper1014 void visitTemplateSpecializationTypeChildren(TemplateSpecializationType *T) {
1015 if (const RecordType *RT = T->getAs<RecordType>())
1016 visitDeclRef(RT->getDecl());
1017
1018 // TODO: TemplateName
1019
1020 push("template_arguments");
1021 completeAttrs();
1022 for (unsigned I = 0, E = T->getNumArgs(); I != E; ++I)
1023 dispatch(T->getArg(I));
1024 pop();
1025 }
1026
1027 //---- Statements ------------------------------------------------//
dispatch__anone86805600111::XMLDumper1028 void dispatch(Stmt *S) {
1029 // FIXME: this is not really XML at all
1030 push("Stmt");
1031 out << ">\n";
1032 Stack.back().State = NS_Children; // explicitly become non-lazy
1033 S->dump(out, Context.getSourceManager());
1034 out << '\n';
1035 pop();
1036 }
1037 };
1038 }
1039
dumpXML() const1040 void Decl::dumpXML() const {
1041 dumpXML(llvm::errs());
1042 }
1043
dumpXML(raw_ostream & out) const1044 void Decl::dumpXML(raw_ostream &out) const {
1045 XMLDumper(out, getASTContext()).dispatch(const_cast<Decl*>(this));
1046 }
1047
1048 #else /* ifndef NDEBUG */
1049
dumpXML() const1050 void Decl::dumpXML() const {}
dumpXML(raw_ostream & out) const1051 void Decl::dumpXML(raw_ostream &out) const {}
1052
1053 #endif
1054