]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Rejigger dwarf_data constructors.
authorRoland McGrath <roland@redhat.com>
Thu, 2 Jul 2009 05:25:13 +0000 (22:25 -0700)
committerRoland McGrath <roland@redhat.com>
Thu, 2 Jul 2009 05:26:29 +0000 (22:26 -0700)
libdw/c++/data-values.hh
libdw/c++/dwarf_data
libdw/c++/dwarf_edit
libdw/c++/dwarf_output
libdw/c++/subr.hh
src/dwarfcmp.cc

index ec1e5455f6bf87dea68783d9b7feff3db31cfb7f..55860f5c5cdac3d5f5777c2e43d7c08f91af246d 100644 (file)
@@ -54,9 +54,9 @@
 namespace elfutils
 {
 
-  template<class impl, typename arg, typename v>
+  template<class impl, typename v>
   dwarf::value_space
-  dwarf_data::attr_value<impl, arg, v>::what_space () const
+  dwarf_data::attr_value<impl, v>::what_space () const
   {
     if (typeid (*_m_value) == typeid (typename v::value_flag))
       return dwarf::VS_flag;
index 56e61ed25d559bb285d5fcc544c3956f8b1c7222..423028f2c6e16bdd241c19a01d80dd959aaeaa6f 100644 (file)
@@ -651,7 +651,7 @@ namespace elfutils
   public:
     struct nothing {};
 
-    template<typename impl, typename constructor_arg_type>
+    template<typename impl>
     struct value
     {
       class value_dispatch
@@ -660,17 +660,17 @@ namespace elfutils
        virtual ~value_dispatch () {}
       };
 
-      template<typename flavor, typename input>
+      template<typename flavor, typename input, typename arg_type>
       static inline value_dispatch *
-      make (flavor *&result, const input &x, const constructor_arg_type &arg)
+      make (flavor *&result, const input &x, const arg_type &arg)
       {
        return result = new flavor (x, arg);
       }
 
       struct value_string : public value_dispatch, public std::string
       {
-       template<typename string>
-       inline value_string (const string &s, const constructor_arg_type &arg)
+       template<typename string, typename arg_type>
+       inline value_string (const string &s, const arg_type &arg)
          : std::string (s)
        {}
 
@@ -685,8 +685,8 @@ namespace elfutils
 
       struct value_identifier : public value_string
       {
-       template<typename id>
-       inline value_identifier (const id &s, const constructor_arg_type &arg)
+       template<typename id, typename arg_type>
+       inline value_identifier (const id &s, const arg_type &arg)
          : value_string (s, arg)
        {}
       };
@@ -694,29 +694,32 @@ namespace elfutils
       struct value_reference : public value_dispatch
       {
        typename impl::debug_info_entry::children_type::iterator ref;
+
+       template<typename arg_type>
        inline value_reference
        (const typename impl::debug_info_entry::children_type::iterator &i,
-        const constructor_arg_type &arg)
+        const arg_type &arg)
          : ref (i)
        {}
 
-       template<typename iter> // XXX dummy
-       value_reference (const iter &i, const constructor_arg_type &arg)
+       template<typename iter, typename arg_type>      // XXX dummy
+       inline value_reference (const iter &i, const arg_type &arg)
          : ref () {}
       };
 
       struct value_unit_reference : public value_dispatch
       {
        typename impl::compile_units::iterator ref;
+
+       template<typename arg_type>
        inline value_unit_reference
        (const typename impl::compile_units::iterator &i,
-        const constructor_arg_type &arg)
+        const arg_type &arg)
          : ref (i)
        {}
 
-       template<typename iter> // XXX dummy
-       value_unit_reference (const iter &i,
-                             const constructor_arg_type &arg)
+       template<typename iter, typename arg_type>      // XXX dummy
+       inline value_unit_reference (const iter &i, const arg_type &arg)
          : ref ()
        {}
       };
@@ -724,7 +727,9 @@ namespace elfutils
       struct value_flag : public value_dispatch
       {
        bool flag;
-       inline value_flag (bool t, const constructor_arg_type &arg)
+
+       template<typename arg_type>
+       inline value_flag (bool t, const arg_type &arg)
          : flag (t)
        {}
       };
@@ -733,25 +738,25 @@ namespace elfutils
       {
        // XXX dwfl, reloc
        ::Dwarf_Addr addr;
-       inline value_address (::Dwarf_Addr a, const constructor_arg_type &arg)
-         : addr (a)
+
+       template<typename arg_type>
+       inline value_address (::Dwarf_Addr x, const arg_type &arg)
+         : addr (x)
        {}
       };
 
       struct value_rangelistptr : public value_dispatch, public range_list
       {
-       template<typename list>
-       inline value_rangelistptr (const list &other,
-                                  const constructor_arg_type &arg)
+       template<typename list, typename arg_type>
+       inline value_rangelistptr (const list &other, const arg_type &arg)
          : range_list (other)
        {}
       };
 
       struct value_lineptr : public value_dispatch, public impl::line_info_table
       {
-       template<typename table>
-       inline value_lineptr (const table &other,
-                             const constructor_arg_type &arg)
+       template<typename table, typename arg_type>
+       inline value_lineptr (const table &other, const arg_type &arg)
          : impl::line_info_table (other)
        {}
       };
@@ -763,7 +768,9 @@ namespace elfutils
          ::Dwarf_Word word;
          ::Dwarf_Sword sword;
        };
-       inline value_constant (::Dwarf_Word x, const constructor_arg_type &arg)
+
+       template<typename arg_type>
+       inline value_constant (::Dwarf_Word x, const arg_type &arg)
          : word (x)
        {}
       };
@@ -771,34 +778,34 @@ namespace elfutils
       struct value_constant_block : public value_dispatch,
                                    public std::vector<uint8_t>
       {
-       template<typename block>
-       inline value_constant_block (const block &b,
-                                    const constructor_arg_type &arg)
+       template<typename block, typename arg_type>
+       inline value_constant_block (const block &b, const arg_type &arg)
          : std::vector<uint8_t> (b.begin (), b.end ())
        {}
       };
 
       struct value_dwarf_constant : public value_dispatch, public dwarf_enum
       {
-       template<typename constant>
-       inline value_dwarf_constant (const constant &other,
-                                    const constructor_arg_type &arg)
-         : dwarf_enum (other) {}
+       template<typename constant, typename arg_type>
+       inline value_dwarf_constant (const constant &other, const arg_type &arg)
+         : dwarf_enum (other)
+       {}
       };
 
       struct value_source_file : public value_dispatch, public source_file
       {
-       template<typename file>
-       inline value_source_file (const file &other,
-                                 const constructor_arg_type &arg)
-         : source_file (other) {}
+       template<typename file, typename arg_type>
+       inline value_source_file (const file &other, const arg_type &arg)
+         : source_file (other)
+       {}
       };
 
       struct value_source_line : public value_dispatch
       {
        unsigned int n;
-       inline value_source_line (unsigned int m,
-                                 const constructor_arg_type &arg)
+
+       template<typename arg_type>
+       inline value_source_line (unsigned int m, const arg_type &arg)
          : n (m)
        {}
       };
@@ -808,27 +815,21 @@ namespace elfutils
 
       struct value_location : public value_dispatch, public location_attr
       {
-       template<typename loc>
-       inline value_location (const loc &other,
-                              const constructor_arg_type &arg)
+       template<typename loc, typename arg_type>
+       inline value_location (const loc &other, const arg_type &arg)
          : location_attr (other)
        {}
       };
     };
 
-    template<class impl,
-            typename constructor_arg_type = nothing,
-            typename vw = value<impl, constructor_arg_type>
-            >
+    template<class impl, typename vw = value<impl> >
     class attr_value
     {
     private:
       typename vw::value_dispatch *_m_value;
 
-      template<typename value>
-      inline void init (const value &other,
-                       const constructor_arg_type &arg
-                       = constructor_arg_type ())
+      template<typename value, typename arg_type>
+      inline void init (const value &other, const arg_type &arg)
       {
        switch (other.what_space ())
          {
@@ -885,13 +886,16 @@ namespace elfutils
       }
 
     public:
-      attr_value (const attr_value &other) : _m_value (NULL)
+      /*
+      attr_value (const attr_value &other)
+       : _m_value (NULL)
       {
        init (other);
       }
+      */
 
-      template<typename value>
-      attr_value (const value &other, const constructor_arg_type &arg)
+      template<typename value, typename arg_type>
+      attr_value (const value &other, const arg_type &arg)
        : _m_value (NULL)
       {
        init (other, arg);
@@ -1082,110 +1086,24 @@ namespace elfutils
       }
     };
 
-    template<class dwarf_output, typename constructor_arg_type = nothing>
-    struct constructor_arg_adapter
-    {
-      template<typename input, typename output>
-      struct make_any
-       : public std::binary_function<typename input::value_type,
-                                     constructor_arg_type,
-                                     typename output::value_type>
-      {
-       inline typename output::value_type
-       operator () (const typename input::value_type &x,
-                    const constructor_arg_type &c) const
-       {
-         return typename output::value_type (x, c);
-       }
-      };
-
-      template<typename input, typename output>
-      struct make_attribute
-       : public std::binary_function<typename input::value_type,
-                                     constructor_arg_type,
-                                     typename output::value_type>
-      {
-       inline typename output::value_type
-       operator () (const typename input::value_type &x,
-                    const constructor_arg_type &c) const
-       {
-         return std::make_pair
-           (x.first, typename output::value_type::second_type (x.second, c));
-       }
-      };
-
-      /* An iterator adapter for use in iterator-based constructors.
-        collectify (iterator) yields an iterator on input where *i
-        constructs output::value_type (input::value_type v, collector).  */
-      template<typename input, typename output,
-              typename make_outlet = make_any<input, output> >
-      struct argify
-       : public std::unary_function<typename input::const_iterator,
-                                    typename output::iterator>
-      {
-       typedef typename input::const_iterator inny;
-       typedef typename output::iterator outty;
-       typedef typename input::value_type inlet;
-       typedef typename output::value_type outlet;
-
-       /* Wrapper worker passed to wrapped_input_iterator.
-          This object holds the collector pointer.  */
-       struct maker
-         : public std::unary_function<inlet, outlet>
-       {
-         constructor_arg_type _m_arg;
-         explicit inline maker (const constructor_arg_type &c) : _m_arg (c) {}
-
-         inline outlet operator () (const inlet &x) const
-         {
-           return make_outlet () (x, _m_arg);
-         }
-       } _m_maker;
-
-       explicit inline argify (const constructor_arg_type &c)
-         : _m_maker (c)
-       {}
-
-       typedef subr::wrapped_input_iterator<input, maker> wrapped;
-
-       inline wrapped operator () (const inny &i)
-       {
-         return wrapped (i, _m_maker);
-       }
-      };
-
-      template<class input>
-      static inline argify<
-       input, typename dwarf_output::debug_info_entry::attributes_type,
-       make_attribute<input,
-                      typename dwarf_output::debug_info_entry::attributes_type>
-       > attr (const input &, const constructor_arg_type &c)
-      {
-       return argify<
-         input, typename dwarf_output::debug_info_entry::attributes_type,
-         make_attribute<
-           input, typename dwarf_output::debug_info_entry::attributes_type>
-           > (c);
-      };
-    };
-
-    template<class impl, typename arg = nothing, typename v = value<impl, arg> >
+    template<class impl, typename arg = nothing, typename v = value<impl> >
     class attributes_type
-      : public std::map<int, attr_value<impl, arg, v> >
+      : public std::map<int, attr_value<impl, v> >
     {
       friend class impl::debug_info_entry;
     private:
-      typedef std::map<int, attr_value<impl, arg, v> > base_type;
-      typedef constructor_arg_adapter<impl, arg> argify;
+      typedef std::map<int, attr_value<impl, v> > base_type;
 
     protected:
       inline attributes_type () {}
 
     public: // XXX should be protected
-      template<typename input>
-      inline attributes_type (const input &other, const arg &c)
-       : base_type (argify::attr (other, c) (other.begin ()),
-                    argify::attr (other, c) (other.end ()))
+      template<typename input, typename arg_type>
+      inline attributes_type (const input &other, const arg_type &c)
+       : base_type (subr::argify2nd<input, attributes_type, arg_type>
+                    (other.begin (), c),
+                    subr::argify2nd<input, attributes_type, arg_type>
+                    (other.end (), c))
       {}
 
     public:
@@ -1212,8 +1130,8 @@ namespace elfutils
     return elfutils::to_string (*this); // Use that.
   }
 
-  template<class impl, typename arg, typename v>
-  inline std::string dwarf_data::attr_value<impl, arg, v>::to_string () const
+  template<class impl, typename v>
+  inline std::string dwarf_data::attr_value<impl, v>::to_string () const
   {
     return elfutils::to_string (*this); // Use that.
   }
index 0d67a3e17e13689d859c5a163e6069c08bd0b04c..239fb3f76bc019487ef77ac779d661fa7f1d650a 100644 (file)
@@ -52,6 +52,7 @@
 
 #include "dwarf"
 #include "dwarf_data"
+#include "dwarf_tracker"
 
 /* Read the comments for elfutils::dwarf first.
 
@@ -109,9 +110,12 @@ namespace elfutils
       private:
         children_type () {}
 
-       template<typename childrens>
-       children_type (const childrens &other)
-         : std::list<debug_info_entry> (other.begin (), other.end ()) {}
+       template<typename input, typename tracker>
+       children_type (const input &other, tracker *t)
+         : std::list<debug_info_entry>
+           (subr::argify<input, children_type, tracker *> (other.begin (), t),
+            subr::argify<input, children_type, tracker *> (other.end (), t))
+       {}
 
       public:
        typedef debug_info_entry value_type;
@@ -126,9 +130,9 @@ namespace elfutils
 
        inline attributes_type () {}
 
-       template<typename attrs>
-       inline attributes_type (const attrs &other)
-         : base_type (other, dwarf_data::nothing ())
+       template<typename attrs, typename tracker>
+       inline attributes_type (const attrs &other, tracker *t)
+         : base_type (other, t)
        {}
       };
 
@@ -146,11 +150,11 @@ namespace elfutils
 
       /* The template constructor lets us copy in from any class that has
         compatibly iterable containers for attributes and children.  */
-      template<typename die_type>
-      debug_info_entry (const die_type &die)
+      template<typename die_type, typename tracker>
+      debug_info_entry (const die_type &die, tracker *t)
        : _m_tag (die.tag ()),
-         _m_attributes (die.attributes ()),
-         _m_children (die.children ())
+         _m_attributes (die.attributes (), t),
+         _m_children (die.children (), t)
       {}
 
       inline int tag () const
@@ -215,8 +219,9 @@ namespace elfutils
 
       // XXX should be private
     public:
-      template<typename die_type>
-      compile_unit (const die_type &die) : debug_info_entry (die)
+      template<typename die_type, typename tracker>
+      inline compile_unit (const die_type &die, tracker *t)
+       : debug_info_entry (die, t)
       {
        if (die.tag () != ::DW_TAG_compile_unit)
          throw std::invalid_argument ("not a compile_unit entry");
@@ -236,12 +241,17 @@ namespace elfutils
       typedef std::list<compile_unit> _base;
 
       // Default constructor: an empty container, no CUs.
-      inline compile_units () {}
+      inline compile_units ()
+      {}
 
       // Constructor copying CUs from input container.
-      template<typename input>
-      compile_units(const input &units)
-       : _base (units.begin (), units.end ()) {}
+      template<typename input, typename tracker>
+      inline compile_units (const input &units, tracker *t)
+       : _base (subr::argify<input, compile_units, tracker *>
+                (units.begin (), t),
+                subr::argify<input, compile_units, tracker *>
+                (units.end (), t))
+      {}
 
     public:
       typedef compile_unit value_type;
@@ -285,8 +295,10 @@ namespace elfutils
     inline dwarf_edit () {}
 
     // Constructor copying CUs from an input file (dwarf or dwarf_edit).
-    template<typename input>
-    dwarf_edit (const input &dw) : _m_units (dw.compile_units ()) {}
+    template<typename input, typename tracker>
+    dwarf_edit (const input &dw, tracker *t)
+      : _m_units (dw.compile_units (), t)
+    {}
 
     template<typename file>
     inline bool operator== (const file &other) const
index 65bff72f7e42e340b735e3cc914e72fd6a62da12..255afa27c06c32a3dacb7cb7ce1d2dd3ec2ec995 100644 (file)
@@ -291,19 +291,20 @@ namespace elfutils
     static inline const std::string &
     collect_string (dwarf_output_collector *, const input &);
 
-    template<typename input>
-    static inline const range_list &
-    collect (dwarf_output_collector *, const typename input::range_list &);
-
     /* An iterator adapter for use in iterator-based constructors.
        collectify (iterator) yields an iterator on input where *i
        constructs output::value_type (input::value_type v, collector).  */
-    typedef dwarf_data::constructor_arg_adapter<dwarf_output,
-                                               dwarf_output_collector *>
-    collectify;
+    template<typename input, typename output>
+    static inline typename subr::argifier<input, output,
+                                         dwarf_output_collector *>::wrapped
+    collectify (const typename input::const_iterator &in,
+               dwarf_output_collector *c)
+    {
+      return subr::argifier<input, output, dwarf_output_collector *> (c) (in);
+    }
 
     struct value_wrapper
-      : public dwarf_data::value<dwarf_output, dwarf_output_collector *>
+      : public dwarf_data::value<dwarf_output>
     {
       struct value_string : public value_dispatch
       {
@@ -331,9 +332,7 @@ namespace elfutils
 
   public:
 
-    typedef dwarf_data::attr_value<dwarf_output,
-                                  dwarf_output_collector *,
-                                  value_wrapper> attr_value;
+    typedef dwarf_data::attr_value<dwarf_output, value_wrapper> attr_value;
 
     class compile_units;
 
@@ -350,8 +349,8 @@ namespace elfutils
        template<typename input>
        inline children_type (const input &other, dwarf_output_collector *c)
          : std::list<debug_info_entry>
-           (collectify::argify<input, children_type> (c) (other.begin ()),
-            collectify::argify<input, children_type> (c) (other.end ()))
+           (collectify<input, children_type> (other.begin (), c),
+            collectify<input, children_type> (other.end (), c))
        {}
 
       public:
@@ -478,8 +477,8 @@ namespace elfutils
       // Constructor copying CUs from input container.
       template<typename input>
       compile_units (const input &units, dwarf_output_collector *c)
-       : _base (collectify::argify<input, compile_units> (c) (units.begin ()),
-                collectify::argify<input, compile_units> (c) (units.end ()))
+       : _base (collectify<input, compile_units> (units.begin (), c),
+                collectify<input, compile_units> (units.end (), c))
       {
       }
 
@@ -563,14 +562,6 @@ namespace elfutils
     return c->_m_strings.add (s);
   }
 
-  template<typename input>
-  inline const dwarf_output::range_list &
-  dwarf_output::collect (dwarf_output_collector *c,
-                        const typename input::range_list &rl)
-  {
-    return c->_m_ranges.add (rl);
-  }
-
 };
 
 #endif // <elfutils/dwarf_output>
index 4a90e50ce5b690541b6e7f537999307185e1f80b..7a799eeb82247a39707d3921049c4855cddb1f59 100644 (file)
@@ -603,6 +603,98 @@ namespace elfutils
        return (*_m_wrapper) (_base::operator* ());
       }
     };
+
+    /* An iterator adapter for use in iterator-based constructors.
+       collectify (iterator) yields an iterator on input where *i
+       constructs output::value_type (input::value_type v, collector).  */
+    template<typename input, typename output, typename arg_type>
+    struct argifier
+      : public std::unary_function<typename input::const_iterator,
+                                  typename output::iterator>
+    {
+      typedef typename input::const_iterator inny;
+      typedef typename output::iterator outty;
+      typedef typename input::value_type inlet;
+      typedef typename output::value_type outlet;
+
+      /* Wrapper worker passed to wrapped_input_iterator.
+        This object holds the collector pointer.  */
+      struct maker
+       : public std::unary_function<inlet, outlet>
+      {
+       arg_type _m_arg;
+       explicit inline maker (const arg_type &c) : _m_arg (c) {}
+
+       inline outlet operator () (const inlet &x) const
+       {
+         return outlet (x, _m_arg);
+       }
+      } _m_maker;
+
+      explicit inline argifier (const arg_type &c)
+       : _m_maker (c)
+      {}
+
+      typedef subr::wrapped_input_iterator<input, maker> wrapped;
+
+      inline wrapped operator () (const inny &i)
+      {
+       return wrapped (i, _m_maker);
+      }
+    };
+
+    template<typename input, typename output, typename arg_type>
+    static inline typename argifier<input, output, arg_type>::wrapped
+    argify (const typename input::const_iterator &in, const arg_type &arg)
+    {
+      return argifier<input, output, arg_type> (arg) (in);
+    }
+
+    template<typename input, typename output, typename arg_type>
+    struct argifier2nd
+      : public std::unary_function<typename input::const_iterator,
+                                  typename output::iterator>
+    {
+      typedef typename input::const_iterator inny;
+      typedef typename output::iterator outty;
+      typedef typename input::value_type inlet;
+      typedef typename output::value_type outlet;
+
+      /* Wrapper worker passed to wrapped_input_iterator.
+        This object holds the collector pointer.  */
+      struct maker
+       : public std::unary_function<inlet, outlet>
+      {
+       arg_type _m_arg;
+       explicit inline maker (const arg_type &c) : _m_arg (c) {}
+
+       inline outlet operator () (const inlet &x) const
+       {
+         return std::make_pair (x.first,
+                                typename outlet::second_type (x.second,
+                                                              _m_arg));
+       }
+      } _m_maker;
+
+      explicit inline argifier2nd (const arg_type &c)
+       : _m_maker (c)
+      {}
+
+      typedef subr::wrapped_input_iterator<input, maker> wrapped;
+
+      inline wrapped operator () (const inny &i)
+      {
+       return wrapped (i, _m_maker);
+      }
+    };
+
+    template<typename input, typename output, typename arg_type>
+    static inline typename argifier2nd<input, output, arg_type>::wrapped
+    argify2nd (const typename input::const_iterator &in, const arg_type &arg)
+    {
+      return argifier2nd<input, output, arg_type> (arg) (in);
+    }
+
   };
 };
 
index e29d2d8c1be6bb361ede1d8d5a035491d43b6978..677a5bebae85f756bb82bdae41e77d3d822d0ede 100644 (file)
@@ -325,8 +325,10 @@ main (int argc, char *argv[])
 
       if (test_writer)
        {
-         dwarf_edit edit1 (file1);
-         dwarf_edit edit2 (file2);
+         dwarf_ref_tracker<dwarf_edit, dwarf> t1;
+         dwarf_ref_tracker<dwarf_edit, dwarf> t2;
+         dwarf_edit edit1 (file1, &t1);
+         dwarf_edit edit2 (file2, &t2);
          test_classes (file1, file2, edit1, edit2, same);
 
          {