#include "dwarf_data"
-#include <typeinfo>
+template<typename v, typename subtype>
+static inline bool is_a (const typename v::value_dispatch *value)
+{
+ return dynamic_cast<const subtype *> (value) != NULL;
+}
namespace elfutils
{
dwarf::value_space
dwarf_data::attr_value<impl, v>::what_space () const
{
- if (typeid (*_m_value) == typeid (typename v::value_flag))
+ if (is_a<v, typename v::value_flag> (_m_value))
return dwarf::VS_flag;
- if (typeid (*_m_value) == typeid (typename v::value_dwarf_constant))
+ if (is_a<v, typename v::value_dwarf_constant> (_m_value))
return dwarf::VS_dwarf_constant;
- if (typeid (*_m_value) == typeid (typename v::value_reference))
+ if (is_a<v, typename v::value_reference> (_m_value))
return dwarf::VS_reference;
- if (typeid (*_m_value) == typeid (typename v::value_lineptr))
+ if (is_a<v, typename v::value_lineptr> (_m_value))
return dwarf::VS_lineptr;
- if (typeid (*_m_value) == typeid (typename v::value_macptr))
+ if (is_a<v, typename v::value_macptr> (_m_value))
return dwarf::VS_macptr;
- if (typeid (*_m_value) == typeid (typename v::value_rangelistptr))
+ if (is_a<v, typename v::value_rangelistptr> (_m_value))
return dwarf::VS_rangelistptr;
- if (typeid (*_m_value) == typeid (typename v::value_identifier))
+ if (is_a<v, typename v::value_identifier> (_m_value))
return dwarf::VS_identifier;
- if (typeid (*_m_value) == typeid (typename v::value_string))
+ if (is_a<v, typename v::value_string> (_m_value))
return dwarf::VS_string;
- if (typeid (*_m_value) == typeid (typename v::value_source_file))
+ if (is_a<v, typename v::value_source_file> (_m_value))
return dwarf::VS_source_file;
- if (typeid (*_m_value) == typeid (typename v::value_source_line))
+ if (is_a<v, typename v::value_source_line> (_m_value))
return dwarf::VS_source_line;
- if (typeid (*_m_value) == typeid (typename v::value_source_column))
+ if (is_a<v, typename v::value_source_column> (_m_value))
return dwarf::VS_source_column;
- if (typeid (*_m_value) == typeid (typename v::value_address))
+ if (is_a<v, typename v::value_address> (_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<v, typename v::value_constant> (_m_value)
+ || is_a<v, typename v::value_constant_block> (_m_value))
return dwarf::VS_constant;
- if (typeid (*_m_value) == typeid (typename v::value_location))
+ if (is_a<v, typename v::value_location> (_m_value))
return dwarf::VS_location;
- throw std::runtime_error ("XXX impossible");
+ throw std::logic_error ("attr_value has no known value_space!");
}
template<typename attr_pair>
return *result;
}
- template<typename flavor, typename input, typename arg_type>
- static inline void
- make (value_dispatch *&v, flavor *&result,
- int /*whatattr*/, const input &x, arg_type &arg)
+ template<typename arg_type>
+ struct maker
{
- assert (alloc_values);
- v = result = new flavor (x, arg);
+ inline explicit maker (const arg_type &) {}
+
+ template<typename flavor, typename input>
+ 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<typename arg_type>
+ static inline maker<arg_type> make (arg_type &arg)
+ {
+ return maker<arg_type> (arg);
}
struct value_string : public value_dispatch, public std::string
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)
{}
typename vw::value_cell_type *_m_value;
typedef typename impl::debug_info_entry::pointer die_ptr;
- template<typename value, typename arg_type = const subr::nothing>
+ template<typename value, typename arg_type = subr::nothing>
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 ())
{
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
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;
typedef dwarf_data::value<dwarf_output> data;
-#if 0
- template<typename flavor, typename input>
- 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<typename input, typename copier_type>
- static inline void
- make (const value_dispatch *&v, value_string *&,
- int, const input &x, copier_type &c)
- {
- v = c ().add_string (x);
- }
-
- template<typename input, typename copier_type>
- static inline void
- make (const value_dispatch *&v, value_identifier *&,
- int, const input &x, copier_type &c)
- {
- v = c ().add_identifier (x);
- }
-
- template<typename input, typename copier_type>
- static inline void
- make (const value_dispatch *&v, value_reference *&,
- int, const input &x, copier_type &c)
- {
- v = c.add_reference (x, &v);
- }
-
- template<typename input, typename copier_type>
- static inline void
- make (const value_dispatch *&v, value_flag *&,
- int, const input &x, copier_type &c)
- {
- v = c ().add_flag (x);
- }
-
- template<typename input, typename copier_type>
- static inline void
- make (const value_dispatch *&v, value_address *&,
- int, const input &x, copier_type &c)
- {
- v = c ().add_address (x);
- }
-
- template<typename input, typename copier_type>
- static inline void
- make (const value_dispatch *&v, value_rangelistptr *&,
- int, const input &x, copier_type &c)
- {
- v = c ().add_ranges (x);
- }
-
- template<typename input, typename copier_type>
- static inline void
- make (const value_dispatch *&v, value_lineptr *&,
- int, const input &x, copier_type &c)
- {
- v = c ().add_line_info (x);
- }
-
- template<typename input, typename copier_type>
- static inline void
- make (const value_dispatch *&v, value_constant *&,
- int, const input &x, copier_type &c)
- {
- v = c ().add_constant (x);
- }
-
- template<typename input, typename copier_type>
- 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<typename input, typename copier_type>
- 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<typename input, typename copier_type>
- 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<typename input, typename copier_type>
- 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<typename copier_type> struct maker;
- template<typename input, typename copier_type>
- static inline void
- make (const value_dispatch *&v, value_source_column *&,
- int, const input &x, copier_type &c)
+ template<typename arg_type>
+ static inline maker<arg_type> make (arg_type &arg)
{
- v = c ().add_source_column (x);
- }
-
- // XXX macptr
-
- template<typename input, typename copier_type>
- 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_type> (arg);
}
// See dwarf_output::copier, below.
return elfutils::to_string (*this); // Use that.
}
+ template<typename copier_type>
+ struct dwarf_output::value::maker
+ {
+ inline explicit maker (copier_type &) {}
+
+ template<typename input>
+ inline void make (const value_dispatch *&v, value_string *&,
+ int, const input &x, copier_type &c)
+ {
+ v = c ().add_string (x);
+ }
+
+ template<typename input>
+ inline void make (const value_dispatch *&v, value_identifier *&,
+ int, const input &x, copier_type &c)
+ {
+ v = c ().add_identifier (x);
+ }
+
+ template<typename input>
+ inline void make (const value_dispatch *&v, value_reference *&,
+ int, const input &x, copier_type &c)
+ {
+ v = c.add_reference (x, &v);
+ }
+
+ template<typename input>
+ inline void make (const value_dispatch *&v, value_flag *&,
+ int, const input &x, copier_type &c)
+ {
+ v = c ().add_flag (x);
+ }
+
+ template<typename input>
+ inline void make (const value_dispatch *&v, value_address *&,
+ int, const input &x, copier_type &c)
+ {
+ v = c ().add_address (x);
+ }
+
+ template<typename input>
+ inline void make (const value_dispatch *&v, value_rangelistptr *&,
+ int, const input &x, copier_type &c)
+ {
+ v = c ().add_ranges (x);
+ }
+
+ template<typename input>
+ inline void make (const value_dispatch *&v, value_lineptr *&,
+ int, const input &x, copier_type &c)
+ {
+ v = c ().add_line_info (x);
+ }
+
+ template<typename input>
+ inline void make (const value_dispatch *&v, value_constant *&,
+ int, const input &x, copier_type &c)
+ {
+ v = c ().add_constant (x);
+ }
+
+ template<typename input>
+ inline void make (const value_dispatch *&v, value_constant_block *&,
+ int, const input &x, copier_type &c)
+ {
+ v = c ().add_constant_block (x);
+ }
+
+ template<typename input>
+ inline void make (const value_dispatch *&v, value_dwarf_constant *&,
+ int, const input &x, copier_type &c)
+ {
+ v = c ().add_dwarf_constant (x);
+ }
+
+ template<typename input>
+ 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<typename input>
+ inline void make (const value_dispatch *&v, value_source_line *&,
+ int, const input &x, copier_type &c)
+ {
+ v = c ().add_source_line (x);
+ }
+
+ template<typename input>
+ 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<typename input>
+ 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<subr::nothing>
+ {
+ inline explicit maker (subr::nothing &) {}
+
+ template<typename... args>
+ inline void make (args&&...)
+ {
+ throw std::logic_error ("dwarf_output cannot be default-constructed");
+ }
+ };
+
struct dwarf_output::die_info
{
std::queue<value::value_reference *> _m_refs;
_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)
{
return this;
}
-#if 1
+#if 0
static inline std::ostream &debug ()
{
return std::cout;