#define _ELFUTILS_DWARF_EDIT 1
#include "dwarf"
+#include <bitset>
/* Read the comments for elfutils::dwarf first.
{
public:
class compile_units;
-
- // XXX later
- class attr_value : public dwarf::attr_value
- {
- public:
- attr_value (const dwarf::attr_value &v) : dwarf::attr_value (v) {}
- };
+ class attr_value;
class debug_info_entry
{
{
friend class dwarf_edit;
private:
+ typedef std::list<compile_unit> _base;
+
// Default constructor: an empty container, no CUs.
inline compile_units () {}
// Constructor copying CUs from input container.
template<typename input>
compile_units(const input &units)
- : std::list<compile_unit> (units.begin (), units.end ())
- {}
+ : _base (units.begin (), units.end ()) {}
public:
typedef compile_unit value_type;
+ typedef _base::iterator iterator;
+ typedef _base::const_iterator const_iterator;
inline compile_unit &new_unit ()
{
template<typename other_children>
bool operator== (const other_children &other) const
{
- return std::equal (begin (), end (), other.begin ());
+ return subr::container_equal (*this, other);
}
template<typename other_children>
bool operator!= (const other_children &other) const
}
};
+ // Same as set<pair<Dwarf_Addr, Dwarf_Addr>>.
+ class range_list : public dwarf::arange_list
+ {
+ public:
+ template<typename list>
+ range_list (const list &other)
+ : dwarf::arange_list (other.begin (), other.end ()) {}
+ };
+
+ class source_file
+ {
+ private:
+ std::string _m_name;
+ ::Dwarf_Word _m_mtime;
+ ::Dwarf_Word _m_size;
+
+ public:
+ source_file () : _m_name (), _m_mtime (0), _m_size (0) {}
+ source_file (const std::string &n, ::Dwarf_Word m = 0, ::Dwarf_Word s = 0)
+ : _m_name (n), _m_mtime (m), _m_size (s) {}
+
+ template<typename file>
+ source_file (const file &other)
+ : _m_name (other.name ()),
+ _m_mtime (other.mtime ()), _m_size (other.size ()) {}
+
+ template<typename file>
+ inline source_file &operator= (const file &other)
+ {
+ _m_name = other.name ();
+ _m_mtime = other.mtime ();
+ _m_size = other.size ();
+ return *this;
+ }
+ inline source_file &operator= (const std::string &n)
+ {
+ _m_name = n;
+ _m_mtime = 0;
+ _m_size = 0;
+ return *this;
+ }
+ inline source_file &operator= (const char *n)
+ {
+ _m_name = n;
+ _m_mtime = 0;
+ _m_size = 0;
+ return *this;
+ }
+
+ inline std::string &name ()
+ {
+ return _m_name;
+ }
+ inline const std::string &name () const
+ {
+ return _m_name;
+ }
+ inline ::Dwarf_Word &mtime ()
+ {
+ return _m_mtime;
+ }
+ inline ::Dwarf_Word mtime () const
+ {
+ return _m_mtime;
+ }
+ inline ::Dwarf_Word &size ()
+ {
+ return _m_size;
+ }
+ inline ::Dwarf_Word size () const
+ {
+ return _m_size;
+ }
+
+ template<typename other_file>
+ bool operator== (const other_file &other) const
+ {
+ if (mtime () != 0)
+ {
+ ::Dwarf_Word other_mtime = other.mtime ();
+ if (other_mtime != 0 && other_mtime != mtime ())
+ return false;
+ }
+ if (size () != 0)
+ {
+ ::Dwarf_Word other_size = other.size ();
+ if (other_size != 0 && other_size != size ())
+ return false;
+ }
+ return name () == other.name ();
+ }
+ template<typename other_file>
+ inline bool operator!= (const other_file &other) const
+ {
+ return !(*this == other);
+ }
+ };
+
+ // This describes a CU's directory table, a simple array of strings.
+ class directory_table : public std::vector<std::string>
+ {
+ private:
+ typedef std::vector<std::string> _base;
+
+ public:
+ directory_table () {}
+
+ template<typename table>
+ directory_table (const table &other)
+ : _base (other.begin (), other.end ()) {}
+
+ template<typename table>
+ inline bool operator== (const table &other) const
+ {
+ return size () == other.size () && subr::container_equal (*this, other);
+ }
+ template<typename table>
+ inline bool operator!= (const table &other) const
+ {
+ return !(*this == other);
+ }
+ };
+
+ class line_entry
+ {
+ private:
+ ::Dwarf_Addr _m_addr; // XXX dwfl, reloc
+ source_file _m_file;
+ unsigned int _m_line;
+ unsigned int _m_column;
+
+ enum flag_bit
+ {
+ flag_statement,
+ flag_basic_block,
+ flag_end_sequence,
+ flag_prologue_end,
+ flag_epilogue_begin,
+ flag_count
+ };
+ std::bitset<flag_count> _m_flags;
+
+ public:
+ line_entry (::Dwarf_Addr addr)
+ : _m_addr (addr), _m_file (), _m_line (0), _m_column (0) {}
+
+ template<typename entry>
+ line_entry (const entry &other)
+ : _m_addr (0), _m_file (), _m_line (0), _m_column (0)
+ {
+ *this = other;
+ }
+
+ template<typename entry>
+ line_entry &operator= (const entry &other)
+ {
+ _m_addr = other.address ();
+ _m_file = other.file ();
+ _m_line = other.line ();
+ _m_column = other.column ();
+ statement () = other.statement ();
+ basic_block () = other.basic_block ();
+ end_sequence () = other.end_sequence ();
+ prologue_end () = other.prologue_end ();
+ epilogue_begin () = other.epilogue_begin ();
+ return *this;
+ }
+
+ inline ::Dwarf_Addr &address ()
+ {
+ return _m_addr;
+ }
+ inline ::Dwarf_Addr address () const
+ {
+ return _m_addr;
+ }
+ inline source_file &file ()
+ {
+ return _m_file;
+ }
+ inline const source_file &file () const
+ {
+ return _m_file;
+ }
+ inline unsigned int &line ()
+ {
+ return _m_line;
+ }
+ inline unsigned int line () const
+ {
+ return _m_line;
+ }
+ inline unsigned int &column ()
+ {
+ return _m_column;
+ }
+ inline unsigned int column () const
+ {
+ return _m_column;
+ }
+
+#define _DWARF_EDIT_LE_FLAG(what) \
+ bool what () const \
+ { \
+ return _m_flags[flag_##what]; \
+ } \
+ std::bitset<flag_count>::reference what () \
+ { \
+ return _m_flags[flag_##what]; \
+ }
+ _DWARF_EDIT_LE_FLAG (statement)
+ _DWARF_EDIT_LE_FLAG (basic_block)
+ _DWARF_EDIT_LE_FLAG (end_sequence)
+ _DWARF_EDIT_LE_FLAG (prologue_end)
+ _DWARF_EDIT_LE_FLAG (epilogue_begin)
+#undef _DWARF_EDIT_LE_FLAG
+
+ template<typename entry>
+ bool operator< (const entry &other) const
+ {
+ return address () < other.address ();
+ }
+ template<typename entry>
+ bool operator> (const entry &other) const
+ {
+ return address () > other.address ();
+ }
+ template<typename entry>
+ bool operator<= (const entry &other) const
+ {
+ return address () <= other.address ();
+ }
+ template<typename entry>
+ bool operator>= (const entry &other) const
+ {
+ return address () >= other.address ();
+ }
+
+ template<typename entry>
+ inline bool operator== (const entry &other) const
+ {
+ return (address () == other.address ()
+ && line () == other.line ()
+ && column () == other.column ()
+ && statement () == other.statement ()
+ && basic_block () == other.basic_block ()
+ && end_sequence () == other.end_sequence ()
+ && prologue_end () == other.prologue_end ()
+ && epilogue_begin () == other.epilogue_begin ()
+ && file () == other.file ());
+ }
+ template<typename entry>
+ inline bool operator!= (const entry &other) const
+ {
+ return !(*this == other);
+ }
+ };
+
+ class line_table : public std::vector<line_entry>
+ {
+ private:
+ typedef std::vector<line_entry> _base;
+
+ public:
+ typedef _base::size_type size_type;
+ typedef _base::difference_type difference_type;
+ typedef _base::value_type value_type;
+ typedef _base::iterator iterator;
+ typedef _base::const_iterator const_iterator;
+
+ line_table () {}
+
+ template<typename table>
+ line_table (const table &other) : _base (other.begin (), other.end ()) {}
+
+ template<typename table>
+ inline bool operator== (const table &other) const
+ {
+ return size () == other.size () && subr::container_equal (*this, other);
+ }
+ template<typename table>
+ inline bool operator!= (const table &other) const
+ {
+ return !(*this == other);
+ }
+
+ // Look up by matching address.
+ iterator find (::Dwarf_Addr);
+ const_iterator find (::Dwarf_Addr) const;
+ };
+
+ class line_info_table
+ {
+ private:
+ directory_table _m_dirs;
+ line_table _m_lines;
+
+ public:
+ line_info_table () : _m_dirs (), _m_lines () {}
+
+ template<typename table>
+ line_info_table (const table &other)
+ : _m_dirs (other.include_directories ()), _m_lines (other.lines ()) {}
+
+ template<typename table>
+ inline line_info_table &operator= (const table &other)
+ {
+ _m_dirs = directory_table (other.include_directories ());
+ _m_lines = line_table (other.lines ());
+ return *this;
+ }
+
+ inline directory_table &include_directories ()
+ {
+ return _m_dirs;
+ }
+ inline const directory_table &include_directories () const
+ {
+ return _m_dirs;
+ }
+ inline line_table &lines ()
+ {
+ return _m_lines;
+ }
+ inline const line_table &lines () const
+ {
+ return _m_lines;
+ }
+
+ template<typename table>
+ inline bool operator== (const table &other) const
+ {
+ return (include_directories () == other.include_directories ()
+ && lines () == other.lines ());
+ }
+ template<typename table>
+ inline bool operator!= (const table &other) const
+ {
+ return !(*this == other);
+ }
+ };
+
+ class location_attr : public std::map<dwarf::location_attr::key_type,
+ std::vector<uint8_t> >
+ {
+ private:
+ typedef std::map<dwarf::location_attr::key_type,
+ std::vector<uint8_t> > _base;
+
+ public:
+ typedef _base::size_type size_type;
+ typedef _base::difference_type difference_type;
+ typedef _base::key_type key_type;
+ typedef _base::mapped_type mapped_type;
+ typedef _base::value_type value_type;
+ typedef _base::iterator iterator;
+ typedef _base::const_iterator const_iterator;
+
+ inline location_attr () : _base () {}
+ inline location_attr (const location_attr &other)
+ : _base (static_cast<const _base &> (other)) {}
+ template<typename loc>
+ inline location_attr (const loc &other) : _base ()
+ {
+ *this = other;
+ }
+
+ template<typename loc>
+ inline location_attr &operator= (const loc &other)
+ {
+ clear ();
+ if (other.empty ())
+ ;
+ else if (other.is_list ())
+ for (typename loc::const_iterator i = other.begin ();
+ i != other.end ();
+ ++i)
+ {
+ const typename loc::mapped_type &x = (*i).second;
+ (*this)[(*i).first] = mapped_type (x.begin (), x.end ());
+ }
+ else
+ (*this)[key_type (0, -1)] = other.location ();
+ return *this;
+ }
+
+ inline bool is_list () const
+ {
+ if (empty ())
+ return false;
+ if (size () > 1)
+ return true;
+
+ const key_type &elt = begin ()->first;
+ return !(elt.first == 0 && elt.second == (Dwarf_Addr) -1);
+ }
+
+ inline mapped_type &location ()
+ {
+ if (empty ())
+ return (*this)[key_type (0, -1)];
+
+ value_type &v = *begin ();
+ if (v.first.first != 0 || v.first.second != (Dwarf_Addr) -1
+ || size () > 1)
+ throw std::runtime_error ("location is list, not single location");
+
+ return v.second;
+ }
+ inline const mapped_type &location () const
+ {
+ if (size () == 1)
+ {
+ const value_type &v = *begin ();
+ if (v.first.first == 0 && v.first.second == (Dwarf_Addr) -1)
+ return v.second;
+ }
+ throw std::runtime_error ("location is list, not single location");
+ }
+ };
+
+ private:
+ class value_dispatch
+ {
+ public:
+ virtual ~value_dispatch () {}
+ };
+
+ struct value_string : public value_dispatch, public std::string
+ {
+ template<typename string>
+ value_string (const string &s) : std::string (s) {}
+
+ std::string to_string () const
+ {
+ std::string result ("\"");
+ result += *this;
+ result += "\"";
+ return result;
+ }
+ };
+
+ struct value_identifier : public value_string
+ {
+ template<typename id>
+ value_identifier (const id &s) : value_string (s) {}
+ };
+
+ struct value_reference : public value_dispatch
+ {
+ debug_info_entry::children::iterator ref;
+ value_reference (const debug_info_entry::children::iterator &i)
+ : ref (i) {}
+
+ template<typename iter> // XXX dummy
+ value_reference (const iter &i) : ref () {}
+ };
+ struct value_unit_reference : public value_dispatch
+ {
+ compile_units::iterator ref;
+ value_unit_reference (const compile_units::iterator &i) : ref (i) {}
+
+ template<typename iter> // XXX dummy
+ value_unit_reference (const iter &i) : ref () {}
+ };
+
+ struct value_flag : public value_dispatch
+ {
+ bool flag;
+ value_flag (bool t) : flag (t) {}
+ };
+
+ struct value_address : public value_dispatch
+ {
+ // XXX dwfl, reloc
+ ::Dwarf_Addr addr;
+ value_address (::Dwarf_Addr a) : addr (a) {}
+ };
+
+ struct value_rangelistptr : public value_dispatch, public range_list
+ {
+ template<typename list>
+ value_rangelistptr (const list &other) : range_list (other) {}
+ };
+
+ struct value_lineptr : public value_dispatch, public line_info_table
+ {
+ template<typename table>
+ value_lineptr (const table &other) : line_info_table (other) {}
+ };
+
+ struct value_constant : public value_dispatch
+ {
+ union
+ {
+ ::Dwarf_Word word;
+ ::Dwarf_Sword sword;
+ };
+ value_constant (::Dwarf_Word x) : word (x) {}
+ };
+
+ struct value_constant_block : public value_dispatch,
+ public std::vector<uint8_t>
+ {
+ template<typename block>
+ value_constant_block (const block &b)
+ : std::vector<uint8_t> (b.begin (), b.end ()) {}
+ };
+
+ struct value_dwarf_constant : public value_constant
+ {
+ value_dwarf_constant (unsigned int x) : value_constant (x) {}
+ };
+
+ struct value_source_file : public value_dispatch, public source_file
+ {
+ template<typename file>
+ value_source_file (const file &other) : source_file (other) {}
+ };
+
+ struct value_source_line : public value_dispatch
+ {
+ unsigned int n;
+ value_source_line (unsigned int m) : n (m) {}
+ };
+ typedef value_source_line value_source_column;
+
+ struct value_macptr : public value_dispatch {};
+
+ struct value_location : public value_dispatch, public location_attr
+ {
+ template<typename loc>
+ value_location (const loc &other) : location_attr (other) {}
+ };
+
+ public:
+ class attr_value
+ {
+ private:
+ value_dispatch *_m_value;
+
+ template<typename value>
+ inline void init (const value &other)
+ {
+ switch (other.what_space ())
+ {
+ case dwarf::VS_identifier:
+ _m_value = new value_identifier (other.identifier ());
+ break;
+ case dwarf::VS_string:
+ _m_value = new value_string (other.string ());
+ break;
+ case dwarf::VS_flag:
+ _m_value = new value_flag (other.flag ());
+ break;
+ case dwarf::VS_rangelistptr:
+ _m_value = new value_rangelistptr (other.ranges ());
+ break;
+ case dwarf::VS_lineptr:
+ _m_value = new value_lineptr (other.line_info ());
+ break;
+ case dwarf::VS_address:
+ _m_value = new value_address (other.address ());
+ break;
+ case dwarf::VS_constant:
+ _m_value = new value_constant (other.constant ());
+ break;
+ case dwarf::VS_source_line:
+ _m_value = new value_source_line (other.source_line ());
+ break;
+ case dwarf::VS_source_column:
+ _m_value = new value_source_column (other.source_column ());
+ break;
+ case dwarf::VS_source_file:
+ _m_value = new value_source_file (other.source_file ());
+ break;
+ case dwarf::VS_dwarf_constant:
+ _m_value = new value_dwarf_constant (other.constant ()); // XXX
+ break;
+ case dwarf::VS_reference:
+ _m_value = new value_reference (other.reference ());
+ break;
+ case dwarf::VS_unit_reference:
+ _m_value = new value_unit_reference (other.unit_reference ());
+ break;
+ case dwarf::VS_location:
+ _m_value = new value_location (other.location ());
+ break;
+#if 0
+ case dwarf::VS_macptr:
+ _m_value = new value_macptr (other.macptr ());
+ break;
+#endif
+ default:
+ case dwarf::VS_discr_list:
+ throw std::runtime_error ("XXX unimplemented");
+ }
+ }
+
+ template<typename flavor>
+ inline flavor &variant () const
+ {
+ flavor *p = dynamic_cast<flavor *> (_m_value);
+ if (p == NULL)
+ throw std::runtime_error ("wrong value type");
+ return *p;
+ }
+
+ public:
+ attr_value (const attr_value &other) : _m_value (NULL)
+ {
+ init (other);
+ }
+ template<typename value>
+ attr_value (const value &other) : _m_value (NULL)
+ {
+ init (other);
+ }
+
+ attr_value () : _m_value (NULL) {}
+
+ ~attr_value ()
+ {
+ if (_m_value != NULL)
+ delete _m_value;
+ }
+
+ inline attr_value &operator= (const attr_value &other)
+ {
+ if (_m_value != NULL)
+ {
+ delete _m_value;
+ _m_value = NULL;
+ }
+ init (other);
+ return *this;
+ }
+ template<typename value>
+ inline attr_value &operator= (const value &other)
+ {
+ if (_m_value != NULL)
+ {
+ delete _m_value;
+ _m_value = NULL;
+ }
+ init (other);
+ return *this;
+ }
+
+ dwarf::value_space what_space () const;
+ std::string to_string () const;
+
+ inline bool &flag () const
+ {
+ return variant<value_flag> ().flag;
+ }
+
+ // XXX dwfl, reloc
+ inline ::Dwarf_Addr &address () const
+ {
+ return variant<value_address> ().addr;
+ }
+
+ inline debug_info_entry::children::iterator reference () const
+ {
+ return variant<value_reference> ().ref;
+ }
+ inline compile_units::iterator unit_reference () const
+ {
+ return variant<value_unit_reference> ().ref;
+ }
+
+ inline location_attr &location () const
+ {
+ return static_cast<location_attr &> (variant<value_location> ());
+ }
+
+ inline std::string &string () const
+ {
+ return static_cast<std::string &> (variant<value_string> ());
+ }
+ inline std::string &identifier () const
+ {
+ return string ();
+ }
+
+ inline dwarf_edit::source_file &source_file () const
+ {
+ return static_cast<dwarf_edit::source_file &>
+ (variant<value_source_file> ());
+ }
+
+ inline unsigned int &source_line () const
+ {
+ return variant<value_source_line> ().n;
+ }
+
+ inline unsigned int &source_column () const
+ {
+ return variant<value_source_column> ().n;
+ }
+
+ inline ::Dwarf_Word &constant () const
+ {
+ return variant<value_constant> ().word;
+ }
+
+ inline ::Dwarf_Sword &signed_constant () const
+ {
+ return variant<value_constant> ().sword;
+ }
+
+ inline std::vector<uint8_t> &constant_block () const
+ {
+ return static_cast<std::vector<uint8_t> &>
+ (variant<value_constant_block> ());
+ }
+
+ // dwarf_constant<>
+
+ inline range_list &ranges () const
+ {
+ return static_cast<range_list &> (variant<value_rangelistptr> ());
+ }
+
+ inline line_info_table &line_info () const
+ {
+ return static_cast<line_info_table &> (variant<value_lineptr> ());
+ }
+
+ // macptr
+
+ template<typename value>
+ inline bool operator== (const value &other) const
+ {
+ const dwarf::value_space what = what_space ();
+ if (likely (other.what_space () == what))
+ switch (what)
+ {
+ case dwarf::VS_identifier:
+ return identifier () == other.identifier ();
+ case dwarf::VS_string:
+ return string () == other.string ();
+ case dwarf::VS_reference:
+ return reference () == other.reference ();
+ case dwarf::VS_unit_reference:
+ return unit_reference () == other.unit_reference ();
+ case dwarf::VS_flag:
+ return flag () == other.flag ();
+ case dwarf::VS_rangelistptr:
+ return ranges () == other.ranges ();
+ case dwarf::VS_lineptr:
+ return line_info () == other.line_info ();
+ case dwarf::VS_constant:
+ return constant () == other.constant ();
+ case dwarf::VS_source_file:
+ return source_file () == other.source_file ();
+ case dwarf::VS_source_line:
+ return source_line () == other.source_line ();
+ case dwarf::VS_source_column:
+ return source_column () == other.source_column ();
+ case dwarf::VS_address:
+ return address () == other.address ();
+ case dwarf::VS_location:
+ return location () == other.location ();
+ case dwarf::VS_dwarf_constant:
+ return constant () == other.constant (); // XXX
+#if 0
+ case dwarf::VS_macptr:
+ return macptr () == other.macptr ();
+#endif
+ default:
+ case dwarf::VS_discr_list:
+ throw std::runtime_error ("XXX unimplemented");
+ }
+ return false;
+ }
+ template<typename value>
+ inline bool operator!= (const value &other) const
+ {
+ return !(*this == other);
+ }
+ };
+
private:
compile_units _m_units;
--- /dev/null
+/* elfutils::dwarf_edit attribute value interfaces.
+ Copyright (C) 2009 Red Hat, Inc.
+ This file is part of Red Hat elfutils.
+
+ Red Hat elfutils is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by the
+ Free Software Foundation; version 2 of the License.
+
+ Red Hat elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with Red Hat elfutils; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+ In addition, as a special exception, Red Hat, Inc. gives You the
+ additional right to link the code of Red Hat elfutils with code licensed
+ under any Open Source Initiative certified open source license
+ (http://www.opensource.org/licenses/index.php) which requires the
+ distribution of source code with any binary distribution and to
+ distribute linked combinations of the two. Non-GPL Code permitted under
+ this exception must only link to the code of Red Hat elfutils through
+ those well defined interfaces identified in the file named EXCEPTION
+ found in the source code files (the "Approved Interfaces"). The files
+ of Non-GPL Code may instantiate templates or use macros or inline
+ functions from the Approved Interfaces without causing the resulting
+ work to be covered by the GNU General Public License. Only Red Hat,
+ Inc. may make changes or additions to the list of Approved Interfaces.
+ Red Hat's grant of this exception is conditioned upon your not adding
+ any new exceptions. If you wish to add a new Approved Interface or
+ exception, please contact Red Hat. You must obey the GNU General Public
+ License in all respects for all of the Red Hat elfutils code and other
+ code used in conjunction with Red Hat elfutils except the Non-GPL Code
+ covered by this exception. If you modify this file, you may extend this
+ exception to your version of the file, but you are not obligated to do
+ so. If you do not wish to provide this exception without modification,
+ you must delete this exception statement from your version and license
+ this file solely under the GPL without exception.
+
+ Red Hat elfutils is an included package of the Open Invention Network.
+ An included package of the Open Invention Network is a package for which
+ Open Invention Network licensees cross-license their patents. No patent
+ license is granted, either expressly or impliedly, by designation as an
+ included package. Should you wish to participate in the Open Invention
+ Network licensing program, please visit www.openinventionnetwork.com
+ <http://www.openinventionnetwork.com>. */
+
+#include <config.h>
+#include "dwarf_edit"
+
+using namespace elfutils;
+
+
+dwarf::value_space
+dwarf_edit::attr_value::what_space () const
+{
+ if (typeid (*_m_value) == typeid (value_flag))
+ return dwarf::VS_flag;
+ if (typeid (*_m_value) == typeid (value_dwarf_constant))
+ return dwarf::VS_dwarf_constant;
+ if (typeid (*_m_value) == typeid (value_reference))
+ return dwarf::VS_reference;
+ if (typeid (*_m_value) == typeid (value_unit_reference))
+ return dwarf::VS_unit_reference;
+ if (typeid (*_m_value) == typeid (value_lineptr))
+ return dwarf::VS_lineptr;
+ if (typeid (*_m_value) == typeid (value_macptr))
+ return dwarf::VS_macptr;
+ if (typeid (*_m_value) == typeid (value_rangelistptr))
+ return dwarf::VS_rangelistptr;
+ if (typeid (*_m_value) == typeid (value_identifier))
+ return dwarf::VS_identifier;
+ if (typeid (*_m_value) == typeid (value_string))
+ return dwarf::VS_string;
+ if (typeid (*_m_value) == typeid (value_source_file))
+ return dwarf::VS_source_file;
+ if (typeid (*_m_value) == typeid (value_source_line))
+ return dwarf::VS_source_line;
+ if (typeid (*_m_value) == typeid (value_source_column))
+ return dwarf::VS_source_column;
+ if (typeid (*_m_value) == typeid (value_address))
+ return dwarf::VS_address;
+ if (typeid (*_m_value) == typeid (value_constant))
+ return dwarf::VS_constant;
+ if (typeid (*_m_value) == typeid (value_location))
+ return dwarf::VS_location;
+
+ throw std::runtime_error ("XXX impossible");
+}