]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Frontend/DeclXML.cpp
Update Clang sources to r73879.
[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 {
24   DocumentXML& Doc;
25
26   void addSubNodes(FunctionDecl* FD)
27   {
28     for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) 
29     {
30       Visit(FD->getParamDecl(i));
31       Doc.toParent();
32     }
33   }
34
35   void addSubNodes(RecordDecl* RD)
36   {
37     for (RecordDecl::field_iterator i = RD->field_begin(*Doc.Ctx), e = RD->field_end(*Doc.Ctx); i != e; ++i)
38     {
39       Visit(*i);
40       Doc.toParent();
41     }
42   }
43
44   void addSubNodes(EnumDecl* ED)
45   {
46     for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(*Doc.Ctx), e = ED->enumerator_end(*Doc.Ctx); i != e; ++i)
47     {
48       Visit(*i);
49       Doc.toParent();
50     }
51   }
52
53   void addSubNodes(EnumConstantDecl* ECD)
54   {
55     if (ECD->getInitExpr()) 
56     {
57       Doc.PrintStmt(ECD->getInitExpr());
58     }
59   }
60
61   void addSubNodes(FieldDecl* FdD)
62   {
63     if (FdD->isBitField())
64     {
65       Doc.PrintStmt(FdD->getBitWidth());
66     }
67   }
68
69   void addSubNodes(VarDecl* V)
70   {
71     if (V->getInit()) 
72     {
73       Doc.PrintStmt(V->getInit());
74     }
75   }
76
77   void addSubNodes(ParmVarDecl* argDecl)
78   {
79     if (argDecl->getDefaultArg())
80     {
81       Doc.PrintStmt(argDecl->getDefaultArg());
82     }
83   }
84
85   void addSpecialAttribute(const char* pName, EnumDecl* ED)
86   {
87     const QualType& enumType = ED->getIntegerType();
88     if (!enumType.isNull())
89     {
90       Doc.addAttribute(pName, enumType);
91     }
92   }
93
94   void addIdAttribute(LinkageSpecDecl* ED)
95   {
96     Doc.addAttribute("id", ED);
97   }
98
99   void addIdAttribute(NamedDecl* ND)
100   {
101     Doc.addAttribute("id", ND);
102   }
103
104 public:
105   DeclPrinter(DocumentXML& doc) : Doc(doc) {}
106
107 #define NODE_XML( CLASS, NAME )          \
108   void Visit##CLASS(CLASS* T)            \
109   {                                      \
110     Doc.addSubNode(NAME);         
111
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);
117
118 #define ATTRIBUTE_ENUM_XML( FN, NAME )  \
119   {                                     \
120     const char* pAttributeName = NAME;  \
121     const bool optional = false;             \
122     switch (T->FN) {                    \
123       default: assert(0 && "unknown enum value"); 
124
125 #define ATTRIBUTE_ENUM_OPT_XML( FN, NAME )  \
126   {                                     \
127     const char* pAttributeName = NAME;  \
128     const bool optional = true;              \
129     switch (T->FN) {                    \
130       default: assert(0 && "unknown enum value"); 
131
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                    }
135
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);
139
140 #include "clang/Frontend/DeclXML.def"
141 };
142
143
144 //--------------------------------------------------------- 
145 void DocumentXML::writeDeclToXML(Decl *D)
146 {
147   DeclPrinter(*this).Visit(D);
148   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 
149   {
150     if (Stmt *Body = FD->getBody(*Ctx)) {
151       addSubNode("Body");
152       PrintStmt(Body);
153       toParent();
154     }
155   }
156   toParent();
157 }
158
159 //--------------------------------------------------------- 
160 } // NS clang
161