Improve XML output for C++ classes, from Olaf Krzikalla!


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97954 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Frontend/DeclXML.def b/include/clang/Frontend/DeclXML.def
index c750492..e839a8c 100644
--- a/include/clang/Frontend/DeclXML.def
+++ b/include/clang/Frontend/DeclXML.def
@@ -103,7 +103,7 @@
   //ATTRIBUTE_OPT_XML(isVariadic(), "variadic")       // in the type reference
   ATTRIBUTE_XML(getNumParams(), "num_args")
   SUB_NODE_SEQUENCE_XML(ParmVarDecl)
-  //SUB_NODE_OPT_XML("Body")
+  SUB_NODE_FN_BODY_XML
 END_NODE_XML
 
 NODE_XML(CXXMethodDecl, "CXXMethodDecl")
@@ -118,13 +118,9 @@
   ATTRIBUTE_OPT_XML(isVirtual(), "virtual")
   ATTRIBUTE_XML(getNumParams(), "num_args")
   SUB_NODE_SEQUENCE_XML(ParmVarDecl)
-  //SUB_NODE_OPT_XML("Body")
+  SUB_NODE_FN_BODY_XML
 END_NODE_XML
 
-//NODE_XML("Body")
-//  SUB_NODE_XML(Stmt)
-//END_NODE_XML
-
 NODE_XML(NamespaceDecl, "Namespace")
   ID_ATTRIBUTE_XML
   ATTRIBUTE_FILE_LOCATION_XML
@@ -156,6 +152,16 @@
   SUB_NODE_SEQUENCE_XML(FieldDecl)
 END_NODE_XML
 
+NODE_XML(CXXRecordDecl, "CXXRecord")
+  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
@@ -248,3 +254,4 @@
 #undef SUB_NODE_XML
 #undef SUB_NODE_SEQUENCE_XML
 #undef SUB_NODE_OPT_XML
+#undef SUB_NODE_FN_BODY_XML
diff --git a/lib/Frontend/DeclXML.cpp b/lib/Frontend/DeclXML.cpp
index d7470d9..8750b1e 100644
--- a/lib/Frontend/DeclXML.cpp
+++ b/lib/Frontend/DeclXML.cpp
@@ -29,6 +29,14 @@
     }
   }
 
+  void addFunctionBody(FunctionDecl* FD) {
+    if (FD->isThisDeclarationADefinition()) {
+      Doc.addSubNode("Body");
+      Doc.PrintStmt(FD->getBody());
+      Doc.toParent();
+    }
+  }
+
   void addSubNodes(RecordDecl* RD) {
     for (RecordDecl::field_iterator i = RD->field_begin(),
                                     e = RD->field_end(); i != e; ++i) {
@@ -37,6 +45,15 @@
     }
   }
 
+  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();
+    }
+  }
+
   void addSubNodes(EnumDecl* ED) {
     for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(),
                                        e = ED->enumerator_end(); i != e; ++i) {
@@ -115,6 +132,8 @@
 #define SUB_NODE_SEQUENCE_XML( CLASS )  addSubNodes(T);
 #define SUB_NODE_OPT_XML( CLASS )       addSubNodes(T);
 
+#define SUB_NODE_FN_BODY_XML            addFunctionBody(T);
+
 #include "clang/Frontend/DeclXML.def"
 };
 
@@ -122,13 +141,6 @@
 //---------------------------------------------------------
 void DocumentXML::writeDeclToXML(Decl *D) {
   DeclPrinter(*this).Visit(D);
-  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    if (Stmt *Body = FD->getBody()) {
-      addSubNode("Body");
-      PrintStmt(Body);
-      toParent();
-    }
-  }
   toParent();
 }