: public std::binary_function<dwarf1, dwarf2, bool>
{
private:
- tracker _m_tracker;
+ tracker &_m_tracker;
template<typename item1, typename item2>
struct matcher : public std::binary_function<item1, item2, bool>
new one, in case of any reference attributes in their subtrees.
The new tracker jump-starts its walk to the referenced DIE from
the root of the CU. */
- bool result = !has_children || (dwarf_comparator (tracker (_m_tracker,
- matched,
- lhs, ref1,
- rhs, ref2))
- .match (a.children (), b.children ()));
+ bool result = !has_children;
+ if (has_children)
+ {
+ tracker t (_m_tracker, matched, lhs, ref1, rhs, ref2);
+ result = dwarf_comparator (t).match (a.children (), b.children ());
+ }
// Let the tracker cache a result for its reference_matched.
matched.notice_match (ref2, result);
return result;
}
- inline explicit dwarf_comparator (const tracker &t)
- : _m_tracker (t)
- {}
-
public:
- inline dwarf_comparator ()
+ inline explicit dwarf_comparator (tracker &t)
+ : _m_tracker (t)
{}
inline bool operator () (const dwarf1 &a, const dwarf2 &b)
impl::debug_info_entry::set (die, arg);
}
+ explicit inline compile_unit ()
+ : impl::debug_info_entry ()
+ {
+ this->_m_tag = ::DW_TAG_compile_unit;
+ }
+
public:
// Fetch the CU's DW_AT_stmt_list.
#include "dwarf_edit"
#include "dwarf_ref_maker"
+#include "dwarf_tracker"
#include <algorithm>
#include <functional>
#include <iterator>
friend class dwarf_output;
private:
+ dwarf_path_finder<dwarf_output> _m_tracker;
+
typedef dwarf_output::debug_info_entry die_type;
typedef die_type::children_type::const_iterator die_ptr;
typedef die_type::attributes_type attrs_type;
shape_map _m_shapes;
void add_shape (die_type &die, bool last_sibling);
-
};
- template<class dw>
+ template<typename dw>
class dwarf_output::copier
: public dwarf_ref_maker<dwarf_output, dw> // XXX temporary
{
friend class dwarf_output;
private:
+
+ struct tracker
+ : public dwarf_ref_tracker<dwarf_output, dw>
+ {
+ typedef dwarf_ref_tracker<dwarf_output, dw> _base;
+
+ inline tracker (const dwarf_output_collector &c)
+ : _base (c._m_tracker)
+ {}
+
+ inline tracker (const tracker &proto,
+ typename _base::reference_match &matched,
+ const typename _base::left_context_type &lhs,
+ const typename _base::die1 &a,
+ const typename _base::right_context_type &rhs,
+ const typename _base::die2 &b)
+ : _base (proto, matched, lhs, a, b)
+ {}
+
+ };
+
dwarf_output_collector *_m_collector;
+ tracker *_m_tracker;
inline copier ()
- : _m_collector (NULL)
+ : _m_collector (NULL), _m_tracker (NULL)
{}
+ inline ~copier ()
+ {
+ if (_m_tracker != NULL)
+ delete _m_tracker;
+ }
+
copier &operator () (dwarf_output_collector &c)
{
_m_collector = &c;
+ assert (_m_tracker == NULL);
+ _m_tracker = new tracker (c);
return *this;
}
die_path _m_path;
+ explicit dwarf_path_finder (const dwarf_path_finder &)
+ {
+ throw std::logic_error ("not copy-constructible");
+ }
+
public:
// Default constructor: an original tracker.
inline dwarf_path_finder ()
: _m_seen (new die_map), _m_delete_seen (true)
{}
- // Construct a derived tracker: does its own walk, but sharing caches.
+ // Construct a derived tracker: does its own whole walk, but sharing caches.
+ inline dwarf_path_finder (const dwarf_path_finder &proto, bool)
+ : _m_seen (proto._m_seen), _m_delete_seen (false)
+ {}
+
+ // Construct a derived tracker that jump-starts a walk.
inline dwarf_path_finder (const dwarf_path_finder &proto,
const die_path &context, const die &there)
: _m_seen (proto._m_seen), _m_delete_seen (false),
private:
typedef dwarf_tracker_base<dwarf1, dwarf2> _base;
+ explicit dwarf_ref_tracker (const dwarf_ref_tracker &)
+ : _base ()
+ {
+ throw std::logic_error ("not copy-constructible");
+ }
+
public:
typedef typename _base::cu1 cu1;
typedef typename _base::cu2 cu2;
typedef typename _base::die2 die2;
typedef typename _base::dwarf1_ref dwarf1_ref;
- private:
+ protected:
typedef dwarf_path_finder<dwarf1> tracker1;
typedef dwarf_path_finder<dwarf2> tracker2;
{
inline bool operator () (const die1 &a, const die2 &b)
{
- return (a->tag () == b->tag ()
- && (dwarf_comparator<dwarf1, dwarf2, true> ()
- .equals (a->attributes (), b->attributes ())));
+ if (a->tag () != b->tag ())
+ return false;
+ dwarf_tracker_base<dwarf1, dwarf2> t;
+ return (dwarf_comparator<dwarf1, dwarf2, true> (t)
+ .equals (a->attributes (), b->attributes ()));
}
};
: _m_equiv (new equiv_map), _m_delete_equiv (true)
{}
+ inline dwarf_ref_tracker (const tracker1 &proto)
+ : _m_left (proto, true),
+ _m_equiv (new equiv_map), _m_delete_equiv (true)
+ {}
+
inline void reset ()
{
_m_equiv->clear ();
inline dwarf_ref_tracker (const dwarf_ref_tracker &proto, reference_match &,
const left_context_type &lhs, const die1 &a,
const right_context_type &rhs, const die2 &b)
- : _m_left (tracker1 (proto._m_left, lhs, a)),
- _m_right (tracker2 (proto._m_right, rhs, b)),
+ : _m_left (proto._m_left, lhs, a),
+ _m_right (proto._m_right, rhs, b),
_m_equiv (proto._m_equiv), _m_delete_equiv (false)
{
// We are starting a recursive consideration of a vs b.
}
};
+template<class dwarf1, class dwarf2, class tracker>
+struct cmp
+ : public dwarf_comparator<dwarf1, dwarf2, false, tracker>
+{
+ tracker _m_tracker;
+ inline cmp ()
+ : dwarf_comparator<dwarf1, dwarf2, false, tracker> (_m_tracker)
+ {}
+};
+
// For a silent comparison we just use the standard ref tracker.
template<class dwarf1, class dwarf2>
-struct quiet_cmp : public dwarf_comparator<dwarf1, dwarf2, false,
- dwarf_ref_tracker<dwarf1, dwarf2> >
+struct quiet_cmp
+ : public cmp<dwarf1, dwarf2, dwarf_ref_tracker<dwarf1, dwarf2> >
{};
// To be noisy, the talker wraps the standard tracker with verbosity hooks.
template<class dwarf1, class dwarf2>
-struct noisy_cmp : public dwarf_comparator<dwarf1, dwarf2, false,
- talker<dwarf1, dwarf2> >
+struct noisy_cmp
+ : public cmp<dwarf1, dwarf2, talker<dwarf1, dwarf2> >
{};