]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
plausible crack at first value_set attr_value flavor
authorRoland McGrath <roland@redhat.com>
Tue, 30 Jun 2009 02:17:03 +0000 (19:17 -0700)
committerRoland McGrath <roland@redhat.com>
Tue, 30 Jun 2009 02:17:03 +0000 (19:17 -0700)
libdw/c++/data-values.hh
libdw/c++/dwarf_data
libdw/c++/dwarf_edit
libdw/c++/dwarf_output
libdw/c++/edit-values.cc
libdw/c++/output-values.cc
libdw/c++/subr.hh

index 246ec755fe5395c486fb6e7af900cd358d87eb42..ec1e5455f6bf87dea68783d9b7feff3db31cfb7f 100644 (file)
@@ -54,9 +54,9 @@
 namespace elfutils
 {
 
-  template<class impl, typename arg>
+  template<class impl, typename arg, typename v>
   dwarf::value_space
-  dwarf_data::attr_value<impl, arg>::what_space () const
+  dwarf_data::attr_value<impl, arg, v>::what_space () const
   {
     if (typeid (*_m_value) == typeid (typename v::value_flag))
       return dwarf::VS_flag;
index de2a2b78eca0e72eabd10cd667f5dada632ddf0a..459dab41410def985993aaa76960bcb37f17082b 100644 (file)
@@ -651,15 +651,15 @@ namespace elfutils
   public:
     struct nothing {};
 
+    class value_dispatch
+    {
+    public:
+      virtual ~value_dispatch () {}
+    };
+
     template<typename impl, typename constructor_arg_type>
     struct value
     {
-      class value_dispatch
-      {
-      public:
-       virtual ~value_dispatch () {}
-      };
-
       struct value_string : public value_dispatch, public std::string
       {
        template<typename string>
@@ -809,13 +809,14 @@ namespace elfutils
       };
     };
 
-    template<class impl, typename constructor_arg_type = nothing>
+    template<class impl,
+            typename constructor_arg_type = nothing,
+            typename vw = value<impl, constructor_arg_type>
+            >
     class attr_value
     {
     private:
-      typedef value<impl, constructor_arg_type> v;
-
-      typename v::value_dispatch *_m_value;
+      value_dispatch *_m_value;
 
       template<typename value>
       inline void init (const value &other,
@@ -825,63 +826,63 @@ namespace elfutils
        switch (other.what_space ())
          {
          case dwarf::VS_identifier:
-           _m_value = new typename v::value_identifier (other.identifier (),
-                                                        arg);
+           _m_value = new typename vw::value_identifier (other.identifier (),
+                                                         arg);
            break;
          case dwarf::VS_string:
-           _m_value = new typename v::value_string (other.string (), arg);
+           _m_value = new typename vw::value_string (other.string (), arg);
            break;
          case dwarf::VS_flag:
-           _m_value = new typename v::value_flag (other.flag (), arg);
+           _m_value = new typename vw::value_flag (other.flag (), arg);
            break;
          case dwarf::VS_rangelistptr:
-           _m_value = new typename v::value_rangelistptr (other.ranges (),
-                                                          arg);
+           _m_value = new typename vw::value_rangelistptr (other.ranges (),
+                                                           arg);
            break;
          case dwarf::VS_lineptr:
-           _m_value = new typename v::value_lineptr (other.line_info (), arg);
+           _m_value = new typename vw::value_lineptr (other.line_info (), arg);
            break;
          case dwarf::VS_address:
-           _m_value = new typename v::value_address (other.address (), arg);
+           _m_value = new typename vw::value_address (other.address (), arg);
            break;
          case dwarf::VS_constant:
            if (other.constant_is_integer ())
-             _m_value = new typename v::value_constant (other.constant (),
-                                                        arg);
+             _m_value = new typename vw::value_constant (other.constant (),
+                                                         arg);
            else
-             _m_value = new typename v::value_constant_block
+             _m_value = new typename vw::value_constant_block
                (other.constant_block (), arg);
            break;
          case dwarf::VS_source_line:
-           _m_value = new typename v::value_source_line (other.source_line (),
-                                                         arg);
+           _m_value = new typename vw::value_source_line (other.source_line (),
+                                                          arg);
            break;
          case dwarf::VS_source_column:
-           _m_value = new typename v::value_source_column
+           _m_value = new typename vw::value_source_column
              (other.source_column (), arg);
            break;
          case dwarf::VS_source_file:
-           _m_value = new typename v::value_source_file (other.source_file (),
-                                                         arg);
+           _m_value = new typename vw::value_source_file (other.source_file (),
+                                                          arg);
            break;
          case dwarf::VS_dwarf_constant:
-           _m_value = new typename v::value_dwarf_constant
+           _m_value = new typename vw::value_dwarf_constant
              (other.dwarf_constant (), arg);
            break;
          case dwarf::VS_reference:
-           _m_value = new typename v::value_reference (other.reference (),
-                                                       arg);
+           _m_value = new typename vw::value_reference (other.reference (),
+                                                        arg);
            break;
          case dwarf::VS_unit_reference:
-           _m_value = new typename v::value_unit_reference
+           _m_value = new typename vw::value_unit_reference
              (other.unit_reference (), arg);
            break;
          case dwarf::VS_location:
-           _m_value = new typename v::value_location (other.location (), arg);
+           _m_value = new typename vw::value_location (other.location (), arg);
            break;
 #if 0
          case dwarf::VS_macptr:
-           _m_value = new typename v::value_macptr (other.macptr (), arg);
+           _m_value = new typename vw::value_macptr (other.macptr (), arg);
            break;
 #endif
          default:
@@ -912,13 +913,6 @@ namespace elfutils
        init (other, arg);
       }
 
-      template<typename value>
-      attr_value (const value &other)
-       : _m_value (NULL)
-      {
-       init (other, constructor_arg_type ()); // XXX
-      }
-
       inline attr_value ()
        : _m_value (NULL)
       {}
@@ -956,38 +950,38 @@ namespace elfutils
 
       inline bool &flag () const
       {
-       return variant<typename v::value_flag> ().flag;
+       return variant<typename vw::value_flag> ().flag;
       }
 
       // XXX dwfl, reloc
       inline ::Dwarf_Addr &address () const
       {
-       return variant<typename v::value_address> ().addr;
+       return variant<typename vw::value_address> ().addr;
       }
 
       inline typename impl::debug_info_entry::children_type::iterator
       reference () const
       {
-       return variant<typename v::value_reference> ().ref;
+       return variant<typename vw::value_reference> ().ref;
       }
       inline typename impl::compile_units::iterator
       unit_reference () const
       {
-       return variant<typename v::value_unit_reference> ().ref;
+       return variant<typename vw::value_unit_reference> ().ref;
       }
 
       inline location_attr &location () const
       {
        return static_cast<location_attr &>
-         (variant<typename v::value_location> ());
+         (variant<typename vw::value_location> ());
       }
 
-      inline std::string &string () const
+      inline const std::string &string () const
       {
-       return static_cast<std::string &>
-         (variant<typename v::value_string> ());
+       return static_cast<const std::string &>
+         (variant<typename vw::value_string> ());
       }
-      inline std::string &identifier () const
+      inline const std::string &identifier () const
       {
        return string ();
       }
@@ -995,55 +989,55 @@ namespace elfutils
       inline typename impl::source_file &source_file () const
       {
        return static_cast<typename impl::source_file &>
-         (variant<typename v::value_source_file> ());
+         (variant<typename vw::value_source_file> ());
       }
 
       inline unsigned int &source_line () const
       {
-       return variant<typename v::value_source_line> ().n;
+       return variant<typename vw::value_source_line> ().n;
       }
 
       inline unsigned int &source_column () const
       {
-       return variant<typename v::value_source_column> ().n;
+       return variant<typename vw::value_source_column> ().n;
       }
 
       inline ::Dwarf_Word &constant () const
       {
-       return variant<typename v::value_constant> ().word;
+       return variant<typename vw::value_constant> ().word;
       }
 
       inline ::Dwarf_Sword &signed_constant () const
       {
-       return variant<typename v::value_constant> ().sword;
+       return variant<typename vw::value_constant> ().sword;
       }
 
       inline std::vector<uint8_t> &constant_block () const
       {
        return static_cast<std::vector<uint8_t> &>
-         (variant<typename v::value_constant_block> ());
+         (variant<typename vw::value_constant_block> ());
       }
 
       inline typename impl::dwarf_enum &dwarf_constant () const
       {
-       return variant<typename v::value_dwarf_constant> ();
+       return variant<typename vw::value_dwarf_constant> ();
       }
 
       inline bool constant_is_integer () const
       {
-       return dynamic_cast<typename v::value_constant *> (_m_value) != NULL;
+       return dynamic_cast<typename vw::value_constant *> (_m_value) != NULL;
       }
 
       inline typename impl::range_list &ranges () const
       {
        return static_cast<range_list &>
-         (variant<typename v::value_rangelistptr> ());
+         (variant<typename vw::value_rangelistptr> ());
       }
 
       inline typename impl::line_info_table &line_info () const
       {
        return static_cast<typename impl::line_info_table &>
-         (variant<typename v::value_lineptr> ());
+         (variant<typename vw::value_lineptr> ());
       }
 
       // macptr
@@ -1104,6 +1098,126 @@ namespace elfutils
       }
     };
 
+    template<class dwarf_output, typename constructor_arg_type = nothing>
+    struct constructor_arg_adapter
+    {
+      template<typename input, typename output>
+      struct make_any
+       : public std::binary_function<typename input::value_type,
+                                     constructor_arg_type,
+                                     typename output::value_type>
+      {
+       inline typename output::value_type
+       operator () (const typename input::value_type &x,
+                    const constructor_arg_type &c) const
+       {
+         return typename output::value_type (x, c);
+       }
+      };
+
+      template<typename input, typename output>
+      struct make_attribute
+       : public std::binary_function<typename input::value_type,
+                                     constructor_arg_type,
+                                     typename output::value_type>
+      {
+       inline typename output::value_type
+       operator () (const typename input::value_type &x,
+                    const constructor_arg_type &c) const
+       {
+         return std::make_pair
+           (x.first, typename output::value_type::second_type (x.second, c));
+       }
+      };
+
+      /* 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).  */
+      template<typename input, typename output,
+              typename make_outlet = make_any<input, output> >
+      struct argify
+       : public std::unary_function<typename input::const_iterator,
+                                    typename output::iterator>
+      {
+       typedef typename input::const_iterator inny;
+       typedef typename output::iterator outty;
+       typedef typename input::value_type inlet;
+       typedef typename output::value_type outlet;
+
+       /* Wrapper worker passed to wrapped_input_iterator.
+          This object holds the collector pointer.  */
+       struct maker
+         : public std::unary_function<inlet, outlet>
+       {
+         constructor_arg_type _m_arg;
+         explicit inline maker (const constructor_arg_type &c) : _m_arg (c) {}
+
+         inline outlet operator () (const inlet &x) const
+         {
+           return make_outlet () (x, _m_arg);
+         }
+       } _m_maker;
+
+       explicit inline argify (const constructor_arg_type &c)
+         : _m_maker (c)
+       {}
+
+       typedef subr::wrapped_input_iterator<input, maker> wrapped;
+
+       inline wrapped operator () (const inny &i)
+       {
+         return wrapped (i, _m_maker);
+       }
+      };
+
+      template<class input>
+      static inline argify<
+       input, typename dwarf_output::debug_info_entry::attributes_type,
+       make_attribute<input,
+                      typename dwarf_output::debug_info_entry::attributes_type>
+       > attr (const input &, const constructor_arg_type &c)
+      {
+       return argify<
+         input, typename dwarf_output::debug_info_entry::attributes_type,
+         make_attribute<
+           input, typename dwarf_output::debug_info_entry::attributes_type>
+           > (c);
+      };
+    };
+
+    template<class impl, typename arg = nothing, typename v = value<impl, arg> >
+    class attributes_type
+      : public std::map<int, attr_value<impl, arg, v> >
+    {
+      friend class impl::debug_info_entry;
+    private:
+      typedef std::map<int, attr_value<impl, arg, v> > base_type;
+      typedef constructor_arg_adapter<impl, arg> argify;
+
+    protected:
+      inline attributes_type () {}
+
+    public: // XXX should be protected
+      template<typename input>
+      inline attributes_type (const input &other, const arg &c)
+       : base_type (argify::attr (other, c) (other.begin ()),
+                    argify::attr (other, c) (other.end ()))
+      {}
+
+    public:
+      typedef typename base_type::key_type key_type;
+      typedef typename base_type::value_type value_type;
+      typedef typename base_type::mapped_type mapped_type;
+
+      static const bool ordered = true;
+
+      template<typename attrs>
+      inline operator attrs () const
+      {
+       return attrs (base_type::begin (), base_type::end ());
+      }
+    };
+
   };
 
   // Explicit specializations.
@@ -1114,8 +1228,8 @@ namespace elfutils
     return elfutils::to_string (*this); // Use that.
   }
 
-  template<class impl, typename arg>
-  inline std::string dwarf_data::attr_value<impl, arg>::to_string () const
+  template<class impl, typename arg, typename v>
+  inline std::string dwarf_data::attr_value<impl, arg, v>::to_string () const
   {
     return elfutils::to_string (*this); // Use that.
   }
index 50714de25d915a45d66fbdb2b333c2665aa15e70..0d67a3e17e13689d859c5a163e6069c08bd0b04c 100644 (file)
@@ -117,30 +117,19 @@ namespace elfutils
        typedef debug_info_entry value_type;
       };
 
-      class attributes_type : public std::map<int, attr_value>
+      class attributes_type
+       : public dwarf_data::attributes_type<dwarf_edit>
       {
        friend class debug_info_entry;
       private:
-       typedef std::map<int, attr_value> base_type;
+       typedef dwarf_data::attributes_type<dwarf_edit> base_type;
 
-       attributes_type () {}
+       inline attributes_type () {}
 
        template<typename attrs>
-       attributes_type (const attrs &other)
-         : std::map<int, attr_value> (other.begin (), other.end ()) {}
-
-      public:
-       typedef base_type::key_type key_type;
-       typedef base_type::value_type value_type;
-       typedef base_type::mapped_type mapped_type;
-
-       static const bool ordered = true;
-
-       template<typename attrs>
-       inline operator attrs () const
-       {
-         return attrs (begin (), end ());
-       }
+       inline attributes_type (const attrs &other)
+         : base_type (other, dwarf_data::nothing ())
+       {}
       };
 
     private:
index e9f96f98ff4e963433e6369a3c242cdaf7fcbf66..7318b17130194e26a17419776075fc322b99c0d1 100644 (file)
@@ -281,10 +281,16 @@ namespace elfutils
     typedef dwarf_data::dwarf_enum dwarf_enum;
     typedef dwarf_data::range_list range_list;
     typedef dwarf_data::location_attr location_attr;
-    typedef dwarf_data::attr_value<dwarf_output,
-                                  dwarf_output_collector *> attr_value;
+
+    class compile_units;
+    class debug_info_entry;
 
   protected:
+
+    template<typename input>
+    static inline const std::string &
+    collect_string (dwarf_output_collector *, const input &);
+
     template<typename input>
     static inline const range_list &
     collect (dwarf_output_collector *, const typename input::range_list &);
@@ -321,43 +327,43 @@ namespace elfutils
     /* 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).  */
-    template<typename input, typename output,
-            typename make_outlet = make_any<input, output> >
-    struct collectify
-      : public std::unary_function<typename input::const_iterator,
-                                  typename output::iterator>
+    typedef dwarf_data::constructor_arg_adapter<dwarf_output,
+                                               dwarf_output_collector *>
+    collectify;
+
+    struct value_wrapper
+      : public dwarf_data::value<dwarf_output, dwarf_output_collector *>
     {
-      typedef typename input::const_iterator inny;
-      typedef typename output::iterator outty;
-      typedef typename input::value_type inlet;
-      typedef typename output::value_type outlet;
-
-      /* Wrapper worker passed to wrapped_input_iterator.
-        This object holds the collector pointer.  */
-      struct maker
-       : public std::unary_function<inlet, outlet>
+      struct value_string : public dwarf_data::value_dispatch
       {
-       dwarf_output_collector *_m_collector;
-       explicit inline maker (dwarf_output_collector *c) : _m_collector (c) {}
+       const std::string &_m_str;
 
-       inline outlet operator () (const inlet &x) const
+       template<typename string>
+       inline value_string (const string &s, dwarf_output_collector *c)
+         : _m_str (collect_string (c, s))
+       {}
+
+       inline operator const std::string & () const
        {
-         return make_outlet () (x, _m_collector);
+         return _m_str;
        }
-      } _m_maker;
-
-      explicit inline collectify (dwarf_output_collector *c) : _m_maker (c) {}
-
-      typedef subr::wrapped_input_iterator<input, maker> wrapped;
 
-      inline wrapped operator () (const inny &i)
-      {
-       return wrapped (i, _m_maker);
-      }
+       std::string to_string () const
+       {
+         std::string result ("\"");
+         result += _m_str;
+         result += "\"";
+         return result;
+       }
+      };
     };
 
   public:
 
+    typedef dwarf_data::attr_value<dwarf_output,
+                                  dwarf_output_collector *,
+                                  value_wrapper> attr_value;
+
     class compile_units;
 
     class debug_info_entry
@@ -373,44 +379,29 @@ namespace elfutils
        template<typename input>
        inline children_type (const input &other, dwarf_output_collector *c)
          : std::list<debug_info_entry>
-           (collectify<input, children_type> (c) (other.begin ()),
-            collectify<input, children_type> (c) (other.end ()))
+           (collectify::argify<input, children_type> (c) (other.begin ()),
+            collectify::argify<input, children_type> (c) (other.end ()))
        {}
 
       public:
        typedef debug_info_entry value_type;
       };
 
-      class attributes_type : public std::map<int, attr_value>
+      class attributes_type
+       : public dwarf_data::attributes_type<dwarf_output,
+                                            dwarf_output_collector *,
+                                            value_wrapper>
       {
        friend class debug_info_entry;
       private:
-       typedef std::map<int, attr_value> base_type;
-
-       attributes_type () {}
+       typedef dwarf_data::attributes_type<dwarf_output,
+                                           dwarf_output_collector *,
+                                           value_wrapper> base_type;
 
        template<typename input>
        inline attributes_type (const input &other, dwarf_output_collector *c)
-         : base_type (collectify<input, attributes_type,
-                                 make_attribute<input, attributes_type> > (c)
-                      (other.begin ()),
-                      collectify<input, attributes_type,
-                                 make_attribute<input, attributes_type> > (c)
-                      (other.end ()))
+         : base_type (other, c)
        {}
-
-      public:
-       typedef base_type::key_type key_type;
-       typedef base_type::value_type value_type;
-       typedef base_type::mapped_type mapped_type;
-
-       static const bool ordered = true;
-
-       template<typename attrs>
-       inline operator attrs () const
-       {
-         return attrs (begin (), end ());
-       }
       };
 
     private:
@@ -516,8 +507,8 @@ namespace elfutils
       // Constructor copying CUs from input container.
       template<typename input>
       compile_units (const input &units, dwarf_output_collector *c)
-       : _base (collectify<input, compile_units> (c) (units.begin ()),
-                collectify<input, compile_units> (c) (units.end ()))
+       : _base (collectify::argify<input, compile_units> (c) (units.begin ()),
+                collectify::argify<input, compile_units> (c) (units.end ()))
       {
       }
 
@@ -589,10 +580,18 @@ namespace elfutils
     friend class dwarf_output;
 
   private:
+    subr::value_set<std::string> _m_strings;
     subr::value_set<dwarf_output::range_list> _m_ranges;
 
   };
 
+  template<typename input>
+  inline const std::string &
+  dwarf_output::collect_string (dwarf_output_collector *c, const input &s)
+  {
+    return c->_m_strings.add (s);
+  }
+
   template<typename input>
   inline const dwarf_output::range_list &
   dwarf_output::collect (dwarf_output_collector *c,
index aaa8a2768542135d48a97b6c274d14016d443b38..7640b4caa8ee1a0c94ea4820d3e3694493b89355 100644 (file)
@@ -53,8 +53,7 @@
 
 using namespace elfutils;
 
-template
-dwarf::value_space dwarf_data::attr_value<dwarf_edit>::what_space () const;
+template dwarf::value_space dwarf_edit::attr_value::what_space () const;
 
 template<>
 std::string
index 289e83aa6cecf87c57b0ac72e065693bee0c110c..d50abb8eb137ffc0589a8801169cd612324260be 100644 (file)
 
 using namespace elfutils;
 
-template
-dwarf::value_space
-dwarf_data::attr_value<dwarf_output,
-                      dwarf_output_collector *>::what_space () const;
+template dwarf::value_space dwarf_output::attr_value::what_space () const;
 
 template<>
 std::string
index 6b4508ba4f532ab775330fcfbf5b0b36b69dfe6b..4a90e50ce5b690541b6e7f537999307185e1f80b 100644 (file)
@@ -23,10 +23,16 @@ namespace elfutils
     template<typename T>
     struct hash : public T::hasher {};
 
+    template<typename T>
+    static inline size_t hash_this (const T &v)
+    {
+      return hash<T> () (v);
+    }
+
     template <typename T>
     inline void hash_combine (size_t &seed, const T &v)
     {
-      seed ^= hash<T> () (v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+      seed ^= hash_this (v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
     }
 
     template <typename T1, typename T2>
@@ -58,7 +64,7 @@ namespace elfutils
        inline hasher () : _m_hash (0) {}
        inline void operator () (const typename T::value_type &x)
        {
-         subr::hash_combine (_m_hash, subr::hash<typename T::value_type> (x));
+         subr::hash_combine (_m_hash, hash_this (x));
        }
       };
 
@@ -94,7 +100,7 @@ namespace elfutils
     struct hashed_hasher
       : public std::unary_function<T, size_t>
     {
-      size_t operator () (const T &v)
+      size_t operator () (const T &v) const
       {
        return v._m_hash;
       }
@@ -104,7 +110,7 @@ namespace elfutils
     struct name_equal : public std::binary_function<const char *, string, bool>
     {
       template<typename mystring>
-      inline bool operator () (const mystring &me, const string &you)
+      inline bool operator () (const mystring &me, const string &you) const
       {
        return you == me;
       }
@@ -115,12 +121,12 @@ namespace elfutils
     struct name_equal<const char *>
       : public std::binary_function<const char *, const char *, bool>
     {
-      bool operator () (const char *me, const char *you)
+      bool operator () (const char *me, const char *you) const
       {
        return !strcmp (me, you);
       }
       template<typename mystring>
-      inline bool operator () (const mystring &me, const char *you)
+      inline bool operator () (const mystring &me, const char *you) const
       {
        return me == you;
       }
@@ -156,7 +162,7 @@ namespace elfutils
     template<typename t1, typename t2>
     struct equal_to : public std::binary_function<t1, t2, bool>
     {
-      inline bool operator () (const t1 &a, const t2 &b)
+      inline bool operator () (const t1 &a, const t2 &b) const
       {
        return a == b;
       }
@@ -181,7 +187,7 @@ namespace elfutils
       {}
 
       inline bool operator () (const typename t1::const_iterator &a,
-                              const typename t2::const_iterator &b)
+                              const typename t2::const_iterator &b) const
       {
        return _m_pred (*a, *b);
       }
@@ -362,14 +368,14 @@ namespace elfutils
       struct hasher
        : public std::unary_function<hashed_value, size_t>
       {
-       inline size_t operator () (const hashed_value &v)
+       inline size_t operator () (const hashed_value &v) const
        {
          return v.first;
        }
       };
 
       hashed_value (const value_type &v)
-       : _base (subr::hash<value_type> (v), v) {}
+       : _base (hash_this (v), v) {}
       hashed_value (const hashed_value &v)
        : _base (v.first, v.second) {}
 
@@ -403,6 +409,12 @@ namespace elfutils
          }
        return p.first->second;
       };
+
+      template<typename input>
+      const value_type &add (const input &v)
+      {
+       return add (value_type (v));
+      }
     };
 
     // A container of hashed_value's that itself acts like a hashed_value.
@@ -499,7 +511,7 @@ namespace elfutils
 
          inline void operator () (const typename _base::value_type &p)
          {
-           subr::hash_combine (_m_hash, subr::hash<key_type> (p.first));
+           subr::hash_combine (_m_hash, hash_this (p.first));
            subr::hash_combine (_m_hash, p.second.first);
          }
        };