diff options
author | Roland McGrath <roland@redhat.com> | 2009-07-07 03:34:59 -0700 |
---|---|---|
committer | Roland McGrath <roland@redhat.com> | 2009-07-07 03:34:59 -0700 |
commit | 2c1901ebaf4862da6e9fb9b1d60f0b5f8ac7dcbc (patch) | |
tree | dbee807691feed3e24b4d82370f1f1b9f644ab49 | |
parent | d0084a295377e0bed6df39bb2bc3997347ea46d7 (diff) | |
download | elfutils-roland/dwarf_output-shape.tar.gz |
unfinishedroland/dwarf_output-shape
-rw-r--r-- | libdw/c++/dwarf_output | 97 | ||||
-rw-r--r-- | libdw/c++/subr.hh | 62 |
2 files changed, 118 insertions, 41 deletions
diff --git a/libdw/c++/dwarf_output b/libdw/c++/dwarf_output index 3d8ea2eb..d0dcd518 100644 --- a/libdw/c++/dwarf_output +++ b/libdw/c++/dwarf_output @@ -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> diff --git a/libdw/c++/subr.hh b/libdw/c++/subr.hh index 8d42a77e..1df1744a 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<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); } }; }; |