]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
more there
authorRoland McGrath <roland@redhat.com>
Mon, 17 Aug 2009 05:15:16 +0000 (22:15 -0700)
committerRoland McGrath <roland@redhat.com>
Mon, 17 Aug 2009 05:15:16 +0000 (22:15 -0700)
libdw/c++/data-values.hh
libdw/c++/dwarf_data
libdw/c++/dwarf_output
libdw/c++/subr.hh

index 712dd6bf6fa9e52cc84cea2f8d6e5fd43d2e5559..5f109042f6cfb6652ae7144b330acb5b837153fc 100644 (file)
 
 #include "dwarf_data"
 
-#include <typeinfo>
+template<typename v, typename subtype>
+static inline bool is_a (const typename v::value_dispatch *value)
+{
+  return dynamic_cast<const subtype *> (value) != NULL;
+}
 
 namespace elfutils
 {
@@ -57,37 +61,37 @@ namespace elfutils
   dwarf::value_space
   dwarf_data::attr_value<impl, v>::what_space () const
   {
-    if (typeid (*_m_value) == typeid (typename v::value_flag))
+    if (is_a<v, typename v::value_flag> (_m_value))
       return dwarf::VS_flag;
-    if (typeid (*_m_value) == typeid (typename v::value_dwarf_constant))
+    if (is_a<v, typename v::value_dwarf_constant> (_m_value))
       return dwarf::VS_dwarf_constant;
-    if (typeid (*_m_value) == typeid (typename v::value_reference))
+    if (is_a<v, typename v::value_reference> (_m_value))
       return dwarf::VS_reference;
-    if (typeid (*_m_value) == typeid (typename v::value_lineptr))
+    if (is_a<v, typename v::value_lineptr> (_m_value))
       return dwarf::VS_lineptr;
-    if (typeid (*_m_value) == typeid (typename v::value_macptr))
+    if (is_a<v, typename v::value_macptr> (_m_value))
       return dwarf::VS_macptr;
-    if (typeid (*_m_value) == typeid (typename v::value_rangelistptr))
+    if (is_a<v, typename v::value_rangelistptr> (_m_value))
       return dwarf::VS_rangelistptr;
-    if (typeid (*_m_value) == typeid (typename v::value_identifier))
+    if (is_a<v, typename v::value_identifier> (_m_value))
       return dwarf::VS_identifier;
-    if (typeid (*_m_value) == typeid (typename v::value_string))
+    if (is_a<v, typename v::value_string> (_m_value))
       return dwarf::VS_string;
-    if (typeid (*_m_value) == typeid (typename v::value_source_file))
+    if (is_a<v, typename v::value_source_file> (_m_value))
       return dwarf::VS_source_file;
-    if (typeid (*_m_value) == typeid (typename v::value_source_line))
+    if (is_a<v, typename v::value_source_line> (_m_value))
       return dwarf::VS_source_line;
-    if (typeid (*_m_value) == typeid (typename v::value_source_column))
+    if (is_a<v, typename v::value_source_column> (_m_value))
       return dwarf::VS_source_column;
-    if (typeid (*_m_value) == typeid (typename v::value_address))
+    if (is_a<v, typename v::value_address> (_m_value))
       return dwarf::VS_address;
-    if (typeid (*_m_value) == typeid (typename v::value_constant)
-       || typeid (*_m_value) == typeid (typename v::value_constant_block))
+    if (is_a<v, typename v::value_constant> (_m_value)
+       || is_a<v, typename v::value_constant_block> (_m_value))
       return dwarf::VS_constant;
-    if (typeid (*_m_value) == typeid (typename v::value_location))
+    if (is_a<v, typename v::value_location> (_m_value))
       return dwarf::VS_location;
 
-    throw std::runtime_error ("XXX impossible");
+    throw std::logic_error ("attr_value has no known value_space!");
   }
 
   template<typename attr_pair>
index 005fc5dcedfe8a29dd33a574eeffdc24dd037cb6..d11efdb308963c71db04316678f46e6809facc26 100644 (file)
@@ -827,13 +827,25 @@ namespace elfutils
        return *result;
       }
 
-      template<typename flavor, typename input, typename arg_type>
-      static inline void
-      make (value_dispatch *&v, flavor *&result,
-           int /*whatattr*/, const input &x, arg_type &arg)
+      template<typename arg_type>
+      struct maker
       {
-       assert (alloc_values);
-       v = result = new flavor (x, arg);
+       inline explicit maker (const arg_type &) {}
+
+       template<typename flavor, typename input>
+       static inline void
+       make (value_dispatch *&v, flavor *&result,
+             int /*whatattr*/, const input &x, arg_type &arg)
+       {
+         assert (alloc_values);
+         v = result = new flavor (x, arg);
+       }
+      };
+
+      template<typename arg_type>
+      static inline maker<arg_type> make (arg_type &arg)
+      {
+       return maker<arg_type> (arg);
       }
 
       struct value_string : public value_dispatch, public std::string
@@ -890,7 +902,7 @@ namespace elfutils
           object.  This is what plain assignment does.  This just uses
           this pointer, rather than translating it from another file
           into this one (which requires a tracker).  */
-       inline value_reference (const value_type &i, const subr::nothing &)
+       inline value_reference (const value_type &i, subr::nothing &)
          : ref (i)
        {}
 
@@ -1125,11 +1137,23 @@ namespace elfutils
       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 value, typename arg_type = subr::nothing>
       struct init
       {
        inline init (attr_value *av, int whatattr,
-                    const value &other, arg_type &arg = arg_type ())
+                    const value &other, arg_type &arg)
+       {
+         do_init (av, whatattr, other, arg);
+       }
+
+       inline init (attr_value *av, int whatattr, const value &other)
+       {
+         arg_type dummy;
+         do_init (av, whatattr, other, dummy);
+       }
+
+       static inline void do_init (attr_value *av, int whatattr,
+                                   const value &other, arg_type &arg)
        {
          switch (other.what_space ())
            {
@@ -1137,7 +1161,8 @@ namespace elfutils
              case dwarf::VS_##flavor:                                        \
                {                                                             \
                  typename vw::value_##flavor *p;                             \
-                 vw::make (av->_m_value, p, whatattr, other.fetch (), arg); \
+                 vw::make (arg)                                              \
+                   .make (av->_m_value, p, whatattr, other.fetch (), arg);   \
                }                                                             \
              break
 
@@ -1158,14 +1183,14 @@ namespace elfutils
              if (other.constant_is_integer ())
                {
                  typename vw::value_constant *p;
-                 vw::make (av->_m_value, p, whatattr,
-                           other.constant (), arg);
+                 vw::make (arg).make (av->_m_value, p, whatattr,
+                                      other.constant (), arg);
                }
              else
                {
                  typename vw::value_constant_block *p;
-                 vw::make (av->_m_value, p, whatattr,
-                           other.constant_block (), arg);
+                 vw::make (arg).make (av->_m_value, p, whatattr,
+                                      other.constant_block (), arg);
                }
              break;
 
index b03dbd4838f4b631d287bbe66c3f81d964305a46..47e82736950158e46e3f70487390a655268e71b6 100644 (file)
@@ -131,128 +131,12 @@ namespace elfutils
 
       typedef dwarf_data::value<dwarf_output> data;
 
-#if 0
-      template<typename flavor, typename input>
-      static inline void
-      make (const value_dispatch *&, flavor *&,
-           int, const input &, const subr::nothing &)
-      {
-       throw std::logic_error ("dwarf_output cannot be default-constructed");
-      }
-#endif
-
-      template<typename input, typename copier_type>
-      static inline void
-      make (const value_dispatch *&v, value_string *&,
-           int, const input &x, copier_type &c)
-      {
-       v = c ().add_string (x);
-      }
-
-      template<typename input, typename copier_type>
-      static inline void
-      make (const value_dispatch *&v, value_identifier *&,
-           int, const input &x, copier_type &c)
-      {
-       v = c ().add_identifier (x);
-      }
-
-      template<typename input, typename copier_type>
-      static inline void
-      make (const value_dispatch *&v, value_reference *&,
-           int, const input &x, copier_type &c)
-      {
-       v = c.add_reference (x, &v);
-      }
-
-      template<typename input, typename copier_type>
-      static inline void
-      make (const value_dispatch *&v, value_flag *&,
-           int, const input &x, copier_type &c)
-      {
-       v = c ().add_flag (x);
-      }
-
-      template<typename input, typename copier_type>
-      static inline void
-      make (const value_dispatch *&v, value_address *&,
-           int, const input &x, copier_type &c)
-      {
-       v = c ().add_address (x);
-      }
-
-      template<typename input, typename copier_type>
-      static inline void
-      make (const value_dispatch *&v, value_rangelistptr *&,
-           int, const input &x, copier_type &c)
-      {
-       v = c ().add_ranges (x);
-      }
-
-      template<typename input, typename copier_type>
-      static inline void
-      make (const value_dispatch *&v, value_lineptr *&,
-           int, const input &x, copier_type &c)
-      {
-       v = c ().add_line_info (x);
-      }
-
-      template<typename input, typename copier_type>
-      static inline void
-      make (const value_dispatch *&v, value_constant *&,
-           int, const input &x, copier_type &c)
-      {
-       v = c ().add_constant (x);
-      }
-
-      template<typename input, typename copier_type>
-      static inline void
-      make (const value_dispatch *&v, value_constant_block *&,
-           int, const input &x, copier_type &c)
-      {
-       v = c ().add_constant_block (x);
-      }
-
-      template<typename input, typename copier_type>
-      static inline void
-      make (const value_dispatch *&v, value_dwarf_constant *&,
-           int, const input &x, copier_type &c)
-      {
-       v = c ().add_dwarf_constant (x);
-      }
-
-      template<typename input, typename copier_type>
-      static inline void
-      make (const value_dispatch *&v, value_source_file *&,
-           int attr, const input &x, copier_type &c)
-      {
-       v = c ().add_source_file (attr, x);
-      }
-
-      template<typename input, typename copier_type>
-      static inline void
-      make (const value_dispatch *&v, value_source_line *&,
-           int, const input &x, copier_type &c)
-      {
-       v = c ().add_source_line (x);
-      }
+      template<typename copier_type> struct maker;
 
-      template<typename input, typename copier_type>
-      static inline void
-      make (const value_dispatch *&v, value_source_column *&,
-           int, const input &x, copier_type &c)
+      template<typename arg_type>
+      static inline maker<arg_type> make (arg_type &arg)
       {
-       v = c ().add_source_column (x);
-      }
-
-      // XXX macptr
-
-      template<typename input, typename copier_type>
-      static inline void
-      make (const value_dispatch *&v, value_location *&,
-           int, const input &x, copier_type &c)
-      {
-       v = c ().add_location (x);
+       return maker<arg_type> (arg);
       }
 
       // See dwarf_output::copier, below.
@@ -754,6 +638,124 @@ namespace elfutils
     return elfutils::to_string (*this); // Use that.
   }
 
+  template<typename copier_type>
+  struct dwarf_output::value::maker
+  {
+    inline explicit maker (copier_type &) {}
+
+    template<typename input>
+    inline void make (const value_dispatch *&v, value_string *&,
+                     int, const input &x, copier_type &c)
+    {
+      v = c ().add_string (x);
+    }
+
+    template<typename input>
+    inline void make (const value_dispatch *&v, value_identifier *&,
+                     int, const input &x, copier_type &c)
+    {
+      v = c ().add_identifier (x);
+    }
+
+    template<typename input>
+    inline void make (const value_dispatch *&v, value_reference *&,
+                     int, const input &x, copier_type &c)
+    {
+      v = c.add_reference (x, &v);
+    }
+
+    template<typename input>
+    inline void make (const value_dispatch *&v, value_flag *&,
+                     int, const input &x, copier_type &c)
+    {
+      v = c ().add_flag (x);
+    }
+
+    template<typename input>
+    inline void make (const value_dispatch *&v, value_address *&,
+                     int, const input &x, copier_type &c)
+    {
+      v = c ().add_address (x);
+    }
+
+    template<typename input>
+    inline void make (const value_dispatch *&v, value_rangelistptr *&,
+                     int, const input &x, copier_type &c)
+    {
+      v = c ().add_ranges (x);
+    }
+
+    template<typename input>
+    inline void make (const value_dispatch *&v, value_lineptr *&,
+                     int, const input &x, copier_type &c)
+    {
+      v = c ().add_line_info (x);
+    }
+
+    template<typename input>
+    inline void make (const value_dispatch *&v, value_constant *&,
+                     int, const input &x, copier_type &c)
+    {
+      v = c ().add_constant (x);
+    }
+
+    template<typename input>
+    inline void make (const value_dispatch *&v, value_constant_block *&,
+                     int, const input &x, copier_type &c)
+    {
+      v = c ().add_constant_block (x);
+    }
+
+    template<typename input>
+    inline void make (const value_dispatch *&v, value_dwarf_constant *&,
+                     int, const input &x, copier_type &c)
+    {
+      v = c ().add_dwarf_constant (x);
+    }
+
+    template<typename input>
+    inline void make (const value_dispatch *&v, value_source_file *&,
+                     int attr, const input &x, copier_type &c)
+    {
+      v = c ().add_source_file (attr, x);
+    }
+
+    template<typename input>
+    inline void make (const value_dispatch *&v, value_source_line *&,
+                     int, const input &x, copier_type &c)
+    {
+      v = c ().add_source_line (x);
+    }
+
+    template<typename input>
+    inline void make (const value_dispatch *&v, value_source_column *&,
+                     int, const input &x, copier_type &c)
+    {
+      v = c ().add_source_column (x);
+    }
+
+    // XXX macptr
+
+    template<typename input>
+    inline void make (const value_dispatch *&v, value_location *&,
+                     int, const input &x, copier_type &c)
+    {
+      v = c ().add_location (x);
+    }
+  };
+
+  template<>
+  struct dwarf_output::value::maker<subr::nothing>
+  {
+    inline explicit maker (subr::nothing &) {}
+
+    template<typename... args>
+    inline void make (args&&...)
+    {
+      throw std::logic_error ("dwarf_output cannot be default-constructed");
+    }
+  };
+
   struct dwarf_output::die_info
   {
     std::queue<value::value_reference *> _m_refs;
@@ -799,7 +801,10 @@ namespace elfutils
       _m_with_sibling[have_sibling] = true;
 
       if (_m_refs.empty ())
-       self (new value::value_reference (ref, subr::nothing ()));
+       {
+         subr::nothing dummy;
+         self (new value::value_reference (ref, dummy));
+       }
       else
        for (size_t n = _m_refs.size (); n > 0; --n)
          {
@@ -1409,7 +1414,7 @@ namespace elfutils
        return this;
       }
 
-#if 1
+#if 0
       static inline std::ostream &debug ()
       {
        return std::cout;
index 07233a5e1f92495afaa3ac88715192bd52e9bea6..de342104c613ecec3d2c99a38414df02e3a8e996 100644 (file)
@@ -873,8 +873,6 @@ namespace elfutils
 
     struct nothing
     {
-      template<typename... args>
-      inline void operator () (args&&...) const {}
     };
 
     // Class instead of function so it can be a friend.