]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Some tracker refactoring.
authorRoland McGrath <roland@redhat.com>
Tue, 7 Jul 2009 10:36:34 +0000 (03:36 -0700)
committerRoland McGrath <roland@redhat.com>
Thu, 9 Jul 2009 06:59:14 +0000 (23:59 -0700)
libdw/c++/dwarf_comparator
libdw/c++/dwarf_data
libdw/c++/dwarf_output
libdw/c++/dwarf_tracker
src/dwarfcmp.cc

index 7465dab52ab20cb3e5120343fe97b8b7d221d835..9bba00586919b04ab354fd7645c63eeeda2a909d 100644 (file)
@@ -173,7 +173,7 @@ namespace elfutils
     : 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>
@@ -491,11 +491,12 @@ namespace elfutils
         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);
@@ -503,12 +504,9 @@ namespace elfutils
       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)
index c49360ce9d2e288e595fb026d131961842c131a5..94c64f981423dc8fc73197a7308ea013613c9ccc 100644 (file)
@@ -115,6 +115,12 @@ namespace elfutils
        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.
index 8fed594030a1cc39ca921a0bcd395d3a2732f34e..b688b38b4883ca5ce8c0ef986830f454972f9345 100644 (file)
@@ -52,6 +52,7 @@
 
 #include "dwarf_edit"
 #include "dwarf_ref_maker"
+#include "dwarf_tracker"
 #include <algorithm>
 #include <functional>
 #include <iterator>
@@ -723,6 +724,8 @@ namespace elfutils
     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;
@@ -798,24 +801,53 @@ namespace elfutils
     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;
     }
 
index 1a442a42fb8106ba2449d3bd7ebdf79023ff4f84..ff20d38005c689a530219b6a645e4dd823e331c4 100644 (file)
@@ -94,13 +94,23 @@ namespace elfutils
 
     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),
@@ -324,6 +334,12 @@ namespace elfutils
   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;
@@ -331,7 +347,7 @@ namespace elfutils
     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;
 
@@ -353,9 +369,11 @@ namespace elfutils
     {
       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 ()));
       }
     };
 
@@ -364,6 +382,11 @@ namespace elfutils
       : _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 ();
@@ -484,8 +507,8 @@ namespace elfutils
     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.
index 6ac78aab489692f95137456d066d707229bb031b..6d3ee0647e023c3ddcaf78e76117e848bf7c81d8 100644 (file)
@@ -212,16 +212,26 @@ struct talker : public dwarf_ref_tracker<dwarf1, dwarf2>
   }
 };
 
+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> >
 {};