//===--- DumpXML.cpp - Detailed XML dumping ---------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the Decl::dumpXML() method, a debugging tool to
//  print a detailed graph of an AST in an unspecified XML format.
//
//  There is no guarantee of stability for this format.
//
//===----------------------------------------------------------------------===//

// Only pay for this in code size in assertions-enabled builds.

#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeLocVisitor.h"
#include "clang/AST/TypeVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "llvm/ADT/SmallString.h"

using namespace clang;

#ifndef NDEBUG

namespace {

enum NodeState {
  NS_Attrs, NS_LazyChildren, NS_Children
};

struct Node {
  StringRef Name;
  NodeState State;
  Node(StringRef name) : Name(name), State(NS_Attrs) {}

  bool isDoneWithAttrs() const { return State != NS_Attrs; }
};

template <class Impl> struct XMLDeclVisitor {
#define DISPATCH(NAME, CLASS) \
  static_cast<Impl*>(this)->NAME(static_cast<CLASS*>(D))

  void dispatch(Decl *D) {
    switch (D->getKind()) {
#define DECL(DERIVED, BASE) \
      case Decl::DERIVED: \
        DISPATCH(dispatch##DERIVED##DeclAttrs, DERIVED##Decl); \
        static_cast<Impl*>(this)->completeAttrs(); \
        DISPATCH(dispatch##DERIVED##DeclChildren, DERIVED##Decl); \
        DISPATCH(dispatch##DERIVED##DeclAsContext, DERIVED##Decl); \
        break;
#define ABSTRACT_DECL(DECL)
#include "clang/AST/DeclNodes.inc"
    }
  }

#define DECL(DERIVED, BASE) \
  void dispatch##DERIVED##DeclAttrs(DERIVED##Decl *D) { \
    DISPATCH(dispatch##BASE##Attrs, BASE); \
    DISPATCH(visit##DERIVED##DeclAttrs, DERIVED##Decl); \
  } \
  void visit##DERIVED##DeclAttrs(DERIVED##Decl *D) {} \
  void dispatch##DERIVED##DeclChildren(DERIVED##Decl *D) { \
    DISPATCH(dispatch##BASE##Children, BASE); \
    DISPATCH(visit##DERIVED##DeclChildren, DERIVED##Decl); \
  } \
  void visit##DERIVED##DeclChildren(DERIVED##Decl *D) {} \
  void dispatch##DERIVED##DeclAsContext(DERIVED##Decl *D) { \
    DISPATCH(dispatch##BASE##AsContext, BASE); \
    DISPATCH(visit##DERIVED##DeclAsContext, DERIVED##Decl); \
  } \
  void visit##DERIVED##DeclAsContext(DERIVED##Decl *D) {}
#include "clang/AST/DeclNodes.inc"

  void dispatchDeclAttrs(Decl *D) {
    DISPATCH(visitDeclAttrs, Decl);
  }
  void visitDeclAttrs(Decl *D) {}

  void dispatchDeclChildren(Decl *D) {
    DISPATCH(visitDeclChildren, Decl);
  }
  void visitDeclChildren(Decl *D) {}

  void dispatchDeclAsContext(Decl *D) {
    DISPATCH(visitDeclAsContext, Decl);
  }
  void visitDeclAsContext(Decl *D) {}

#undef DISPATCH  
};

template <class Impl> struct XMLTypeVisitor {
#define DISPATCH(NAME, CLASS) \
  static_cast<Impl*>(this)->NAME(static_cast<CLASS*>(T))

  void dispatch(Type *T) {
    switch (T->getTypeClass()) {
#define TYPE(DERIVED, BASE) \
      case Type::DERIVED: \
        DISPATCH(dispatch##DERIVED##TypeAttrs, DERIVED##Type); \
        static_cast<Impl*>(this)->completeAttrs(); \
        DISPATCH(dispatch##DERIVED##TypeChildren, DERIVED##Type); \
        break;
#define ABSTRACT_TYPE(DERIVED, BASE)
#include "clang/AST/TypeNodes.def"
    }
  }

#define TYPE(DERIVED, BASE) \
  void dispatch##DERIVED##TypeAttrs(DERIVED##Type *T) { \
    DISPATCH(dispatch##BASE##Attrs, BASE); \
    DISPATCH(visit##DERIVED##TypeAttrs, DERIVED##Type); \
  } \
  void visit##DERIVED##TypeAttrs(DERIVED##Type *T) {} \
  void dispatch##DERIVED##TypeChildren(DERIVED##Type *T) { \
    DISPATCH(dispatch##BASE##Children, BASE); \
    DISPATCH(visit##DERIVED##TypeChildren, DERIVED##Type); \
  } \
  void visit##DERIVED##TypeChildren(DERIVED##Type *T) {}
#include "clang/AST/TypeNodes.def"

  void dispatchTypeAttrs(Type *T) {
    DISPATCH(visitTypeAttrs, Type);
  }
  void visitTypeAttrs(Type *T) {}

  void dispatchTypeChildren(Type *T) {
    DISPATCH(visitTypeChildren, Type);
  }
  void visitTypeChildren(Type *T) {}

#undef DISPATCH  
};

static StringRef getTypeKindName(Type *T) {
  switch (T->getTypeClass()) {
#define TYPE(DERIVED, BASE) case Type::DERIVED: return #DERIVED "Type";
#define ABSTRACT_TYPE(DERIVED, BASE)
#include "clang/AST/TypeNodes.def"
  }

  llvm_unreachable("unknown type kind!");
}

struct XMLDumper : public XMLDeclVisitor<XMLDumper>,
                   public XMLTypeVisitor<XMLDumper> {
  raw_ostream &out;
  ASTContext &Context;
  SmallVector<Node, 16> Stack;
  unsigned Indent;
  explicit XMLDumper(raw_ostream &OS, ASTContext &context)
    : out(OS), Context(context), Indent(0) {}

  void indent() {
    for (unsigned I = Indent; I; --I)
      out << ' ';
  }

  /// Push a new node on the stack.
  void push(StringRef name) {
    if (!Stack.empty()) {
      assert(Stack.back().isDoneWithAttrs());
      if (Stack.back().State == NS_LazyChildren) {
        Stack.back().State = NS_Children;
        out << ">\n";
      }
      Indent++;
      indent();
    }
    Stack.push_back(Node(name));
    out << '<' << name;
  }

  /// Set the given attribute to the given value.
  void set(StringRef attr, StringRef value) {
    assert(!Stack.empty() && !Stack.back().isDoneWithAttrs());
    out << ' ' << attr << '=' << '"' << value << '"'; // TODO: quotation
  }

  /// Finish attributes.
  void completeAttrs() {
    assert(!Stack.empty() && !Stack.back().isDoneWithAttrs());
    Stack.back().State = NS_LazyChildren;
  }

  /// Pop a node.
  void pop() {
    assert(!Stack.empty() && Stack.back().isDoneWithAttrs());
    if (Stack.back().State == NS_LazyChildren) {
      out << "/>\n";
    } else {
      indent();
      out << "</" << Stack.back().Name << ">\n";
    }
    if (Stack.size() > 1) Indent--;
    Stack.pop_back();
  }

  //---- General utilities -------------------------------------------//

  void setPointer(StringRef prop, const void *p) {
    SmallString<10> buffer;
    llvm::raw_svector_ostream os(buffer);
    os << p;
    os.flush();
    set(prop, buffer);
  }

  void setPointer(void *p) {
    setPointer("ptr", p);
  }

  void setInteger(StringRef prop, const llvm::APSInt &v) {
    set(prop, v.toString(10));
  }

  void setInteger(StringRef prop, unsigned n) {
    SmallString<10> buffer;
    llvm::raw_svector_ostream os(buffer);
    os << n;
    os.flush();
    set(prop, buffer);
  }

  void setFlag(StringRef prop, bool flag) {
    if (flag) set(prop, "true");
  }

  void setName(DeclarationName Name) {
    if (!Name)
      return set("name", "");

    // Common case.
    if (Name.isIdentifier())
      return set("name", Name.getAsIdentifierInfo()->getName());

    set("name", Name.getAsString());
  }

  class TemporaryContainer {
    XMLDumper &Dumper;
  public:
    TemporaryContainer(XMLDumper &dumper, StringRef name)
      : Dumper(dumper) {
      Dumper.push(name);
      Dumper.completeAttrs();
    }

    ~TemporaryContainer() {
      Dumper.pop();
    }
  };

  void visitTemplateParameters(TemplateParameterList *L) {
    push("template_parameters");
    completeAttrs();
    for (TemplateParameterList::iterator
           I = L->begin(), E = L->end(); I != E; ++I)
      dispatch(*I);
    pop();
  }

  void visitTemplateArguments(const TemplateArgumentList &L) {
    push("template_arguments");
    completeAttrs();
    for (unsigned I = 0, E = L.size(); I != E; ++I)
      dispatch(L[I]);
    pop();
  }

  /// Visits a reference to the given declaration.
  void visitDeclRef(Decl *D) {
    push(D->getDeclKindName());
    setPointer("ref", D);
    completeAttrs();
    pop();
  }
  void visitDeclRef(StringRef Name, Decl *D) {
    TemporaryContainer C(*this, Name);
    if (D) visitDeclRef(D);
  }

  void dispatch(const TemplateArgument &A) {
    switch (A.getKind()) {
    case TemplateArgument::Null: {
      TemporaryContainer C(*this, "null");
      break;
    }
    case TemplateArgument::Type: {
      dispatch(A.getAsType());
      break;
    }
    case TemplateArgument::Template:
    case TemplateArgument::TemplateExpansion:
      // FIXME: Implement!
      break;
        
    case TemplateArgument::Declaration: {
      if (Decl *D = A.getAsDecl())
        visitDeclRef(D);
      break;
    }
    case TemplateArgument::Integral: {
      push("integer");
      setInteger("value", A.getAsIntegral());
      completeAttrs();
      pop();
      break;
    }
    case TemplateArgument::Expression: {
      dispatch(A.getAsExpr());
      break;
    }
    case TemplateArgument::Pack: {
      for (TemplateArgument::pack_iterator P = A.pack_begin(), 
                                        PEnd = A.pack_end();
           P != PEnd; ++P)
        dispatch(*P);
      break;
    }
    }
  }

  void dispatch(const TemplateArgumentLoc &A) {
    dispatch(A.getArgument());
  }

  //---- Declarations ------------------------------------------------//
  // Calls are made in this order:
  //   # Enter a new node.
  //   push("FieldDecl")
  //
  //   # In this phase, attributes are set on the node.
  //   visitDeclAttrs(D)
  //   visitNamedDeclAttrs(D)
  //   ...
  //   visitFieldDeclAttrs(D)
  //
  //   # No more attributes after this point.
  //   completeAttrs()
  //
  //   # Create "header" child nodes, i.e. those which logically
  //   # belong to the declaration itself.
  //   visitDeclChildren(D)
  //   visitNamedDeclChildren(D)
  //   ...
  //   visitFieldDeclChildren(D)
  //
  //   # Create nodes for the lexical children.
  //   visitDeclAsContext(D)
  //   visitNamedDeclAsContext(D)
  //   ...
  //   visitFieldDeclAsContext(D)
  //
  //   # Finish the node.
  //   pop();
  void dispatch(Decl *D) {
    push(D->getDeclKindName());
    XMLDeclVisitor<XMLDumper>::dispatch(D);
    pop();
  }
  void visitDeclAttrs(Decl *D) {
    setPointer(D);
  }

  /// Visit all the lexical decls in the given context.
  void visitDeclContext(DeclContext *DC) {
    for (DeclContext::decl_iterator
           I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I)
      dispatch(*I);

    // FIXME: point out visible declarations not in lexical context?
  }

  /// Set the "access" attribute on the current node according to the
  /// given specifier.
  void setAccess(AccessSpecifier AS) {
    switch (AS) {
    case AS_public: return set("access", "public");
    case AS_protected: return set("access", "protected");
    case AS_private: return set("access", "private");
    case AS_none: llvm_unreachable("explicit forbidden access");
    }
  }

  template <class T> void visitRedeclarableAttrs(T *D) {
    if (T *Prev = D->getPreviousDecl())
      setPointer("previous", Prev);
  }


  // TranslationUnitDecl
  void visitTranslationUnitDeclAsContext(TranslationUnitDecl *D) {
    visitDeclContext(D);
  }

  // LinkageSpecDecl
  void visitLinkageSpecDeclAttrs(LinkageSpecDecl *D) {
    StringRef lang = "";
    switch (D->getLanguage()) {
    case LinkageSpecDecl::lang_c: lang = "C"; break;
    case LinkageSpecDecl::lang_cxx: lang = "C++"; break;
    }
    set("lang", lang);
  }
  void visitLinkageSpecDeclAsContext(LinkageSpecDecl *D) {
    visitDeclContext(D);
  }

  // NamespaceDecl
  void visitNamespaceDeclAttrs(NamespaceDecl *D) {
    setFlag("inline", D->isInline());
    if (!D->isOriginalNamespace())
      setPointer("original", D->getOriginalNamespace());
  }
  void visitNamespaceDeclAsContext(NamespaceDecl *D) {
    visitDeclContext(D);
  }

  // NamedDecl
  void visitNamedDeclAttrs(NamedDecl *D) {
    setName(D->getDeclName());
  }

  // ValueDecl
  void visitValueDeclChildren(ValueDecl *D) {
    dispatch(D->getType());
  }

  // DeclaratorDecl
  void visitDeclaratorDeclChildren(DeclaratorDecl *D) {
    //dispatch(D->getTypeSourceInfo()->getTypeLoc());
  }

  // VarDecl
  void visitVarDeclAttrs(VarDecl *D) {
    visitRedeclarableAttrs(D);
    if (D->getStorageClass() != SC_None)
      set("storage",
          VarDecl::getStorageClassSpecifierString(D->getStorageClass()));
    StringRef initStyle = "";
    switch (D->getInitStyle()) {
    case VarDecl::CInit: initStyle = "c"; break;
    case VarDecl::CallInit: initStyle = "call"; break;
    case VarDecl::ListInit: initStyle = "list"; break;
    }
    set("initstyle", initStyle);
    setFlag("nrvo", D->isNRVOVariable());
    // TODO: instantiation, etc.
  }
  void visitVarDeclChildren(VarDecl *D) {
    if (D->hasInit()) dispatch(D->getInit());
  }

  // ParmVarDecl?

  // FunctionDecl
  void visitFunctionDeclAttrs(FunctionDecl *D) {
    visitRedeclarableAttrs(D);
    setFlag("pure", D->isPure());
    setFlag("trivial", D->isTrivial());
    setFlag("returnzero", D->hasImplicitReturnZero());
    setFlag("prototype", D->hasWrittenPrototype());
    setFlag("deleted", D->isDeletedAsWritten());
    if (D->getStorageClass() != SC_None)
      set("storage",
          VarDecl::getStorageClassSpecifierString(D->getStorageClass()));
    setFlag("inline", D->isInlineSpecified());
    if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>())
      set("asmlabel", ALA->getLabel());
    // TODO: instantiation, etc.
  }
  void visitFunctionDeclChildren(FunctionDecl *D) {
    for (FunctionDecl::param_iterator
           I = D->param_begin(), E = D->param_end(); I != E; ++I)
      dispatch(*I);
    for (llvm::ArrayRef<NamedDecl*>::iterator
           I = D->getDeclsInPrototypeScope().begin(), E = D->getDeclsInPrototypeScope().end();
         I != E; ++I)
      dispatch(*I);
    if (D->doesThisDeclarationHaveABody())
      dispatch(D->getBody());
  }

  // CXXMethodDecl ?
  // CXXConstructorDecl ?
  // CXXDestructorDecl ?
  // CXXConversionDecl ?

  void dispatch(CXXCtorInitializer *Init) {
    // TODO
  }

  // FieldDecl
  void visitFieldDeclAttrs(FieldDecl *D) {
    setFlag("mutable", D->isMutable());
  }
  void visitFieldDeclChildren(FieldDecl *D) {
    if (D->isBitField()) {
      TemporaryContainer C(*this, "bitwidth");
      dispatch(D->getBitWidth());
    }
    // TODO: C++0x member initializer
  }

  // EnumConstantDecl
  void visitEnumConstantDeclChildren(EnumConstantDecl *D) {
    // value in any case?
    if (D->getInitExpr()) dispatch(D->getInitExpr());
  }

  // IndirectFieldDecl
  void visitIndirectFieldDeclChildren(IndirectFieldDecl *D) {
    for (IndirectFieldDecl::chain_iterator
           I = D->chain_begin(), E = D->chain_end(); I != E; ++I) {
      NamedDecl *VD = const_cast<NamedDecl*>(*I);
      push(isa<VarDecl>(VD) ? "variable" : "field");
      setPointer("ptr", VD);
      completeAttrs();
      pop();
    }
  }

  // TypeDecl
  void visitTypeDeclAttrs(TypeDecl *D) {
    setPointer("typeptr", D->getTypeForDecl());
  }

  // TypedefDecl
  void visitTypedefDeclAttrs(TypedefDecl *D) {
    visitRedeclarableAttrs<TypedefNameDecl>(D);
  }
  void visitTypedefDeclChildren(TypedefDecl *D) {
    dispatch(D->getTypeSourceInfo()->getTypeLoc());
  }

  // TypeAliasDecl
  void visitTypeAliasDeclAttrs(TypeAliasDecl *D) {
    visitRedeclarableAttrs<TypedefNameDecl>(D);
  }
  void visitTypeAliasDeclChildren(TypeAliasDecl *D) {
    dispatch(D->getTypeSourceInfo()->getTypeLoc());
  }

  // TagDecl
  void visitTagDeclAttrs(TagDecl *D) {
    visitRedeclarableAttrs(D);
  }
  void visitTagDeclAsContext(TagDecl *D) {
    visitDeclContext(D);
  }

  // EnumDecl
  void visitEnumDeclAttrs(EnumDecl *D) {
    setFlag("scoped", D->isScoped());
    setFlag("fixed", D->isFixed());
  }
  void visitEnumDeclChildren(EnumDecl *D) {
    {
      TemporaryContainer C(*this, "promotion_type");
      dispatch(D->getPromotionType());
    }
    {
      TemporaryContainer C(*this, "integer_type");
      dispatch(D->getIntegerType());
    }
  }

  // RecordDecl ?

  void visitCXXRecordDeclChildren(CXXRecordDecl *D) {
    if (!D->isThisDeclarationADefinition()) return;

    for (CXXRecordDecl::base_class_iterator
           I = D->bases_begin(), E = D->bases_end(); I != E; ++I) {
      push("base");
      setAccess(I->getAccessSpecifier());
      completeAttrs();
      dispatch(I->getTypeSourceInfo()->getTypeLoc());
      pop();
    }
  }

  // ClassTemplateSpecializationDecl ?

  // FileScopeAsmDecl ?

  // BlockDecl
  void visitBlockDeclAttrs(BlockDecl *D) {
    setFlag("variadic", D->isVariadic());
  }
  void visitBlockDeclChildren(BlockDecl *D) {
    for (FunctionDecl::param_iterator
           I = D->param_begin(), E = D->param_end(); I != E; ++I)
      dispatch(*I);
    dispatch(D->getBody());
  }

  // AccessSpecDecl
  void visitAccessSpecDeclAttrs(AccessSpecDecl *D) {
    setAccess(D->getAccess());
  }

  // TemplateDecl
  void visitTemplateDeclChildren(TemplateDecl *D) {
    visitTemplateParameters(D->getTemplateParameters());
    if (D->getTemplatedDecl())
      dispatch(D->getTemplatedDecl());
  }

  // FunctionTemplateDecl
  void visitFunctionTemplateDeclAttrs(FunctionTemplateDecl *D) {
    visitRedeclarableAttrs(D);
  }
  void visitFunctionTemplateDeclChildren(FunctionTemplateDecl *D) {
    // Mention all the specializations which don't have explicit
    // declarations elsewhere.
    for (FunctionTemplateDecl::spec_iterator
           I = D->spec_begin(), E = D->spec_end(); I != E; ++I) {
      FunctionTemplateSpecializationInfo *Info
        = I->getTemplateSpecializationInfo();

      bool Unknown = false;
      switch (Info->getTemplateSpecializationKind()) {
      case TSK_ImplicitInstantiation: Unknown = false; break;
      case TSK_Undeclared: Unknown = true; break;

      // These will be covered at their respective sites.
      case TSK_ExplicitSpecialization: continue;
      case TSK_ExplicitInstantiationDeclaration: continue;
      case TSK_ExplicitInstantiationDefinition: continue;
      }

      TemporaryContainer C(*this,
                           Unknown ? "uninstantiated" : "instantiation");
      visitTemplateArguments(*Info->TemplateArguments);
      dispatch(Info->Function);
    }
  }

  // ClasTemplateDecl
  void visitClassTemplateDeclAttrs(ClassTemplateDecl *D) {
    visitRedeclarableAttrs(D);
  }
  void visitClassTemplateDeclChildren(ClassTemplateDecl *D) {
    // Mention all the specializations which don't have explicit
    // declarations elsewhere.
    for (ClassTemplateDecl::spec_iterator
           I = D->spec_begin(), E = D->spec_end(); I != E; ++I) {

      bool Unknown = false;
      switch (I->getTemplateSpecializationKind()) {
      case TSK_ImplicitInstantiation: Unknown = false; break;
      case TSK_Undeclared: Unknown = true; break;

      // These will be covered at their respective sites.
      case TSK_ExplicitSpecialization: continue;
      case TSK_ExplicitInstantiationDeclaration: continue;
      case TSK_ExplicitInstantiationDefinition: continue;
      }

      TemporaryContainer C(*this,
                           Unknown ? "uninstantiated" : "instantiation");
      visitTemplateArguments(I->getTemplateArgs());
      dispatch(*I);
    }
  }

  // TemplateTypeParmDecl
  void visitTemplateTypeParmDeclAttrs(TemplateTypeParmDecl *D) {
    setInteger("depth", D->getDepth());
    setInteger("index", D->getIndex());
  }
  void visitTemplateTypeParmDeclChildren(TemplateTypeParmDecl *D) {
    if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
      dispatch(D->getDefaultArgumentInfo()->getTypeLoc());
    // parameter pack?
  }

  // NonTypeTemplateParmDecl
  void visitNonTypeTemplateParmDeclAttrs(NonTypeTemplateParmDecl *D) {
    setInteger("depth", D->getDepth());
    setInteger("index", D->getIndex());
  }
  void visitNonTypeTemplateParmDeclChildren(NonTypeTemplateParmDecl *D) {
    if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
      dispatch(D->getDefaultArgument());
    // parameter pack?
  }

  // TemplateTemplateParmDecl
  void visitTemplateTemplateParmDeclAttrs(TemplateTemplateParmDecl *D) {
    setInteger("depth", D->getDepth());
    setInteger("index", D->getIndex());
  }
  void visitTemplateTemplateParmDeclChildren(TemplateTemplateParmDecl *D) {
    if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
      dispatch(D->getDefaultArgument());
    // parameter pack?
  }

  // FriendDecl
  void visitFriendDeclChildren(FriendDecl *D) {
    if (TypeSourceInfo *T = D->getFriendType())
      dispatch(T->getTypeLoc());
    else
      dispatch(D->getFriendDecl());
  }

  // UsingDirectiveDecl ?
  // UsingDecl ?
  // UsingShadowDecl ?
  // NamespaceAliasDecl ?
  // UnresolvedUsingValueDecl ?
  // UnresolvedUsingTypenameDecl ?
  // StaticAssertDecl ?

  // ObjCImplDecl
  void visitObjCImplDeclChildren(ObjCImplDecl *D) {
    visitDeclRef(D->getClassInterface());
  }
  void visitObjCImplDeclAsContext(ObjCImplDecl *D) {
    visitDeclContext(D);
  }

  // ObjCInterfaceDecl
  void visitCategoryList(ObjCCategoryDecl *D) {
    if (!D) return;

    TemporaryContainer C(*this, "categories");
    for (; D; D = D->getNextClassCategory())
      visitDeclRef(D);
  }
  void visitObjCInterfaceDeclAttrs(ObjCInterfaceDecl *D) {
    setPointer("typeptr", D->getTypeForDecl());
    setFlag("forward_decl", !D->isThisDeclarationADefinition());
    setFlag("implicit_interface", D->isImplicitInterfaceDecl());
  }
  void visitObjCInterfaceDeclChildren(ObjCInterfaceDecl *D) {
    visitDeclRef("super", D->getSuperClass());
    visitDeclRef("implementation", D->getImplementation());
    if (D->protocol_begin() != D->protocol_end()) {
      TemporaryContainer C(*this, "protocols");
      for (ObjCInterfaceDecl::protocol_iterator
             I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
        visitDeclRef(*I);
    }
    visitCategoryList(D->getCategoryList());
  }
  void visitObjCInterfaceDeclAsContext(ObjCInterfaceDecl *D) {
    visitDeclContext(D);
  }

  // ObjCCategoryDecl
  void visitObjCCategoryDeclAttrs(ObjCCategoryDecl *D) {
    setFlag("extension", D->IsClassExtension());
    setFlag("synth_bitfield", D->hasSynthBitfield());
  }
  void visitObjCCategoryDeclChildren(ObjCCategoryDecl *D) {
    visitDeclRef("interface", D->getClassInterface());
    visitDeclRef("implementation", D->getImplementation());
    if (D->protocol_begin() != D->protocol_end()) {
      TemporaryContainer C(*this, "protocols");
      for (ObjCCategoryDecl::protocol_iterator
             I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
        visitDeclRef(*I);
    }
  }
  void visitObjCCategoryDeclAsContext(ObjCCategoryDecl *D) {
    visitDeclContext(D);
  }

  // ObjCCategoryImplDecl
  void visitObjCCategoryImplDeclAttrs(ObjCCategoryImplDecl *D) {
    set("identifier", D->getName());
  }
  void visitObjCCategoryImplDeclChildren(ObjCCategoryImplDecl *D) {
    visitDeclRef(D->getCategoryDecl());
  }

  // ObjCImplementationDecl
  void visitObjCImplementationDeclAttrs(ObjCImplementationDecl *D) {
    setFlag("synth_bitfield", D->hasSynthBitfield());
    set("identifier", D->getName());
  }
  void visitObjCImplementationDeclChildren(ObjCImplementationDecl *D) {
    visitDeclRef("super", D->getSuperClass());
    if (D->init_begin() != D->init_end()) {
      TemporaryContainer C(*this, "initializers");
      for (ObjCImplementationDecl::init_iterator
             I = D->init_begin(), E = D->init_end(); I != E; ++I)
        dispatch(*I);
    }
  }

  // ObjCProtocolDecl
  void visitObjCProtocolDeclChildren(ObjCProtocolDecl *D) {
    if (!D->isThisDeclarationADefinition())
      return;
    
    if (D->protocol_begin() != D->protocol_end()) {
      TemporaryContainer C(*this, "protocols");
      for (ObjCInterfaceDecl::protocol_iterator
             I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
        visitDeclRef(*I);
    }
  }
  void visitObjCProtocolDeclAsContext(ObjCProtocolDecl *D) {
    if (!D->isThisDeclarationADefinition())
      return;
    
    visitDeclContext(D);
  }

  // ObjCMethodDecl
  void visitObjCMethodDeclAttrs(ObjCMethodDecl *D) {
    // decl qualifier?
    // implementation control?

    setFlag("instance", D->isInstanceMethod());
    setFlag("variadic", D->isVariadic());
    setFlag("synthesized", D->isSynthesized());
    setFlag("defined", D->isDefined());
    setFlag("related_result_type", D->hasRelatedResultType());
  }
  void visitObjCMethodDeclChildren(ObjCMethodDecl *D) {
    dispatch(D->getResultType());
    for (ObjCMethodDecl::param_iterator
           I = D->param_begin(), E = D->param_end(); I != E; ++I)
      dispatch(*I);
    if (D->isThisDeclarationADefinition())
      dispatch(D->getBody());
  }

  // ObjCIvarDecl
  void setAccessControl(StringRef prop, ObjCIvarDecl::AccessControl AC) {
    switch (AC) {
    case ObjCIvarDecl::None: return set(prop, "none");
    case ObjCIvarDecl::Private: return set(prop, "private");
    case ObjCIvarDecl::Protected: return set(prop, "protected");
    case ObjCIvarDecl::Public: return set(prop, "public");
    case ObjCIvarDecl::Package: return set(prop, "package");
    }
  }
  void visitObjCIvarDeclAttrs(ObjCIvarDecl *D) {
    setFlag("synthesize", D->getSynthesize());
    setAccessControl("access", D->getAccessControl());
  }

  // ObjCCompatibleAliasDecl
  void visitObjCCompatibleAliasDeclChildren(ObjCCompatibleAliasDecl *D) {
    visitDeclRef(D->getClassInterface());
  }

  // FIXME: ObjCPropertyDecl
  // FIXME: ObjCPropertyImplDecl

  //---- Types -----------------------------------------------------//
  void dispatch(TypeLoc TL) {
    dispatch(TL.getType()); // for now
  }

  void dispatch(QualType T) {
    if (T.hasLocalQualifiers()) {
      push("QualType");
      Qualifiers Qs = T.getLocalQualifiers();
      setFlag("const", Qs.hasConst());
      setFlag("volatile", Qs.hasVolatile());
      setFlag("restrict", Qs.hasRestrict());
      if (Qs.hasAddressSpace()) setInteger("addrspace", Qs.getAddressSpace());
      if (Qs.hasObjCGCAttr()) {
        switch (Qs.getObjCGCAttr()) {
        case Qualifiers::Weak: set("gc", "weak"); break;
        case Qualifiers::Strong: set("gc", "strong"); break;
        case Qualifiers::GCNone: llvm_unreachable("explicit none");
        }
      }
      
      completeAttrs();
      dispatch(QualType(T.getTypePtr(), 0));
      pop();
      return;
    }

    Type *Ty = const_cast<Type*>(T.getTypePtr());
    push(getTypeKindName(Ty));
    XMLTypeVisitor<XMLDumper>::dispatch(const_cast<Type*>(T.getTypePtr()));
    pop();
  }

  void setCallingConv(CallingConv CC) {
    switch (CC) {
    case CC_Default: return;
    case CC_C: return set("cc", "cdecl");
    case CC_X86FastCall: return set("cc", "x86_fastcall");
    case CC_X86StdCall: return set("cc", "x86_stdcall");
    case CC_X86ThisCall: return set("cc", "x86_thiscall");
    case CC_X86Pascal: return set("cc", "x86_pascal");
    case CC_AAPCS: return set("cc", "aapcs");
    case CC_AAPCS_VFP: return set("cc", "aapcs_vfp");
    }
  }

  void visitTypeAttrs(Type *D) {
    setPointer(D);
    setFlag("dependent", D->isDependentType());
    setFlag("variably_modified", D->isVariablyModifiedType());

    setPointer("canonical", D->getCanonicalTypeInternal().getAsOpaquePtr());
  }

  void visitPointerTypeChildren(PointerType *T) {
    dispatch(T->getPointeeType());
  }
  void visitReferenceTypeChildren(ReferenceType *T) {
    dispatch(T->getPointeeType());
  }
  void visitObjCObjectPointerTypeChildren(ObjCObjectPointerType *T) {
    dispatch(T->getPointeeType());
  }
  void visitBlockPointerTypeChildren(BlockPointerType *T) {
    dispatch(T->getPointeeType());
  }

  // Types that just wrap declarations.
  void visitTagTypeChildren(TagType *T) {
    visitDeclRef(T->getDecl());
  }
  void visitTypedefTypeChildren(TypedefType *T) {
    visitDeclRef(T->getDecl());
  }
  void visitObjCInterfaceTypeChildren(ObjCInterfaceType *T) {
    visitDeclRef(T->getDecl());
  }
  void visitUnresolvedUsingTypeChildren(UnresolvedUsingType *T) {
    visitDeclRef(T->getDecl());
  }
  void visitInjectedClassNameTypeChildren(InjectedClassNameType *T) {
    visitDeclRef(T->getDecl());
  }

  void visitFunctionTypeAttrs(FunctionType *T) {
    setFlag("noreturn", T->getNoReturnAttr());
    setCallingConv(T->getCallConv());
    if (T->getHasRegParm()) setInteger("regparm", T->getRegParmType());
  }
  void visitFunctionTypeChildren(FunctionType *T) {
    dispatch(T->getResultType());
  }

  void visitFunctionProtoTypeAttrs(FunctionProtoType *T) {
    setFlag("const", T->getTypeQuals() & Qualifiers::Const);
    setFlag("volatile", T->getTypeQuals() & Qualifiers::Volatile);
    setFlag("restrict", T->getTypeQuals() & Qualifiers::Restrict);
  }
  void visitFunctionProtoTypeChildren(FunctionProtoType *T) {
    push("parameters");
    setFlag("variadic", T->isVariadic());
    completeAttrs();
    for (FunctionProtoType::arg_type_iterator
           I = T->arg_type_begin(), E = T->arg_type_end(); I != E; ++I)
      dispatch(*I);
    pop();

    if (T->hasDynamicExceptionSpec()) {
      push("exception_specifiers");
      setFlag("any", T->getExceptionSpecType() == EST_MSAny);
      completeAttrs();
      for (FunctionProtoType::exception_iterator
             I = T->exception_begin(), E = T->exception_end(); I != E; ++I)
        dispatch(*I);
      pop();
    }
    // FIXME: noexcept specifier
  }

  void visitTemplateSpecializationTypeChildren(TemplateSpecializationType *T) {
    if (const RecordType *RT = T->getAs<RecordType>())
      visitDeclRef(RT->getDecl());

    // TODO: TemplateName

    push("template_arguments");
    completeAttrs();
    for (unsigned I = 0, E = T->getNumArgs(); I != E; ++I)
      dispatch(T->getArg(I));
    pop();
  }

  //---- Statements ------------------------------------------------//
  void dispatch(Stmt *S) {
    // FIXME: this is not really XML at all
    push("Stmt");
    out << ">\n";
    Stack.back().State = NS_Children; // explicitly become non-lazy
    S->dump(out, Context.getSourceManager());
    out << '\n';
    pop();
  }
};
}

void Decl::dumpXML() const {
  dumpXML(llvm::errs());
}

void Decl::dumpXML(raw_ostream &out) const {
  XMLDumper(out, getASTContext()).dispatch(const_cast<Decl*>(this));
}

#else /* ifndef NDEBUG */

void Decl::dumpXML() const {}
void Decl::dumpXML(raw_ostream &out) const {}

#endif
