1 //===--- DeclXML.cpp - XML implementation for Decl ASTs -------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the XML document class, which provides the means to
11 // dump out the AST in a XML form that exposes type details and other fields.
13 //===----------------------------------------------------------------------===//
15 #include "clang/Frontend/DocumentXML.h"
16 #include "clang/AST/DeclVisitor.h"
17 #include "clang/AST/Expr.h"
21 //---------------------------------------------------------
22 class DocumentXML::DeclPrinter : public DeclVisitor<DocumentXML::DeclPrinter>
26 void addSubNodes(FunctionDecl* FD)
28 for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i)
30 Visit(FD->getParamDecl(i));
35 void addSubNodes(RecordDecl* RD)
37 for (RecordDecl::field_iterator i = RD->field_begin(*Doc.Ctx), e = RD->field_end(*Doc.Ctx); i != e; ++i)
44 void addSubNodes(EnumDecl* ED)
46 for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(*Doc.Ctx), e = ED->enumerator_end(*Doc.Ctx); i != e; ++i)
53 void addSubNodes(EnumConstantDecl* ECD)
55 if (ECD->getInitExpr())
57 Doc.PrintStmt(ECD->getInitExpr());
61 void addSubNodes(FieldDecl* FdD)
63 if (FdD->isBitField())
65 Doc.PrintStmt(FdD->getBitWidth());
69 void addSubNodes(VarDecl* V)
73 Doc.PrintStmt(V->getInit());
77 void addSubNodes(ParmVarDecl* argDecl)
79 if (argDecl->getDefaultArg())
81 Doc.PrintStmt(argDecl->getDefaultArg());
85 void addSpecialAttribute(const char* pName, EnumDecl* ED)
87 const QualType& enumType = ED->getIntegerType();
88 if (!enumType.isNull())
90 Doc.addAttribute(pName, enumType);
94 void addIdAttribute(LinkageSpecDecl* ED)
96 Doc.addAttribute("id", ED);
99 void addIdAttribute(NamedDecl* ND)
101 Doc.addAttribute("id", ND);
105 DeclPrinter(DocumentXML& doc) : Doc(doc) {}
107 #define NODE_XML( CLASS, NAME ) \
108 void Visit##CLASS(CLASS* T) \
110 Doc.addSubNode(NAME);
112 #define ID_ATTRIBUTE_XML addIdAttribute(T);
113 #define ATTRIBUTE_XML( FN, NAME ) Doc.addAttribute(NAME, T->FN);
114 #define ATTRIBUTE_OPT_XML( FN, NAME ) Doc.addAttributeOptional(NAME, T->FN);
115 #define ATTRIBUTE_FILE_LOCATION_XML Doc.addLocation(T->getLocation());
116 #define ATTRIBUTE_SPECIAL_XML( FN, NAME ) addSpecialAttribute(NAME, T);
118 #define ATTRIBUTE_ENUM_XML( FN, NAME ) \
120 const char* pAttributeName = NAME; \
121 const bool optional = false; \
123 default: assert(0 && "unknown enum value");
125 #define ATTRIBUTE_ENUM_OPT_XML( FN, NAME ) \
127 const char* pAttributeName = NAME; \
128 const bool optional = true; \
130 default: assert(0 && "unknown enum value");
132 #define ENUM_XML( VALUE, NAME ) case VALUE: if ((!optional) || NAME[0]) Doc.addAttribute(pAttributeName, NAME); break;
133 #define END_ENUM_XML } }
134 #define END_NODE_XML }
136 #define SUB_NODE_XML( CLASS ) addSubNodes(T);
137 #define SUB_NODE_SEQUENCE_XML( CLASS ) addSubNodes(T);
138 #define SUB_NODE_OPT_XML( CLASS ) addSubNodes(T);
140 #include "clang/Frontend/DeclXML.def"
144 //---------------------------------------------------------
145 void DocumentXML::writeDeclToXML(Decl *D)
147 DeclPrinter(*this).Visit(D);
148 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
150 if (Stmt *Body = FD->getBody(*Ctx)) {
159 //---------------------------------------------------------