• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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