From: Roland McGrath Date: Mon, 17 Aug 2009 05:15:16 +0000 (-0700) Subject: more there X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a9818bd7629296c5bf7e84a5ea1fe342fc1cf0c1;p=thirdparty%2Felfutils.git more there --- diff --git a/libdw/c++/data-values.hh b/libdw/c++/data-values.hh index 712dd6bf6..5f109042f 100644 --- a/libdw/c++/data-values.hh +++ b/libdw/c++/data-values.hh @@ -49,7 +49,11 @@ #include "dwarf_data" -#include +template +static inline bool is_a (const typename v::value_dispatch *value) +{ + return dynamic_cast (value) != NULL; +} namespace elfutils { @@ -57,37 +61,37 @@ namespace elfutils dwarf::value_space dwarf_data::attr_value::what_space () const { - if (typeid (*_m_value) == typeid (typename v::value_flag)) + if (is_a (_m_value)) return dwarf::VS_flag; - if (typeid (*_m_value) == typeid (typename v::value_dwarf_constant)) + if (is_a (_m_value)) return dwarf::VS_dwarf_constant; - if (typeid (*_m_value) == typeid (typename v::value_reference)) + if (is_a (_m_value)) return dwarf::VS_reference; - if (typeid (*_m_value) == typeid (typename v::value_lineptr)) + if (is_a (_m_value)) return dwarf::VS_lineptr; - if (typeid (*_m_value) == typeid (typename v::value_macptr)) + if (is_a (_m_value)) return dwarf::VS_macptr; - if (typeid (*_m_value) == typeid (typename v::value_rangelistptr)) + if (is_a (_m_value)) return dwarf::VS_rangelistptr; - if (typeid (*_m_value) == typeid (typename v::value_identifier)) + if (is_a (_m_value)) return dwarf::VS_identifier; - if (typeid (*_m_value) == typeid (typename v::value_string)) + if (is_a (_m_value)) return dwarf::VS_string; - if (typeid (*_m_value) == typeid (typename v::value_source_file)) + if (is_a (_m_value)) return dwarf::VS_source_file; - if (typeid (*_m_value) == typeid (typename v::value_source_line)) + if (is_a (_m_value)) return dwarf::VS_source_line; - if (typeid (*_m_value) == typeid (typename v::value_source_column)) + if (is_a (_m_value)) return dwarf::VS_source_column; - if (typeid (*_m_value) == typeid (typename v::value_address)) + if (is_a (_m_value)) return dwarf::VS_address; - if (typeid (*_m_value) == typeid (typename v::value_constant) - || typeid (*_m_value) == typeid (typename v::value_constant_block)) + if (is_a (_m_value) + || is_a (_m_value)) return dwarf::VS_constant; - if (typeid (*_m_value) == typeid (typename v::value_location)) + if (is_a (_m_value)) return dwarf::VS_location; - throw std::runtime_error ("XXX impossible"); + throw std::logic_error ("attr_value has no known value_space!"); } template diff --git a/libdw/c++/dwarf_data b/libdw/c++/dwarf_data index 005fc5dce..d11efdb30 100644 --- a/libdw/c++/dwarf_data +++ b/libdw/c++/dwarf_data @@ -827,13 +827,25 @@ namespace elfutils return *result; } - template - static inline void - make (value_dispatch *&v, flavor *&result, - int /*whatattr*/, const input &x, arg_type &arg) + template + struct maker { - assert (alloc_values); - v = result = new flavor (x, arg); + inline explicit maker (const arg_type &) {} + + template + static inline void + make (value_dispatch *&v, flavor *&result, + int /*whatattr*/, const input &x, arg_type &arg) + { + assert (alloc_values); + v = result = new flavor (x, arg); + } + }; + + template + static inline maker make (arg_type &arg) + { + return maker (arg); } struct value_string : public value_dispatch, public std::string @@ -890,7 +902,7 @@ namespace elfutils object. This is what plain assignment does. This just uses this pointer, rather than translating it from another file into this one (which requires a tracker). */ - inline value_reference (const value_type &i, const subr::nothing &) + inline value_reference (const value_type &i, subr::nothing &) : ref (i) {} @@ -1125,11 +1137,23 @@ namespace elfutils typename vw::value_cell_type *_m_value; typedef typename impl::debug_info_entry::pointer die_ptr; - template + template struct init { inline init (attr_value *av, int whatattr, - const value &other, arg_type &arg = arg_type ()) + const value &other, arg_type &arg) + { + do_init (av, whatattr, other, arg); + } + + inline init (attr_value *av, int whatattr, const value &other) + { + arg_type dummy; + do_init (av, whatattr, other, dummy); + } + + static inline void do_init (attr_value *av, int whatattr, + const value &other, arg_type &arg) { switch (other.what_space ()) { @@ -1137,7 +1161,8 @@ namespace elfutils case dwarf::VS_##flavor: \ { \ typename vw::value_##flavor *p; \ - vw::make (av->_m_value, p, whatattr, other.fetch (), arg); \ + vw::make (arg) \ + .make (av->_m_value, p, whatattr, other.fetch (), arg); \ } \ break @@ -1158,14 +1183,14 @@ namespace elfutils if (other.constant_is_integer ()) { typename vw::value_constant *p; - vw::make (av->_m_value, p, whatattr, - other.constant (), arg); + vw::make (arg).make (av->_m_value, p, whatattr, + other.constant (), arg); } else { typename vw::value_constant_block *p; - vw::make (av->_m_value, p, whatattr, - other.constant_block (), arg); + vw::make (arg).make (av->_m_value, p, whatattr, + other.constant_block (), arg); } break; diff --git a/libdw/c++/dwarf_output b/libdw/c++/dwarf_output index b03dbd483..47e827369 100644 --- a/libdw/c++/dwarf_output +++ b/libdw/c++/dwarf_output @@ -131,128 +131,12 @@ namespace elfutils typedef dwarf_data::value data; -#if 0 - template - static inline void - make (const value_dispatch *&, flavor *&, - int, const input &, const subr::nothing &) - { - throw std::logic_error ("dwarf_output cannot be default-constructed"); - } -#endif - - template - static inline void - make (const value_dispatch *&v, value_string *&, - int, const input &x, copier_type &c) - { - v = c ().add_string (x); - } - - template - static inline void - make (const value_dispatch *&v, value_identifier *&, - int, const input &x, copier_type &c) - { - v = c ().add_identifier (x); - } - - template - static inline void - make (const value_dispatch *&v, value_reference *&, - int, const input &x, copier_type &c) - { - v = c.add_reference (x, &v); - } - - template - static inline void - make (const value_dispatch *&v, value_flag *&, - int, const input &x, copier_type &c) - { - v = c ().add_flag (x); - } - - template - static inline void - make (const value_dispatch *&v, value_address *&, - int, const input &x, copier_type &c) - { - v = c ().add_address (x); - } - - template - static inline void - make (const value_dispatch *&v, value_rangelistptr *&, - int, const input &x, copier_type &c) - { - v = c ().add_ranges (x); - } - - template - static inline void - make (const value_dispatch *&v, value_lineptr *&, - int, const input &x, copier_type &c) - { - v = c ().add_line_info (x); - } - - template - static inline void - make (const value_dispatch *&v, value_constant *&, - int, const input &x, copier_type &c) - { - v = c ().add_constant (x); - } - - template - static inline void - make (const value_dispatch *&v, value_constant_block *&, - int, const input &x, copier_type &c) - { - v = c ().add_constant_block (x); - } - - template - static inline void - make (const value_dispatch *&v, value_dwarf_constant *&, - int, const input &x, copier_type &c) - { - v = c ().add_dwarf_constant (x); - } - - template - static inline void - make (const value_dispatch *&v, value_source_file *&, - int attr, const input &x, copier_type &c) - { - v = c ().add_source_file (attr, x); - } - - template - static inline void - make (const value_dispatch *&v, value_source_line *&, - int, const input &x, copier_type &c) - { - v = c ().add_source_line (x); - } + template struct maker; - template - static inline void - make (const value_dispatch *&v, value_source_column *&, - int, const input &x, copier_type &c) + template + static inline maker make (arg_type &arg) { - v = c ().add_source_column (x); - } - - // XXX macptr - - template - static inline void - make (const value_dispatch *&v, value_location *&, - int, const input &x, copier_type &c) - { - v = c ().add_location (x); + return maker (arg); } // See dwarf_output::copier, below. @@ -754,6 +638,124 @@ namespace elfutils return elfutils::to_string (*this); // Use that. } + template + struct dwarf_output::value::maker + { + inline explicit maker (copier_type &) {} + + template + inline void make (const value_dispatch *&v, value_string *&, + int, const input &x, copier_type &c) + { + v = c ().add_string (x); + } + + template + inline void make (const value_dispatch *&v, value_identifier *&, + int, const input &x, copier_type &c) + { + v = c ().add_identifier (x); + } + + template + inline void make (const value_dispatch *&v, value_reference *&, + int, const input &x, copier_type &c) + { + v = c.add_reference (x, &v); + } + + template + inline void make (const value_dispatch *&v, value_flag *&, + int, const input &x, copier_type &c) + { + v = c ().add_flag (x); + } + + template + inline void make (const value_dispatch *&v, value_address *&, + int, const input &x, copier_type &c) + { + v = c ().add_address (x); + } + + template + inline void make (const value_dispatch *&v, value_rangelistptr *&, + int, const input &x, copier_type &c) + { + v = c ().add_ranges (x); + } + + template + inline void make (const value_dispatch *&v, value_lineptr *&, + int, const input &x, copier_type &c) + { + v = c ().add_line_info (x); + } + + template + inline void make (const value_dispatch *&v, value_constant *&, + int, const input &x, copier_type &c) + { + v = c ().add_constant (x); + } + + template + inline void make (const value_dispatch *&v, value_constant_block *&, + int, const input &x, copier_type &c) + { + v = c ().add_constant_block (x); + } + + template + inline void make (const value_dispatch *&v, value_dwarf_constant *&, + int, const input &x, copier_type &c) + { + v = c ().add_dwarf_constant (x); + } + + template + inline void make (const value_dispatch *&v, value_source_file *&, + int attr, const input &x, copier_type &c) + { + v = c ().add_source_file (attr, x); + } + + template + inline void make (const value_dispatch *&v, value_source_line *&, + int, const input &x, copier_type &c) + { + v = c ().add_source_line (x); + } + + template + inline void make (const value_dispatch *&v, value_source_column *&, + int, const input &x, copier_type &c) + { + v = c ().add_source_column (x); + } + + // XXX macptr + + template + inline void make (const value_dispatch *&v, value_location *&, + int, const input &x, copier_type &c) + { + v = c ().add_location (x); + } + }; + + template<> + struct dwarf_output::value::maker + { + inline explicit maker (subr::nothing &) {} + + template + inline void make (args&&...) + { + throw std::logic_error ("dwarf_output cannot be default-constructed"); + } + }; + struct dwarf_output::die_info { std::queue _m_refs; @@ -799,7 +801,10 @@ namespace elfutils _m_with_sibling[have_sibling] = true; if (_m_refs.empty ()) - self (new value::value_reference (ref, subr::nothing ())); + { + subr::nothing dummy; + self (new value::value_reference (ref, dummy)); + } else for (size_t n = _m_refs.size (); n > 0; --n) { @@ -1409,7 +1414,7 @@ namespace elfutils return this; } -#if 1 +#if 0 static inline std::ostream &debug () { return std::cout; diff --git a/libdw/c++/subr.hh b/libdw/c++/subr.hh index 07233a5e1..de342104c 100644 --- a/libdw/c++/subr.hh +++ b/libdw/c++/subr.hh @@ -873,8 +873,6 @@ namespace elfutils struct nothing { - template - inline void operator () (args&&...) const {} }; // Class instead of function so it can be a friend.