blob: f32fbbd2413ba03bc88f1f312ccff308ff02ab69 [file] [log] [blame]
Douglas Gregor038f75a2009-06-15 19:02:54 +00001//===--- DocumentXML.cpp - XML document for 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/TypeVisitor.h"
17#include "clang/AST/Type.h"
18#include "clang/AST/Decl.h"
19
20namespace clang {
21 namespace XML {
22 namespace {
23
24//---------------------------------------------------------
25class TypeWriter : public TypeVisitor<TypeWriter>
26{
27 DocumentXML& Doc;
28
29public:
30 TypeWriter(DocumentXML& doc) : Doc(doc) {}
31
32#define NODE_XML( CLASS, NAME ) \
33 void Visit##CLASS(CLASS* T) \
34 { \
35 Doc.addSubNode(NAME);
36
37#define ID_ATTRIBUTE_XML // done by the Document class itself
38#define ATTRIBUTE_XML( FN, NAME ) Doc.addAttribute(NAME, T->FN);
39#define TYPE_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "type")
40#define CONTEXT_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "context")
41#define ATTRIBUTE_OPT_XML( FN, NAME ) Doc.addAttributeOptional(NAME, T->FN);
42
43#define ATTRIBUTE_ENUM_XML( FN, NAME ) \
44 { \
45 const char* pAttributeName = NAME; \
46 const bool optional = false; \
47 switch (T->FN) { \
48 default: assert(0 && "unknown enum value");
49
50#define ATTRIBUTE_ENUM_OPT_XML( FN, NAME ) \
51 { \
52 const char* pAttributeName = NAME; \
53 const bool optional = true; \
54 switch (T->FN) { \
55 default: assert(0 && "unknown enum value");
56
57#define ENUM_XML( VALUE, NAME ) case VALUE: if ((!optional) || NAME[0]) Doc.addAttribute(pAttributeName, NAME); break;
58#define END_ENUM_XML } }
59#define END_NODE_XML }
60
61#include "clang/Frontend/TypeXML.def"
62
63};
64
65//---------------------------------------------------------
66 } // anon clang
67 } // NS XML
68
69//---------------------------------------------------------
70class DocumentXML::TypeAdder : public TypeVisitor<DocumentXML::TypeAdder>
71{
72 DocumentXML& Doc;
73
74 void addIfType(const Type* pType)
75 {
76 Doc.addTypeRecursively(pType);
77 }
78
79 void addIfType(const QualType& pType)
80 {
81 Doc.addTypeRecursively(pType);
82 }
83
84 template<class T> void addIfType(T) {}
85
86public:
87 TypeAdder(DocumentXML& doc) : Doc(doc) {}
88
89#define NODE_XML( CLASS, NAME ) \
90 void Visit##CLASS(CLASS* T) \
91 {
92
93#define ID_ATTRIBUTE_XML
94#define TYPE_ATTRIBUTE_XML( FN ) Doc.addTypeRecursively(T->FN);
95#define CONTEXT_ATTRIBUTE_XML( FN )
96#define ATTRIBUTE_XML( FN, NAME ) addIfType(T->FN);
97#define ATTRIBUTE_OPT_XML( FN, NAME )
98#define ATTRIBUTE_ENUM_XML( FN, NAME )
99#define ATTRIBUTE_ENUM_OPT_XML( FN, NAME )
100#define ENUM_XML( VALUE, NAME )
101#define END_ENUM_XML
102#define END_NODE_XML }
103
104#include "clang/Frontend/TypeXML.def"
105};
106
107//---------------------------------------------------------
108void DocumentXML::addParentTypes(const Type* pType)
109{
110 TypeAdder(*this).Visit(const_cast<Type*>(pType));
111}
112
113//---------------------------------------------------------
114void DocumentXML::writeTypeToXML(const Type* pType)
115{
116 XML::TypeWriter(*this).Visit(const_cast<Type*>(pType));
117}
118
119//---------------------------------------------------------
120void DocumentXML::writeTypeToXML(const QualType& pType)
121{
122 XML::TypeWriter(*this).VisitQualType(const_cast<QualType*>(&pType));
123}
124
125//---------------------------------------------------------
126} // NS clang
127