Home | History | Annotate | Download | only in AST
      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_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 
    931   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 
    939   void visitPointerTypeChildren(PointerType *T) {
    940     dispatch(T->getPointeeType());
    941   }
    942   void visitReferenceTypeChildren(ReferenceType *T) {
    943     dispatch(T->getPointeeType());
    944   }
    945   void visitObjCObjectPointerTypeChildren(ObjCObjectPointerType *T) {
    946     dispatch(T->getPointeeType());
    947   }
    948   void visitBlockPointerTypeChildren(BlockPointerType *T) {
    949     dispatch(T->getPointeeType());
    950   }
    951 
    952   // Types that just wrap declarations.
    953   void visitTagTypeChildren(TagType *T) {
    954     visitDeclRef(T->getDecl());
    955   }
    956   void visitTypedefTypeChildren(TypedefType *T) {
    957     visitDeclRef(T->getDecl());
    958   }
    959   void visitObjCInterfaceTypeChildren(ObjCInterfaceType *T) {
    960     visitDeclRef(T->getDecl());
    961   }
    962   void visitUnresolvedUsingTypeChildren(UnresolvedUsingType *T) {
    963     visitDeclRef(T->getDecl());
    964   }
    965   void visitInjectedClassNameTypeChildren(InjectedClassNameType *T) {
    966     visitDeclRef(T->getDecl());
    967   }
    968 
    969   void visitFunctionTypeAttrs(FunctionType *T) {
    970     setFlag("noreturn", T->getNoReturnAttr());
    971     setCallingConv(T->getCallConv());
    972     if (T->getHasRegParm()) setInteger("regparm", T->getRegParmType());
    973   }
    974   void visitFunctionTypeChildren(FunctionType *T) {
    975     dispatch(T->getResultType());
    976   }
    977 
    978   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   }
    993   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 
   1014   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 ------------------------------------------------//
   1028   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 
   1040 void Decl::dumpXML() const {
   1041   dumpXML(llvm::errs());
   1042 }
   1043 
   1044 void Decl::dumpXML(raw_ostream &out) const {
   1045   XMLDumper(out, getASTContext()).dispatch(const_cast<Decl*>(this));
   1046 }
   1047 
   1048 #else /* ifndef NDEBUG */
   1049 
   1050 void Decl::dumpXML() const {}
   1051 void Decl::dumpXML(raw_ostream &out) const {}
   1052 
   1053 #endif
   1054