[llvm-commits] [hlvm] r38066 - in /hlvm/trunk: hlvm/AST/AST.cpp hlvm/AST/AST.h hlvm/AST/Documentation.cpp hlvm/AST/Documentation.h hlvm/AST/Node.cpp hlvm/AST/Node.h hlvm/Reader/XML/HLVM.rng hlvm/Reader/XML/XMLReader.cpp hlvm/Writer/XML/XMLWriter.cpp test/xml2xml/doc.hlx

Reid Spencer reid at x10sys.com
Sat Jul 7 16:59:30 PDT 2007


Author: reid
Date: Sat Jul  7 18:59:30 2007
New Revision: 38066

URL: http://llvm.org/viewvc/llvm-project?rev=38066&view=rev
Log:
Add support for Documentation nodes that can appear nearly anywhere in the tree.
This approach supports automated generation of documentation from the AST only.
The documentation node is intended to contain XHTML text, but it can be anything
and the only requirement is that its formatting match that of the processor that
will produce the framework out. HLVM will provide an XHTML based documentation
generator. 

Added:
    hlvm/trunk/hlvm/AST/Documentation.cpp
    hlvm/trunk/hlvm/AST/Documentation.h
    hlvm/trunk/test/xml2xml/doc.hlx
Modified:
    hlvm/trunk/hlvm/AST/AST.cpp
    hlvm/trunk/hlvm/AST/AST.h
    hlvm/trunk/hlvm/AST/Node.cpp
    hlvm/trunk/hlvm/AST/Node.h
    hlvm/trunk/hlvm/Reader/XML/HLVM.rng
    hlvm/trunk/hlvm/Reader/XML/XMLReader.cpp
    hlvm/trunk/hlvm/Writer/XML/XMLWriter.cpp

Modified: hlvm/trunk/hlvm/AST/AST.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/AST.cpp?rev=38066&r1=38065&r2=38066&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/AST.cpp (original)
+++ hlvm/trunk/hlvm/AST/AST.cpp Sat Jul  7 18:59:30 2007
@@ -29,6 +29,7 @@
 
 #include <hlvm/AST/AST.h>
 #include <hlvm/AST/Bundle.h>
+#include <hlvm/AST/Documentation.h>
 #include <hlvm/AST/ContainerType.h>
 #include <hlvm/AST/Function.h>
 #include <hlvm/AST/Import.h>
@@ -342,4 +343,12 @@
   return new OpaqueType(id);
 }
 
+Documentation* 
+AST::new_Documentation(const Locator& loc)
+{
+  Documentation* result = new Documentation();
+  result->setLocator(loc);
+  return result;
+}
+
 }}

Modified: hlvm/trunk/hlvm/AST/AST.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/AST.h?rev=38066&r1=38065&r2=38066&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/AST.h (original)
+++ hlvm/trunk/hlvm/AST/AST.h Sat Jul  7 18:59:30 2007
@@ -42,6 +42,7 @@
 namespace AST
 {
   class Bundle;   
+  class Documentation;
   class Function; 
   class Import;
   class Locator; 
@@ -171,35 +172,38 @@
       );
       OpaqueType* new_OpaqueType(const std::string& id);
       RealType* new_f128(const Locator& l, const std::string& id)
-      { return new_RealType(l,id,112,15); }
+        { return new_RealType(l,id,112,15); }
       RealType* new_f80(const Locator& l, const std::string& id)
-      { return new_RealType(l,id,64,15); }
+        { return new_RealType(l,id,64,15); }
       RealType* new_f64(const Locator& l, const std::string& id)
-      { return new_RealType(l,id,52,11); }
+        { return new_RealType(l,id,52,11); }
       RealType* new_f43(const Locator& l, const std::string& id)
-      { return new_RealType(l,id,32,11); }
+        { return new_RealType(l,id,32,11); }
       RealType* new_f32(const Locator& l, const std::string& id)
-      { return new_RealType(l,id,23,8); }
+        { return new_RealType(l,id,23,8); }
       IntegerType* new_s128(const Locator& l, const std::string& id)
-      { return new_IntegerType(l,id,128,true); }
+        { return new_IntegerType(l,id,128,true); }
       IntegerType* new_s64(const Locator& l, const std::string& id)
-      { return new_IntegerType(l,id,64,true); }
+        { return new_IntegerType(l,id,64,true); }
       IntegerType* new_s32(const Locator& l, const std::string& id)
-      { return new_IntegerType(l,id,32,true); }
+        { return new_IntegerType(l,id,32,true); }
       IntegerType* new_s16(const Locator& l, const std::string& id)
-      { return new_IntegerType(l,id,16,true); }
+        { return new_IntegerType(l,id,16,true); }
       IntegerType* new_s8(const Locator& l, const std::string& id)
-      { return new_IntegerType(l,id,8,true); }
+        { return new_IntegerType(l,id,8,true); }
       IntegerType* new_u128(const Locator& l, const std::string& id)
-      { return new_IntegerType(l,id,128,false); }
+        { return new_IntegerType(l,id,128,false); }
       IntegerType* new_u64(const Locator& l, const std::string& id)
-      { return new_IntegerType(l,id,64,false); }
+        { return new_IntegerType(l,id,64,false); }
       IntegerType* new_u32(const Locator& l, const std::string& id)
-      { return new_IntegerType(l,id,32,false); }
+        { return new_IntegerType(l,id,32,false); }
       IntegerType* new_u16(const Locator& l, const std::string& id)
-      { return new_IntegerType(l,id,16,false); }
+        { return new_IntegerType(l,id,16,false); }
       IntegerType* new_u8(const Locator& l, const std::string& id)
-      { return new_IntegerType(l,id,8,false); }
+        { return new_IntegerType(l,id,8,false); }
+
+      Documentation* new_Documentation(const Locator& loc);
+
     /// @}
     /// @name Data
     /// @{

Added: hlvm/trunk/hlvm/AST/Documentation.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Documentation.cpp?rev=38066&view=auto

==============================================================================
--- hlvm/trunk/hlvm/AST/Documentation.cpp (added)
+++ hlvm/trunk/hlvm/AST/Documentation.cpp Sat Jul  7 18:59:30 2007
@@ -0,0 +1,38 @@
+//===-- AST Documentation Classes -------------------------------*- C++ -*-===//
+//
+//                      High Level Virtual Machine (HLVM)
+//
+// Copyright (C) 2006 Reid Spencer. All Rights Reserved.
+//
+// This software is free software; you can redistribute it and/or modify it 
+// under the terms of the GNU Lesser General Public License as published by 
+// the Free Software Foundation; either version 2.1 of the License, or (at 
+// your option) any later version.
+//
+// This software is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for 
+// more details.
+//
+// You should have received a copy of the GNU Lesser General Public License 
+// along with this library in the file named LICENSE.txt; if not, write to the 
+// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+// MA 02110-1301 USA
+//
+//===----------------------------------------------------------------------===//
+/// @file hlvm/AST/Documentation.cpp
+/// @author Reid Spencer <rspencer at reidspencer.org> (original author)
+/// @date 2006/05/19
+/// @since 0.1.0
+/// @brief Implements the functions of class hlvm::AST::Documentation.
+//===----------------------------------------------------------------------===//
+
+#include <hlvm/AST/Documentation.h>
+
+namespace hlvm { namespace AST {
+
+Documentation::~Documentation()
+{
+}
+
+}}

Added: hlvm/trunk/hlvm/AST/Documentation.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Documentation.h?rev=38066&view=auto

==============================================================================
--- hlvm/trunk/hlvm/AST/Documentation.h (added)
+++ hlvm/trunk/hlvm/AST/Documentation.h Sat Jul  7 18:59:30 2007
@@ -0,0 +1,83 @@
+//===-- AST Documentation Classes -------------------------------*- C++ -*-===//
+//
+//                      High Level Virtual Machine (HLVM)
+//
+// Copyright (C) 2006 Reid Spencer. All Rights Reserved.
+//
+// This software is free software; you can redistribute it and/or modify it 
+// under the terms of the GNU Lesser General Public License as published by 
+// the Free Software Foundation; either version 2.1 of the License, or (at 
+// your option) any later version.
+//
+// This software is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for 
+// more details.
+//
+// You should have received a copy of the GNU Lesser General Public License 
+// along with this library in the file named LICENSE.txt; if not, write to the 
+// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+// MA 02110-1301 USA
+//
+//===----------------------------------------------------------------------===//
+/// @file hlvm/AST/Documentation.h
+/// @author Reid Spencer <reid at hlvm.org> (original author)
+/// @date 2006/05/19
+/// @since 0.1.0
+/// @brief Declares the class hlvm::AST::Documentation
+//===----------------------------------------------------------------------===//
+
+#ifndef HLVM_AST_DOCUMENTATION_H
+#define HLVM_AST_DOCUMENTATION_H
+
+#include <hlvm/AST/Node.h>
+
+namespace hlvm { namespace AST {
+
+  /// The HLVM AST permits documentation (not just comments) to be included into
+  /// the nodes of the AST. Each such block of documentation is represented by
+  /// a Documentation node, implemented by this class. The content of a 
+  /// documentation node is simply a block of text. The intended use is that
+  /// the text contain XHTML markup. In this way, an automated documentation
+  /// facility can translate the AST into XHTML documentation with perfect
+  /// precision. Since the documentation node can be associated with any kind
+  /// of node, this affords a complete system for documenting HLVM programs 
+  /// with XHTML markup.
+  /// @brief HLVM AST Function Node
+  class Documentation : public Node
+  {
+    /// @name Constructors
+    /// @{
+    protected:
+      Documentation() : Node(DocumentationID) {}
+
+    public:
+      virtual ~Documentation();
+
+    /// @}
+    /// @name Accessors
+    /// @{
+    public:
+      const std::string& getDoc() const { return doc; }
+      static inline bool classof(const Documentation*) { return true; }
+      static inline bool classof(const Node* N) 
+      { return N->is(DocumentationID); }
+
+    /// @}
+    /// @name Mutators
+    /// @{
+    public:
+      void setDoc(const std::string& d) { doc = d; }
+      void addDoc(const std::string& d) { doc += d; }
+
+    /// @}
+    /// @name Data
+    /// @{
+    protected:
+      std::string doc;
+    /// @}
+    friend class AST;
+  };
+} // AST
+} // hlvm
+#endif

Modified: hlvm/trunk/hlvm/AST/Node.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Node.cpp?rev=38066&r1=38065&r2=38066&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Node.cpp (original)
+++ hlvm/trunk/hlvm/AST/Node.cpp Sat Jul  7 18:59:30 2007
@@ -35,10 +35,6 @@
 {
 }
 
-NamedNode::~NamedNode()
-{
-}
-
 bool 
 Node::isNamedNode() const
 {
@@ -85,4 +81,12 @@
 }
 #endif
 
+Documentable::~Documentable()
+{
+}
+
+NamedNode::~NamedNode()
+{
+}
+
 }}

Modified: hlvm/trunk/hlvm/AST/Node.h
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/AST/Node.h?rev=38066&r1=38065&r2=38066&view=diff

==============================================================================
--- hlvm/trunk/hlvm/AST/Node.h (original)
+++ hlvm/trunk/hlvm/AST/Node.h Sat Jul  7 18:59:30 2007
@@ -37,6 +37,8 @@
 namespace hlvm {
 namespace AST {
 
+  class Documentation;
+
   /// This enumeration is used to identify a specific type. Its organization is
   /// very specific and dependent on the class hierarchy. In order to use these
   /// values as ranges for class identification (classof methods), we need to 
@@ -179,6 +181,9 @@
     VectorOpID,         ///< Constant Vector Value
     StructureOpID,      ///< Constant Structure Value
 
+    // Miscellaneous Nodes
+    DocumentationID,    ///< XHTML Documentation Node
+
     // Enumeration Ranges and Limits
     NumNodeIDs,         ///< The number of node identifiers in the enum
     FirstPrimitiveTypeID = VoidTypeID, ///< First Primitive Type
@@ -233,9 +238,12 @@
         return id >= FirstOperatorID && id <= LastOperatorID;
       }
 
-      /// Determine if the node is a ParentNode
+      /// Determine if the node is a NamedNode
       bool isNamedNode() const ; 
 
+      /// Determine if the node is a Documentable Node
+      bool isDocumentable() const;
+
       /// Determine if the node is a LinkageItem
       bool isLinkageItem() const;
 
@@ -287,11 +295,46 @@
     friend class AST;
   };
 
-  class NamedNode : public Node {
+  class Documentable : public Node
+  {
+    /// @name Constructors
+    /// @{
+    protected:
+      Documentable(NodeIDs id) : Node(id), doc(0) {}
+    public:
+      virtual ~Documentable();
+
+    /// @}
+    /// @name Accessors
+    /// @{
+    public:
+      /// Get the name of the node
+      inline Documentation* getDoc() { return doc; }
+
+      static inline bool classof(const Documentable*) { return true; }
+      static inline bool classof(const Node* N) { return N->isDocumentable(); }
+
+    /// @}
+    /// @name Mutators
+    /// @{
+    public:
+      void setDoc(Documentation* d) { doc = d; }
+
+    /// @}
+    /// @name Data
+    /// @{
+    protected:
+      Documentation* doc;///< All named nodes can have documentation
+    /// @}
+    friend class AST;
+  };
+
+  class NamedNode : public Documentable 
+  {
     /// @name Constructors
     /// @{
     protected:
-      NamedNode(NodeIDs id) : Node(id), name() {}
+      NamedNode(NodeIDs id) : Documentable(id), name() {}
     public:
       virtual ~NamedNode();
 
@@ -316,6 +359,7 @@
     /// @{
     protected:
       std::string name;  ///< The name of this node.
+      Documentation* doc;///< All named nodes can have documentation
     /// @}
     friend class AST;
   };

Modified: hlvm/trunk/hlvm/Reader/XML/HLVM.rng
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Reader/XML/HLVM.rng?rev=38066&r1=38065&r2=38066&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Reader/XML/HLVM.rng (original)
+++ hlvm/trunk/hlvm/Reader/XML/HLVM.rng Sat Jul  7 18:59:30 2007
@@ -118,27 +118,27 @@
   <!-- PATTERNS THAT DEFINE name AND type ATTRIBUTES -->
 
   <define name="Named_Element.pat">
-    <ref name="Documentation.pat"/>
     <attribute name="name">
       <ref name="Identifier.type"/>
     </attribute>
+    <ref name="Documentation.pat"/>
   </define>
 
   <define name="Typed_Element.pat">
-    <ref name="Documentation.pat"/>
     <attribute name="type">
       <ref name="Identifier.type"/>
     </attribute>
+    <ref name="Documentation.pat"/>
   </define>
 
   <define name="Named_Typed_Element.pat">
-    <ref name="Documentation.pat"/>
     <attribute name="name">
       <ref name="Identifier.type"/>
     </attribute>
     <attribute name="type">
       <ref name="Identifier.type"/>
     </attribute>
+    <ref name="Documentation.pat"/>
   </define>
 
   <!-- HLVM PATTERN -->
@@ -183,13 +183,13 @@
 
   <define name="import.elem">
     <element name="import">
-      <ref name="Documentation.pat"/>
       <attribute name="prefix">
         <ref name="Identifier.type"/>
       </attribute>
       <attribute name="pubid">
         <data type="anyURI"/>
       </attribute>
+      <ref name="Documentation.pat"/>
     </element>
   </define>
 
@@ -291,6 +291,7 @@
           <attribute name="id">
             <ref name="Unprefixed_Identifier.type"/>
           </attribute>
+          <ref name="Documentation.pat"/>
         </element>
       </oneOrMore>
     </element>

Modified: hlvm/trunk/hlvm/Reader/XML/XMLReader.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Reader/XML/XMLReader.cpp?rev=38066&r1=38065&r2=38066&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Reader/XML/XMLReader.cpp (original)
+++ hlvm/trunk/hlvm/Reader/XML/XMLReader.cpp Sat Jul  7 18:59:30 2007
@@ -34,6 +34,7 @@
 #include <hlvm/AST/AST.h>
 #include <hlvm/AST/Bundle.h>
 #include <hlvm/AST/ContainerType.h>
+#include <hlvm/AST/Documentation.h>
 #include <hlvm/AST/Function.h>
 #include <hlvm/AST/Import.h>
 #include <hlvm/AST/Variable.h>
@@ -85,19 +86,21 @@
   inline void handleParseError(xmlErrorPtr error);
   inline void handleValidationError(xmlErrorPtr error);
 
-  void parseTree();
-  AST::AliasType*parseAlias(xmlNodePtr& cur);
-  AST::Type*     parseArray(xmlNodePtr& cur);
-  AST::Type*     parseAtom(xmlNodePtr& cur);
-  AST::Bundle*   parseBundle(xmlNodePtr& cur);
-  AST::Type*     parseEnumeration(xmlNodePtr& cur);
-  AST::Function* parseFunction(xmlNodePtr& cur);
-  AST::Import*   parseImport(xmlNodePtr& cur);
-  AST::Type*     parsePointer(xmlNodePtr& cur);
-  AST::Type*     parseStructure(xmlNodePtr& cur);
-  AST::Type*     parseSignature(xmlNodePtr& cur);
-  AST::Variable* parseVariable(xmlNodePtr& cur);
-  AST::Type*     parseVector(xmlNodePtr& cur);
+  void                parseTree          ();
+  AST::AliasType*     parseAlias         (xmlNodePtr& cur);
+  AST::Type*          parseArray         (xmlNodePtr& cur);
+  AST::Type*          parseAtom          (xmlNodePtr& cur);
+  AST::Bundle*        parseBundle        (xmlNodePtr& cur);
+  AST::Documentation* parseDocumentation (xmlNodePtr& cur);
+  AST::Type*          parseEnumeration   (xmlNodePtr& cur);
+  AST::Function*      parseFunction      (xmlNodePtr& cur);
+  AST::Import*        parseImport        (xmlNodePtr& cur);
+  AST::Type*          parsePointer       (xmlNodePtr& cur);
+  AST::Type*          parseStructure     (xmlNodePtr& cur);
+  AST::Type*          parseSignature     (xmlNodePtr& cur);
+  AST::Variable*      parseVariable      (xmlNodePtr& cur);
+  AST::Type*          parseVector        (xmlNodePtr& cur);
+  inline xmlNodePtr   checkDoc(xmlNodePtr cur, AST::Documentable* node);
 private:
 };
 
@@ -205,14 +208,49 @@
   type = getAttribute(cur,"type");
 }
 
+AST::Documentation*
+XMLReaderImpl::parseDocumentation(xmlNodePtr& cur)
+{
+  // Documentation is always optional so don't error out if the
+  // node is not a TKN_doc
+  if (cur && skipBlanks(cur) && getToken(cur->name) == TKN_doc) {
+    AST::Locator loc(cur->line,0,&ast->getSystemID());
+    xmlBufferPtr buffer = xmlBufferCreate();
+    xmlNodeDump(buffer,doc,cur,0,0);
+    int length = xmlBufferLength(buffer);
+    std::string str(reinterpret_cast<const char*>(xmlBufferContent(buffer)));
+    str.erase(0,5); // Zap the <doc> at the start
+    str.erase(str.length()-6); // Zap the </doc> at the end
+    AST::Documentation* progDoc = ast->new_Documentation(loc);
+    progDoc->setDoc(str);
+    xmlBufferFree(buffer);
+    return progDoc;
+  }
+  // Just signal that there's no documentation in this node
+  return 0;
+}
+
+inline xmlNodePtr
+XMLReaderImpl::checkDoc(xmlNodePtr cur, AST::Documentable* node)
+{
+  xmlNodePtr child = cur->children;
+  AST::Documentation* theDoc = parseDocumentation(child);
+  if (theDoc) {
+    node->setDoc(theDoc);
+    return child->next;
+  }
+  return child;
+}
+
 AST::Function*
 XMLReaderImpl::parseFunction(xmlNodePtr& cur)
 {
-  assert(getToken(cur->name)==TKN_import);
+  assert(getToken(cur->name)==TKN_function);
   AST::Locator loc(cur->line,0,&ast->getSystemID());
   std::string name, type;
   getNameType(cur, name, type);
   AST::Function* func = ast->new_Function(loc,name);
+  checkDoc(cur,func);
   return func;
 }
 
@@ -223,6 +261,7 @@
   AST::Locator loc(cur->line,0,&ast->getSystemID());
   std::string pfx = getAttribute(cur,"prefix");
   AST::Import* imp = ast->new_Import(loc,pfx);
+  checkDoc(cur,imp);
   return imp;
 }
 
@@ -233,7 +272,9 @@
   AST::Locator loc(cur->line,0,&ast->getSystemID());
   std::string name = getAttribute(cur,"name");
   std::string type = getAttribute(cur,"renames");
-  return ast->new_AliasType(loc,name,ast->resolveType(type));
+  AST::AliasType* alias = ast->new_AliasType(loc,name,ast->resolveType(type));
+  checkDoc(cur,alias);
+  return alias;
 }
 
 AST::Type*     
@@ -242,8 +283,10 @@
   assert(getToken(cur->name)==TKN_atom);
   AST::Locator loc(cur->line,0,&ast->getSystemID());
   std::string name = getAttribute(cur,"name");
-
   xmlNodePtr child = cur->children;
+  AST::Documentation* theDoc = parseDocumentation(child);
+  child = (theDoc==0 ? child : child->next );
+  AST::Type* result = 0;
   if (child && skipBlanks(child) && child->type == XML_ELEMENT_NODE) {
     int tkn = getToken(child->name);
     switch (tkn) {
@@ -251,7 +294,6 @@
         const char* is = getAttribute(child,"is");
         if (!is)
           assert(!"intrinsic element requires 'is' attribute");
-        AST::Type* result = 0;
         int typeTkn = getToken(reinterpret_cast<const xmlChar*>(is));
         switch (typeTkn) {
           case TKN_any:  result=ast->new_AnyType(loc,name); break;
@@ -277,13 +319,14 @@
           default:
             assert(!"Invalid intrinsic kind");
         }
-        return result;
+        break;
       }
       case TKN_signed: {
         const char* bits = getAttribute(child,"bits");
         if (bits) {
           uint64_t numBits = recognize_nonNegativeInteger(bits);
-          return ast->new_IntegerType(loc,name,numBits,/*signed=*/true);
+          result = ast->new_IntegerType(loc,name,numBits,/*signed=*/true);
+          break;
         }
         assert(!"Missing 'bits' attribute");
         break;
@@ -292,7 +335,8 @@
         const char* bits = getAttribute(child,"bits");
         if (bits) {
           uint64_t numBits = recognize_nonNegativeInteger(bits);
-          return ast->new_IntegerType(loc,name,numBits,/*signed=*/false);
+          result = ast->new_IntegerType(loc,name,numBits,/*signed=*/false);
+          break;
         }
         assert(!"Missing 'bits' attribute");
         break;
@@ -303,7 +347,8 @@
         if (min && max) {
           int64_t minVal = recognize_Integer(min);
           int64_t maxVal = recognize_Integer(max);
-          return ast->new_RangeType(loc,name,minVal,maxVal);
+          result = ast->new_RangeType(loc,name,minVal,maxVal);
+          break;
         }
         assert(!"Missing 'min' or 'max' attribute");
         break;
@@ -314,14 +359,19 @@
         if (mantissa && exponent) {
           int32_t mantVal = recognize_nonNegativeInteger(mantissa);
           int32_t expoVal = recognize_nonNegativeInteger(exponent);
-          return ast->new_RealType(loc,name,mantVal,expoVal);
+          result = ast->new_RealType(loc,name,mantVal,expoVal);
         }
         break;
       }
       default:
-        assert(!"Invalid content for bundle");
+        assert(!"Invalid content for atom");
         break;
     }
+    if (result) {
+      if (theDoc)
+        result->setDoc(theDoc);
+      return result;
+    }
   }
   assert(!"Atom definition element expected");
 }
@@ -333,7 +383,7 @@
   AST::Locator loc(cur->line,0,&ast->getSystemID());
   std::string name = getAttribute(cur,"name");
   AST::EnumerationType* en = ast->new_EnumerationType(loc,name);
-  xmlNodePtr child = cur->children;
+  xmlNodePtr child = checkDoc(cur,en);
   while (child && skipBlanks(child) && child->type == XML_ELEMENT_NODE) {
     assert(getToken(child->name) == TKN_enumerator);
     std::string id = getAttribute(child,"id");
@@ -350,7 +400,10 @@
   AST::Locator loc(cur->line,0,&ast->getSystemID());
   std::string name = getAttribute(cur,"name");
   std::string type = getAttribute(cur,"to");
-  return ast->new_PointerType(loc,name,ast->resolveType(type));
+  AST::PointerType* result = 
+    ast->new_PointerType(loc,name,ast->resolveType(type));
+  checkDoc(cur,result);
+  return result;
 }
 
 AST::Type*     
@@ -361,8 +414,10 @@
   std::string name = getAttribute(cur,"name");
   std::string type = getAttribute(cur,"of");
   const char* len = getAttribute(cur,"length");
-  return ast->new_ArrayType(loc, name, ast->resolveType(type), 
-                            recognize_nonNegativeInteger(len));
+  AST::ArrayType* result = ast->new_ArrayType(
+    loc, name, ast->resolveType(type), recognize_nonNegativeInteger(len));
+  checkDoc(cur,result);
+  return result;
 }
 
 AST::Type*     
@@ -373,24 +428,28 @@
   std::string name = getAttribute(cur,"name");
   std::string type = getAttribute(cur,"of");
   const char* len  = getAttribute(cur,"length");
-  return ast->new_VectorType(loc,name,ast->resolveType(type),
-                             recognize_nonNegativeInteger(len));
+  AST::VectorType* result =
+    ast->new_VectorType(
+      loc,name,ast->resolveType(type), recognize_nonNegativeInteger(len));
+  checkDoc(cur,result);
+  return result;
 }
 
-AST::Type*     
+AST::Type*
 XMLReaderImpl::parseStructure(xmlNodePtr& cur)
 {
   assert(getToken(cur->name)==TKN_structure);
   AST::Locator loc(cur->line,0,&ast->getSystemID());
   std::string name = getAttribute(cur,"name");
   AST::StructureType* struc = ast->new_StructureType(loc,name);
-  xmlNodePtr child = cur->children;
+  xmlNodePtr child = checkDoc(cur,struc); 
   while (child && skipBlanks(child) && child->type == XML_ELEMENT_NODE) {
     assert(getToken(child->name) == TKN_field && "Structure only has fields");
     std::string name = getAttribute(child,"name");
     std::string type = getAttribute(child,"type");
-    AST::AliasType* nt = ast->new_AliasType(loc,name,ast->resolveType(type));
-    nt->setParent(struc);
+    AST::AliasType* alias = ast->new_AliasType(loc,name,ast->resolveType(type));
+    alias->setParent(struc);
+    checkDoc(child,alias);
     child = child->next;
   }
   return struc;
@@ -408,13 +467,14 @@
     ast->new_SignatureType(loc,name,ast->resolveType(result));
   if (varargs)
     sig->setIsVarArgs(recognize_boolean(varargs));
-  xmlNodePtr child = cur->children;
+  xmlNodePtr child = checkDoc(cur,sig); 
   while (child && skipBlanks(child) && child->type == XML_ELEMENT_NODE) {
     assert(getToken(child->name) == TKN_arg && "Signature only has args");
     std::string name = getAttribute(child,"name");
     std::string type = getAttribute(child,"type");
-    AST::AliasType* nt = ast->new_AliasType(loc,name,ast->resolveType(type));
-    nt->setParent(sig);
+    AST::AliasType* alias = ast->new_AliasType(loc,name,ast->resolveType(type));
+    alias->setParent(sig);
+    checkDoc(child,alias);
     child = child->next;
   }
   return sig;
@@ -429,6 +489,7 @@
   getNameType(cur, name, type);
   AST::Variable* var = ast->new_Variable(loc,name);
   var->setType(ast->resolveType(type));
+  checkDoc(cur,var);
   return var;
 }
 
@@ -445,6 +506,11 @@
     int tkn = getToken(child->name);
     AST::Node* n = 0;
     switch (tkn) {
+      case TKN_doc      :
+        AST::Documentation* theDoc = parseDocumentation(child);
+        if (theDoc)
+          bundle->setDoc(theDoc);
+        break;
       case TKN_import   : n = parseImport(child); break;
       case TKN_bundle   : n = parseBundle(child); break;
       case TKN_function : n = parseFunction(child); break;

Modified: hlvm/trunk/hlvm/Writer/XML/XMLWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/hlvm/Writer/XML/XMLWriter.cpp?rev=38066&r1=38065&r2=38066&view=diff

==============================================================================
--- hlvm/trunk/hlvm/Writer/XML/XMLWriter.cpp (original)
+++ hlvm/trunk/hlvm/Writer/XML/XMLWriter.cpp Sat Jul  7 18:59:30 2007
@@ -30,6 +30,7 @@
 #include <hlvm/Writer/XML/XMLWriter.h>
 #include <hlvm/AST/AST.h>
 #include <hlvm/AST/Bundle.h>
+#include <hlvm/AST/Documentation.h>
 #include <hlvm/AST/Function.h>
 #include <hlvm/AST/Import.h>
 #include <hlvm/AST/ContainerType.h>
@@ -90,7 +91,9 @@
 
   inline void putHeader();
   inline void putFooter();
+  inline void putDoc(AST::Documentable* node);
   inline void put(AST::Bundle* b);
+  inline void put(AST::Documentation* b);
   inline void put(AST::Variable* v);
   inline void put(AST::Function* f);
   inline void put(AST::AliasType* t);
@@ -110,6 +113,14 @@
   inline void put(AST::SignatureType* t);
 };
 
+inline void
+XMLWriterImpl::putDoc(AST::Documentable* node)
+{
+  AST::Documentation* theDoc = node->getDoc();
+  if (theDoc) {
+    this->put(theDoc);
+  }
+}
 
 void
 XMLWriterImpl::putHeader() 
@@ -132,11 +143,22 @@
 }
 
 void 
+XMLWriterImpl::put(AST::Documentation* b)
+{
+  startElement("doc");
+  const std::string& data = b->getDoc();
+  xmlTextWriterWriteRawLen(writer,
+    reinterpret_cast<const xmlChar*>(data.c_str()),data.length());
+  endElement();
+}
+
+void 
 XMLWriterImpl::put(AST::AliasType* t)
 {
   startElement("alias");
   writeAttribute("name",t->getName());
   writeAttribute("renames",t->getType());
+  putDoc(t);
   endElement();
 }
 void 
@@ -144,6 +166,7 @@
 {
   startElement("atom");
   writeAttribute("name",t->getName());
+  putDoc(t);
   startElement("intrinsic");
   writeAttribute("is","any");
   endElement();
@@ -155,6 +178,7 @@
 {
   startElement("atom");
   writeAttribute("name",t->getName().c_str());
+  putDoc(t);
   startElement("intrinsic");
   writeAttribute("is","bool");
   endElement();
@@ -166,6 +190,7 @@
 {
   startElement("atom");
   writeAttribute("name",t->getName().c_str());
+  putDoc(t);
   startElement("intrinsic");
   writeAttribute("is","char");
   endElement();
@@ -177,6 +202,7 @@
 {
   startElement("atom");
   writeAttribute("name",t->getName().c_str());
+  putDoc(t);
   const char* primName = t->getPrimitiveName();
   if (primName) {
     startElement("intrinsic");
@@ -199,6 +225,7 @@
   writeAttribute("name",t->getName());
   writeAttribute("min",t->getMin());
   writeAttribute("max",t->getMax());
+  putDoc(t);
   endElement();
 }
 
@@ -207,6 +234,7 @@
 {
   startElement("enumeration");
   writeAttribute("name",t->getName());
+  putDoc(t);
   for (AST::EnumerationType::const_iterator I = t->begin(), E = t->end(); 
        I != E; ++I)
   {
@@ -222,6 +250,7 @@
 {
   startElement("atom");
   writeAttribute("name",t->getName().c_str());
+  putDoc(t);
   const char* primName = t->getPrimitiveName();
   if (primName) {
     startElement("intrinsic");
@@ -241,6 +270,7 @@
 {
   startElement("atom");
   writeAttribute("name",t->getName().c_str());
+  putDoc(t);
   startElement("intrinsic");
   writeAttribute("is","octet");
   endElement();
@@ -252,6 +282,7 @@
 {
   startElement("atom");
   writeAttribute("name",t->getName());
+  putDoc(t);
   startElement("intrinsic");
   writeAttribute("is","void");
   endElement();
@@ -264,6 +295,7 @@
   startElement("pointer");
   writeAttribute("name", t->getName());
   writeAttribute("to", t->getTargetType());
+  putDoc(t);
   endElement();
 }
 
@@ -274,6 +306,7 @@
   writeAttribute("name", t->getName());
   writeAttribute("of", t->getElementType());
   writeAttribute("length", t->getMaxSize());
+  putDoc(t);
   endElement();
 }
 
@@ -284,6 +317,7 @@
   writeAttribute("name", t->getName());
   writeAttribute("of", t->getElementType());
   writeAttribute("length", t->getSize());
+  putDoc(t);
   endElement();
 }
 
@@ -292,11 +326,13 @@
 {
   startElement("structure");
   writeAttribute("name",t->getName());
+  putDoc(t);
   for (AST::StructureType::iterator I = t->begin(), E = t->end(); I != E; ++I) {
     startElement("field");
-    AST::AliasType* nt = cast<AST::AliasType>(*I);
-    writeAttribute("name",nt->getName());
-    writeAttribute("type",nt->getType());
+    AST::AliasType* alias = cast<AST::AliasType>(*I);
+    writeAttribute("name",alias->getName());
+    writeAttribute("type",alias->getType());
+    putDoc(alias);
     endElement();
   }
   endElement();
@@ -309,11 +345,13 @@
   writeAttribute("name",t->getName());
   writeAttribute("result",t->getResultType());
   writeAttribute("varargs",t->isVarArgs() ? "true" : "false");
+  putDoc(t);
   for (AST::SignatureType::iterator I = t->begin(), E = t->end(); I != E; ++I) {
     startElement("arg");
-    AST::AliasType* nt = cast<AST::AliasType>(*I);
-    writeAttribute("name",nt->getName());
-    writeAttribute("type",nt->getType());
+    AST::AliasType* alias = cast<AST::AliasType>(*I);
+    writeAttribute("name",alias->getName());
+    writeAttribute("type",alias->getType());
+    putDoc(alias);
     endElement();
   }
   endElement();
@@ -325,6 +363,7 @@
   startElement("var");
   writeAttribute("name",v->getName().c_str());
   writeAttribute("type",v->getType()->getName().c_str());
+  putDoc(v);
   endElement();
 }
 
@@ -333,10 +372,12 @@
 {
   startElement("bundle");
   writeAttribute("pubid",b->getName().c_str());
+  putDoc(b);
   for (AST::Bundle::const_iterator I = b->begin(),E = b->end(); I != E; ++I)
   {
     switch ((*I)->getID()) 
     {
+      case AST::DocumentationID:    put(cast<AST::Documentation>(*I)); break;
       case AST::VariableID:         put(cast<AST::Variable>(*I)); break;
       case AST::FunctionID:         put(cast<AST::Function>(*I)); break;
       case AST::AliasTypeID:        put(cast<AST::AliasType>(*I)); break;

Added: hlvm/trunk/test/xml2xml/doc.hlx
URL: http://llvm.org/viewvc/llvm-project/hlvm/trunk/test/xml2xml/doc.hlx?rev=38066&view=auto

==============================================================================
--- hlvm/trunk/test/xml2xml/doc.hlx (added)
+++ hlvm/trunk/test/xml2xml/doc.hlx Sat Jul  7 18:59:30 2007
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<hlvm xmlns="http://hlvm.org/src/hlvm/Reader/XML/HLVM.rng">
+  <bundle pubid="bundle">
+    <doc><p>This is a documentation node for a bundle element</p></doc>
+    <atom name="someType">
+      <doc><p>Atom Doc</p></doc>
+      <intrinsic is="any"/>
+    </atom>
+    <alias name="anAlias" renames="someType">
+      <doc><p>Alias Doc</p></doc>
+    </alias>
+    <array name="anArray" of="someType" length="128">
+      <doc><p>Array Doc</p></doc>
+    </array>
+    <enumeration name="anEnumeration">
+      <doc>This is anEnumeration</doc>
+      <enumerator id="one"/>
+      <enumerator id="two"/>
+      <enumerator id="three"/>
+      <enumerator id="four"/>
+    </enumeration>
+    <atom name="1">
+      <doc>Any can hold anything. It provides the dynamic typing</doc>
+      <intrinsic is="any"/>
+    </atom>
+    <atom name="2">
+      <doc>Obviously this is a boolean</doc>
+      <intrinsic is="bool"/>
+    </atom>
+    <atom name="3">
+      <doc>UTF-16 character</doc>
+      <intrinsic is="char"/>
+    </atom>
+    <atom name="4">
+      <doc>IEEE Quad Floating Point (128 bits)</doc>
+      <intrinsic is="f128"/>
+    </atom>
+    <atom name="5">
+      <doc>IEEE Extended Double Floating Point (80 bits)</doc>
+      <intrinsic is="f80"/>
+    </atom>
+    <atom name="6">
+      <doc>IEEE Double Floating Point (64 bits)</doc>
+      <intrinsic is="f64"/>
+    </atom>
+    <atom name="7">
+      <doc>IEEE Extended Single Floating Point (43 bits)</doc>
+      <intrinsic is="f43"/>
+    </atom>
+    <atom name="8">
+      <doc>IEEE Single Floating Point (32 bits)</doc>
+      <intrinsic is="f32"/>
+    </atom>
+    <atom name="9">
+      <doc>Signed 128 bit integer</doc>
+      <intrinsic is="s128"/>
+    </atom>
+    <atom name="10">
+      <doc>Signed 64 bit integer</doc>
+      <intrinsic is="s64"/>
+    </atom>
+    <atom name="11">
+      <doc>Signed 32 bit integer</doc>
+      <intrinsic is="s32"/>
+    </atom>
+    <atom name="12">
+      <doc>Signed 16 bit integer</doc>
+      <intrinsic is="s16"/>
+    </atom>
+    <atom name="13">
+      <doc>Signed 8 bit integer</doc>
+      <intrinsic is="s8"/>
+    </atom>
+    <atom name="14">
+      <doc>An 8-bit non-numerical quantity</doc>
+      <intrinsic is="octet"/>
+    </atom>
+    <atom name="15">
+      <doc>Unsigned 128 bit integer</doc>
+      <intrinsic is="u128"/>
+    </atom>
+    <atom name="16">
+      <doc>Unsigned 64 bit integer</doc>
+      <intrinsic is="u64"/>
+    </atom>
+    <atom name="17">
+      <doc>Unsigned 32 bit integer</doc>
+      <intrinsic is="u32"/>
+    </atom>
+    <atom name="18">
+      <doc>Unsigned 16 bit integer</doc>
+      <intrinsic is="u16"/>
+    </atom>
+    <atom name="19">
+      <doc>Unsigned 8 bit integer</doc>
+      <intrinsic is="u8"/>
+    </atom>
+    <atom name="20">
+      <doc>The void type, zero size</doc>
+      <intrinsic is="void"/>
+    </atom>
+    <pointer name="aPointerType" to="someType">
+      <doc>A Pointer Type</doc>
+    </pointer>
+    <signature name="struct2" result="someType" varargs="true">
+      <doc>This is signature doc</doc>
+      <arg name="arg1" type="someType">
+        <doc>Doc for "arg1"</doc>
+      </arg>
+      <arg name="arg2" type="someType">
+        <doc><i>Doc for "arg2"</i></doc>
+      </arg>
+    </signature>
+    <structure name="struct2">
+      <doc>This is structure doc</doc>
+      <field name="field1" type="someType">
+        <doc><p><i><b>Field 1 Documentation</b></i></p></doc>
+      </field>
+      <field name="field2" type="someType">
+        <doc>Documentation for field 2</doc>
+      </field>
+    </structure>
+    <var name="var" type="int">
+      <doc><p>This is documentation for a <i>var</i>iable</p></doc>
+    </var>
+    <vector name="aVector" of="f32" length="128">
+      <doc>Vector doc</doc>
+    </vector>
+  </bundle>
+</hlvm>





More information about the llvm-commits mailing list