return result;
}
+ template<typename die_type>
+ std::string
+ die_string (const die_type &die)
+ {
+ std::string result ("<");
+ result += dwarf::tags::name (die.tag ());
+
+ typename die_type::attributes_type::const_iterator name_attr
+ = die.attributes ().find (::DW_AT_name);
+ if (name_attr != die.attributes ().end ())
+ {
+ result += " ";
+ result += to_string (*name_attr);
+ }
+
+ result += die.has_children () ? ">" : "/>";
+ return result;
+ }
+
};
class const_pointer;
+ inline std::string to_string () const;
+
inline int tag () const
{
int t = ::dwarf_tag (thisdie ());
// Explicit specializations.
template<>
+ std::string
+ to_string<dwarf::debug_info_entry> (const dwarf::debug_info_entry &);
+ inline std::string dwarf::debug_info_entry::to_string () const
+ {
+ return elfutils::to_string (*this); // Use that.
+ }
+ template<>
std::string to_string<dwarf::attribute> (const dwarf::attribute &);
inline std::string dwarf::attribute::to_string () const
{
_m_children (die.children (), t)
{}
+ inline std::string to_string () const;
+
inline int tag () const
{
return _m_tag;
// Explicit specializations.
template<>
+ std::string to_string<dwarf_edit::debug_info_entry>
+ (const dwarf_edit::debug_info_entry &);
+ inline std::string dwarf_edit::debug_info_entry::to_string () const
+ {
+ return elfutils::to_string (*this); // Use that.
+ }
+ template<>
std::string to_string<dwarf_edit::attribute> (const dwarf_edit::attribute &);
template<>
std::string to_string<dwarf_edit::attr_value> (const dwarf_edit::attr_value&);
&& _m_children == that._m_children);
}
+ inline std::string to_string () const;
+
inline int tag () const
{
return _m_tag;
// Explicit specializations.
template<>
+ std::string to_string<dwarf_output::debug_info_entry>
+ (const dwarf_output::debug_info_entry &);
+ inline std::string dwarf_output::debug_info_entry::to_string () const
+ {
+ return elfutils::to_string (*this); // Use that.
+ }
+ template<>
std::string
to_string<dwarf_output::attribute> (const dwarf_output::attribute &);
template<>
private:
dwarf_path_finder<dwarf_output> _m_tracker;
+ unsigned int _m_total;
typedef dwarf_output::debug_info_entry die_type;
typedef die_type::attributes_type attrs_type;
= *_m_unique.insert (std::make_pair (die_type (other, c),
die_info ())).first;
x.second.uses++;
+ ++_m_total;
if (has_sibling)
x.second.with_sibling = true;
else
shape_map _m_shapes;
void add_shape (die_type &die, bool last_sibling);
+
+ public:
+ inline dwarf_output_collector ()
+ : _m_total (0)
+ {}
+
+ static void die_stats (const die_map::value_type &elt)
+ {
+ std::cout << to_string (elt.first) << " uses="
+ << std::dec << elt.second.uses
+ << " (" << elt.second.with_sibling
+ << "," << elt.second.without_sibling << ")\n";
+ }
+
+ void stats () const
+ {
+ std::cout << "collected " << std::dec << _m_unique.size ()
+ << " unique of " << _m_total << " total DIEs\n";
+ std::for_each (_m_unique.begin (), _m_unique.end (), die_stats);
+ }
};
template<typename dw>
return attribute_string (attr);
}
+namespace elfutils
+{
+ template<>
+ std::string to_string (const dwarf_edit::debug_info_entry &die)
+ {
+ return die_string (die);
+ }
+};
+
std::string
dwarf_data::source_file::to_string () const
{
return attribute_string (attr);
}
+namespace elfutils
+{
+ template<>
+ std::string to_string (const dwarf_output::debug_info_entry &die)
+ {
+ return die_string (die);
+ }
+};
+
const dwarf_output::value::value_flag dwarf_output_collector::flag_true (1);
const dwarf_output::value::value_flag dwarf_output_collector::flag_false (0);
return const_vector<uint8_t> (block);
}
+
+namespace elfutils
+{
+ template<>
+ std::string to_string (const dwarf::debug_info_entry &die)
+ {
+ return die_string (die);
+ }
+};
\f
// dwarf::range_list
dwarf_output_collector c1;
dwarf_output_collector c2;
dwarf_output out1 (in1, c1);
+ c1.stats ();
dwarf_output out2 (in2, c2);
+ c2.stats ();
test_classes (file1, file2, out1, out2, same);