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