summaryrefslogtreecommitdiffstats
path: root/lib/Frontend/TypeXML.cpp
blob: f32fbbd2413ba03bc88f1f312ccff308ff02ab69 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//===--- DocumentXML.cpp - XML document for ASTs --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the XML document class, which provides the means to 
// dump out the AST in a XML form that exposes type details and other fields.
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/DocumentXML.h"
#include "clang/AST/TypeVisitor.h"
#include "clang/AST/Type.h"
#include "clang/AST/Decl.h"

namespace clang {
  namespace XML {
    namespace {

//--------------------------------------------------------- 
class TypeWriter : public TypeVisitor<TypeWriter>
{
  DocumentXML& Doc;

public:
  TypeWriter(DocumentXML& doc) : Doc(doc) {}

#define NODE_XML( CLASS, NAME )          \
  void Visit##CLASS(CLASS* T)            \
  {                                      \
    Doc.addSubNode(NAME);         

#define ID_ATTRIBUTE_XML                // done by the Document class itself
#define ATTRIBUTE_XML( FN, NAME )       Doc.addAttribute(NAME, T->FN); 
#define TYPE_ATTRIBUTE_XML( FN )        ATTRIBUTE_XML(FN, "type")
#define CONTEXT_ATTRIBUTE_XML( FN )     ATTRIBUTE_XML(FN, "context")
#define ATTRIBUTE_OPT_XML( FN, NAME )   Doc.addAttributeOptional(NAME, T->FN); 

#define ATTRIBUTE_ENUM_XML( FN, NAME )  \
  {                                     \
    const char* pAttributeName = NAME;  \
    const bool optional = false;             \
    switch (T->FN) {                    \
      default: assert(0 && "unknown enum value"); 

#define ATTRIBUTE_ENUM_OPT_XML( FN, NAME )  \
  {                                     \
    const char* pAttributeName = NAME;  \
    const bool optional = true;              \
    switch (T->FN) {                    \
      default: assert(0 && "unknown enum value"); 

#define ENUM_XML( VALUE, NAME )         case VALUE: if ((!optional) || NAME[0]) Doc.addAttribute(pAttributeName, NAME); break;
#define END_ENUM_XML                    } }
#define END_NODE_XML                    }

#include "clang/Frontend/TypeXML.def"

};

//--------------------------------------------------------- 
    } // anon clang
  } // NS XML

//--------------------------------------------------------- 
class DocumentXML::TypeAdder : public TypeVisitor<DocumentXML::TypeAdder>
{
  DocumentXML& Doc;

  void addIfType(const Type* pType)
  {
    Doc.addTypeRecursively(pType);
  }

  void addIfType(const QualType& pType)
  {
    Doc.addTypeRecursively(pType);
  }

  template<class T> void addIfType(T) {}

public:
  TypeAdder(DocumentXML& doc) : Doc(doc) {}

#define NODE_XML( CLASS, NAME )          \
  void Visit##CLASS(CLASS* T)            \
  {                                      

#define ID_ATTRIBUTE_XML                
#define TYPE_ATTRIBUTE_XML( FN )        Doc.addTypeRecursively(T->FN); 
#define CONTEXT_ATTRIBUTE_XML( FN )     
#define ATTRIBUTE_XML( FN, NAME )       addIfType(T->FN); 
#define ATTRIBUTE_OPT_XML( FN, NAME )   
#define ATTRIBUTE_ENUM_XML( FN, NAME )  
#define ATTRIBUTE_ENUM_OPT_XML( FN, NAME )  
#define ENUM_XML( VALUE, NAME )         
#define END_ENUM_XML                    
#define END_NODE_XML                    }

#include "clang/Frontend/TypeXML.def"
};

//--------------------------------------------------------- 
void DocumentXML::addParentTypes(const Type* pType)
{
  TypeAdder(*this).Visit(const_cast<Type*>(pType));
}

//--------------------------------------------------------- 
void DocumentXML::writeTypeToXML(const Type* pType)
{
  XML::TypeWriter(*this).Visit(const_cast<Type*>(pType));
}

//--------------------------------------------------------- 
void DocumentXML::writeTypeToXML(const QualType& pType)
{
  XML::TypeWriter(*this).VisitQualType(const_cast<QualType*>(&pType));
}

//--------------------------------------------------------- 
} // NS clang

OpenPOWER on IntegriCloud