From: Roland McGrath Date: Tue, 30 Jun 2009 02:17:03 +0000 (-0700) Subject: plausible crack at first value_set attr_value flavor X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a9289117e8c37a7d6aa904f57362bd4d451a56bc;p=thirdparty%2Felfutils.git plausible crack at first value_set attr_value flavor --- diff --git a/libdw/c++/data-values.hh b/libdw/c++/data-values.hh index 246ec755f..ec1e5455f 100644 --- a/libdw/c++/data-values.hh +++ b/libdw/c++/data-values.hh @@ -54,9 +54,9 @@ namespace elfutils { - template + template dwarf::value_space - dwarf_data::attr_value::what_space () const + dwarf_data::attr_value::what_space () const { if (typeid (*_m_value) == typeid (typename v::value_flag)) return dwarf::VS_flag; diff --git a/libdw/c++/dwarf_data b/libdw/c++/dwarf_data index de2a2b78e..459dab414 100644 --- a/libdw/c++/dwarf_data +++ b/libdw/c++/dwarf_data @@ -651,15 +651,15 @@ namespace elfutils public: struct nothing {}; + class value_dispatch + { + public: + virtual ~value_dispatch () {} + }; + template struct value { - class value_dispatch - { - public: - virtual ~value_dispatch () {} - }; - struct value_string : public value_dispatch, public std::string { template @@ -809,13 +809,14 @@ namespace elfutils }; }; - template + template + > class attr_value { private: - typedef value v; - - typename v::value_dispatch *_m_value; + value_dispatch *_m_value; template inline void init (const value &other, @@ -825,63 +826,63 @@ namespace elfutils switch (other.what_space ()) { case dwarf::VS_identifier: - _m_value = new typename v::value_identifier (other.identifier (), - arg); + _m_value = new typename vw::value_identifier (other.identifier (), + arg); break; case dwarf::VS_string: - _m_value = new typename v::value_string (other.string (), arg); + _m_value = new typename vw::value_string (other.string (), arg); break; case dwarf::VS_flag: - _m_value = new typename v::value_flag (other.flag (), arg); + _m_value = new typename vw::value_flag (other.flag (), arg); break; case dwarf::VS_rangelistptr: - _m_value = new typename v::value_rangelistptr (other.ranges (), - arg); + _m_value = new typename vw::value_rangelistptr (other.ranges (), + arg); break; case dwarf::VS_lineptr: - _m_value = new typename v::value_lineptr (other.line_info (), arg); + _m_value = new typename vw::value_lineptr (other.line_info (), arg); break; case dwarf::VS_address: - _m_value = new typename v::value_address (other.address (), arg); + _m_value = new typename vw::value_address (other.address (), arg); break; case dwarf::VS_constant: if (other.constant_is_integer ()) - _m_value = new typename v::value_constant (other.constant (), - arg); + _m_value = new typename vw::value_constant (other.constant (), + arg); else - _m_value = new typename v::value_constant_block + _m_value = new typename vw::value_constant_block (other.constant_block (), arg); break; case dwarf::VS_source_line: - _m_value = new typename v::value_source_line (other.source_line (), - arg); + _m_value = new typename vw::value_source_line (other.source_line (), + arg); break; case dwarf::VS_source_column: - _m_value = new typename v::value_source_column + _m_value = new typename vw::value_source_column (other.source_column (), arg); break; case dwarf::VS_source_file: - _m_value = new typename v::value_source_file (other.source_file (), - arg); + _m_value = new typename vw::value_source_file (other.source_file (), + arg); break; case dwarf::VS_dwarf_constant: - _m_value = new typename v::value_dwarf_constant + _m_value = new typename vw::value_dwarf_constant (other.dwarf_constant (), arg); break; case dwarf::VS_reference: - _m_value = new typename v::value_reference (other.reference (), - arg); + _m_value = new typename vw::value_reference (other.reference (), + arg); break; case dwarf::VS_unit_reference: - _m_value = new typename v::value_unit_reference + _m_value = new typename vw::value_unit_reference (other.unit_reference (), arg); break; case dwarf::VS_location: - _m_value = new typename v::value_location (other.location (), arg); + _m_value = new typename vw::value_location (other.location (), arg); break; #if 0 case dwarf::VS_macptr: - _m_value = new typename v::value_macptr (other.macptr (), arg); + _m_value = new typename vw::value_macptr (other.macptr (), arg); break; #endif default: @@ -912,13 +913,6 @@ namespace elfutils init (other, arg); } - template - attr_value (const value &other) - : _m_value (NULL) - { - init (other, constructor_arg_type ()); // XXX - } - inline attr_value () : _m_value (NULL) {} @@ -956,38 +950,38 @@ namespace elfutils inline bool &flag () const { - return variant ().flag; + return variant ().flag; } // XXX dwfl, reloc inline ::Dwarf_Addr &address () const { - return variant ().addr; + return variant ().addr; } inline typename impl::debug_info_entry::children_type::iterator reference () const { - return variant ().ref; + return variant ().ref; } inline typename impl::compile_units::iterator unit_reference () const { - return variant ().ref; + return variant ().ref; } inline location_attr &location () const { return static_cast - (variant ()); + (variant ()); } - inline std::string &string () const + inline const std::string &string () const { - return static_cast - (variant ()); + return static_cast + (variant ()); } - inline std::string &identifier () const + inline const std::string &identifier () const { return string (); } @@ -995,55 +989,55 @@ namespace elfutils inline typename impl::source_file &source_file () const { return static_cast - (variant ()); + (variant ()); } inline unsigned int &source_line () const { - return variant ().n; + return variant ().n; } inline unsigned int &source_column () const { - return variant ().n; + return variant ().n; } inline ::Dwarf_Word &constant () const { - return variant ().word; + return variant ().word; } inline ::Dwarf_Sword &signed_constant () const { - return variant ().sword; + return variant ().sword; } inline std::vector &constant_block () const { return static_cast &> - (variant ()); + (variant ()); } inline typename impl::dwarf_enum &dwarf_constant () const { - return variant (); + return variant (); } inline bool constant_is_integer () const { - return dynamic_cast (_m_value) != NULL; + return dynamic_cast (_m_value) != NULL; } inline typename impl::range_list &ranges () const { return static_cast - (variant ()); + (variant ()); } inline typename impl::line_info_table &line_info () const { return static_cast - (variant ()); + (variant ()); } // macptr @@ -1104,6 +1098,126 @@ namespace elfutils } }; + template + struct constructor_arg_adapter + { + template + struct make_any + : public std::binary_function + { + 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 + struct make_attribute + : public std::binary_function + { + 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 > + struct argify + : public std::unary_function + { + 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 + { + 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 wrapped; + + inline wrapped operator () (const inny &i) + { + return wrapped (i, _m_maker); + } + }; + + template + static inline argify< + input, typename dwarf_output::debug_info_entry::attributes_type, + make_attribute + > 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 attributes_type + : public std::map > + { + friend class impl::debug_info_entry; + private: + typedef std::map > base_type; + typedef constructor_arg_adapter argify; + + protected: + inline attributes_type () {} + + public: // XXX should be protected + template + inline attributes_type (const input &other, const arg &c) + : base_type (argify::attr (other, c) (other.begin ()), + argify::attr (other, c) (other.end ())) + {} + + public: + typedef typename base_type::key_type key_type; + typedef typename base_type::value_type value_type; + typedef typename base_type::mapped_type mapped_type; + + static const bool ordered = true; + + template + inline operator attrs () const + { + return attrs (base_type::begin (), base_type::end ()); + } + }; + }; // Explicit specializations. @@ -1114,8 +1228,8 @@ namespace elfutils return elfutils::to_string (*this); // Use that. } - template - inline std::string dwarf_data::attr_value::to_string () const + template + inline std::string dwarf_data::attr_value::to_string () const { return elfutils::to_string (*this); // Use that. } diff --git a/libdw/c++/dwarf_edit b/libdw/c++/dwarf_edit index 50714de25..0d67a3e17 100644 --- a/libdw/c++/dwarf_edit +++ b/libdw/c++/dwarf_edit @@ -117,30 +117,19 @@ namespace elfutils typedef debug_info_entry value_type; }; - class attributes_type : public std::map + class attributes_type + : public dwarf_data::attributes_type { friend class debug_info_entry; private: - typedef std::map base_type; + typedef dwarf_data::attributes_type base_type; - attributes_type () {} + inline attributes_type () {} template - attributes_type (const attrs &other) - : std::map (other.begin (), other.end ()) {} - - public: - typedef base_type::key_type key_type; - typedef base_type::value_type value_type; - typedef base_type::mapped_type mapped_type; - - static const bool ordered = true; - - template - inline operator attrs () const - { - return attrs (begin (), end ()); - } + inline attributes_type (const attrs &other) + : base_type (other, dwarf_data::nothing ()) + {} }; private: diff --git a/libdw/c++/dwarf_output b/libdw/c++/dwarf_output index e9f96f98f..7318b1713 100644 --- a/libdw/c++/dwarf_output +++ b/libdw/c++/dwarf_output @@ -281,10 +281,16 @@ namespace elfutils typedef dwarf_data::dwarf_enum dwarf_enum; typedef dwarf_data::range_list range_list; typedef dwarf_data::location_attr location_attr; - typedef dwarf_data::attr_value attr_value; + + class compile_units; + class debug_info_entry; protected: + + template + static inline const std::string & + collect_string (dwarf_output_collector *, const input &); + template static inline const range_list & collect (dwarf_output_collector *, const typename input::range_list &); @@ -321,43 +327,43 @@ namespace elfutils /* 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 > - struct collectify - : public std::unary_function + typedef dwarf_data::constructor_arg_adapter + collectify; + + struct value_wrapper + : public dwarf_data::value { - 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 + struct value_string : public dwarf_data::value_dispatch { - dwarf_output_collector *_m_collector; - explicit inline maker (dwarf_output_collector *c) : _m_collector (c) {} + const std::string &_m_str; - inline outlet operator () (const inlet &x) const + template + inline value_string (const string &s, dwarf_output_collector *c) + : _m_str (collect_string (c, s)) + {} + + inline operator const std::string & () const { - return make_outlet () (x, _m_collector); + return _m_str; } - } _m_maker; - - explicit inline collectify (dwarf_output_collector *c) : _m_maker (c) {} - - typedef subr::wrapped_input_iterator wrapped; - inline wrapped operator () (const inny &i) - { - return wrapped (i, _m_maker); - } + std::string to_string () const + { + std::string result ("\""); + result += _m_str; + result += "\""; + return result; + } + }; }; public: + typedef dwarf_data::attr_value attr_value; + class compile_units; class debug_info_entry @@ -373,44 +379,29 @@ namespace elfutils template inline children_type (const input &other, dwarf_output_collector *c) : std::list - (collectify (c) (other.begin ()), - collectify (c) (other.end ())) + (collectify::argify (c) (other.begin ()), + collectify::argify (c) (other.end ())) {} public: typedef debug_info_entry value_type; }; - class attributes_type : public std::map + class attributes_type + : public dwarf_data::attributes_type { friend class debug_info_entry; private: - typedef std::map base_type; - - attributes_type () {} + typedef dwarf_data::attributes_type base_type; template inline attributes_type (const input &other, dwarf_output_collector *c) - : base_type (collectify > (c) - (other.begin ()), - collectify > (c) - (other.end ())) + : base_type (other, c) {} - - public: - typedef base_type::key_type key_type; - typedef base_type::value_type value_type; - typedef base_type::mapped_type mapped_type; - - static const bool ordered = true; - - template - inline operator attrs () const - { - return attrs (begin (), end ()); - } }; private: @@ -516,8 +507,8 @@ namespace elfutils // Constructor copying CUs from input container. template compile_units (const input &units, dwarf_output_collector *c) - : _base (collectify (c) (units.begin ()), - collectify (c) (units.end ())) + : _base (collectify::argify (c) (units.begin ()), + collectify::argify (c) (units.end ())) { } @@ -589,10 +580,18 @@ namespace elfutils friend class dwarf_output; private: + subr::value_set _m_strings; subr::value_set _m_ranges; }; + template + inline const std::string & + dwarf_output::collect_string (dwarf_output_collector *c, const input &s) + { + return c->_m_strings.add (s); + } + template inline const dwarf_output::range_list & dwarf_output::collect (dwarf_output_collector *c, diff --git a/libdw/c++/edit-values.cc b/libdw/c++/edit-values.cc index aaa8a2768..7640b4caa 100644 --- a/libdw/c++/edit-values.cc +++ b/libdw/c++/edit-values.cc @@ -53,8 +53,7 @@ using namespace elfutils; -template -dwarf::value_space dwarf_data::attr_value::what_space () const; +template dwarf::value_space dwarf_edit::attr_value::what_space () const; template<> std::string diff --git a/libdw/c++/output-values.cc b/libdw/c++/output-values.cc index 289e83aa6..d50abb8eb 100644 --- a/libdw/c++/output-values.cc +++ b/libdw/c++/output-values.cc @@ -55,10 +55,7 @@ using namespace elfutils; -template -dwarf::value_space -dwarf_data::attr_value::what_space () const; +template dwarf::value_space dwarf_output::attr_value::what_space () const; template<> std::string diff --git a/libdw/c++/subr.hh b/libdw/c++/subr.hh index 6b4508ba4..4a90e50ce 100644 --- a/libdw/c++/subr.hh +++ b/libdw/c++/subr.hh @@ -23,10 +23,16 @@ namespace elfutils template struct hash : public T::hasher {}; + template + static inline size_t hash_this (const T &v) + { + return hash () (v); + } + template inline void hash_combine (size_t &seed, const T &v) { - seed ^= hash () (v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + seed ^= hash_this (v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); } template @@ -58,7 +64,7 @@ namespace elfutils inline hasher () : _m_hash (0) {} inline void operator () (const typename T::value_type &x) { - subr::hash_combine (_m_hash, subr::hash (x)); + subr::hash_combine (_m_hash, hash_this (x)); } }; @@ -94,7 +100,7 @@ namespace elfutils struct hashed_hasher : public std::unary_function { - size_t operator () (const T &v) + size_t operator () (const T &v) const { return v._m_hash; } @@ -104,7 +110,7 @@ namespace elfutils struct name_equal : public std::binary_function { template - inline bool operator () (const mystring &me, const string &you) + inline bool operator () (const mystring &me, const string &you) const { return you == me; } @@ -115,12 +121,12 @@ namespace elfutils struct name_equal : public std::binary_function { - bool operator () (const char *me, const char *you) + bool operator () (const char *me, const char *you) const { return !strcmp (me, you); } template - inline bool operator () (const mystring &me, const char *you) + inline bool operator () (const mystring &me, const char *you) const { return me == you; } @@ -156,7 +162,7 @@ namespace elfutils template struct equal_to : public std::binary_function { - inline bool operator () (const t1 &a, const t2 &b) + inline bool operator () (const t1 &a, const t2 &b) const { return a == b; } @@ -181,7 +187,7 @@ namespace elfutils {} inline bool operator () (const typename t1::const_iterator &a, - const typename t2::const_iterator &b) + const typename t2::const_iterator &b) const { return _m_pred (*a, *b); } @@ -362,14 +368,14 @@ namespace elfutils struct hasher : public std::unary_function { - inline size_t operator () (const hashed_value &v) + inline size_t operator () (const hashed_value &v) const { return v.first; } }; hashed_value (const value_type &v) - : _base (subr::hash (v), v) {} + : _base (hash_this (v), v) {} hashed_value (const hashed_value &v) : _base (v.first, v.second) {} @@ -403,6 +409,12 @@ namespace elfutils } return p.first->second; }; + + template + const value_type &add (const input &v) + { + return add (value_type (v)); + } }; // A container of hashed_value's that itself acts like a hashed_value. @@ -499,7 +511,7 @@ namespace elfutils inline void operator () (const typename _base::value_type &p) { - subr::hash_combine (_m_hash, subr::hash (p.first)); + subr::hash_combine (_m_hash, hash_this (p.first)); subr::hash_combine (_m_hash, p.second.first); } };