public inbox for libabigail@sourceware.org
 help / color / mirror / Atom feed
From: Dodji Seketeli <dodji@redhat.com>
To: gprocida@google.com
Cc: woodard@redhat.com,  guillermo.e.martinez@oracle.com,
	jose.marchesi@oracle.com,  dodji@redhat.com,
	libabigail@sourceware.org
Subject: [PATCH 1/2] Use environment by reference
Date: Wed, 16 Nov 2022 18:28:55 +0100	[thread overview]
Message-ID: <87cz9molk8.fsf@redhat.com> (raw)
In-Reply-To: <87k03uom03.fsf@redhat.com> (Dodji Seketeli's message of "Wed, 16 Nov 2022 18:19:24 +0100")

Hello,

This patch simplifies how the environment is created and passed around
the functions that create front ends.  With this change, the
environment can simply be allocated on the stack and passed by
reference to the libabigail pipeline.

At the core of this change, type_or_decl_base::priv now carries a
const reference to an environment rather than a pointer.  The side
effect is that type_or_decl_base can no longer be copied.  This is not
a problem because throughout the years I could see that the use case
to copy ABI artifacts is just not there.  Similarly, elf_symbol::priv
carries a const reference to environment now, no more a pointer.
Getters, setters and code that use the environment from the ABI
artifacts are updated accordingly.

The DWARF front-end can now be created by code that looks like this,
for instance:

    vector<char**> debug_info_paths;
    abigail::ir::environment env;

    abigail::ctf_reader::read_context_sptr reader =
      abigail::dwarf_reader::create_read_context("elf/file/to/analyze",
						 debug_info_paths, env);

    elf_reader::status reading_status;
    corpus_sptr abi_corpus =
      abigail::dwarf_reader::read_corpus_from_elf(reader, reading_status);

	/* then do something with the resulting abi_corpus*/

Note how, you don't need to use the "new" operator to instantiate the
"env" object of type environment.  It can sit on the stack and it's
passed to the read_corpus_from_elf function by reference.

In other words, the internal representation types have been changed to
refer to the environment by reference, rather than requiring a pointer
to it.

	* include/abg-corpus.h (corpus::corpus)
	(corpus_group::corpus_group): Take environment&, not environment*
	as parameter.
	(corpus::{get_environment, set_environment}): Take or return
	environment&, not environment*.
	* src/abg-corpus.cc (corpus::corpus): Likewise.
	(corpus::{get_environment, set_environment}): Likewise.
	(corpus::add): Don't update the environment of the translation
	unit.
	(corpus::{record_type_as_reachable_from_public_interfaces,
	type_is_reachable_from_public_interfaces, init_format_version,
	add_corpus}): Adjust for accessing a reference to environment,
	rather than a pointer.
	* include/abg-ctf-reader.h (create_read_context): Take or return
	environment&, not environment*.
	* src/abg-ctf-reader.cc (read_context::ir_env): Make this a
	reference to environment, not pointer anymore.
	(read_context::read_context): Initialize the reference to
	environment.
	(read_context::initialize): Do not re-set the environment.
	(process_ctf_base_type)
	(build_ir_node_for_variadic_parameter_type)
	(process_ctf_enum_type, read_corpus): Adjust for accessing a
	reference to environment, rather than a pointer.
	(create_read_context, reset_read_context): Take environment&, not
	environment*.
	* include/abg-dwarf-reader.h (create_read_context)
	(reset_read_context, read_corpus_from_elf)
	(lookup_symbol_from_elf, lookup_public_function_symbol_from_elf):
	Likewise.
	* src/abg-dwarf-reader.cc (lookup_symbol_from_sysv_hash_tab)
	(lookup_symbol_from_gnu_hash_tab)
	(lookup_symbol_from_elf_hash_tab, lookup_symbol_from_symtab)
	(lookup_symbol_from_elf, lookup_public_function_symbol_from_elf):
	Likewise.
	(read_context::options_type::env): Make this be a reference to
	environment, not a pointer.
	(read_context::options::options): Remove the default constructor.
	Add a new one to initialize the environment data member.
	(read_context::read_context): Take environment&, not environment*.
	Initialize the options_ data member.
	(read_context::initialize): Do not take or initialize an
	environment anymore.
	(read_context::env): Return or take environment&, not
	environment*.
	(read_context::{get_die_qualified_name,
	get_die_qualified_type_name, get_die_pretty_type_representation,
	get_die_pretty_representation, compare_before_canonicalisation})
	(build_translation_unit_and_add_to_ir, build_function_type)
	(build_typedef_type, read_debug_info_into_corpus)
	(read_debug_info_into_corpus, build_ir_node_from_die)
	(build_ir_node_for_variadic_parameter_type, has_alt_debug_info):
	Adjust to use an environment&, not a pointer.
	(create_default_fn_sym, create_read_context)
	(read_corpus_from_elf, lookup_symbol_from_elf)
	(lookup_public_function_symbol_from_elf): Take environment&, not
	environment*.
	(reset_read_context): Do not take or reset environment* anymore.
	* include/abg-fwd.h (type_or_void): Likewise.
	* include/abg-ir.h (translation_unit::translation_unit): Likewise.
	(translation_unit::{get_environment, set_environment}): Likewise.
	(elf_symbol::elf_symbol): Likewise.
	(elf_symbol::create): Remove the overload that takes no
	parameter.  Then for overload that take parameters then take
	environment&, not environment*.
	(elf_symbol::get_environment): Take environment&, not
	environment*.
	(type_or_decl_base::type_or_decl_base): Make the copy constructor
	and assignment operator private.
	(type_or_decl_base::{s,g}et_environment): Take or return
	environment& not environment*.
	(type_or_decl_base::set_environment_for_artifact): Erase these
	methods.
	(decl_base::decl_base): Make copy constructor private.  Take or
	return environment&, not environment* for the other constructors.
	(scope_decl::scope_decl): Take or return environment&, not
	environment*.
	(type_base::type_base): Likewise.
	(scope_type_decl::scope_type_decl): Likewise.
	(namespace_decl::namespace_decl): Likewise.
	(qualified_type_def::qualified_type_def): Likewise.
	(pointer_type_def::pointer_type_def): Likewise.
	(reference_type_def::reference_type_def): Likewise.
	(array_type_def::subrange_type::subrange_type): Likewise.
	(enum_type_def::enumerator::enumerator): Likewise.
	(enum_type_def::enumerator::{get_name, get_qualified_name}):
	Return a string&, no more interned_string&.  As the enumerator
	don't have an enumerator anymore, there is no way to intern the
	string anymore.  Hopefully this won't incur a performance loss.
	(typedef_decl::typedef_decl, function_type::function_type)
	(method_type::method_type, template_decl::template_decl)
	(function_tdecl::function_tdecl, class_tdecl::class_tdecl)
	(class_or_union::class_or_union, class_decl::class_decl)
	(union_decl::union_decl): Take or return environment&, not
	environment*.
	* include/abg-reader.h (read_translation_unit_from_file)
	(read_translation_unit_from_buffer)
	(read_translation_unit_from_istream)
	(create_native_xml_read_context, create_native_xml_read_context)
	(read_corpus_from_native_xml, read_corpus_from_native_xml_file)
	(read_corpus_group_from_native_xml)
	(read_corpus_group_from_native_xml_file): Likewise.
	* include/abg-tools-utils.h
	(build_corpus_group_from_kernel_dist_under): Likewise.
	* src/abg-tools-utils.cc (maybe_load_vmlinux_dwarf_corpus)
	(maybe_load_vmlinux_ctf_corpus)
	(build_corpus_group_from_kernel_dist_under): Likewise.
	* include/abg-writer.h (create_write_context): Likewise.
	* src/abg-writer.cc (id_manager::m_env, id_manager::id_manager)
	(id_manager::get_environment, id_manager::get_id)
	(id_manager::get_id_with_prefix): Adjust.
	(write_context::m_env, write_context::write_context)
	(write_context::get_environment, write_context::get_config)
	(write_context::get_id_for_type, write_context::decl_is_emitted)
	(write_context::record_decl_as_emitted, create_write_context)
	(write_class_decl): Likewise.
	* src/abg-comparison.cc (compute_diff): Stop ensuring that the two
	artifacts being compare are in the same environment.  Now that the
	environment is passed by reference, the potential for
	accendentally comparing artifacts coming from different
	environments is very low, given how the API is used in practice.
	This is in the overloads for decl_base_sptr, type_base_sptr,
	var_decl_sptr, pointer_type_def_sptr, array_type_def_sptr,
	reference_type_def_sptr, qualified_type_def_sptr,
	enum_type_decl_sptr, class_decl_sptr, class_decl::base_spec_sptr,
	union_decl_sptr, scope_decl_sptr, function_decl::parameter_sptr,
	function_type_sptr, function_decl_sptr, type_decl_sptr,
	typedef_decl_sptr, translation_unit_sptr, corpus_sptr.
	* src/abg-corpus-priv.h (corpus::priv::env): Make this be a
	reference to environments, not a pointer.
	(corpus::priv::priv): Pass environment&, not environment*.
	* src/abg-ir-priv.h (translation_unit::priv::env_): Make this an
	environment&, not an environment* anymore.
	(translation_unit::priv::priv): Take an environment&, not an
	environment*.
	(environment::priv::{confirm_ct_propagation_for_types_dependant_on,
	confirm_ct_propagation,
	cancel_ct_propagation_for_types_dependant_on,
	mark_as_being_compared, unmark_as_being_compared,
	comparison_started, mark_as_being_compared, comparison_started}):
	Adjust to use an environment&, not a pointer.
	* src/abg-ir.cc (class environment_setter): Remove this class.
	(push_composite_type_comparison_operands)
	(pop_composite_type_comparison_operands, try_canonical_compare)
	(return_comparison_result, translation_unit::{get_global_scope,
	bind_function_type_life_time}): Adjust.
	(translation_unit::{translation_unit, get_environment}): Take or
	get an environment&, not an environment*.  Remove the getter that
	returns an environment*.
	(elf_symbol::priv::env_): Make this an environment&, not an
	environment*.
	(elf_symbol::priv::priv): Adjust.
	(elf_symbol::elf_symbol): Remove the default constructor.  Change
	the one that takes an environment.
	(elf_symbol::create): Remove the default one.  Adjust the one that
	takes an environment.
	(elf_symbol::get_environment): Adjust.
	(elf_symbol::set_environment_for_artifact): Remove.
	(environment::{get_void_type, get_variadic_parameter_type}):
	Adjust.
	(type_or_decl_base::priv::env_): Make this be a const
	environment&, not a const environment*.
	(type_or_decl_base::priv::priv): Adjust.
	(type_or_decl_base::type_or_decl_base): Remove the default and
	copy constructor.
	(type_or_decl_base::{set_environment, operator=})
	(set_environment_for_artifact): Remove.
	(type_or_decl_base::get_environment): Adjust.
	(decl_base::{decl_base, set_name, set_naming_typedef,
	set_linkage_name}): Adjust.
	(get_decl_name_for_comparison, strip_typedef)
	(strip_useless_const_qualification): Adjust.
	(scope_decl::{scope_decl, add_member_decl, insert_member_decl}):
	Adjust.
	(get_generic_anonymous_internal_type_name, get_type_name)
	(get_name_of_pointer_to_type, get_name_of_reference_to_type)
	(get_name_of_qualified_type, get_function_type_name)
	(get_method_type_name, is_void_pointer_type, lookup_basic_type)
	(lookup_union_type, lookup_union_type_per_location)
	(lookup_enum_type, lookup_typedef_type, lookup_pointer_type)
	(lookup_type, lookup_basic_type_per_location)
	(lookup_basic_type_per_location, lookup_basic_type)
	(lookup_class_type, lookup_class_types)
	(lookup_class_type_per_location, lookup_union_type)
	(lookup_enum_type, lookup_enum_types)
	(lookup_enum_type_per_location, lookup_typedef_type)
	(lookup_typedef_type_per_location, maybe_update_types_lookup_map)
	(maybe_update_types_lookup_map)
	(synthesize_type_from_translation_unit)
	(synthesize_function_type_from_translation_unit)
	(demangle_cplus_mangled_name, type_or_void)
	(types_defined_same_linux_kernel_corpus_public)
	(compare_types_during_canonicalization)
	(type_base::get_canonical_type_for, type_base::type_base)
	(type_base::get_cached_pretty_representation)
	(type_decl::type_decl, type_decl::get_qualified_name): Adjust.
	(scope_type_decl::scope_type_decl)
	(namespace_decl::namespace_decl, qualified_type_def::build_name)
	(qualified_type_def::qualified_type_def)
	(qualified_type_def::get_qualified_name)
	(qualified_type_def::set_underlying_type)
	(pointer_type_def::pointer_type_def)
	(pointer_type_def::set_pointed_to_type)
	(reference_type_def::reference_type_def)
	(reference_type_def::set_pointed_to_type)
	(array_type_def::subrange_type::subrange_type)
	(array_type_def::array_type_def, array_type_def::update_size)
	(array_type_def::set_element_type)
	(array_type_def::append_subranges)
	(array_type_def::get_qualified_name, enum_has_non_name_change):
	Adjust.
	(enum_type_decl::enumerator::priv::env_): Remove this pointer to
	env.  This is because the enumerator must be copy-able.  As the
	enumerator doesn't have an env anymore, it can't intern strings.
	So the enumerator name and qualified name is not going to be
	interned.  If that incurs a performance hit, we'll reconsider this
	decision.  For now, it seems to work OK.  As it simplifies things,
	I am keeping this for now.
	(enum_type_decl::enumerator::priv::{name, qualified_name}): Make
	this be string, not interned_string.
	(enum_type_decl::enumerator::get_environment): Remove.
	(enum_type_decl::enumerator::priv::priv): Adjust.
	(enum_type_decl::enumerator::enumerator)
	(enum_type_decl::enumerator::operator=)
	(enum_type_decl::enumerator::get_name)
	(enum_type_decl::enumerator::get_qualified_name)
	(enum_type_decl::enumerator::set_name): Likewise.
	(typedef_decl::typedef_decl): Adjust.
	(var_decl::get_id, var_decl::get_qualified_name): Adjust.
	(function_type::function_type, method_type::method_type)
	(function_decl::get_pretty_representation_of_declarator)
	(function_decl::set_symbol): Likewise.
	(function_decl::get_id, function_decl::parameter::get_type)
	(function_decl::parameter::get_type_name)
	(function_decl::parameter::get_type_pretty_representation)
	(function_decl::parameter::get_name_id)
	(class_or_union::class_or_union, class_decl::class_decl)
	(class_decl::add_base_specifier, union_decl::union_decl)
	(union_decl::union_decl, template_decl::template_decl)
	(class_tdecl::class_tdecl)
	(maybe_cancel_propagated_canonical_type)
	(dump_classes_being_compared)
	(dump_fn_types_being_compared, copy_member_function)
	(maybe_propagate_canonical_type, keep_type_alive)
	(is_non_canonicalized_type, qualified_name_setter::do_update):
	Likewise.
	(equals): Adjust the overloads for var_decl, function_type,
	class_or_union, class_decl, union_decl.
	* src/abg-reader.cc (read_context::m_env): Make this be an
	environment&, not an environment*.
	(read_context::read_context): Adjust
	(read_context::set_environment): Remove.
	(read_context::{get_environment,
	maybe_check_abixml_canonical_type_stability}): Adjust.
	(read_corpus_from_input, read_corpus_group_from_native_xml)
	(read_corpus_group_from_native_xml_file)
	(read_translation_unit_from_file)
	(read_translation_unit_from_buffer, read_translation_unit)
	(maybe_map_type_with_type_id, build_namespace_decl)
	(build_elf_symbol, build_function_parameter, build_function_decl)
	(build_function_type, build_enum_type_decl, build_class_decl)
	(build_union_decl, build_function_tdecl, build_class_tdecl)
	(build_type_tparameter, read_translation_unit_from_istream)
	(create_native_xml_read_context, read_corpus_from_native_xml):
	Likewise.
	* src/abg-symtab-reader.h (symtab::load): Likewise.
	* src/abg-symtab-reader.cc (symtab::load): Likewise.
	* tests/print-diff-tree.cc (main): Likewise.
	* tests/test-abidiff.cc (main): Likewise.
	* tests/test-diff-dwarf.cc (main): Likewise.
	* tests/test-ir-walker.cc (main): Likewise.
	* tests/test-read-ctf.cc (test_task_ctf::perform): Likewise.
	* tests/test-symtab.cc (read_corpus): Likewise.
	* tools/abicompat.cc (read_corpus, main): Likewise.
	* tools/abidiff.cc (main): Likewise.
	* tools/abidw.cc (load_corpus_and_write_abixml)
	(load_kernel_corpus_group_and_write_abixml, main): Likewise.
	* tools/abilint.cc (main): Likewise.
	* tools/abipkgdiff.cc (compare, compare_to_self)
	(compare_prepared_linux_kernel_packages,  compare_task::perform):
	Likewise.
	* tools/abisym.cc (main): Likewise.
	* tools/kmidiff.cc (main): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
---
 include/abg-corpus.h       |  12 +-
 include/abg-ctf-reader.h   |   5 +-
 include/abg-dwarf-reader.h |   9 +-
 include/abg-fwd.h          |   2 +-
 include/abg-ir.h           | 154 +++----
 include/abg-reader.h       |  19 +-
 include/abg-tools-utils.h  |   2 +-
 include/abg-writer.h       |   2 +-
 src/abg-comparison.cc      |  67 +--
 src/abg-corpus-priv.h      |   6 +-
 src/abg-corpus.cc          |  58 +--
 src/abg-ctf-reader.cc      |  32 +-
 src/abg-dwarf-reader.cc    | 115 +++---
 src/abg-ir-priv.h          |  57 ++-
 src/abg-ir.cc              | 815 +++++++++++++------------------------
 src/abg-reader.cc          | 132 +++---
 src/abg-symtab-reader.cc   |   5 +-
 src/abg-symtab-reader.h    |   6 +-
 src/abg-tools-utils.cc     |  27 +-
 src/abg-writer.cc          |  39 +-
 tests/print-diff-tree.cc   |   6 +-
 tests/test-abidiff.cc      |  14 +-
 tests/test-diff-dwarf.cc   |   6 +-
 tests/test-ir-walker.cc    |   4 +-
 tests/test-read-ctf.cc     |   5 +-
 tests/test-symtab.cc       |   4 +-
 tools/abicompat.cc         |  10 +-
 tools/abidiff.cc           |  28 +-
 tools/abidw.cc             |  28 +-
 tools/abilint.cc           |  29 +-
 tools/abipkgdiff.cc        |  32 +-
 tools/abisym.cc            |   4 +-
 tools/kmidiff.cc           |   8 +-
 33 files changed, 642 insertions(+), 1100 deletions(-)

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;
-- 
2.38.0



-- 
		Dodji


  reply	other threads:[~2022-11-16 17:29 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-16 17:19 [PATCH 0/2, v2] Make front-ends be first class in the libabigail framework Dodji Seketeli
2022-11-16 17:28 ` Dodji Seketeli [this message]
2022-11-17 14:17   ` [PATCH 1/2] Use environment by reference Giuliano Procida
2022-11-17 15:35     ` Dodji Seketeli
2022-11-16 17:29 ` [PATCH 2/2] Make Front Ends first class citizens Dodji Seketeli
2022-11-18 17:19 ` [PATCH 0/2, v2] Make front-ends be first class in the libabigail framework Dodji Seketeli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87cz9molk8.fsf@redhat.com \
    --to=dodji@redhat.com \
    --cc=gprocida@google.com \
    --cc=guillermo.e.martinez@oracle.com \
    --cc=jose.marchesi@oracle.com \
    --cc=libabigail@sourceware.org \
    --cc=woodard@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).