//===--- DeclXML.cpp - XML implementation for Decl ASTs -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the XML document class, which provides the means to
// dump out the AST in a XML form that exposes type details and other fields.
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/DocumentXML.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/Expr.h"

namespace clang {

//---------------------------------------------------------
class DocumentXML::DeclPrinter : public DeclVisitor<DocumentXML::DeclPrinter> {
  DocumentXML& Doc;

  void addSubNodes(FunctionDecl* FD) {
    for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
      Visit(FD->getParamDecl(i));
      Doc.toParent();
    }
  }

  void addSubNodes(RecordDecl* RD) {
    for (RecordDecl::field_iterator i = RD->field_begin(),
                                    e = RD->field_end(); i != e; ++i) {
      Visit(*i);
      Doc.toParent();
    }
  }

  void addSubNodes(EnumDecl* ED) {
    for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(),
                                       e = ED->enumerator_end(); i != e; ++i) {
      Visit(*i);
      Doc.toParent();
    }
  }

  void addSubNodes(EnumConstantDecl* ECD) {
    if (ECD->getInitExpr())
      Doc.PrintStmt(ECD->getInitExpr());
  }

  void addSubNodes(FieldDecl* FdD)  {
    if (FdD->isBitField())
      Doc.PrintStmt(FdD->getBitWidth());
  }

  void addSubNodes(VarDecl* V) {
    if (V->getInit())
      Doc.PrintStmt(V->getInit());
  }

  void addSubNodes(ParmVarDecl* argDecl) {
    if (argDecl->getDefaultArg())
      Doc.PrintStmt(argDecl->getDefaultArg());
  }

  void addSpecialAttribute(const char* pName, EnumDecl* ED) {
    const QualType& enumType = ED->getIntegerType();
    if (!enumType.isNull())
      Doc.addAttribute(pName, enumType);
  }

  void addIdAttribute(LinkageSpecDecl* ED) {
    Doc.addAttribute("id", ED);
  }

  void addIdAttribute(NamedDecl* ND) {
    Doc.addAttribute("id", ND);
  }

public:
  DeclPrinter(DocumentXML& doc) : Doc(doc) {}

#define NODE_XML( CLASS, NAME )          \
  void Visit##CLASS(CLASS* T)            \
  {                                      \
    Doc.addSubNode(NAME);

#define ID_ATTRIBUTE_XML                  addIdAttribute(T);
#define ATTRIBUTE_XML( FN, NAME )         Doc.addAttribute(NAME, T->FN);
#define ATTRIBUTE_OPT_XML( FN, NAME )     Doc.addAttributeOptional(NAME, T->FN);
#define ATTRIBUTE_FILE_LOCATION_XML       Doc.addLocation(T->getLocation());
#define ATTRIBUTE_SPECIAL_XML( FN, NAME ) addSpecialAttribute(NAME, T);

#define ATTRIBUTE_ENUM_XML( FN, NAME )  \
  {                                     \
    const char* pAttributeName = NAME;  \
    const bool optional = false;             \
    switch (T->FN) {                    \
    default: assert(0 && "unknown enum value");

#define ATTRIBUTE_ENUM_OPT_XML( FN, NAME )  \
  {                                     \
    const char* pAttributeName = NAME;  \
    const bool optional = true;              \
    switch (T->FN) {                    \
    default: assert(0 && "unknown enum value");

#define ENUM_XML( VALUE, NAME )         case VALUE: if ((!optional) || NAME[0]) Doc.addAttribute(pAttributeName, NAME); break;
#define END_ENUM_XML                    } }
#define END_NODE_XML                    }

#define SUB_NODE_XML( CLASS )           addSubNodes(T);
#define SUB_NODE_SEQUENCE_XML( CLASS )  addSubNodes(T);
#define SUB_NODE_OPT_XML( CLASS )       addSubNodes(T);

#include "clang/Frontend/DeclXML.def"
};


//---------------------------------------------------------
void DocumentXML::writeDeclToXML(Decl *D) {
  DeclPrinter(*this).Visit(D);
  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
    if (Stmt *Body = FD->getBody()) {
      addSubNode("Body");
      PrintStmt(Body);
      toParent();
    }
  }
  toParent();
}

//---------------------------------------------------------
} // NS clang

