typedef std::pair<directory_table, line_table> _base;
public:
- struct hasher
- : public std::unary_function<line_info_table, size_t>
- {
- 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<typename table>
{
size_t operator () (const dwarf_enum &v) const
{
- return v.first;
+ return subr::hash_this<_base> (v);
}
};
};
public:
- template<typename impl>
+ template<typename impl, bool alloc_values = true>
struct value
{
struct value_dispatch
virtual ~value_dispatch () {}
};
+ typedef value_dispatch value_cell_type;
+
+ static const bool delete_value = alloc_values;
+
template<typename flavor, typename input, typename arg_type>
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<std::string> hasher;
+
inline value_string () {}
template<typename string, typename arg_type>
: std::string (s)
{}
+ template<typename string>
+ inline value_string (const string &s)
+ : std::string (s)
+ {}
+
std::string to_string () const
{
std::string result ("\"");
inline value_identifier (const id &s, arg_type &arg)
: value_string (s, arg)
{}
+
+ template<typename id>
+ inline value_identifier (const id &s)
+ : value_string (s)
+ {}
};
struct value_reference : public value_dispatch
{
bool flag;
- inline value_flag ()
- : flag (true)
+ inline value_flag (bool t = true)
+ : flag (t)
{}
template<typename arg_type>
// XXX dwfl, reloc
::Dwarf_Addr addr;
- inline value_address ()
- : addr (0)
+ inline value_address (::Dwarf_Addr x = 0)
+ : addr (x)
{}
template<typename arg_type>
inline value_address (::Dwarf_Addr x, arg_type &)
: addr (x)
{}
+
+ struct hasher : public std::unary_function<value_address, size_t>
+ {
+ 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
inline value_rangelistptr (const list &other, arg_type &)
: range_list (other)
{}
+
+ template<typename list>
+ inline value_rangelistptr (const list &other)
+ : range_list (other)
+ {}
};
struct value_lineptr : public value_dispatch, public impl::line_info_table
::Dwarf_Sword sword;
};
- inline value_constant ()
- : word (0)
+ inline value_constant (::Dwarf_Word value = 0)
+ : word (value)
{}
template<typename arg_type>
inline value_constant (::Dwarf_Word x, arg_type &)
: word (x)
{}
+
+ struct hasher : public std::unary_function<value_constant, size_t>
+ {
+ 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<uint8_t>
{
+ typedef subr::hash<std::vector<uint8_t> > hasher;
+
inline value_constant_block () {}
template<typename block, typename arg_type>
inline value_constant_block (const block &b, arg_type &)
: std::vector<uint8_t> (b.begin (), b.end ())
{}
+
+ template<typename block>
+ inline value_constant_block (const block &b)
+ : std::vector<uint8_t> (b.begin (), b.end ())
+ {}
};
struct value_dwarf_constant : public value_dispatch, public dwarf_enum
{
inline value_dwarf_constant () {}
+ template<typename constant>
+ inline value_dwarf_constant (const constant &other)
+ : dwarf_enum (other)
+ {}
+
template<typename constant, typename arg_type>
inline value_dwarf_constant (const constant &other, arg_type &)
: dwarf_enum (other)
inline value_source_file (const file &other, arg_type &)
: source_file (other)
{}
+
+ template<typename file>
+ 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<typename arg_type>
inline value_source_line (unsigned int m, arg_type &)
: n (m)
{}
+
+ struct hasher : public std::unary_function<value_source_line, size_t>
+ {
+ 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 {};
friend class attributes_type<impl, vw>;
private:
- typename vw::value_dispatch *_m_value;
+ 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 flavor>
- inline flavor &variant () const
+ inline const flavor &variant () const
{
- return const_variant<flavor> ();
+ return const_variant<const flavor> ();
}
template<typename flavor>
~attr_value ()
{
- if (_m_value != NULL)
+ if (vw::delete_value && _m_value != NULL)
delete _m_value;
}
dwarf::value_space what_space () const;
inline std::string to_string () const;
- inline bool &flag () const
+ inline const bool &flag () const
{
return variant<typename vw::value_flag> ().flag;
}
}
// XXX dwfl, reloc
- inline ::Dwarf_Addr &address () const
+ inline const ::Dwarf_Addr &address () const
{
return variant<typename vw::value_address> ().addr;
}
return variant<typename vw::value_address> ().addr;
}
- inline die_ptr &reference () const
+ inline const die_ptr &reference () const
{
return variant<typename vw::value_reference> ().ref;
}
return variant<typename vw::value_reference> ().ref;
}
- inline location_attr &location () const
+ inline const location_attr &location () const
{
- return static_cast<location_attr &>
+ return static_cast<const location_attr &>
(variant<typename vw::value_location> ());
}
inline const typename impl::source_file &source_file () const
{
- return static_cast<typename impl::source_file &>
+ return static_cast<const typename impl::source_file &>
(variant<typename vw::value_source_file> ());
}
inline const std::vector<uint8_t> &constant_block () const
{
- return static_cast<std::vector<uint8_t> &>
+ return static_cast<const std::vector<uint8_t> &>
(variant<typename vw::value_constant_block> ());
}
inline bool constant_is_integer () const
{
- return dynamic_cast<typename vw::value_constant *> (_m_value) != NULL;
+ return (dynamic_cast<const typename vw::value_constant *> (_m_value)
+ != NULL);
}
inline const typename impl::range_list &ranges () const
{
- return static_cast<range_list &>
- (variant<typename vw::value_rangelistptr> ());
+ return static_cast<const range_list &>
+ (variant<const typename vw::value_rangelistptr> ());
}
inline typename impl::range_list &ranges ()
inline const typename impl::line_info_table &line_info () const
{
- return static_cast<typename impl::line_info_table &>
- (variant<typename vw::value_lineptr> ());
+ return static_cast<const typename impl::line_info_table &>
+ (variant<const typename vw::value_lineptr> ());
}
inline typename impl::line_info_table &line_info ()
class dwarf_output
{
+ friend class dwarf_output_collector;
+
public:
typedef dwarf_data::source_file source_file;
typedef dwarf_data::directory_table directory_table;
protected:
template<typename input> class copier; // Below.
- template<typename input>
- 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). */
return subr::argifier<input, output, dwarf_output_collector &> (c) (in);
}
- struct value_wrapper
- : public dwarf_data::value<dwarf_output>
+ struct value
+ : public dwarf_data::value<dwarf_output, false>
{
- struct value_string : public value_dispatch
- {
- const std::string &_m_str;
+ typedef const value_dispatch value_cell_type;
- template<typename string, typename input>
- inline value_string (const string &s, dwarf_output::copier<input> &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<dwarf_output> data;
template<typename flavor, typename input>
static inline value_dispatch *
throw std::logic_error ("dwarf_output cannot be default-constructed");
}
- template<typename flavor, typename input, typename arg_type>
+ // XXX temporary
+ template<typename flavor, typename input, typename input_dw>
static inline value_dispatch *
- make (flavor *&result, const input &x, arg_type &arg)
+ make (flavor *&result, const input &x, copier<input_dw> &c)
{
- return result = new flavor (x, arg);
+ return result = new flavor (x, c);
}
- template<typename input>
- static inline value_dispatch *
- make (value_string *&result, const input &x, dwarf_output_collector &c)
+ template<typename input, typename input_dw>
+ static inline const value_dispatch *
+ make (value_string *&, const input &x, copier<input_dw> &c)
+ {
+ return c.add_string (x);
+ }
+
+ template<typename input, typename input_dw>
+ static inline const value_dispatch *
+ make (value_identifier *&, const input &x, copier<input_dw> &c)
+ {
+ return c.add_identifier (x);
+ }
+
+ // XXX reference
+
+ template<typename input, typename input_dw>
+ static inline const value_dispatch *
+ make (value_flag *&, const input &x, copier<input_dw> &c)
+ {
+ return c.add_flag (x);
+ }
+
+ template<typename input, typename input_dw>
+ static inline const value_dispatch *
+ make (value_address *&, const input &x, copier<input_dw> &c)
+ {
+ return c.add_address (x);
+ }
+
+ template<typename input, typename input_dw>
+ static inline const value_dispatch *
+ make (value_rangelistptr *&, const input &x, copier<input_dw> &c)
+ {
+ return c.add_ranges (x);
+ }
+
+ /* XXX lineptr
+ template<typename input, typename input_dw>
+ static inline const value_dispatch *
+ make (value_lineptr *&, const input &x, copier<input_dw> &c)
+ {
+ return c.add_line_info (x);
+ }
+ */
+
+ template<typename input, typename input_dw>
+ static inline const value_dispatch *
+ make (value_constant *&, const input &x, copier<input_dw> &c)
+ {
+ return c.add_constant (x);
+ }
+
+ template<typename input, typename input_dw>
+ static inline const value_dispatch *
+ make (value_constant_block *&, const input &x, copier<input_dw> &c)
+ {
+ return c.add_constant_block (x);
+ }
+
+ template<typename input, typename input_dw>
+ static inline const value_dispatch *
+ make (value_dwarf_constant *&, const input &x, copier<input_dw> &c)
{
- return result = new value_string (x, c);
+ return c.add_dwarf_constant (x);
}
+ template<typename input, typename input_dw>
+ static inline const value_dispatch *
+ make (value_source_file *&, const input &x, copier<input_dw> &c)
+ {
+ return c.add_source_file (x);
+ }
+
+ template<typename input, typename input_dw>
+ static inline const value_dispatch *
+ make (value_source_line *&, const input &x, copier<input_dw> &c)
+ {
+ return c.add_source_line (x);
+ }
+
+ template<typename input, typename input_dw>
+ static inline const value_dispatch *
+ make (value_source_column *&, const input &x, copier<input_dw> &c)
+ {
+ return c.add_source_column (x);
+ }
+
+ // XXX macptr
+ // XXX location
};
public:
- typedef dwarf_data::attr_value<dwarf_output, value_wrapper> attr_value;
+ typedef dwarf_data::attr_value<dwarf_output, value> attr_value;
class debug_info_entry
{
friend class subr::create_container;
public:
- typedef dwarf_data::attributes_type<dwarf_output,
- value_wrapper> attributes_type;
+ typedef dwarf_data::attributes_type<dwarf_output, value> attributes_type;
class children_type : public std::list<debug_info_entry>
{
friend class dwarf_output;
private:
- subr::value_set<std::string> _m_strings;
- subr::value_set<dwarf_output::range_list> _m_ranges;
-
- public:
-
+ subr::value_set<dwarf_output::value::value_string> _m_strings;
+ subr::value_set<dwarf_output::value::value_identifier> _m_identifiers;
+ subr::value_set<dwarf_output::value::value_address> _m_address;
+ subr::value_set<dwarf_output::value::value_rangelistptr> _m_ranges;
+ subr::value_set<dwarf_output::value::value_constant> _m_constants;
+ subr::value_set<dwarf_output::value::value_constant_block> _m_const_block;
+ subr::value_set<dwarf_output::value::value_dwarf_constant> _m_dwarf_const;
+ subr::value_set<dwarf_output::value::value_source_file> _m_source_file;
+ subr::value_set<dwarf_output::value::value_source_line> _m_source_line;
+ subr::value_set<dwarf_output::value::value_source_column> _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<class input>
+ template<class dw>
class dwarf_output::copier
- : public dwarf_ref_maker<dwarf_output, input> // XXX temporary
+ : public dwarf_ref_maker<dwarf_output, dw> // XXX temporary
{
friend class dwarf_output;
private:
{
return *_m_collector;
}
+
+ template<typename input>
+ inline const value::value_string *add_string (const input &x)
+ {
+ return _m_collector->_m_strings.add (x);
+ }
+
+ template<typename input>
+ inline const value::value_string *add_identifier (const input &x)
+ {
+ return _m_collector->_m_identifiers.add (x);
+ }
+
+ template<typename input>
+ inline const value::value_flag *add_flag (const input &x)
+ {
+ return dwarf_output_collector::flag (x);
+ }
+
+ template<typename input>
+ inline const value::value_address *add_address (const input &x)
+ {
+ return _m_collector->_m_address.add (x);
+ }
+
+ template<typename input>
+ inline const value::value_rangelistptr *add_ranges (const input &x)
+ {
+ return _m_collector->_m_ranges.add (x);
+ }
+
+ template<typename input>
+ inline const value::value_constant *add_constant (const input &x)
+ {
+ return _m_collector->_m_constants.add (x);
+ }
+
+ template<typename input>
+ inline const value::value_constant_block *
+ add_constant_block (const input &x)
+ {
+ return _m_collector->_m_const_block.add (x);
+ }
+
+ template<typename input>
+ inline const value::value_dwarf_constant *
+ add_dwarf_constant (const input &x)
+ {
+ return _m_collector->_m_dwarf_const.add (x);
+ }
+
+ template<typename input>
+ inline const value::value_source_file *add_source_file (const input &x)
+ {
+ return _m_collector->_m_source_file.add (x);
+ }
+
+ template<typename input>
+ inline const value::value_source_line *add_source_line (const input &x)
+ {
+ return _m_collector->_m_source_line.add (x);
+ }
+
+ template<typename input>
+ 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.
copier<input> maker)
: _m_units (dw.compile_units (), maker (c))
{}
-
- template<typename input>
- inline const std::string &
- dwarf_output::collect_string (dwarf_output_collector &c, const input &s)
- {
- return c._m_strings.add (s);
- }
-
};
#endif // <elfutils/dwarf_output>