]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: ref_record is now template parametrized by locus type pmachata/dwarflint
authorPetr Machata <pmachata@redhat.com>
Tue, 19 Apr 2011 13:10:06 +0000 (15:10 +0200)
committerPetr Machata <pmachata@redhat.com>
Tue, 19 Apr 2011 13:10:06 +0000 (15:10 +0200)
- the theory being that most of the time all you need to track comes from
  one source
- the upshot is that now the locus::clone and related business can go away

13 files changed:
dwarflint/addr-record.cc
dwarflint/addr-record.hh
dwarflint/check_debug_abbrev.hh
dwarflint/check_debug_aranges.hh
dwarflint/check_debug_info.cc
dwarflint/check_debug_info.hh
dwarflint/check_debug_line.cc
dwarflint/check_debug_loc_range.cc
dwarflint/check_debug_loc_range.hh
dwarflint/die_locus.hh
dwarflint/locus.cc
dwarflint/locus.hh
dwarflint/reloc.cc

index f4cc87b9bdb40bf28fca06f952b89e951cf39c60..220f4b1dc6bb74de352ae4026de0a2a92549e273 100644 (file)
@@ -66,36 +66,3 @@ addr_record::add (uint64_t addr)
   if (it == end () || *it != addr)
     insert (it, addr);
 }
-
-ref::ref ()
-  : addr (-1)
-  , who (NULL)
-{}
-
-ref::ref (uint64_t a_addr, locus const &a_who)
-  : addr (a_addr)
-  , who (a_who.clone ())
-{}
-
-ref::ref (ref const &copy)
-  : who (NULL)
-{
-  *this = copy;
-}
-
-ref &
-ref::operator= (ref const &copy)
-{
-  if (&copy != this)
-    {
-      addr = copy.addr;
-      delete who;
-      who = copy.who ? copy.who->clone () : NULL;
-    }
-  return *this;
-}
-
-ref::~ref ()
-{
-  delete who;
-}
index 1772c9315d42fa5f457430ce496787baf32dcd29..4bbd0c51d0e5c0e6cc44ac119a6b8d5dd011ea07 100644 (file)
 
 #include "locus.hh"
 
-/* Functions and data structures for address record handling.  We
-   use that to check that all DIE references actually point to an
-   existing die, not somewhere mid-DIE, where it just happens to be
-   interpretable as a DIE.  */
-
+/// Address record is used to check that all DIE references actually
+/// point to an existing die, not somewhere mid-DIE, where it just
+/// happens to be interpretable as a DIE.  This is stored as sorted
+/// array for quick lookup and duplicate removal.
 struct addr_record
   : private std::vector<uint64_t>
 {
@@ -48,27 +47,31 @@ public:
   void add (uint64_t addr);
 };
 
-/* Functions and data structures for reference handling.  Just like
-   the above, we use this to check validity of DIE references.
-   Unlike the above, this is not stored as sorted set, but simply as
-   an array of records, because duplicates are unlikely.  */
-
-struct ref
+/// One reference for use in ref_record, parametrized by locus type.
+template <class L>
+struct ref_T
 {
   uint64_t addr; // Referee address
-  locus *who;    // Referrer
+  L who;         // Referrer
+
+  ref_T ()
+    : addr (-1)
+  {}
 
-  ref ();
-  ref (uint64_t a_addr, locus const &a_who);
-  ref (ref const &copy);
-  ~ref ();
-  ref &operator= (ref const &copy);
+  ref_T (uint64_t a_addr, L const &a_who)
+    : addr (a_addr)
+    , who (a_who)
+  {}
 };
 
-class ref_record
-  : private std::vector<struct ref>
+/// Reference record is used to check validity of DIE references.
+/// Unlike the above, this is not stored as sorted set, but simply as
+/// an array of records, because duplicates are unlikely.
+template <class L>
+class ref_record_T
+  : private std::vector<ref_T<L> >
 {
-  typedef std::vector<struct ref> _super_t;
+  typedef std::vector<ref_T<L> > _super_t;
 public:
   using _super_t::const_iterator;
   using _super_t::begin;
index 9565f885454ced2ed4057343104f23e2e7e8b1c5..54d03ce872512b8c3cb092c2819f0882cf95c619 100644 (file)
@@ -41,7 +41,7 @@ typedef fixed_locus<sec_abbrev,
                    locus_simple_fmt::hex> abbrev_locus;
 
 class abbrev_attrib_locus
-  : public clonable_locus<abbrev_attrib_locus>
+  : public locus
 {
   uint64_t _m_abbr_offset;
   uint64_t _m_attr_offset;
index 9840245c925da05a3cdf1a22ee9f4d68f880cdd9..109cf0bc97d4dfb15b8fa2801dd2c980c855d0f4 100644 (file)
@@ -56,7 +56,7 @@ public:
 };
 
 class arange_locus
-  : public clonable_locus<arange_locus>
+  : public locus
 {
   Dwarf_Off _m_table_offset;
   Dwarf_Off _m_arange_offset;
index 5aff2b996ee5af4d8146a243063d7ea66b5e45a4..e415fb180a7f26ca3ec0a4452437b730bc3f4087 100644 (file)
@@ -109,15 +109,14 @@ namespace
   }
 
   bool
-  check_die_references (struct cu *cu,
-                       struct ref_record *die_refs)
+  check_die_references (cu *cu, ref_record *die_refs)
   {
     bool retval = true;
     for (ref_record::const_iterator it = die_refs->begin ();
         it != die_refs->end (); ++it)
       if (!cu->die_addrs.has_addr (it->addr))
        {
-         wr_error (*it->who)
+         wr_error (it->who)
            << "unresolved reference to " << pri::DIE (it->addr)
            << '.' << std::endl;
          retval = false;
@@ -143,7 +142,7 @@ namespace
 
          if (ref_cu == NULL)
            {
-             wr_error (*rt->who)
+             wr_error (rt->who)
                << "unresolved (non-CU-local) reference to "
                << pri::hex (rt->addr) << '.' << std::endl;
              retval = false;
@@ -153,7 +152,7 @@ namespace
               reference is valid, which it is.  But warn about this
               anyway, perhaps local reference could be formed on
               smaller number of bytes.  */
-           wr_message (*rt->who, mc_impact_2 | mc_acc_suboptimal | mc_die_rel)
+           wr_message (rt->who, mc_impact_2 | mc_acc_suboptimal | mc_die_rel)
              << "local reference to " << pri::DIE (rt->addr)
              << " formed as global." << std::endl;
        }
@@ -390,9 +389,9 @@ namespace
   struct value_check_cb_ctx
   {
     struct read_ctx *const ctx;
-    locus const *where;
+    die_locus const *where;
     struct cu *const cu;
-    struct ref_record *local_die_refs;
+    ref_record *local_die_refs;
     Elf_Data *strings;
     struct coverage *strings_coverage;
     struct coverage *pc_coverage;
@@ -525,14 +524,14 @@ namespace
   int
   read_die_chain (dwarf_version const *ver,
                  elf_file const &file,
-                 struct read_ctx *ctx,
-                 struct cu *cu,
-                 struct abbrev_table const *abbrevs,
+                 read_ctx *ctx,
+                 cu *cu,
+                 abbrev_table const *abbrevs,
                  Elf_Data *strings,
-                 struct ref_record *local_die_refs,
-                 struct coverage *strings_coverage,
-                 struct relocation_data *reloc,
-                 struct coverage *pc_coverage,
+                 ref_record *local_die_refs,
+                 coverage *strings_coverage,
+                 relocation_data *reloc,
+                 coverage *pc_coverage,
                  bool *need_rangesp,
                  unsigned level)
   {
@@ -1075,7 +1074,7 @@ check_debug_info::check_debug_info (checkstack &stack, dwarflint &lint)
   sec &sec = _m_sec_info->sect;
   Elf_Data *const strings = _m_sec_str->sect.data;
 
-  struct ref_record die_refs;
+  ref_record die_refs;
 
   bool success = true;
 
@@ -1253,12 +1252,12 @@ check_debug_info_refs::check_debug_info_refs (checkstack &stack,
       if (it->stmt_list.addr == (uint64_t)-1)
        for (ref_record::const_iterator jt = it->decl_file_refs.begin ();
             jt != it->decl_file_refs.end (); ++jt)
-         wr_error (*jt->who)
+         wr_error (jt->who)
            << "references .debug_line table, but CU DIE lacks DW_AT_stmt_list."
            << std::endl;
       else if (_m_line == NULL
               || !_m_line->has_line_table (it->stmt_list.addr))
-       wr_error (*it->stmt_list.who)
+       wr_error (it->stmt_list.who)
          << "unresolved reference to .debug_line table "
          << pri::hex (it->stmt_list.addr) << '.' << std::endl;
 
index ad139c3af6651201fe34652eb35d4688bd2ebaca..e8dc8506930d5f9aa064d3129adb5d7285ba199f 100644 (file)
@@ -37,6 +37,9 @@
 #include "sections_i.hh"
 #include "die_locus.hh"
 
+typedef ref_T<die_locus> ref;
+typedef ref_record_T<die_locus> ref_record;
+
 struct cu_head
 {
   Dwarf_Off offset;
@@ -68,15 +71,15 @@ struct cu
 {
   struct cu *next;              // For compatibility with C level.
                                 // xxx will probably go away eventually
-  struct cu_head const *head;
+  cu_head const *head;
   uint64_t cudie_offset;
   uint64_t low_pc;              // DW_AT_low_pc value of CU DIE, -1 if not present.
-  struct ref stmt_list;
-  struct addr_record die_addrs; // Addresses where DIEs begin in this CU.
-  struct ref_record die_refs;   // DIE references into other CUs from this CU.
-  struct ref_record loc_refs;   // references into .debug_loc from this CU.
-  struct ref_record range_refs; // references into .debug_ranges from this CU.
-  struct ref_record decl_file_refs;  // values of DW_AT_decl_file in this CU.
+  ::ref stmt_list;
+  addr_record die_addrs;        // Addresses where DIEs begin in this CU.
+  ref_record die_refs;          // DIE references into other CUs from this CU.
+  ref_record loc_refs;          // references into .debug_loc from this CU.
+  ref_record range_refs;        // references into .debug_ranges from this CU.
+  ref_record decl_file_refs;    // values of DW_AT_decl_file in this CU.
   bool has_arange;              // Whether we saw arange section pointing at this CU.
   bool has_pubnames;            // Likewise for pubnames.
   bool has_pubtypes;            // Likewise for pubtypes.
index 57238bc4b90c4bed15a63a3eb522fc1bd0a8824d..d75aed2bd034f41dfc267dcfdef0dabebc5215a9 100644 (file)
@@ -358,7 +358,7 @@ check_debug_line::check_debug_line (checkstack &stack, dwarflint &lint)
                for (ref_record::const_iterator
                       jt = it->decl_file_refs.begin ();
                     jt != it->decl_file_refs.end (); ++jt)
-                 if (!use_file (files, jt->addr, *jt->who))
+                 if (!use_file (files, jt->addr, jt->who))
                    success = false;
              }
          if (!found)
index 9c0017446d279f394274d8f3c16af2a1a117dbe6..ac6f789fc73f3fbaf6f5ec7b6411ceefce957623 100644 (file)
@@ -579,9 +579,12 @@ namespace
 
   struct ref_cu
   {
-    struct ref ref;
-    struct cu *cu;
-    bool operator < (ref_cu const& other) const {
+    ::ref ref;
+    ::cu *cu;
+
+    bool
+    operator < (ref_cu const& other) const
+    {
       return ref.addr < other.ref.addr;
     }
   };
@@ -627,7 +630,7 @@ namespace
     ref_cu_vect refs;
     for (struct cu *cu = cu_chain; cu != NULL; cu = cu->next)
       {
-       struct ref_record *rec
+       ref_record *rec
          = sec->id == sec_loc ? &cu->loc_refs : &cu->range_refs;
        for (ref_record::const_iterator it = rec->begin ();
             it != rec->end (); ++it)
@@ -664,7 +667,7 @@ namespace
           Perhaps that's undesirable.  */
        if (!check_loc_or_range_ref (ver, file, &ctx, it->cu, sec,
                                     &coverage, coverage_map, pc_coverage,
-                                    off, *it->ref.who, cat))
+                                    off, it->ref.who, cat))
          retval = false;
        last_off = off;
       }
@@ -858,10 +861,10 @@ namespace
 }
 
 class locexpr_locus
-  : public clonable_locus<locexpr_locus>
+  : public locus
 {
-  uint64_t const _m_offset;
-  locus const *const _m_context;
+  uint64_t _m_offset;
+  locus const *_m_context;
 
 public:
   explicit locexpr_locus (uint64_t offset, locus const *context)
@@ -897,7 +900,9 @@ check_location_expression (dwarf_version const *ver,
       return false;
     }
 
-  ref_record oprefs;
+  typedef ref_T<locexpr_locus> locexpr_ref;
+  typedef ref_record_T<locexpr_locus> locexpr_ref_record;
+  locexpr_ref_record oprefs;
   addr_record opaddrs;
 
   while (!read_ctx_eof (&ctx))
@@ -954,7 +959,7 @@ check_location_expression (dwarf_version const *ver,
            else
              {
                uint64_t off_after = read_ctx_get_offset (&ctx) + init_off;
-               oprefs.push_back (ref (off_after + skip, where));
+               oprefs.push_back (locexpr_ref (off_after + skip, where));
              }
 
            break;
@@ -983,11 +988,11 @@ check_location_expression (dwarf_version const *ver,
     }
 
  out:
-  for (ref_record::const_iterator it = oprefs.begin ();
+  for (locexpr_ref_record::const_iterator it = oprefs.begin ();
        it != oprefs.end (); ++it)
     if (!opaddrs.has_addr (it->addr))
-      wr_error (*it->who) << "unresolved reference to opcode at "
-                         << pri::hex (it->addr) << ".\n";
+      wr_error (it->who) << "unresolved reference to opcode at "
+                        << pri::hex (it->addr) << ".\n";
 
   return true;
 }
index 882b529b4a236cebd2e6e89fb9f0f56c9d3174d2..cbc1e7cbf30c561da45905a50a71dd67577989d1 100644 (file)
@@ -31,7 +31,7 @@
 #include "dwarf_version_i.hh"
 
 class loc_range_locus
-  : public clonable_locus<loc_range_locus>
+  : public locus
 {
   locus const &_m_parent;
   Dwarf_Off _m_offset;
index 9363bc8d713985703c2962b96a1386e65456fec8..0c57d4f54bd6c68fc1915308749233a0beaed359 100644 (file)
@@ -39,13 +39,13 @@ typedef fixed_locus<sec_info,
                    locus_simple_fmt::dec> cu_locus;
 
 class die_locus
-  : public clonable_locus<die_locus>
+  : public locus
 {
   Dwarf_Off _m_offset;
   int _m_attrib_name;
 
 public:
-  explicit die_locus (Dwarf_Off offset, int attrib_name = -1)
+  explicit die_locus (Dwarf_Off offset = -1, int attrib_name = -1)
     : _m_offset (offset)
     , _m_attrib_name (attrib_name)
   {}
index 19efd1a61e57203b55f166888f70366a33036c55..553e7d8b7e31d7d7f8b0cfc1c78437823f62bfa8 100644 (file)
 #include "locus.hh"
 #include "section_id.hh"
 #include <sstream>
+#include <iostream>
+
+std::ostream &
+operator << (std::ostream &os, locus const &loc)
+{
+  os << loc.format ();
+  return os;
+}
 
 char const *
 locus_simple_fmt::offset_n ()
index 3a61b9a83a868fea8dce9067b4bb7d9013f9edcf..4557c2a7c8b9ab1bbdd5b69d852b60a470db2e26 100644 (file)
 #include "section_id.hh"
 
 #include <stdint.h>
-#include <stdlib.h>
 #include <iosfwd>
-#include <iostream>
-#include <cassert>
+#include <string>
 
 /// Instances of the locus subclasses are used as pointers into
 /// debuginfo for documentation purposes (messages and errors).  They
@@ -43,23 +41,10 @@ class locus
 {
 public:
   virtual std::string format (bool brief = false) const = 0;
-  virtual locus *clone () const = 0;
   virtual ~locus () {}
 };
 
-/// This is to simplify creation of subclasses.  Most locus subclasses
-/// should in fact inherit from this using CRTP:
-///   class X: public clonable_locus<X>
-template <class T>
-class clonable_locus
-  : public locus
-{
-public:
-  virtual locus *clone () const
-  {
-    return new T (*static_cast<T const*> (this));
-  }
-};
+std::ostream &operator << (std::ostream &os, locus const &loc);
 
 /// Helper class for simple_locus to reduce the template bloat.
 class simple_locus_aux
@@ -79,7 +64,7 @@ protected:
 template<char const *(*N) (),
         void (*F) (std::ostream &, uint64_t)>
 class simple_locus
-  : public clonable_locus<simple_locus<N, F> >
+  : public locus
   , private simple_locus_aux
 {
   section_id _m_sec;
@@ -124,11 +109,4 @@ namespace locus_simple_fmt
 typedef simple_locus<locus_simple_fmt::offset_n,
                     locus_simple_fmt::hex> section_locus;
 
-inline std::ostream &
-operator << (std::ostream &os, locus const &loc)
-{
-  os << loc.format ();
-  return os;
-}
-
 #endif//DWARFLINT_WHERE_HH
index dce458a19a4b04a0ec062eab2b82a7a156647e55..ff1aaa2dbca1e40596d0809abf6f3835d4dad1c0 100644 (file)
@@ -41,7 +41,7 @@
 namespace
 {
   class reloc_locus
-    : public clonable_locus<reloc_locus>
+    : public locus
   {
     locus const &_m_ref;
     size_t _m_index;