]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Use non-copying const_vector type for blocks.
authorRoland McGrath <roland@redhat.com>
Mon, 26 Jan 2009 12:40:30 +0000 (04:40 -0800)
committerRoland McGrath <roland@redhat.com>
Mon, 26 Jan 2009 12:40:30 +0000 (04:40 -0800)
libdw/c++/dwarf
libdw/c++/values.cc

index 3f2756b33d738b2f2238063e407d3b92d9ddbc0d..36535a8e30734ffa5f4fbb59a4debc168d29d4c9 100644 (file)
@@ -149,6 +149,68 @@ namespace elfutils
     return a.first == b.first && a.second == b.second;
   }
 
+  // Used like std::vector<elt>, but is really just a simple fixed array.
+  template<typename elt>
+  class const_vector
+  {
+  private:
+    size_t _m_size;
+    const elt *_m_array;
+
+  public:
+    typedef const elt *const_iterator;
+
+    const_vector ()
+      : _m_size (0), _m_array (NULL) {}
+    const_vector (const const_vector &v)
+      : _m_size (v._m_size), _m_array (v._m_array) {}
+    const_vector (const elt *start, const elt *stop)
+      : _m_size (stop - start), _m_array (start) {}
+
+    inline const_vector &operator= (const const_vector &v)
+    {
+      _m_size = v._m_size;
+      _m_array = v._m_array;
+      return *this;
+    }
+
+    inline size_t size () const
+    {
+      return _m_size;
+    }
+    inline bool empty () const
+    {
+      return _m_size == 0;
+    }
+
+    const_iterator begin () const
+    {
+      return _m_array;
+    }
+    const_iterator end () const
+    {
+      return &_m_array[_m_size];
+    }
+
+    template<typename other>
+    inline operator other () const
+    {
+      return other (begin (), end ());
+    }
+
+    template<typename vec>
+    inline bool operator== (const vec &other) const
+    {
+      return (other.size () == size ()
+             && std::equal (begin (), end (), other.begin ()));
+    }
+    template<typename vec>
+    inline bool operator!= (const vec &other) const
+    {
+      return !(*this == other);
+    }
+  };
+
   // One DWARF object file.
   class dwarf
   {
@@ -928,8 +990,7 @@ namespace elfutils
       // XXX reloc
       ::Dwarf_Word constant () const;
       ::Dwarf_Sword signed_constant () const;
-      // XXX better type??
-      std::vector<uint8_t> constant_block () const;
+      const_vector<uint8_t> constant_block () const;
 
       // XXX known enums
       // dwarf_enum dwarf_constant () const;
@@ -982,7 +1043,7 @@ namespace elfutils
              return source_file () == other.source_file ();
 
            case VS_location:
-             return location () == other; // XXX
+             return location () == other; // XXX will be other.location ()
 
            case VS_discr_list:
              throw std::runtime_error ("XXX unimplemented");
@@ -1013,7 +1074,7 @@ namespace elfutils
       template<typename other_attr>
       bool operator== (const other_attr &other) const
       {
-       // XXX hack
+       // XXX hack, real location interface later
        if (singleton ())
          return _m_attr.constant_block () == other.constant_block ();
        // loclistptr XXX punt for now, treat as constant
index 0523a30a54810084733c6fb168c856f81462c688..22bee1354cd528f8c16c7fc73440c61b8425cc51 100644 (file)
@@ -210,7 +210,7 @@ dwarf::attr_value::to_string () const
       return location ().to_string ();
 
     case VS_discr_list:
-      break;           // XXX
+      break;                   // XXX DW_AT_discr_list unimplemented
     }
 
   throw std::runtime_error ("XXX unsupported value space");
@@ -242,7 +242,7 @@ dwarf::attr_value::string () const
   return result;
 }
 
-vector<uint8_t>
+const_vector<uint8_t>
 dwarf::attr_value::constant_block () const
 {
   Dwarf_Block block;
@@ -279,6 +279,12 @@ dwarf::attr_value::constant_block () const
     case DW_FORM_udata:
     case DW_FORM_sdata:
       // XXX ?
+      if ((*(const uint8_t *) thisattr ()->valp & 0x80) == 0)
+       {
+         block.length = 1;
+         block.data = thisattr ()->valp;
+         break;
+       }
 
     default:
       throw std::runtime_error ("XXX wrong form");
@@ -286,7 +292,7 @@ dwarf::attr_value::constant_block () const
 
   const uint8_t *const begin = reinterpret_cast<const uint8_t *> (block.data);
   const uint8_t *const end = begin + block.length;
-  return vector<uint8_t> (begin, end);
+  return const_vector<uint8_t> (begin, end);
 }
 \f
 // dwarf::source_file