From: Roland McGrath Date: Mon, 26 Jan 2009 12:40:30 +0000 (-0800) Subject: Use non-copying const_vector type for blocks. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7e4902740562d04f214fec7daff341369c83f2e4;p=thirdparty%2Felfutils.git Use non-copying const_vector type for blocks. --- diff --git a/libdw/c++/dwarf b/libdw/c++/dwarf index 3f2756b33..36535a8e3 100644 --- a/libdw/c++/dwarf +++ b/libdw/c++/dwarf @@ -149,6 +149,68 @@ namespace elfutils return a.first == b.first && a.second == b.second; } + // Used like std::vector, but is really just a simple fixed array. + template + 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 + inline operator other () const + { + return other (begin (), end ()); + } + + template + inline bool operator== (const vec &other) const + { + return (other.size () == size () + && std::equal (begin (), end (), other.begin ())); + } + template + 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 constant_block () const; + const_vector 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 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 diff --git a/libdw/c++/values.cc b/libdw/c++/values.cc index 0523a30a5..22bee1354 100644 --- a/libdw/c++/values.cc +++ b/libdw/c++/values.cc @@ -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 +const_vector 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 (block.data); const uint8_t *const end = begin + block.length; - return vector (begin, end); + return const_vector (begin, end); } // dwarf::source_file