]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
unfinished roland/dwarf_output-shape
authorRoland McGrath <roland@redhat.com>
Tue, 7 Jul 2009 10:34:59 +0000 (03:34 -0700)
committerRoland McGrath <roland@redhat.com>
Tue, 7 Jul 2009 10:34:59 +0000 (03:34 -0700)
libdw/c++/dwarf_output
libdw/c++/subr.hh

index 3d8ea2eb2ce1562fe00500eaf8b48bb288de2ee7..d0dcd5187efbf29808f9b8cfb4c9bb6d5f25a61e 100644 (file)
@@ -488,10 +488,19 @@ namespace elfutils
          t.equivalence (out, in);
        }
 
-       template<typename input, typename tracker>
-       inline children_type (const input &other, tracker &t)
+       template<typename input_dw>
+       static inline void
+       add_shape (const iterator &out, bool no_sibling, copier<input_dw> &c)
+       {
+         c.add_shape (*out, no_sibling);
+       }
+
+       template<typename input, typename input_dw>
+       inline children_type (const input &other, copier<input_dw> &c)
        {
-         subr::create_container (this, other, t, equivalence<input, tracker>);
+         subr::create_container (this, other, c,
+                                 equivalence<input, copier<input_dw> >,
+                                 add_shape<input_dw>);
        }
 
       public:
@@ -760,16 +769,27 @@ template<typename flavor>
       return flag ? &flag_true : &flag_false;
     }
 
-    struct same_attrs : public std::equal_to<die_type::attributes_type>
+    class shape;
+
+    struct attrs_shape : public attrs_type
+    {
+      shape *_m_shape;
+
+      template<typename input, typename copier_type>
+      inline attrs_shape (const input &x, copier_type &c)
+       : attrs_type (x, c), _m_shape (NULL)
+      {}
+    };
+
+    struct same_attrs : public std::equal_to<attrs_type>
     {
-      bool operator () (const die_type::attributes_type &a,
-                       const die_type::attributes_type &b) const
+      bool operator () (const attrs_shape &a, const attrs_shape &b) const
       {
        return a.are (b);
       }
     };
 
-    typedef std::tr1::unordered_set<attrs_type, attrs_type::hasher,
+    typedef std::tr1::unordered_set<attrs_shape, attrs_shape::hasher,
                                    same_attrs> attrs_set;
     attrs_set _m_attr_sets;
 
@@ -777,12 +797,59 @@ template<typename flavor>
     inline const attrs_type *add_attributes (const input &x, copier_type &c)
     {
       std::pair<attrs_set::iterator, bool> p
-       = _m_attr_sets.insert (attrs_type (x, c));
-      if (p.second)
+       = _m_attr_sets.insert (attrs_shape (x, c));
+      assert (p.second == (p.first->_m_shape == NULL));
+      return &*p.first;
+    }
+
+    typedef subr::container_hasher<std::map<int, int> > map_hasher;
+
+    struct shape
+      : public subr::hashed_value<std::map<int, int>, map_hasher>
+    {
+      typedef subr::hashed_value<std::map<int, int>, map_hasher> _base;
+      typedef _base::value_type::value_type shape_pair;
+
+      enum context
        {
-         // XXX hook for collection: abbrev building, etc.
+         no_children_no_sibling,
+         no_children_has_sibling,
+         has_children_no_sibling,
+         has_children_has_sibling,
+         shape_context_bits
+       };
+      std::bitset<shape_context_bits> _m_used;
+
+      struct make_shape_pair
+       : public std::unary_function<attrs_type::value_type, shape_pair>
+      {
+       inline shape_pair operator () (const attrs_type::value_type &attr) const
+       {
+         return shape_pair (attr.first,
+                            (int) DW_FORM_indirect); // XXX
        }
-      return &(*p.first);
+      };
+
+      typedef subr::wrapped_input_iterator<attrs_type, make_shape_pair> maker;
+
+      inline shape (const attrs_type &attrs)
+       : _base (maker (attrs.begin ()), maker (attrs.end ())), _m_used ()
+      {}
+
+      inline void user (bool has_children, bool has_sibling)
+      {
+       _m_used.set (has_children * 2 + has_sibling);
+      }
+    };
+
+    subr::value_set<shape> _m_shapes;
+
+    inline void add_shape (const die_type &die, bool no_sibling)
+    {
+      const attrs_shape &attrs = const_cast<attrs_shape &>
+       (static_cast<const attrs_shape &> (die.attributes ()));
+      assert (attrs._m_shape == NULL && (no_sibling || !no_sibling));
+      // XXX hook for collection: abbrev building, etc.
     }
 
   };
@@ -904,7 +971,13 @@ template<typename flavor>
     {
       return _m_collector->add_attributes (x, *this);
     }
-  };
+
+    inline void add_shape (const dwarf_output::debug_info_entry &die,
+                          bool no_sibling)
+    {
+      _m_collector->add_shape (die, no_sibling);
+    }
+ };
 
   // Copy construction instantiates a copier derived from the collector.
   template<typename input>
index 8d42a77ebef877a9cc21525cd92d2c5f394851fd..1df1744a677f96b07f2f64d9d9f727ebd79209b9 100644 (file)
@@ -387,33 +387,29 @@ namespace elfutils
     };
 
     // Pair of some value and its precomputed hash.
-    template<typename T>
-    class hashed_value
-      : public std::pair<size_t, const T>
+    template<typename T, typename value_hasher = subr::hash<T> >
+    struct hashed_value
     {
-    private:
-      typedef std::pair<size_t, const T> _base;
-
-    public:
       typedef T value_type;
 
-      struct hasher
-       : public std::unary_function<hashed_value, size_t>
-      {
-       inline size_t operator () (const hashed_value &v) const
-       {
-         return v.first;
-       }
-      };
+      const T _m_value;
+      size_t _m_hash;
+
+      friend class hashed_hasher<hashed_value>;
+      typedef hashed_hasher<hashed_value> hasher;
 
-      hashed_value (const value_type &v)
-       : _base (hash_this (v), v) {}
-      hashed_value (const hashed_value &v)
-       : _base (v.first, v.second) {}
+      inline hashed_value (const hashed_value &v)
+       : _m_value (v._m_value), _m_hash (v._m_hash)
+      {}
+
+      template<typename... argtypes>
+      inline hashed_value (argtypes&&...args)
+       : _m_value (args...), _m_hash (value_hasher () (_m_value))
+      {}
 
       bool operator== (const hashed_value &other) const
       {
-       return other.first == this->first && other.second == this->second;
+       return other._m_hash == _m_hash && other._m_value == _m_value;
       }
     };
 
@@ -439,7 +435,7 @@ namespace elfutils
          {
            // XXX hook for collection: abbrev building, etc.
          }
-       return &p.first->second;
+       return &p.first->_m_value;
       };
 
       template<typename input>
@@ -628,9 +624,9 @@ namespace elfutils
     public:
       typedef element value_type;
 
-      template<typename arg_type>
-      inline wrapped_input_iterator (const _base &i, const arg_type &arg)
-       : _base (static_cast<_base> (i)), _m_wrapper (arg)
+      template<typename... argtypes>
+      inline wrapped_input_iterator (const _base &i, argtypes&&...args)
+       : _base (static_cast<_base> (i)), _m_wrapper (args...)
       {}
 
       inline wrapped_input_iterator (const wrapped_input_iterator &i)
@@ -833,13 +829,18 @@ namespace elfutils
     struct create_container
     {
       template<typename container, typename input, typename arg_type,
-              typename hook_type = const nothing>
+              typename hook_type = const nothing,
+              typename hook2_type = const nothing>
       inline create_container (container *me, const input &other,
-                              arg_type &arg, hook_type &hook = hook_type ())
+                              arg_type &arg,
+                              hook_type &hook = hook_type (),
+                              hook2_type &hook2 = hook2_type ())
        {
-         for (typename input::const_iterator in = other.begin ();
-              in != other.end ();
-              ++in)
+         typename input::const_iterator in = other.begin ();
+         if (in == other.end ())
+           return;
+         bool last;
+         do
            {
              /* Don't copy-construct the entry from *in here because that
                 copies it again into the list and destroys the first copy.  */
@@ -847,7 +848,10 @@ namespace elfutils
              typename container::iterator out = --me->end ();
              out->set (*in, arg);
              hook (out, in, arg);
+             last = ++in == other.end ();
+             hook2 (out, last, arg);
            }
+         while (!last);
        }
     };
   };