]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Frontend/DeclXML.cpp
Update clang to r94309.
[FreeBSD/FreeBSD.git] / lib / Frontend / DeclXML.cpp
1 //===--- DeclXML.cpp - XML implementation for Decl ASTs -------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
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.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "clang/Frontend/DocumentXML.h"
16 #include "clang/AST/DeclVisitor.h"
17 #include "clang/AST/Expr.h"
18
19 namespace clang {
20
21 //---------------------------------------------------------
22 class DocumentXML::DeclPrinter : public DeclVisitor<DocumentXML::DeclPrinter> {
23   DocumentXML& Doc;
24
25   void addSubNodes(FunctionDecl* FD) {
26     for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
27       Visit(FD->getParamDecl(i));
28       Doc.toParent();
29     }
30   }
31
32   void addSubNodes(RecordDecl* RD) {
33     for (RecordDecl::field_iterator i = RD->field_begin(),
34                                     e = RD->field_end(); i != e; ++i) {
35       Visit(*i);
36       Doc.toParent();
37     }
38   }
39
40   void addSubNodes(EnumDecl* ED) {
41     for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(),
42                                        e = ED->enumerator_end(); i != e; ++i) {
43       Visit(*i);
44       Doc.toParent();
45     }
46   }
47
48   void addSubNodes(EnumConstantDecl* ECD) {
49     if (ECD->getInitExpr())
50       Doc.PrintStmt(ECD->getInitExpr());
51   }
52
53   void addSubNodes(FieldDecl* FdD)  {
54     if (FdD->isBitField())
55       Doc.PrintStmt(FdD->getBitWidth());
56   }
57
58   void addSubNodes(VarDecl* V) {
59     if (V->getInit())
60       Doc.PrintStmt(V->getInit());
61   }
62
63   void addSubNodes(ParmVarDecl* argDecl) {
64     if (argDecl->getDefaultArg())
65       Doc.PrintStmt(argDecl->getDefaultArg());
66   }
67
68   void addSpecialAttribute(const char* pName, EnumDecl* ED) {
69     const QualType& enumType = ED->getIntegerType();
70     if (!enumType.isNull())
71       Doc.addAttribute(pName, enumType);
72   }
73
74   void addIdAttribute(LinkageSpecDecl* ED) {
75     Doc.addAttribute("id", ED);
76   }
77
78   void addIdAttribute(NamedDecl* ND) {
79     Doc.addAttribute("id", ND);
80   }
81
82 public:
83   DeclPrinter(DocumentXML& doc) : Doc(doc) {}
84
85 #define NODE_XML( CLASS, NAME )          \
86   void Visit##CLASS(CLASS* T)            \
87   {                                      \
88     Doc.addSubNode(NAME);
89
90 #define ID_ATTRIBUTE_XML                  addIdAttribute(T);
91 #define ATTRIBUTE_XML( FN, NAME )         Doc.addAttribute(NAME, T->FN);
92 #define ATTRIBUTE_OPT_XML( FN, NAME )     Doc.addAttributeOptional(NAME, T->FN);
93 #define ATTRIBUTE_FILE_LOCATION_XML       Doc.addLocation(T->getLocation());
94 #define ATTRIBUTE_SPECIAL_XML( FN, NAME ) addSpecialAttribute(NAME, T);
95
96 #define ATTRIBUTE_ENUM_XML( FN, NAME )  \
97   {                                     \
98     const char* pAttributeName = NAME;  \
99     const bool optional = false;             \
100     switch (T->FN) {                    \
101     default: assert(0 && "unknown enum value");
102
103 #define ATTRIBUTE_ENUM_OPT_XML( FN, NAME )  \
104   {                                     \
105     const char* pAttributeName = NAME;  \
106     const bool optional = true;              \
107     switch (T->FN) {                    \
108     default: assert(0 && "unknown enum value");
109
110 #define ENUM_XML( VALUE, NAME )         case VALUE: if ((!optional) || NAME[0]) Doc.addAttribute(pAttributeName, NAME); break;
111 #define END_ENUM_XML                    } }
112 #define END_NODE_XML                    }
113
114 #define SUB_NODE_XML( CLASS )           addSubNodes(T);
115 #define SUB_NODE_SEQUENCE_XML( CLASS )  addSubNodes(T);
116 #define SUB_NODE_OPT_XML( CLASS )       addSubNodes(T);
117
118 #include "clang/Frontend/DeclXML.def"
119 };
120
121
122 //---------------------------------------------------------
123 void DocumentXML::writeDeclToXML(Decl *D) {
124   DeclPrinter(*this).Visit(D);
125   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
126     if (Stmt *Body = FD->getBody()) {
127       addSubNode("Body");
128       PrintStmt(Body);
129       toParent();
130     }
131   }
132   toParent();
133 }
134
135 //---------------------------------------------------------
136 } // NS clang
137