From: Roland McGrath Date: Mon, 6 Jul 2009 11:34:46 +0000 (-0700) Subject: Getting there on dwarf_output value sets. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=18c31ede9490fdfbee3a9bf85b536d8e8852f87b;p=thirdparty%2Felfutils.git Getting there on dwarf_output value sets. --- diff --git a/libdw/c++/dwarf_data b/libdw/c++/dwarf_data index 19457d91d..91d4e663d 100644 --- a/libdw/c++/dwarf_data +++ b/libdw/c++/dwarf_data @@ -516,18 +516,6 @@ namespace elfutils typedef std::pair _base; public: - struct hasher - : public std::unary_function - { - size_t operator () (const line_info_table &v) const - { - size_t hash = 0; - subr::hash_combine (hash, v.first); - subr::hash_combine (hash, v.second); - return hash; - } - }; - inline line_info_table () : _base () {} template @@ -591,7 +579,7 @@ namespace elfutils { size_t operator () (const dwarf_enum &v) const { - return v.first; + return subr::hash_this<_base> (v); } }; @@ -781,7 +769,7 @@ namespace elfutils }; public: - template + template struct value { struct value_dispatch @@ -789,15 +777,22 @@ namespace elfutils virtual ~value_dispatch () {} }; + typedef value_dispatch value_cell_type; + + static const bool delete_value = alloc_values; + template static inline value_dispatch * make (flavor *&result, const input &x, arg_type &arg) { + assert (alloc_values); return result = new flavor (x, arg); } struct value_string : public value_dispatch, public std::string { + typedef subr::hash hasher; + inline value_string () {} template @@ -805,6 +800,11 @@ namespace elfutils : std::string (s) {} + template + inline value_string (const string &s) + : std::string (s) + {} + std::string to_string () const { std::string result ("\""); @@ -822,6 +822,11 @@ namespace elfutils inline value_identifier (const id &s, arg_type &arg) : value_string (s, arg) {} + + template + inline value_identifier (const id &s) + : value_string (s) + {} }; struct value_reference : public value_dispatch @@ -854,8 +859,8 @@ namespace elfutils { bool flag; - inline value_flag () - : flag (true) + inline value_flag (bool t = true) + : flag (t) {} template @@ -869,14 +874,32 @@ namespace elfutils // XXX dwfl, reloc ::Dwarf_Addr addr; - inline value_address () - : addr (0) + inline value_address (::Dwarf_Addr x = 0) + : addr (x) {} template inline value_address (::Dwarf_Addr x, arg_type &) : addr (x) {} + + struct hasher : public std::unary_function + { + inline size_t operator () (const value_address &c) const + { + return c.addr; + } + }; + + inline operator ::Dwarf_Addr () const + { + return addr; + } + + inline bool operator== (::Dwarf_Addr x) const + { + return addr == x; + } }; struct value_rangelistptr : public value_dispatch, public range_list @@ -887,6 +910,11 @@ namespace elfutils inline value_rangelistptr (const list &other, arg_type &) : range_list (other) {} + + template + inline value_rangelistptr (const list &other) + : range_list (other) + {} }; struct value_lineptr : public value_dispatch, public impl::line_info_table @@ -907,31 +935,61 @@ namespace elfutils ::Dwarf_Sword sword; }; - inline value_constant () - : word (0) + inline value_constant (::Dwarf_Word value = 0) + : word (value) {} template inline value_constant (::Dwarf_Word x, arg_type &) : word (x) {} + + struct hasher : public std::unary_function + { + inline size_t operator () (const value_constant &c) const + { + return c.word; + } + }; + + inline operator ::Dwarf_Word () const + { + return word; + } + + inline bool operator== (::Dwarf_Word x) const + { + return word == x; + } }; struct value_constant_block : public value_dispatch, public std::vector { + typedef subr::hash > hasher; + inline value_constant_block () {} template inline value_constant_block (const block &b, arg_type &) : std::vector (b.begin (), b.end ()) {} + + template + inline value_constant_block (const block &b) + : std::vector (b.begin (), b.end ()) + {} }; struct value_dwarf_constant : public value_dispatch, public dwarf_enum { inline value_dwarf_constant () {} + template + inline value_dwarf_constant (const constant &other) + : dwarf_enum (other) + {} + template inline value_dwarf_constant (const constant &other, arg_type &) : dwarf_enum (other) @@ -946,22 +1004,48 @@ namespace elfutils inline value_source_file (const file &other, arg_type &) : source_file (other) {} + + template + inline value_source_file (const file &other) + : source_file (other) + {} }; struct value_source_line : public value_dispatch { unsigned int n; - inline value_source_line () - : n (0) + inline value_source_line (unsigned int x = 0) + : n (x) {} template inline value_source_line (unsigned int m, arg_type &) : n (m) {} + + struct hasher : public std::unary_function + { + inline size_t operator () (const value_source_line &c) const + { + return c.n; + } + }; + + inline operator unsigned int () const + { + return n; + } + + inline bool operator== (unsigned int x) const + { + return n == x; + } + }; + + class value_source_column : public value_source_line + { }; - typedef value_source_line value_source_column; struct value_macptr : public value_dispatch {}; @@ -985,7 +1069,7 @@ namespace elfutils friend class attributes_type; private: - typename vw::value_dispatch *_m_value; + typename vw::value_cell_type *_m_value; typedef typename impl::debug_info_entry::pointer die_ptr; template @@ -1058,9 +1142,9 @@ namespace elfutils } template - inline flavor &variant () const + inline const flavor &variant () const { - return const_variant (); + return const_variant (); } template @@ -1092,7 +1176,7 @@ namespace elfutils ~attr_value () { - if (_m_value != NULL) + if (vw::delete_value && _m_value != NULL) delete _m_value; } @@ -1121,7 +1205,7 @@ namespace elfutils dwarf::value_space what_space () const; inline std::string to_string () const; - inline bool &flag () const + inline const bool &flag () const { return variant ().flag; } @@ -1132,7 +1216,7 @@ namespace elfutils } // XXX dwfl, reloc - inline ::Dwarf_Addr &address () const + inline const ::Dwarf_Addr &address () const { return variant ().addr; } @@ -1143,7 +1227,7 @@ namespace elfutils return variant ().addr; } - inline die_ptr &reference () const + inline const die_ptr &reference () const { return variant ().ref; } @@ -1153,9 +1237,9 @@ namespace elfutils return variant ().ref; } - inline location_attr &location () const + inline const location_attr &location () const { - return static_cast + return static_cast (variant ()); } @@ -1191,7 +1275,7 @@ namespace elfutils inline const typename impl::source_file &source_file () const { - return static_cast + return static_cast (variant ()); } @@ -1243,7 +1327,7 @@ namespace elfutils inline const std::vector &constant_block () const { - return static_cast &> + return static_cast &> (variant ()); } @@ -1265,13 +1349,14 @@ namespace elfutils inline bool constant_is_integer () const { - return dynamic_cast (_m_value) != NULL; + return (dynamic_cast (_m_value) + != NULL); } inline const typename impl::range_list &ranges () const { - return static_cast - (variant ()); + return static_cast + (variant ()); } inline typename impl::range_list &ranges () @@ -1282,8 +1367,8 @@ namespace elfutils inline const typename impl::line_info_table &line_info () const { - return static_cast - (variant ()); + return static_cast + (variant ()); } inline typename impl::line_info_table &line_info () diff --git a/libdw/c++/dwarf_output b/libdw/c++/dwarf_output index efd29859d..bd9b63b7d 100644 --- a/libdw/c++/dwarf_output +++ b/libdw/c++/dwarf_output @@ -272,6 +272,8 @@ namespace elfutils class dwarf_output { + friend class dwarf_output_collector; + public: typedef dwarf_data::source_file source_file; typedef dwarf_data::directory_table directory_table; @@ -289,10 +291,6 @@ namespace elfutils protected: template class copier; // Below. - template - static inline const std::string & - collect_string (dwarf_output_collector &c, const input &); - /* 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). */ @@ -305,31 +303,12 @@ namespace elfutils return subr::argifier (c) (in); } - struct value_wrapper - : public dwarf_data::value + struct value + : public dwarf_data::value { - struct value_string : public value_dispatch - { - const std::string &_m_str; + typedef const value_dispatch value_cell_type; - template - inline value_string (const string &s, dwarf_output::copier &c) - : _m_str (collect_string (c, s)) - {} - - inline operator const std::string & () const - { - return _m_str; - } - - std::string to_string () const - { - std::string result ("\""); - result += _m_str; - result += "\""; - return result; - } - }; + typedef dwarf_data::value data; template static inline value_dispatch * @@ -338,33 +317,116 @@ namespace elfutils throw std::logic_error ("dwarf_output cannot be default-constructed"); } - template + // XXX temporary + template static inline value_dispatch * - make (flavor *&result, const input &x, arg_type &arg) + make (flavor *&result, const input &x, copier &c) { - return result = new flavor (x, arg); + return result = new flavor (x, c); } - template - static inline value_dispatch * - make (value_string *&result, const input &x, dwarf_output_collector &c) + template + static inline const value_dispatch * + make (value_string *&, const input &x, copier &c) + { + return c.add_string (x); + } + + template + static inline const value_dispatch * + make (value_identifier *&, const input &x, copier &c) + { + return c.add_identifier (x); + } + + // XXX reference + + template + static inline const value_dispatch * + make (value_flag *&, const input &x, copier &c) + { + return c.add_flag (x); + } + + template + static inline const value_dispatch * + make (value_address *&, const input &x, copier &c) + { + return c.add_address (x); + } + + template + static inline const value_dispatch * + make (value_rangelistptr *&, const input &x, copier &c) + { + return c.add_ranges (x); + } + + /* XXX lineptr + template + static inline const value_dispatch * + make (value_lineptr *&, const input &x, copier &c) + { + return c.add_line_info (x); + } + */ + + template + static inline const value_dispatch * + make (value_constant *&, const input &x, copier &c) + { + return c.add_constant (x); + } + + template + static inline const value_dispatch * + make (value_constant_block *&, const input &x, copier &c) + { + return c.add_constant_block (x); + } + + template + static inline const value_dispatch * + make (value_dwarf_constant *&, const input &x, copier &c) { - return result = new value_string (x, c); + return c.add_dwarf_constant (x); } + template + static inline const value_dispatch * + make (value_source_file *&, const input &x, copier &c) + { + return c.add_source_file (x); + } + + template + static inline const value_dispatch * + make (value_source_line *&, const input &x, copier &c) + { + return c.add_source_line (x); + } + + template + static inline const value_dispatch * + make (value_source_column *&, const input &x, copier &c) + { + return c.add_source_column (x); + } + + // XXX macptr + // XXX location }; public: - typedef dwarf_data::attr_value attr_value; + typedef dwarf_data::attr_value attr_value; class debug_info_entry { friend class subr::create_container; public: - typedef dwarf_data::attributes_type attributes_type; + typedef dwarf_data::attributes_type attributes_type; class children_type : public std::list { @@ -580,16 +642,28 @@ namespace elfutils friend class dwarf_output; private: - subr::value_set _m_strings; - subr::value_set _m_ranges; - - public: - + subr::value_set _m_strings; + subr::value_set _m_identifiers; + subr::value_set _m_address; + subr::value_set _m_ranges; + subr::value_set _m_constants; + subr::value_set _m_const_block; + subr::value_set _m_dwarf_const; + subr::value_set _m_source_file; + subr::value_set _m_source_line; + subr::value_set _m_source_column; + + static const dwarf_output::value::value_flag flag_true; + static const dwarf_output::value::value_flag flag_false; + static inline const dwarf_output::value::value_flag *flag (bool flag) + { + return flag ? &flag_true : &flag_false; + } }; - template + template class dwarf_output::copier - : public dwarf_ref_maker // XXX temporary + : public dwarf_ref_maker // XXX temporary { friend class dwarf_output; private: @@ -609,6 +683,74 @@ namespace elfutils { return *_m_collector; } + + template + inline const value::value_string *add_string (const input &x) + { + return _m_collector->_m_strings.add (x); + } + + template + inline const value::value_string *add_identifier (const input &x) + { + return _m_collector->_m_identifiers.add (x); + } + + template + inline const value::value_flag *add_flag (const input &x) + { + return dwarf_output_collector::flag (x); + } + + template + inline const value::value_address *add_address (const input &x) + { + return _m_collector->_m_address.add (x); + } + + template + inline const value::value_rangelistptr *add_ranges (const input &x) + { + return _m_collector->_m_ranges.add (x); + } + + template + inline const value::value_constant *add_constant (const input &x) + { + return _m_collector->_m_constants.add (x); + } + + template + inline const value::value_constant_block * + add_constant_block (const input &x) + { + return _m_collector->_m_const_block.add (x); + } + + template + inline const value::value_dwarf_constant * + add_dwarf_constant (const input &x) + { + return _m_collector->_m_dwarf_const.add (x); + } + + template + inline const value::value_source_file *add_source_file (const input &x) + { + return _m_collector->_m_source_file.add (x); + } + + template + inline const value::value_source_line *add_source_line (const input &x) + { + return _m_collector->_m_source_line.add (x); + } + + template + inline const value::value_source_column *add_source_column (const input &x) + { + return _m_collector->_m_source_column.add (x); + } }; // Copy construction instantiates a copier derived from the collector. @@ -618,14 +760,6 @@ namespace elfutils copier maker) : _m_units (dw.compile_units (), maker (c)) {} - - template - inline const std::string & - dwarf_output::collect_string (dwarf_output_collector &c, const input &s) - { - return c._m_strings.add (s); - } - }; #endif // diff --git a/libdw/c++/output-values.cc b/libdw/c++/output-values.cc index 05e9b7404..aa45180ce 100644 --- a/libdw/c++/output-values.cc +++ b/libdw/c++/output-values.cc @@ -67,3 +67,6 @@ to_string (const dwarf_output::attribute &attr) result += attr.second.to_string (); return result; } + +const dwarf_output::value::value_flag dwarf_output_collector::flag_true (1); +const dwarf_output::value::value_flag dwarf_output_collector::flag_false (0); diff --git a/libdw/c++/subr.hh b/libdw/c++/subr.hh index 02d95b381..694b9b215 100644 --- a/libdw/c++/subr.hh +++ b/libdw/c++/subr.hh @@ -53,7 +53,23 @@ namespace elfutils template<> struct hash : public integer_hash {}; template<> + struct hash : public integer_hash {}; + template<> struct hash : public integer_hash {}; + template<> + struct hash : public integer_hash {}; + + template + struct hash > + : public std::unary_function, size_t> + { + inline size_t operator () (const std::pair &x) const + { + size_t h = 0; + subr::hash_combine (h, x); + return h; + } + }; template struct container_hasher : public std::unary_function @@ -76,8 +92,15 @@ namespace elfutils } }; + template + struct hash > + : public container_hasher > + { + }; + template<> struct hash + : public container_hasher { private: struct hasher : public container_hasher::hasher @@ -399,7 +422,7 @@ namespace elfutils struct hashed_value_type::hasher> _base; public: - const value_type &add (const value_type &v) + const value_type *add (const value_type &v) { std::pair p = _base::insert (hashed_value_type (v)); @@ -407,11 +430,11 @@ namespace elfutils { // XXX hook for collection: abbrev building, etc. } - return p.first->second; + return &p.first->second; }; template - const value_type &add (const input &v) + const value_type *add (const input &v) { return add (value_type (v)); }