blob: 8bd05443a7fef8ce941bcd1d1755739fe380cc85 [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//
Mike Stump1eb44332009-09-09 15:08:12 +000010// This file implements the XML document class, which provides the means to
Douglas Gregor038f75a2009-06-15 19:02:54 +000011// 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
Mike Stump1eb44332009-09-09 15:08:12 +000024//---------------------------------------------------------
25class TypeWriter : public TypeVisitor<TypeWriter> {
Douglas Gregor038f75a2009-06-15 19:02:54 +000026 DocumentXML& Doc;
27
28public:
29 TypeWriter(DocumentXML& doc) : Doc(doc) {}
30
31#define NODE_XML( CLASS, NAME ) \
Mike Stump1eb44332009-09-09 15:08:12 +000032 void Visit##CLASS(CLASS* T) { \
33 Doc.addSubNode(NAME);
Douglas Gregor038f75a2009-06-15 19:02:54 +000034
35#define ID_ATTRIBUTE_XML // done by the Document class itself
Mike Stump1eb44332009-09-09 15:08:12 +000036#define ATTRIBUTE_XML( FN, NAME ) Doc.addAttribute(NAME, T->FN);
Douglas Gregor038f75a2009-06-15 19:02:54 +000037#define TYPE_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "type")
38#define CONTEXT_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "context")
Mike Stump1eb44332009-09-09 15:08:12 +000039#define ATTRIBUTE_OPT_XML( FN, NAME ) Doc.addAttributeOptional(NAME, T->FN);
Douglas Gregor038f75a2009-06-15 19:02:54 +000040
41#define ATTRIBUTE_ENUM_XML( FN, NAME ) \
42 { \
43 const char* pAttributeName = NAME; \
44 const bool optional = false; \
45 switch (T->FN) { \
Mike Stump1eb44332009-09-09 15:08:12 +000046 default: assert(0 && "unknown enum value");
Douglas Gregor038f75a2009-06-15 19:02:54 +000047
48#define ATTRIBUTE_ENUM_OPT_XML( FN, NAME ) \
49 { \
50 const char* pAttributeName = NAME; \
51 const bool optional = true; \
52 switch (T->FN) { \
Mike Stump1eb44332009-09-09 15:08:12 +000053 default: assert(0 && "unknown enum value");
Douglas Gregor038f75a2009-06-15 19:02:54 +000054
55#define ENUM_XML( VALUE, NAME ) case VALUE: if ((!optional) || NAME[0]) Doc.addAttribute(pAttributeName, NAME); break;
56#define END_ENUM_XML } }
57#define END_NODE_XML }
58
59#include "clang/Frontend/TypeXML.def"
60
61};
62
Mike Stump1eb44332009-09-09 15:08:12 +000063//---------------------------------------------------------
Douglas Gregor038f75a2009-06-15 19:02:54 +000064 } // anon clang
65 } // NS XML
66
Mike Stump1eb44332009-09-09 15:08:12 +000067//---------------------------------------------------------
68class DocumentXML::TypeAdder : public TypeVisitor<DocumentXML::TypeAdder> {
Douglas Gregor038f75a2009-06-15 19:02:54 +000069 DocumentXML& Doc;
70
Mike Stump1eb44332009-09-09 15:08:12 +000071 void addIfType(const Type* pType) {
Douglas Gregor038f75a2009-06-15 19:02:54 +000072 Doc.addTypeRecursively(pType);
73 }
74
Mike Stump1eb44332009-09-09 15:08:12 +000075 void addIfType(const QualType& pType) {
Douglas Gregor038f75a2009-06-15 19:02:54 +000076 Doc.addTypeRecursively(pType);
77 }
78
79 template<class T> void addIfType(T) {}
80
81public:
82 TypeAdder(DocumentXML& doc) : Doc(doc) {}
83
84#define NODE_XML( CLASS, NAME ) \
85 void Visit##CLASS(CLASS* T) \
Mike Stump1eb44332009-09-09 15:08:12 +000086 {
Douglas Gregor038f75a2009-06-15 19:02:54 +000087
Mike Stump1eb44332009-09-09 15:08:12 +000088#define ID_ATTRIBUTE_XML
89#define TYPE_ATTRIBUTE_XML( FN ) Doc.addTypeRecursively(T->FN);
90#define CONTEXT_ATTRIBUTE_XML( FN )
91#define ATTRIBUTE_XML( FN, NAME ) addIfType(T->FN);
92#define ATTRIBUTE_OPT_XML( FN, NAME )
93#define ATTRIBUTE_ENUM_XML( FN, NAME )
94#define ATTRIBUTE_ENUM_OPT_XML( FN, NAME )
95#define ENUM_XML( VALUE, NAME )
96#define END_ENUM_XML
Douglas Gregor038f75a2009-06-15 19:02:54 +000097#define END_NODE_XML }
98
99#include "clang/Frontend/TypeXML.def"
100};
101
Mike Stump1eb44332009-09-09 15:08:12 +0000102//---------------------------------------------------------
103void DocumentXML::addParentTypes(const Type* pType) {
Douglas Gregor038f75a2009-06-15 19:02:54 +0000104 TypeAdder(*this).Visit(const_cast<Type*>(pType));
105}
106
Mike Stump1eb44332009-09-09 15:08:12 +0000107//---------------------------------------------------------
108void DocumentXML::writeTypeToXML(const Type* pType) {
Douglas Gregor038f75a2009-06-15 19:02:54 +0000109 XML::TypeWriter(*this).Visit(const_cast<Type*>(pType));
110}
111
Mike Stump1eb44332009-09-09 15:08:12 +0000112//---------------------------------------------------------
113void DocumentXML::writeTypeToXML(const QualType& pType) {
Douglas Gregor038f75a2009-06-15 19:02:54 +0000114 XML::TypeWriter(*this).VisitQualType(const_cast<QualType*>(&pType));
115}
116
Mike Stump1eb44332009-09-09 15:08:12 +0000117//---------------------------------------------------------
Douglas Gregor038f75a2009-06-15 19:02:54 +0000118} // NS clang
119