2009-06-16 03:02:54 +08:00
|
|
|
//===--- 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.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2009-09-09 23:08:12 +08:00
|
|
|
// This file implements the XML document class, which provides the means to
|
2009-06-16 03:02:54 +08:00
|
|
|
// 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 {
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
//---------------------------------------------------------
|
|
|
|
class DocumentXML::DeclPrinter : public DeclVisitor<DocumentXML::DeclPrinter> {
|
2009-06-16 03:02:54 +08:00
|
|
|
DocumentXML& Doc;
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
void addSubNodes(FunctionDecl* FD) {
|
|
|
|
for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
|
2009-06-16 03:02:54 +08:00
|
|
|
Visit(FD->getParamDecl(i));
|
|
|
|
Doc.toParent();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
void addSubNodes(RecordDecl* RD) {
|
2009-06-30 10:36:12 +08:00
|
|
|
for (RecordDecl::field_iterator i = RD->field_begin(),
|
|
|
|
e = RD->field_end(); i != e; ++i) {
|
2009-06-16 03:02:54 +08:00
|
|
|
Visit(*i);
|
|
|
|
Doc.toParent();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
void addSubNodes(EnumDecl* ED) {
|
2009-06-30 10:36:12 +08:00
|
|
|
for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(),
|
|
|
|
e = ED->enumerator_end(); i != e; ++i) {
|
2009-06-16 03:02:54 +08:00
|
|
|
Visit(*i);
|
|
|
|
Doc.toParent();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
void addSubNodes(EnumConstantDecl* ECD) {
|
|
|
|
if (ECD->getInitExpr())
|
2009-06-16 03:02:54 +08:00
|
|
|
Doc.PrintStmt(ECD->getInitExpr());
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
void addSubNodes(FieldDecl* FdD) {
|
2009-06-16 03:02:54 +08:00
|
|
|
if (FdD->isBitField())
|
|
|
|
Doc.PrintStmt(FdD->getBitWidth());
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
void addSubNodes(VarDecl* V) {
|
|
|
|
if (V->getInit())
|
2009-06-16 03:02:54 +08:00
|
|
|
Doc.PrintStmt(V->getInit());
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
void addSubNodes(ParmVarDecl* argDecl) {
|
2009-06-16 03:02:54 +08:00
|
|
|
if (argDecl->getDefaultArg())
|
|
|
|
Doc.PrintStmt(argDecl->getDefaultArg());
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
void addSpecialAttribute(const char* pName, EnumDecl* ED) {
|
2009-06-16 03:02:54 +08:00
|
|
|
const QualType& enumType = ED->getIntegerType();
|
|
|
|
if (!enumType.isNull())
|
|
|
|
Doc.addAttribute(pName, enumType);
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
void addIdAttribute(LinkageSpecDecl* ED) {
|
2009-06-16 03:02:54 +08:00
|
|
|
Doc.addAttribute("id", ED);
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
void addIdAttribute(NamedDecl* ND) {
|
2009-06-16 03:02:54 +08:00
|
|
|
Doc.addAttribute("id", ND);
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
DeclPrinter(DocumentXML& doc) : Doc(doc) {}
|
|
|
|
|
|
|
|
#define NODE_XML( CLASS, NAME ) \
|
|
|
|
void Visit##CLASS(CLASS* T) \
|
|
|
|
{ \
|
2009-09-09 23:08:12 +08:00
|
|
|
Doc.addSubNode(NAME);
|
2009-06-16 03:02:54 +08:00
|
|
|
|
|
|
|
#define ID_ATTRIBUTE_XML addIdAttribute(T);
|
2009-09-09 23:08:12 +08:00
|
|
|
#define ATTRIBUTE_XML( FN, NAME ) Doc.addAttribute(NAME, T->FN);
|
|
|
|
#define ATTRIBUTE_OPT_XML( FN, NAME ) Doc.addAttributeOptional(NAME, T->FN);
|
2009-06-16 03:02:54 +08:00
|
|
|
#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) { \
|
2009-09-09 23:08:12 +08:00
|
|
|
default: assert(0 && "unknown enum value");
|
2009-06-16 03:02:54 +08:00
|
|
|
|
|
|
|
#define ATTRIBUTE_ENUM_OPT_XML( FN, NAME ) \
|
|
|
|
{ \
|
|
|
|
const char* pAttributeName = NAME; \
|
|
|
|
const bool optional = true; \
|
|
|
|
switch (T->FN) { \
|
2009-09-09 23:08:12 +08:00
|
|
|
default: assert(0 && "unknown enum value");
|
2009-06-16 03:02:54 +08:00
|
|
|
|
|
|
|
#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"
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
//---------------------------------------------------------
|
|
|
|
void DocumentXML::writeDeclToXML(Decl *D) {
|
2009-06-16 03:02:54 +08:00
|
|
|
DeclPrinter(*this).Visit(D);
|
2009-09-09 23:08:12 +08:00
|
|
|
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
2009-06-30 10:35:26 +08:00
|
|
|
if (Stmt *Body = FD->getBody()) {
|
2009-06-16 03:02:54 +08:00
|
|
|
addSubNode("Body");
|
|
|
|
PrintStmt(Body);
|
|
|
|
toParent();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
toParent();
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
//---------------------------------------------------------
|
2009-06-16 03:02:54 +08:00
|
|
|
} // NS clang
|
|
|
|
|