diff --git a/include/abg-corpus.h b/include/abg-corpus.h
index 27de8c2f..930f56de 100644
--- a/include/abg-corpus.h
+++ b/include/abg-corpus.h
@@ -60,19 +60,13 @@ public:
   struct priv;
   std::unique_ptr<priv> priv_;
 
-  corpus(ir::environment*, const string& path= "");
+  corpus(const ir::environment&, const string& path= "");
 
   virtual ~corpus();
 
-  const environment*
+  const environment&
   get_environment() const;
 
-  environment*
-  get_environment();
-
-  void
-  set_environment(environment*);
-
   void
   add(const translation_unit_sptr);
 
@@ -355,7 +349,7 @@ class corpus_group : public corpus
 public:
   typedef vector<corpus_sptr> corpora_type;
 
-  corpus_group(ir::environment*, const string&);
+  corpus_group(const ir::environment&, const string&);
 
   virtual ~corpus_group();
 
diff --git a/include/abg-ctf-reader.h b/include/abg-ctf-reader.h
index 0f49b5eb..93d20973 100644
--- a/include/abg-ctf-reader.h
+++ b/include/abg-ctf-reader.h
@@ -32,7 +32,7 @@ typedef shared_ptr<read_context> read_context_sptr;
 read_context_sptr
 create_read_context(const std::string& elf_path,
                     const vector<char**>& debug_info_root_paths,
-                    ir::environment *env);
+                    ir::environment& env);
 corpus_sptr
 read_corpus(read_context *ctxt, elf_reader::status& status);
 
@@ -48,8 +48,7 @@ set_read_context_corpus_group(read_context& ctxt, corpus_group_sptr& group);
 void
 reset_read_context(read_context_sptr &ctxt,
                    const std::string&	elf_path,
-                   const vector<char**>& debug_info_root_path,
-                   ir::environment*	environment);
+	     const vector<char**>&	debug_info_root_path);
 std::string
 dic_type_key(ctf_dict_t *dic, ctf_id_t ctf_type);
 } // end namespace ctf_reader
diff --git a/include/abg-dwarf-reader.h b/include/abg-dwarf-reader.h
index 5766f906..a127f7ce 100644
--- a/include/abg-dwarf-reader.h
+++ b/include/abg-dwarf-reader.h
@@ -53,7 +53,7 @@ typedef shared_ptr<read_context> read_context_sptr;
 read_context_sptr
 create_read_context(const std::string&	elf_path,
 		    const vector<char**>& debug_info_root_paths,
-		    ir::environment*	environment,
+		    ir::environment&	environment,
 		    bool		read_all_types = false,
 		    bool		linux_kernel_mode = false);
 
@@ -64,7 +64,6 @@ void
 reset_read_context(read_context_sptr &ctxt,
 		   const std::string&	elf_path,
 		   const vector<char**>& debug_info_root_paths,
-		   ir::environment*	environment,
 		   bool		read_all_types = false,
 		   bool		linux_kernel_mode = false);
 
@@ -81,7 +80,7 @@ read_corpus_from_elf(read_context& ctxt, elf_reader::status& stat);
 corpus_sptr
 read_corpus_from_elf(const std::string& elf_path,
 		     const vector<char**>& debug_info_root_paths,
-		     ir::environment*	environment,
+		     ir::environment&	environment,
 		     bool		load_all_types,
 		     elf_reader::status&);
 
@@ -89,14 +88,14 @@ corpus_sptr
 read_and_add_corpus_to_group_from_elf(read_context&, corpus_group&, elf_reader::status&);
 
 bool
-lookup_symbol_from_elf(const environment*		env,
+lookup_symbol_from_elf(environment&			env,
 		       const string&			elf_path,
 		       const string&			symbol_name,
 		       bool				demangle,
 		       vector<elf_symbol_sptr>&	symbols);
 
 bool
-lookup_public_function_symbol_from_elf(const environment*		env,
+lookup_public_function_symbol_from_elf(environment&			env,
 				       const string&			path,
 				       const string&			symname,
 				       vector<elf_symbol_sptr>&	func_syms);
diff --git a/include/abg-fwd.h b/include/abg-fwd.h
index 1dbe99bb..33087b90 100644
--- a/include/abg-fwd.h
+++ b/include/abg-fwd.h
@@ -1384,7 +1384,7 @@ string
 demangle_cplus_mangled_name(const string&);
 
 type_base_sptr
-type_or_void(const type_base_sptr, const environment*);
+type_or_void(const type_base_sptr, const environment&);
 
 type_base_sptr
 canonicalize(type_base_sptr);
diff --git a/include/abg-ir.h b/include/abg-ir.h
index 4892f0e2..ee24891d 100644
--- a/include/abg-ir.h
+++ b/include/abg-ir.h
@@ -689,21 +689,15 @@ public:
   };
 
 public:
-  translation_unit(const ir::environment*	env,
+  translation_unit(const ir::environment&	env,
 		   const std::string&		path,
 		   char			address_size = 0);
 
   virtual ~translation_unit();
 
-  const environment*
+  const environment&
   get_environment() const;
 
-  environment*
-  get_environment();
-
-  void
-  set_environment(const environment*);
-
   language
   get_language() const;
 
@@ -929,7 +923,7 @@ private:
 
   elf_symbol();
 
-  elf_symbol(const environment* e,
+  elf_symbol(const environment& e,
 	     size_t		i,
 	     size_t		s,
 	     const string&	n,
@@ -952,30 +946,24 @@ private:
 public:
 
   static elf_symbol_sptr
-  create();
-
-  static elf_symbol_sptr
-  create(const environment* e,
-	 size_t		    i,
-	 size_t		    s,
-	 const string&	    n,
-	 type		    t,
-	 binding	    b,
-	 bool		    d,
-	 bool		    c,
-	 const version&	    ve,
-	 visibility	    vi,
-	 bool		    is_in_ksymtab = false,
+  create(const environment&	e,
+	 size_t		i,
+	 size_t		s,
+	 const string&		n,
+	 type			t,
+	 binding		b,
+	 bool			d,
+	 bool			c,
+	 const version&	ve,
+	 visibility		vi,
+	 bool			is_in_ksymtab = false,
 	 const abg_compat::optional<uint64_t>&		crc = {},
 	 const abg_compat::optional<std::string>&	ns = {},
-	 bool		    is_suppressed = false);
+	 bool						is_suppressed = false);
 
-  const environment*
+  const environment&
   get_environment() const;
 
-  void
-  set_environment(const environment*) const;
-
   size_t
   get_index() const;
 
@@ -1340,6 +1328,7 @@ class type_or_decl_base : public ir_traversable_base
   mutable std::unique_ptr<priv> priv_;
 
   type_or_decl_base();
+  type_or_decl_base(const type_or_decl_base&);
 
 protected:
 
@@ -1399,13 +1388,14 @@ protected:
 
   void hashing_started(bool) const;
 
+  type_or_decl_base&
+  operator=(const type_or_decl_base&);
+
 public:
 
-  type_or_decl_base(const environment*,
+  type_or_decl_base(const environment&,
 		    enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL);
 
-  type_or_decl_base(const type_or_decl_base&);
-
   virtual ~type_or_decl_base();
 
   bool
@@ -1414,15 +1404,9 @@ public:
   void
   set_is_artificial(bool);
 
-  const environment*
+  const environment&
   get_environment() const;
 
-  environment*
-  get_environment();
-
-  void
-  set_environment(const environment*);
-
   void
   set_artificial_location(const location &);
 
@@ -1447,9 +1431,6 @@ public:
   translation_unit*
   get_translation_unit();
 
-  type_or_decl_base&
-  operator=(const type_or_decl_base&);
-
   virtual bool
   traverse(ir_node_visitor&);
 
@@ -1511,14 +1492,6 @@ operator==(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&);
 bool
 operator!=(const type_or_decl_base_sptr&, const type_or_decl_base_sptr&);
 
-void
-set_environment_for_artifact(type_or_decl_base* artifact,
-			     const environment* env);
-
-void
-set_environment_for_artifact(type_or_decl_base_sptr artifact,
-			     const environment* env);
-
 /// The base type of all declarations.
 class decl_base : public virtual type_or_decl_base
 {
@@ -1591,23 +1564,22 @@ protected:
 
   void
   set_context_rel(context_rel *c);
+  decl_base(const decl_base&);
 
 public:
-  decl_base(const environment* e,
+  decl_base(const environment& e,
 	    const string& name,
 	    const location& locus,
 	    const string& mangled_name = "",
 	    visibility vis = VISIBILITY_DEFAULT);
 
-  decl_base(const environment* e,
+  decl_base(const environment& e,
 	    const interned_string& name,
 	    const location& locus,
 	    const interned_string& mangled_name = interned_string(),
 	    visibility vis = VISIBILITY_DEFAULT);
 
-  decl_base(const environment*, const location&);
-
-  decl_base(const decl_base&);
+  decl_base(const environment&, const location&);
 
   virtual bool
   operator==(const decl_base&) const;
@@ -1821,11 +1793,11 @@ protected:
 public:
   struct hash;
 
-  scope_decl(const environment* env,
+  scope_decl(const environment& env,
 	     const string& name, const location& locus,
 	     visibility	vis = VISIBILITY_DEFAULT);
 
-  scope_decl(const environment* env, location& l);
+  scope_decl(const environment& env, location& l);
 
   virtual size_t
   get_hash() const;
@@ -2000,7 +1972,7 @@ public:
   /// runtime type of the type pointed to.
   struct shared_ptr_hash;
 
-  type_base(const environment* e, size_t s, size_t a);
+  type_base(const environment& e, size_t s, size_t a);
 
   friend type_base_sptr canonicalize(type_base_sptr);
 
@@ -2104,7 +2076,7 @@ public:
   /// Facility to hash instance of type_decl
   struct hash;
 
-  type_decl(const environment*	env,
+  type_decl(const environment&	env,
 	    const string&	name,
 	    size_t		size_in_bits,
 	    size_t		alignment_in_bits,
@@ -2159,7 +2131,7 @@ public:
   /// Hasher for instances of scope_type_decl
   struct hash;
 
-  scope_type_decl(const environment* env, const string& name,
+  scope_type_decl(const environment& env, const string& name,
 		  size_t size_in_bits, size_t alignment_in_bits,
 		  const location& locus, visibility vis = VISIBILITY_DEFAULT);
 
@@ -2180,7 +2152,7 @@ class namespace_decl : public scope_decl
 {
 public:
 
-  namespace_decl(const environment* env, const string& name,
+  namespace_decl(const environment& env, const string& name,
 		 const location& locus, visibility vis = VISIBILITY_DEFAULT);
 
   virtual string
@@ -2234,7 +2206,7 @@ public:
 
   qualified_type_def(type_base_sptr type, CV quals, const location& locus);
 
-  qualified_type_def(environment* env, CV quals, const location& locus);
+  qualified_type_def(const environment& env, CV quals, const location& locus);
 
   virtual size_t
   get_size_in_bits() const;
@@ -2335,10 +2307,9 @@ public:
   pointer_type_def(const type_base_sptr& pointed_to_type, size_t size_in_bits,
 		   size_t alignment_in_bits, const location& locus);
 
-  pointer_type_def(environment* env, size_t size_in_bits,
+  pointer_type_def(const environment& env, size_t size_in_bits,
 		   size_t alignment_in_bits, const location& locus);
 
-
   void
   set_pointed_to_type(const type_base_sptr&);
 
@@ -2400,7 +2371,7 @@ public:
 		     bool lvalue, size_t size_in_bits,
 		     size_t alignment_in_bits, const location& locus);
 
-  reference_type_def(const environment* env, bool lvalue, size_t size_in_bits,
+  reference_type_def(const environment& env, bool lvalue, size_t size_in_bits,
 		     size_t alignment_in_bits, const location& locus);
 
   void
@@ -2522,7 +2493,7 @@ public:
     /// Hasher for an instance of array::subrange
     struct hash;
 
-    subrange_type(const environment*	env,
+    subrange_type(const environment&	env,
 		  const string&	name,
 		  bound_value		lower_bound,
 		  bound_value		upper_bound,
@@ -2530,14 +2501,14 @@ public:
 		  const location&	loc,
 		  translation_unit::language l = translation_unit::LANG_C11);
 
-    subrange_type(const environment* env,
+    subrange_type(const environment& env,
 		  const string& name,
 		  bound_value lower_bound,
 		  bound_value upper_bound,
 		  const location& loc,
 		  translation_unit::language l = translation_unit::LANG_C11);
 
-    subrange_type(const environment* env,
+    subrange_type(const environment& env,
 		  const string& name,
 		  bound_value upper_bound,
 		  const location& loc,
@@ -2603,7 +2574,7 @@ public:
 		 const std::vector<subrange_sptr>& subs,
 		 const location& locus);
 
-  array_type_def(environment* env,
+  array_type_def(const environment& env,
 		 const std::vector<subrange_sptr>& subs,
 		 const location& locus);
 
@@ -2761,7 +2732,7 @@ public:
 
   ~enumerator();
 
-  enumerator(const environment* env, const string& name, int64_t value);
+  enumerator(const string& name, int64_t value);
 
   enumerator(const enumerator&);
 
@@ -2774,13 +2745,10 @@ public:
   bool
   operator!=(const enumerator& other) const;
 
-  const environment*
-  get_environment() const;
-
-  const interned_string&
+  const string&
   get_name() const;
 
-  const interned_string&
+  const string&
   get_qualified_name(bool internal = false) const;
 
   void
@@ -2823,7 +2791,7 @@ public:
 	       visibility vis = VISIBILITY_DEFAULT);
 
   typedef_decl(const string& name,
-	       environment* env,
+	       const environment& env,
 	       const location& locus,
 	       const string& mangled_name = "",
 	       visibility vis = VISIBILITY_DEFAULT);
@@ -3320,7 +3288,7 @@ public:
 		size_t		size_in_bits,
 		size_t		alignment_in_bits);
 
-  function_type(const environment*	env,
+  function_type(const environment&	env,
 		size_t		size_in_bits,
 		size_t		alignment_in_bits);
 
@@ -3415,7 +3383,7 @@ public:
 	      size_t size_in_bits,
 	      size_t alignment_in_bits);
 
-  method_type(const environment* env,
+  method_type(const environment& env,
 	      size_t size_in_bits,
 	      size_t alignment_in_bits);
 
@@ -3452,7 +3420,7 @@ public:
   /// Hasher.
   struct hash;
 
-  template_decl(const environment*	env,
+  template_decl(const environment&	env,
 		const string&		name,
 		const location&	locus,
 		visibility		vis = VISIBILITY_DEFAULT);
@@ -3683,7 +3651,7 @@ public:
   struct hash;
   struct shared_ptr_hash;
 
-  function_tdecl(const environment*	env,
+  function_tdecl(const environment&	env,
 		 const location&	locus,
 		 visibility		vis = VISIBILITY_DEFAULT,
 		 binding		bind = BINDING_NONE);
@@ -3732,7 +3700,7 @@ public:
   struct hash;
   struct shared_ptr_hash;
 
-  class_tdecl(const environment* env, const location& locus,
+  class_tdecl(const environment& env, const location& locus,
 	      visibility vis = VISIBILITY_DEFAULT);
 
   class_tdecl(class_decl_sptr	pattern,
@@ -3953,17 +3921,17 @@ public:
   typedef unordered_map<string, method_decl_sptr> string_mem_fn_sptr_map_type;
   /// @}
 
-  class_or_union(const environment* env, const string& name,
+  class_or_union(const environment& env, const string& name,
 		 size_t size_in_bits, size_t align_in_bits,
 		 const location& locus, visibility vis,
 		 member_types& mbrs, data_members& data_mbrs,
 		 member_functions& member_fns);
 
-  class_or_union(const environment* env, const string& name,
+  class_or_union(const environment& env, const string& name,
 		 size_t size_in_bits, size_t align_in_bits,
 		 const location& locus, visibility vis);
 
-  class_or_union(const environment* env, const string& name,
+  class_or_union(const environment& env, const string& name,
 		 bool is_declaration_only = true);
 
   virtual void
@@ -4159,30 +4127,30 @@ private:
 
 public:
 
-  class_decl(const environment* env, const string& name,
+  class_decl(const environment& env, const string& name,
 	     size_t size_in_bits, size_t align_in_bits,
 	     bool is_struct, const location& locus,
 	     visibility vis, base_specs& bases,
 	     member_types& mbrs, data_members& data_mbrs,
 	     member_functions& member_fns);
 
-  class_decl(const environment* env, const string& name,
+  class_decl(const environment& env, const string& name,
 	     size_t size_in_bits, size_t align_in_bits,
 	     bool is_struct, const location& locus,
 	     visibility vis, base_specs& bases,
 	     member_types& mbrs, data_members& data_mbrs,
 	     member_functions& member_fns, bool is_anonymous);
 
-  class_decl(const environment* env, const string& name,
+  class_decl(const environment& env, const string& name,
 	     size_t size_in_bits, size_t align_in_bits,
 	     bool is_struct, const location& locus, visibility vis);
 
-  class_decl(const environment* env, const string& name,
+  class_decl(const environment& env, const string& name,
 	     size_t size_in_bits, size_t align_in_bits,
 	     bool is_struct, const location& locus,
 	     visibility vis, bool is_anonymous);
 
-  class_decl(const environment* env, const string& name, bool is_struct,
+  class_decl(const environment& env, const string& name, bool is_struct,
 	     bool is_declaration_only = true);
 
   virtual string
@@ -4376,26 +4344,26 @@ class union_decl : public class_or_union
 
 public:
 
-  union_decl(const environment* env, const string& name,
+  union_decl(const environment& env, const string& name,
 	     size_t size_in_bits, const location& locus,
 	     visibility vis, member_types& mbrs,
 	     data_members& data_mbrs, member_functions& member_fns);
 
-  union_decl(const environment* env, const string& name,
+  union_decl(const environment& env, const string& name,
 	     size_t size_in_bits, const location& locus,
 	     visibility vis, member_types& mbrs,
 	     data_members& data_mbrs, member_functions& member_fns,
 	     bool is_anonymous);
 
-  union_decl(const environment* env, const string& name,
+  union_decl(const environment& env, const string& name,
 	     size_t size_in_bits, const location& locus,
 	     visibility vis);
 
-  union_decl(const environment* env, const string& name,
+  union_decl(const environment& env, const string& name,
 	     size_t size_in_bits, const location& locus,
 	     visibility vis, bool is_anonymous);
 
-  union_decl(const environment* env, const string& name,
+  union_decl(const environment& env, const string& name,
 	     bool is_declaration_only = true);
 
   virtual string
diff --git a/include/abg-reader.h b/include/abg-reader.h
index 624311bc..eb50482c 100644
--- a/include/abg-reader.h
+++ b/include/abg-reader.h
@@ -30,15 +30,15 @@ class read_context;
 
 translation_unit_sptr
 read_translation_unit_from_file(const std::string&	file_path,
-				environment*		env);
+				environment&		env);
 
 translation_unit_sptr
 read_translation_unit_from_buffer(const std::string&	file_path,
-				  environment*		env);
+				  environment&		env);
 
 translation_unit_sptr
 read_translation_unit_from_istream(std::istream*	in,
-				   environment*	env);
+				   environment&	env);
 
 translation_unit_sptr
 read_translation_unit(read_context&);
@@ -47,21 +47,20 @@ read_translation_unit(read_context&);
 typedef shared_ptr<read_context> read_context_sptr;
 
 read_context_sptr
-create_native_xml_read_context(const string& path, environment *env);
+create_native_xml_read_context(const string& path, environment& env);
 
 read_context_sptr
-create_native_xml_read_context(std::istream* in, environment* env);
-
+create_native_xml_read_context(std::istream* in, environment& env);
 const string&
 read_context_get_path(const read_context&);
 
 corpus_sptr
 read_corpus_from_native_xml(std::istream* in,
-			    environment*  env);
+			    environment&  env);
 
 corpus_sptr
 read_corpus_from_native_xml_file(const string& path,
-				 environment*  env);
+				 environment&  env);
 
 corpus_sptr
 read_corpus_from_input(read_context& ctxt);
@@ -71,11 +70,11 @@ read_corpus_group_from_input(read_context& ctxt);
 
 corpus_group_sptr
 read_corpus_group_from_native_xml(std::istream* in,
-				  environment*  env);
+				  environment&  env);
 
 corpus_group_sptr
 read_corpus_group_from_native_xml_file(const string& path,
-				       environment*  env);
+				       environment&  env);
 
 void
 add_read_context_suppressions(read_context& ctxt,
diff --git a/include/abg-tools-utils.h b/include/abg-tools-utils.h
index 27bbfefe..c442c7c4 100644
--- a/include/abg-tools-utils.h
+++ b/include/abg-tools-utils.h
@@ -311,7 +311,7 @@ build_corpus_group_from_kernel_dist_under(const string&	root,
 					  vector<string>&	kabi_wl_paths,
 					  suppr::suppressions_type&	supprs,
 					  bool				verbose,
-					  environment_sptr&		env,
+					  environment&			env,
 					  corpus::origin	origin = corpus::DWARF_ORIGIN);
 }// end namespace tools_utils
 
diff --git a/include/abg-writer.h b/include/abg-writer.h
index ab01b486..58f60b74 100644
--- a/include/abg-writer.h
+++ b/include/abg-writer.h
@@ -36,7 +36,7 @@ class write_context;
 typedef shared_ptr<write_context> write_context_sptr;
 
 write_context_sptr
-create_write_context(const environment *env,
+create_write_context(const environment& env,
 		     ostream& output_stream);
 
 void
diff --git a/src/abg-comparison.cc b/src/abg-comparison.cc
index 6e3b2b55..0868d384 100644
--- a/src/abg-comparison.cc
+++ b/src/abg-comparison.cc
@@ -3133,8 +3133,6 @@ compute_diff(const decl_base_sptr	first,
   if (!first || !second)
     return diff_sptr();
 
-  ABG_ASSERT(first->get_environment() == second->get_environment());
-
   diff_sptr d;
   if (is_type(first) && is_type(second))
     d = compute_diff_for_types(first, second, ctxt);
@@ -3165,9 +3163,6 @@ compute_diff(const type_base_sptr	first,
   decl_base_sptr f = get_type_declaration(first),
     s = get_type_declaration(second);
 
-  if (first && second)
-    ABG_ASSERT(first->get_environment() == second->get_environment());
-
   diff_sptr d = compute_diff_for_types(f,s, ctxt);
   ABG_ASSERT(d);
   return d;
@@ -3317,9 +3312,6 @@ compute_diff(const var_decl_sptr	first,
 	     const var_decl_sptr	second,
 	     diff_context_sptr		ctxt)
 {
-  if (first && second)
-    ABG_ASSERT(first->get_environment() == second->get_environment());
-
   var_diff_sptr d(new var_diff(first, second, diff_sptr(), ctxt));
   ctxt->initialize_canonical_diff(d);
 
@@ -3451,9 +3443,6 @@ compute_diff(pointer_type_def_sptr	first,
 	     pointer_type_def_sptr	second,
 	     diff_context_sptr		ctxt)
 {
-  if (first && second)
-    ABG_ASSERT(first->get_environment() == second->get_environment());
-
   diff_sptr d = compute_diff_for_types(first->get_pointed_to_type(),
 				       second->get_pointed_to_type(),
 				       ctxt);
@@ -3607,9 +3596,6 @@ compute_diff(array_type_def_sptr	first,
 	     array_type_def_sptr	second,
 	     diff_context_sptr		ctxt)
 {
-  if (first && second)
-    ABG_ASSERT(first->get_environment() == second->get_environment());
-
   diff_sptr d = compute_diff_for_types(first->get_element_type(),
 				       second->get_element_type(),
 				       ctxt);
@@ -3742,9 +3728,6 @@ compute_diff(reference_type_def_sptr	first,
 	     reference_type_def_sptr	second,
 	     diff_context_sptr		ctxt)
 {
-  if (first && second)
-    ABG_ASSERT(first->get_environment() == second->get_environment());
-
   diff_sptr d = compute_diff_for_types(first->get_pointed_to_type(),
 				       second->get_pointed_to_type(),
 				       ctxt);
@@ -3892,9 +3875,6 @@ compute_diff(const qualified_type_def_sptr	first,
 	     const qualified_type_def_sptr	second,
 	     diff_context_sptr			ctxt)
 {
-  if (first && second)
-    ABG_ASSERT(first->get_environment() == second->get_environment());
-
   diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
 				       second->get_underlying_type(),
 				       ctxt);
@@ -4110,9 +4090,6 @@ compute_diff(const enum_type_decl_sptr first,
 	     const enum_type_decl_sptr second,
 	     diff_context_sptr ctxt)
 {
-  if (first && second)
-    ABG_ASSERT(first->get_environment() == second->get_environment());
-
   diff_sptr ud = compute_diff_for_types(first->get_underlying_type(),
 					second->get_underlying_type(),
 					ctxt);
@@ -5596,9 +5573,6 @@ compute_diff(const class_decl_sptr	first,
 	     const class_decl_sptr	second,
 	     diff_context_sptr		ctxt)
 {
-  if (first && second)
-    ABG_ASSERT(first->get_environment() == second->get_environment());
-
   class_decl_sptr f = is_class_type(look_through_decl_only_class(first)),
     s = is_class_type(look_through_decl_only_class(second));
 
@@ -5821,15 +5795,6 @@ compute_diff(const class_decl::base_spec_sptr	first,
 	     const class_decl::base_spec_sptr	second,
 	     diff_context_sptr			ctxt)
 {
-  if (first && second)
-    {
-      ABG_ASSERT(first->get_environment() == second->get_environment());
-      ABG_ASSERT(first->get_base_class()->get_environment()
-	     == second->get_base_class()->get_environment());
-      ABG_ASSERT(first->get_environment()
-	     == first->get_base_class()->get_environment());
-    }
-
   class_diff_sptr cl = compute_diff(first->get_base_class(),
 				    second->get_base_class(),
 				    ctxt);
@@ -5945,9 +5910,6 @@ compute_diff(const union_decl_sptr	first,
 	     const union_decl_sptr	second,
 	     diff_context_sptr	ctxt)
 {
-  if (first && second)
-    ABG_ASSERT(first->get_environment() == second->get_environment());
-
   union_diff_sptr changes(new union_diff(first, second, ctxt));
 
   ctxt->initialize_canonical_diff(changes);
@@ -6449,9 +6411,6 @@ compute_diff(const scope_decl_sptr	first,
 {
   ABG_ASSERT(d->first_scope() == first && d->second_scope() == second);
 
-  if (first && second)
-    ABG_ASSERT(first->get_environment() == second->get_environment());
-
   compute_diff(first->get_member_decls().begin(),
 	       first->get_member_decls().end(),
 	       second->get_member_decls().begin(),
@@ -6482,10 +6441,6 @@ compute_diff(const scope_decl_sptr	first_scope,
 	     const scope_decl_sptr	second_scope,
 	     diff_context_sptr		ctxt)
 {
-  if (first_scope && second_scope)
-    ABG_ASSERT(first_scope->get_environment()
-	   == second_scope->get_environment());
-
   scope_diff_sptr d(new scope_diff(first_scope, second_scope, ctxt));
   d = compute_diff(first_scope, second_scope, d, ctxt);
   ctxt->initialize_canonical_diff(d);
@@ -6632,8 +6587,6 @@ compute_diff(const function_decl::parameter_sptr	first,
   if (!first || !second)
     return fn_parm_diff_sptr();
 
-  ABG_ASSERT(first->get_environment() == second->get_environment());
-
   fn_parm_diff_sptr result(new fn_parm_diff(first, second, ctxt));
   ctxt->initialize_canonical_diff(result);
 
@@ -6930,8 +6883,6 @@ compute_diff(const function_type_sptr	first,
       return function_type_diff_sptr();
     }
 
-  ABG_ASSERT(first->get_environment() == second->get_environment());
-
   function_type_diff_sptr result(new function_type_diff(first, second, ctxt));
 
   diff_utils::compute_diff(first->get_first_parm(),
@@ -7072,8 +7023,6 @@ compute_diff(const function_decl_sptr first,
       return function_decl_diff_sptr();
     }
 
-  ABG_ASSERT(first->get_environment() == second->get_environment());
-
   function_type_diff_sptr type_diff = compute_diff(first->get_type(),
 						   second->get_type(),
 						   ctxt);
@@ -7196,9 +7145,6 @@ compute_diff(const type_decl_sptr	first,
 	     const type_decl_sptr	second,
 	     diff_context_sptr		ctxt)
 {
-  if (first && second)
-    ABG_ASSERT(first->get_environment() == second->get_environment());
-
   type_decl_diff_sptr result(new type_decl_diff(first, second, ctxt));
 
   // We don't need to actually compute a diff here as a type_decl
@@ -7349,9 +7295,6 @@ compute_diff(const typedef_decl_sptr	first,
 	     const typedef_decl_sptr	second,
 	     diff_context_sptr		ctxt)
 {
-  if (first && second)
-    ABG_ASSERT(first->get_environment() == second->get_environment());
-
   diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
 				       second->get_underlying_type(),
 				       ctxt);
@@ -7470,8 +7413,6 @@ compute_diff(const translation_unit_sptr	first,
 {
   ABG_ASSERT(first && second);
 
-  ABG_ASSERT(first->get_environment() == second->get_environment());
-
   if (!ctxt)
     ctxt.reset(new diff_context);
 
@@ -10929,10 +10870,6 @@ compute_diff(const corpus_sptr	f,
 
   ABG_ASSERT(f && s);
 
-  // We can only compare two corpora that were built out of the same
-  // environment.
-  ABG_ASSERT(f->get_environment() == s->get_environment());
-
   if (!ctxt)
     ctxt.reset(new diff_context);
 
@@ -12272,11 +12209,11 @@ is_diff_of_variadic_parameter_type(const diff* d)
     return false;
 
   type_base_sptr t = is_type(d->first_subject());
-  if (t && t->get_environment()->is_variadic_parameter_type(t))
+  if (t && t->get_environment().is_variadic_parameter_type(t))
     return true;
 
   t = is_type(d->second_subject());
-  if (t && t->get_environment()->is_variadic_parameter_type(t))
+  if (t && t->get_environment().is_variadic_parameter_type(t))
     return true;
 
   return false;
diff --git a/src/abg-corpus-priv.h b/src/abg-corpus-priv.h
index 8719be56..74dc9448 100644
--- a/src/abg-corpus-priv.h
+++ b/src/abg-corpus-priv.h
@@ -667,7 +667,7 @@ struct corpus::priv
   mutable unordered_map<string, type_base_sptr> canonical_types_;
   string					format_major_version_number_;
   string					format_minor_version_number_;
-  environment*					env;
+  const environment&				env;
   corpus_group*				group;
   corpus::exported_decls_builder_sptr		exported_decls_builder;
   corpus::origin				origin_;
@@ -717,8 +717,8 @@ private:
   mutable abg_compat::optional<elf_symbols> unrefed_fun_symbols;
 
 public:
-  priv(const string &	p,
-       environment*	e)
+  priv(const string &		p,
+       const environment&	e)
     : env(e),
       group(),
       origin_(ARTIFICIAL_ORIGIN),
diff --git a/src/abg-corpus.cc b/src/abg-corpus.cc
index 0b23667f..a42cbaa1 100644
--- a/src/abg-corpus.cc
+++ b/src/abg-corpus.cc
@@ -596,7 +596,7 @@ corpus::priv::~priv()
 /// @param env the environment of the corpus.
 ///
 /// @param path the path to the file containing the ABI corpus.
-corpus::corpus(ir::environment* env, const string& path)
+corpus::corpus(const ir::environment& env, const string& path)
 {
   priv_.reset(new priv(path, env));
   init_format_version();
@@ -607,27 +607,10 @@ corpus::~corpus() = default;
 /// Getter of the enviroment of the corpus.
 ///
 /// @return the environment of this corpus.
-const environment*
+const environment&
 corpus::get_environment() const
 {return priv_->env;}
 
-/// Getter of the enviroment of the corpus.
-///
-/// @return the environment of this corpus.
-environment*
-corpus::get_environment()
-{return priv_->env;}
-
-/// Setter of the environment of this corpus.
-///
-/// @param e the new environment.
-void
-corpus::set_environment(environment* e)
-{
-  priv_->env = e;
-  init_format_version();
-}
-
 /// Add a translation unit to the current ABI Corpus. Next time
 /// corpus::save is called, all the translation unit that got added to
 /// the corpus are going to be serialized on disk in the file
@@ -641,11 +624,6 @@ corpus::set_environment(environment* e)
 void
 corpus::add(const translation_unit_sptr tu)
 {
-  if (!tu->get_environment())
-    tu->set_environment(get_environment());
-
-  ABG_ASSERT(tu->get_environment() == get_environment());
-
   ABG_ASSERT(priv_->members.insert(tu).second);
 
   if (!tu->get_absolute_path().empty())
@@ -741,7 +719,7 @@ void
 corpus::record_type_as_reachable_from_public_interfaces(const type_base& t)
 {
   string repr = get_pretty_representation(&t, /*internal=*/true);
-  interned_string s = t.get_environment()->intern(repr);
+  interned_string s = t.get_environment().intern(repr);
   priv_->get_public_types_pretty_representations()->insert(s);
 }
 
@@ -759,7 +737,7 @@ bool
 corpus::type_is_reachable_from_public_interfaces(const type_base& t) const
 {
   string repr = get_pretty_representation(&t, /*internal=*/true);
-  interned_string s = t.get_environment()->intern(repr);
+  interned_string s = t.get_environment().intern(repr);
 
   return (priv_->get_public_types_pretty_representations()->find(s)
 	  !=  priv_->get_public_types_pretty_representations()->end());
@@ -839,13 +817,10 @@ corpus::set_group(corpus_group* g)
 void
 corpus::init_format_version()
 {
-  if (priv_->env)
-    {
-      set_format_major_version_number
-	(priv_->env->get_config().get_format_major_version_number());
-      set_format_minor_version_number
-	(priv_->env->get_config().get_format_minor_version_number());
-    }
+  set_format_major_version_number
+    (priv_->env.get_config().get_format_major_version_number());
+  set_format_minor_version_number
+    (priv_->env.get_config().get_format_minor_version_number());
 }
 
 /// Getter for the origin of the corpus.
@@ -1690,8 +1665,12 @@ struct corpus_group::priv
   }
 }; // end corpus_group::priv
 
-/// Default constructor of the @ref corpus_group type.
-corpus_group::corpus_group(environment* env, const string& path = "")
+/// Constructor of the @ref corpus_group type.
+///
+/// @param env the environment of the @ref corpus_group.
+///
+/// @param path the path to the file represented by the corpus group.
+corpus_group::corpus_group(const environment& env, const string& path = "")
   : corpus(env, path), priv_(new priv)
 {}
 
@@ -1708,15 +1687,6 @@ corpus_group::add_corpus(const corpus_sptr& corp)
   if (!corp)
     return;
 
-  // Ensure the new environment patches the current one.
-  if (const environment* cur_env = get_environment())
-    {
-      if (environment* corp_env = corp->get_environment())
-	ABG_ASSERT(cur_env == corp_env);
-    }
-  else
-    set_environment(corp->get_environment());
-
   // Ensure the new architecture name matches the current one.
   string cur_arch = get_architecture_name(),
     corp_arch = corp->get_architecture_name();
diff --git a/src/abg-ctf-reader.cc b/src/abg-ctf-reader.cc
index e307fcd7..49dd69df 100644
--- a/src/abg-ctf-reader.cc
+++ b/src/abg-ctf-reader.cc
@@ -54,7 +54,7 @@ public:
   string filename;
 
   /// The IR environment.
-  ir::environment *ir_env;
+  ir::environment& ir_env;
 
   /// The CTF archive read from FILENAME.  If an archive couldn't
   /// be read from the file then this is NULL.
@@ -271,10 +271,10 @@ public:
   /// created within the same environment.
   read_context(const string& elf_path,
                const vector<char**>& debug_info_root_paths,
-               ir::environment *env) :
-   ctfa(NULL)
+               ir::environment& env) :
+   ir_env(env), ctfa(nullptr)
   {
-    initialize(elf_path, debug_info_root_paths, env);
+    initialize(elf_path, debug_info_root_paths);
   }
 
   /// Initializer of read_context.
@@ -297,12 +297,10 @@ public:
   /// the environment.
   void
   initialize(const string& elf_path,
-             const vector<char**>& debug_info_root_paths,
-             ir::environment *env)
+             const vector<char**>& debug_info_root_paths)
   {
     types_map.clear();
     filename = elf_path;
-    ir_env = env;
     elf_handler = NULL;
     elf_handler_dbg = NULL;
     elf_fd = -1;
@@ -425,7 +423,7 @@ process_ctf_base_type(read_context *ctxt,
       && type_encoding.cte_format == CTF_INT_SIGNED)
     {
       /* This is the `void' type.  */
-      type_base_sptr void_type = ctxt->ir_env->get_void_type();
+      type_base_sptr void_type = ctxt->ir_env.get_void_type();
       decl_base_sptr type_declaration = get_type_declaration(void_type);
       result = is_type_decl(type_declaration);
       canonicalize(result);
@@ -472,9 +470,8 @@ build_ir_node_for_variadic_parameter_type(read_context &ctxt,
                                           translation_unit_sptr tunit)
 {
 
-  ir::environment* env = ctxt.ir_env;
-  ABG_ASSERT(env);
-  type_base_sptr t = env->get_variadic_parameter_type();
+  ir::environment& env = ctxt.ir_env;
+  type_base_sptr t = env.get_variadic_parameter_type();
   decl_base_sptr type_declaration = get_type_declaration(t);
   if (!has_scope(type_declaration))
     add_decl_to_scope(type_declaration, tunit->get_global_scope());
@@ -1041,7 +1038,7 @@ process_ctf_enum_type(read_context *ctxt,
   int evalue;
 
   while ((ename = ctf_enum_next(ctf_dictionary, ctf_type, &enum_next, &evalue)))
-    enms.push_back(enum_type_decl::enumerator(ctxt->ir_env, ename, evalue));
+    enms.push_back(enum_type_decl::enumerator(ename, evalue));
   if (ctf_errno(ctf_dictionary) != ECTF_NEXT_END)
     {
       fprintf(stderr, "ERROR from ctf_enum_next\n");
@@ -1618,7 +1615,7 @@ find_ctfa_file(read_context *ctxt, std::string& ctfa_file)
 read_context_sptr
 create_read_context(const std::string& elf_path,
                     const vector<char**>& debug_info_root_paths,
-                    ir::environment *env)
+                    ir::environment& env)
 {
   read_context_sptr result(new read_context(elf_path,
                                             debug_info_root_paths,
@@ -1687,7 +1684,7 @@ read_corpus(read_context *ctxt, elf_reader::status &status)
     ctxt->ctfa = ctf_arc_bufopen(&ctxt->ctf_sect, &ctxt->symtab_sect,
                                  &ctxt->strtab_sect, &errp);
 
-  ctxt->ir_env->canonicalization_is_done(false);
+  ctxt->ir_env.canonicalization_is_done(false);
   if (ctxt->ctfa == NULL)
     status |= elf_reader::STATUS_DEBUG_INFO_NOT_FOUND;
   else
@@ -1697,7 +1694,7 @@ read_corpus(read_context *ctxt, elf_reader::status &status)
       ctxt->cur_corpus_->sort_variables();
     }
 
-  ctxt->ir_env->canonicalization_is_done(true);
+  ctxt->ir_env.canonicalization_is_done(true);
 
   /* Cleanup and return.  */
   close_elf_handler(ctxt);
@@ -1776,11 +1773,10 @@ read_and_add_corpus_to_group_from_elf(read_context* ctxt,
 void
 reset_read_context(read_context_sptr	&ctxt,
                    const std::string&	 elf_path,
-                   const vector<char**>& debug_info_root_path,
-                   ir::environment*	 environment)
+	     const vector<char**>&	debug_info_root_path)
 {
   if (ctxt)
-    ctxt->initialize(elf_path, debug_info_root_path, environment);
+    ctxt->initialize(elf_path, debug_info_root_path);
 }
 
 /// Returns a key to be use in types_map dict conformed by
diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc
index ddd040e1..f07cb80e 100644
--- a/src/abg-dwarf-reader.cc
+++ b/src/abg-dwarf-reader.cc
@@ -892,7 +892,7 @@ compare_symbol_name(const string& symbol_name,
 /// @param syms_found a vector of symbols found with the name @p
 /// sym_name.  table.
 static bool
-lookup_symbol_from_sysv_hash_tab(const environment*		env,
+lookup_symbol_from_sysv_hash_tab(const environment&		env,
 				 Elf*				elf_handle,
 				 const string&			sym_name,
 				 size_t			ht_index,
@@ -1169,7 +1169,7 @@ setup_gnu_ht(Elf* elf_handle,
 ///
 /// @return true if a symbol was actually found.
 static bool
-lookup_symbol_from_gnu_hash_tab(const environment*		env,
+lookup_symbol_from_gnu_hash_tab(const environment&		env,
 				Elf*				elf_handle,
 				const string&			sym_name,
 				size_t				ht_index,
@@ -1301,7 +1301,7 @@ lookup_symbol_from_gnu_hash_tab(const environment*		env,
 /// @return true iff the function found the symbol from the elf hash
 /// table.
 static bool
-lookup_symbol_from_elf_hash_tab(const environment*		env,
+lookup_symbol_from_elf_hash_tab(const environment&		env,
 				Elf*				elf_handle,
 				hash_table_kind		ht_kind,
 				size_t				ht_index,
@@ -1358,7 +1358,7 @@ lookup_symbol_from_elf_hash_tab(const environment*		env,
 ///
 /// @return true iff the symbol was found.
 static bool
-lookup_symbol_from_symtab(const environment*		env,
+lookup_symbol_from_symtab(environment&			env,
 			  Elf*				elf_handle,
 			  const string&		sym_name,
 			  size_t			sym_tab_index,
@@ -1449,7 +1449,7 @@ lookup_symbol_from_symtab(const environment*		env,
 ///
 /// @return true iff a symbol with the name @p symbol_name was found.
 static bool
-lookup_symbol_from_elf(const environment*		env,
+lookup_symbol_from_elf(environment&			env,
 		       Elf*				elf_handle,
 		       const string&			symbol_name,
 		       bool				demangle,
@@ -1500,7 +1500,7 @@ lookup_symbol_from_elf(const environment*		env,
 ///
 /// @return true iff the symbol was found.
 static bool
-lookup_public_function_symbol_from_elf(const environment*		env,
+lookup_public_function_symbol_from_elf(environment&			env,
 				       Elf*				elf_handle,
 				       const string&			symbol_name,
 				       vector<elf_symbol_sptr>&	func_syms)
@@ -2019,14 +2019,14 @@ class read_context
 public:
   struct options_type
   {
-    environment*	env;
+    environment&	env;
     bool		load_in_linux_kernel_mode;
     bool		load_all_types;
     bool		show_stats;
     bool		do_log;
 
-    options_type()
-      : env(),
+    options_type(environment& e)
+      : env(e),
 	load_in_linux_kernel_mode(),
 	load_all_types(),
 	show_stats(),
@@ -2280,11 +2280,12 @@ public:
   /// exported or not.
   read_context(const string&	elf_path,
 	       const vector<char**>& debug_info_root_paths,
-	       ir::environment* environment,
+	       ir::environment& environment,
 	       bool		load_all_types,
 	       bool		linux_kernel_mode)
+    : options_(environment)
   {
-    initialize(elf_path, debug_info_root_paths, environment,
+    initialize(elf_path, debug_info_root_paths,
 	       load_all_types, linux_kernel_mode);
   }
 
@@ -2320,7 +2321,6 @@ public:
   void
   initialize(const string&	elf_path,
 	     const vector<char**>& debug_info_root_paths,
-	     ir::environment* environment,
 	     bool		load_all_types,
 	     bool		linux_kernel_mode)
   {
@@ -2378,7 +2378,6 @@ public:
 
     memset(&offline_callbacks_, 0, sizeof(offline_callbacks_));
     create_default_dwfl(debug_info_root_paths);
-    options_.env = environment;
     options_.load_in_linux_kernel_mode = linux_kernel_mode;
     options_.load_all_types = load_all_types;
     drop_undefined_syms_ = false;
@@ -2442,23 +2441,16 @@ public:
   /// Getter for the current environment.
   ///
   /// @return the current environment.
-  const ir::environment*
-  env() const
+  environment&
+  env()
   {return options_.env;}
 
   /// Getter for the current environment.
   ///
   /// @return the current environment.
-  ir::environment*
-  env()
-  {return options_.env;}
-
-  /// Setter for the current environment.
-  ///
-  /// @param env the new current environment.
-  void
-  env(ir::environment* env)
-  {options_.env = env;}
+  const environment&
+  env() const
+  {return const_cast<read_context*>(this)->env();}
 
   /// Getter for the flag that tells us if we are dropping functions
   /// and variables that have undefined symbols.
@@ -3333,7 +3325,7 @@ public:
       {
 	read_context& ctxt  = *const_cast<read_context*>(this);
 	string qualified_name = die_qualified_name(ctxt, die, where_offset);
-	interned_string istr = env()->intern(qualified_name);
+	interned_string istr = env().intern(qualified_name);
 	map[die_offset] = istr;
 	return istr;
       }
@@ -3384,7 +3376,7 @@ public:
 
     // The name of the translation unit die is "".
     if (die == cur_tu_die())
-      return env()->intern("");
+      return env().intern("");
 
     die_istring_map_type& map =
       die_qualified_name_maps_.get_container(*const_cast<read_context*>(this),
@@ -3412,7 +3404,7 @@ public:
 	  qualified_name =
 	    die_qualified_type_name(ctxt, die, where_offset);
 
-	interned_string istr = env()->intern(qualified_name);
+	interned_string istr = env().intern(qualified_name);
 	map[die_offset] = istr;
 	return istr;
       }
@@ -3453,7 +3445,7 @@ public:
 	read_context& ctxt = *const_cast<read_context*>(this);
 	string pretty_representation =
 	  die_pretty_print_type(ctxt, die, where_offset);
-	interned_string istr = env()->intern(pretty_representation);
+	interned_string istr = env().intern(pretty_representation);
 	map[die_offset] = istr;
 	return istr;
       }
@@ -3490,7 +3482,7 @@ public:
 	read_context& ctxt = *const_cast<read_context*>(this);
 	string pretty_representation =
 	  die_pretty_print(ctxt, die, where_offset);
-	interned_string istr = env()->intern(pretty_representation);
+	interned_string istr = env().intern(pretty_representation);
 	map[die_offset] = istr;
 	return istr;
       }
@@ -4262,16 +4254,16 @@ public:
     if (!l || !r)
       return !!l == !!r;
 
-    const environment* e = l->get_environment();
-    ABG_ASSERT(!e->canonicalization_is_done());
+    const environment& e = l->get_environment();
+    ABG_ASSERT(!e.canonicalization_is_done());
 
-    e->priv_->allow_type_comparison_results_caching(true);
-    bool s0 = e->decl_only_class_equals_definition();
-    e->decl_only_class_equals_definition(true);
+    e.priv_->allow_type_comparison_results_caching(true);
+    bool s0 = e.decl_only_class_equals_definition();
+    e.decl_only_class_equals_definition(true);
     bool equal = l == r;
-    e->decl_only_class_equals_definition(s0);
-    e->priv_->clear_type_comparison_results_cache();
-    e->priv_->allow_type_comparison_results_caching(false);
+    e.decl_only_class_equals_definition(s0);
+    e.priv_->clear_type_comparison_results_cache();
+    e.priv_->allow_type_comparison_results_caching(false);
     return equal;
   }
 
@@ -12764,7 +12756,7 @@ build_translation_unit_and_add_to_ir(read_context&	ctxt,
   do
     // Analyze all the DIEs we encounter unless we are asked to only
     // analyze exported interfaces and the types reachables from them.
-    if (!ctxt.env()->analyze_exported_interfaces_only()
+    if (!ctxt.env().analyze_exported_interfaces_only()
 	|| ctxt.is_decl_die_with_exported_symbol(&child))
       build_ir_node_from_die(ctxt, &child,
 			     die_is_public_decl(&child),
@@ -13098,7 +13090,7 @@ build_enum_type(read_context&	ctxt,
 	  die_loc_and_name(ctxt, &child, l, n, m);
 	  uint64_t val = 0;
 	  die_unsigned_constant_attribute(&child, DW_AT_const_value, val);
-	  enms.push_back(enum_type_decl::enumerator(ctxt.env(), n, val));
+	  enms.push_back(enum_type_decl::enumerator(n, val));
 	}
       while (dwarf_siblingof(&child, &child) == 0);
     }
@@ -14698,8 +14690,7 @@ build_function_type(read_context&	ctxt,
 	  {
 	    // This is a variadic function parameter.
 	    bool is_artificial = die_is_artificial(&child);
-	    ir::environment* env = ctxt.env();
-	    ABG_ASSERT(env);
+
 	    type_base_sptr parm_type =
 	      is_type(build_ir_node_for_variadic_parameter_type(ctxt));
 	    function_decl::parameter_sptr p
@@ -15044,7 +15035,7 @@ build_typedef_type(read_context&	ctxt,
       if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
 	// A typedef DIE with no underlying type means a typedef to
 	// void type.
-	utype = ctxt.env()->get_void_type();
+	utype = ctxt.env().get_void_type();
 
       if (!utype)
 	utype =
@@ -15639,7 +15630,7 @@ get_opaque_version_of_type(read_context	&ctxt,
 ///
 /// @return the newly created symbol.
 elf_symbol_sptr
-create_default_fn_sym(const string& sym_name, const environment *env)
+create_default_fn_sym(const string& sym_name, const environment& env)
 {
   elf_symbol::version ver;
   elf_symbol_sptr result =
@@ -15795,14 +15786,14 @@ read_debug_info_into_corpus(read_context& ctxt)
   ctxt.current_corpus()->set_origin(origin);
 
   if (origin & corpus::LINUX_KERNEL_BINARY_ORIGIN
-      && !ctxt.env()->user_set_analyze_exported_interfaces_only())
+      && !ctxt.env().user_set_analyze_exported_interfaces_only())
     // So we are looking at the Linux Kernel and the user has not set
     // any particular option regarding the amount of types to analyse.
     // In that case, we need to only analyze types that are reachable
     // from exported interfaces otherwise we get such a massive amount
     // of type DIEs to look at that things are just too slow down the
     // road.
-    ctxt.env()->analyze_exported_interfaces_only(true);
+    ctxt.env().analyze_exported_interfaces_only(true);
 
   ctxt.current_corpus()->set_soname(ctxt.dt_soname());
   ctxt.current_corpus()->set_needed(ctxt.dt_needed());
@@ -15825,8 +15816,8 @@ read_debug_info_into_corpus(read_context& ctxt)
     (ctxt.current_corpus()->get_exported_decls_builder().get());
 
 #ifdef WITH_DEBUG_SELF_COMPARISON
-  if (ctxt.env()->self_comparison_debug_is_on())
-    ctxt.env()->set_self_comparison_debug_input(ctxt.current_corpus());
+  if (ctxt.env().self_comparison_debug_is_on())
+    ctxt.env().set_self_comparison_debug_input(ctxt.current_corpus());
 #endif
 
   // Walk all the DIEs of the debug info to build a DIE -> parent map
@@ -15851,7 +15842,7 @@ read_debug_info_into_corpus(read_context& ctxt)
       }
   }
 
-  ctxt.env()->canonicalization_is_done(false);
+  ctxt.env().canonicalization_is_done(false);
 
   {
     tools_utils::timer t;
@@ -15987,7 +15978,7 @@ read_debug_info_into_corpus(read_context& ctxt)
       }
   }
 
-  ctxt.env()->canonicalization_is_done(true);
+  ctxt.env().canonicalization_is_done(true);
 
   {
     tools_utils::timer t;
@@ -16739,9 +16730,8 @@ build_ir_node_from_die(read_context&	ctxt,
 static decl_base_sptr
 build_ir_node_for_void_type(read_context& ctxt)
 {
-  ir::environment* env = ctxt.env();
-  ABG_ASSERT(env);
-  type_base_sptr t = env->get_void_type();
+  ir::environment& env = ctxt.env();
+  type_base_sptr t = env.get_void_type();
   decl_base_sptr type_declaration = get_type_declaration(t);
   if (!has_scope(type_declaration))
     add_decl_to_scope(type_declaration,
@@ -16759,9 +16749,8 @@ static decl_base_sptr
 build_ir_node_for_variadic_parameter_type(read_context &ctxt)
 {
 
-  ir::environment* env = ctxt.env();
-  ABG_ASSERT(env);
-  type_base_sptr t = env->get_variadic_parameter_type();
+  ir::environment& env = ctxt.env();
+  type_base_sptr t = env.get_variadic_parameter_type();
   decl_base_sptr type_declaration = get_type_declaration(t);
   if (!has_scope(type_declaration))
     add_decl_to_scope(type_declaration,
@@ -16862,7 +16851,7 @@ build_ir_node_from_die(read_context&	ctxt,
 read_context_sptr
 create_read_context(const std::string&		elf_path,
 		    const vector<char**>&	debug_info_root_paths,
-		    ir::environment*		environment,
+		    ir::environment&		environment,
 		    bool			load_all_types,
 		    bool			linux_kernel_mode)
 {
@@ -16919,12 +16908,11 @@ void
 reset_read_context(read_context_sptr	&ctxt,
 		   const std::string&	 elf_path,
 		   const vector<char**>& debug_info_root_path,
-		   ir::environment*	 environment,
 		   bool		 read_all_types,
 		   bool		 linux_kernel_mode)
 {
   if (ctxt)
-    ctxt->initialize(elf_path, debug_info_root_path, environment,
+    ctxt->initialize(elf_path, debug_info_root_path,
 		     read_all_types, linux_kernel_mode);
 }
 
@@ -17082,7 +17070,7 @@ read_and_add_corpus_to_group_from_elf(read_context& ctxt,
 corpus_sptr
 read_corpus_from_elf(const std::string& elf_path,
 		     const vector<char**>& debug_info_root_paths,
-		     ir::environment*	environment,
+		     environment&	environment,
 		     bool		load_all_types,
 		     status&		status)
 {
@@ -17111,7 +17099,7 @@ read_corpus_from_elf(const std::string& elf_path,
 /// @return true iff the symbol was found among the publicly exported
 /// symbols of the ELF file.
 bool
-lookup_symbol_from_elf(const environment*		env,
+lookup_symbol_from_elf(environment&			env,
 		       const string&			elf_path,
 		       const string&			symbol_name,
 		       bool				demangle,
@@ -17156,7 +17144,7 @@ lookup_symbol_from_elf(const environment*		env,
 /// @return true iff a function with symbol name @p symbol_name is
 /// found.
 bool
-lookup_public_function_symbol_from_elf(const environment*		env,
+lookup_public_function_symbol_from_elf(environment&			env,
 				       const string&			path,
 				       const string&			symname,
 				       vector<elf_symbol_sptr>&	syms)
@@ -17279,7 +17267,8 @@ has_alt_debug_info(const string&	elf_path,
 {
   vector<char**> di_roots;
   di_roots.push_back(debug_info_root_path);
-  read_context_sptr c = create_read_context(elf_path, di_roots, 0);
+  environment env;
+  read_context_sptr c = create_read_context(elf_path, di_roots, env);
   read_context& ctxt = *c;
 
   // Load debug info from the elf path.
diff --git a/src/abg-ir-priv.h b/src/abg-ir-priv.h
index dd3c6276..32041d31 100644
--- a/src/abg-ir-priv.h
+++ b/src/abg-ir-priv.h
@@ -141,7 +141,7 @@ parse_integral_type(const string& type_name,
 /// Private type to hold private members of @ref translation_unit
 struct translation_unit::priv
 {
-  const environment*				env_;
+  const environment&				env_;
   corpus*					corp;
   bool						is_constructed_;
   char						address_size_;
@@ -156,7 +156,7 @@ struct translation_unit::priv
   type_maps					types_;
 
 
-  priv(const environment* env)
+  priv(const environment& env)
     : env_(env),
       corp(),
       is_constructed_(),
@@ -845,7 +845,7 @@ struct environment::priv
     for (auto i : types_with_non_confirmed_propagated_ct_)
       {
 	type_base *t = reinterpret_cast<type_base*>(i);
-	ABG_ASSERT(t->get_environment()->priv_->is_recursive_type(t)
+	ABG_ASSERT(t->get_environment().priv_->is_recursive_type(t)
 		   || t->priv_->depends_on_recursive_type());
 	t->priv_->set_does_not_depend_on_recursive_type(dependant_type);
 	if (!t->priv_->depends_on_recursive_type())
@@ -876,13 +876,12 @@ struct environment::priv
     if (!t || t->priv_->propagated_canonical_type_confirmed())
       return;
 
-    const environment* env = t->get_environment();
-    ABG_ASSERT(env);
+    const environment& env = t->get_environment();
 
-    env->priv_->confirm_ct_propagation_for_types_dependant_on(t);
+    env.priv_->confirm_ct_propagation_for_types_dependant_on(t);
     t->priv_->set_does_not_depend_on_recursive_type();
-    env->priv_->remove_from_types_with_non_confirmed_propagated_ct(t);
-    env->priv_->set_is_not_recursive(t);
+    env.priv_->remove_from_types_with_non_confirmed_propagated_ct(t);
+    env.priv_->set_is_not_recursive(t);
     t->priv_->set_propagated_canonical_type_confirmed(true);
   }
 
@@ -900,7 +899,7 @@ struct environment::priv
     for (auto i : types_with_non_confirmed_propagated_ct_)
       {
 	type_base *t = reinterpret_cast<type_base*>(i);
-	ABG_ASSERT(t->get_environment()->priv_->is_recursive_type(t)
+	ABG_ASSERT(t->get_environment().priv_->is_recursive_type(t)
 		   || t->priv_->depends_on_recursive_type());
 	t->priv_->set_does_not_depend_on_recursive_type();
 	t->priv_->set_propagated_canonical_type_confirmed(true);
@@ -970,7 +969,7 @@ struct environment::priv
     for (auto i : to_remove)
       {
 	type_base *t = reinterpret_cast<type_base*>(i);
-	ABG_ASSERT(t->get_environment()->priv_->is_recursive_type(t)
+	ABG_ASSERT(t->get_environment().priv_->is_recursive_type(t)
 		   || t->priv_->depends_on_recursive_type());
 	type_base_sptr canonical = t->priv_->canonical_type.lock();
 	if (canonical)
@@ -1007,10 +1006,10 @@ struct environment::priv
     if (!t)
       return;
 
-    const environment *env = t->get_environment();
-    env->priv_->cancel_ct_propagation_for_types_dependant_on(t);
+    const environment& env = t->get_environment();
+    env.priv_->cancel_ct_propagation_for_types_dependant_on(t);
     if (t->priv_->depends_on_recursive_type()
-	|| env->priv_->is_recursive_type(t))
+	|| env.priv_->is_recursive_type(t))
       {
 	// This cannot carry any tentative canonical type at this
 	// point.
@@ -1020,7 +1019,7 @@ struct environment::priv
 	// Reset the marking of the type as it no longer carries a
 	// tentative canonical type that might be later cancelled.
 	t->priv_->set_does_not_depend_on_recursive_type();
-	env->priv_->remove_from_types_with_non_confirmed_propagated_ct(t);
+	env.priv_->remove_from_types_with_non_confirmed_propagated_ct(t);
       }
   }
 
@@ -1174,9 +1173,8 @@ struct class_or_union::priv
   mark_as_being_compared(const class_or_union& first,
 			 const class_or_union& second) const
   {
-    const environment* env = first.get_environment();
-    ABG_ASSERT(env);
-    env->priv_->classes_being_compared_.insert
+    const environment& env = first.get_environment();
+    env.priv_->classes_being_compared_.insert
       (std::make_pair(reinterpret_cast<uint64_t>(&first),
 		      reinterpret_cast<uint64_t>(&second)));
   }
@@ -1237,9 +1235,8 @@ struct class_or_union::priv
   unmark_as_being_compared(const class_or_union& first,
 			   const class_or_union& second) const
   {
-    const environment* env = first.get_environment();
-    ABG_ASSERT(env);
-    env->priv_->classes_being_compared_.erase
+    const environment& env = first.get_environment();
+    env.priv_->classes_being_compared_.erase
       (std::make_pair(reinterpret_cast<uint64_t>(&first),
 		      reinterpret_cast<uint64_t>(&second)));
   }
@@ -1279,9 +1276,8 @@ struct class_or_union::priv
   comparison_started(const class_or_union& first,
 		     const class_or_union& second) const
   {
-    const environment* env = first.get_environment();
-    ABG_ASSERT(env);
-    return env->priv_->
+    const environment& env = first.get_environment();
+    return env.priv_->
       classes_being_compared_.count
       (std::make_pair(reinterpret_cast<uint64_t>(&first),
 		      reinterpret_cast<uint64_t>((&second))));
@@ -1340,9 +1336,8 @@ struct function_type::priv
   mark_as_being_compared(const function_type& first,
 			 const function_type& second) const
   {
-    const environment* env = first.get_environment();
-    ABG_ASSERT(env);
-    env->priv_->fn_types_being_compared_.insert
+    const environment& env = first.get_environment();
+    env.priv_->fn_types_being_compared_.insert
       (std::make_pair(reinterpret_cast<uint64_t>(&first),
 		      reinterpret_cast<uint64_t>(&second)));
   }
@@ -1358,9 +1353,8 @@ struct function_type::priv
   unmark_as_being_compared(const function_type& first,
 			   const function_type& second) const
   {
-    const environment* env = first.get_environment();
-    ABG_ASSERT(env);
-    env->priv_->fn_types_being_compared_.erase
+    const environment& env = first.get_environment();
+    env.priv_->fn_types_being_compared_.erase
       (std::make_pair(reinterpret_cast<uint64_t>(&first),
 		      reinterpret_cast<uint64_t>(&second)));
   }
@@ -1374,9 +1368,8 @@ struct function_type::priv
   comparison_started(const function_type& first,
 		     const function_type& second) const
   {
-    const environment* env = first.get_environment();
-    ABG_ASSERT(env);
-    return env->priv_->fn_types_being_compared_.count
+    const environment& env = first.get_environment();
+    return env.priv_->fn_types_being_compared_.count
       (std::make_pair(reinterpret_cast<uint64_t>(&first),
 		      reinterpret_cast<uint64_t>(&second)));
   }
diff --git a/src/abg-ir.cc b/src/abg-ir.cc
index 5193934a..f4b50cae 100644
--- a/src/abg-ir.cc
+++ b/src/abg-ir.cc
@@ -39,59 +39,6 @@ ABG_END_EXPORT_DECLARATIONS
 
 namespace
 {
-/// This internal type is a tree walker that walks the sub-tree of a
-/// type and sets the environment of the type (including its sub-type)
-/// to a new environment.
-class environment_setter : public abigail::ir::ir_node_visitor
-{
-  const abigail::ir::environment* env_;
-
-public:
-  environment_setter(const abigail::ir::environment* env)
-    : env_(env)
-  {}
-
-  /// This function is called on each sub-tree node that is a
-  /// declaration.  Note that it's also called on some types because
-  /// most types that have a declarations also inherit the type @ref
-  /// decl_base.
-  ///
-  /// @param d the declaration being visited.
-  bool
-  visit_begin(abigail::ir::decl_base* d)
-  {
-    if (const abigail::ir::environment* env = d->get_environment())
-      {
-	ABG_ASSERT(env == env_);
-	return false;
-      }
-    else
-      d->set_environment(env_);
-
-    return true;
-
-  }
-
-  /// This function is called on each sub-tree node that is a type.
-  ///
-  /// @param t the type being visited.
-  bool
-  visit_begin(abigail::ir::type_base* t)
-  {
-    if (abigail::ir::environment* env = t->get_environment())
-      {
-	ABG_ASSERT(env == env_);
-	return false;
-      }
-    else
-      {
-	ABG_ASSERT(!t->get_environment());
-	t->set_environment(env_);
-      }
-    return true;
-  }
-};
-
 /// This internal type is a tree walking that is used to set the
 /// qualified name of a tree of decls and types.  It used by the
 /// function update_qualified_name().
@@ -297,8 +244,8 @@ void
 push_composite_type_comparison_operands(const type_base& left,
 					const type_base& right)
 {
-  const environment * env = left.get_environment();
-  env->priv_->push_composite_type_comparison_operands(&left, &right);
+  const environment& env = left.get_environment();
+  env.priv_->push_composite_type_comparison_operands(&left, &right);
 }
 
 /// Pop a pair of operands from the stack of operands to the current
@@ -318,8 +265,8 @@ void
 pop_composite_type_comparison_operands(const type_base& left,
 				       const type_base& right)
 {
-  const environment * env = left.get_environment();
-  env->priv_->pop_composite_type_comparison_operands(&left, &right);
+  const environment& env = left.get_environment();
+  env.priv_->pop_composite_type_comparison_operands(&left, &right);
 }
 
 /// In the stack of the current types being compared (as part of type
@@ -381,9 +328,9 @@ pop_composite_type_comparison_operands(const type_base& left,
 bool
 mark_dependant_types_compared_until(const type_base &r)
 {
-  const environment * env = r.get_environment();
-  if (env->do_on_the_fly_canonicalization())
-    return env->priv_->mark_dependant_types_compared_until(&r);
+  const environment& env = r.get_environment();
+  if (env.do_on_the_fly_canonicalization())
+    return env.priv_->mark_dependant_types_compared_until(&r);
   return false;
 }
 
@@ -888,8 +835,8 @@ try_canonical_compare(const T *l, const T *r)
   // instructing us to compare them canonically, and the second time
   // with that boolean set to false, instructing us to compare them
   // structurally.
-  const environment *env = l->get_environment();
-  if (env->priv_->use_canonical_type_comparison_)
+  const environment&env = l->get_environment();
+  if (env.priv_->use_canonical_type_comparison_)
     {
       if (const type_base *lc = l->get_naked_canonical_type())
 	if (const type_base *rc = r->get_naked_canonical_type())
@@ -1073,8 +1020,8 @@ return_comparison_result(T& l, T& r, bool value,
 
   unmark_types_as_being_compared(l, r);
 
-  const environment* env = l.get_environment();
-  if (env->do_on_the_fly_canonicalization())
+  const environment& env = l.get_environment();
+  if (env.do_on_the_fly_canonicalization())
     // We are instructed to perform the "canonical type propagation"
     // optimization, making 'r' to possibly get the canonical type of
     // 'l' if it has one.  This mostly means that we are currently
@@ -1083,17 +1030,17 @@ return_comparison_result(T& l, T& r, bool value,
     {
       if (value == true
 	  && (is_type(&r)->priv_->depends_on_recursive_type()
-	      || env->priv_->is_recursive_type(&r))
+	      || env.priv_->is_recursive_type(&r))
 	  && is_type(&r)->priv_->canonical_type_propagated()
 	  && !is_type(&r)->priv_->propagated_canonical_type_confirmed()
-	  && !env->priv_->right_type_comp_operands_.empty())
+	  && !env.priv_->right_type_comp_operands_.empty())
 	{
 	  // Track the object 'r' for which the propagated canonical
 	  // type might be re-initialized if the current comparison
 	  // eventually fails.
-	  env->priv_->add_to_types_with_non_confirmed_propagated_ct(is_type(&r));
+	  env.priv_->add_to_types_with_non_confirmed_propagated_ct(is_type(&r));
 	}
-      else if (value == true && env->priv_->right_type_comp_operands_.empty())
+      else if (value == true && env.priv_->right_type_comp_operands_.empty())
 	{
 	  // The type provided in the 'r' argument is the type that is
 	  // being canonicalized; 'r' is not a mere subtype being
@@ -1102,16 +1049,16 @@ return_comparison_result(T& l, T& r, bool value,
 	  // confirm the "canonical type propagation" of all the
 	  // sub-types that were compared during the comparison of
 	  // 'r'.
-	  env->priv_->confirm_ct_propagation(&r);
+	  env.priv_->confirm_ct_propagation(&r);
 	}
       else if (value == false)
 	{
 	  // The comparison of the current sub-type failed.  So all
 	  // the types in
-	  // env->prix_->types_with_non_confirmed_propagated_ct_
+	  // env.prix_->types_with_non_confirmed_propagated_ct_
 	  // should see their tentatively propagated canonical type
 	  // cancelled.
-	  env->priv_->cancel_ct_propagation(&r);
+	  env.priv_->cancel_ct_propagation(&r);
 	}
     }
 
@@ -1123,13 +1070,13 @@ return_comparison_result(T& l, T& r, bool value,
   // propagation can now see their tentative canonical type be
   // confirmed for real.
   if (value == true
-      && env->priv_->right_type_comp_operands_.empty()
-      && !env->priv_->types_with_non_confirmed_propagated_ct_.empty())
+      && env.priv_->right_type_comp_operands_.empty()
+      && !env.priv_->types_with_non_confirmed_propagated_ct_.empty())
     // So the comparison is completely done and there are some
     // types for which their propagated canonical type is sitll
     // considered not confirmed.  As the comparison did yield true, we
     // shall now confirm the propagation for all those types.
-    env->priv_->confirm_ct_propagation();
+    env.priv_->confirm_ct_propagation();
 
   ABG_RETURN(value);
 }
@@ -1188,7 +1135,7 @@ type_maps::get_types_sorted_by_name() const
 ///
 /// @param address_size the size of addresses in the translation unit,
 /// in bits.
-translation_unit::translation_unit(const environment*	env,
+translation_unit::translation_unit(const environment&	env,
 				   const std::string&	path,
 				   char		address_size)
   : priv_(new priv(env))
@@ -1220,10 +1167,6 @@ translation_unit::get_global_scope()
     {
       priv_->global_scope_.reset
 	(new global_scope(const_cast<translation_unit*>(this)));
-      // The global scope must be out of the same environment as its
-      // translation unit.
-      priv_->global_scope_->
-	set_environment(const_cast<environment*>(get_environment()));
       priv_->global_scope_->set_translation_unit
 	(const_cast<translation_unit*>(this));
     }
@@ -1256,24 +1199,10 @@ translation_unit::get_live_fn_types() const
 /// Getter of the environment of the current @ref translation_unit.
 ///
 /// @return the translation unit of the current translation unit.
-const environment*
+const environment&
 translation_unit::get_environment() const
 {return priv_->env_;}
 
-/// Getter of the environment of the current @ref translation_unit.
-///
-/// @return the translation unit of the current translation unit.
-environment*
-translation_unit::get_environment()
-{return const_cast<environment*>(priv_->env_);}
-
-/// Setter of the environment of the current @ref translation_unit.
-///
-/// @param env the environment.
-void
-translation_unit::set_environment(const environment* env)
-{priv_->env_ = env;}
-
 /// Getter of the language of the source code of the translation unit.
 ///
 /// @return the language of the source code.
@@ -1496,8 +1425,7 @@ translation_unit::operator!=(const translation_unit& o) const
 void
 translation_unit::bind_function_type_life_time(function_type_sptr ftype) const
 {
-  const environment* env = get_environment();
-  ABG_ASSERT(env);
+  const environment& env = get_environment();
 
   const_cast<translation_unit*>(this)->priv_->live_fn_types_.push_back(ftype);
 
@@ -1507,10 +1435,10 @@ translation_unit::bind_function_type_life_time(function_type_sptr ftype) const
 
   // The function type must be out of the same environment as its
   // translation unit.
-  if (const environment* e = ftype->get_environment())
-    ABG_ASSERT(env == e);
-  else
-    ftype->set_environment(const_cast<environment*>(env));
+  {
+    const environment& e = ftype->get_environment();
+    ABG_ASSERT(&env == &e);
+  }
 
   if (const translation_unit* existing_tu = ftype->get_translation_unit())
     ABG_ASSERT(existing_tu == this);
@@ -1749,7 +1677,7 @@ operator!=(const translation_unit_sptr& l, const translation_unit_sptr& r)
 // <elf_symbol stuff>
 struct elf_symbol::priv
 {
-  const environment*	env_;
+  const environment&	env_;
   size_t		index_;
   size_t		size_;
   string		name_;
@@ -1796,8 +1724,8 @@ struct elf_symbol::priv
   elf_symbol_wptr	next_common_instance_;
   string		id_string_;
 
-  priv()
-    : env_(),
+  priv(const environment& e)
+    : env_(e),
       index_(),
       size_(),
       type_(elf_symbol::NOTYPE_TYPE),
@@ -1811,7 +1739,7 @@ struct elf_symbol::priv
       is_suppressed_(false)
   {}
 
-  priv(const environment*	  e,
+  priv(const environment&	  e,
        size_t			  i,
        size_t			  s,
        const string&		  n,
@@ -1845,16 +1773,6 @@ struct elf_symbol::priv
   }
 }; // end struct elf_symbol::priv
 
-/// Default constructor of the @ref elf_symbol type.
-///
-/// Note that this constructor is private, so client code cannot use
-/// it to create instances of @ref elf_symbol.  Rather, client code
-/// should use the @ref elf_symbol::create() function to create
-/// instances of @ref elf_symbol instead.
-elf_symbol::elf_symbol()
-  : priv_(new priv)
-{}
-
 /// Constructor of the @ref elf_symbol type.
 ///
 /// Note that this constructor is private, so client code cannot use
@@ -1885,7 +1803,7 @@ elf_symbol::elf_symbol()
 /// @param crc the CRC (modversions) value of Linux Kernel symbols
 ///
 /// @param ns the namespace of Linux Kernel symbols, if any
-elf_symbol::elf_symbol(const environment* e,
+elf_symbol::elf_symbol(const environment& e,
 		       size_t		  i,
 		       size_t		  s,
 		       const string&	  n,
@@ -1915,20 +1833,6 @@ elf_symbol::elf_symbol(const environment* e,
 		   is_suppressed))
 {}
 
-/// Factory of instances of @ref elf_symbol.
-///
-/// This is the function to use to create instances of @ref elf_symbol.
-///
-/// @return a (smart) pointer to a newly created instance of @ref
-/// elf_symbol.
-elf_symbol_sptr
-elf_symbol::create()
-{
-  elf_symbol_sptr e(new elf_symbol());
-  e->priv_->main_symbol_ = e;
-  return e;
-}
-
 /// Factory of instances of @ref elf_symbol.
 ///
 /// This is the function to use to create instances of @ref elf_symbol.
@@ -1960,7 +1864,7 @@ elf_symbol::create()
 /// @return a (smart) pointer to a newly created instance of @ref
 /// elf_symbol.
 elf_symbol_sptr
-elf_symbol::create(const environment* e,
+elf_symbol::create(const environment& e,
 		   size_t	      i,
 		   size_t	      s,
 		   const string&      n,
@@ -2015,19 +1919,10 @@ textually_equals(const elf_symbol&l,
 /// elf_symbol.
 ///
 /// @return the enviroment used by the current instance of @ref elf_symbol.
-const environment*
+const environment&
 elf_symbol::get_environment() const
 {return priv_->env_;}
 
-/// Setter of the environment used by the current instance of @ref
-/// elf_symbol.
-///
-/// @param The new enviroment used by the current instance of @ref
-/// elf_symbol.
-void
-elf_symbol::set_environment(const environment* e) const
-{priv_->env_ = e;}
-
 /// Getter for the index
 ///
 /// @return the index of the symbol.
@@ -3593,7 +3488,7 @@ const type_base_sptr&
 environment::get_void_type() const
 {
   if (!priv_->void_type_)
-    priv_->void_type_.reset(new type_decl(const_cast<environment*>(this),
+    priv_->void_type_.reset(new type_decl(*this,
 					  intern("void"),
 					  0, 0, location()));
   return priv_->void_type_;
@@ -3609,7 +3504,7 @@ environment::get_variadic_parameter_type() const
 {
   if (!priv_->variadic_marker_type_)
     priv_->variadic_marker_type_.
-      reset(new type_decl(const_cast<environment*>(this),
+      reset(new type_decl(*this,
 			  intern("variadic parameter type"),
 			  0, 0, location()));
   return priv_->variadic_marker_type_;
@@ -4064,7 +3959,7 @@ struct type_or_decl_base::priv
   // hotspots, due to their use of dynamic_cast.
   void*			type_or_decl_ptr_;
   bool				hashing_started_;
-  const environment*		env_;
+  const environment&		env_;
   translation_unit*		translation_unit_;
   // The location of an artifact as seen from its input by the
   // artifact reader.  This might be different from the source
@@ -4082,7 +3977,7 @@ struct type_or_decl_base::priv
   ///
   /// @param k the identifier of the runtime type of the current
   /// instance of ABI artifact.
-  priv(const environment* e = 0,
+  priv(const environment& e,
        enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL)
     : kind_(k),
       rtti_(),
@@ -4142,26 +4037,17 @@ operator&=(type_or_decl_base::type_or_decl_kind& l,
   return l;
 }
 
-/// Default constructor of @ref type_or_decl_base.
-type_or_decl_base::type_or_decl_base()
-  :priv_(new priv)
-{}
-
 /// Constructor of @ref type_or_decl_base.
 ///
 /// @param the environment the current ABI artifact is constructed
 /// from.
 ///
 /// @param k the runtime identifier bitmap of the type being built.
-type_or_decl_base::type_or_decl_base(const environment* e,
+type_or_decl_base::type_or_decl_base(const environment& e,
 				     enum type_or_decl_kind k)
   :priv_(new priv(e, k))
 {}
 
-/// Copy constructor of @ref type_or_decl_base.
-type_or_decl_base::type_or_decl_base(const type_or_decl_base& o)
-{*priv_ = *o.priv_;}
-
 /// The destructor of the @ref type_or_decl_base type.
 type_or_decl_base::~type_or_decl_base()
 {}
@@ -4280,22 +4166,10 @@ void
 type_or_decl_base::hashing_started(bool b) const
 {priv_->hashing_started_ = b;}
 
-/// Setter of the environment of the current ABI artifact.
-///
-/// This just sets the environment artifact of the current ABI
-/// artifact, not on its sub-trees.  If you want to set the
-/// environment of an ABI artifact including its sub-tree, use the
-/// abigail::ir::set_environment_for_artifact() function.
-///
-/// @param env the new environment.
-void
-type_or_decl_base::set_environment(const environment* env)
-{priv_->env_ = env;}
-
 /// Getter of the environment of the current ABI artifact.
 ///
 /// @return the environment of the artifact.
-const environment*
+const environment&
 type_or_decl_base::get_environment() const
 {return priv_->env_;}
 
@@ -4345,13 +4219,6 @@ type_or_decl_base::has_artificial_location() const
 	  && priv_->artificial_location_.get_is_artificial());
 }
 
-/// Getter of the environment of the current ABI artifact.
-///
-/// @return the environment of the artifact.
-environment*
-type_or_decl_base::get_environment()
-{return const_cast<environment*>(priv_->env_);}
-
 /// Get the @ref corpus this ABI artifact belongs to.
 ///
 /// @return the corpus this ABI artifact belongs to, or nil if it
@@ -4399,19 +4266,6 @@ const translation_unit*
 type_or_decl_base::get_translation_unit() const
 {return const_cast<type_or_decl_base*>(this)->get_translation_unit();}
 
-/// Assignment operator for @ref type_or_decl_base.
-///
-/// @param o the other instance to assign the current instance to.
-///
-/// return a reference to the assigned instance of @ref
-/// type_or_decl_base.
-type_or_decl_base&
-type_or_decl_base::operator=(const type_or_decl_base& o)
-{
-  *priv_ = *o.priv_;
-  return *this;
-}
-
 /// Traverse the the ABI artifact.
 ///
 /// @param v the visitor used to traverse the sub-tree nodes of the
@@ -4420,33 +4274,6 @@ bool
 type_or_decl_base::traverse(ir_node_visitor&)
 {return true;}
 
-/// Set the environment of a given ABI artifact, including recursively
-/// setting the environment on the sub-trees of the artifact.
-///
-/// @param artifact the artifact to set the environment for.
-///
-/// @param env the new environment.
-void
-set_environment_for_artifact(type_or_decl_base* artifact,
-			     const environment* env)
-{
-  ABG_ASSERT(artifact && env);
-
-  ::environment_setter s(env);
-  artifact->traverse(s);
-}
-
-/// Set the environment of a given ABI artifact, including recursively
-/// setting the environment on the sub-trees of the artifact.
-///
-/// @param artifact the artifact to set the environment for.
-///
-/// @param env the new environment.
-void
-set_environment_for_artifact(type_or_decl_base_sptr artifact,
-			     const environment* env)
-{set_environment_for_artifact(artifact.get(), env);}
-
 /// Non-member equality operator for the @type_or_decl_base type.
 ///
 /// @param lr the left-hand operand of the equality.
@@ -4590,13 +4417,13 @@ struct decl_base::priv
 /// @param linkage_name the linkage name of the declaration.
 ///
 /// @param vis the visibility of the declaration.
-decl_base::decl_base(const environment* e,
+decl_base::decl_base(const environment& e,
 		     const string&	name,
 		     const location&	locus,
 		     const string&	linkage_name,
 		     visibility	vis)
   : type_or_decl_base(e, ABSTRACT_DECL_BASE),
-    priv_(new priv(e->intern(name), e->intern(linkage_name), vis))
+    priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
 {
   set_location(locus);
 }
@@ -4614,7 +4441,7 @@ decl_base::decl_base(const environment* e,
 /// constructed.
 ///
 /// @param vis the visibility of the declaration being constructed.
-decl_base::decl_base(const environment* e,
+decl_base::decl_base(const environment& e,
 		     const interned_string& name,
 		     const location& locus,
 		     const interned_string& linkage_name,
@@ -4632,26 +4459,13 @@ decl_base::decl_base(const environment* e,
 ///
 /// @param l the location where to find the declaration in the source
 /// code.
-decl_base::decl_base(const environment* e, const location& l)
+decl_base::decl_base(const environment& e, const location& l)
   : type_or_decl_base(e, ABSTRACT_DECL_BASE),
     priv_(new priv())
 {
   set_location(l);
 }
 
-decl_base::decl_base(const decl_base& d)
-  : type_or_decl_base(d)
-{
-  priv_->in_pub_sym_tab_ = d.priv_->in_pub_sym_tab_;
-  priv_->location_ = d.priv_->location_;
-  priv_->name_ = d.priv_->name_;
-  priv_->qualified_parent_name_ = d.priv_->qualified_parent_name_;
-  priv_->qualified_name_ = d.priv_->qualified_name_;
-  priv_->linkage_name_ = d.priv_->linkage_name_;
-  priv_->context_ = d.priv_->context_;
-  priv_->visibility_ = d.priv_->visibility_;
-}
-
 /// Getter for the qualified name.
 ///
 /// Unlike decl_base::get_qualified_name() this doesn't try to update
@@ -4831,7 +4645,7 @@ decl_base::set_location(const location& l)
 void
 decl_base::set_name(const string& n)
 {
-  priv_->name_ = get_environment()->intern(n);
+  priv_->name_ = get_environment().intern(n);
   priv_->is_anonymous_ = n.empty();
 }
 
@@ -4923,7 +4737,7 @@ decl_base::set_naming_typedef(const typedef_decl_sptr& t)
   priv_->naming_typedef_ = t;
   set_name(t->get_name());
   string qualified_name = build_qualified_name(get_scope(), t->get_name());
-  set_qualified_name(get_environment()->intern(qualified_name));
+  set_qualified_name(get_environment().intern(qualified_name));
   set_is_anonymous(false);
   // Now that the qualified type of the decl has changed, let's update
   // the qualified names of the member types of this decls.
@@ -4943,9 +4757,8 @@ decl_base::get_linkage_name() const
 void
 decl_base::set_linkage_name(const string& m)
 {
-  const environment* env = get_environment();
-  ABG_ASSERT(env);
-  priv_->linkage_name_ = env->intern(m);
+  const environment& env = get_environment();
+  priv_->linkage_name_ = env.intern(m);
 }
 
 /// Getter for the visibility of the decl.
@@ -5271,7 +5084,7 @@ get_decl_name_for_comparison(const decl_base &d)
       // other anymous types of the same kind.
       string r;
       r += get_generic_anonymous_internal_type_name(&d);
-      return d.get_environment()->intern(r);
+      return d.get_environment().intern(r);
     }
 
   interned_string n = (is_anonymous_or_typedef_named(d)
@@ -6722,8 +6535,7 @@ strip_typedef(const type_base_sptr type)
       return type;
     }
 
-  environment* env = type->get_environment();
-  ABG_ASSERT(env);
+  const environment& env = type->get_environment();
   type_base_sptr t = type;
 
   if (const typedef_decl_sptr ty = is_typedef(t))
@@ -6818,9 +6630,6 @@ strip_typedef(const type_base_sptr type)
 				ty->get_alignment_in_bits()));
     }
 
-  if (!t->get_environment())
-    set_environment_for_artifact(t, env);
-
   if (!t->get_translation_unit())
     t->set_translation_unit(type->get_translation_unit());
 
@@ -6852,12 +6661,12 @@ strip_useless_const_qualification(const qualified_type_def_sptr t)
 
   decl_base_sptr result = t;
   type_base_sptr u = t->get_underlying_type();
-  environment* env = t->get_environment();
+  const environment& env = t->get_environment();
 
   if ((t->get_cv_quals() & qualified_type_def::CV_CONST
        && (is_reference_type(u)))
       || (t->get_cv_quals() & qualified_type_def::CV_CONST
-	  && env->is_void_type(u))
+	  && env.is_void_type(u))
       || t->get_cv_quals() == qualified_type_def::CV_NONE)
     // Let's strip the const qualifier because a reference is always
     // 'const' and a const void doesn't make sense.  They will just
@@ -7696,7 +7505,7 @@ struct scope_decl::priv
 /// @param locus the source location where the scope_decl is defined.
 ///
 /// @param vis the visibility of the declaration.
-scope_decl::scope_decl(const environment* env,
+scope_decl::scope_decl(const environment& env,
 		       const string& name,
 		       const location& locus,
 		       visibility vis)
@@ -7712,7 +7521,7 @@ scope_decl::scope_decl(const environment* env,
 /// @param l the source location where the scope_decl is defined.
 ///
 /// @param vis the visibility of the declaration.
-scope_decl::scope_decl(const environment* env, location& l)
+scope_decl::scope_decl(const environment& env, location& l)
   : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
     decl_base(env, "", l),
     priv_(new priv)
@@ -7898,9 +7707,6 @@ scope_decl::add_member_decl(const decl_base_sptr& member)
 
   update_qualified_name(member);
 
-  if (const environment* env = get_environment())
-    set_environment_for_artifact(member, env);
-
   if (translation_unit* tu = get_translation_unit())
     {
       if (translation_unit* existing_tu = member->get_translation_unit())
@@ -8043,9 +7849,6 @@ scope_decl::insert_member_decl(decl_base_sptr member,
 
   update_qualified_name(member);
 
-  if (const environment* env = get_environment())
-    set_environment_for_artifact(member, env);
-
   if (translation_unit* tu = get_translation_unit())
     {
       if (translation_unit* existing_tu = member->get_translation_unit())
@@ -8714,18 +8517,18 @@ get_generic_anonymous_internal_type_name(const decl_base *d)
 {
   ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
 
-  const environment *env = d->get_environment();
+  const environment&env = d->get_environment();
 
   interned_string result;
   if (is_class_type(d))
     result =
-      env->intern(tools_utils::get_anonymous_struct_internal_name_prefix());
+      env.intern(tools_utils::get_anonymous_struct_internal_name_prefix());
   else if (is_union_type(d))
     result =
-      env->intern(tools_utils::get_anonymous_union_internal_name_prefix());
+      env.intern(tools_utils::get_anonymous_union_internal_name_prefix());
   else if (is_enum_type(d))
     result =
-      env->intern(tools_utils::get_anonymous_enum_internal_name_prefix());
+      env.intern(tools_utils::get_anonymous_enum_internal_name_prefix());
   else
     ABG_ASSERT_NOT_REACHED;
 
@@ -8795,15 +8598,14 @@ get_type_name(const type_base* t, bool qualified, bool internal)
 	{
 	  string r;
 	  r += get_generic_anonymous_internal_type_name(d);
-	  return t->get_environment()->intern(r);
+	  return t->get_environment().intern(r);
 	}
 
       if (qualified)
 	return d->get_qualified_name(internal);
 
-      const environment *env = d->get_environment();
-      ABG_ASSERT(env);
-      return env->intern(get_internal_integral_type_name(t));
+      const environment&env = d->get_environment();
+      return env.intern(get_internal_integral_type_name(t));
     }
 
   if (qualified)
@@ -8844,13 +8646,11 @@ interned_string
 get_name_of_pointer_to_type(const type_base& pointed_to_type,
 			    bool qualified, bool internal)
 {
-  const environment* env = pointed_to_type.get_environment();
-  ABG_ASSERT(env);
-
+  const environment& env = pointed_to_type.get_environment();
   string tn = get_type_name(pointed_to_type, qualified, internal);
   tn =  tn + "*";
 
-  return env->intern(tn);
+  return env.intern(tn);
 }
 
 /// Get the name of the reference to a given type.
@@ -8869,8 +8669,7 @@ get_name_of_reference_to_type(const type_base& pointed_to_type,
 			      bool lvalue_reference,
 			      bool qualified, bool internal)
 {
-  const environment* env = pointed_to_type.get_environment();
-  ABG_ASSERT(env);
+  const environment& env = pointed_to_type.get_environment();
 
   string name = get_type_name(pointed_to_type, qualified, internal);
   if (lvalue_reference)
@@ -8878,7 +8677,7 @@ get_name_of_reference_to_type(const type_base& pointed_to_type,
   else
     name = name + "&&";
 
-  return env->intern(name);
+  return env.intern(name);
 }
 
 /// Get the name of a qualified type, given the underlying type and
@@ -8900,8 +8699,7 @@ get_name_of_qualified_type(const type_base_sptr& underlying_type,
 			   qualified_type_def::CV quals,
 			   bool qualified, bool internal)
 {
-  const environment* env = underlying_type->get_environment();
-  ABG_ASSERT(env);
+  const environment& env = underlying_type->get_environment();
 
   string quals_repr = get_string_representation_of_cv_quals(quals);
   string name = get_type_name(underlying_type, qualified, internal);
@@ -8931,7 +8729,7 @@ get_name_of_qualified_type(const type_base_sptr& underlying_type,
 	name = quals_repr + " " + name;
     }
 
-  return env->intern(name);
+  return env.intern(name);
 }
 
 /// Get the name of a given function type and return a copy of it.
@@ -8994,8 +8792,7 @@ get_function_type_name(const function_type& fn_type,
     internal
     ? peel_typedef_type(fn_type.get_return_type())
     : fn_type.get_return_type();
-  const environment* env = fn_type.get_environment();
-  ABG_ASSERT(env);
+  const environment& env = fn_type.get_environment();
 
   o <<  get_pretty_representation(return_type, internal);
 
@@ -9015,7 +8812,7 @@ get_function_type_name(const function_type& fn_type,
     }
   o <<")";
 
-  return env->intern(o.str());
+  return env.intern(o.str());
 }
 
 /// Get the name of a given method type and return a copy of it.
@@ -9076,8 +8873,7 @@ get_method_type_name(const method_type& fn_type,
     internal
     ? peel_typedef_type(fn_type.get_return_type())
     : fn_type.get_return_type();
-  const environment* env = fn_type.get_environment();
-  ABG_ASSERT(env);
+  const environment& env = fn_type.get_environment();
 
   if (return_type)
     o << return_type->get_cached_pretty_representation(internal);
@@ -9112,7 +8908,7 @@ get_method_type_name(const method_type& fn_type,
     }
   o <<")";
 
-  return env->intern(o.str());
+  return env.intern(o.str());
 }
 
 /// Build and return a copy of the pretty representation of an ABI
@@ -10572,7 +10368,7 @@ is_void_pointer_type(const type_base* type)
   // Look through typedefs in the pointed-to type as well.
   type_base * ty = t->get_pointed_to_type().get();
   ty = peel_qualified_or_typedef_type(ty);
-  if (ty->get_environment()->is_void_type(ty))
+  if (ty->get_environment().is_void_type(ty))
     return ty;
 
   return 0;
@@ -11198,10 +10994,9 @@ lookup_basic_type(const interned_string& type_name, const translation_unit& tu)
 type_decl_sptr
 lookup_basic_type(const string& type_name, const translation_unit& tu)
 {
-  const environment* env = tu.get_environment();
-  ABG_ASSERT(env);
+  const environment& env = tu.get_environment();
 
-  interned_string s = env->intern(type_name);
+  interned_string s = env.intern(type_name);
   return lookup_basic_type(s, tu);
 }
 
@@ -11221,10 +11016,8 @@ lookup_basic_type(const string& type_name, const translation_unit& tu)
 class_decl_sptr
 lookup_class_type(const string& fqn, const translation_unit& tu)
 {
-  const environment* env = tu.get_environment();
-  ABG_ASSERT(env);
-
-  interned_string s = env->intern(fqn);
+  const environment& env = tu.get_environment();
+  interned_string s = env.intern(fqn);
   return lookup_class_type(s, tu);
 }
 
@@ -11278,10 +11071,8 @@ lookup_union_type(const interned_string& type_name, const translation_unit& tu)
 union_decl_sptr
 lookup_union_type(const string& fqn, const translation_unit& tu)
 {
-  const environment* env = tu.get_environment();
-  ABG_ASSERT(env);
-
-  interned_string s = env->intern(fqn);
+  const environment& env = tu.get_environment();
+  interned_string s = env.intern(fqn);
   return lookup_union_type(s, tu);
 }
 
@@ -11312,10 +11103,8 @@ lookup_union_type_per_location(const interned_string &loc, const corpus& corp)
 union_decl_sptr
 lookup_union_type_per_location(const string& loc, const corpus& corp)
 {
-  const environment* env = corp.get_environment();
-  ABG_ASSERT(env);
-
-  return lookup_union_type_per_location(env->intern(loc), corp);
+  const environment& env = corp.get_environment();
+  return lookup_union_type_per_location(env.intern(loc), corp);
 }
 
 /// Lookup an enum type from a translation unit.
@@ -11350,10 +11139,8 @@ lookup_enum_type(const interned_string& type_name, const translation_unit& tu)
 enum_type_decl_sptr
 lookup_enum_type(const string& type_name, const translation_unit& tu)
 {
-  const environment* env = tu.get_environment();
-  ABG_ASSERT(env);
-
-  interned_string s = env->intern(type_name);
+  const environment& env = tu.get_environment();
+  interned_string s = env.intern(type_name);
   return lookup_enum_type(s, tu);
 }
 
@@ -11392,10 +11179,8 @@ lookup_typedef_type(const interned_string& type_name,
 typedef_decl_sptr
 lookup_typedef_type(const string& type_name, const translation_unit& tu)
 {
-  const environment* env = tu.get_environment();
-  ABG_ASSERT(env);
-
-  interned_string s = env->intern(type_name);
+  const environment& env = tu.get_environment();
+  interned_string s = env.intern(type_name);
   return lookup_typedef_type(s, tu);
 }
 
@@ -11481,10 +11266,8 @@ lookup_pointer_type(const interned_string& type_name,
 pointer_type_def_sptr
 lookup_pointer_type(const string& type_name, const translation_unit& tu)
 {
-  const environment* env = tu.get_environment();
-  ABG_ASSERT(env);
-
-  interned_string s = env->intern(type_name);
+  const environment& env = tu.get_environment();
+  interned_string s = env.intern(type_name);
   return lookup_pointer_type(s, tu);
 }
 
@@ -11666,9 +11449,8 @@ lookup_type(const interned_string& fqn,
 type_base_sptr
 lookup_type(const string& fqn, const translation_unit& tu)
 {
-  const environment *env = tu.get_environment();
-  ABG_ASSERT(env);
-  interned_string ifqn = env->intern(fqn);
+  const environment&env = tu.get_environment();
+  interned_string ifqn = env.intern(fqn);
   return lookup_type(ifqn, tu);
 }
 
@@ -12450,10 +12232,8 @@ lookup_basic_type_per_location(const interned_string &loc,
 type_decl_sptr
 lookup_basic_type_per_location(const string &loc, const corpus &corp)
 {
-  const environment* env = corp.get_environment();
-  ABG_ASSERT(env);
-
-  return lookup_basic_type_per_location(env->intern(loc), corp);
+  const environment& env = corp.get_environment();
+  return lookup_basic_type_per_location(env.intern(loc), corp);
 }
 
 /// Look into a given corpus to find a basic type which has a given
@@ -12471,7 +12251,7 @@ lookup_basic_type_per_location(const string &loc, const corpus &corp)
 type_decl_sptr
 lookup_basic_type(const string& qualified_name, const corpus& corp)
 {
-  return lookup_basic_type(corp.get_environment()->intern(qualified_name),
+  return lookup_basic_type(corp.get_environment().intern(qualified_name),
 			   corp);
 }
 
@@ -12508,7 +12288,7 @@ lookup_class_type(const class_decl& t, const corpus& corp)
 class_decl_sptr
 lookup_class_type(const string& qualified_name, const corpus& corp)
 {
-  interned_string s = corp.get_environment()->intern(qualified_name);
+  interned_string s = corp.get_environment().intern(qualified_name);
   return lookup_class_type(s, corp);
 }
 
@@ -12595,7 +12375,7 @@ lookup_decl_only_class_types(const interned_string& qualified_name,
 const type_base_wptrs_type*
 lookup_class_types(const string& qualified_name, const corpus& corp)
 {
-  interned_string s = corp.get_environment()->intern(qualified_name);
+  interned_string s = corp.get_environment().intern(qualified_name);
   return lookup_class_types(s, corp);
 }
 
@@ -12627,10 +12407,8 @@ lookup_class_type_per_location(const interned_string& loc,
 class_decl_sptr
 lookup_class_type_per_location(const string &loc, const corpus &corp)
 {
-  const environment* env = corp.get_environment();
-  ABG_ASSERT(env);
-
-  return lookup_class_type_per_location(env->intern(loc), corp);
+  const environment& env = corp.get_environment();
+  return lookup_class_type_per_location(env.intern(loc), corp);
 }
 
 /// Look into a given corpus to find a union type which has a given
@@ -12670,7 +12448,7 @@ lookup_union_type(const interned_string& type_name, const corpus& corp)
 union_decl_sptr
 lookup_union_type(const string& type_name, const corpus& corp)
 {
-  interned_string s = corp.get_environment()->intern(type_name);
+  interned_string s = corp.get_environment().intern(type_name);
   return lookup_union_type(s, corp);
 }
 
@@ -12708,7 +12486,7 @@ lookup_enum_type(const enum_type_decl& t, const corpus& corp)
 enum_type_decl_sptr
 lookup_enum_type(const string& qualified_name, const corpus& corp)
 {
-  interned_string s = corp.get_environment()->intern(qualified_name);
+  interned_string s = corp.get_environment().intern(qualified_name);
   return lookup_enum_type(s, corp);
 }
 
@@ -12764,7 +12542,7 @@ lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
 const type_base_wptrs_type*
 lookup_enum_types(const string& qualified_name, const corpus& corp)
 {
-  interned_string s = corp.get_environment()->intern(qualified_name);
+  interned_string s = corp.get_environment().intern(qualified_name);
   return lookup_enum_types(s, corp);
 }
 
@@ -12795,10 +12573,8 @@ lookup_enum_type_per_location(const interned_string &loc, const corpus& corp)
 enum_type_decl_sptr
 lookup_enum_type_per_location(const string &loc, const corpus &corp)
 {
-  const environment* env = corp.get_environment();
-  ABG_ASSERT(env);
-
-  return lookup_enum_type_per_location(env->intern(loc), corp);
+  const environment& env = corp.get_environment();
+  return lookup_enum_type_per_location(env.intern(loc), corp);
 }
 
 /// Look into a given corpus to find a typedef type which has the
@@ -12835,7 +12611,7 @@ lookup_typedef_type(const typedef_decl& t, const corpus& corp)
 typedef_decl_sptr
 lookup_typedef_type(const string& qualified_name, const corpus& corp)
 {
-  interned_string s = corp.get_environment()->intern(qualified_name);
+  interned_string s = corp.get_environment().intern(qualified_name);
   return lookup_typedef_type(s, corp);
 }
 
@@ -12892,10 +12668,8 @@ lookup_typedef_type_per_location(const interned_string &loc, const corpus &corp)
 typedef_decl_sptr
 lookup_typedef_type_per_location(const string &loc, const corpus &corp)
 {
-  const environment* env = corp.get_environment();
-  ABG_ASSERT(env);
-
-  return lookup_typedef_type_per_location(env->intern(loc), corp);
+  const environment& env = corp.get_environment();
+  return lookup_typedef_type_per_location(env.intern(loc), corp);
 }
 
 /// Look into a corpus to find a class, union or typedef type which
@@ -13329,7 +13103,7 @@ maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
   else if (location l = type->get_location())
     {
       string str = l.expand();
-      s = type->get_environment()->intern(str);
+      s = type->get_environment().intern(str);
     }
 
   istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
@@ -13384,12 +13158,12 @@ maybe_update_types_lookup_map<class_decl>(const class_decl_sptr& class_type,
   if (use_type_name_as_key)
     {
       string qname = type->get_qualified_name();
-      s = type->get_environment()->intern(qname);
+      s = type->get_environment().intern(qname);
     }
   else if (location l = type->get_location())
     {
       string str = l.expand();
-      s = type->get_environment()->intern(str);
+      s = type->get_environment().intern(str);
     }
 
   bool result = false;
@@ -13988,7 +13762,6 @@ synthesize_type_from_translation_unit(const type_base_sptr& type,
 						p->get_size_in_bits(),
 						p->get_alignment_in_bits(),
 						p->get_location()));
-	      result->set_environment(pointed_to_type->get_environment());
 	    }
 	}
       else if (reference_type_def_sptr r = is_reference_type(type))
@@ -14002,7 +13775,6 @@ synthesize_type_from_translation_unit(const type_base_sptr& type,
 						  r->get_size_in_bits(),
 						  r->get_alignment_in_bits(),
 						  r->get_location()));
-	      result->set_environment(pointed_to_type->get_environment());
 	    }
 	}
       else if (function_type_sptr f = is_function_type(type))
@@ -14046,13 +13818,12 @@ synthesize_function_type_from_translation_unit(const function_type& fn_type,
 {
   function_type_sptr nil = function_type_sptr();
 
-  environment* env = tu.get_environment();
-  ABG_ASSERT(env);
+  const environment& env = tu.get_environment();
 
   type_base_sptr return_type = fn_type.get_return_type();
   type_base_sptr result_return_type;
-  if (!return_type || env->is_void_type(return_type))
-    result_return_type = env->get_void_type();
+  if (!return_type || env.is_void_type(return_type))
+    result_return_type = env.get_void_type();
   else
     result_return_type = synthesize_type_from_translation_unit(return_type, tu);
   if (!result_return_type)
@@ -14104,9 +13875,6 @@ synthesize_function_type_from_translation_unit(const function_type& fn_type,
 					   fn_type.get_alignment_in_bits()));
 
   tu.priv_->synthesized_types_.push_back(result_fn_type);
-  // The new synthesized type must be in the same environment as its
-  // translation unit.
-  result_fn_type->set_environment(tu.get_environment());
   tu.bind_function_type_life_time(result_fn_type);
 
   canonicalize(result_fn_type);
@@ -14149,17 +13917,14 @@ demangle_cplus_mangled_name(const string& mangled_name)
 ///
 /// @return either @p t if it is non-null, or the void type.
 type_base_sptr
-type_or_void(const type_base_sptr t, const environment* env)
+type_or_void(const type_base_sptr t, const environment& env)
 {
   type_base_sptr r;
 
   if (t)
     r = t;
   else
-    {
-      ABG_ASSERT(env);
-      r = type_base_sptr(env->get_void_type());
-    }
+    r = type_base_sptr(env.get_void_type());
 
   return r;
 }
@@ -14239,7 +14004,7 @@ types_defined_same_linux_kernel_corpus_public(const type_base& t1,
     {
       if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
 	{
-	  if (c1->get_environment()->decl_only_class_equals_definition())
+	  if (c1->get_environment().decl_only_class_equals_definition())
 	    // At least one of classes/union is declaration-only.
 	    // Because we are in a context in which a declaration-only
 	    // class/union is equal to all definitions of that
@@ -14316,13 +14081,13 @@ compare_types_during_canonicalization(const type_base_sptr& canonical_type,
 				      const type_base_sptr& candidate_type)
 {
 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
-  environment *env = canonical_type->get_environment();
-  if (env->debug_type_canonicalization_is_on())
+  const environment&env = canonical_type->get_environment();
+  if (env.debug_type_canonicalization_is_on())
     {
       bool canonical_equality = false, structural_equality = false;
-      env->priv_->use_canonical_type_comparison_ = false;
+      env.priv_->use_canonical_type_comparison_ = false;
       structural_equality = canonical_type == candidate_type;
-      env->priv_->use_canonical_type_comparison_ = true;
+      env.priv_->use_canonical_type_comparison_ = true;
       canonical_equality = canonical_type == candidate_type;
       if (canonical_equality != structural_equality)
 	{
@@ -14365,8 +14130,7 @@ type_base::get_canonical_type_for(type_base_sptr t)
   if (!t)
     return t;
 
-  environment* env = t->get_environment();
-  ABG_ASSERT(env);
+  environment& env = const_cast<environment&>(t->get_environment());
 
   if (is_non_canonicalized_type(t))
     // This type should not be canonicalized!
@@ -14377,7 +14141,7 @@ type_base::get_canonical_type_for(type_base_sptr t)
 
   // Look through decl-only types (classes, unions and enums)
   bool decl_only_class_equals_definition =
-    (odr_is_relevant(*t) || env->decl_only_class_equals_definition());
+    (odr_is_relevant(*t) || env.decl_only_class_equals_definition());
 
   class_or_union_sptr class_or_union = is_class_or_union_type(t);
 
@@ -14424,7 +14188,7 @@ type_base::get_canonical_type_for(type_base_sptr t)
   // type.
   type_base_sptr canonical_type_present_in_corpus;
   environment::canonical_types_map_type& types =
-    env->get_canonical_types_map();
+    env.get_canonical_types_map();
 
   type_base_sptr result;
   environment::canonical_types_map_type::iterator i = types.find(repr);
@@ -14465,20 +14229,20 @@ type_base::get_canonical_type_for(type_base_sptr t)
 	  // declaration-only struct S should be left alone and not
 	  // resolved to any of the two definitions of struct S.
 	  bool saved_decl_only_class_equals_definition =
-	    env->decl_only_class_equals_definition();
-	  env->do_on_the_fly_canonicalization(true);
+	    env.decl_only_class_equals_definition();
+	  env.do_on_the_fly_canonicalization(true);
 	  // Compare types by considering that decl-only classes don't
 	  // equal their definition.
-	  env->decl_only_class_equals_definition(false);
-	  env->priv_->allow_type_comparison_results_caching(true);
+	  env.decl_only_class_equals_definition(false);
+	  env.priv_->allow_type_comparison_results_caching(true);
 	  bool equal = (types_defined_same_linux_kernel_corpus_public(**it, *t)
 			|| compare_types_during_canonicalization(*it, t));
 	  // Restore the state of the on-the-fly-canonicalization and
 	  // the decl-only-class-being-equal-to-a-matching-definition
 	  // flags.
-	  env->priv_->allow_type_comparison_results_caching(false);
-	  env->do_on_the_fly_canonicalization(false);
-	  env->decl_only_class_equals_definition
+	  env.priv_->allow_type_comparison_results_caching(false);
+	  env.do_on_the_fly_canonicalization(false);
+	  env.decl_only_class_equals_definition
 	    (saved_decl_only_class_equals_definition);
 	  if (equal)
 	    {
@@ -14487,12 +14251,12 @@ type_base::get_canonical_type_for(type_base_sptr t)
 	    }
 	}
 #ifdef WITH_DEBUG_SELF_COMPARISON
-      if (env->self_comparison_debug_is_on())
+      if (env.self_comparison_debug_is_on())
 	{
 	  // So we are debugging the canonicalization process,
 	  // possibly via the use of 'abidw --debug-abidiff <binary>'.
 	  corpus_sptr corp1, corp2;
-	  env->get_self_comparison_debug_inputs(corp1, corp2);
+	  env.get_self_comparison_debug_inputs(corp1, corp2);
 	  if (corp1 && corp2 && t->get_corpus() == corp2.get())
 	    {
 	      // If 't' comes from the second corpus, then it *must*
@@ -14503,7 +14267,7 @@ type_base::get_canonical_type_for(type_base_sptr t)
 	      // have canonical types coming from the first corpus.
 	      if (result)
 		{
-		  if (!env->priv_->
+		  if (!env.priv_->
 		      check_canonical_type_from_abixml_during_self_comp(t,
 									result))
 		    // The canonical type of the type re-read from abixml
@@ -14521,7 +14285,7 @@ type_base::get_canonical_type_for(type_base_sptr t)
 	      else //!result
 		{
 		  uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
-		  string type_id = env->get_type_id_from_pointer(ptr_val);
+		  string type_id = env.get_type_id_from_pointer(ptr_val);
 		  if (type_id.empty())
 		    type_id = "type-id-<not-found>";
 		  // We are in the case where 't' is different from all
@@ -14743,7 +14507,7 @@ decl_base::set_definition_of_declaration(const decl_base_sptr& d)
 /// @param s the size of the type, in bits.
 ///
 /// @param a the alignment of the type, in bits.
-type_base::type_base(const environment* e, size_t s, size_t a)
+type_base::type_base(const environment& e, size_t s, size_t a)
   : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
     priv_(new priv(s, a))
 {}
@@ -14796,7 +14560,7 @@ type_base::get_cached_pretty_representation(bool internal) const
       if (!get_naked_canonical_type() || priv_->internal_cached_repr_.empty())
 	{
 	  string r = ir::get_pretty_representation(this, internal);
-	  priv_->internal_cached_repr_ = get_environment()->intern(r);
+	  priv_->internal_cached_repr_ = get_environment().intern(r);
 	}
       return priv_->internal_cached_repr_;
     }
@@ -14804,7 +14568,7 @@ type_base::get_cached_pretty_representation(bool internal) const
   if (!get_naked_canonical_type() || priv_->cached_repr_.empty())
     {
       string r = ir::get_pretty_representation(this, internal);
-      priv_->cached_repr_ = get_environment()->intern(r);
+      priv_->cached_repr_ = get_environment().intern(r);
     }
 
   return priv_->cached_repr_;
@@ -15291,7 +15055,7 @@ integral_type::operator string() const
 /// @param linkage_name the linkage_name of the current type declaration.
 ///
 /// @param vis the visibility of the type declaration.
-type_decl::type_decl(const environment* env,
+type_decl::type_decl(const environment& env,
 		     const string&	name,
 		     size_t		size_in_bits,
 		     size_t		alignment_in_bits,
@@ -15476,8 +15240,8 @@ type_decl::get_qualified_name(interned_string& qualified_name,
 const interned_string&
 type_decl::get_qualified_name(bool internal) const
 {
-  const environment* env = get_environment();
-  ABG_ASSERT(env);
+  const environment& env = get_environment();
+
 
   if (internal)
     if (is_integral_type(this))
@@ -15486,13 +15250,13 @@ type_decl::get_qualified_name(bool internal) const
 	  {
 	    if (decl_base::priv_->internal_qualified_name_.empty())
 	      decl_base::priv_->internal_qualified_name_ =
-		env->intern(get_internal_integral_type_name(this));
+		env.intern(get_internal_integral_type_name(this));
 	    return decl_base::priv_->internal_qualified_name_;
 	  }
 	else
 	  {
 	    decl_base::priv_->temporary_internal_qualified_name_ =
-	      env->intern(get_internal_integral_type_name(this));
+	      env.intern(get_internal_integral_type_name(this));
 	    return decl_base::priv_->temporary_internal_qualified_name_;
 	  }
       }
@@ -15569,7 +15333,7 @@ type_decl::~type_decl()
 /// @param locus the source location where the type is defined.
 ///
 /// @param vis the visibility of the type.
-scope_type_decl::scope_type_decl(const environment*	env,
+scope_type_decl::scope_type_decl(const environment&	env,
 				 const string&		name,
 				 size_t		size_in_bits,
 				 size_t		alignment_in_bits,
@@ -15706,7 +15470,7 @@ scope_type_decl::~scope_type_decl()
 /// @param locus the source location where the namespace is defined.
 ///
 /// @param vis the visibility of the namespace.
-namespace_decl::namespace_decl(const environment*	env,
+namespace_decl::namespace_decl(const environment&	env,
 			       const string&		name,
 			       const location&		locus,
 			       visibility		vis)
@@ -15883,7 +15647,7 @@ qualified_type_def::build_name(bool fully_qualified, bool internal) const
     // especially during the construction of the type, while the
     // underlying type is not yet constructed.  In that case, let's do
     // like if the underlying type is the 'void' type.
-    t = get_environment()->get_void_type();
+    t = get_environment().get_void_type();
 
   return get_name_of_qualified_type(t, get_cv_quals(),
 				    fully_qualified,
@@ -15922,7 +15686,7 @@ qualified_type_def::qualified_type_def(type_base_sptr		type,
     priv_(new priv(quals, type))
 {
   runtime_type_instance(this);
-  interned_string name = type->get_environment()->intern(build_name(false));
+  interned_string name = type->get_environment().intern(build_name(false));
   set_name(name);
 }
 
@@ -15933,7 +15697,7 @@ qualified_type_def::qualified_type_def(type_base_sptr		type,
 /// @param quals a bitfield representing the const/volatile qualifiers
 ///
 /// @param locus the location of the qualified type definition
-qualified_type_def::qualified_type_def(environment* env,
+qualified_type_def::qualified_type_def(const environment& env,
 				       CV quals,
 				       const location& locus)
   : type_or_decl_base(env,
@@ -15948,7 +15712,7 @@ qualified_type_def::qualified_type_def(environment* env,
   runtime_type_instance(this);
   // We don't yet have an underlying type.  So for naming purpose,
   // let's temporarily pretend the underlying type is 'void'.
-  interned_string name = env->intern("void");
+  interned_string name = env.intern("void");
   set_name(name);
 }
 
@@ -16109,8 +15873,8 @@ qualified_type_def::get_qualified_name(interned_string& qualified_name,
 const interned_string&
 qualified_type_def::get_qualified_name(bool internal) const
 {
-  const environment* env = get_environment();
-  ABG_ASSERT(env);
+  const environment& env = get_environment();
+
 
   if (!get_canonical_type())
     {
@@ -16124,14 +15888,14 @@ qualified_type_def::get_qualified_name(bool internal) const
 	  // Lets compute it and return a reference to where it's
 	  // stored.
 	  priv_->temporary_internal_name_ =
-	      env->intern(build_name(true, /*internal=*/true));
+	      env.intern(build_name(true, /*internal=*/true));
 	  return priv_->temporary_internal_name_;
 	}
       else
 	{
 	  // We are asked to return a temporary non-internal name.
 	    set_temporary_qualified_name
-	      (env->intern(build_name(true, /*internal=*/false)));
+	      (env.intern(build_name(true, /*internal=*/false)));
 	  return peek_temporary_qualified_name();
 	}
     }
@@ -16143,7 +15907,7 @@ qualified_type_def::get_qualified_name(bool internal) const
 	{
 	  if (priv_->internal_name_.empty())
 	    priv_->internal_name_ =
-	      env->intern(build_name(/*qualified=*/true,
+	      env.intern(build_name(/*qualified=*/true,
 				     /*internal=*/true));
 	  return priv_->internal_name_;
 	}
@@ -16151,7 +15915,7 @@ qualified_type_def::get_qualified_name(bool internal) const
 	{
 	  if (peek_qualified_name().empty())
 	    set_qualified_name
-	      (env->intern(build_name(/*qualified=*/true,
+	      (env.intern(build_name(/*qualified=*/true,
 				      /*internal=*/false)));
 	  return peek_qualified_name();
 	}
@@ -16225,7 +15989,7 @@ qualified_type_def::set_underlying_type(const type_base_sptr& t)
   // Now we need to update other properties that depend on the new underlying type.
   set_size_in_bits(t->get_size_in_bits());
   set_alignment_in_bits(t->get_alignment_in_bits());
-  interned_string name = get_environment()->intern(build_name(false));
+  interned_string name = get_environment().intern(build_name(false));
   set_name(name);
   if (scope_decl* s = get_scope())
       {
@@ -16350,7 +16114,7 @@ struct pointer_type_def::priv
   interned_string temp_internal_qualified_name_;
 
   priv(const type_base_sptr& t)
-    : pointed_to_type_(type_or_void(t, 0)),
+    : pointed_to_type_(type_or_void(t, t->get_environment())),
       naked_pointed_to_type_(t.get())
   {}
 
@@ -16396,10 +16160,10 @@ pointer_type_def::pointer_type_def(const type_base_sptr&	pointed_to,
   try
     {
       ABG_ASSERT(pointed_to);
-      const environment* env = pointed_to->get_environment();
+      const environment& env = pointed_to->get_environment();
       decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
       string name = (pto ? pto->get_name() : string("void")) + "*";
-      set_name(env->intern(name));
+      set_name(env.intern(name));
       if (pto)
 	set_visibility(pto->get_visibility());
     }
@@ -16416,7 +16180,7 @@ pointer_type_def::pointer_type_def(const type_base_sptr&	pointed_to,
 /// @param align_in_bits the alignment of the type, in bits.
 ///
 /// @param locus the source location where the type was defined.
-pointer_type_def::pointer_type_def(environment* env, size_t size_in_bits,
+pointer_type_def::pointer_type_def(const environment& env, size_t size_in_bits,
 				   size_t alignment_in_bits,
 				   const location& locus)
   : type_or_decl_base(env,
@@ -16429,7 +16193,7 @@ pointer_type_def::pointer_type_def(environment* env, size_t size_in_bits,
 {
   runtime_type_instance(this);
   string name = string("void") + "*";
-  set_name(env->intern(name));
+  set_name(env.intern(name));
 }
 
 /// Set the pointed-to type of the pointer.
@@ -16444,11 +16208,10 @@ pointer_type_def::set_pointed_to_type(const type_base_sptr& t)
 
   try
     {
-      const environment* env = t->get_environment();
-      ABG_ASSERT(get_environment() == env);
+      const environment& env = t->get_environment();
       decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
       string name = (pto ? pto->get_name() : string("void")) + "*";
-      set_name(env->intern(name));
+      set_name(env.intern(name));
       if (pto)
 	set_visibility(pto->get_visibility());
     }
@@ -16763,11 +16526,12 @@ reference_type_def::reference_type_def(const type_base_sptr	pointed_to,
 
       if (!is_lvalue())
 	name += "&";
-      environment* env = pointed_to->get_environment();
-      ABG_ASSERT(env);
-      set_name(env->intern(name));
+      const environment& env = pointed_to->get_environment();
+      set_name(env.intern(name));
 
-      pointed_to_type_ = type_base_wptr(type_or_void(pointed_to, 0));
+      pointed_to_type_ =
+	type_base_wptr(type_or_void(pointed_to,
+				    pointed_to->get_environment()));
     }
   catch (...)
     {}
@@ -16790,7 +16554,7 @@ reference_type_def::reference_type_def(const type_base_sptr	pointed_to,
 /// @param align_in_bits the alignment of the type, in bits.
 ///
 /// @param locus the source location of the type.
-reference_type_def::reference_type_def(const environment* env, bool lvalue,
+reference_type_def::reference_type_def(const environment& env, bool lvalue,
 				       size_t size_in_bits,
 				       size_t alignment_in_bits,
 				       const location& locus)
@@ -16806,9 +16570,9 @@ reference_type_def::reference_type_def(const environment* env, bool lvalue,
   string name = "void&";
   if (!is_lvalue())
     name += "&";
-  ABG_ASSERT(env);
-  set_name(env->intern(name));
-  pointed_to_type_ = type_base_wptr(env->get_void_type());
+
+  set_name(env.intern(name));
+  pointed_to_type_ = type_base_wptr(env.get_void_type());
 }
 
 /// Setter of the pointed_to type of the current reference type.
@@ -16832,9 +16596,8 @@ reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
       string name = string(pto->get_name()) + "&";
       if (!is_lvalue())
 	name += "&";
-      environment* env = pto->get_environment();
-      ABG_ASSERT(env && env == get_environment());
-      set_name(env->intern(name));
+      const environment& env = pto->get_environment();
+      set_name(env.intern(name));
     }
 }
 
@@ -17210,7 +16973,7 @@ struct array_type_def::subrange_type::priv
 /// @param underlying_type the underlying type of the subrange type.
 ///
 /// @param loc the source location where the type is defined.
-array_type_def::subrange_type::subrange_type(const environment* env,
+array_type_def::subrange_type::subrange_type(const environment& env,
 					     const string&	name,
 					     bound_value	lower_bound,
 					     bound_value	upper_bound,
@@ -17242,7 +17005,7 @@ array_type_def::subrange_type::subrange_type(const environment* env,
 /// @param loc the source location where the type is defined.
 ///
 /// @param l the language that generated this subrange.
-array_type_def::subrange_type::subrange_type(const environment* env,
+array_type_def::subrange_type::subrange_type(const environment& env,
 					     const string&	name,
 					     bound_value	lower_bound,
 					     bound_value	upper_bound,
@@ -17270,7 +17033,7 @@ array_type_def::subrange_type::subrange_type(const environment* env,
 /// @param loc the source location of the type.
 ///
 /// @param the language that generated this type.
-array_type_def::subrange_type::subrange_type(const environment* env,
+array_type_def::subrange_type::subrange_type(const environment& env,
 					     const string&	name,
 					     bound_value	upper_bound,
 					     const location&	loc,
@@ -17625,7 +17388,7 @@ array_type_def::array_type_def(const type_base_sptr			e_type,
 /// @param subs a vector of the array's subranges(dimensions)
 ///
 /// @param locus the source location of the array type definition.
-array_type_def::array_type_def(environment*				env,
+array_type_def::array_type_def(const environment&				env,
 			       const std::vector<subrange_sptr>&	subs,
 			       const location&				locus)
   : type_or_decl_base(env,
@@ -17655,9 +17418,6 @@ array_type_def::update_size()
 	{
 	  for (const auto &sub : get_subranges())
 	    s *= sub->get_length();
-
-	  const environment* env = e->get_environment();
-	  ABG_ASSERT(env);
 	  set_size_in_bits(s);
 	}
       set_alignment_in_bits(e->get_alignment_in_bits());
@@ -17900,7 +17660,7 @@ array_type_def::set_element_type(const type_base_sptr& element_type)
 {
   priv_->element_type_ = element_type;
   update_size();
-  set_name(get_environment()->intern(get_pretty_representation()));
+  set_name(get_environment().intern(get_pretty_representation()));
 }
 
 /// Append subranges from the vector @param subs to the current
@@ -17913,7 +17673,7 @@ array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
     priv_->subranges_.push_back(sub);
 
   update_size();
-  set_name(get_environment()->intern(get_pretty_representation()));
+  set_name(get_environment().intern(get_pretty_representation()));
 }
 
 /// @return true if one of the sub-ranges of the array is infinite, or
@@ -17964,8 +17724,8 @@ array_type_def::get_qualified_name(interned_string& qn, bool internal) const
 const interned_string&
 array_type_def::get_qualified_name(bool internal) const
 {
-  const environment* env = get_environment();
-  ABG_ASSERT(env);
+  const environment& env = get_environment();
+
 
   if (internal)
     {
@@ -17973,13 +17733,13 @@ array_type_def::get_qualified_name(bool internal) const
 	{
 	  if (priv_->internal_qualified_name_.empty())
 	    priv_->internal_qualified_name_ =
-	      env->intern(get_type_representation(*this, /*internal=*/true));
+	      env.intern(get_type_representation(*this, /*internal=*/true));
 	  return priv_->internal_qualified_name_;
 	}
       else
 	{
 	  priv_->temp_internal_qualified_name_ =
-	    env->intern(get_type_representation(*this, /*internal=*/true));
+	    env.intern(get_type_representation(*this, /*internal=*/true));
 	  return priv_->temp_internal_qualified_name_;
 	}
     }
@@ -17988,13 +17748,13 @@ array_type_def::get_qualified_name(bool internal) const
       if (get_canonical_type())
 	{
 	  if (decl_base::peek_qualified_name().empty())
-	    set_qualified_name(env->intern(get_type_representation
+	    set_qualified_name(env.intern(get_type_representation
 					   (*this, /*internal=*/false)));
 	  return decl_base::peek_qualified_name();
 	}
       else
 	{
-	  set_temporary_qualified_name(env->intern(get_type_representation
+	  set_temporary_qualified_name(env.intern(get_type_representation
 						   (*this,
 						    /*internal=*/false)));
 	  return decl_base::peek_temporary_qualified_name();
@@ -18229,8 +17989,8 @@ enum_has_non_name_change(const enum_type_decl& l,
     }
 
   enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
-  interned_string qn_r = l.get_environment()->intern(r.get_qualified_name());
-  interned_string qn_l = l.get_environment()->intern(l.get_qualified_name());
+  interned_string qn_r = l.get_environment().intern(r.get_qualified_name());
+  interned_string qn_l = l.get_environment().intern(l.get_qualified_name());
   string n_l = l.get_name();
   string n_r = r.get_name();
   local_r.set_qualified_name(qn_l);
@@ -18576,10 +18336,9 @@ operator!=(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r)
 /// enum_type_decl::enumerator.
 class enum_type_decl::enumerator::priv
 {
-  const environment*	env_;
-  interned_string	name_;
+  string		name_;
   int64_t		value_;
-  interned_string	qualified_name_;
+  string		qualified_name_;
   enum_type_decl*	enum_type_;
 
   friend class	enum_type_decl::enumerator;
@@ -18587,16 +18346,13 @@ class enum_type_decl::enumerator::priv
 public:
 
   priv()
-    : env_(),
-      enum_type_()
+    : enum_type_()
   {}
 
-  priv(const environment* env,
-       const string& name,
+  priv(const string& name,
        int64_t value,
        enum_type_decl* e = 0)
-    : env_(env),
-      name_(env ? env->intern(name) : interned_string()),
+    : name_(name),
       value_(value),
       enum_type_(e)
   {}
@@ -18609,7 +18365,6 @@ enum_type_decl::enumerator::enumerator()
 
 enum_type_decl::enumerator::~enumerator() = default;
 
-
 /// Constructor of the @ref enum_type_decl::enumerator type.
 ///
 /// @param env the environment we are operating from.
@@ -18617,18 +18372,16 @@ enum_type_decl::enumerator::~enumerator() = default;
 /// @param name the name of the enumerator.
 ///
 /// @param value the value of the enumerator.
-enum_type_decl::enumerator::enumerator(const environment* env,
-				       const string& name,
+enum_type_decl::enumerator::enumerator(const string& name,
 				       int64_t value)
-  : priv_(new priv(env, name, value))
+  : priv_(new priv(name, value))
 {}
 
 /// Copy constructor of the @ref enum_type_decl::enumerator type.
 ///
 /// @param other enumerator to copy.
 enum_type_decl::enumerator::enumerator(const enumerator& other)
-  : priv_(new priv(other.get_environment(),
-		   other.get_name(),
+  : priv_(new priv(other.get_name(),
 		   other.get_value(),
 		   other.get_enum_type()))
 {}
@@ -18639,12 +18392,12 @@ enum_type_decl::enumerator::enumerator(const enumerator& other)
 enum_type_decl::enumerator&
 enum_type_decl::enumerator::operator=(const enumerator& o)
 {
-  priv_->env_ = o.get_environment();
   priv_->name_ = o.get_name();
   priv_->value_ = o.get_value();
   priv_->enum_type_ = o.get_enum_type();
   return *this;
 }
+
 /// Equality operator
 ///
 /// @param other the enumerator to compare to the current
@@ -18669,19 +18422,12 @@ bool
 enum_type_decl::enumerator::operator!=(const enumerator& other) const
 {return !operator==(other);}
 
-/// Getter of the environment of this enumerator.
-///
-/// @return the environment of this enumerator.
-const environment*
-enum_type_decl::enumerator::get_environment() const
-{return priv_->env_;}
-
 /// Getter for the name of the current instance of
 /// enum_type_decl::enumerator.
 ///
 /// @return a reference to the name of the current instance of
 /// enum_type_decl::enumerator.
-const interned_string&
+const string&
 enum_type_decl::enumerator::get_name() const
 {return priv_->name_;}
 
@@ -18698,17 +18444,15 @@ enum_type_decl::enumerator::get_name() const
 ///
 /// @return the qualified name of the current instance of
 /// enum_type_decl::enumerator.
-const interned_string&
+const string&
 enum_type_decl::enumerator::get_qualified_name(bool internal) const
 {
   if (priv_->qualified_name_.empty())
     {
-      const environment* env = priv_->enum_type_->get_environment();
-      ABG_ASSERT(env);
       priv_->qualified_name_ =
-	env->intern(get_enum_type()->get_qualified_name(internal)
-		    + "::"
-		    + get_name());
+	get_enum_type()->get_qualified_name(internal)
+	+ "::"
+	+ get_name();
     }
   return priv_->qualified_name_;
 }
@@ -18718,11 +18462,7 @@ enum_type_decl::enumerator::get_qualified_name(bool internal) const
 /// @param n the new name.
 void
 enum_type_decl::enumerator::set_name(const string& n)
-{
-  const environment* env = get_environment();
-  ABG_ASSERT(env);
-  priv_->name_ = env->intern(n);
-}
+{priv_->name_ = n;}
 
 /// Getter for the value of @ref enum_type_decl::enumerator.
 ///
@@ -18810,7 +18550,7 @@ typedef_decl::typedef_decl(const string&		name,
 ///
 /// @param vis the visibility of the typedef type.
 typedef_decl::typedef_decl(const string& name,
-			   environment* env,
+			   const environment& env,
 			   const location& locus,
 			   const string& mangled_name,
 			   visibility vis)
@@ -19117,7 +18857,7 @@ var_decl::set_symbol(const elf_symbol_sptr& sym)
   priv_->symbol_ = sym;
   // The variable id cache that depends on the symbol must be
   // invalidated because the symbol changed.
-  priv_->id_ = get_environment()->intern("");
+  priv_->id_ = get_environment().intern("");
 }
 
 /// Gets the the underlying ELF symbol for the current variable,
@@ -19241,10 +18981,10 @@ equals(const var_decl& l, const var_decl& r, change_kind* k)
       // The variables have underlying elf symbols that are equal, so
       // now, let's compare the decl_base part of the variables w/o
       // considering their decl names.
-      const environment* env = l.get_environment();
+      const environment& env = l.get_environment();
       const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
-      const_cast<var_decl&>(l).set_qualified_name(env->intern(""));
-      const_cast<var_decl&>(r).set_qualified_name(env->intern(""));
+      const_cast<var_decl&>(l).set_qualified_name(env.intern(""));
+      const_cast<var_decl&>(r).set_qualified_name(env.intern(""));
       bool decl_bases_different = !l.decl_base::operator==(r);
       const_cast<var_decl&>(l).set_qualified_name(n1);
       const_cast<var_decl&>(r).set_qualified_name(n2);
@@ -19321,11 +19061,11 @@ var_decl::get_id() const
 	sym_str = s->get_id_string();
       else if (!get_linkage_name().empty())
 	sym_str = get_linkage_name();
-      const environment* env = get_type()->get_environment();
-      ABG_ASSERT(env);
-      priv_->id_ = env->intern(repr);
+
+      const environment& env = get_type()->get_environment();
+      priv_->id_ = env.intern(repr);
       if (!sym_str.empty())
-	priv_->id_ = env->intern(priv_->id_ + "{" + sym_str + "}");
+	priv_->id_ = env.intern(priv_->id_ + "{" + sym_str + "}");
     }
   return priv_->id_;
 }
@@ -19374,7 +19114,7 @@ var_decl::get_qualified_name(bool internal) const
     {
       // Display the anonymous data member in a way that makes sense.
       string r = get_pretty_representation(internal);
-      set_qualified_name(get_environment()->intern(r));
+      set_qualified_name(get_environment().intern(r));
     }
 
   return decl_base::get_qualified_name(internal);
@@ -19614,7 +19354,7 @@ function_type::function_type(type_base_sptr return_type,
 /// @param size_in_bits the size of this type, in bits.
 ///
 /// @param alignment_in_bits the alignment of this type, in bits.
-function_type::function_type(const environment* env,
+function_type::function_type(const environment& env,
 			     size_t		size_in_bits,
 			     size_t		alignment_in_bits)
   : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
@@ -19772,7 +19512,7 @@ equals(const function_type& l,
     // comparison has been cached, let's just re-use it, rather than
     // comparing them all over again.
     bool cached_result = false;
-    if (l.get_environment()->priv_->is_type_comparison_cached(l, r,
+    if (l.get_environment().priv_->is_type_comparison_cached(l, r,
 							      cached_result))
       return cached_result;
   }
@@ -19914,7 +19654,7 @@ equals(const function_type& l,
   // perform this caching also on the earlier return points of this
   // function.  That would basically mean to redefine the RETURN macro
   // to make it perform this caching for us.
-  l.get_environment()->priv_->cache_type_comparison_result(l, r, result);
+  l.get_environment().priv_->cache_type_comparison_result(l, r, result);
 
   RETURN(result);
 #undef RETURN
@@ -20186,7 +19926,7 @@ method_type::method_type(type_base_sptr return_type,
 /// @param size_in_bits the size of the type, expressed in bits.
 ///
 /// @param alignment_in_bits the alignment of the type, expressed in bits
-method_type::method_type(const environment*	env,
+method_type::method_type(const environment&	env,
 			 size_t		size_in_bits,
 			 size_t		alignment_in_bits)
   : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
@@ -20493,7 +20233,7 @@ function_decl::get_pretty_representation_of_declarator (bool internal) const
       if (parm.get() != first_parm.get())
 	result += ", ";
       if (parm->get_variadic_marker()
-	  || get_environment()->is_variadic_parameter_type(parm->get_type()))
+	  || get_environment().is_variadic_parameter_type(parm->get_type()))
 	result += "...";
       else
 	{
@@ -20581,7 +20321,7 @@ function_decl::set_symbol(const elf_symbol_sptr& sym)
   priv_->symbol_ = sym;
   // The function id cache that depends on the symbol must be
   // invalidated because the symbol changed.
-  priv_->id_ = get_environment()->intern("");
+  priv_->id_ = get_environment().intern("");
 }
 
 /// Gets the the underlying ELF symbol for the current variable,
@@ -20880,22 +20620,22 @@ function_decl::get_id() const
 {
   if (priv_->id_.empty())
     {
-      const environment* env = get_type()->get_environment();
+      const environment& env = get_type()->get_environment();
       if (elf_symbol_sptr s = get_symbol())
 	{
 	  if (s->has_aliases())
 	    // The symbol has several aliases, so let's use a scheme
 	    // that allows all aliased functions to have different
 	    // IDs.
-	    priv_->id_ = env->intern(get_name() + "/" + s->get_id_string());
+	    priv_->id_ = env.intern(get_name() + "/" + s->get_id_string());
 	  else
 	    // Let's use the full symbol name with its version as ID.
-	    priv_->id_ = env->intern(s->get_id_string());
+	    priv_->id_ = env.intern(s->get_id_string());
 	}
       else if (!get_linkage_name().empty())
-	priv_->id_= env->intern(get_linkage_name());
+	priv_->id_= env.intern(get_linkage_name());
       else
-	priv_->id_ = env->intern(get_pretty_representation());
+	priv_->id_ = env.intern(get_pretty_representation());
     }
   return priv_->id_;
 }
@@ -21069,19 +20809,18 @@ function_decl::parameter::get_type()const
 interned_string
 function_decl::parameter::get_type_name() const
 {
-  const environment* env = get_environment();
-  ABG_ASSERT(env);
+  const environment& env = get_environment();
 
   type_base_sptr t = get_type();
   string str;
-  if (get_variadic_marker() || env->is_variadic_parameter_type(t))
+  if (get_variadic_marker() || env.is_variadic_parameter_type(t))
     str = "...";
   else
     {
 	ABG_ASSERT(t);
 	str = abigail::ir::get_type_name(t);
     }
-  return env->intern(str);
+  return env.intern(str);
 }
 
 /// @return a copy of the pretty representation of the type of the
@@ -21092,7 +20831,7 @@ function_decl::parameter::get_type_pretty_representation() const
   type_base_sptr t = get_type();
   string str;
   if (get_variadic_marker()
-      || get_environment()->is_variadic_parameter_type(t))
+      || get_environment().is_variadic_parameter_type(t))
     str = "...";
   else
     {
@@ -21108,13 +20847,13 @@ function_decl::parameter::get_type_pretty_representation() const
 interned_string
 function_decl::parameter::get_name_id() const
 {
-  const environment* env = get_environment();
-  ABG_ASSERT(env);
+  const environment& env = get_environment();
+
 
   std::ostringstream o;
   o << "parameter-" << get_index();
 
-  return env->intern(o.str());
+  return env.intern(o.str());
 }
 
 unsigned
@@ -21302,14 +21041,13 @@ string
 function_decl::parameter::get_pretty_representation(bool internal,
 						    bool /*qualified_name*/) const
 {
-  const environment* env = get_environment();
-  ABG_ASSERT(env);
+  const environment& env = get_environment();
 
   string type_repr;
   type_base_sptr t = get_type();
   if (!t)
     type_repr = "void";
-  else if (env->is_variadic_parameter_type(t))
+  else if (env.is_variadic_parameter_type(t))
     type_repr = "...";
   else
     type_repr = ir::get_pretty_representation(t, internal);
@@ -21351,7 +21089,7 @@ function_decl::parameter::get_pretty_representation(bool internal,
 ///
 /// @param member_fns the vector of member functions of this instance
 /// of @ref class_or_union.
-class_or_union::class_or_union(const environment* env, const string& name,
+class_or_union::class_or_union(const environment& env, const string& name,
 			       size_t size_in_bits, size_t align_in_bits,
 			       const location& locus, visibility vis,
 			       member_types& mem_types,
@@ -21401,7 +21139,7 @@ class_or_union::class_or_union(const environment* env, const string& name,
 /// @param locus the source location of declaration point this class.
 ///
 /// @param vis the visibility of instances of @ref class_or_union.
-class_or_union::class_or_union(const environment* env, const string& name,
+class_or_union::class_or_union(const environment& env, const string& name,
 			       size_t size_in_bits, size_t align_in_bits,
 			       const location& locus, visibility vis)
   : type_or_decl_base(env,
@@ -21423,7 +21161,7 @@ class_or_union::class_or_union(const environment* env, const string& name,
 ///
 /// @param is_declaration_only a boolean saying whether the instance
 /// represents a declaration only, or not.
-class_or_union::class_or_union(const environment* env, const string& name,
+class_or_union::class_or_union(const environment& env, const string& name,
 			       bool is_declaration_only)
   : type_or_decl_base(env,
 		      ABSTRACT_TYPE_BASE
@@ -22127,7 +21865,7 @@ class_or_union::operator==(const class_or_union& other) const
 /// classes of interest are being compared.
 void
 dump_classes_being_compared(const type_or_decl_base& c)
-{c.get_environment()->priv_->dump_classes_being_compared();}
+{c.get_environment().priv_->dump_classes_being_compared();}
 
 /// Dumps a textual representation (to the standard error output) of
 /// the content of the set of function types being currently compared
@@ -22139,7 +21877,7 @@ dump_classes_being_compared(const type_or_decl_base& c)
 /// function types of interest are being compared.
 void
 dump_fn_types_being_compared(const type_or_decl_base& t)
-{t.get_environment()->priv_->dump_fn_types_being_compared();}
+{t.get_environment().priv_->dump_fn_types_being_compared();}
 
 /// Compares two instances of @ref class_or_union.
 ///
@@ -22193,7 +21931,7 @@ equals(const class_or_union& l, const class_or_union& r, change_kind* k)
 	    // change.
 	    return true;
 
-	  if ((l.get_environment()->decl_only_class_equals_definition()
+	  if ((l.get_environment().decl_only_class_equals_definition()
 	       || ((odr_is_relevant(l) && !def1)
 		   || (odr_is_relevant(r) && !def2)))
 	      && !is_anonymous_or_typedef_named(l)
@@ -22414,7 +22152,6 @@ copy_member_function(const class_or_union_sptr& t, const method_decl* method)
 					    old_type->get_is_const(),
 					    old_type->get_size_in_bits(),
 					    old_type->get_alignment_in_bits()));
-  new_type->set_environment(t->get_environment());
   keep_type_alive(new_type);
 
   method_decl_sptr
@@ -22553,18 +22290,17 @@ static bool
 maybe_propagate_canonical_type(const type_base& lhs_type,
 			       const type_base& rhs_type)
 {
+  const environment& env = lhs_type.get_environment();
 #if WITH_DEBUG_TYPE_CANONICALIZATION
-  if (const environment *env = lhs_type.get_environment())
-    if (!env->priv_->use_canonical_type_comparison_)
-      return false;
+  if (!env.priv_->use_canonical_type_comparison_)
+    return false;
 #endif
 
-  if (const environment *env = lhs_type.get_environment())
-    if (env->do_on_the_fly_canonicalization())
-      if (type_base_sptr canonical_type = lhs_type.get_canonical_type())
-	if (!rhs_type.get_canonical_type())
-	  if (env->priv_->propagate_ct(lhs_type, rhs_type))
-	    return true;
+  if (env.do_on_the_fly_canonicalization())
+    if (type_base_sptr canonical_type = lhs_type.get_canonical_type())
+      if (!rhs_type.get_canonical_type())
+	if (env.priv_->propagate_ct(lhs_type, rhs_type))
+	  return true;
   return false;
 }
 
@@ -22623,7 +22359,7 @@ struct class_decl::priv
 ///
 /// @param mbr_fns the vector of member functions of this instance of
 /// class_decl.
-class_decl::class_decl(const environment* env, const string& name,
+class_decl::class_decl(const environment& env, const string& name,
 		       size_t size_in_bits, size_t align_in_bits,
 		       bool is_struct, const location& locus,
 		       visibility vis, base_specs& bases,
@@ -22674,7 +22410,7 @@ class_decl::class_decl(const environment* env, const string& name,
 ///
 /// @param is_anonymous whether the newly created instance is
 /// anonymous.
-class_decl::class_decl(const environment* env, const string& name,
+class_decl::class_decl(const environment& env, const string& name,
 		       size_t size_in_bits, size_t align_in_bits,
 		       bool is_struct, const location& locus,
 		       visibility vis, base_specs& bases,
@@ -22720,7 +22456,7 @@ class_decl::class_decl(const environment* env, const string& name,
 /// @param locus the source location of declaration point this class.
 ///
 /// @param vis the visibility of instances of class_decl.
-class_decl::class_decl(const environment* env, const string& name,
+class_decl::class_decl(const environment& env, const string& name,
 		       size_t size_in_bits, size_t align_in_bits,
 		       bool is_struct, const location& locus,
 		       visibility vis)
@@ -22757,7 +22493,7 @@ class_decl::class_decl(const environment* env, const string& name,
 ///
 /// @param is_anonymous whether the newly created instance is
 /// anonymous.
-class_decl:: class_decl(const environment* env, const string& name,
+class_decl:: class_decl(const environment& env, const string& name,
 			size_t size_in_bits, size_t align_in_bits,
 			bool is_struct, const location& locus,
 			visibility vis, bool is_anonymous)
@@ -22795,7 +22531,7 @@ class_decl:: class_decl(const environment* env, const string& name,
 ///
 /// @param is_declaration_only a boolean saying whether the instance
 /// represents a declaration only, or not.
-class_decl::class_decl(const environment* env, const string& name,
+class_decl::class_decl(const environment& env, const string& name,
 		       bool is_struct, bool is_declaration_only)
   : type_or_decl_base(env,
 		      CLASS_TYPE
@@ -22848,12 +22584,8 @@ class_decl::is_struct() const
 void
 class_decl::add_base_specifier(base_spec_sptr b)
 {
-  ABG_ASSERT(get_environment());
-  ABG_ASSERT(b->get_environment() == get_environment());
   priv_->bases_.push_back(b);
   priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
-  if (const environment* env = get_environment())
-    b->set_environment(env);
 }
 
 /// Get the base specifiers for this class.
@@ -23755,12 +23487,12 @@ method_matches_at_least_one_in_vector(const method_decl_sptr& method,
 static bool
 maybe_cancel_propagated_canonical_type(const class_or_union& t)
 {
-  const environment* env = t.get_environment();
-  if (env && env->do_on_the_fly_canonicalization())
+  const environment& env = t.get_environment();
+  if (env.do_on_the_fly_canonicalization())
     if (is_type(&t)->priv_->canonical_type_propagated())
       {
 	is_type(&t)->priv_->clear_propagated_canonical_type();
-	env->priv_->remove_from_types_with_non_confirmed_propagated_ct(&t);
+	env.priv_->remove_from_types_with_non_confirmed_propagated_ct(&t);
 	return true;
       }
   return false;
@@ -23794,7 +23526,7 @@ equals(const class_decl& l, const class_decl& r, change_kind* k)
     // cached, let's just re-use it, rather than comparing them all
     // over again.
     bool result = false;
-    if (l.get_environment()->priv_->is_type_comparison_cached(l, r, result))
+    if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
       return result;
   }
 
@@ -23950,7 +23682,7 @@ equals(const class_decl& l, const class_decl& r, change_kind* k)
   // perform this caching also on the earlier return points of this
   // function.  That would basically mean to redefine the RETURN macro
   // to make it perform this caching for us.
-  l.get_environment()->priv_->cache_type_comparison_result(l, r, result);
+  l.get_environment().priv_->cache_type_comparison_result(l, r, result);
 
   RETURN(result);
 #undef RETURN
@@ -24591,7 +24323,7 @@ set_member_is_static(const decl_base_sptr& d, bool s)
 /// @param data_mbrs the data members of the union.
 ///
 /// @param member_fns the member functions of the union.
-union_decl::union_decl(const environment* env, const string& name,
+union_decl::union_decl(const environment& env, const string& name,
 		       size_t size_in_bits, const location& locus,
 		       visibility vis, member_types& mbr_types,
 		       data_members& data_mbrs, member_functions& member_fns)
@@ -24627,7 +24359,7 @@ union_decl::union_decl(const environment* env, const string& name,
 ///
 /// @param is_anonymous whether the newly created instance is
 /// anonymous.
-union_decl::union_decl(const environment* env, const string& name,
+union_decl::union_decl(const environment& env, const string& name,
 		       size_t size_in_bits, const location& locus,
 		       visibility vis, member_types& mbr_types,
 		       data_members& data_mbrs, member_functions& member_fns,
@@ -24665,7 +24397,7 @@ union_decl::union_decl(const environment* env, const string& name,
 /// @param locus the location of the type.
 ///
 /// @param vis the visibility of instances of @ref union_decl.
-union_decl::union_decl(const environment* env, const string& name,
+union_decl::union_decl(const environment& env, const string& name,
 		       size_t size_in_bits, const location& locus,
 		       visibility vis)
   : type_or_decl_base(env,
@@ -24696,7 +24428,7 @@ union_decl::union_decl(const environment* env, const string& name,
 ///
 /// @param is_anonymous whether the newly created instance is
 /// anonymous.
-union_decl::union_decl(const environment* env, const string& name,
+union_decl::union_decl(const environment& env, const string& name,
 		       size_t size_in_bits, const location& locus,
 		       visibility vis, bool is_anonymous)
   : type_or_decl_base(env,
@@ -24731,7 +24463,7 @@ union_decl::union_decl(const environment* env, const string& name,
 ///
 /// @param is_declaration_only a boolean saying whether the instance
 /// represents a declaration only, or not.
-union_decl::union_decl(const environment* env,
+union_decl::union_decl(const environment& env,
 		       const string& name,
 		       bool is_declaration_only)
   : type_or_decl_base(env,
@@ -24948,7 +24680,7 @@ equals(const union_decl& l, const union_decl& r, change_kind* k)
     // cached, let's just re-use it, rather than comparing them all
     // over again.
     bool result = false;
-    if (l.get_environment()->priv_->is_type_comparison_cached(l, r, result))
+    if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
       return result;
   }
 
@@ -24970,7 +24702,7 @@ equals(const union_decl& l, const union_decl& r, change_kind* k)
   // perform this caching also on the earlier return points of this
   // function.  That would basically mean to redefine the RETURN macro
   // to make it perform this caching for us.
-  l.get_environment()->priv_->cache_type_comparison_result(l, r, result);
+  l.get_environment().priv_->cache_type_comparison_result(l, r, result);
 
   RETURN(result);
 }
@@ -25076,7 +24808,7 @@ template_decl::get_template_parameters() const
 /// defined.
 ///
 /// @param vis the visibility of the template declaration.
-template_decl::template_decl(const environment* env,
+template_decl::template_decl(const environment& env,
 			     const string& name,
 			     const location& locus,
 			     visibility vis)
@@ -25556,7 +25288,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(const environment*	env,
+function_tdecl::function_tdecl(const environment&	env,
 			       const location&		locus,
 			       visibility		vis,
 			       binding			bind)
@@ -25730,7 +25462,7 @@ public:
 ///
 /// @param vis the visibility of the instance of class instantiated
 /// from this template.
-class_tdecl::class_tdecl(const environment*	env,
+class_tdecl::class_tdecl(const environment&	env,
 			 const location&	locus,
 			 visibility		vis)
   : type_or_decl_base(env,
@@ -25976,9 +25708,8 @@ type_has_sub_type_changes(const type_base_sptr t_v1,
 void
 keep_type_alive(type_base_sptr t)
 {
-  environment* env = t->get_environment();
-  ABG_ASSERT(env);
-  env->priv_->extra_live_types_.push_back(t);
+  const environment& env = t->get_environment();
+  env.priv_->extra_live_types_.push_back(t);
 }
 
 /// Hash an ABI artifact that is either a type or a decl.
@@ -26107,10 +25838,10 @@ is_non_canonicalized_type(const type_base *t)
   if (!t)
     return true;
 
-  const environment* env = t->get_environment();
+  const environment& env = t->get_environment();
   return (is_declaration_only_class_or_union_type(t)
-	  || env->is_void_type(t)
-	  || env->is_variadic_parameter_type(t));
+	  || env.is_void_type(t)
+	  || env.is_variadic_parameter_type(t));
 }
 
 /// For a given type, return its exemplar type.
@@ -26984,15 +26715,15 @@ qualified_name_setter::do_update(abigail::ir::decl_base* d)
   else
     d->priv_->qualified_parent_name_ = abigail::interned_string();
 
-  abigail::environment* env = d->get_environment();
-  ABG_ASSERT(env);
+  const abigail::ir::environment& env = d->get_environment();
+
   if (!d->priv_->qualified_parent_name_.empty())
     {
       if (d->get_name().empty())
 	d->priv_->qualified_name_ = abigail::interned_string();
       else
 	d->priv_->qualified_name_ =
-	  env->intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
+	  env.intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
     }
 
   if (d->priv_->scoped_name_.empty())
@@ -27001,10 +26732,10 @@ qualified_name_setter::do_update(abigail::ir::decl_base* d)
 	  && !parent->get_is_anonymous()
 	  && !parent->get_name().empty())
 	d->priv_->scoped_name_ =
-	  env->intern(parent->get_name() + "::" + d->get_name());
+	  env.intern(parent->get_name() + "::" + d->get_name());
       else
 	d->priv_->scoped_name_ =
-	  env->intern(d->get_name());
+	  env.intern(d->get_name());
     }
 
   if (!is_scope_decl(d))
diff --git a/src/abg-reader.cc b/src/abg-reader.cc
index 4afa427a..24b2ea30 100644
--- a/src/abg-reader.cc
+++ b/src/abg-reader.cc
@@ -110,7 +110,7 @@ public:
 
 private:
   string						m_path;
-  environment*						m_env;
+  environment&						m_env;
   unordered_map<string, vector<type_base_sptr> >	m_types_map;
   unordered_map<string, shared_ptr<function_tdecl> >	m_fn_tmpl_map;
   unordered_map<string, shared_ptr<class_tdecl> >	m_class_tmpl_map;
@@ -135,7 +135,7 @@ private:
 
 public:
   read_context(xml::reader_sptr reader,
-	       environment*	env)
+	 environment&	env)
     : m_env(env),
       m_reader(reader),
       m_corp_node(),
@@ -196,23 +196,16 @@ public:
   /// Getter for the environment of this reader.
   ///
   /// @return the environment of this reader.
-  const environment*
-  get_environment() const
+  environment&
+  get_environment()
   {return m_env;}
 
   /// Getter for the environment of this reader.
   ///
   /// @return the environment of this reader.
-  environment*
-  get_environment()
-  {return m_env;}
-
-  /// Setter for the environment of this reader.
-  ///
-  /// @param env the environment of this reader.
-  void
-  set_environment(environment* env)
-  {m_env = env;}
+  const environment&
+  get_environment() const
+  {return const_cast<read_context*>(this)->get_environment();}
 
   xml::reader_sptr
   get_reader() const
@@ -923,8 +916,8 @@ public:
   void
   maybe_check_abixml_canonical_type_stability(type_base_sptr& t)
   {
-    if (!m_env->self_comparison_debug_is_on()
-	|| m_env->get_type_id_canonical_type_map().empty())
+    if (!get_environment().self_comparison_debug_is_on()
+	|| get_environment().get_type_id_canonical_type_map().empty())
       return ;
 
     if (class_decl_sptr c = is_class_type(t))
@@ -936,15 +929,15 @@ public:
     // Let's get the type-id of this type as recorded in the
     // originating abixml file.
     string type_id =
-      m_env->get_type_id_from_pointer(reinterpret_cast<uintptr_t>(t.get()));
+      get_environment().get_type_id_from_pointer(reinterpret_cast<uintptr_t>(t.get()));
 
     if (!type_id.empty())
       {
 	// Now let's get the canonical type that initially led to the
 	// serialization of a type with this type-id, when the abixml
 	// was being serialized.
-	auto j = m_env->get_type_id_canonical_type_map().find(type_id);
-	if (j == m_env->get_type_id_canonical_type_map().end())
+	auto j = get_environment().get_type_id_canonical_type_map().find(type_id);
+	if (j == get_environment().get_type_id_canonical_type_map().end())
 	  {
 	    if (t->get_naked_canonical_type())
 	      std::cerr << "error: no type with type-id: '"
@@ -2111,8 +2104,8 @@ read_corpus_from_input(read_context& ctxt)
     {
       ctxt.set_corpus(std::make_shared<corpus>(ctxt.get_environment(), ""));
 #ifdef WITH_DEBUG_SELF_COMPARISON
-      if (ctxt.get_environment()->self_comparison_debug_is_on())
-	ctxt.get_environment()->
+      if (ctxt.get_environment().self_comparison_debug_is_on())
+	ctxt.get_environment().
 	  set_self_comparison_debug_input(ctxt.get_corpus());
 #endif
 
@@ -2167,7 +2160,7 @@ read_corpus_from_input(read_context& ctxt)
   // due to potential suppression specifications.  That's fine.
   corp.set_symtab(symtab_reader::symtab::load(fn_sym_db, var_sym_db));
 
-  ctxt.get_environment()->canonicalization_is_done(false);
+  ctxt.get_environment().canonicalization_is_done(false);
 
   // Read the translation units.
   while (read_translation_unit_from_input(ctxt))
@@ -2186,7 +2179,7 @@ read_corpus_from_input(read_context& ctxt)
 
   ctxt.perform_late_type_canonicalizing();
 
-  ctxt.get_environment()->canonicalization_is_done(true);
+  ctxt.get_environment().canonicalization_is_done(true);
 
   if (call_reader_next)
     {
@@ -2286,7 +2279,7 @@ read_corpus_group_from_input(read_context& ctxt)
 /// This is non-null iff the parsing resulted in a valid corpus group.
 corpus_group_sptr
 read_corpus_group_from_native_xml(std::istream* in,
-				  environment*  env)
+				  environment&  env)
 {
   read_context_sptr read_ctxt = create_native_xml_read_context(in, env);
   return read_corpus_group_from_input(*read_ctxt);
@@ -2308,7 +2301,7 @@ read_corpus_group_from_native_xml(std::istream* in,
 /// group.
 corpus_group_sptr
 read_corpus_group_from_native_xml_file(const string& path,
-				       environment*  env)
+				   environment&  env)
 {
     read_context_sptr read_ctxt = create_native_xml_read_context(path, env);
     corpus_group_sptr group = read_corpus_group_from_input(*read_ctxt);
@@ -2326,13 +2319,13 @@ read_corpus_group_from_native_xml_file(const string& path,
 /// successful completion, or nil.
 translation_unit_sptr
 read_translation_unit_from_file(const string&	input_file,
-				environment*	env)
+				environment&	env)
 {
   read_context ctxt(xml::new_reader_from_file(input_file), env);
   translation_unit_sptr tu = read_translation_unit_from_input(ctxt);
-  ctxt.get_environment()->canonicalization_is_done(false);
+  env.canonicalization_is_done(false);
   ctxt.perform_late_type_canonicalizing();
-  ctxt.get_environment()->canonicalization_is_done(true);
+  env.canonicalization_is_done(true);
   return tu;
 }
 
@@ -2348,13 +2341,13 @@ read_translation_unit_from_file(const string&	input_file,
 /// successful completion, or nil.
 translation_unit_sptr
 read_translation_unit_from_buffer(const string&	buffer,
-				  environment*		env)
+				  environment&	env)
 {
   read_context ctxt(xml::new_reader_from_buffer(buffer), env);
   translation_unit_sptr tu = read_translation_unit_from_input(ctxt);
-  ctxt.get_environment()->canonicalization_is_done(false);
+  env.canonicalization_is_done(false);
   ctxt.perform_late_type_canonicalizing();
-  ctxt.get_environment()->canonicalization_is_done(true);
+  env.canonicalization_is_done(true);
   return tu;
 }
 
@@ -2369,9 +2362,9 @@ translation_unit_sptr
 read_translation_unit(read_context& ctxt)
 {
   translation_unit_sptr tu = read_translation_unit_from_input(ctxt);
-  ctxt.get_environment()->canonicalization_is_done(false);
+  ctxt.get_environment().canonicalization_is_done(false);
   ctxt.perform_late_type_canonicalizing();
-  ctxt.get_environment()->canonicalization_is_done(true);
+  ctxt.get_environment().canonicalization_is_done(true);
   return tu;
 }
 
@@ -3052,12 +3045,12 @@ maybe_map_type_with_type_id(const type_base_sptr& t,
   if (!t)
     return false;
 
-  environment *env = t->get_environment();
-  if (!env->self_comparison_debug_is_on()
+  const environment& env = t->get_environment();
+  if (!env.self_comparison_debug_is_on()
       || is_non_canonicalized_type(t.get()))
     return false;
 
-  env->get_pointer_type_id_map()[reinterpret_cast<uintptr_t>(t.get())] =
+  env.get_pointer_type_id_map()[reinterpret_cast<uintptr_t>(t.get())] =
     type_id;
 
   return true;
@@ -3083,8 +3076,8 @@ maybe_map_type_with_type_id(const type_base_sptr& t,
   if (!t)
     return false;
 
-  environment *env = t->get_environment();
-  if (!env->self_comparison_debug_is_on()
+  const environment& env = t->get_environment();
+  if (!env.self_comparison_debug_is_on()
       || is_non_canonicalized_type(t.get()))
     return false;
 
@@ -3159,7 +3152,7 @@ build_namespace_decl(read_context&	ctxt,
   location loc;
   read_location(ctxt, node, loc);
 
-  const environment* env = ctxt.get_environment();
+  const environment& env = ctxt.get_environment();
   namespace_decl_sptr decl(new namespace_decl(env, name, loc));
   maybe_set_artificial_location(ctxt, node, decl);
   ctxt.push_decl_to_current_scope(decl, add_to_current_scope);
@@ -3255,7 +3248,7 @@ build_elf_symbol(read_context& ctxt, const xmlNodePtr node,
   if (drop_if_suppressed && is_suppressed)
     return elf_symbol_sptr();
 
-  const environment* env = ctxt.get_environment();
+  const environment& env = ctxt.get_environment();
   elf_symbol_sptr e = elf_symbol::create(env, /*index=*/0,
 					 size, name, type, binding,
 					 is_defined, is_common,
@@ -3410,7 +3403,7 @@ build_elf_symbol_db(read_context& ctxt,
 
 /// Build a function parameter from a 'parameter' xml element node.
 ///
-/// @param ctxt the contexte of the xml parsing.
+/// @param rdr the contexte of the xml parsing.
 ///
 /// @param node the xml 'parameter' element node to de-serialize from.
 static shared_ptr<function_decl::parameter>
@@ -3421,8 +3414,6 @@ build_function_parameter(read_context& ctxt, const xmlNodePtr node)
   if (!node || !xmlStrEqual(node->name, BAD_CAST("parameter")))
     return nil;
 
-  ABG_ASSERT(ctxt.get_environment());
-
   bool is_variadic = false;
   string is_variadic_str;
   if (xml_char_sptr s =
@@ -3441,14 +3432,13 @@ build_function_parameter(read_context& ctxt, const xmlNodePtr node)
 
   type_base_sptr type;
   if (is_variadic)
-    type = ctxt.get_environment()->get_variadic_parameter_type();
+    type = ctxt.get_environment().get_variadic_parameter_type();
   else
     {
       ABG_ASSERT(!type_id.empty());
       type = ctxt.build_or_get_type_decl(type_id, true);
     }
   ABG_ASSERT(type);
-  ABG_ASSERT(type->get_environment() == ctxt.get_environment());
 
   string name;
   if (xml_char_sptr a = xml::build_sptr(xmlGetProp(node, BAD_CAST("name"))))
@@ -3518,10 +3508,9 @@ build_function_decl(read_context&	ctxt,
   location loc;
   read_location(ctxt, node, loc);
 
-  environment* env = ctxt.get_environment();
-  ABG_ASSERT(env);
+  environment& env = ctxt.get_environment();
   std::vector<function_decl::parameter_sptr> parms;
-  type_base_sptr return_type = env->get_void_type();
+  type_base_sptr return_type = env.get_void_type();
 
   for (xmlNodePtr n = xmlFirstElementChild(node);
        n ;
@@ -3885,7 +3874,7 @@ build_type_decl(read_context&		ctxt,
       return ty;
     }
 
-  const environment* env = ctxt.get_environment();
+  const environment& env = ctxt.get_environment();
   type_decl_sptr decl(new type_decl(env, name, size_in_bits,
 				    alignment_in_bits, loc));
   maybe_set_artificial_location(ctxt, node, decl);
@@ -4179,10 +4168,9 @@ build_function_type(read_context&	ctxt,
   size_t size = ctxt.get_translation_unit()->get_address_size(), align = 0;
   read_size_and_alignment(node, size, align);
 
-  environment* env = ctxt.get_environment();
-  ABG_ASSERT(env);
+  const environment& env = ctxt.get_environment();
   std::vector<shared_ptr<function_decl::parameter> > parms;
-  type_base_sptr return_type = env->get_void_type();
+  type_base_sptr return_type = env.get_void_type();
 
   class_or_union_sptr method_class_type;
   if (is_method_t)
@@ -4196,7 +4184,7 @@ build_function_type(read_context&	ctxt,
 
  function_type_sptr fn_type(is_method_t
 			    ? new method_type(method_class_type,
-					      ctxt.get_environment(),
+					      /*is_const=*/false,
 					      size, align)
 			    : new function_type(return_type,
 						parms, size, align));
@@ -4586,9 +4574,6 @@ build_enum_type_decl(read_context&	ctxt,
 
   ABG_ASSERT(!id.empty());
 
-  const environment* env = ctxt.get_environment();
-  ABG_ASSERT(env);
-
   string base_type_id;
   enum_type_decl::enumerators enums;
   for (xmlNodePtr n = xmlFirstElementChild(node);
@@ -4623,7 +4608,7 @@ build_enum_type_decl(read_context&	ctxt,
 		return nil;
 	    }
 
-	  enums.push_back(enum_type_decl::enumerator(env, name, value));
+	  enums.push_back(enum_type_decl::enumerator(name, value));
 	}
     }
 
@@ -4864,8 +4849,7 @@ build_class_decl(read_context&		ctxt,
 	return previous_declaration;
     }
 
-  const environment* env = ctxt.get_environment();
-  ABG_ASSERT(env);
+  const environment& env = ctxt.get_environment();
 
   if (!is_decl_only && previous_definition)
     // We are in the case where we've read this class definition
@@ -5281,8 +5265,7 @@ build_union_decl(read_context& ctxt,
 	return previous_declaration;
     }
 
-  const environment* env = ctxt.get_environment();
-  ABG_ASSERT(env);
+  const environment& env = ctxt.get_environment();
 
   if (!is_decl_only && previous_definition)
     // We are in the case where we've read this class definition
@@ -5569,8 +5552,7 @@ build_function_tdecl(read_context& ctxt,
   decl_base::binding bind = decl_base::BINDING_NONE;
   read_binding(node, bind);
 
-  const environment* env = ctxt.get_environment();
-  ABG_ASSERT(env);
+  const environment& env = ctxt.get_environment();
 
   function_tdecl_sptr fn_tmpl_decl(new function_tdecl(env, loc, vis, bind));
   maybe_set_artificial_location(ctxt, node, fn_tmpl_decl);
@@ -5633,8 +5615,7 @@ build_class_tdecl(read_context&	ctxt,
   decl_base::visibility vis = decl_base::VISIBILITY_NONE;
   read_visibility(node, vis);
 
-  const environment* env = ctxt.get_environment();
-  ABG_ASSERT(env);
+  const environment& env = ctxt.get_environment();
 
   class_tdecl_sptr class_tmpl (new class_tdecl(env, loc, vis));
   maybe_set_artificial_location(ctxt, node, class_tmpl);
@@ -5723,7 +5704,6 @@ build_type_tparameter(read_context&		ctxt,
   else
     ctxt.push_and_key_type_decl(result, id, /*add_to_current_scope=*/true);
 
-  ABG_ASSERT(result->get_environment());
 
   ctxt.maybe_canonicalize_type(result, /*force_delay=*/false);
 
@@ -6252,7 +6232,7 @@ handle_class_tdecl(read_context&	ctxt,
 /// @return the translation unit resulting from the parsing upon
 /// successful completion, or nil.
 translation_unit_sptr
-read_translation_unit_from_istream(istream* in, environment* env)
+read_translation_unit_from_istream(istream* in, environment& env)
 {
   read_context read_ctxt(xml::new_reader_from_istream(in), env);
   return read_translation_unit_from_input(read_ctxt);
@@ -6276,7 +6256,7 @@ struct array_deleter
 ///
 /// @return the created context.
 read_context_sptr
-create_native_xml_read_context(const string& path, environment *env)
+create_native_xml_read_context(const string& path, environment& env)
 {
   read_context_sptr result(new read_context(xml::new_reader_from_file(path),
 					    env));
@@ -6284,8 +6264,8 @@ create_native_xml_read_context(const string& path, environment *env)
   corp->set_origin(corpus::NATIVE_XML_ORIGIN);
   result->set_corpus(corp);
 #ifdef WITH_DEBUG_SELF_COMPARISON
-  if (env->self_comparison_debug_is_on())
-    env->set_self_comparison_debug_input(result->get_corpus());
+  if (env.self_comparison_debug_is_on())
+    env.set_self_comparison_debug_input(result->corpus());
 #endif
   result->set_path(path);
   return result;
@@ -6300,7 +6280,7 @@ create_native_xml_read_context(const string& path, environment *env)
 ///
 /// @return the created context.
 read_context_sptr
-create_native_xml_read_context(std::istream* in, environment* env)
+create_native_xml_read_context(std::istream* in, environment& env)
 {
   read_context_sptr result(new read_context(xml::new_reader_from_istream(in),
 					    env));
@@ -6308,8 +6288,8 @@ create_native_xml_read_context(std::istream* in, environment* env)
   corp->set_origin(corpus::NATIVE_XML_ORIGIN);
   result->set_corpus(corp);
 #ifdef WITH_DEBUG_SELF_COMPARISON
-  if (env->self_comparison_debug_is_on())
-    env->set_self_comparison_debug_input(result->get_corpus());
+  if (env.self_comparison_debug_is_on())
+    env.set_self_comparison_debug_input(result->corpus());
 #endif
   return result;
 }
@@ -6335,7 +6315,7 @@ read_context_get_path(const read_context& ctxt)
 /// is non-null iff the parsing resulted in a valid corpus.
 corpus_sptr
 read_corpus_from_native_xml(std::istream* in,
-			    environment* env)
+			    environment& env)
 {
   read_context_sptr read_ctxt = create_native_xml_read_context(in, env);
   return read_corpus_from_input(*read_ctxt);
@@ -6356,7 +6336,7 @@ read_corpus_from_native_xml(std::istream* in,
 /// is non-null if the parsing successfully resulted in a corpus.
 corpus_sptr
 read_corpus_from_native_xml_file(const string& path,
-				 environment* env)
+				 environment& env)
 {
   read_context_sptr read_ctxt = create_native_xml_read_context(path, env);
   corpus_sptr corp = read_corpus_from_input(*read_ctxt);
@@ -6443,7 +6423,7 @@ load_canonical_type_ids(xml_reader::read_context& ctxt, const string &file_path)
 	      // that are not canonicalized.  Look into function
 	      // hash_as_canonical_type_or_constant for the details.
 	      && v != 0xdeadbabe)
-	    ctxt.get_environment()->get_type_id_canonical_type_map()[id] = v;
+	    ctxt.get_environment().get_type_id_canonical_type_map()[id] = v;
 	}
     }
   return true;
diff --git a/src/abg-symtab-reader.cc b/src/abg-symtab-reader.cc
index 606c96a2..219ab6c6 100644
--- a/src/abg-symtab-reader.cc
+++ b/src/abg-symtab-reader.cc
@@ -139,11 +139,10 @@ static struct
 /// not completed
 symtab_ptr
 symtab::load(Elf*	      elf_handle,
-	     ir::environment* env,
+	     const ir::environment& env,
 	     symbol_predicate is_suppressed)
 {
   ABG_ASSERT(elf_handle);
-  ABG_ASSERT(env);
 
   symtab_ptr result(new symtab);
   if (!result->load_(elf_handle, env, is_suppressed))
@@ -201,7 +200,7 @@ symtab::symtab()
 /// @return true if the load succeeded
 bool
 symtab::load_(Elf*	       elf_handle,
-	      ir::environment* env,
+	      const ir::environment& env,
 	      symbol_predicate is_suppressed)
 {
   GElf_Ehdr ehdr_mem;
diff --git a/src/abg-symtab-reader.h b/src/abg-symtab-reader.h
index 384d757f..4d90c302 100644
--- a/src/abg-symtab-reader.h
+++ b/src/abg-symtab-reader.h
@@ -243,7 +243,7 @@ public:
 
   static symtab_ptr
   load(Elf*		elf_handle,
-       ir::environment* env,
+       const ir::environment& env,
        symbol_predicate is_suppressed = NULL);
 
   static symtab_ptr
@@ -283,7 +283,9 @@ private:
   addr_symbol_map_type entry_addr_symbol_map_;
 
   bool
-  load_(Elf* elf_handle, ir::environment* env, symbol_predicate is_suppressed);
+  load_(Elf* elf_handle,
+	const ir::environment& env,
+	symbol_predicate is_suppressed);
 
   bool
   load_(string_elf_symbols_map_sptr function_symbol_map,
diff --git a/src/abg-tools-utils.cc b/src/abg-tools-utils.cc
index fe9ebc72..29700416 100644
--- a/src/abg-tools-utils.cc
+++ b/src/abg-tools-utils.cc
@@ -2537,19 +2537,18 @@ maybe_load_vmlinux_dwarf_corpus(corpus::origin      origin,
                                 suppressions_type&  supprs,
                                 bool                verbose,
                                 timer&              t,
-                                environment_sptr&   env)
+                                environment&        env)
 {
   if (!(origin & corpus::DWARF_ORIGIN))
     return;
 
-  abigail::elf_reader::status status = abigail::elf_reader::STATUS_OK;
+   abigail::elf_reader::status status = abigail::elf_reader::STATUS_OK;
   dwarf_reader::read_context_sptr ctxt;
   ctxt =
-   dwarf_reader::create_read_context(vmlinux, di_roots, env.get(),
-                                     /*read_all_types=*/false,
-                                     /*linux_kernel_mode=*/true);
-  dwarf_reader::set_do_log(*ctxt, verbose);
-
+    dwarf_reader::create_read_context(vmlinux, di_roots, env,
+                                      /*read_all_types=*/false,
+                                      /*linux_kernel_mode=*/true);
+   dwarf_reader::set_do_log(*ctxt, verbose);
   t.start();
   load_generate_apply_suppressions(*ctxt, suppr_paths,
                                    kabi_wl_paths, supprs);
@@ -2560,7 +2559,7 @@ maybe_load_vmlinux_dwarf_corpus(corpus::origin      origin,
      << t
      << "\n";
 
-  group.reset(new corpus_group(env.get(), root));
+  group.reset(new corpus_group(env, root));
 
   set_read_context_corpus_group(*ctxt, group);
 
@@ -2595,7 +2594,7 @@ maybe_load_vmlinux_dwarf_corpus(corpus::origin      origin,
          << "/" << total_nb_modules
          << ") ... " << std::flush;
 
-      reset_read_context(ctxt, *m, di_roots, env.get(),
+      reset_read_context(ctxt, *m, di_roots,
                          /*read_all_types=*/false,
                          /*linux_kernel_mode=*/true);
 
@@ -2652,15 +2651,15 @@ maybe_load_vmlinux_ctf_corpus(corpus::origin	  origin,
                               vector<char**>&     di_roots,
                               bool                verbose,
                               timer&              t,
-                              environment_sptr&   env)
+                              environment&        env)
 {
   if (!(origin & corpus::CTF_ORIGIN))
     return;
 
   abigail::elf_reader::status status = abigail::elf_reader::STATUS_OK;
   ctf_reader::read_context_sptr ctxt;
-  ctxt = ctf_reader::create_read_context(vmlinux, di_roots, env.get());
-  group.reset(new corpus_group(env.get(), root));
+  ctxt = ctf_reader::create_read_context(vmlinux, di_roots, env);
+  group.reset(new corpus_group(env, root));
   set_read_context_corpus_group(*ctxt, group);
 
   if (verbose)
@@ -2694,7 +2693,7 @@ maybe_load_vmlinux_ctf_corpus(corpus::origin	  origin,
          << "/" << total_nb_modules
          << ") ... " << std::flush;
 
-      reset_read_context(ctxt, *m, di_roots, env.get());
+      reset_read_context(ctxt, *m, di_roots);
       set_read_context_corpus_group(*ctxt, group);
 
       t.start();
@@ -2757,7 +2756,7 @@ build_corpus_group_from_kernel_dist_under(const string&	root,
 					  vector<string>&	kabi_wl_paths,
 					  suppressions_type&	supprs,
 					  bool			verbose,
-					  environment_sptr&	env,
+					  environment&		env,
 					  corpus::origin	origin)
 {
   string vmlinux = vmlinux_path;
diff --git a/src/abg-writer.cc b/src/abg-writer.cc
index dff8813a..1cffd77b 100644
--- a/src/abg-writer.cc
+++ b/src/abg-writer.cc
@@ -65,7 +65,7 @@ namespace xml_writer
 
 class id_manager
 {
-  const environment* m_env;
+  const environment& m_env;
   mutable unsigned long long m_cur_id;
 
   unsigned long long
@@ -73,11 +73,11 @@ class id_manager
   { return ++m_cur_id; }
 
 public:
-  id_manager(const environment* env)
+  id_manager(const environment& env)
     : m_env(env),
       m_cur_id(0) {}
 
-  const environment*
+  const environment&
   get_environment() const
   {return m_env;}
 
@@ -87,9 +87,8 @@ public:
   {
     ostringstream o;
     o << get_new_id();
-    const environment* env = get_environment();
-    ABG_ASSERT(env);
-    return env->intern(o.str());
+    const environment& env = get_environment();
+    return env.intern(o.str());
   }
 
   /// Return a unique string representing a numerical ID, prefixed by
@@ -101,9 +100,8 @@ public:
   {
     ostringstream o;
     o << prefix << get_new_id();
-    const environment* env = get_environment();
-    ABG_ASSERT(env);
-    return env->intern(o.str());
+    const environment& env = get_environment();
+    return env.intern(o.str());
   }
 };
 
@@ -207,7 +205,7 @@ typedef unordered_map<shared_ptr<class_tdecl>,
 
 class write_context
 {
-  const environment*			m_env;
+  const environment&			m_env;
   id_manager				m_id_manager;
   ostream*				m_ostream;
   bool					m_annotate;
@@ -243,7 +241,7 @@ public:
   /// @param env the enviroment we are operating from.
   ///
   /// @param os the output stream to write to.
-  write_context(const environment* env, ostream& os)
+  write_context(const environment& env, ostream& os)
     : m_env(env),
       m_id_manager(env),
       m_ostream(&os),
@@ -262,16 +260,13 @@ public:
   /// Getter of the environment we are operating from.
   ///
   /// @return the environment we are operating from.
-  const environment*
+  const environment&
   get_environment() const
   {return m_env;}
 
   const config&
   get_config() const
-  {
-    ABG_ASSERT(get_environment());
-    return get_environment()->get_config();
-  }
+  {return get_environment().get_config();}
 
   /// Getter for the current ostream
   ///
@@ -498,7 +493,7 @@ public:
 	    ++hash;
 	  std::ostringstream os;
 	  os << std::hex << std::setfill('0') << std::setw(8) << hash;
-	  return m_type_id_map[c] = c->get_environment()->intern(os.str());
+	  return m_type_id_map[c] = c->get_environment().intern(os.str());
 	}
       }
     ABG_ASSERT_NOT_REACHED;
@@ -808,7 +803,7 @@ public:
   {
     ABG_ASSERT(!is_type(decl));
     string repr = get_pretty_representation(decl, true);
-    interned_string irepr = decl->get_environment()->intern(repr);
+    interned_string irepr = decl->get_environment().intern(repr);
     return m_emitted_decls_set.find(irepr) != m_emitted_decls_set.end();
   }
 
@@ -819,7 +814,7 @@ public:
   record_decl_as_emitted(const decl_base_sptr& decl)
   {
     string repr = get_pretty_representation(decl, true);
-    interned_string irepr = decl->get_environment()->intern(repr);
+    interned_string irepr = decl->get_environment().intern(repr);
     m_emitted_decls_set.insert(irepr);
   }
 
@@ -2064,7 +2059,7 @@ write_decl_in_scope(const decl_base_sptr&	decl,
 ///
 /// @return the new @ref write_context object.
 write_context_sptr
-create_write_context(const environment *env,
+create_write_context(const environment& env,
 		     ostream& default_output_stream)
 {
   write_context_sptr ctxt(new write_context(env, default_output_stream));
@@ -3691,7 +3686,7 @@ write_class_decl(const class_decl_sptr& d,
     {
       type_base_wptrs_type result;
       canonical_type_sptr_set_type member_types;
-      const environment* env = ctxt.get_environment();
+      const environment& env = ctxt.get_environment();
 
       // We are looking at a decl-only class.  All decl-only classes
       // of a given name are equal.  But then the problem is that a
@@ -3708,7 +3703,7 @@ write_class_decl(const class_decl_sptr& d,
       //
       // So let's gather all the member-types of all the decl-only
       // classes of the fully-qualified name and emit them here.
-      if (lookup_decl_only_class_types(env->intern(decl->get_qualified_name()),
+      if (lookup_decl_only_class_types(env.intern(decl->get_qualified_name()),
 				       *decl->get_corpus(),
 				       result))
 	{
diff --git a/tests/print-diff-tree.cc b/tests/print-diff-tree.cc
index c0c7195a..dce1c124 100644
--- a/tests/print-diff-tree.cc
+++ b/tests/print-diff-tree.cc
@@ -104,9 +104,9 @@ main(int argc, char* argv[])
       elf_reader::status c1_status, c2_status;
       corpus_sptr c1, c2;
 
-      environment_sptr env(new environment);
+      environment env;
       vector<char**> di_roots;
-      c1 = dwarf_reader::read_corpus_from_elf(opts.elf1, di_roots, env.get(),
+      c1 = dwarf_reader::read_corpus_from_elf(opts.elf1, di_roots, env,
 					      /*load_all_types=*/false,
 					      c1_status);
       if (c1_status != elf_reader::STATUS_OK)
@@ -115,7 +115,7 @@ main(int argc, char* argv[])
 	  return 1;
 	}
 
-      c2 = dwarf_reader::read_corpus_from_elf(opts.elf2, di_roots, env.get(),
+      c2 = dwarf_reader::read_corpus_from_elf(opts.elf2, di_roots, env,
 					      /*load_all_types=*/false,
 					      c2_status);
       if (c2_status != elf_reader::STATUS_OK)
diff --git a/tests/test-abidiff.cc b/tests/test-abidiff.cc
index 951b6d25..0e2b922b 100644
--- a/tests/test-abidiff.cc
+++ b/tests/test-abidiff.cc
@@ -211,18 +211,18 @@ main(int, char*[])
 	  continue;
 	}
 
-      environment_sptr env(new environment);
+      environment env;
       translation_unit_sptr tu1, tu2;
       corpus_sptr corpus1, corpus2;
       corpus_group_sptr corpus_group1, corpus_group2;
       file_type t = guess_file_type(first_in_path);
       if (t == abigail::tools_utils::FILE_TYPE_NATIVE_BI)
-	tu1 = read_translation_unit_from_file(first_in_path, env.get());
+	tu1 = read_translation_unit_from_file(first_in_path, env);
       else if (t == abigail::tools_utils::FILE_TYPE_XML_CORPUS)
-	corpus1 = read_corpus_from_native_xml_file(first_in_path, env.get());
+	corpus1 = read_corpus_from_native_xml_file(first_in_path, env);
       else if (t == abigail::tools_utils::FILE_TYPE_XML_CORPUS_GROUP)
 	corpus_group1 = read_corpus_group_from_native_xml_file(first_in_path,
-							       env.get());
+							       env);
       else
 	abort();
       if (!tu1 && !corpus1 && !corpus_group1)
@@ -234,12 +234,12 @@ main(int, char*[])
 
       t = guess_file_type(second_in_path);
       if (t == abigail::tools_utils::FILE_TYPE_NATIVE_BI)
-	tu2 = read_translation_unit_from_file(second_in_path, env.get());
+	tu2 = read_translation_unit_from_file(second_in_path, env);
       else if (t == abigail::tools_utils::FILE_TYPE_XML_CORPUS)
-	corpus2 = read_corpus_from_native_xml_file(second_in_path, env.get());
+	corpus2 = read_corpus_from_native_xml_file(second_in_path, env);
       else if (t == abigail::tools_utils::FILE_TYPE_XML_CORPUS_GROUP)
 	corpus_group2 = read_corpus_group_from_native_xml_file(first_in_path,
-							       env.get());
+							       env);
       else
 	abort();
       if (!tu2 && !corpus2 && !corpus_group2)
diff --git a/tests/test-diff-dwarf.cc b/tests/test-diff-dwarf.cc
index 42e25dfa..3a31284f 100644
--- a/tests/test-diff-dwarf.cc
+++ b/tests/test-diff-dwarf.cc
@@ -383,19 +383,19 @@ main()
       abigail::elf_reader::status status =
 	abigail::elf_reader::STATUS_UNKNOWN;
 
-      environment_sptr env(new environment);
+      environment env;
       std::vector<char**> di_roots;
       abigail::corpus_sptr corp0 =
 	read_corpus_from_elf(in_elfv0_path,
 			     /*debug_info_root_path=*/di_roots,
-			     env.get(),
+			     env,
 			     /*load_all_types=*/false,
 			     status);
 
       abigail::corpus_sptr corp1 =
 	read_corpus_from_elf(in_elfv1_path,
 			     /*debug_info_root_path=*/di_roots,
-			     env.get(),
+			     env,
 			     /*load_all_types=*/false,
 			     status);
 
diff --git a/tests/test-ir-walker.cc b/tests/test-ir-walker.cc
index b6042d20..b8e0d5e2 100644
--- a/tests/test-ir-walker.cc
+++ b/tests/test-ir-walker.cc
@@ -155,12 +155,12 @@ main(int argc, char **argv)
 
   string file_name = argv[1];
 
-  abigail::ir::environment_sptr env(new abigail::ir::environment);
+  abigail::ir::environment env;
   abigail::corpus_sptr c;
   abigail::elf_reader::status status = abigail::elf_reader::STATUS_OK;
   std::vector<char**> di_roots;
   if (!(c = abigail::dwarf_reader::read_corpus_from_elf(file_name, di_roots,
-							env.get(),
+							env,
 							/*load_all_type=*/false,
 							status)))
     {
diff --git a/tests/test-read-ctf.cc b/tests/test-read-ctf.cc
index b0ef7de6..1a689bfa 100644
--- a/tests/test-read-ctf.cc
+++ b/tests/test-read-ctf.cc
@@ -348,12 +348,11 @@ test_task_ctf::test_task_ctf(const InOutSpec &s,
 void
 test_task_ctf::perform()
 {
-  abigail::ir::environment_sptr env;
+  abigail::ir::environment env;
 
   set_in_elf_path();
   set_in_suppr_spec_path();
 
-  env.reset(new abigail::ir::environment);
   abigail::elf_reader::status status =
     abigail::elf_reader::STATUS_UNKNOWN;
   vector<char**> di_roots;
@@ -361,7 +360,7 @@ test_task_ctf::perform()
 
   read_context_sptr ctxt = create_read_context(in_elf_path,
                                                di_roots,
-                                               env.get());
+                                               env);
   ABG_ASSERT(ctxt);
 
   corpus_sptr corp = read_corpus(ctxt.get(), status);
diff --git a/tests/test-symtab.cc b/tests/test-symtab.cc
index efef9a99..2ca51e22 100644
--- a/tests/test-symtab.cc
+++ b/tests/test-symtab.cc
@@ -42,10 +42,10 @@ read_corpus(const std::string&		    path,
 {
   const std::string& absolute_path = test_data_dir + path;
 
-  environment_sptr	    env(new environment);
+  environment env;
   const std::vector<char**> debug_info_root_paths;
   read_context_sptr	    ctxt =
-      create_read_context(absolute_path, debug_info_root_paths, env.get(),
+      create_read_context(absolute_path, debug_info_root_paths, env,
 			  /* load_all_type = */ true,
 			  /* linux_kernel_mode = */ true);
 
diff --git a/tools/abicompat.cc b/tools/abicompat.cc
index 0be49a86..9bad54b8 100644
--- a/tools/abicompat.cc
+++ b/tools/abicompat.cc
@@ -657,7 +657,7 @@ perform_compat_check_in_weak_mode(options& opts,
 static corpus_sptr
 read_corpus(options opts, status &status,
 	    const vector<char**> di_roots,
-	    const environment_sptr &env,
+	    environment&      env,
 	    const string &path)
 {
   corpus_sptr retval = NULL;
@@ -677,14 +677,14 @@ read_corpus(options opts, status &status,
 	  {
 	    abigail::ctf_reader::read_context_sptr r_ctxt
 	      = abigail::ctf_reader::create_read_context(path,
-							 env.get());
+							 env);
 	    ABG_ASSERT(r_ctxt);
 
 	    retval = abigail::ctf_reader::read_corpus(r_ctxt.get(), status);
 	  }
 	else
 #endif
-	  retval = read_corpus_from_elf(path, di_roots, env.get(),
+	  retval = read_corpus_from_elf(path, di_roots, env,
 					/*load_all_types=*/opts.weak_mode,
 					status);
       }
@@ -692,7 +692,7 @@ read_corpus(options opts, status &status,
     case abigail::tools_utils::FILE_TYPE_XML_CORPUS:
       {
 	abigail::xml_reader::read_context_sptr r_ctxt =
-	  abigail::xml_reader::create_native_xml_read_context(path, env.get());
+	  abigail::xml_reader::create_native_xml_read_context(path, env);
 	assert(r_ctxt);
 	retval = abigail::xml_reader::read_corpus_from_input(*r_ctxt);
       }
@@ -789,7 +789,7 @@ main(int argc, char* argv[])
   vector<char**> app_di_roots;
   app_di_roots.push_back(&app_di_root);
   status status = abigail::elf_reader::STATUS_UNKNOWN;
-  environment_sptr env(new environment);
+  environment env;
 
   corpus_sptr app_corpus = read_corpus(opts, status,
 				       app_di_roots, env,
diff --git a/tools/abidiff.cc b/tools/abidiff.cc
index 9b2ab784..44d30c43 100644
--- a/tools/abidiff.cc
+++ b/tools/abidiff.cc
@@ -1153,17 +1153,17 @@ main(int argc, char* argv[])
       t1_type = guess_file_type(opts.file1);
       t2_type = guess_file_type(opts.file2);
 
-      environment_sptr env(new environment);
+      environment env;
       if (opts.exported_interfaces_only.has_value())
-	env->analyze_exported_interfaces_only(*opts.exported_interfaces_only);
+	env.analyze_exported_interfaces_only(*opts.exported_interfaces_only);
 
 #ifdef WITH_DEBUG_SELF_COMPARISON
 	    if (opts.do_debug_self_comparison)
-	      env->self_comparison_debug_is_on(true);
+	      env.self_comparison_debug_is_on(true);
 #endif
 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
 	    if (opts.do_debug_type_canonicalization)
-	      env->debug_type_canonicalization_is_on(true);
+	      env.debug_type_canonicalization_is_on(true);
 #endif
       translation_unit_sptr t1, t2;
       abigail::elf_reader::status c1_status =
@@ -1194,7 +1194,7 @@ main(int argc, char* argv[])
 	  break;
 	case abigail::tools_utils::FILE_TYPE_NATIVE_BI:
 	  t1 = abigail::xml_reader::read_translation_unit_from_file(opts.file1,
-								    env.get());
+								    env);
 	  break;
 	case abigail::tools_utils::FILE_TYPE_ELF: // fall through
 	case abigail::tools_utils::FILE_TYPE_AR:
@@ -1205,7 +1205,7 @@ main(int argc, char* argv[])
                 abigail::ctf_reader::read_context_sptr ctxt
                   = abigail::ctf_reader::create_read_context(opts.file1,
                                                              opts.prepared_di_root_paths1,
-                                                             env.get());
+                                                             env);
                 ABG_ASSERT(ctxt);
                 c1 = abigail::ctf_reader::read_corpus(ctxt.get(),
                                                       c1_status);
@@ -1216,7 +1216,7 @@ main(int argc, char* argv[])
                 abigail::dwarf_reader::read_context_sptr ctxt =
                   abigail::dwarf_reader::create_read_context
                   (opts.file1, opts.prepared_di_root_paths1,
-                   env.get(), /*read_all_types=*/opts.show_all_types,
+                   env, /*read_all_types=*/opts.show_all_types,
                    opts.linux_kernel_mode);
                 assert(ctxt);
 
@@ -1237,7 +1237,7 @@ main(int argc, char* argv[])
 	  {
 	    abigail::xml_reader::read_context_sptr ctxt =
 	      abigail::xml_reader::create_native_xml_read_context(opts.file1,
-								  env.get());
+								  env);
 	    assert(ctxt);
 	    set_suppressions(*ctxt, opts);
 	    set_native_xml_reader_options(*ctxt, opts);
@@ -1251,7 +1251,7 @@ main(int argc, char* argv[])
 	  {
 	    abigail::xml_reader::read_context_sptr ctxt =
 	      abigail::xml_reader::create_native_xml_read_context(opts.file1,
-								  env.get());
+								  env);
 	    assert(ctxt);
 	    set_suppressions(*ctxt, opts);
 	    set_native_xml_reader_options(*ctxt, opts);
@@ -1278,7 +1278,7 @@ main(int argc, char* argv[])
 	  break;
 	case abigail::tools_utils::FILE_TYPE_NATIVE_BI:
 	  t2 = abigail::xml_reader::read_translation_unit_from_file(opts.file2,
-								    env.get());
+								    env);
 	  break;
 	case abigail::tools_utils::FILE_TYPE_ELF: // Fall through
 	case abigail::tools_utils::FILE_TYPE_AR:
@@ -1289,7 +1289,7 @@ main(int argc, char* argv[])
                 abigail::ctf_reader::read_context_sptr ctxt
                   = abigail::ctf_reader::create_read_context(opts.file2,
                                                              opts.prepared_di_root_paths2,
-                                                             env.get());
+                                                             env);
                 ABG_ASSERT(ctxt);
                 c2 = abigail::ctf_reader::read_corpus(ctxt.get(),
                                                       c2_status);
@@ -1300,7 +1300,7 @@ main(int argc, char* argv[])
                 abigail::dwarf_reader::read_context_sptr ctxt =
                   abigail::dwarf_reader::create_read_context
                   (opts.file2, opts.prepared_di_root_paths2,
-                   env.get(), /*read_all_types=*/opts.show_all_types,
+                   env, /*read_all_types=*/opts.show_all_types,
                    opts.linux_kernel_mode);
                 assert(ctxt);
                 abigail::dwarf_reader::set_show_stats(*ctxt, opts.show_stats);
@@ -1320,7 +1320,7 @@ main(int argc, char* argv[])
 	  {
 	    abigail::xml_reader::read_context_sptr ctxt =
 	      abigail::xml_reader::create_native_xml_read_context(opts.file2,
-								  env.get());
+								  env);
 	    assert(ctxt);
 	    set_suppressions(*ctxt, opts);
 	    set_native_xml_reader_options(*ctxt, opts);
@@ -1334,7 +1334,7 @@ main(int argc, char* argv[])
 	  {
 	    abigail::xml_reader::read_context_sptr ctxt =
 	      abigail::xml_reader::create_native_xml_read_context(opts.file2,
-								  env.get());
+								  env);
 	    assert(ctxt);
 	    set_suppressions(*ctxt, opts);
 	    set_native_xml_reader_options(*ctxt, opts);
diff --git a/tools/abidw.cc b/tools/abidw.cc
index f38d6048..a536a707 100644
--- a/tools/abidw.cc
+++ b/tools/abidw.cc
@@ -531,7 +531,7 @@ set_suppressions(dwarf_reader::read_context& read_ctxt, options& opts)
 /// otherwise.
 static int
 load_corpus_and_write_abixml(char* argv[],
-			     environment_sptr& env,
+			     environment& env,
 			     options& opts)
 {
   int exit_code = 0;
@@ -539,14 +539,14 @@ load_corpus_and_write_abixml(char* argv[],
 
 #ifdef WITH_DEBUG_SELF_COMPARISON
   if (opts.debug_abidiff)
-    env->self_comparison_debug_is_on(true);
+    env.self_comparison_debug_is_on(true);
 #endif
 
 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
   if (opts.debug_type_canonicalization)
-    env->debug_type_canonicalization_is_on(true);
+    env.debug_type_canonicalization_is_on(true);
   if (opts.debug_die_canonicalization)
-    env->debug_die_canonicalization_is_on(true);
+    env.debug_die_canonicalization_is_on(true);
 #endif
 
   // First of all, read a libabigail IR corpus from the file specified
@@ -559,7 +559,7 @@ load_corpus_and_write_abixml(char* argv[],
       abigail::ctf_reader::read_context_sptr ctxt
         = abigail::ctf_reader::create_read_context(opts.in_file_path,
                                                    opts.prepared_di_root_paths,
-                                                   env.get());
+                                                   env);
       assert (ctxt);
       t.start();
       corp = abigail::ctf_reader::read_corpus (ctxt, s);
@@ -574,7 +574,7 @@ load_corpus_and_write_abixml(char* argv[],
       dwarf_reader::read_context_sptr c
         = abigail::dwarf_reader::create_read_context(opts.in_file_path,
                                                      opts.prepared_di_root_paths,
-                                                     env.get(),
+                                                     env,
                                                      opts.load_all_types,
                                                      opts.linux_kernel_mode);
       dwarf_reader::read_context& ctxt = *c;
@@ -615,8 +615,10 @@ load_corpus_and_write_abixml(char* argv[],
             }
         }
 
-      if (opts.exported_interfaces_only.has_value())
-	env->analyze_exported_interfaces_only(*opts.exported_interfaces_only);
+  // ... if we are asked to only analyze exported interfaces (to stay
+  // concise), then take that into account ...
+  if (opts.exported_interfaces_only.has_value())
+    env.analyze_exported_interfaces_only(*opts.exported_interfaces_only);
 
       t.start();
       corp = dwarf_reader::read_corpus_from_elf(ctxt, s);
@@ -707,7 +709,7 @@ load_corpus_and_write_abixml(char* argv[],
         }
 #endif
       xml_reader::read_context_sptr read_ctxt =
-        create_native_xml_read_context(tmp_file->get_path(), env.get());
+        create_native_xml_read_context(tmp_file->get_path(), env);
 
 #ifdef WITH_DEBUG_SELF_COMPARISON
       if (opts.debug_abidiff
@@ -810,7 +812,7 @@ load_corpus_and_write_abixml(char* argv[],
 /// otherwise.
 static int
 load_kernel_corpus_group_and_write_abixml(char* argv[],
-					  environment_sptr& env,
+					  environment& env,
 					  options& opts)
 {
   if (!(tools_utils::is_dir(opts.in_file_path) && opts.corpus_group_for_linux))
@@ -826,7 +828,7 @@ load_kernel_corpus_group_and_write_abixml(char* argv[],
   suppressions_type supprs;
 
   if (opts.exported_interfaces_only.has_value())
-    env->analyze_exported_interfaces_only(*opts.exported_interfaces_only);
+    env.analyze_exported_interfaces_only(*opts.exported_interfaces_only);
 
   if (opts.do_log)
     emit_prefix(argv[0], cerr)
@@ -861,7 +863,7 @@ corpus::origin origin =
   if (!opts.noout)
     {
       const xml_writer::write_context_sptr& ctxt
-	  = xml_writer::create_write_context(group->get_environment(), cout);
+	  = xml_writer::create_write_context(env, cout);
       set_common_options(*ctxt, opts);
 
       if (!opts.out_file_path.empty())
@@ -983,7 +985,7 @@ main(int argc, char* argv[])
       return 1;
     }
 
-  environment_sptr env(new environment);
+  environment env;
   int exit_code = 0;
 
   if (tools_utils::is_regular_file(opts.in_file_path))
diff --git a/tools/abilint.cc b/tools/abilint.cc
index 087fc45f..55941865 100644
--- a/tools/abilint.cc
+++ b/tools/abilint.cc
@@ -702,7 +702,7 @@ main(int argc, char* argv[])
   if (!maybe_check_suppression_files(opts))
     return 1;
 
-  abigail::ir::environment_sptr env(new abigail::ir::environment);
+  abigail::ir::environment env;
   if (opts.read_from_stdin)
     {
       if (!cin.good())
@@ -711,7 +711,7 @@ main(int argc, char* argv[])
       if (opts.read_tu)
 	{
 	  abigail::translation_unit_sptr tu =
-	    read_translation_unit_from_istream(&cin, env.get());
+	    read_translation_unit_from_istream(&cin, env);
 
 	  if (!tu)
 	    {
@@ -723,7 +723,7 @@ main(int argc, char* argv[])
 	  if (!opts.noout)
 	    {
 	      const write_context_sptr& ctxt
-		  = create_write_context(tu->get_environment(), cout);
+		  = create_write_context(env, cout);
 	      write_translation_unit(*ctxt, *tu, 0);
 	    }
 	  return 0;
@@ -732,14 +732,14 @@ main(int argc, char* argv[])
 	{
 	  abigail::xml_reader::read_context_sptr ctxt =
 	    abigail::xml_reader::create_native_xml_read_context(&cin,
-								env.get());
+								env);
 	  assert(ctxt);
 	  set_suppressions(*ctxt, opts);
 	  corpus_sptr corp = abigail::xml_reader::read_corpus_from_input(*ctxt);
 	  if (!opts.noout)
 	    {
 	      const write_context_sptr& ctxt
-		  = create_write_context(corp->get_environment(), cout);
+		  = create_write_context(env, cout);
 	      write_corpus(*ctxt, corp, /*indent=*/0);
 	    }
 	  return 0;
@@ -768,7 +768,7 @@ main(int argc, char* argv[])
 	  {
 	    abixml_read_ctxt =
 	      abigail::xml_reader::create_native_xml_read_context(opts.file_path,
-								  env.get());
+								  env);
 	    tu = read_translation_unit(*abixml_read_ctxt);
 	  }
 	  break;
@@ -785,7 +785,7 @@ main(int argc, char* argv[])
                 abigail::ctf_reader::read_context_sptr ctxt =
                   abigail::ctf_reader::create_read_context(opts.file_path,
                                                            di_roots,
-                                                           env.get());
+                                                           env);
                 ABG_ASSERT(ctxt);
                 corp = abigail::ctf_reader::read_corpus(ctxt.get(), s);
               }
@@ -794,7 +794,7 @@ main(int argc, char* argv[])
               {
                 abigail::dwarf_reader::read_context_sptr ctxt =
                   abigail::dwarf_reader::create_read_context(opts.file_path,
-                                                             di_roots, env.get(),
+                                                             di_roots, env,
                                                              /*load_all_types=*/false);
                 assert(ctxt);
                 set_suppressions(*ctxt, opts);
@@ -806,7 +806,7 @@ main(int argc, char* argv[])
 	  {
 	    abixml_read_ctxt =
 	      abigail::xml_reader::create_native_xml_read_context(opts.file_path,
-								  env.get());
+								  env);
 	    assert(abixml_read_ctxt);
 	    set_suppressions(*abixml_read_ctxt, opts);
 	    corp = read_corpus_from_input(*abixml_read_ctxt);
@@ -816,7 +816,7 @@ main(int argc, char* argv[])
 	  {
 	    abixml_read_ctxt =
 	      abigail::xml_reader::create_native_xml_read_context(opts.file_path,
-								  env.get());
+								  env);
 	    assert(abixml_read_ctxt);
 	    set_suppressions(*abixml_read_ctxt, opts);
 	    group = read_corpus_group_from_input(*abixml_read_ctxt);
@@ -874,15 +874,6 @@ main(int argc, char* argv[])
 	}
 
       std::ostream& of = opts.diff ? tmp_file->get_stream() : cout;
-      const abigail::ir::environment* env = 0;
-      if (tu)
-	env = tu->get_environment();
-      else if (corp)
-	env = corp->get_environment();
-      else if (group)
-	env = group->get_environment();
-
-      ABG_ASSERT(env);
       const write_context_sptr ctxt = create_write_context(env, of);
 
       bool is_ok = true;
diff --git a/tools/abipkgdiff.cc b/tools/abipkgdiff.cc
index 656d5882..a8f160da 100644
--- a/tools/abipkgdiff.cc
+++ b/tools/abipkgdiff.cc
@@ -1260,7 +1260,7 @@ compare(const elf_file& elf1,
 	const string&	debug_dir2,
 	const suppressions_type& priv_types_supprs2,
 	const options&	opts,
-	abigail::ir::environment_sptr	&env,
+	abigail::ir::environment&	env,
 	corpus_diff_sptr	&diff,
 	diff_context_sptr	&ctxt,
 	abigail::elf_reader::status *detailed_error_status = 0)
@@ -1331,7 +1331,7 @@ compare(const elf_file& elf1,
       {
         ctxt_ctf = abigail::ctf_reader::create_read_context(elf1.path,
 							    di_dirs1,
-                                                            env.get());
+                                                            env);
         ABG_ASSERT(ctxt_ctf);
         corpus1 = abigail::ctf_reader::read_corpus(ctxt_ctf.get(),
                                                    c1_status);
@@ -1339,7 +1339,7 @@ compare(const elf_file& elf1,
     else
 #endif
       {
-        ctxt_dwarf = create_read_context(elf1.path, di_dirs1, env.get(),
+        ctxt_dwarf = create_read_context(elf1.path, di_dirs1, env,
                                          /*load_all_types=*/opts.show_all_types);
         add_read_context_suppressions(*ctxt_dwarf, priv_types_supprs1);
         if (!opts.kabi_suppressions.empty())
@@ -1436,14 +1436,14 @@ compare(const elf_file& elf1,
       {
         ctxt_ctf = abigail::ctf_reader::create_read_context(elf2.path,
 							    di_dirs2,
-							    env.get());
+							    env);
         corpus2 = abigail::ctf_reader::read_corpus(ctxt_ctf.get(),
                                                    c2_status);
       }
     else
 #endif
       {
-        ctxt_dwarf = create_read_context(elf2.path, di_dirs2, env.get(),
+        ctxt_dwarf = create_read_context(elf2.path, di_dirs2, env,
                                          /*load_all_types=*/opts.show_all_types);
         add_read_context_suppressions(*ctxt_dwarf, priv_types_supprs2);
 
@@ -1575,7 +1575,7 @@ static abidiff_status
 compare_to_self(const elf_file& elf,
 		const string&	debug_dir,
 		const options&	opts,
-		abigail::ir::environment_sptr	&env,
+		abigail::ir::environment&	env,
 		corpus_diff_sptr	&diff,
 		diff_context_sptr	&ctxt,
 		abigail::elf_reader::status *detailed_error_status = 0)
@@ -1610,7 +1610,7 @@ compare_to_self(const elf_file& elf,
       {
         ctxt_ctf = abigail::ctf_reader::create_read_context(elf.path,
 							    di_dirs,
-                                                            env.get());
+                                                            env);
         ABG_ASSERT(ctxt_ctf);
         corp = abigail::ctf_reader::read_corpus(ctxt_ctf.get(),
                                                    c_status);
@@ -1619,7 +1619,7 @@ compare_to_self(const elf_file& elf,
 #endif
       {
         ctxt_dwarf =
-         create_read_context(elf.path, di_dirs, env.get(),
+         create_read_context(elf.path, di_dirs, env,
                              /*read_all_types=*/opts.show_all_types);
 
         corp = read_corpus_from_elf(*ctxt_dwarf, c_status);
@@ -1666,7 +1666,7 @@ compare_to_self(const elf_file& elf,
 
     {
       const abigail::xml_writer::write_context_sptr c =
-	abigail::xml_writer::create_write_context(env.get(), of);
+	abigail::xml_writer::create_write_context(env, of);
 
       if (opts.verbose)
 	emit_prefix("abipkgdiff", cerr)
@@ -1697,7 +1697,7 @@ compare_to_self(const elf_file& elf,
     {
       abigail::xml_reader::read_context_sptr c =
 	abigail::xml_reader::create_native_xml_read_context(abi_file_path,
-							    env.get());
+							    env);
       if (!c)
 	{
 	  if (opts.verbose)
@@ -2074,7 +2074,7 @@ public:
   virtual void
   perform()
   {
-    abigail::ir::environment_sptr env(new abigail::ir::environment);
+    abigail::ir::environment env;
     diff_context_sptr ctxt;
     corpus_diff_sptr diff;
 
@@ -2082,7 +2082,7 @@ public:
       abigail::elf_reader::STATUS_UNKNOWN;
 
     if (args->opts.exported_interfaces_only.has_value())
-      env->analyze_exported_interfaces_only
+      env.analyze_exported_interfaces_only
 	(*args->opts.exported_interfaces_only);
 
     status |= compare(args->elf1, args->debug_dir1, args->private_types_suppr1,
@@ -2147,12 +2147,12 @@ public:
   virtual void
   perform()
   {
-    abigail::ir::environment_sptr env(new abigail::ir::environment);
+    abigail::ir::environment env;
     diff_context_sptr ctxt;
     corpus_diff_sptr diff;
 
     if (args->opts.exported_interfaces_only.has_value())
-      env->analyze_exported_interfaces_only
+      env.analyze_exported_interfaces_only
 	(*args->opts.exported_interfaces_only);
 
     abigail::elf_reader::status detailed_status =
@@ -3036,9 +3036,9 @@ compare_prepared_linux_kernel_packages(package& first_package,
   string dist_root1 = first_package.extracted_dir_path();
   string dist_root2 = second_package.extracted_dir_path();
 
-  abigail::ir::environment_sptr env(new abigail::ir::environment);
+  abigail::ir::environment env;
   if (opts.exported_interfaces_only.has_value())
-    env->analyze_exported_interfaces_only
+    env.analyze_exported_interfaces_only
       (*opts.exported_interfaces_only);
 
   suppressions_type supprs;
diff --git a/tools/abisym.cc b/tools/abisym.cc
index 1e2215a6..7b708e42 100644
--- a/tools/abisym.cc
+++ b/tools/abisym.cc
@@ -131,9 +131,9 @@ main(int argc, char* argv[])
 	 && opts.symbol_name != 0);
 
   string p = opts.elf_path, n = opts.symbol_name;
-  environment_sptr env(new environment);
+  environment env;
   vector<elf_symbol_sptr> syms;
-  if (!lookup_symbol_from_elf(env.get(), p, n, opts.demangle, syms))
+  if (!lookup_symbol_from_elf(env, p, n, opts.demangle, syms))
     {
       cout << "could not find symbol '"
 	   << opts.symbol_name
diff --git a/tools/kmidiff.cc b/tools/kmidiff.cc
index f3332765..2a77db7e 100644
--- a/tools/kmidiff.cc
+++ b/tools/kmidiff.cc
@@ -415,10 +415,10 @@ main(int argc, char* argv[])
       return 0;
     }
 
-  environment_sptr env(new environment);
+  environment env;
 
   if (opts.exported_interfaces_only.has_value())
-    env->analyze_exported_interfaces_only(*opts.exported_interfaces_only);
+    env.analyze_exported_interfaces_only(*opts.exported_interfaces_only);
 
   corpus_group_sptr group1, group2;
   string debug_info_root_dir;
@@ -451,7 +451,7 @@ main(int argc, char* argv[])
       else if (ftype == FILE_TYPE_XML_CORPUS_GROUP)
 	group1 =
 	  read_corpus_group_from_native_xml_file(opts.kernel_dist_root1,
-						 env.get());
+						 env);
 
     }
 
@@ -477,7 +477,7 @@ main(int argc, char* argv[])
       else if (ftype == FILE_TYPE_XML_CORPUS_GROUP)
 	group2 =
 	  read_corpus_group_from_native_xml_file(opts.kernel_dist_root2,
-						 env.get());
+						 env);
     }
 
   abidiff_status status = abigail::tools_utils::ABIDIFF_OK;
