Improved -ast-print-xml for C++, from Sebastien Binet!


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103412 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/DeclXML.cpp b/lib/Frontend/DeclXML.cpp
index 8750b1e..3ae25f9 100644
--- a/lib/Frontend/DeclXML.cpp
+++ b/lib/Frontend/DeclXML.cpp
@@ -47,11 +47,38 @@
 
   void addSubNodes(CXXRecordDecl* RD) {
     addSubNodes(cast<RecordDecl>(RD));
-    for (CXXRecordDecl::method_iterator i = RD->method_begin(),
-                                        e = RD->method_end(); i != e; ++i) {
-      Visit(*i);
-      Doc.toParent();
+
+    if (RD->isDefinition()) {
+      Doc.addAttribute("num_bases", RD->getNumBases());
+
+      for (CXXRecordDecl::base_class_iterator 
+             base = RD->bases_begin(),
+             bend = RD->bases_end();
+           base != bend;
+           ++base) {
+        Doc.addSubNode("Base");
+        Doc.addAttribute("id", base->getType());
+        AccessSpecifier as = base->getAccessSpecifierAsWritten();
+        const char* as_name = "";
+        switch(as) {
+        case AS_none:      as_name = ""; break;
+        case AS_public:    as_name = "public"; break;
+        case AS_protected: as_name = "protected"; break;
+        case AS_private:   as_name = "private"; break;
+        }
+        Doc.addAttributeOptional("access", as_name);
+        Doc.addAttribute("is_virtual", base->isVirtual());
+        Doc.toParent();
+      }
+
+      for (CXXRecordDecl::method_iterator i = RD->method_begin(),
+             e = RD->method_end(); i != e; ++i) {
+        Visit(*i);
+        Doc.toParent();
+      }
+
     }
+
   }
 
   void addSubNodes(EnumDecl* ED) {
@@ -82,6 +109,18 @@
       Doc.PrintStmt(argDecl->getDefaultArg());
   }
 
+  void addSubNodes(NamespaceDecl* ns) {
+
+    for (DeclContext::decl_iterator 
+           d    = ns->decls_begin(), 
+           dend = ns->decls_end();
+         d != dend;
+         ++d) {
+      Visit(*d);
+      Doc.toParent();
+    }
+  }
+
   void addSpecialAttribute(const char* pName, EnumDecl* ED) {
     const QualType& enumType = ED->getIntegerType();
     if (!enumType.isNull())
diff --git a/lib/Frontend/DocumentXML.cpp b/lib/Frontend/DocumentXML.cpp
index 0263c30..894f230 100644
--- a/lib/Frontend/DocumentXML.cpp
+++ b/lib/Frontend/DocumentXML.cpp
@@ -199,6 +199,35 @@
 }
 
 //---------------------------------------------------------
+void DocumentXML::addPtrAttribute(const char* pAttributeName,
+                                  const NestedNameSpecifier* pNNS) {
+  switch (pNNS->getKind()) {
+  case NestedNameSpecifier::Identifier: {
+    IdentifierInfo *ii = pNNS->getAsIdentifier();
+    // FIXME how should we handle those ?
+    addPtrAttribute(pAttributeName, ii->getName().data());
+    break;
+  }
+  case NestedNameSpecifier::Namespace: {
+    addPtrAttribute(pAttributeName, pNNS->getAsNamespace());
+    break;
+  }
+  case NestedNameSpecifier::TypeSpec: {
+    addPtrAttribute(pAttributeName, pNNS->getAsType());
+    break;
+  }
+  case NestedNameSpecifier::TypeSpecWithTemplate: {
+    addPtrAttribute(pAttributeName, pNNS->getAsType());
+    break;
+  }
+  case NestedNameSpecifier::Global: {
+    addPtrAttribute(pAttributeName, "::");
+    break;
+  }
+  }
+}
+
+//---------------------------------------------------------
 void DocumentXML::addTypeRecursively(const QualType& pType)
 {
   if (addToMap(Types, pType))