]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/clang/lib/AST/DumpXML.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / clang / lib / AST / DumpXML.cpp
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;
56   Node(StringRef name) : Name(name), State(NS_Attrs) {}
57
58   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
65   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
99   void dispatchDeclAttrs(Decl *D) {
100     DISPATCH(visitDeclAttrs, Decl);
101   }
102   void visitDeclAttrs(Decl *D) {}
103
104   void dispatchDeclChildren(Decl *D) {
105     DISPATCH(visitDeclChildren, Decl);
106   }
107   void visitDeclChildren(Decl *D) {}
108
109   void dispatchDeclAsContext(Decl *D) {
110     DISPATCH(visitDeclAsContext, Decl);
111   }
112   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
121   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
147   void dispatchTypeAttrs(Type *T) {
148     DISPATCH(visitTypeAttrs, Type);
149   }
150   void visitTypeAttrs(Type *T) {}
151
152   void dispatchTypeChildren(Type *T) {
153     DISPATCH(visitTypeChildren, Type);
154   }
155   void visitTypeChildren(Type *T) {}
156
157 #undef DISPATCH  
158 };
159
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;
176   explicit XMLDumper(raw_ostream &OS, ASTContext &context)
177     : out(OS), Context(context), Indent(0) {}
178
179   void indent() {
180     for (unsigned I = Indent; I; --I)
181       out << ' ';
182   }
183
184   /// Push a new node on the stack.
185   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.
200   void set(StringRef attr, StringRef value) {
201     assert(!Stack.empty() && !Stack.back().isDoneWithAttrs());
202     out << ' ' << attr << '=' << '"' << value << '"'; // TODO: quotation
203   }
204
205   /// Finish attributes.
206   void completeAttrs() {
207     assert(!Stack.empty() && !Stack.back().isDoneWithAttrs());
208     Stack.back().State = NS_LazyChildren;
209   }
210
211   /// Pop a node.
212   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
226   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
234   void setPointer(void *p) {
235     setPointer("ptr", p);
236   }
237
238   void setInteger(StringRef prop, const llvm::APSInt &v) {
239     set(prop, v.toString(10));
240   }
241
242   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
250   void setFlag(StringRef prop, bool flag) {
251     if (flag) set(prop, "true");
252   }
253
254   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:
268     TemporaryContainer(XMLDumper &dumper, StringRef name)
269       : Dumper(dumper) {
270       Dumper.push(name);
271       Dumper.completeAttrs();
272     }
273
274     ~TemporaryContainer() {
275       Dumper.pop();
276     }
277   };
278
279   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
288   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.
297   void visitDeclRef(Decl *D) {
298     push(D->getDeclKindName());
299     setPointer("ref", D);
300     completeAttrs();
301     pop();
302   }
303   void visitDeclRef(StringRef Name, Decl *D) {
304     TemporaryContainer C(*this, Name);
305     if (D) visitDeclRef(D);
306   }
307
308   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
349   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();
382   void dispatch(Decl *D) {
383     push(D->getDeclKindName());
384     XMLDeclVisitor<XMLDumper>::dispatch(D);
385     pop();
386   }
387   void visitDeclAttrs(Decl *D) {
388     setPointer(D);
389   }
390
391   /// Visit all the lexical decls in the given context.
392   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.
402   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
411   template <class T> void visitRedeclarableAttrs(T *D) {
412     if (T *Prev = D->getPreviousDecl())
413       setPointer("previous", Prev);
414   }
415
416
417   // TranslationUnitDecl
418   void visitTranslationUnitDeclAsContext(TranslationUnitDecl *D) {
419     visitDeclContext(D);
420   }
421
422   // LinkageSpecDecl
423   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   }
431   void visitLinkageSpecDeclAsContext(LinkageSpecDecl *D) {
432     visitDeclContext(D);
433   }
434
435   // NamespaceDecl
436   void visitNamespaceDeclAttrs(NamespaceDecl *D) {
437     setFlag("inline", D->isInline());
438     if (!D->isOriginalNamespace())
439       setPointer("original", D->getOriginalNamespace());
440   }
441   void visitNamespaceDeclAsContext(NamespaceDecl *D) {
442     visitDeclContext(D);
443   }
444
445   // NamedDecl
446   void visitNamedDeclAttrs(NamedDecl *D) {
447     setName(D->getDeclName());
448   }
449
450   // ValueDecl
451   void visitValueDeclChildren(ValueDecl *D) {
452     dispatch(D->getType());
453   }
454
455   // DeclaratorDecl
456   void visitDeclaratorDeclChildren(DeclaratorDecl *D) {
457     //dispatch(D->getTypeSourceInfo()->getTypeLoc());
458   }
459
460   // VarDecl
461   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   }
476   void visitVarDeclChildren(VarDecl *D) {
477     if (D->hasInit()) dispatch(D->getInit());
478   }
479
480   // ParmVarDecl?
481
482   // FunctionDecl
483   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   }
498   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
515   void dispatch(CXXCtorInitializer *Init) {
516     // TODO
517   }
518
519   // FieldDecl
520   void visitFieldDeclAttrs(FieldDecl *D) {
521     setFlag("mutable", D->isMutable());
522   }
523   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
532   void visitEnumConstantDeclChildren(EnumConstantDecl *D) {
533     // value in any case?
534     if (D->getInitExpr()) dispatch(D->getInitExpr());
535   }
536
537   // IndirectFieldDecl
538   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
550   void visitTypeDeclAttrs(TypeDecl *D) {
551     setPointer("typeptr", D->getTypeForDecl());
552   }
553
554   // TypedefDecl
555   void visitTypedefDeclAttrs(TypedefDecl *D) {
556     visitRedeclarableAttrs<TypedefNameDecl>(D);
557   }
558   void visitTypedefDeclChildren(TypedefDecl *D) {
559     dispatch(D->getTypeSourceInfo()->getTypeLoc());
560   }
561
562   // TypeAliasDecl
563   void visitTypeAliasDeclAttrs(TypeAliasDecl *D) {
564     visitRedeclarableAttrs<TypedefNameDecl>(D);
565   }
566   void visitTypeAliasDeclChildren(TypeAliasDecl *D) {
567     dispatch(D->getTypeSourceInfo()->getTypeLoc());
568   }
569
570   // TagDecl
571   void visitTagDeclAttrs(TagDecl *D) {
572     visitRedeclarableAttrs(D);
573   }
574   void visitTagDeclAsContext(TagDecl *D) {
575     visitDeclContext(D);
576   }
577
578   // EnumDecl
579   void visitEnumDeclAttrs(EnumDecl *D) {
580     setFlag("scoped", D->isScoped());
581     setFlag("fixed", D->isFixed());
582   }
583   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
596   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
614   void visitBlockDeclAttrs(BlockDecl *D) {
615     setFlag("variadic", D->isVariadic());
616   }
617   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
625   void visitAccessSpecDeclAttrs(AccessSpecDecl *D) {
626     setAccess(D->getAccess());
627   }
628
629   // TemplateDecl
630   void visitTemplateDeclChildren(TemplateDecl *D) {
631     visitTemplateParameters(D->getTemplateParameters());
632     if (D->getTemplatedDecl())
633       dispatch(D->getTemplatedDecl());
634   }
635
636   // FunctionTemplateDecl
637   void visitFunctionTemplateDeclAttrs(FunctionTemplateDecl *D) {
638     visitRedeclarableAttrs(D);
639   }
640   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
667   void visitClassTemplateDeclAttrs(ClassTemplateDecl *D) {
668     visitRedeclarableAttrs(D);
669   }
670   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
695   void visitTemplateTypeParmDeclAttrs(TemplateTypeParmDecl *D) {
696     setInteger("depth", D->getDepth());
697     setInteger("index", D->getIndex());
698   }
699   void visitTemplateTypeParmDeclChildren(TemplateTypeParmDecl *D) {
700     if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
701       dispatch(D->getDefaultArgumentInfo()->getTypeLoc());
702     // parameter pack?
703   }
704
705   // NonTypeTemplateParmDecl
706   void visitNonTypeTemplateParmDeclAttrs(NonTypeTemplateParmDecl *D) {
707     setInteger("depth", D->getDepth());
708     setInteger("index", D->getIndex());
709   }
710   void visitNonTypeTemplateParmDeclChildren(NonTypeTemplateParmDecl *D) {
711     if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
712       dispatch(D->getDefaultArgument());
713     // parameter pack?
714   }
715
716   // TemplateTemplateParmDecl
717   void visitTemplateTemplateParmDeclAttrs(TemplateTemplateParmDecl *D) {
718     setInteger("depth", D->getDepth());
719     setInteger("index", D->getIndex());
720   }
721   void visitTemplateTemplateParmDeclChildren(TemplateTemplateParmDecl *D) {
722     if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
723       dispatch(D->getDefaultArgument());
724     // parameter pack?
725   }
726
727   // FriendDecl
728   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
744   void visitObjCImplDeclChildren(ObjCImplDecl *D) {
745     visitDeclRef(D->getClassInterface());
746   }
747   void visitObjCImplDeclAsContext(ObjCImplDecl *D) {
748     visitDeclContext(D);
749   }
750
751   void visitObjCInterfaceDeclAttrs(ObjCInterfaceDecl *D) {
752     setPointer("typeptr", D->getTypeForDecl());
753     setFlag("forward_decl", !D->isThisDeclarationADefinition());
754     setFlag("implicit_interface", D->isImplicitInterfaceDecl());
755   }
756   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   }
777   void visitObjCInterfaceDeclAsContext(ObjCInterfaceDecl *D) {
778     visitDeclContext(D);
779   }
780
781   // ObjCCategoryDecl
782   void visitObjCCategoryDeclAttrs(ObjCCategoryDecl *D) {
783     setFlag("extension", D->IsClassExtension());
784   }
785   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   }
795   void visitObjCCategoryDeclAsContext(ObjCCategoryDecl *D) {
796     visitDeclContext(D);
797   }
798
799   // ObjCCategoryImplDecl
800   void visitObjCCategoryImplDeclAttrs(ObjCCategoryImplDecl *D) {
801     set("identifier", D->getName());
802   }
803   void visitObjCCategoryImplDeclChildren(ObjCCategoryImplDecl *D) {
804     visitDeclRef(D->getCategoryDecl());
805   }
806
807   // ObjCImplementationDecl
808   void visitObjCImplementationDeclAttrs(ObjCImplementationDecl *D) {
809     set("identifier", D->getName());
810   }
811   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
822   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   }
833   void visitObjCProtocolDeclAsContext(ObjCProtocolDecl *D) {
834     if (!D->isThisDeclarationADefinition())
835       return;
836     
837     visitDeclContext(D);
838   }
839
840   // ObjCMethodDecl
841   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   }
851   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
861   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   }
870   void visitObjCIvarDeclAttrs(ObjCIvarDecl *D) {
871     setFlag("synthesize", D->getSynthesize());
872     setAccessControl("access", D->getAccessControl());
873   }
874
875   // ObjCCompatibleAliasDecl
876   void visitObjCCompatibleAliasDeclChildren(ObjCCompatibleAliasDecl *D) {
877     visitDeclRef(D->getClassInterface());
878   }
879
880   // FIXME: ObjCPropertyDecl
881   // FIXME: ObjCPropertyImplDecl
882
883   //---- Types -----------------------------------------------------//
884   void dispatch(TypeLoc TL) {
885     dispatch(TL.getType()); // for now
886   }
887
888   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
916   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_X86_64Win64: return set("cc", "x86_64_win64");
925     case CC_X86_64SysV: return set("cc", "x86_64_sysv");
926     case CC_AAPCS: return set("cc", "aapcs");
927     case CC_AAPCS_VFP: return set("cc", "aapcs_vfp");
928     case CC_PnaclCall: return set("cc", "pnaclcall");
929     case CC_IntelOclBicc: return set("cc", "intel_ocl_bicc");
930     }
931   }
932
933   void visitTypeAttrs(Type *D) {
934     setPointer(D);
935     setFlag("dependent", D->isDependentType());
936     setFlag("variably_modified", D->isVariablyModifiedType());
937
938     setPointer("canonical", D->getCanonicalTypeInternal().getAsOpaquePtr());
939   }
940
941   void visitPointerTypeChildren(PointerType *T) {
942     dispatch(T->getPointeeType());
943   }
944   void visitReferenceTypeChildren(ReferenceType *T) {
945     dispatch(T->getPointeeType());
946   }
947   void visitObjCObjectPointerTypeChildren(ObjCObjectPointerType *T) {
948     dispatch(T->getPointeeType());
949   }
950   void visitBlockPointerTypeChildren(BlockPointerType *T) {
951     dispatch(T->getPointeeType());
952   }
953
954   // Types that just wrap declarations.
955   void visitTagTypeChildren(TagType *T) {
956     visitDeclRef(T->getDecl());
957   }
958   void visitTypedefTypeChildren(TypedefType *T) {
959     visitDeclRef(T->getDecl());
960   }
961   void visitObjCInterfaceTypeChildren(ObjCInterfaceType *T) {
962     visitDeclRef(T->getDecl());
963   }
964   void visitUnresolvedUsingTypeChildren(UnresolvedUsingType *T) {
965     visitDeclRef(T->getDecl());
966   }
967   void visitInjectedClassNameTypeChildren(InjectedClassNameType *T) {
968     visitDeclRef(T->getDecl());
969   }
970
971   void visitFunctionTypeAttrs(FunctionType *T) {
972     setFlag("noreturn", T->getNoReturnAttr());
973     setCallingConv(T->getCallConv());
974     if (T->getHasRegParm()) setInteger("regparm", T->getRegParmType());
975   }
976   void visitFunctionTypeChildren(FunctionType *T) {
977     dispatch(T->getResultType());
978   }
979
980   void visitFunctionProtoTypeAttrs(FunctionProtoType *T) {
981     setFlag("const", T->isConst());
982     setFlag("volatile", T->isVolatile());
983     setFlag("restrict", T->isRestrict());
984     switch (T->getExceptionSpecType()) {
985     case EST_None: break;
986     case EST_DynamicNone: set("exception_spec", "throw()"); break;
987     case EST_Dynamic: set("exception_spec", "throw(T)"); break;
988     case EST_MSAny: set("exception_spec", "throw(...)"); break;
989     case EST_BasicNoexcept: set("exception_spec", "noexcept"); break;
990     case EST_ComputedNoexcept: set("exception_spec", "noexcept(expr)"); break;
991     case EST_Unevaluated: set("exception_spec", "unevaluated"); break;
992     case EST_Uninstantiated: set("exception_spec", "uninstantiated"); break;
993     }
994   }
995   void visitFunctionProtoTypeChildren(FunctionProtoType *T) {
996     push("parameters");
997     setFlag("variadic", T->isVariadic());
998     completeAttrs();
999     for (FunctionProtoType::arg_type_iterator
1000            I = T->arg_type_begin(), E = T->arg_type_end(); I != E; ++I)
1001       dispatch(*I);
1002     pop();
1003
1004     if (T->hasDynamicExceptionSpec()) {
1005       push("exception_specifiers");
1006       setFlag("any", T->getExceptionSpecType() == EST_MSAny);
1007       completeAttrs();
1008       for (FunctionProtoType::exception_iterator
1009              I = T->exception_begin(), E = T->exception_end(); I != E; ++I)
1010         dispatch(*I);
1011       pop();
1012     }
1013     // FIXME: noexcept specifier
1014   }
1015
1016   void visitTemplateSpecializationTypeChildren(TemplateSpecializationType *T) {
1017     if (const RecordType *RT = T->getAs<RecordType>())
1018       visitDeclRef(RT->getDecl());
1019
1020     // TODO: TemplateName
1021
1022     push("template_arguments");
1023     completeAttrs();
1024     for (unsigned I = 0, E = T->getNumArgs(); I != E; ++I)
1025       dispatch(T->getArg(I));
1026     pop();
1027   }
1028
1029   //---- Statements ------------------------------------------------//
1030   void dispatch(Stmt *S) {
1031     // FIXME: this is not really XML at all
1032     push("Stmt");
1033     out << ">\n";
1034     Stack.back().State = NS_Children; // explicitly become non-lazy
1035     S->dump(out, Context.getSourceManager());
1036     out << '\n';
1037     pop();
1038   }
1039 };
1040 }
1041
1042 void Decl::dumpXML() const {
1043   dumpXML(llvm::errs());
1044 }
1045
1046 void Decl::dumpXML(raw_ostream &out) const {
1047   XMLDumper(out, getASTContext()).dispatch(const_cast<Decl*>(this));
1048 }
1049
1050 #else /* ifndef NDEBUG */
1051
1052 void Decl::dumpXML() const {}
1053 void Decl::dumpXML(raw_ostream &out) const {}
1054
1055 #endif