138 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
	
//===--- 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
 | 
						|
 |