From: Roland McGrath Date: Tue, 7 Jul 2009 10:34:59 +0000 (-0700) Subject: unfinished X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Froland%2Fdwarf_output-shape;p=thirdparty%2Felfutils.git unfinished --- diff --git a/libdw/c++/dwarf_output b/libdw/c++/dwarf_output index 3d8ea2eb2..d0dcd5187 100644 --- a/libdw/c++/dwarf_output +++ b/libdw/c++/dwarf_output @@ -488,10 +488,19 @@ namespace elfutils t.equivalence (out, in); } - template - inline children_type (const input &other, tracker &t) + template + static inline void + add_shape (const iterator &out, bool no_sibling, copier &c) + { + c.add_shape (*out, no_sibling); + } + + template + inline children_type (const input &other, copier &c) { - subr::create_container (this, other, t, equivalence); + subr::create_container (this, other, c, + equivalence >, + add_shape); } public: @@ -760,16 +769,27 @@ template return flag ? &flag_true : &flag_false; } - struct same_attrs : public std::equal_to + class shape; + + struct attrs_shape : public attrs_type + { + shape *_m_shape; + + template + inline attrs_shape (const input &x, copier_type &c) + : attrs_type (x, c), _m_shape (NULL) + {} + }; + + struct same_attrs : public std::equal_to { - 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_set; attrs_set _m_attr_sets; @@ -777,12 +797,59 @@ template inline const attrs_type *add_attributes (const input &x, copier_type &c) { std::pair 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 > map_hasher; + + struct shape + : public subr::hashed_value, map_hasher> + { + typedef subr::hashed_value, 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 _m_used; + + struct make_shape_pair + : public std::unary_function + { + 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 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 _m_shapes; + + inline void add_shape (const die_type &die, bool no_sibling) + { + const attrs_shape &attrs = const_cast + (static_cast (die.attributes ())); + assert (attrs._m_shape == NULL && (no_sibling || !no_sibling)); + // XXX hook for collection: abbrev building, etc. } }; @@ -904,7 +971,13 @@ template { 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 diff --git a/libdw/c++/subr.hh b/libdw/c++/subr.hh index 8d42a77eb..1df1744a6 100644 --- a/libdw/c++/subr.hh +++ b/libdw/c++/subr.hh @@ -387,33 +387,29 @@ namespace elfutils }; // Pair of some value and its precomputed hash. - template - class hashed_value - : public std::pair + template > + struct hashed_value { - private: - typedef std::pair _base; - - public: typedef T value_type; - struct hasher - : public std::unary_function - { - inline size_t operator () (const hashed_value &v) const - { - return v.first; - } - }; + const T _m_value; + size_t _m_hash; + + friend class hashed_hasher; + typedef hashed_hasher 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 + 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 @@ -628,9 +624,9 @@ namespace elfutils public: typedef element value_type; - template - inline wrapped_input_iterator (const _base &i, const arg_type &arg) - : _base (static_cast<_base> (i)), _m_wrapper (arg) + template + 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 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); } }; };