]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
More like dwarf_output compiling.
authorRoland McGrath <roland@redhat.com>
Sat, 4 Jul 2009 10:44:01 +0000 (03:44 -0700)
committerRoland McGrath <roland@redhat.com>
Sat, 4 Jul 2009 10:44:01 +0000 (03:44 -0700)
libdw/c++/dwarf_edit
libdw/c++/dwarf_output
libdw/c++/output-values.cc
libdw/c++/values.cc

index 73eff273501369686967a461b6c6a85c8cf4bf9d..fbd59b3fd0a49637064d5d6592be2e02ca9d6483 100644 (file)
@@ -106,6 +106,7 @@ namespace elfutils
       friend class subr::create_container;
 
     public:
+      typedef dwarf_data::attributes_type<dwarf_edit> attributes_type;
 
       class children_type : public std::list<debug_info_entry>
       {
@@ -144,21 +145,6 @@ namespace elfutils
       typedef children_type::iterator pointer;
       typedef children_type::const_iterator const_pointer;
 
-      class attributes_type
-       : public dwarf_data::attributes_type<dwarf_edit>
-      {
-       friend class debug_info_entry;
-      private:
-       typedef dwarf_data::attributes_type<dwarf_edit> base_type;
-
-       inline attributes_type () {}
-
-       template<typename attrs, typename tracker>
-       inline attributes_type (const attrs &other, tracker &t)
-         : base_type (other, t)
-       {}
-      };
-
     protected:
       int _m_tag;
       attributes_type _m_attributes;
@@ -370,7 +356,7 @@ namespace elfutils
   template<>
   std::string to_string<dwarf_edit::attribute> (const dwarf_edit::attribute &);
   template<>
-  std::string to_string<dwarf_edit::attr_value> (const dwarf_edit::attr_value &);
+  std::string to_string<dwarf_edit::attr_value> (const dwarf_edit::attr_value&);
 };
 
 #endif // <elfutils/dwarf_edit>
index 4202fb16d8bd557facfc30af7e1df9a7292f8ba0..402a85139edc9220090ddf00e7f529f4f5591341 100644 (file)
@@ -356,11 +356,12 @@ namespace elfutils
 
     typedef dwarf_data::attr_value<dwarf_output, value_wrapper> attr_value;
 
-    class compile_units;
-
     class debug_info_entry
     {
+      friend class subr::create_container;
+
     public:
+      typedef dwarf_data::attributes_type<dwarf_output> attributes_type;
 
       class children_type : public std::list<debug_info_entry>
       {
@@ -368,45 +369,82 @@ namespace elfutils
       private:
         inline children_type () {}
 
-       template<typename input>
-       inline children_type (const input &other, dwarf_output_collector &c)
-         : std::list<debug_info_entry>
-           (collectify<input, children_type> (other.begin (), c),
-            collectify<input, children_type> (other.end (), c))
-       {}
+       template<typename input, typename tracker>
+       static inline void
+       equivalence (const iterator &out,
+                    const typename input::const_iterator &in, tracker &t)
+       {
+         t.equivalence (out, in);
+       }
+
+       template<typename input, typename tracker>
+       inline children_type (const input &other, tracker &t)
+       {
+         subr::create_container (this, other, t, equivalence<input, tracker>);
+       }
 
       public:
        typedef debug_info_entry value_type;
-      };
-
-      typedef children_type::const_iterator const_pointer;
-      typedef children_type::const_iterator pointer;
 
-      class attributes_type
-       : public dwarf_data::attributes_type<dwarf_output, value_wrapper>
-      {
-       friend class debug_info_entry;
-      private:
-       typedef dwarf_data::attributes_type<dwarf_output,
-                                           value_wrapper> base_type;
+       inline iterator add_entry (int tag, const iterator &pos)
+       {
+         return insert (pos, debug_info_entry (tag));
+       }
 
-       template<typename input>
-       inline attributes_type (const input &other, dwarf_output_collector &c)
-         : base_type (other, c)
-       {}
+       inline iterator add_entry (int tag)
+       {
+         return add_entry (tag, end ());
+       }
       };
 
-    private:
-      const int _m_tag;
+      typedef children_type::iterator pointer;
+      typedef children_type::const_iterator const_pointer;
+
+    protected:
+      int _m_tag;
       attributes_type _m_attributes;
       children_type _m_children;
 
+      // This is can only be used by the children_type constructor,
+      // which immediately calls set.
+      inline debug_info_entry ()
+       : _m_tag (-1), _m_attributes (), _m_children ()
+      {}
+
+      template<typename die_type, typename arg_type>
+      inline void set (const die_type &die, arg_type &arg)
+      {
+       try
+         {
+           _m_tag = die.tag ();
+           _m_attributes.swap (attributes_type (die.attributes (), arg));
+           _m_children.swap (children_type (die.children (), arg));
+         }
+       catch (...)
+         {
+           // Never leave a partially-formed DIE.
+           _m_tag = -1;
+           _m_attributes.clear ();
+           _m_children.clear ();
+           throw;
+         };
+      }
+
     public:
-      template<typename die_type>
-      debug_info_entry (const die_type &die, dwarf_output_collector &c)
+      inline debug_info_entry (int t)
+       : _m_tag (t), _m_attributes (), _m_children ()
+      {
+       if (unlikely (t <= 0))
+         throw std::invalid_argument ("invalid tag");
+      }
+
+      /* The template constructor lets us copy in from any class that has
+        compatibly iterable containers for attributes and children.  */
+      template<typename die_type, typename tracker>
+      debug_info_entry (const die_type &die, tracker &t)
        : _m_tag (die.tag ()),
-         _m_attributes (die.attributes (), c),
-         _m_children (die.children (), c)
+         _m_attributes (die.attributes (), t),
+         _m_children (die.children (), t)
       {}
 
       inline int tag () const
@@ -419,19 +457,11 @@ namespace elfutils
        return !_m_children.empty ();
       }
 
-      inline children_type &children ()
-      {
-       return _m_children;
-      }
       inline const children_type &children () const
       {
        return _m_children;
       }
 
-      inline attributes_type &attributes ()
-      {
-       return _m_attributes;
-      }
       inline const attributes_type &attributes () const
       {
        return _m_attributes;
@@ -463,62 +493,31 @@ namespace elfutils
 
     typedef debug_info_entry::attributes_type::value_type attribute;
 
-    class compile_unit : public debug_info_entry
-    {
-      friend class compile_units;
-
-      // XXX should be private
-    public:
-      template<typename die_type>
-      compile_unit (const die_type &die, dwarf_output_collector &c)
-       : debug_info_entry (die, c)
-      {
-       if (die.tag () != ::DW_TAG_compile_unit)
-         throw std::invalid_argument ("not a compile_unit entry");
-      }
-
-      /* XXX doesn't help
-       public:
-       compile_unit (const compile_unit &u) : debug_info_entry (u) {}
-      */
-    };
+    typedef dwarf_data::compile_unit<dwarf_output> compile_unit;
 
     // Main container anchoring all the output.
     class compile_units
-      : public std::list<compile_unit>
+      : public dwarf_data::compile_units<dwarf_output>
     {
       friend class dwarf_output;
-    private:
-      typedef std::list<compile_unit> _base;
 
-      // Default constructor: an empty container, no CUs.
-      inline compile_units ()
-       : _base ()
+    private:
+      // Constructor copying CUs from input container.
+      template<typename input, typename tracker>
+      inline compile_units (const input &other, tracker &t)
+       : dwarf_data::compile_units<dwarf_output> (other, t)
       {}
 
-      // Constructor copying CUs from input container.
-      template<typename input>
-      compile_units (const input &units, dwarf_output_collector &c)
-       : _base (collectify<input, compile_units> (units.begin (), c),
-                collectify<input, compile_units> (units.end (), c))
+      inline compile_units (const compile_units &)
+       : dwarf_data::compile_units<dwarf_output> ()
       {
+       throw std::logic_error
+         ("must copy-construct top-level dwarf_output object instead");
       }
 
     public:
-      typedef compile_unit value_type;
-      typedef _base::iterator iterator;
-      typedef _base::const_iterator const_iterator;
-
-      template<typename other_children>
-      bool operator== (const other_children &other) const
-      {
-       return subr::container_equal (*this, other);
-      }
-      template<typename other_children>
-      bool operator!= (const other_children &other) const
-      {
-       return !(*this == other);
-      }
+      // Default constructor: an empty container, no CUs.
+      inline compile_units () {}
     };
 
   private:
@@ -559,9 +558,18 @@ namespace elfutils
 
   // Explicit specializations.
   template<>
-  std::string to_string<dwarf_output::attribute> (const dwarf_output::attribute &);
+  std::string
+  to_string<dwarf_output::attribute> (const dwarf_output::attribute &);
+  template<>
+  std::string
+  to_string<dwarf_output::attr_value> (const dwarf_output::attr_value&);
+
   template<>
-  std::string to_string<dwarf_output::attr_value> (const dwarf_output::attr_value&);
+  std::string
+  to_string<dwarf_data::attr_value<dwarf_output,
+                                  dwarf_data::value<dwarf_output> > >
+  (const dwarf_data::attr_value<dwarf_output,
+                               dwarf_data::value<dwarf_output> > &);
 
 #endif
 
index d50abb8eb137ffc0589a8801169cd612324260be..ad383fd7694d9dd89a63385b4b14f8c5193a5b0f 100644 (file)
 
 using namespace elfutils;
 
+// Actually both the same thing!
 template dwarf::value_space dwarf_output::attr_value::what_space () const;
+template dwarf::value_space
+dwarf_data::attr_value<dwarf_output, dwarf_data::value<dwarf_output>
+                      >::what_space () const;
 
 template<>
 std::string
index 37e5122c0330841cc9028cb9b06ad9add52e6c5e..93c4230e434b88ed73c406d473a1315ce92b9f8b 100644 (file)
@@ -256,9 +256,13 @@ to_string<dwarf_edit::attr_value> (const dwarf_edit::attr_value &value)
   return value_string (value);
 }
 
+// Really.
 template<>
 string
-to_string<dwarf_output::attr_value> (const dwarf_output::attr_value &value)
+to_string<dwarf_data::attr_value<dwarf_output,
+                                dwarf_data::value<dwarf_output> > >
+(const dwarf_data::attr_value<dwarf_output,
+                             dwarf_data::value<dwarf_output> > &value)
 {
   return value_string (value);
 }