//===--- 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/SmallVector.h"
#include "llvm/ADT/StringRef.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) {
    llvm::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) {
    llvm::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: {
      visitDeclRef(A.getAsDecl());
      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()));
    setFlag("directinit", D->hasCXXDirectInitializer());
    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);
    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
