Index: include/clang/AST/TypeVisitor.h
===================================================================
--- include/clang/AST/TypeVisitor.h	(revision 0)
+++ include/clang/AST/TypeVisitor.h	(revision 0)
@@ -0,0 +1,50 @@
+//===--- TypeVisitor.h - Visitor for Stmt subclasses ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the TypeVisitor interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TYPEVISITOR_H
+#define LLVM_CLANG_AST_TYPEVISITOR_H
+
+#include "clang/AST/Type.h"
+
+namespace clang {
+  
+#define DISPATCH(CLASS) \
+  return static_cast<ImplClass*>(this)->Visit ## CLASS(static_cast<CLASS*>(T))
+  
+template<typename ImplClass, typename RetTy=void>
+class TypeVisitor {
+public:
+  RetTy Visit(Type *T) {
+    // Top switch stmt: dispatch to VisitFooStmt for each FooStmt.
+    switch (T->getTypeClass()) {
+    default: assert(0 && "Unknown type class!");
+#define ABSTRACT_TYPE(CLASS, PARENT) 
+#define TYPE(CLASS, PARENT) case Type::CLASS: DISPATCH(CLASS##Type);
+#include "clang/AST/TypeNodes.def"
+    }
+  }
+    
+  // If the implementation chooses not to implement a certain visit method, fall
+  // back on superclass.
+#define TYPE(CLASS, PARENT) RetTy Visit##CLASS##Type(CLASS##Type *T) { DISPATCH(PARENT); }
+#include "clang/AST/TypeNodes.def"
+
+  // Base case, ignore it. :)
+  RetTy VisitType(Type*) { return RetTy(); }
+};
+
+#undef DISPATCH
+
+}  // end namespace clang
+
+#endif
Index: include/clang/Frontend/DeclContextXML.def
===================================================================
--- include/clang/Frontend/DeclContextXML.def	(revision 0)
+++ include/clang/Frontend/DeclContextXML.def	(revision 0)
@@ -0,0 +1,113 @@
+//===-- DeclContextXML.def - Metadata about Context XML nodes ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the XML context info database as written in the   
+//  <ReferenceSection>/<Contexts> sub-nodes of the XML document. Type nodes 
+//  are referred by "context" reference attributes throughout the document.
+//  A context node never contains sub-nodes. 
+//  The semantics of the attributes and enums are mostly self-documenting
+//  by looking at the appropriate internally used functions and values.
+//  The following macros are used:
+//
+//  NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete 
+//  context of class CLASS where CLASS is a class name used internally by clang. 
+//  After a NODE_XML the definition of all (optional) attributes of that context 
+//  node and possible sub-nodes follows.
+//
+//  END_NODE_XML - Closes the attribute definition of the current node.
+//
+//  ID_ATTRIBUTE_XML - Context nodes have an "id" attribute containing a 
+//  string, which value uniquely identify that statement. Other nodes may refer 
+//  by "context" attributes to this value.
+//
+//  TYPE_ATTRIBUTE_XML( FN ) - Context nodes may refer to the ids of type 
+//  nodes by a "type" attribute, if they create a type during declaration. 
+//  For instance 'struct S;' creates both a context 'S::' and a type 'S'. 
+//  Contexts and types always have different ids, however declarations and 
+//  contexts may share the same ids. FN is internally used by clang.
+// 
+//  ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally 
+//  used by clang. A boolean attribute have the values "0" or "1".
+//
+//  ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value
+//  is an enumeration defined with ENUM_XML macros immediately following after 
+//  that macro. An optional attribute is ommited, if the particular enum is the 
+//  empty string. FN is internally used by clang.
+//  
+//  ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is 
+//  internally used by clang.
+//
+//  END_ENUM_XML - Closes the enumeration definition of the current attribute.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TYPE_ATTRIBUTE_XML
+#  define TYPE_ATTRIBUTE_XML( FN )     ATTRIBUTE_XML(FN, "type")
+#endif
+
+#ifndef CONTEXT_ATTRIBUTE_XML
+#  define CONTEXT_ATTRIBUTE_XML( FN )  ATTRIBUTE_XML(FN, "context")
+#endif
+
+NODE_XML(TranslationUnitDecl, "TranslationUnit")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(FunctionDecl, "Function")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getType()->getAsFunctionType())
+END_NODE_XML
+
+NODE_XML(NamespaceDecl, "Namespace")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+END_NODE_XML
+
+NODE_XML(RecordDecl, "Record")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getTypeForDecl()) 
+END_NODE_XML
+
+NODE_XML(EnumDecl, "Enum")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getTypeForDecl()) 
+END_NODE_XML
+
+NODE_XML(LinkageSpecDecl, "LinkageSpec")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_ENUM_OPT_XML(getLanguage(), "lang")
+	  ENUM_XML(LinkageSpecDecl::lang_c, "C")
+	  ENUM_XML(LinkageSpecDecl::lang_cxx, "CXX")
+  END_ENUM_XML
+END_NODE_XML
+
+//===----------------------------------------------------------------------===//
+#undef NODE_XML
+#undef ID_ATTRIBUTE_XML                
+#undef TYPE_ATTRIBUTE_XML
+#undef ATTRIBUTE_XML
+#undef ATTRIBUTE_SPECIAL_XML
+#undef ATTRIBUTE_OPT_XML
+#undef ATTRIBUTE_ENUM_XML
+#undef ATTRIBUTE_ENUM_OPT_XML
+#undef ATTRIBUTE_FILE_LOCATION_XML
+#undef ENUM_XML
+#undef END_ENUM_XML                    
+#undef END_NODE_XML                    
+#undef SUB_NODE_XML
+#undef SUB_NODE_SEQUENCE_XML
+#undef SUB_NODE_OPT_XML
Index: include/clang/Frontend/DeclXML.def
===================================================================
--- include/clang/Frontend/DeclXML.def	(revision 0)
+++ include/clang/Frontend/DeclXML.def	(revision 0)
@@ -0,0 +1,250 @@
+//===-- DeclXML.def - Metadata about Decl XML nodes ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the XML statement database structure as written in 
+//  <TranslationUnit> sub-nodes of the XML document. 
+//  The semantics of the attributes and enums are mostly self-documenting
+//  by looking at the appropriate internally used functions and values.
+//  The following macros are used:
+//
+//  NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete 
+//  statement of class CLASS where CLASS is a class name used internally by clang. 
+//  After a NODE_XML the definition of all (optional) attributes of that statement 
+//  node and possible sub-nodes follows.
+//
+//  END_NODE_XML - Closes the attribute definition of the current node.
+//
+//  ID_ATTRIBUTE_XML - Some statement nodes have an "id" attribute containing a 
+//  string, which value uniquely identify that statement. Other nodes may refer 
+//  by reference attributes to this value (currently used only for Label).
+//
+//  TYPE_ATTRIBUTE_XML( FN ) - Type nodes refer to the result type id of an
+//  expression by a "type" attribute. FN is internally used by clang.
+// 
+//  ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally 
+//  used by clang. A boolean attribute have the values "0" or "1".
+//
+//  ATTRIBUTE_SPECIAL_XML( FN, NAME ) - An attribute named NAME which deserves 
+//  a special handling. See the appropriate documentations. 
+//
+//  ATTRIBUTE_FILE_LOCATION_XML - A bunch of attributes denoting the location of
+//  a statement in the source file(s).
+//
+//  ATTRIBUTE_OPT_XML( FN, NAME ) - An optional attribute named NAME. 
+//  Optional attributes are omitted for boolean types, if the value is false, 
+//  for integral types, if the value is null and for strings, 
+//  if the value is the empty string. FN is internally used by clang.
+//
+//  ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value
+//  is an enumeration defined with ENUM_XML macros immediately following after 
+//  that macro. An optional attribute is ommited, if the particular enum is the 
+//  empty string. FN is internally used by clang.
+//  
+//  ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is 
+//  internally used by clang.
+//
+//  END_ENUM_XML - Closes the enumeration definition of the current attribute.
+//
+//  SUB_NODE_XML( CLASS ) - A mandatory sub-node of class CLASS or its sub-classes.
+//
+//  SUB_NODE_OPT_XML( CLASS ) - An optional sub-node of class CLASS or its sub-classes.
+//
+//  SUB_NODE_SEQUENCE_XML( CLASS ) - Zero or more sub-nodes of class CLASS or 
+//  its sub-classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ATTRIBUTE_FILE_LOCATION_XML
+#  define ATTRIBUTE_FILE_LOCATION_XML             \
+     ATTRIBUTE_XML(getFilename(), "file")         \
+     ATTRIBUTE_XML(getLine(), "line")             \
+     ATTRIBUTE_XML(getColumn(), "col")            \
+     ATTRIBUTE_OPT_XML(getFilename(), "endfile")  \
+     ATTRIBUTE_OPT_XML(getLine(), "endline")      \
+     ATTRIBUTE_OPT_XML(getColumn(), "endcol")
+#endif
+
+#ifndef TYPE_ATTRIBUTE_XML
+#  define TYPE_ATTRIBUTE_XML( FN )    ATTRIBUTE_XML(FN, "type")
+#endif
+
+#ifndef CONTEXT_ATTRIBUTE_XML
+#  define CONTEXT_ATTRIBUTE_XML( FN ) ATTRIBUTE_XML(FN, "context")
+#endif
+
+//NODE_XML(TranslationUnitDecl, "TranslationUnit")
+//  SUB_NODE_SEQUENCE_XML(Decl)
+//END_NODE_XML
+
+NODE_XML(Decl, "FIXME_Decl")
+  ATTRIBUTE_FILE_LOCATION_XML
+END_NODE_XML
+
+NODE_XML(FunctionDecl, "Function")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getType()->getAsFunctionType()->getResultType())
+  ATTRIBUTE_XML(getType()->getAsFunctionType(), "function_type")
+  ATTRIBUTE_ENUM_OPT_XML(getStorageClass(), "storage_class")
+	  ENUM_XML(FunctionDecl::None, "")
+	  ENUM_XML(FunctionDecl::Extern, "extern")
+	  ENUM_XML(FunctionDecl::Static, "static")
+	  ENUM_XML(FunctionDecl::PrivateExtern, "__private_extern__")
+  END_ENUM_XML
+  ATTRIBUTE_OPT_XML(isInline(), "inline")
+  //ATTRIBUTE_OPT_XML(isVariadic(), "variadic")       // in the type reference
+  ATTRIBUTE_XML(getNumParams(), "num_args")
+  SUB_NODE_SEQUENCE_XML(ParmVarDecl)
+  //SUB_NODE_OPT_XML("Body")
+END_NODE_XML
+
+NODE_XML(CXXMethodDecl, "CXXMethodDecl")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getType()->getAsFunctionType()->getResultType())
+  ATTRIBUTE_XML(getType()->getAsFunctionType(), "function_type")
+  ATTRIBUTE_OPT_XML(isInline(), "inline")
+  ATTRIBUTE_OPT_XML(isStatic(), "static")       
+  ATTRIBUTE_OPT_XML(isVirtual(), "virtual")       
+  ATTRIBUTE_XML(getNumParams(), "num_args")
+  SUB_NODE_SEQUENCE_XML(ParmVarDecl)
+  //SUB_NODE_OPT_XML("Body")
+END_NODE_XML
+
+//NODE_XML("Body")
+//  SUB_NODE_XML(Stmt)
+//END_NODE_XML
+  
+NODE_XML(NamespaceDecl, "Namespace")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+END_NODE_XML
+
+NODE_XML(UsingDirectiveDecl, "UsingDirective")
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  ATTRIBUTE_XML(getNominatedNamespace(), "ref")
+END_NODE_XML
+
+NODE_XML(NamespaceAliasDecl, "NamespaceAlias")
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  ATTRIBUTE_XML(getNamespace(), "ref")
+END_NODE_XML
+
+NODE_XML(RecordDecl, "Record")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  ATTRIBUTE_OPT_XML(isDefinition() == false, "forward")
+  ATTRIBUTE_XML(getTypeForDecl(), "type")             // refers to the type this decl creates 
+  SUB_NODE_SEQUENCE_XML(FieldDecl)
+END_NODE_XML
+
+NODE_XML(EnumDecl, "Enum")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  ATTRIBUTE_OPT_XML(isDefinition() == false, "forward")
+  ATTRIBUTE_SPECIAL_XML(getIntegerType(), "type")     // is NULL in pure declarations thus deserves special handling 
+  SUB_NODE_SEQUENCE_XML(EnumConstantDecl)             // only present in definition
+END_NODE_XML
+
+NODE_XML(EnumConstantDecl, "EnumConstant")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getInitVal().toString(10, true), "value")     // integer
+  SUB_NODE_OPT_XML(Expr)                                      // init expr of this constant
+END_NODE_XML
+
+NODE_XML(FieldDecl, "Field")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_OPT_XML(isMutable(), "mutable")
+  ATTRIBUTE_OPT_XML(isBitField(), "bitfield")
+  SUB_NODE_OPT_XML(Expr)                                      // init expr of a bit field
+END_NODE_XML
+
+NODE_XML(TypedefDecl, "Typedef")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getUnderlyingType())
+END_NODE_XML
+
+NODE_XML(VarDecl, "Var")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_ENUM_OPT_XML(getStorageClass(), "storage_class")
+	  ENUM_XML(VarDecl::None, "")
+	  ENUM_XML(VarDecl::Auto, "auto")
+	  ENUM_XML(VarDecl::Register, "register")
+	  ENUM_XML(VarDecl::Extern, "extern")
+	  ENUM_XML(VarDecl::Static, "static")
+	  ENUM_XML(VarDecl::PrivateExtern, "__private_extern__")
+  END_ENUM_XML
+  SUB_NODE_OPT_XML(Expr)                                      // init expr 
+END_NODE_XML
+
+NODE_XML(ParmVarDecl, "ParmVar")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_XML(getNameAsString(), "name")
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_OPT_XML(Expr)                                      // default argument expression 
+END_NODE_XML
+
+NODE_XML(LinkageSpecDecl, "LinkageSpec")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getDeclContext(), "context")
+  ATTRIBUTE_ENUM_OPT_XML(getLanguage(), "lang")
+	  ENUM_XML(LinkageSpecDecl::lang_c, "C")
+	  ENUM_XML(LinkageSpecDecl::lang_cxx, "CXX")
+  END_ENUM_XML
+END_NODE_XML
+
+
+//===----------------------------------------------------------------------===//
+#undef NODE_XML
+#undef ID_ATTRIBUTE_XML                
+#undef TYPE_ATTRIBUTE_XML
+#undef ATTRIBUTE_XML
+#undef ATTRIBUTE_SPECIAL_XML
+#undef ATTRIBUTE_OPT_XML
+#undef ATTRIBUTE_ENUM_XML
+#undef ATTRIBUTE_ENUM_OPT_XML
+#undef ATTRIBUTE_FILE_LOCATION_XML
+#undef ENUM_XML
+#undef END_ENUM_XML                    
+#undef END_NODE_XML                    
+#undef SUB_NODE_XML
+#undef SUB_NODE_SEQUENCE_XML
+#undef SUB_NODE_OPT_XML
Index: include/clang/Frontend/DocumentXML.def
===================================================================
--- include/clang/Frontend/DocumentXML.def	(revision 0)
+++ include/clang/Frontend/DocumentXML.def	(revision 0)
@@ -0,0 +1,75 @@
+//===-- DocumentXML.def - Metadata about Document XML nodes -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the XML root database structure as written in 
+//  an AST XML document. 
+//  The following macros are used:
+//
+//  NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete 
+//  statement of class CLASS where CLASS is a class name used internally by clang. 
+//  After a NODE_XML the definition of all (optional) attributes of that statement 
+//  node and possible sub-nodes follows.
+//
+//  END_NODE_XML - Closes the attribute definition of the current node.
+//
+//  ID_ATTRIBUTE_XML - Some nodes have an "id" attribute containing a 
+//  string, which value uniquely identify the entity represented by that node. 
+//  Other nodes may refer by reference attributes to this value.
+//
+//  ATTRIBUTE_SPECIAL_XML( FN, NAME ) - An attribute named NAME which deserves 
+//  a special handling. See the appropriate documentations. 
+//
+//  SUB_NODE_XML( CLASS ) - A mandatory sub-node of class CLASS or its sub-classes.
+//
+//  SUB_NODE_SEQUENCE_XML( CLASS ) - Zero or more sub-nodes of class CLASS or 
+//  its sub-classes.
+//
+//===----------------------------------------------------------------------===//
+
+ROOT_NODE_XML("CLANG_XML")
+  ATTRIBUTE_SPECIAL_XML(ignore, "version")     // special retrieving needed
+  SUB_NODE_XML("TranslationUnit")
+  SUB_NODE_XML("ReferenceSection")
+END_NODE_XML
+
+NODE_XML("TranslationUnit")
+  SUB_NODE_SEQUENCE_XML(Decl)
+END_NODE_XML
+
+NODE_XML("ReferenceSection")
+  SUB_NODE_XML("Types")
+  SUB_NODE_XML("Contexts")
+  SUB_NODE_XML("Files")
+END_NODE_XML
+
+NODE_XML("Types")
+  SUB_NODE_SEQUENCE_XML(Type)
+END_NODE_XML
+
+NODE_XML("Contexts")
+  SUB_NODE_SEQUENCE_XML(DeclContext)
+END_NODE_XML
+
+NODE_XML("Files")
+  SUB_NODE_SEQUENCE_XML("File")
+END_NODE_XML
+
+NODE_XML("File")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_SPECIAL_XML(ignore, "name")         // special retrieving needed, denotes the source file name
+END_NODE_XML
+
+
+//===----------------------------------------------------------------------===//
+#undef NODE_XML
+#undef ID_ATTRIBUTE_XML                
+#undef ATTRIBUTE_SPECIAL_XML
+#undef END_NODE_XML                    
+#undef SUB_NODE_XML
+#undef SUB_NODE_SEQUENCE_XML
Index: include/clang/Frontend/DocumentXML.h
===================================================================
--- include/clang/Frontend/DocumentXML.h	(revision 72467)
+++ include/clang/Frontend/DocumentXML.h	(working copy)
@@ -17,6 +17,7 @@
 
 #include <string>
 #include <map>
+#include <stack>
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeOrdering.h"
 #include "llvm/Support/raw_ostream.h"
@@ -30,6 +31,7 @@
 class NamedDecl;
 class FunctionDecl;
 class ASTContext;
+class LabelStmt;
  
 //--------------------------------------------------------- 
 namespace XML
@@ -50,26 +52,37 @@
 {
 public:
   DocumentXML(const std::string& rootName, llvm::raw_ostream& out);
-  ~DocumentXML();
 
   void initialize(ASTContext &Context);
   void PrintDecl(Decl *D);
   void PrintStmt(const Stmt *S);    // defined in StmtXML.cpp
-
   void finalize();
 
 
   DocumentXML& addSubNode(const std::string& name);   // also enters the sub node, returns *this
   DocumentXML& toParent();                            // returns *this
 
+  void addAttribute(const char* pName, const QualType& pType);  
+  void addAttribute(const char* pName, bool value);
+
   template<class T>
+  void addAttribute(const char* pName, const T* value)
+  {
+    addPtrAttribute(pName, value);
+  }
+
+  template<class T>
+  void addAttribute(const char* pName, T* value)
+  {
+    addPtrAttribute(pName, value);
+  }
+
+  template<class T>
   void addAttribute(const char* pName, const T& value);
   
-  void addTypeAttribute(const QualType& pType);  
-  void addRefAttribute(const NamedDecl* D);
+  template<class T>
+  void addAttributeOptional(const char* pName, const T& value);
 
-  enum tContextUsage { CONTEXT_AS_CONTEXT, CONTEXT_AS_ID };
-  void addContextAttribute(const DeclContext *DC, tContextUsage usage = CONTEXT_AS_CONTEXT);
   void addSourceFileAttribute(const std::string& fileName);
 
   PresumedLoc addLocation(const SourceLocation& Loc);
@@ -81,13 +94,9 @@
   DocumentXML(const DocumentXML&);              // not defined
   DocumentXML& operator=(const DocumentXML&);   // not defined
 
-  struct NodeXML;
-
-  NodeXML*  Root;
-  NodeXML*  CurrentNode;   // always after Root
+  std::stack<std::string> NodeStack;
   llvm::raw_ostream& Out;
   ASTContext *Ctx;
-  int       CurrentIndent;
   bool      HasCurrentNodeSubNodes;
 
 
@@ -96,15 +105,38 @@
   XML::IdMap<const Type*>              BasicTypes;
   XML::IdMap<std::string>              SourceFiles;
   XML::IdMap<const NamedDecl*>         Decls;
+  XML::IdMap<const LabelStmt*>         Labels;
 
   void addContextsRecursively(const DeclContext *DC);
-  void addBasicTypeRecursively(const Type* pType);
+  void addTypeRecursively(const Type* pType);
   void addTypeRecursively(const QualType& pType);
 
-  void PrintFunctionDecl(FunctionDecl *FD);
-  void addDeclIdAttribute(const NamedDecl* D);
-  void addTypeIdAttribute(const Type* pType);  
   void Indent();
+
+  // forced pointer dispatch:
+  void addPtrAttribute(const char* pName, const Type* pType);  
+  void addPtrAttribute(const char* pName, const NamedDecl* D);
+  void addPtrAttribute(const char* pName, const DeclContext* D);
+  void addPtrAttribute(const char* pName, const NamespaceDecl* D);    // disambiguation
+  void addPtrAttribute(const char* pName, const LabelStmt* L);
+  void addPtrAttribute(const char* pName, const char* text);
+
+  // defined in TypeXML.cpp:
+  void addParentTypes(const Type* pType);
+  void writeTypeToXML(const Type* pType);
+  void writeTypeToXML(const QualType& pType);
+  class TypeAdder;
+  friend class TypeAdder;
+
+  // defined in DeclXML.cpp:
+  void writeDeclToXML(Decl *D);
+  class DeclPrinter;
+  friend class DeclPrinter;
+
+  // for addAttributeOptional:
+  static bool isDefault(unsigned value)           { return value == 0; }
+  static bool isDefault(bool value)               { return !value; }
+  static bool isDefault(const std::string& value) { return value.empty(); }
 };
 
 //--------------------------------------------------------- inlines
@@ -122,7 +154,29 @@
 }
 
 //--------------------------------------------------------- 
+inline void DocumentXML::addPtrAttribute(const char* pName, const char* text)
+{
+  Out << ' ' << pName << "=\"" << text << "\"";
+}
 
+//--------------------------------------------------------- 
+inline void DocumentXML::addAttribute(const char* pName, bool value)
+{
+  addPtrAttribute(pName, value ? "1" : "0");
+}
+
+//--------------------------------------------------------- 
+template<class T>
+inline void DocumentXML::addAttributeOptional(const char* pName, const T& value)
+{
+  if (!isDefault(value))
+  {
+    addAttribute(pName, value);
+  }
+}
+
+//--------------------------------------------------------- 
+
 } //namespace clang 
 
 #endif //LLVM_CLANG_DOCUMENTXML_H
Index: include/clang/Frontend/StmtXML.def
===================================================================
--- include/clang/Frontend/StmtXML.def	(revision 0)
+++ include/clang/Frontend/StmtXML.def	(revision 0)
@@ -0,0 +1,517 @@
+//===-- StmtXML.def - Metadata about Stmt XML nodes ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the XML statement database structure as written in 
+//  <TranslationUnit> sub-nodes of the XML document. 
+//  The semantics of the attributes and enums are mostly self-documenting
+//  by looking at the appropriate internally used functions and values.
+//  The following macros are used:
+//
+//  NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete 
+//  statement of class CLASS where CLASS is a class name used internally by clang. 
+//  After a NODE_XML the definition of all (optional) attributes of that statement 
+//  node and possible sub-nodes follows.
+//
+//  END_NODE_XML - Closes the attribute definition of the current node.
+//
+//  ID_ATTRIBUTE_XML - Some statement nodes have an "id" attribute containing a 
+//  string, which value uniquely identify that statement. Other nodes may refer 
+//  by reference attributes to this value (currently used only for Label).
+//
+//  TYPE_ATTRIBUTE_XML( FN ) - Type nodes refer to the result type id of an
+//  expression by a "type" attribute. FN is internally used by clang.
+// 
+//  ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally 
+//  used by clang. A boolean attribute have the values "0" or "1".
+//
+//  ATTRIBUTE_SPECIAL_XML( FN, NAME ) - An attribute named NAME which deserves 
+//  a special handling. See the appropriate documentations. 
+//
+//  ATTRIBUTE_FILE_LOCATION_XML - A bunch of attributes denoting the location of
+//  a statement in the source file(s).
+//
+//  ATTRIBUTE_OPT_XML( FN, NAME ) - An optional attribute named NAME. 
+//  Optional attributes are omitted for boolean types, if the value is false, 
+//  for integral types, if the value is null and for strings, 
+//  if the value is the empty string. FN is internally used by clang.
+//
+//  ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value
+//  is an enumeration defined with ENUM_XML macros immediately following after 
+//  that macro. An optional attribute is ommited, if the particular enum is the 
+//  empty string. FN is internally used by clang.
+//  
+//  ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is 
+//  internally used by clang.
+//
+//  END_ENUM_XML - Closes the enumeration definition of the current attribute.
+//
+//  SUB_NODE_XML( CLASS ) - A mandatory sub-node of class CLASS or its sub-classes.
+//
+//  SUB_NODE_OPT_XML( CLASS ) - An optional sub-node of class CLASS or its sub-classes.
+//
+//  SUB_NODE_SEQUENCE_XML( CLASS ) - Zero or more sub-nodes of class CLASS or 
+//  its sub-classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ATTRIBUTE_FILE_LOCATION_XML
+#  define ATTRIBUTE_FILE_LOCATION_XML             \
+     ATTRIBUTE_XML(getFilename(), "file")         \
+     ATTRIBUTE_XML(getLine(), "line")             \
+     ATTRIBUTE_XML(getColumn(), "col")            \
+     ATTRIBUTE_OPT_XML(getFilename(), "endfile")  \
+     ATTRIBUTE_OPT_XML(getLine(), "endline")      \
+     ATTRIBUTE_OPT_XML(getColumn(), "endcol")
+#endif
+
+#ifndef TYPE_ATTRIBUTE_XML
+#  define TYPE_ATTRIBUTE_XML( FN )     ATTRIBUTE_XML(FN, "type")
+#endif
+
+#ifndef CONTEXT_ATTRIBUTE_XML
+#  define CONTEXT_ATTRIBUTE_XML( FN )  ATTRIBUTE_XML(FN, "context")
+#endif
+
+
+NODE_XML(NullStmt, "NullStmt")
+  ATTRIBUTE_FILE_LOCATION_XML
+END_NODE_XML
+
+NODE_XML(CompoundStmt, "CompoundStmt")
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(size(), "num_stmts")
+  SUB_NODE_SEQUENCE_XML(Stmt)
+END_NODE_XML
+
+NODE_XML(CaseStmt, "CaseStmt")                        // case expr: body;
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Stmt)                                  // body 
+  SUB_NODE_XML(Expr)                                  // expr
+  SUB_NODE_XML(Expr)                                  // rhs expr in gc extension: case expr .. expr: body;
+END_NODE_XML
+
+NODE_XML(DefaultStmt, "DefaultStmt")                  // default: body;
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Stmt)                                  // body 
+END_NODE_XML
+
+NODE_XML(LabelStmt, "LabelStmt")                      // Label: body;
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getName(), "name")                    // string
+  SUB_NODE_XML(Stmt)                                  // body 
+END_NODE_XML
+
+NODE_XML(IfStmt, "IfStmt")                            // if (cond) stmt1; else stmt2;
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Expr)                                  // cond
+  SUB_NODE_XML(Stmt)                                  // stmt1
+  SUB_NODE_XML(Stmt)                                  // stmt2
+END_NODE_XML
+
+NODE_XML(SwitchStmt, "SwitchStmt")                    // switch (cond) body;
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Expr)                                  // cond
+  SUB_NODE_XML(Stmt)                                  // body
+END_NODE_XML
+
+NODE_XML(WhileStmt, "WhileStmt")                      // while (cond) body;
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Expr)                                  // cond
+  SUB_NODE_XML(Stmt)                                  // body
+END_NODE_XML
+
+NODE_XML(DoStmt, "DoStmt")                            // do body while (cond);
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Expr)                                  // cond
+  SUB_NODE_XML(Stmt)                                  // body
+END_NODE_XML
+
+NODE_XML(ForStmt, "ForStmt")                          // for (init; cond; inc) body;
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Stmt)                                  // init
+  SUB_NODE_XML(Expr)                                  // cond
+  SUB_NODE_XML(Expr)                                  // inc
+  SUB_NODE_XML(Stmt)                                  // body
+END_NODE_XML
+
+NODE_XML(GotoStmt, "GotoStmt")                        // goto label;
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getLabel()->getName(), "name")        // informal string
+  ATTRIBUTE_XML(getLabel(), "ref")                    // id string
+END_NODE_XML
+
+NODE_XML(IndirectGotoStmt, "IndirectGotoStmt")        // goto expr;
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Expr)                                  // expr
+END_NODE_XML
+
+NODE_XML(ContinueStmt, "ContinueStmt")                // continue
+  ATTRIBUTE_FILE_LOCATION_XML
+END_NODE_XML
+
+NODE_XML(BreakStmt, "BreakStmt")                      // break
+  ATTRIBUTE_FILE_LOCATION_XML
+END_NODE_XML
+
+NODE_XML(ReturnStmt, "ReturnStmt")                    // return expr;
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(Expr)                                  // expr
+END_NODE_XML
+
+NODE_XML(AsmStmt, "AsmStmt")                          // GNU inline-assembly statement extension
+  ATTRIBUTE_FILE_LOCATION_XML
+  // FIXME
+END_NODE_XML
+
+NODE_XML(DeclStmt, "DeclStmt")                        // a declaration statement   
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_SEQUENCE_XML(Decl)                                  
+END_NODE_XML
+
+// C++ statements
+NODE_XML(CXXTryStmt, "CXXTryStmt")                    // try CompoundStmt CXXCatchStmt1 CXXCatchStmt2 ..
+  ATTRIBUTE_FILE_LOCATION_XML
+  ATTRIBUTE_XML(getNumHandlers(), "num_handlers")
+  SUB_NODE_XML(CompoundStmt) 
+  SUB_NODE_SEQUENCE_XML(CXXCatchStmt)                                  
+END_NODE_XML
+
+NODE_XML(CXXCatchStmt, "CXXCatchStmt")                // catch (decl) Stmt
+  ATTRIBUTE_FILE_LOCATION_XML
+  SUB_NODE_XML(VarDecl)
+  SUB_NODE_XML(Stmt) 
+END_NODE_XML
+
+// Expressions
+NODE_XML(PredefinedExpr, "PredefinedExpr")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_ENUM_XML(getIdentType(), "kind")
+	  ENUM_XML(PredefinedExpr::Func, "__func__")
+	  ENUM_XML(PredefinedExpr::Function, "__FUNCTION__")
+	  ENUM_XML(PredefinedExpr::PrettyFunction, "__PRETTY_FUNCTION__")
+  END_ENUM_XML
+END_NODE_XML
+
+NODE_XML(DeclRefExpr, "DeclRefExpr")                  // an expression referring to a declared entity
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getDecl(), "ref")                     // id string of the declaration
+  ATTRIBUTE_XML(getDecl()->getNameAsString(), "name") // informal
+  //ATTRIBUTE_ENUM_XML(getDecl()->getKind(), "kind")  // really needed here?
+END_NODE_XML
+
+NODE_XML(IntegerLiteral, "IntegerLiteral")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getValue(), "value")                  // (signed) integer
+END_NODE_XML
+
+NODE_XML(CharacterLiteral, "CharacterLiteral")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getValue(), "value")                  // unsigned
+END_NODE_XML
+
+NODE_XML(FloatingLiteral, "FloatingLiteral")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  // FIXME: output float as written in source (no approximation or the like)
+  //ATTRIBUTE_XML(getValueAsApproximateDouble(), "value")   // float
+END_NODE_XML
+
+NODE_XML(StringLiteral, "StringLiteral")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_SPECIAL_XML(getStrData(), "value")          // string, special handling for escaping needed
+  ATTRIBUTE_OPT_XML(isWide(), "is_wide")                // boolean  
+END_NODE_XML
+
+NODE_XML(UnaryOperator, "UnaryOperator")                // op(expr) or (expr)op
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_ENUM_XML(getOpcode(), "kind")
+    ENUM_XML(UnaryOperator::PostInc, "postinc")
+    ENUM_XML(UnaryOperator::PostDec, "postdec")
+    ENUM_XML(UnaryOperator::PreInc,  "preinc")
+    ENUM_XML(UnaryOperator::PreDec,  "predec")
+    ENUM_XML(UnaryOperator::AddrOf,  "addrof")
+    ENUM_XML(UnaryOperator::Deref,   "deref")
+    ENUM_XML(UnaryOperator::Plus,    "plus")
+    ENUM_XML(UnaryOperator::Minus,   "minus")
+    ENUM_XML(UnaryOperator::Not,     "not")             // bitwise not
+    ENUM_XML(UnaryOperator::LNot,    "lnot")            // boolean not
+    ENUM_XML(UnaryOperator::Real,    "__real") 
+    ENUM_XML(UnaryOperator::Imag,    "__imag")
+    ENUM_XML(UnaryOperator::Extension, "__extension__")
+    ENUM_XML(UnaryOperator::OffsetOf,  "__builtin_offsetof")
+  END_ENUM_XML
+  SUB_NODE_XML(Expr)                                    // expr
+END_NODE_XML
+
+NODE_XML(BinaryOperator, "BinaryOperator")              // (expr1) op (expr2)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_ENUM_XML(getOpcode(), "kind")
+    ENUM_XML(BinaryOperator::PtrMemD  , "ptrmemd")
+    ENUM_XML(BinaryOperator::PtrMemI  , "ptrmemi")
+    ENUM_XML(BinaryOperator::Mul      , "mul")
+    ENUM_XML(BinaryOperator::Div      , "div")
+    ENUM_XML(BinaryOperator::Rem      , "rem")
+    ENUM_XML(BinaryOperator::Add      , "add")
+    ENUM_XML(BinaryOperator::Sub      , "sub")
+    ENUM_XML(BinaryOperator::Shl      , "shl")
+    ENUM_XML(BinaryOperator::Shr      , "shr")
+    ENUM_XML(BinaryOperator::LT       , "lt")
+    ENUM_XML(BinaryOperator::GT       , "gt")
+    ENUM_XML(BinaryOperator::LE       , "le")
+    ENUM_XML(BinaryOperator::GE       , "ge")
+    ENUM_XML(BinaryOperator::EQ       , "eq")
+    ENUM_XML(BinaryOperator::NE       , "ne")
+    ENUM_XML(BinaryOperator::And      , "and")          // bitwise and
+    ENUM_XML(BinaryOperator::Xor      , "xor")
+    ENUM_XML(BinaryOperator::Or       , "or")           // bitwise or
+    ENUM_XML(BinaryOperator::LAnd     , "land")         // boolean and
+    ENUM_XML(BinaryOperator::LOr      , "lor")          // boolean or
+    ENUM_XML(BinaryOperator::Assign   , "assign")
+    ENUM_XML(BinaryOperator::MulAssign, "mulassign")
+    ENUM_XML(BinaryOperator::DivAssign, "divassign")
+    ENUM_XML(BinaryOperator::RemAssign, "remassign")
+    ENUM_XML(BinaryOperator::AddAssign, "addassign")
+    ENUM_XML(BinaryOperator::SubAssign, "subassign")
+    ENUM_XML(BinaryOperator::ShlAssign, "shlassign")
+    ENUM_XML(BinaryOperator::ShrAssign, "shrassign")
+    ENUM_XML(BinaryOperator::AndAssign, "andassign")
+    ENUM_XML(BinaryOperator::XorAssign, "xorassign")
+    ENUM_XML(BinaryOperator::OrAssign , "orassign")
+    ENUM_XML(BinaryOperator::Comma    , "comma")
+  END_ENUM_XML
+  SUB_NODE_XML(Expr)                                    // expr1
+  SUB_NODE_XML(Expr)                                    // expr2
+END_NODE_XML
+
+// FIXME: is there a special class needed or is BinaryOperator sufficient?
+//NODE_XML(CompoundAssignOperator, "CompoundAssignOperator")
+
+NODE_XML(ConditionalOperator, "ConditionalOperator")    // expr1 ? expr2 : expr3
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_XML(Expr)                                    // expr1
+  SUB_NODE_XML(Expr)                                    // expr2
+  SUB_NODE_XML(Expr)                                    // expr3
+END_NODE_XML
+
+NODE_XML(SizeOfAlignOfExpr, "SizeOfAlignOfExpr")        // sizeof(expr) or alignof(expr)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(isSizeOf(), "is_sizeof")  
+  ATTRIBUTE_XML(isArgumentType(), "is_type")            // "1" if expr denotes a type
+  ATTRIBUTE_SPECIAL_XML(getArgumentType(), "type_ref")  // optional, denotes the type of expr, if is_type=="1", special handling needed since getArgumentType() could assert
+  SUB_NODE_OPT_XML(Expr)                                // expr, if is_type=="0"
+END_NODE_XML
+
+NODE_XML(ArraySubscriptExpr, "ArraySubscriptExpr")      // expr1[expr2]
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_XML(Expr)                                    // expr1
+  SUB_NODE_XML(Expr)                                    // expr2
+END_NODE_XML
+
+NODE_XML(CallExpr, "CallExpr")                          // fnexpr(arg1, arg2, ...)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getNumArgs(), "num_args")               // unsigned
+  SUB_NODE_XML(Expr)                                    // fnexpr
+  SUB_NODE_SEQUENCE_XML(Expr)                           // arg1..argN
+END_NODE_XML
+
+NODE_XML(MemberExpr, "MemberExpr")                      // expr->F or expr.F
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(isArrow(), "is_deref")
+  ATTRIBUTE_XML(getMemberDecl(), "ref")                 // refers to F
+  ATTRIBUTE_XML(getMemberDecl()->getNameAsString(), "name") // informal
+  SUB_NODE_XML(Expr)                                    // expr
+END_NODE_XML
+
+NODE_XML(CStyleCastExpr, "CStyleCastExpr")              // (type)expr
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())                         
+  ATTRIBUTE_XML(getTypeAsWritten(), "type_ref")         // denotes the type as written in the source code
+  SUB_NODE_XML(Expr)                                    // expr
+END_NODE_XML
+
+NODE_XML(ImplicitCastExpr, "ImplicitCastExpr")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())                         
+  SUB_NODE_XML(Expr)                                   
+END_NODE_XML
+
+NODE_XML(CompoundLiteralExpr, "CompoundLiteralExpr")    // [C99 6.5.2.5] 
+  SUB_NODE_XML(Expr)                                    // init
+END_NODE_XML
+
+NODE_XML(ExtVectorElementExpr, "ExtVectorElementExpr")
+  SUB_NODE_XML(Expr)                                    // base 
+END_NODE_XML
+
+NODE_XML(InitListExpr, "InitListExpr")                  // struct foo x = { expr1, { expr2, expr3 } };
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_OPT_XML(getInitializedFieldInUnion(), "field_ref")  // if a union is initialized, this refers to the initialized union field id 
+  ATTRIBUTE_XML(getNumInits(), "num_inits")             // unsigned
+  SUB_NODE_SEQUENCE_XML(Expr)                           // expr1..exprN
+END_NODE_XML
+
+NODE_XML(DesignatedInitExpr, "DesignatedInitExpr")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+END_NODE_XML
+
+NODE_XML(ImplicitValueInitExpr, "ImplicitValueInitExpr")  //  Implicit value initializations occur within InitListExpr
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+END_NODE_XML
+
+NODE_XML(VAArgExpr, "VAArgExpr")                        // used for the builtin function __builtin_va_start(expr)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_XML(Expr)                                    // expr
+END_NODE_XML
+
+NODE_XML(ParenExpr, "ParenExpr")                        // this represents a parethesized expression "(expr)". Only formed if full location information is requested.
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_XML(Expr)                                    // expr
+END_NODE_XML
+
+// GNU Extensions
+NODE_XML(AddrLabelExpr, "AddrLabelExpr")                // the GNU address of label extension, representing &&label.
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getLabel(), "ref")                      // id string
+  SUB_NODE_XML(LabelStmt)                               // expr
+END_NODE_XML
+
+NODE_XML(StmtExpr, "StmtExpr")                          // StmtExpr contains a single CompoundStmt node, which it evaluates and takes the value of the last subexpression.
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_XML(CompoundStmt)
+END_NODE_XML
+
+NODE_XML(TypesCompatibleExpr, "TypesCompatibleExpr")    // GNU builtin-in function __builtin_types_compatible_p
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getArgType1(), "type1_ref")             // id of type1 
+  ATTRIBUTE_XML(getArgType2(), "type2_ref")             // id of type2 
+END_NODE_XML
+
+NODE_XML(ChooseExpr, "ChooseExpr")                      // GNU builtin-in function __builtin_choose_expr(expr1, expr2, expr3)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_XML(Expr)                                    // expr1
+  SUB_NODE_XML(Expr)                                    // expr2
+  SUB_NODE_XML(Expr)                                    // expr3
+END_NODE_XML
+
+NODE_XML(GNUNullExpr, "GNUNullExpr")                    // GNU __null extension
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+END_NODE_XML
+
+// C++ Expressions
+NODE_XML(CXXOperatorCallExpr, "CXXOperatorCallExpr")    // fnexpr(arg1, arg2, ...)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getNumArgs(), "num_args")               // unsigned
+  SUB_NODE_XML(Expr)                                    // fnexpr
+  SUB_NODE_SEQUENCE_XML(Expr)                           // arg1..argN
+END_NODE_XML
+
+NODE_XML(CXXNamedCastExpr, "CXXNamedCastExpr")          // xxx_cast<type>(expr)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_ENUM_XML(getStmtClass(), "kind")
+	  ENUM_XML(Stmt::CXXStaticCastExprClass, "static_cast")
+	  ENUM_XML(Stmt::CXXDynamicCastExprClass, "dynamic_cast")
+	  ENUM_XML(Stmt::CXXReinterpretCastExprClass, "reinterpret_cast")
+	  ENUM_XML(Stmt::CXXConstCastExprClass, "const_cast")
+  END_ENUM_XML
+  ATTRIBUTE_XML(getTypeAsWritten(), "type_ref")         // denotes the type as written in the source code
+  SUB_NODE_XML(Expr)                                    // expr
+END_NODE_XML
+
+NODE_XML(CXXMemberCallExpr, "CXXMemberCallExpr")        // fnexpr(arg1, arg2, ...)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getNumArgs(), "num_args")               // unsigned
+  SUB_NODE_XML(Expr)                                    // fnexpr
+  SUB_NODE_SEQUENCE_XML(Expr)                           // arg1..argN
+END_NODE_XML
+
+NODE_XML(CXXBoolLiteralExpr, "CXXBoolLiteralExpr")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getValue(), "value")                    // boolean
+END_NODE_XML
+
+NODE_XML(CXXNullPtrLiteralExpr, "CXXNullPtrLiteralExpr")  // [C++0x 2.14.7] C++ Pointer Literal
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+END_NODE_XML
+
+NODE_XML(CXXTypeidExpr, "CXXTypeidExpr")                // typeid(expr)
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(isTypeOperand(), "is_type")             // "1" if expr denotes a type
+  ATTRIBUTE_SPECIAL_XML(getTypeOperand(), "type_ref")   // optional, denotes the type of expr, if is_type=="1", special handling needed since getTypeOperand() could assert
+  SUB_NODE_OPT_XML(Expr)                                // expr, if is_type=="0"
+END_NODE_XML
+
+NODE_XML(CXXThisExpr, "CXXThisExpr")                    // this
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+END_NODE_XML
+
+NODE_XML(CXXThrowExpr, "CXXThrowExpr")                  // throw (expr);
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_XML(Expr)                                    // NULL in case of "throw;"
+END_NODE_XML
+
+NODE_XML(CXXDefaultArgExpr, "CXXDefaultArgExpr")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  ATTRIBUTE_XML(getParam(), "ref")                      // id of the parameter declaration (the expression is a subnode of the declaration)
+END_NODE_XML
+
+NODE_XML(CXXConditionDeclExpr, "CXXConditionDeclExpr")
+  ATTRIBUTE_FILE_LOCATION_XML
+  TYPE_ATTRIBUTE_XML(getType())
+  SUB_NODE_XML(VarDecl)                                 // a CXXConditionDeclExpr owns the declaration
+END_NODE_XML
+
+
+//===----------------------------------------------------------------------===//
+#undef NODE_XML
+#undef ID_ATTRIBUTE_XML                
+#undef TYPE_ATTRIBUTE_XML
+#undef ATTRIBUTE_XML
+#undef ATTRIBUTE_SPECIAL_XML
+#undef ATTRIBUTE_OPT_XML
+#undef ATTRIBUTE_ENUM_XML
+#undef ATTRIBUTE_ENUM_OPT_XML
+#undef ATTRIBUTE_FILE_LOCATION_XML
+#undef ENUM_XML
+#undef END_ENUM_XML                    
+#undef END_NODE_XML                    
+#undef SUB_NODE_XML
+#undef SUB_NODE_SEQUENCE_XML
+#undef SUB_NODE_OPT_XML
Index: include/clang/Frontend/TypeXML.def
===================================================================
--- include/clang/Frontend/TypeXML.def	(revision 0)
+++ include/clang/Frontend/TypeXML.def	(revision 0)
@@ -0,0 +1,277 @@
+//===-- TypeXML.def - Metadata about Type XML nodes ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the XML type info database as written in the   
+//  <ReferenceSection>/<Types> sub-nodes of the XML document. Type nodes 
+//  are referred by "type" reference attributes throughout the document.
+//  A type node never contains sub-nodes. 
+//  The semantics of the attributes and enums are mostly self-documenting
+//  by looking at the appropriate internally used functions and values.
+//  The following macros are used:
+//
+//  NODE_XML( CLASS, NAME ) - A node of name NAME denotes a concrete 
+//  type of class CLASS where CLASS is a class name used internally by clang. 
+//  After a NODE_XML the definition of all (optional) attributes of that type 
+//  node follows.
+//
+//  END_NODE_XML - Closes the attribute definition of the current node.
+//
+//  ID_ATTRIBUTE_XML - Each type node has an "id" attribute containing a 
+//  string, which value uniquely identify the type. Other nodes may refer 
+//  by "type" reference attributes to this value.
+//
+//  TYPE_ATTRIBUTE_XML( FN ) - Type nodes may refer to the ids of other type 
+//  nodes by a "type" attribute. FN is internally used by clang.
+// 
+//  CONTEXT_ATTRIBUTE_XML( FN ) - Type nodes may refer to the ids of their 
+//  declaration contexts by a "context" attribute. FN is internally used by 
+//  clang.
+//
+//  ATTRIBUTE_XML( FN, NAME ) - An attribute named NAME. FN is internally 
+//  used by clang. A boolean attribute have the values "0" or "1".
+//
+//  ATTRIBUTE_OPT_XML( FN, NAME ) - An optional attribute named NAME. 
+//  Optional attributes are omitted for boolean types, if the value is false, 
+//  for integral types, if the value is null and for strings, 
+//  if the value is the empty string. FN is internally used by clang.
+//
+//  ATTRIBUTE_ENUM[_OPT]_XML( FN, NAME ) - An attribute named NAME. The value
+//  is an enumeration defined with ENUM_XML macros immediately following after 
+//  that macro. An optional attribute is ommited, if the particular enum is the 
+//  empty string. FN is internally used by clang.
+//  
+//  ENUM_XML( VALUE, NAME ) - An enumeration element named NAME. VALUE is 
+//  internally used by clang.
+//
+//  END_ENUM_XML - Closes the enumeration definition of the current attribute.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TYPE_ATTRIBUTE_XML
+#  define TYPE_ATTRIBUTE_XML( FN )     ATTRIBUTE_XML(FN, "type")
+#endif
+
+#ifndef CONTEXT_ATTRIBUTE_XML
+#  define CONTEXT_ATTRIBUTE_XML( FN )  ATTRIBUTE_XML(FN, "context")
+#endif
+
+
+NODE_XML(QualType, "CvQualifiedType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getTypePtr())                      // the qualified type, e.g. for 'T* const' it's 'T*'
+  ATTRIBUTE_OPT_XML(isConstQualified(), "const")        // boolean
+  ATTRIBUTE_OPT_XML(isVolatileQualified(), "volatile")  // boolean
+  ATTRIBUTE_OPT_XML(isRestrictQualified(), "restrict")  // boolean
+END_NODE_XML
+
+NODE_XML(ExtQualType, "ExtQualType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getBaseType())
+  ATTRIBUTE_OPT_XML(getAddressSpace(), "adress_space")  // unsigned: Address Space ID - The address space ID this type is qualified with.
+  ATTRIBUTE_ENUM_OPT_XML(getObjCGCAttr(), "objc_gc")    // GC __weak/__strong attributes
+	  ENUM_XML(QualType::GCNone, "")
+	  ENUM_XML(QualType::Weak, "weak")
+	  ENUM_XML(QualType::Strong, "strong")
+  END_ENUM_XML
+END_NODE_XML
+
+NODE_XML(BuiltinType, "FundamentalType")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_ENUM_XML(getKind(), "kind")
+	  ENUM_XML(BuiltinType::Void, "void")
+	  ENUM_XML(BuiltinType::Bool, "bool")
+	  ENUM_XML(BuiltinType::Char_U, "char")               // not explicitely qualified char, depends on target platform
+	  ENUM_XML(BuiltinType::Char_S, "char")               // not explicitely qualified char, depends on target platform
+	  ENUM_XML(BuiltinType::SChar, "signed char")
+	  ENUM_XML(BuiltinType::Short, "short");
+	  ENUM_XML(BuiltinType::Int, "int");
+	  ENUM_XML(BuiltinType::Long, "long");
+	  ENUM_XML(BuiltinType::LongLong, "long long");
+	  ENUM_XML(BuiltinType::Int128, "__int128_t");
+	  ENUM_XML(BuiltinType::UChar, "unsigned char");
+	  ENUM_XML(BuiltinType::UShort, "unsigned short");
+	  ENUM_XML(BuiltinType::UInt, "unsigned int");
+	  ENUM_XML(BuiltinType::ULong, "unsigned long");
+	  ENUM_XML(BuiltinType::ULongLong, "unsigned long long");
+	  ENUM_XML(BuiltinType::UInt128, "__uint128_t");
+	  ENUM_XML(BuiltinType::Float, "float");
+	  ENUM_XML(BuiltinType::Double, "double");
+	  ENUM_XML(BuiltinType::LongDouble, "long double");
+	  ENUM_XML(BuiltinType::WChar, "wchar_t");
+	  ENUM_XML(BuiltinType::NullPtr, "nullptr_t");        // This is the type of C++0x 'nullptr'.
+	  ENUM_XML(BuiltinType::Overload, "overloaded");
+	  ENUM_XML(BuiltinType::Dependent, "dependent");
+  END_ENUM_XML
+END_NODE_XML
+
+NODE_XML(FixedWidthIntType, "FixedWidthIntType")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getWidth(), "width")                    // unsigned
+  ATTRIBUTE_XML(isSigned(), "is_signed")                // boolean
+END_NODE_XML
+
+NODE_XML(PointerType, "PointerType")    
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getPointeeType())
+END_NODE_XML
+
+NODE_XML(LValueReferenceType, "ReferenceType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getPointeeType())
+END_NODE_XML
+
+NODE_XML(RValueReferenceType, "ReferenceType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getPointeeType())
+END_NODE_XML
+
+NODE_XML(FunctionNoProtoType, "FunctionNoProtoType")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(FunctionProtoType, "FunctionType")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getResultType(), "result_type")
+  ATTRIBUTE_OPT_XML(isVariadic(), "variadic")
+END_NODE_XML
+
+NODE_XML(TypedefType, "Typedef")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getDecl()->getUnderlyingType())
+  ATTRIBUTE_XML(getDecl()->getNameAsString(), "name")     // string
+  CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext())
+END_NODE_XML
+
+NODE_XML(ComplexType, "ComplexType")                      // C99 complex types (_Complex float etc)
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getElementType())
+END_NODE_XML
+
+NODE_XML(BlockPointerType, "BlockPointerType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getPointeeType())                    // alway refers to a function type
+END_NODE_XML
+
+NODE_XML(MemberPointerType, "MemberPointerType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getPointeeType())
+  ATTRIBUTE_XML(getClass(), "class_type")                 // refers to the class type id of which the pointee is a member
+END_NODE_XML
+
+NODE_XML(ConstantArrayType, "ArrayType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getElementType())
+  ATTRIBUTE_XML(getSize(), "size")                        // unsigned                    
+  ATTRIBUTE_ENUM_OPT_XML(getSizeModifier(), "size_modifier")
+	  ENUM_XML(ArrayType::Normal, "")
+	  ENUM_XML(ArrayType::Static, "static")
+	  ENUM_XML(ArrayType::Star, "star")
+  END_ENUM_XML
+  ATTRIBUTE_OPT_XML(getIndexTypeQualifier(), "index_type_qualifier")   // unsigned
+END_NODE_XML
+
+NODE_XML(IncompleteArrayType, "IncompleteArrayType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getElementType())
+END_NODE_XML
+
+NODE_XML(VariableArrayType, "VariableArrayType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getElementType())
+  // note: the size expression is print at the point of declaration
+END_NODE_XML
+
+NODE_XML(DependentSizedArrayType, "DependentSizedArrayType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getElementType())
+  // FIXME: how to deal with size expression?
+END_NODE_XML
+
+NODE_XML(VectorType, "VectorType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getElementType())
+  ATTRIBUTE_XML(getNumElements(), "size")               // unsigned
+END_NODE_XML
+
+NODE_XML(ExtVectorType, "ExtVectorType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getElementType())
+  ATTRIBUTE_XML(getNumElements(), "size")               // unsigned
+END_NODE_XML
+
+NODE_XML(TypeOfExprType, "TypeOfExprType")
+  ID_ATTRIBUTE_XML
+  // note: the typeof expression is print at the point of use
+END_NODE_XML
+
+NODE_XML(TypeOfType, "TypeOfType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getUnderlyingType())
+END_NODE_XML
+
+
+NODE_XML(RecordType, "Record")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getDecl()->getNameAsString(), "name")   // string
+  ATTRIBUTE_ENUM_XML(getDecl()->getTagKind(), "kind")
+    ENUM_XML(TagDecl::TK_struct, "struct")
+    ENUM_XML(TagDecl::TK_union, "union")
+    ENUM_XML(TagDecl::TK_class, "class")
+  END_ENUM_XML
+  CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext())
+END_NODE_XML
+
+NODE_XML(EnumType, "Enum")
+  ID_ATTRIBUTE_XML
+  ATTRIBUTE_XML(getDecl()->getNameAsString(), "name")   // string
+  CONTEXT_ATTRIBUTE_XML(getDecl()->getDeclContext())
+END_NODE_XML
+
+NODE_XML(TemplateTypeParmType, "TemplateTypeParmType")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(TemplateSpecializationType, "TemplateSpecializationType")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(QualifiedNameType, "QualifiedNameType")
+  ID_ATTRIBUTE_XML
+  TYPE_ATTRIBUTE_XML(getNamedType())
+END_NODE_XML
+
+NODE_XML(TypenameType, "TypenameType")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(ObjCInterfaceType, "ObjCInterfaceType")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(ObjCQualifiedInterfaceType, "ObjCQualifiedInterfaceType")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+NODE_XML(ObjCQualifiedIdType, "ObjCQualifiedIdType")
+  ID_ATTRIBUTE_XML
+END_NODE_XML
+
+
+//===----------------------------------------------------------------------===//
+#undef NODE_XML
+#undef ID_ATTRIBUTE_XML                
+#undef TYPE_ATTRIBUTE_XML
+#undef CONTEXT_ATTRIBUTE_XML
+#undef ATTRIBUTE_XML
+#undef ATTRIBUTE_OPT_XML
+#undef ATTRIBUTE_ENUM_XML
+#undef ATTRIBUTE_ENUM_OPT_XML
+#undef ENUM_XML
+#undef END_ENUM_XML                    
+#undef END_NODE_XML                    
Index: lib/Frontend/CMakeLists.txt
===================================================================
--- lib/Frontend/CMakeLists.txt	(revision 72467)
+++ lib/Frontend/CMakeLists.txt	(working copy)
@@ -5,6 +5,7 @@
   ASTConsumers.cpp
   Backend.cpp
   CacheTokens.cpp
+  DeclXML.cpp
   DependencyFile.cpp
   DiagChecker.cpp
   DocumentXML.cpp
@@ -31,5 +32,6 @@
   StmtXML.cpp
   TextDiagnosticBuffer.cpp
   TextDiagnosticPrinter.cpp
+  TypeXML.cpp
   Warnings.cpp
   )
Index: lib/Frontend/DeclXML.cpp
===================================================================
--- lib/Frontend/DeclXML.cpp	(revision 0)
+++ lib/Frontend/DeclXML.cpp	(revision 0)
@@ -0,0 +1,161 @@
+//===--- DeclXML.cpp - XML implementation for Decl 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/DeclVisitor.h"
+#include "clang/AST/Expr.h"
+
+namespace clang {
+
+//--------------------------------------------------------- 
+class DocumentXML::DeclPrinter : public DeclVisitor<DocumentXML::DeclPrinter>
+{
+  DocumentXML& Doc;
+
+  void addSubNodes(FunctionDecl* FD)
+  {
+    for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) 
+    {
+      Visit(FD->getParamDecl(i));
+      Doc.toParent();
+    }
+  }
+
+  void addSubNodes(RecordDecl* RD)
+  {
+    for (RecordDecl::field_iterator i = RD->field_begin(*Doc.Ctx), e = RD->field_end(*Doc.Ctx); i != e; ++i)
+    {
+      Visit(*i);
+      Doc.toParent();
+    }
+  }
+
+  void addSubNodes(EnumDecl* ED)
+  {
+    for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(*Doc.Ctx), e = ED->enumerator_end(*Doc.Ctx); i != e; ++i)
+    {
+      Visit(*i);
+      Doc.toParent();
+    }
+  }
+
+  void addSubNodes(EnumConstantDecl* ECD)
+  {
+    if (ECD->getInitExpr()) 
+    {
+      Doc.PrintStmt(ECD->getInitExpr());
+    }
+  }
+
+  void addSubNodes(FieldDecl* FdD)
+  {
+    if (FdD->isBitField())
+    {
+      Doc.PrintStmt(FdD->getBitWidth());
+    }
+  }
+
+  void addSubNodes(VarDecl* V)
+  {
+    if (V->getInit()) 
+    {
+      Doc.PrintStmt(V->getInit());
+    }
+  }
+
+  void addSubNodes(ParmVarDecl* argDecl)
+  {
+    if (argDecl->getDefaultArg())
+    {
+      Doc.PrintStmt(argDecl->getDefaultArg());
+    }
+  }
+
+  void addSpecialAttribute(const char* pName, EnumDecl* ED)
+  {
+    const QualType& enumType = ED->getIntegerType();
+    if (!enumType.isNull())
+    {
+      Doc.addAttribute(pName, enumType);
+    }
+  }
+
+  void addIdAttribute(LinkageSpecDecl* ED)
+  {
+    Doc.addAttribute("id", ED);
+  }
+
+  void addIdAttribute(NamedDecl* ND)
+  {
+    Doc.addAttribute("id", ND);
+  }
+
+public:
+  DeclPrinter(DocumentXML& doc) : Doc(doc) {}
+
+#define NODE_XML( CLASS, NAME )          \
+  void Visit##CLASS(CLASS* T)            \
+  {                                      \
+    Doc.addSubNode(NAME);         
+
+#define ID_ATTRIBUTE_XML                  addIdAttribute(T);
+#define ATTRIBUTE_XML( FN, NAME )         Doc.addAttribute(NAME, T->FN); 
+#define ATTRIBUTE_OPT_XML( FN, NAME )     Doc.addAttributeOptional(NAME, T->FN); 
+#define ATTRIBUTE_FILE_LOCATION_XML       Doc.addLocation(T->getLocation());
+#define ATTRIBUTE_SPECIAL_XML( FN, NAME ) addSpecialAttribute(NAME, T);
+
+#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                    }
+
+#define SUB_NODE_XML( CLASS )           addSubNodes(T);
+#define SUB_NODE_SEQUENCE_XML( CLASS )  addSubNodes(T);
+#define SUB_NODE_OPT_XML( CLASS )       addSubNodes(T);
+
+#include "clang/Frontend/DeclXML.def"
+};
+
+
+//--------------------------------------------------------- 
+void DocumentXML::writeDeclToXML(Decl *D)
+{
+  DeclPrinter(*this).Visit(D);
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 
+  {
+    if (Stmt *Body = FD->getBody(*Ctx)) {
+      addSubNode("Body");
+      PrintStmt(Body);
+      toParent();
+    }
+  }
+  toParent();
+}
+
+//--------------------------------------------------------- 
+} // NS clang
+
Index: lib/Frontend/DocumentXML.cpp
===================================================================
--- lib/Frontend/DocumentXML.cpp	(revision 72467)
+++ lib/Frontend/DocumentXML.cpp	(working copy)
@@ -14,92 +14,66 @@
 
 #include "clang/Frontend/DocumentXML.h"
 #include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/Expr.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/StringExtras.h"
 
 namespace clang {
 
 //--------------------------------------------------------- 
-struct DocumentXML::NodeXML
-{
-  std::string               Name;
-  NodeXML*                  Parent;
-
-  NodeXML(const std::string& name, NodeXML* parent) :
-    Name(name),
-    Parent(parent)
-  {}
-};
-
-//--------------------------------------------------------- 
 DocumentXML::DocumentXML(const std::string& rootName, llvm::raw_ostream& out) :
-  Root(new NodeXML(rootName, 0)),
-  CurrentNode(Root),
   Out(out),
   Ctx(0),
-  CurrentIndent(0),
   HasCurrentNodeSubNodes(false)
 {
+  NodeStack.push(rootName);
   Out << "<?xml version=\"1.0\"?>\n<" << rootName;
 }
 
 //--------------------------------------------------------- 
-DocumentXML::~DocumentXML()
-{
-  assert(CurrentNode == Root && "not completely backtracked");
-  delete Root;
-}
-
-//--------------------------------------------------------- 
 DocumentXML& DocumentXML::addSubNode(const std::string& name)
 {
   if (!HasCurrentNodeSubNodes)
   {
     Out << ">\n";
   }
-  CurrentNode = new NodeXML(name, CurrentNode);
+  NodeStack.push(name);
   HasCurrentNodeSubNodes = false;
-  CurrentIndent += 2;
   Indent();
-  Out << "<" << CurrentNode->Name;
+  Out << "<" << NodeStack.top();
   return *this;
 }
 
 //--------------------------------------------------------- 
 void DocumentXML::Indent() 
 {
-  for (int i = 0; i < CurrentIndent; ++i)
+  for (size_t i = 0, e = (NodeStack.size() - 1) * 2; i < e; ++i)
     Out << ' ';
 }
 
 //--------------------------------------------------------- 
 DocumentXML& DocumentXML::toParent() 
 { 
-  assert(CurrentNode != Root && "to much backtracking");
+  assert(NodeStack.size() > 1 && "to much backtracking");
 
   if (HasCurrentNodeSubNodes)
   {
     Indent();
-    Out << "</" << CurrentNode->Name << ">\n";
+    Out << "</" << NodeStack.top() << ">\n";
   }
   else
   {
     Out << "/>\n";
   }
-  NodeXML* NodeToDelete = CurrentNode;
-  CurrentNode = CurrentNode->Parent; 
-  delete NodeToDelete;
+  NodeStack.pop();
   HasCurrentNodeSubNodes = true;
-  CurrentIndent -= 2;
   return *this; 
 }
 
 //--------------------------------------------------------- 
 namespace {
 
-enum tIdType { ID_NORMAL, ID_FILE, ID_LAST };
+enum tIdType { ID_NORMAL, ID_FILE, ID_LABEL, ID_LAST };
 
 unsigned getNewId(tIdType idType)
 {
@@ -110,7 +84,7 @@
 //--------------------------------------------------------- 
 inline std::string getPrefixedId(unsigned uId, tIdType idType)
 {
-  static const char idPrefix[ID_LAST] = { '_', 'f' };
+  static const char idPrefix[ID_LAST] = { '_', 'f', 'l' };
   char buffer[20];
   char* BufPtr = llvm::utohex_buffer(uId, buffer + 20);
   *--BufPtr = idPrefix[idType];
@@ -132,6 +106,7 @@
 
 } // anon NS
 
+
 //--------------------------------------------------------- 
 std::string DocumentXML::escapeString(const char* pStr, std::string::size_type len)
 {
@@ -170,7 +145,7 @@
 //--------------------------------------------------------- 
 void DocumentXML::finalize()
 {
-  assert(CurrentNode == Root && "not completely backtracked");
+  assert(NodeStack.size() == 1 && "not completely backtracked");
 
   addSubNode("ReferenceSection");
   addSubNode("Types");
@@ -179,71 +154,15 @@
   {
     if (i->first.getCVRQualifiers() != 0)
     {
-      addSubNode("CvQualifiedType");
+      writeTypeToXML(i->first);
       addAttribute("id", getPrefixedId(i->second, ID_NORMAL));
-      addAttribute("type", getPrefixedId(BasicTypes[i->first.getTypePtr()], ID_NORMAL));
-      if (i->first.isConstQualified()) addAttribute("const", "1");
-      if (i->first.isVolatileQualified()) addAttribute("volatile", "1");
-      if (i->first.isRestrictQualified()) addAttribute("restrict", "1");
       toParent();
     }
   }
 
   for (XML::IdMap<const Type*>::iterator i = BasicTypes.begin(), e = BasicTypes.end(); i != e; ++i)
   {
-    // don't use the get methods as they strip of typedef infos
-    if (const BuiltinType *BT = dyn_cast<BuiltinType>(i->first)) {
-      addSubNode("FundamentalType");
-      addAttribute("name", BT->getName());
-    }
-    else if (const PointerType *PT = dyn_cast<PointerType>(i->first)) {
-      addSubNode("PointerType");
-      addTypeAttribute(PT->getPointeeType());
-    }
-    else if (dyn_cast<FunctionType>(i->first) != 0) {
-      addSubNode("FunctionType");
-    }
-    else if (const ReferenceType *RT = dyn_cast<ReferenceType>(i->first)) {
-      addSubNode("ReferenceType");
-      addTypeAttribute(RT->getPointeeType());
-    }
-    else if (const TypedefType * TT = dyn_cast<TypedefType>(i->first)) {
-      addSubNode("Typedef");
-      addAttribute("name", TT->getDecl()->getNameAsString());
-      addTypeAttribute(TT->getDecl()->getUnderlyingType());
-      addContextAttribute(TT->getDecl()->getDeclContext());
-    }
-    else if (const QualifiedNameType *QT = dyn_cast<QualifiedNameType>(i->first)) {
-      addSubNode("QualifiedNameType");
-      addTypeAttribute(QT->getNamedType());
-    }
-    else if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(i->first)) {
-      addSubNode("ArrayType");
-      addAttribute("min", 0);
-      addAttribute("max", (CAT->getSize() - 1).toString(10, false));
-      addTypeAttribute(CAT->getElementType());
-    }
-    else if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(i->first)) {
-      addSubNode("VariableArrayType");
-      addTypeAttribute(VAT->getElementType());
-    } 
-    else if (const TagType *RET = dyn_cast<TagType>(i->first)) {
-      const TagDecl *tagDecl = RET->getDecl();
-      std::string tagKind = tagDecl->getKindName();
-      tagKind[0] = std::toupper(tagKind[0]);
-      addSubNode(tagKind);
-      addAttribute("name", tagDecl->getNameAsString());
-      addContextAttribute(tagDecl->getDeclContext());
-    }
-    else if (const VectorType* VT = dyn_cast<VectorType>(i->first)) {
-      addSubNode("VectorType");
-      addTypeAttribute(VT->getElementType());
-      addAttribute("num_elements", VT->getNumElements());
-    }
-    else 
-    {
-      addSubNode("FIXMEType");
-    }
+    writeTypeToXML(i->first);
     addAttribute("id", getPrefixedId(i->second, ID_NORMAL));
     toParent();
   }
@@ -267,7 +186,7 @@
 
     if (const DeclContext* parent = i->first->getParent())
     {
-      addContextAttribute(parent);
+      addAttribute("context", parent);
     } 
     toParent();
   }
@@ -285,21 +204,21 @@
   toParent().toParent();
   
   // write the root closing node (which has always subnodes)
-  Out << "</" << CurrentNode->Name << ">\n";
+  Out << "</" << NodeStack.top() << ">\n";
 }
 
 //--------------------------------------------------------- 
-void DocumentXML::addTypeAttribute(const QualType& pType)
+void DocumentXML::addAttribute(const char* pAttributeName, const QualType& pType)
 {
   addTypeRecursively(pType);
-  addAttribute("type", getPrefixedId(Types[pType], ID_NORMAL));
+  addAttribute(pAttributeName, getPrefixedId(Types[pType], ID_NORMAL));
 }
 
 //--------------------------------------------------------- 
-void DocumentXML::addTypeIdAttribute(const Type* pType)
+void DocumentXML::addPtrAttribute(const char* pAttributeName, const Type* pType)
 {
-  addBasicTypeRecursively(pType);
-  addAttribute("id", getPrefixedId(BasicTypes[pType], ID_NORMAL));
+  addTypeRecursively(pType);
+  addAttribute(pAttributeName, getPrefixedId(BasicTypes[pType], ID_NORMAL));
 }
 
 //--------------------------------------------------------- 
@@ -307,7 +226,7 @@
 {
   if (addToMap(Types, pType))
   {
-    addBasicTypeRecursively(pType.getTypePtr());
+    addTypeRecursively(pType.getTypePtr());
     // beautifier: a non-qualified type shall be transparent
     if (pType.getCVRQualifiers() == 0)
     {
@@ -317,46 +236,52 @@
 }
 
 //--------------------------------------------------------- 
-void DocumentXML::addBasicTypeRecursively(const Type* pType)
+void DocumentXML::addTypeRecursively(const Type* pType)
 {
   if (addToMap(BasicTypes, pType))
   {
-    if (const PointerType *PT = dyn_cast<PointerType>(pType)) {
-      addTypeRecursively(PT->getPointeeType());
+    addParentTypes(pType);
+/*
+    // FIXME: doesn't work in the immediate streaming approach
+    if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(pType)) 
+    {
+      addSubNode("VariableArraySizeExpression");
+      PrintStmt(VAT->getSizeExpr());
+      toParent();
     }
-    else if (const ReferenceType *RT = dyn_cast<ReferenceType>(pType)) {
-      addTypeRecursively(RT->getPointeeType());
-    }
-    else if (const TypedefType *TT = dyn_cast<TypedefType>(pType)) {
-      addTypeRecursively(TT->getDecl()->getUnderlyingType());
-      addContextsRecursively(TT->getDecl()->getDeclContext());
-    }
-    else if (const QualifiedNameType *QT = dyn_cast<QualifiedNameType>(pType)) {
-      addTypeRecursively(QT->getNamedType());
-      // FIXME: what to do with NestedNameSpecifier or shall this type be transparent?
-    }
-    else if (const ArrayType *AT = dyn_cast<ArrayType>(pType)) {
-      addTypeRecursively(AT->getElementType());
-      // FIXME: doesn't work in the immediate streaming approach
-      /*if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(AT)) 
-      {
-        addSubNode("VariableArraySizeExpression");
-        PrintStmt(VAT->getSizeExpr());
-        toParent();
-      }*/
-    }
+*/
   }
 }
 
 //--------------------------------------------------------- 
-void DocumentXML::addContextAttribute(const DeclContext *DC, tContextUsage usage)
+void DocumentXML::addPtrAttribute(const char* pName, const DeclContext* DC)
 {
   addContextsRecursively(DC);
-  const char* pAttributeTags[2] = { "context", "id" };
-  addAttribute(pAttributeTags[usage], getPrefixedId(Contexts[DC], ID_NORMAL));
+  addAttribute(pName, getPrefixedId(Contexts[DC], ID_NORMAL));
 }
 
 //--------------------------------------------------------- 
+void DocumentXML::addPtrAttribute(const char* pAttributeName, const NamedDecl* D)
+{
+  if (const DeclContext* DC = dyn_cast<DeclContext>(D))
+  {
+    addContextsRecursively(DC);
+    addAttribute(pAttributeName, getPrefixedId(Contexts[DC], ID_NORMAL));
+  }
+  else
+  {
+    addToMap(Decls, D);
+    addAttribute(pAttributeName, getPrefixedId(Decls[D], ID_NORMAL));
+  }
+}
+
+//--------------------------------------------------------- 
+void DocumentXML::addPtrAttribute(const char* pName, const NamespaceDecl* D)
+{
+  addPtrAttribute(pName, static_cast<const DeclContext*>(D));
+}
+
+//--------------------------------------------------------- 
 void DocumentXML::addContextsRecursively(const DeclContext *DC)
 {
   if (DC != 0 && addToMap(Contexts, DC))
@@ -372,7 +297,16 @@
   addAttribute("file", getPrefixedId(SourceFiles[fileName], ID_FILE));
 }
 
+
 //--------------------------------------------------------- 
+void DocumentXML::addPtrAttribute(const char* pName, const LabelStmt* L)
+{
+  addToMap(Labels, L, ID_LABEL);
+  addAttribute(pName, getPrefixedId(Labels[L], ID_LABEL));
+}
+
+
+//--------------------------------------------------------- 
 PresumedLoc DocumentXML::addLocation(const SourceLocation& Loc)
 {
   SourceManager& SM = Ctx->getSourceManager();
@@ -417,159 +351,9 @@
 }
 
 //--------------------------------------------------------- 
-void DocumentXML::PrintFunctionDecl(FunctionDecl *FD) 
-{
-  switch (FD->getStorageClass()) {
-  default: assert(0 && "Unknown storage class");
-  case FunctionDecl::None: break;
-  case FunctionDecl::Extern: addAttribute("storage_class", "extern"); break;
-  case FunctionDecl::Static: addAttribute("storage_class", "static"); break;
-  case FunctionDecl::PrivateExtern: addAttribute("storage_class", "__private_extern__"); break;
-  }
-
-  if (FD->isInline())
-    addAttribute("inline", "1");
-  
-  const FunctionType *AFT = FD->getType()->getAsFunctionType();
-  addTypeAttribute(AFT->getResultType());
-  addBasicTypeRecursively(AFT);  
-
-  if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT)) {
-    addAttribute("num_args", FD->getNumParams());
-    for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) {
-      addSubNode("Argument");
-      ParmVarDecl *argDecl = FD->getParamDecl(i);
-      addAttribute("name", argDecl->getNameAsString());
-      addTypeAttribute(FT->getArgType(i));
-      addDeclIdAttribute(argDecl);
-      if (argDecl->getDefaultArg())
-      {
-        addAttribute("default_arg", "1");
-        PrintStmt(argDecl->getDefaultArg());
-      }
-      toParent();
-    }
-    
-    if (FT->isVariadic()) {
-      addSubNode("Ellipsis").toParent();
-    }
-  } else {
-    assert(isa<FunctionNoProtoType>(AFT));
-  }
-}
-
-//--------------------------------------------------------- 
-void DocumentXML::addRefAttribute(const NamedDecl* D)
-{
-  // FIXME: in case of CXX inline member functions referring to a member defined 
-  // after the function it needs to be tested, if the ids are already there
-  // (should work, but I couldn't test it)
-  if (const DeclContext* DC = dyn_cast<DeclContext>(D))
-  {
-    addAttribute("ref", getPrefixedId(Contexts[DC], ID_NORMAL));
-  }
-  else
-  {
-    addAttribute("ref", getPrefixedId(Decls[D], ID_NORMAL));
-  }
-}
-
-//--------------------------------------------------------- 
-void DocumentXML::addDeclIdAttribute(const NamedDecl* D)
-{
-  addToMap(Decls, D);
-  addAttribute("id", getPrefixedId(Decls[D], ID_NORMAL));
-}
-
-//--------------------------------------------------------- 
 void DocumentXML::PrintDecl(Decl *D)
 {
-  addSubNode(D->getDeclKindName());
-  addContextAttribute(D->getDeclContext());
-  addLocation(D->getLocation());
-  if (DeclContext* DC = dyn_cast<DeclContext>(D))
-  {
-    addContextAttribute(DC, CONTEXT_AS_ID);
-  }
-
-  if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
-    addAttribute("name", ND->getNameAsString());
-
-    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-      PrintFunctionDecl(FD);
-      if (Stmt *Body = FD->getBody(*Ctx)) {
-        addSubNode("Body");
-        PrintStmt(Body);
-        toParent();
-      }
-    } else if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
-      addBasicTypeRecursively(RD->getTypeForDecl());
-      addAttribute("type", getPrefixedId(BasicTypes[RD->getTypeForDecl()], ID_NORMAL));
-      if (!RD->isDefinition())
-      {
-        addAttribute("forward", "1");
-      }
-
-      for (RecordDecl::field_iterator i = RD->field_begin(*Ctx), e = RD->field_end(*Ctx); i != e; ++i)
-      {
-        PrintDecl(*i);
-      }
-    } else if (EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
-      const QualType& enumType = ED->getIntegerType();
-      if (!enumType.isNull())
-      {
-        addTypeAttribute(enumType);
-        for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(*Ctx), e = ED->enumerator_end(*Ctx); i != e; ++i)
-        {
-          PrintDecl(*i);
-        }
-      }
-    } else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) {
-      addTypeAttribute(ECD->getType());
-      addAttribute("value", ECD->getInitVal().toString(10, true));
-      if (ECD->getInitExpr()) 
-      {
-        PrintStmt(ECD->getInitExpr());
-      }
-    } else if (FieldDecl *FdD = dyn_cast<FieldDecl>(D)) {
-      addTypeAttribute(FdD->getType());
-      addDeclIdAttribute(ND);
-      if (FdD->isMutable())
-        addAttribute("mutable", "1");
-      if (FdD->isBitField())
-      {
-        addAttribute("bitfield", "1");
-        PrintStmt(FdD->getBitWidth());
-      }
-    } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
-      addTypeIdAttribute(Ctx->getTypedefType(TD).getTypePtr());
-      addTypeAttribute(TD->getUnderlyingType());
-    } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
-      addTypeAttribute(VD->getType());
-      addDeclIdAttribute(ND);
-
-      VarDecl *V = dyn_cast<VarDecl>(VD);
-      if (V && V->getStorageClass() != VarDecl::None)
-      {
-        addAttribute("storage_class", VarDecl::getStorageClassSpecifierString(V->getStorageClass()));
-      }
-      
-      if (V && V->getInit()) 
-      {
-        PrintStmt(V->getInit());
-      }
-    }
-  } else if (LinkageSpecDecl* LSD = dyn_cast<LinkageSpecDecl>(D)) {
-    switch (LSD->getLanguage())
-    {
-      case LinkageSpecDecl::lang_c:    addAttribute("lang", "C");  break;
-      case LinkageSpecDecl::lang_cxx:  addAttribute("lang", "CXX");  break;
-      default:                         assert(0 && "Unexpected lang id");
-    }
-  } else {
-    assert(0 && "Unexpected decl");
-  }
-  toParent();
+  writeDeclToXML(D);
 }
 
 //--------------------------------------------------------- 
Index: lib/Frontend/StmtXML.cpp
===================================================================
--- lib/Frontend/StmtXML.cpp	(revision 72467)
+++ lib/Frontend/StmtXML.cpp	(working copy)
@@ -28,9 +28,32 @@
   class VISIBILITY_HIDDEN StmtXML : public StmtVisitor<StmtXML> {
     DocumentXML&  Doc;
 
-    static const char *getOpcodeStr(UnaryOperator::Opcode Op);
-    static const char *getOpcodeStr(BinaryOperator::Opcode Op);
+    //static const char *getOpcodeStr(UnaryOperator::Opcode Op);
+    //static const char *getOpcodeStr(BinaryOperator::Opcode Op);
 
+
+  void addSpecialAttribute(const char* pName, StringLiteral* Str)
+  {
+    Doc.addAttribute(pName, Doc.escapeString(Str->getStrData(), Str->getByteLength()));
+  }
+
+  void addSpecialAttribute(const char* pName, SizeOfAlignOfExpr* S)
+  {
+    if (S->isArgumentType())
+    {
+      Doc.addAttribute(pName, S->getArgumentType());
+    }
+  }
+
+  void addSpecialAttribute(const char* pName, CXXTypeidExpr* S)
+  {
+    if (S->isTypeOperand())
+    {
+      Doc.addAttribute(pName, S->getTypeOperand());
+    }
+  }
+
+
   public:
     StmtXML(DocumentXML& doc)
       : Doc(doc) {
@@ -39,12 +62,21 @@
     void DumpSubTree(Stmt *S) {
       if (S) 
       {
-        Doc.addSubNode(S->getStmtClassName());
-        Doc.addLocationRange(S->getSourceRange());
-        if (DeclStmt* DS = dyn_cast<DeclStmt>(S)) {
-          VisitDeclStmt(DS);
-        } else {        
-          Visit(S);
+        Visit(S);
+        if (DeclStmt* DS = dyn_cast<DeclStmt>(S)) 
+        {
+          for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
+               DI != DE; ++DI) 
+          {
+            Doc.PrintDecl(*DI);
+          }
+        } 
+        else 
+        {    
+          if (CXXConditionDeclExpr* CCDE = dyn_cast<CXXConditionDeclExpr>(S))
+          {
+            Doc.PrintDecl(CCDE->getVarDecl());
+          }
           for (Stmt::child_iterator i = S->child_begin(), e = S->child_end(); i != e; ++i)
           {
             DumpSubTree(*i);
@@ -56,17 +88,46 @@
       }
     }
 
-    void DumpTypeExpr(const QualType& T)
-    {
-      Doc.addSubNode("TypeExpr");
-      Doc.addTypeAttribute(T);
-      Doc.toParent();
-    }
 
-    void DumpExpr(const Expr *Node) {
-      Doc.addTypeAttribute(Node->getType());
-    }
+#define NODE_XML( CLASS, NAME )          \
+  void Visit##CLASS(CLASS* S)            \
+  {                                      \
+    typedef CLASS tStmtType;             \
+    Doc.addSubNode(NAME);         
 
+#define ATTRIBUTE_XML( FN, NAME )         Doc.addAttribute(NAME, S->FN); 
+#define TYPE_ATTRIBUTE_XML( FN )          ATTRIBUTE_XML(FN, "type")
+#define ATTRIBUTE_OPT_XML( FN, NAME )     Doc.addAttributeOptional(NAME, S->FN); 
+#define ATTRIBUTE_SPECIAL_XML( FN, NAME ) addSpecialAttribute(NAME, S); 
+#define ATTRIBUTE_FILE_LOCATION_XML       Doc.addLocationRange(S->getSourceRange());
+
+
+#define ATTRIBUTE_ENUM_XML( FN, NAME )  \
+  {                                     \
+    const char* pAttributeName = NAME;  \
+    const bool optional = false;        \
+    switch (S->FN) {                    \
+      default: assert(0 && "unknown enum value"); 
+
+#define ATTRIBUTE_ENUM_OPT_XML( FN, NAME )  \
+  {                                         \
+    const char* pAttributeName = NAME;      \
+    const bool optional = true;             \
+    switch (S->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                    }
+
+#define ID_ATTRIBUTE_XML                Doc.addAttribute("id", S);
+#define SUB_NODE_XML( CLASS )
+#define SUB_NODE_SEQUENCE_XML( CLASS )
+#define SUB_NODE_OPT_XML( CLASS )
+
+#include "clang/Frontend/StmtXML.def"
+
+#if (0)
     // Stmts.
     void VisitStmt(Stmt *Node);
     void VisitDeclStmt(DeclStmt *Node);
@@ -105,13 +166,14 @@
     void VisitObjCKVCRefExpr(ObjCKVCRefExpr *Node);
     void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
     void VisitObjCSuperExpr(ObjCSuperExpr *Node);
+#endif
   };
 }
 
 //===----------------------------------------------------------------------===//
 //  Stmt printing methods.
 //===----------------------------------------------------------------------===//
-
+#if (0)
 void StmtXML::VisitStmt(Stmt *Node) 
 {
   // nothing special to do
@@ -396,7 +458,7 @@
   if (Node->isFreeIvar())
     Doc.addAttribute("isFreeIvar", "1");
 }
-
+#endif
 //===----------------------------------------------------------------------===//
 // Stmt method implementations
 //===----------------------------------------------------------------------===//
Index: lib/Frontend/TypeXML.cpp
===================================================================
--- lib/Frontend/TypeXML.cpp	(revision 0)
+++ lib/Frontend/TypeXML.cpp	(revision 0)
@@ -0,0 +1,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
+
