Bug 19126 - abidw segv on a dwz compressed version of r300_dri.so
authorDodji Seketeli <dodji@redhat.com>
Thu, 10 Dec 2015 13:18:46 +0000 (14:18 +0100)
committerDodji Seketeli <dodji@redhat.com>
Thu, 10 Dec 2015 15:47:18 +0000 (16:47 +0100)
Suppose a declaration D (which locus is in a file F) is imported at an
offset offset of O1 into a compilation unit C1 and at an offset O2
(using DW_TAG_imported_unit) into a compilation unit C2.

When the DWARF reader creates the ABI artifact for D in O1, its
location is encoded by a location manager that is handled by C1.

At O2 (in C2) the ABI artifact for D (created at O1, in C1) is
re-used.  But then, to decode the location of D, the DWARF reader
wrongly uses the location manager that is handled by C2.  It should
use the location manager of C1, because that is the one used to encode
the location of D.

It picks the wrong location manager because it picks the wrong
translation unit for D. Right now, the translation unit for a given
declaration is the "current" translation unit at the moment the DIE
was being inspected.  And that is wrong when imported type units kick
in.

1/ More generally, each ABI artifact should be associated with its
translation unit, which is the current translation unit when the
artifact was created.  As there is just one copy of D, its translation
unit should always be the same.

2/ Also, the location should ensure that about the location manager used
to encode it is the same one used to decode it, so that this kind of
bug cannot arise.

This patch fixes the issue by doing 1/ and 2/.  The r300_dri.so test
case on which is was failing is not added to the test suite because
it's too big.  It was taking more than 55 minutes to have complete
abidw --abidiff complete on that binary, on my machine.  So I am going
to work on the performance side of things, I think.

* include/abg-ir.h (class location_manager): Forward declare it
before class location.
(location::loc_manager_): New data member.
(location::location): Take the location manager in one overload
and initialize the new loc_managers_ in all the overloads.
(location::get_location_manager): New getter.
(location::expand): New member function.
(location::*): Add API doc to all entry points.
(location_manager::expand_location): Take a const location.
(type_or_decl_base::set_corpus): Remove.
(type_or_decl_base::{get,set}_translation): New accessors.
(decl_base::{decl_base,get_location}): Take or return a reference
on location.
(scope_decl::scope_decl): Likewise.
(type_decl::type_decl): Likewise.
(namespace_decl::namespace_decl): Likewise.
(qualified_type_def::qualified_type_def): Likewise.
(pointer_type_def::pointer_type_def): Likewise.
(reference_type_def::reference_type_def): Likewise.
(array_type_def::subrange_type::{subrange_type,
get_location}): Likewise.
(enum_type_decl::enum_type_decl): Likewise.
(typedef_decl::typedef_decl): Likewise.
(var_decl::var_decl): Likewise.
(function_decl::function_decl): Likewise.
(function_decl::parameter::parameter): Likewise.
(template_decl::template_decl): Likewise.
(type_tparameter::type_tparameter): Likewise.
(non_type_tparameter::non_type_tparameter): Likewise.
(function_tdecl::function_tdecl): Likewise.
(class_tdecl::class_tdecl): Likewise.
(class_decl::class_decl): Likewise.
(class_decl::method_decl::method_decl): Likewise.
* src/abg-ir.cc (location::expand_location): Define new member
function.
(type_or_decl_base::priv::corpus_): Remove.
(type_or_decl_base::priv::translation_unit_): New data member.
(type_or_decl_base::priv::priv): Adjust.
(type_or_decl_base::set_corpus): Remove.
(type_or_decl_base::get_corpus): Adjust.
(type_or_decl_base::{get,set}_translation_unit): New member
functions.
(decl_base::priv::priv): Take a reference to location.
(decl_base::decl_base): Likewise.
(decl_base::get_location): Return a reference to location.
(location_manager::create_new_location): Adjust.
(location_manager::expand_location): Take a reference to location.
(translation_unit::get_global_scope()): Adjust.
(translation_unit::bind_function_type_life_time): Likewise.
(scope_decl::{add,insert}_member_decl): Adjust.
(get_translation_unit): Likewise.
(type_decl::type_decl): Take a reference to location.
(namespace_decl::namespace_decl): Likewise.
(qualified_type_def::qualified_type_def): Likewise.
(pointer_type_def::pointer_type_def): Likewise.
(reference_type_def::reference_type_def): Likewise.
(array_type_def::subrange_type::priv::priv): Likewise.
(array_type_def::subrange_type::{subrange_type,
get_location}): Likewise.
(enum_type_decl::enum_type_decl): Likewise.
(typedef_decl::typedef_decl): Likewise.
(var_decl::var_decl): Likewise.
(function_decl::function_decl): Likewise.
(function_decl::parameter::parameter): Likewise.
(template_decl::template_decl): Likewise.
(type_tparameter::type_tparameter): Likewise.
(non_type_tparameter::non_type_tparameter): Likewise.
(function_tdecl::function_tdecl): Likewise.
(class_tdecl::class_tdecl): Likewise.
(class_decl::class_decl): Likewise.
(class_decl::method_decl::method_decl): Likewise.
* src/abg-writer.cc (write_location): Take a reference to
location and adjust.
(write_array_type_def, write_function_decl, dump_decl_location):
Adjust.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
include/abg-ir.h
src/abg-ir.cc
src/abg-writer.cc

index 7241741..a45f18f 100644 (file)
@@ -171,6 +171,7 @@ public:
   friend void keep_type_alive(type_base_sptr);
 }; // end class environment
 
+class location_manager;
 /// @brief The source location of a token.
 ///
 /// This represents the location of a token coming from a given
@@ -183,27 +184,82 @@ public:
 class location
 {
   unsigned             value_;
+  // The location manager to use to decode the value above.  There is
+  // one location manager per translation unit, and the location
+  // manager's life time is managed by its translation unit.
+  location_manager*    loc_manager_;
 
-  location(unsigned v) : value_(v) {}
+  location(unsigned v, location_manager* m)
+    : value_(v), loc_manager_(m)
+  {}
+
+  /// Get the location manager to use to decode the value of this
+  /// location.
+  ///
+  /// @return the location manager for the current location value.
+  location_manager*
+  get_location_manager() const
+  {return loc_manager_;}
 
 public:
 
-  location() : value_(0) { }
+  /// Copy constructor of the location.
+  ///
+  /// @param l the location to copy from.
+  location(const location& l)
+    : value_(l.value_),
+      loc_manager_(l.loc_manager_)
+  {}
+
+  /// Default constructor for the @ref location type.
+  location()
+    : value_(), loc_manager_()
+  {}
 
+  /// Get the value of the location.
   unsigned
   get_value() const
   {return value_;}
 
+  /// Convert the location into a boolean.
+  ///
+  /// @return true iff the value of the location is different from
+  /// zero.
   operator bool() const
-  { return !!value_; }
+  {return !!value_;}
 
+  /// Equality operator of the @ref location type.
+  ///
+  /// @param other the other location to compare against.
+  ///
+  /// @return true iff both locations are equal.
   bool
   operator==(const location other) const
   {return value_ == other.value_;}
 
+  /// "Less than" operator of the @ref location type.
+  ///
+  /// @parm other the other location type to compare against.
+  ///
+  /// @return true iff the current instance is less than the @p other
+  /// one.
   bool
   operator<(const location other) const
-  { return value_ < other.value_; }
+  {return value_ < other.value_;}
+
+  /// Expand the current location into a tripplet file path, line and
+  /// column number.
+  ///
+  /// @param path the output parameter this function sets the expanded
+  /// path to.
+  ///
+  /// @param line the output parameter this function sets the expanded
+  /// line number to.
+  ///
+  /// @param column the output parameter this function sets the
+  /// expanded column number to.
+  void
+  expand(std::string& path, unsigned& line, unsigned& column) const;
 
   friend class location_manager;
 }; // end class location
@@ -227,7 +283,7 @@ public:
   create_new_location(const std::string& fle, size_t lne, size_t col);
 
   void
-  expand_location(const location location, std::string& path,
+  expand_location(const location& location, std::string& path,
                  unsigned& line, unsigned& column) const;
 };
 
@@ -856,12 +912,15 @@ public:
   void
   set_environment(environment*);
 
-  void
-  set_corpus(const corpus*);
-
   const corpus*
   get_corpus() const;
 
+  void
+  set_translation_unit(const translation_unit*);
+
+  const translation_unit*
+  get_translation_unit() const;
+
   virtual bool
   traverse(ir_node_visitor&);
 
@@ -948,11 +1007,11 @@ protected:
   set_context_rel(context_rel_sptr c);
 
 public:
-  decl_base(const std::string& name, location locus,
+  decl_base(const std::string& name, const location& locus,
            const std::string&  mangled_name = "",
            visibility vis = VISIBILITY_DEFAULT);
 
-  decl_base(location);
+  decl_base(const location&);
 
   decl_base(const decl_base&);
 
@@ -982,7 +1041,7 @@ public:
   void
   set_is_in_public_symbol_table(bool);
 
-  location
+  const location&
   get_location() const;
 
   void
@@ -1118,13 +1177,13 @@ protected:
 public:
   struct hash;
 
-  scope_decl(const std::string& name, location locus,
+  scope_decl(const std::string& name, const location& locus,
             visibility vis = VISIBILITY_DEFAULT)
     : type_or_decl_base(),
       decl_base(name, locus, /*mangled_name=*/name, vis)
   {}
 
-  scope_decl(location l) : decl_base("", l)
+  scope_decl(location& l) : decl_base("", l)
   {}
 
   virtual size_t
@@ -1348,8 +1407,10 @@ public:
   struct hash;
 
   type_decl(const std::string& name,
-           size_t size_in_bits, size_t alignment_in_bits,
-           location locus, const std::string&  mangled_name = "",
+           size_t size_in_bits,
+           size_t alignment_in_bits,
+           const location& locus,
+           const std::string&  mangled_name = "",
            visibility vis = VISIBILITY_DEFAULT);
 
   virtual bool
@@ -1387,7 +1448,7 @@ public:
   struct hash;
 
   scope_type_decl(const std::string& name, size_t size_in_bits,
-                 size_t alignment_in_bits, location locus,
+                 size_t alignment_in_bits, const location& locus,
                  visibility vis = VISIBILITY_DEFAULT);
 
   virtual bool
@@ -1410,7 +1471,7 @@ class namespace_decl : public scope_decl
 {
 public:
 
-  namespace_decl(const std::string& name, location locus,
+  namespace_decl(const std::string& name, const location& locus,
                 visibility vis = VISIBILITY_DEFAULT);
 
   virtual string
@@ -1458,7 +1519,7 @@ public:
     CV_RESTRICT = 1 << 2
   };
 
-  qualified_type_def(type_base_sptr type, CV quals, location locus);
+  qualified_type_def(type_base_sptr type, CV quals, const location& locus);
 
   virtual size_t
   get_size_in_bits() const;
@@ -1534,7 +1595,7 @@ public:
   struct hash;
 
   pointer_type_def(const type_base_sptr& pointed_to_type, size_t size_in_bits,
-                  size_t alignment_in_bits, location locus);
+                  size_t alignment_in_bits, const location& locus);
 
   virtual bool
   operator==(const decl_base&) const;
@@ -1585,7 +1646,7 @@ public:
 
   reference_type_def(const type_base_sptr pointed_to_type,
                     bool lvalue, size_t size_in_bits,
-                    size_t alignment_in_bits, location locus);
+                    size_t alignment_in_bits, const location& locus);
 
   virtual bool
   operator==(const decl_base&) const;
@@ -1662,10 +1723,11 @@ public:
     /// Hasher for an instance of array::subrange
     struct hash;
 
-    subrange_type(size_t lower_bound, size_t upper_bound,
-                 location loc);
+    subrange_type(size_t lower_bound,
+                 size_t upper_bound,
+                 const location& loc);
 
-    subrange_type(size_t upper_bound, location loc);
+    subrange_type(size_t upper_bound, const location& loc);
 
     size_t
     get_upper_bound() const;
@@ -1688,13 +1750,13 @@ public:
     bool
     operator==(const subrange_type& o) const;
 
-    location
+    const location&
     get_location() const;
   };
 
   array_type_def(const type_base_sptr type,
                 const std::vector<subrange_sptr>& subs,
-                location locus);
+                const location& locus);
 
   virtual bool
   operator==(const decl_base&) const;
@@ -1732,7 +1794,7 @@ public:
   virtual bool
   traverse(ir_node_visitor& v);
 
-  location
+  const location&
   get_location() const;
 
   const std::vector<subrange_sptr>&
@@ -1788,7 +1850,7 @@ public:
   /// @param mangled_name the mangled name of the enum type.
   ///
   /// @param vis the visibility of instances of this type.
-  enum_type_decl(const string& name, location locus,
+  enum_type_decl(const string& name, const location& locus,
                 type_base_sptr underlying_type,
                 enumerators& enms, const std::string& mangled_name = "",
                 visibility vis = VISIBILITY_DEFAULT);
@@ -1883,7 +1945,7 @@ public:
   struct hash;
 
   typedef_decl(const string& name, const shared_ptr<type_base> underlying_type,
-              location locus, const std::string& mangled_name = "",
+              const location& locus, const std::string& mangled_name = "",
               visibility vis = VISIBILITY_DEFAULT);
 
   virtual size_t
@@ -2006,7 +2068,7 @@ public:
 
   var_decl(const std::string&          name,
           shared_ptr<type_base>        type,
-          location                     locus,
+          const location&              locus,
           const std::string&           mangled_name,
           visibility                   vis = VISIBILITY_DEFAULT,
           binding                      bind = BINDING_NONE);
@@ -2099,7 +2161,7 @@ public:
   function_decl(const std::string& name,
                function_type_sptr function_type,
                bool declared_inline,
-               location locus,
+               const location& locus,
                const std::string& mangled_name,
                visibility vis,
                binding bind);
@@ -2107,7 +2169,7 @@ public:
   function_decl(const std::string& name,
                shared_ptr<type_base> fn_type,
                bool declared_inline,
-               location locus,
+               const location& locus,
                const std::string& mangled_name = "",
                visibility vis = VISIBILITY_DEFAULT,
                binding bind = BINDING_GLOBAL);
@@ -2201,19 +2263,19 @@ public:
   parameter(const type_base_sptr       type,
            unsigned                    index,
            const std::string&          name,
-           location                    loc,
+           const location&             loc,
            bool                        variadic_marker = false);
 
   parameter(const type_base_sptr       type,
            unsigned                    index,
            const std::string&          name,
-           location                    loc,
+           const location&             loc,
            bool                        variadic_marker,
            bool                        is_artificial);
 
   parameter(const type_base_sptr       type,
            const std::string&          name,
-           location                    loc,
+           const location&             loc,
            bool                        variadic_marker = false,
            bool                        is_artificial   = false);
 
@@ -2445,9 +2507,9 @@ public:
   /// Hasher.
   struct hash;
 
-  template_decl(const string& name,
-               location locus,
-               visibility vis = VISIBILITY_DEFAULT);
+  template_decl(const string&          name,
+               const location& locus,
+               visibility              vis = VISIBILITY_DEFAULT);
 
   void
   add_template_parameter(const template_parameter_sptr p);
@@ -2529,7 +2591,7 @@ public:
   type_tparameter(unsigned             index,
                  template_decl_sptr    enclosing_tdecl,
                  const std::string&    name,
-                 location              locus);
+                 const location&       locus);
 
   virtual bool
   operator==(const type_base&) const;
@@ -2567,8 +2629,8 @@ public:
   non_type_tparameter(unsigned                 index,
                      template_decl_sptr        enclosing_tdecl,
                      const std::string&        name,
-                     shared_ptr<type_base>     type,
-                     location                  locus);
+                     type_base_sptr            type,
+                     const location&           locus);
   virtual size_t
   get_hash() const;
 
@@ -2614,10 +2676,10 @@ public:
   /// A hasher for instances of template_tparameter
   struct hash;
 
-  template_tparameter(unsigned index,
-                     template_decl_sptr enclosing_tdecl,
-                     const std::string& name,
-                     location locus);
+  template_tparameter(unsigned                 index,
+                     template_decl_sptr        enclosing_tdecl,
+                     const std::string&        name,
+                     const location&           locus);
 
   virtual bool
   operator==(const type_base&) const;
@@ -2698,12 +2760,12 @@ public:
   struct hash;
   struct shared_ptr_hash;
 
-  function_tdecl(location      locus,
-                visibility     vis = VISIBILITY_DEFAULT,
-                binding        bind = BINDING_NONE);
+  function_tdecl(const location&       locus,
+                visibility             vis = VISIBILITY_DEFAULT,
+                binding                bind = BINDING_NONE);
 
   function_tdecl(function_decl_sptr    pattern,
-                location               locus,
+                const location&        locus,
                 visibility             vis = VISIBILITY_DEFAULT,
                 binding                bind = BINDING_NONE);
 
@@ -2751,10 +2813,11 @@ public:
   struct hash;
   struct shared_ptr_hash;
 
-  class_tdecl(location locus, visibility vis = VISIBILITY_DEFAULT);
+  class_tdecl(const location& locus, visibility vis = VISIBILITY_DEFAULT);
 
-  class_tdecl(shared_ptr<class_decl> pattern,
-             location locus, visibility vis = VISIBILITY_DEFAULT);
+  class_tdecl(class_decl_sptr  pattern,
+             const location&   locus,
+             visibility        vis = VISIBILITY_DEFAULT);
 
   virtual bool
   operator==(const decl_base&) const;
@@ -2830,13 +2893,13 @@ public:
 
   class_decl(const std::string& name, size_t size_in_bits,
             size_t align_in_bits, bool is_struct,
-            location locus, visibility vis,
+            const location& locus, visibility vis,
             base_specs& bases, member_types& mbrs,
             data_members& data_mbrs, member_functions& member_fns);
 
   class_decl(const std::string& name, size_t size_in_bits,
             size_t align_in_bits, bool is_struct,
-            location locus, visibility vis);
+            const location& locus, visibility vis);
   class_decl(const std::string& name, bool is_struct,
             bool is_declaration_only = true);
 
@@ -3284,22 +3347,22 @@ class class_decl::method_decl : public function_decl
 
 public:
 
-  method_decl(const std::string& name, shared_ptr<method_type> type,
-             bool declared_inline, location locus,
+  method_decl(const std::string& name, method_type_sptr type,
+             bool declared_inline, const location& locus,
              const std::string& mangled_name = "",
              visibility vis = VISIBILITY_DEFAULT,
              binding   bind = BINDING_GLOBAL);
 
   method_decl(const std::string& name,
-             shared_ptr<function_type> type,
+             function_type_sptr type,
              bool declared_inline,
-             location locus,
+             const location& locus,
              const std::string& mangled_name = "",
              visibility vis  = VISIBILITY_DEFAULT,
              binding   bind = BINDING_GLOBAL);
 
-  method_decl(const std::string& name, shared_ptr<type_base> type,
-             bool declared_inline, location locus,
+  method_decl(const std::string& name, type_base_sptr type,
+             bool declared_inline, const location& locus,
              const std::string& mangled_name = "",
              visibility vis = VISIBILITY_DEFAULT,
              binding bind = BINDING_GLOBAL);
index 13b7006..d890ad9 100644 (file)
@@ -176,6 +176,23 @@ public:
   }
 };
 
+/// Expand the location into a tripplet path, line and column number.
+///
+/// @param path the output parameter where this function sets the
+/// expanded path.
+///
+/// @param line the output parameter where this function sets the
+/// expanded line.
+///
+/// @param column the ouptut parameter where this function sets the
+/// expanded column.
+void
+location::expand(std::string& path, unsigned& line, unsigned& column) const
+{
+  assert(get_location_manager());
+  get_location_manager()->expand_location(*this, path, line, column);
+}
+
 struct location_manager::priv
 {
   /// This sorted vector contains the expanded locations of the tokens
@@ -206,7 +223,7 @@ location_manager::create_new_location(const std::string&    file_path,
   // Just append the new expanded location to the end of the vector
   // and return its index.  Note that indexes start at 1.
   priv_->locs.push_back(l);
-  return location(priv_->locs.size());
+  return location(priv_->locs.size(), this);
 }
 
 /// Given an instance of location type, return the triplet
@@ -220,7 +237,7 @@ location_manager::create_new_location(const std::string&    file_path,
 /// @param line the resulting line of the source locus
 /// @param column the resulting colum of the source locus
 void
-location_manager::expand_location(const location       location,
+location_manager::expand_location(const location&      location,
                                  std::string&          path,
                                  unsigned&             line,
                                  unsigned&             column) const
@@ -303,7 +320,7 @@ translation_unit::get_global_scope() const
       // translation unit.
       priv_->global_scope_->
        set_environment(const_cast<environment*>(get_environment()));
-      priv_->global_scope_->set_corpus(get_corpus());
+      priv_->global_scope_->set_translation_unit(this);
     }
   return priv_->global_scope_;
 }
@@ -504,13 +521,10 @@ translation_unit::bind_function_type_life_time(function_type_sptr ftype) const
       ftype->set_environment(const_cast<environment*>(env));
     }
 
-  if (const corpus* c = get_corpus())
-    {
-      if (const corpus* existing_corpus = ftype->get_corpus())
-       assert(existing_corpus == c);
-      else
-       ftype->set_corpus(c);
-    }
+  if (const translation_unit* existing_tu = ftype->get_translation_unit())
+    assert(existing_tu == this);
+  else
+    ftype->set_translation_unit(this);
 }
 
 /// This implements the ir_traversable_base::traverse virtual
@@ -1777,12 +1791,12 @@ struct type_or_decl_base::priv
 {
   bool                 hashing_started_;
   environment*         env_;
-  const corpus*        corpus_;
+  const translation_unit* translation_unit_;
 
   priv()
     : hashing_started_(),
       env_(),
-      corpus_()
+      translation_unit_()
   {}
 }; // end struct type_or_decl_base
 
@@ -1839,23 +1853,34 @@ environment*
 type_or_decl_base::get_environment()
 {return priv_->env_;}
 
-/// Set the @ref corpus this ABI artifact belongs to.
-///
-/// Note that adding an ABI artifact to a containining one should
-/// invoke this this member function.
-///
-/// @param c the new corpus.
-void
-type_or_decl_base::set_corpus(const corpus* c)
-{priv_->corpus_ = c;}
-
 /// Get the @ref corpus this ABI artifact belongs to.
 ///
 /// @return the corpus this ABI artifact belongs to, or nil if it
 /// belongs to none for now.
 const corpus*
 type_or_decl_base::get_corpus() const
-{return priv_->corpus_;}
+{
+  const translation_unit* tu = get_translation_unit();
+  if (!tu)
+    return 0;
+  return tu->get_corpus();
+}
+
+/// Set the @ref translation_unit this ABI artifact belongs to.
+///
+/// Note that adding an ABI artifact to a containining on should
+/// invoke this member function.
+void
+type_or_decl_base::set_translation_unit(const translation_unit* tu)
+{priv_->translation_unit_ = tu;}
+
+/// Get the @ref translation_unit this ABI artifact belongs to.
+///
+/// @return the translation unit this ABI artifact belongs to, or nil
+/// if belongs to none for now.
+const translation_unit*
+type_or_decl_base::get_translation_unit() const
+{return priv_->translation_unit_;}
 
 /// Traverse the the ABI artifact.
 ///
@@ -1971,7 +1996,7 @@ struct decl_base::priv
       visibility_(VISIBILITY_DEFAULT)
   {}
 
-  priv(const std::string& name, location locus,
+  priv(const std::string& name, const location& locus,
        const std::string& linkage_name, visibility vis)
     : in_pub_sym_tab_(false),
       location_(locus),
@@ -1990,14 +2015,28 @@ struct decl_base::priv
   {}
 };// end struct decl_base::priv
 
-decl_base::decl_base(const std::string& name,
-                    location           locus,
-                    const std::string& linkage_name,
-                    visibility vis)
+/// Constructor for the @ref decl_base type.
+///
+/// @param name the name of the declaration.
+///
+/// @param locus the location where to find the declaration in the
+/// source code.
+///
+/// @pram linkage_name the linkage name of the declaration.
+///
+/// @param vis the visibility of the declaration.
+decl_base::decl_base(const std::string&        name,
+                    const location&            locus,
+                    const std::string& linkage_name,
+                    visibility         vis)
   : priv_(new priv(name, locus, linkage_name, vis))
 {}
 
-decl_base::decl_base(location l)
+/// Constructor for the @ref decl_base type.
+///
+/// @param l the location where to find the declaration in the source
+/// code.
+decl_base::decl_base(const location& l)
   : priv_(new priv(l))
 {}
 
@@ -2131,7 +2170,7 @@ decl_base::set_is_in_public_symbol_table(bool f)
 /// translation_unit::get_loc_mgr().
 ///
 /// @return the location of the current instance of @ref decl_base.
-location
+const location&
 decl_base::get_location() const
 {return priv_->location_;}
 
@@ -3737,12 +3776,12 @@ scope_decl::add_member_decl(const decl_base_sptr member)
   if (environment* env = get_environment())
     set_environment_for_artifact(member, env);
 
-  if (const corpus* c = get_corpus())
+  if (const translation_unit* tu = get_translation_unit())
     {
-      if (const corpus* existing_corpus = member->get_corpus())
-       assert(c == existing_corpus);
+      if (const translation_unit* existing_tu = member->get_translation_unit())
+       assert(tu == existing_tu);
       else
-       member->set_corpus(c);
+       member->set_translation_unit(tu);
     }
 
   maybe_update_types_lookup_map(this, member);
@@ -3778,12 +3817,12 @@ scope_decl::insert_member_decl(const decl_base_sptr member,
   if (environment* env = get_environment())
     set_environment_for_artifact(member, env);
 
-  if (const corpus* c = get_corpus())
+  if (const translation_unit* tu = get_translation_unit())
     {
-      if (const corpus* existing_corpus = member->get_corpus())
-       assert(c == existing_corpus);
+      if (const translation_unit* existing_tu = member->get_translation_unit())
+       assert(tu == existing_tu);
       else
-       member->set_corpus(c);
+       member->set_translation_unit(tu);
     }
 
   maybe_update_types_lookup_map(this, member);
@@ -4763,13 +4802,7 @@ types_are_compatible(const decl_base_sptr d1,
 /// yet added to a translation unit.
 translation_unit*
 get_translation_unit(const decl_base& decl)
-{
-  const global_scope* global = get_global_scope(decl);
-
-  if (global)
-    return global->get_translation_unit();
-  return 0;
-}
+{return const_cast<translation_unit*>(decl.get_translation_unit());}
 
 /// Return the translation unit a declaration belongs to.
 ///
@@ -6536,7 +6569,7 @@ type_base::~type_base()
 type_decl::type_decl(const std::string&        name,
                     size_t                     size_in_bits,
                     size_t                     alignment_in_bits,
-                    location                   locus,
+                    const location&            locus,
                     const std::string& linkage_name,
                     visibility         vis)
 
@@ -6676,11 +6709,11 @@ type_decl::~type_decl()
 
 // <scope_type_decl definitions>
 
-scope_type_decl::scope_type_decl(const std::string&            name,
-                                size_t                 size_in_bits,
-                                size_t                 alignment_in_bits,
-                                location                       locus,
-                                visibility                     vis)
+scope_type_decl::scope_type_decl(const std::string&    name,
+                                size_t         size_in_bits,
+                                size_t         alignment_in_bits,
+                                const location&        locus,
+                                visibility             vis)
   : decl_base(name, locus, "", vis),
     type_base(size_in_bits, alignment_in_bits),
     scope_decl(name, locus)
@@ -6799,9 +6832,9 @@ scope_type_decl::~scope_type_decl()
 // </scope_type_decl definitions>
 
 // <namespace_decl>
-namespace_decl::namespace_decl(const std::string& name,
-                              location   locus,
-                              visibility         vis)
+namespace_decl::namespace_decl(const std::string&      name,
+                              const location&          locus,
+                              visibility               vis)
   : // We need to call the constructor of decl_base directly here
     // because it is virtually inherited by scope_decl.  Note that we
     // just implicitely call the default constructor for scope_decl
@@ -6957,9 +6990,9 @@ qualified_type_def::build_name(bool fully_qualified, bool internal) const
 /// @param quals a bitfield representing the const/volatile qualifiers
 ///
 /// @param locus the location of the qualified type definition
-qualified_type_def::qualified_type_def(shared_ptr<type_base>   type,
-                                      CV                       quals,
-                                      location         locus)
+qualified_type_def::qualified_type_def(type_base_sptr  type,
+                                      CV               quals,
+                                      const location&  locus)
   : type_base(type->get_size_in_bits(),
              type->get_alignment_in_bits()),
     decl_base("", locus, "",
@@ -7326,7 +7359,7 @@ struct pointer_type_def::priv
 pointer_type_def::pointer_type_def(const type_base_sptr&       pointed_to,
                                   size_t                       size_in_bits,
                                   size_t                       align_in_bits,
-                                  location                     locus)
+                                  const location&              locus)
   : type_base(size_in_bits, align_in_bits),
     decl_base("", locus, ""),
     priv_(new priv)
@@ -7554,7 +7587,7 @@ reference_type_def::reference_type_def(const type_base_sptr       pointed_to,
                                       bool                     lvalue,
                                       size_t                   size_in_bits,
                                       size_t                   align_in_bits,
-                                      location         locus)
+                                      const location&          locus)
   : type_base(size_in_bits, align_in_bits),
     decl_base("", locus, ""),
     is_lvalue_(lvalue)
@@ -7780,19 +7813,21 @@ struct array_type_def::subrange_type::priv
   size_t       lower_bound_;
   size_t       upper_bound_;
   location     location_;
-  priv(size_t ub, location loc)
+  priv(size_t ub, const location& loc)
     : lower_bound_(0), upper_bound_(ub), location_(loc) {}
-  priv(size_t lb, size_t ub, location loc)
+
+  priv(size_t lb, size_t ub, const location& loc)
     : lower_bound_(lb), upper_bound_(ub), location_(loc) {}
 };
 
-array_type_def::subrange_type::subrange_type(size_t    lower_bound,
-                                            size_t     upper_bound,
-                                            location   loc)
+array_type_def::subrange_type::subrange_type(size_t            lower_bound,
+                                            size_t             upper_bound,
+                                            const location&    loc)
   : priv_(new priv(lower_bound, upper_bound, loc))
 {}
 
-array_type_def::subrange_type::subrange_type(size_t upper_bound, location loc)
+array_type_def::subrange_type::subrange_type(size_t            upper_bound,
+                                            const location&    loc)
   : priv_(new priv(upper_bound, loc))
 {}
 
@@ -7827,7 +7862,7 @@ array_type_def::subrange_type::operator==(const subrange_type& o) const
          && get_upper_bound() == o.get_upper_bound());
 }
 
-location
+const location&
 array_type_def::subrange_type::get_location() const
 {return priv_->location_;}
 
@@ -7860,7 +7895,7 @@ struct array_type_def::priv
 /// @param locus the source location of the array type definition.
 array_type_def::array_type_def(const type_base_sptr                    e_type,
                               const std::vector<subrange_sptr>&        subs,
-                              location                         locus)
+                              const location&                          locus)
   : type_base(0, e_type->get_alignment_in_bits()),
     decl_base(locus),
     priv_(new priv(e_type))
@@ -8140,7 +8175,7 @@ array_type_def::traverse(ir_node_visitor& v)
   return v.visit_end(this);
 }
 
-location
+const location&
 array_type_def::get_location() const
 {return decl_base::get_location();}
 
@@ -8174,9 +8209,11 @@ public:
   {}
 }; // end class enum_type_decl::priv
 
-enum_type_decl::enum_type_decl(const string& name, location locus,
+enum_type_decl::enum_type_decl(const string& name,
+                              const location& locus,
                               type_base_sptr underlying_type,
-                              enumerators& enums, const string& mangled_name,
+                              enumerators& enums,
+                              const string& mangled_name,
                               visibility vis)
   : type_base(underlying_type->get_size_in_bits(),
              underlying_type->get_alignment_in_bits()),
@@ -8522,7 +8559,7 @@ struct typedef_decl::priv
 /// @param vis the visibility of the typedef type.
 typedef_decl::typedef_decl(const string&               name,
                           const type_base_sptr underlying_type,
-                          location                     locus,
+                          const location&              locus,
                           const std::string&           linkage_name,
                           visibility vis)
   : type_base(underlying_type->get_size_in_bits(),
@@ -8712,7 +8749,7 @@ struct var_decl::priv
 
 var_decl::var_decl(const std::string&          name,
                   shared_ptr<type_base>        type,
-                  location                     locus,
+                  const location&              locus,
                   const std::string&           linkage_name,
                   visibility                   vis,
                   binding                      bind)
@@ -9623,7 +9660,7 @@ struct function_decl::priv
 function_decl::function_decl(const std::string& name,
                             function_type_sptr function_type,
                             bool declared_inline,
-                            location locus,
+                            const location& locus,
                             const std::string& mangled_name,
                             visibility vis,
                             binding bind)
@@ -9657,7 +9694,7 @@ function_decl::function_decl(const std::string& name,
 function_decl::function_decl(const std::string& name,
                             shared_ptr<type_base> fn_type,
                             bool       declared_inline,
-                            location locus,
+                            const location& locus,
                             const std::string& linkage_name,
                             visibility vis,
                             binding bind)
@@ -10193,7 +10230,7 @@ struct function_decl::parameter::priv
 function_decl::parameter::parameter(const type_base_sptr       type,
                                    unsigned                    index,
                                    const std::string&          name,
-                                   location                    loc,
+                                   const location&             loc,
                                    bool                        is_variadic)
   : decl_base(name, loc),
     priv_(new priv(type, index, is_variadic, /*is_artificial=*/false))
@@ -10202,7 +10239,7 @@ function_decl::parameter::parameter(const type_base_sptr        type,
 function_decl::parameter::parameter(const type_base_sptr       type,
                                    unsigned                    index,
                                    const std::string&          name,
-                                   location                    loc,
+                                   const location&             loc,
                                    bool                        is_variadic,
                                    bool                        is_artificial)
   : decl_base(name, loc),
@@ -10211,7 +10248,7 @@ function_decl::parameter::parameter(const type_base_sptr        type,
 
 function_decl::parameter::parameter(const type_base_sptr       type,
                                    const std::string&          name,
-                                   location                    loc,
+                                   const location&             loc,
                                    bool                        is_variadic,
                                    bool                        is_artificial)
   : decl_base(name, loc),
@@ -10660,7 +10697,7 @@ struct class_decl::priv
 /// class_decl.
 class_decl::class_decl(const std::string& name, size_t size_in_bits,
                       size_t align_in_bits, bool is_struct,
-                      location locus, visibility vis,
+                      const location& locus, visibility vis,
                       base_specs& bases, member_types& mbr_types,
                       data_members& data_mbrs,
                       member_functions& mbr_fns)
@@ -10700,7 +10737,7 @@ class_decl::class_decl(const std::string& name, size_t size_in_bits,
 /// @param vis the visibility of instances of class_decl.
 class_decl::class_decl(const std::string& name, size_t size_in_bits,
                       size_t align_in_bits, bool is_struct,
-                      location locus, visibility vis)
+                      const location& locus, visibility vis)
   : decl_base(name, locus, name, vis),
     type_base(size_in_bits, align_in_bits),
     scope_type_decl(name, size_in_bits, align_in_bits, locus, vis),
@@ -11361,7 +11398,7 @@ class_decl::method_decl::method_decl
 (const std::string&                    name,
  shared_ptr<method_type>               type,
  bool                                  declared_inline,
location                              locus,
const location&                       locus,
  const std::string&                    linkage_name,
  visibility                            vis,
  binding                               bind)
@@ -11391,7 +11428,7 @@ class_decl::method_decl::method_decl
 class_decl::method_decl::method_decl(const std::string&        name,
                                     shared_ptr<function_type>  type,
                                     bool                       declared_inline,
-                                    location                   locus,
+                                    const location&            locus,
                        const std::string&                      linkage_name,
                        visibility                              vis,
                        binding                         bind)
@@ -11421,7 +11458,7 @@ class_decl::method_decl::method_decl(const std::string& name,
 class_decl::method_decl::method_decl(const std::string&        name,
                                     shared_ptr<type_base>      type,
                                     bool                       declared_inline,
-                                    location                   locus,
+                                    const location&            locus,
                                     const std::string& linkage_name,
                                     visibility         vis,
                                     binding                    bind)
@@ -12438,7 +12475,9 @@ const std::list<template_parameter_sptr>&
 template_decl::get_template_parameters() const
 {return priv_->parms_;}
 
-template_decl::template_decl(const string& name, location locus, visibility vis)
+template_decl::template_decl(const string& name,
+                            const location& locus,
+                            visibility vis)
   : decl_base(name, locus, /*mangled_name=*/"", vis),
     priv_(new priv)
 {
@@ -12576,7 +12615,7 @@ class type_tparameter::priv
 type_tparameter::type_tparameter(unsigned              index,
                                 template_decl_sptr     enclosing_tdecl,
                                 const std::string&     name,
-                                location               locus)
+                                const location&        locus)
   : decl_base(name, locus),
     type_base(0, 0),
     type_decl(name, 0, 0, locus),
@@ -12651,7 +12690,7 @@ non_type_tparameter::non_type_tparameter(unsigned               index,
                                         template_decl_sptr     enclosing_tdecl,
                                         const std::string&     name,
                                         type_base_sptr type,
-                                        location               locus)
+                                        const location&        locus)
     : decl_base(name, locus, ""),
       template_parameter(index, enclosing_tdecl),
       priv_(new priv(type))
@@ -12730,7 +12769,7 @@ class template_tparameter::priv
 template_tparameter::template_tparameter(unsigned              index,
                                         template_decl_sptr     enclosing_tdecl,
                                         const std::string&     name,
-                                        location               locus)
+                                        const location&        locus)
     : decl_base(name, locus),
       type_base(0, 0),
       type_decl(name, 0, 0, locus, name, VISIBILITY_DEFAULT),
@@ -12886,7 +12925,7 @@ public:
 ///
 /// @param bind the binding of the declaration.  This is the binding
 /// the functions instantiated from this template are going to have.
-function_tdecl::function_tdecl(location        locus,
+function_tdecl::function_tdecl(const location& locus,
                               visibility       vis,
                               binding          bind)
   : decl_base("", locus, "", vis),
@@ -12908,7 +12947,7 @@ function_tdecl::function_tdecl(location locus,
 /// @param bind the binding of the declaration.  This is the binding
 /// the functions instantiated from this template are going to have.
 function_tdecl::function_tdecl(function_decl_sptr      pattern,
-                              location         locus,
+                              const location&          locus,
                               visibility               vis,
                               binding                  bind)
   : decl_base(pattern->get_name(), locus,
@@ -13044,7 +13083,7 @@ public:
 ///
 /// @param vis the visibility of the instance of class instantiated
 /// from this template.
-class_tdecl::class_tdecl(location locus, visibility vis)
+class_tdecl::class_tdecl(const location& locus, visibility vis)
   : decl_base("", locus, "", vis),
     template_decl("", locus, vis),
     scope_decl("", locus),
@@ -13062,7 +13101,8 @@ class_tdecl::class_tdecl(location locus, visibility vis)
 /// @param vis the visibility of the instances of class instantiated
 /// from this template.
 class_tdecl::class_tdecl(class_decl_sptr pattern,
-                        location locus, visibility vis)
+                        const location& locus,
+                        visibility vis)
 : decl_base(pattern->get_name(), locus,
            pattern->get_name(), vis),
   template_decl(pattern->get_name(), locus, vis),
index dcece4a..4679584 100644 (file)
@@ -450,7 +450,7 @@ public:
 
 static bool write_translation_unit(const translation_unit&,
                                   write_context&, unsigned);
-static void write_location(location, translation_unit&, ostream&);
+static void write_location(const location&, ostream&);
 static void write_location(const shared_ptr<decl_base>&, ostream&);
 static bool write_visibility(const shared_ptr<decl_base>&, ostream&);
 static bool write_binding(const shared_ptr<decl_base>&, ostream&);
@@ -582,7 +582,7 @@ get_indent_to_level(write_context& ctxt, unsigned initial_indent,
 ///
 /// @param o the output stream to write to.
 static void
-write_location(location        loc, translation_unit& tu, ostream&     o)
+write_location(const location& loc, ostream& o)
 {
   if (!loc)
     return;
@@ -590,7 +590,7 @@ write_location(location     loc, translation_unit& tu, ostream&     o)
   string filepath;
   unsigned line = 0, column = 0;
 
-  tu.get_loc_mgr().expand_location(loc, filepath, line, column);
+  loc.expand(filepath, line, column);
 
   o << " filepath='" << filepath << "'"
     << " line='"     << line     << "'"
@@ -605,8 +605,8 @@ write_location(location     loc, translation_unit& tu, ostream&     o)
 ///
 /// @param o the output stream to write to.
 static void
-write_location(const shared_ptr<decl_base>&    decl,
-              ostream&                 o)
+write_location(const decl_base_sptr&   decl,
+              ostream&         o)
 {
   if (!decl)
     return;
@@ -617,9 +617,8 @@ write_location(const shared_ptr<decl_base>& decl,
 
   string filepath;
   unsigned line = 0, column = 0;
-  translation_unit& tu = *get_translation_unit(decl);
 
-  tu.get_loc_mgr().expand_location(loc, filepath, line, column);
+  loc.expand(filepath, line, column);
 
   o << " filepath='" << filepath << "'"
     << " line='"     << line     << "'"
@@ -1775,7 +1774,7 @@ write_array_type_def(const array_type_def_sptr            decl,
             }
           o << "'";
 
-          write_location((*si)->get_location(), *get_translation_unit(decl), o);
+          write_location((*si)->get_location(), o);
 
           o << "/>\n";
         }
@@ -2187,7 +2186,7 @@ write_function_decl(const shared_ptr<function_decl> decl, write_context& ctxt,
        }
       if ((*pi)->get_artificial())
          o << " is-artificial='yes'";
-      write_location((*pi)->get_location(), *get_translation_unit(decl), o);
+      write_location((*pi)->get_location(), o);
       o << "/>\n";
     }
 
@@ -3364,9 +3363,9 @@ dump_decl_location(const decl_base& d, ostream& o)
 {
   string path;
   unsigned line = 0, col = 0;
-  translation_unit* tu = get_translation_unit(d);
 
-  tu->get_loc_mgr().expand_location(d.get_location(), path, line, col);
+  const location& l = d.get_location();
+  l.expand(path, line, col);
   o << path << ":" << line << "," << col << "\n";
 }