diff --git a/src/abg-corpus-priv.h b/src/abg-corpus-priv.h
index 282796e1b685..c8bf7f9d4cf6 100644
--- a/src/abg-corpus-priv.h
+++ b/src/abg-corpus-priv.h
@@ -686,8 +686,6 @@ struct corpus::priv
   symtab_reader::symtab_sptr			symtab_;
   string_elf_symbols_map_sptr			fun_symbol_map;
   string_elf_symbols_map_sptr			undefined_fun_symbol_map;
-  elf_symbols					unrefed_fun_symbols;
-  elf_symbols					unrefed_var_symbols;
   // The type maps contained in this data member are populated if the
   // corpus follows the One Definition Rule and thus if there is only
   // one copy of a type with a given name, per corpus. Otherwise, if
@@ -709,8 +707,10 @@ private:
 
   mutable abg_compat::optional<elf_symbols> sorted_var_symbols;
   mutable abg_compat::optional<elf_symbols> sorted_undefined_var_symbols;
+  mutable abg_compat::optional<elf_symbols> unrefed_var_symbols;
   mutable abg_compat::optional<elf_symbols> sorted_fun_symbols;
   mutable abg_compat::optional<elf_symbols> sorted_undefined_fun_symbols;
+  mutable abg_compat::optional<elf_symbols> unrefed_fun_symbols;
 
 public:
   priv(const string &	p,
@@ -722,9 +722,6 @@ public:
       pub_type_pretty_reprs_()
   {}
 
-  void
-  build_unreferenced_symbols_tables();
-
   type_maps&
   get_types();
 
@@ -737,12 +734,18 @@ public:
   const elf_symbols&
   get_sorted_undefined_fun_symbols() const;
 
+  const elf_symbols&
+  get_unreferenced_function_symbols() const;
+
   const elf_symbols&
   get_sorted_var_symbols() const;
 
   const elf_symbols&
   get_sorted_undefined_var_symbols() const;
 
+  const elf_symbols&
+  get_unreferenced_variable_symbols() const;
+
   unordered_set<interned_string, hash_interned_string>*
   get_public_types_pretty_representations();
 
diff --git a/src/abg-corpus.cc b/src/abg-corpus.cc
index 75f897eb72a8..f9f51a360707 100644
--- a/src/abg-corpus.cc
+++ b/src/abg-corpus.cc
@@ -302,132 +302,6 @@ struct comp_elf_symbols_functor
 
 // <corpus stuff>
 
-
-/// Build the tables of symbols that are not referenced by any
-/// function or variables of corpus::get_functions() or
-/// corpus::get_variables().
-///
-/// Note that this function considers the list of function and
-/// variable symbols to keep, that is provided by
-/// corpus::get_sym_ids_of_fns_to_keep() and
-/// corpus::get_sym_ids_of_vars_to_keep().  If a given unreferenced
-/// function or variable symbol is not in the list of variable and
-/// function symbols to keep, then that symbol is dropped and will not
-/// be part of the resulting table of unreferenced symbol that is
-/// built.
-///
-/// The built tables are accessible from
-/// corpus::get_unreferenced_function_symbols() and
-/// corpus::get_unreferenced_variable_symbols().
-void
-corpus::priv::build_unreferenced_symbols_tables()
-{
-  unordered_map<string, bool> refed_funs, refed_vars;
-  elf_symbol_sptr sym;
-
-  for (vector<function_decl*>::const_iterator f = fns.begin();
-       f != fns.end();
-       ++f)
-    if ((sym = (*f)->get_symbol()))
-      {
-	refed_funs[sym->get_id_string()] = true;
-	for (elf_symbol_sptr a = sym->get_next_alias();
-	     a && !a->is_main_symbol();
-	     a = a->get_next_alias())
-	  refed_funs[a->get_id_string()] = true;
-      }
-
-  for (vector<var_decl*>::const_iterator v = vars.begin();
-       v != vars.end();
-       ++v)
-    if ((sym = (*v)->get_symbol()))
-      {
-	refed_vars[sym->get_id_string()] = true;
-	for (elf_symbol_sptr a = sym->get_next_alias();
-	     a && !a->is_main_symbol();
-	     a = a->get_next_alias())
-	  refed_vars[a->get_id_string()] = true;
-      }
-
-  if (fun_symbol_map)
-    {
-      // Let's assume that the size of the unreferenced symbols vector
-      // is roughly smaller than the size of the symbol table.
-      unrefed_fun_symbols.reserve(fun_symbol_map->size());
-      for (string_elf_symbols_map_type::const_iterator i
-	     = fun_symbol_map->begin();
-	   i != fun_symbol_map->end();
-	   ++i)
-	for (elf_symbols::const_iterator s = i->second.begin();
-	     s != i->second.end();
-	     ++s)
-	  {
-	    string sym_id = (*s)->get_id_string();
-	    if (refed_funs.find(sym_id) == refed_funs.end())
-	      {
-		bool keep = sym_id_fns_to_keep.empty();
-		for (vector<string>::const_iterator i =
-		       sym_id_fns_to_keep.begin();
-		     i != sym_id_fns_to_keep.end();
-		     ++i)
-		  {
-		    if (*i == sym_id)
-		      {
-			keep = true;
-			break;
-		      }
-		  }
-		if (keep)
-		  unrefed_fun_symbols.push_back(*s);
-	      }
-	  }
-
-      comp_elf_symbols_functor comp;
-      std::sort(unrefed_fun_symbols.begin(),
-		unrefed_fun_symbols.end(),
-		comp);
-    }
-
-  if (var_symbol_map)
-    {
-      // Let's assume that the size of the unreferenced symbols vector
-      // is roughly smaller than the size of the symbol table.
-      unrefed_var_symbols.reserve(var_symbol_map->size());
-      for (string_elf_symbols_map_type::const_iterator i
-	     = var_symbol_map->begin();
-	   i != var_symbol_map->end();
-	   ++i)
-	for (elf_symbols::const_iterator s = i->second.begin();
-	     s != i->second.end();
-	     ++s)
-	  {
-	    string sym_id = (*s)->get_id_string();
-	    if (refed_vars.find(sym_id) == refed_vars.end())
-	      {
-		bool keep = sym_id_vars_to_keep.empty();
-		for (vector<string>::const_iterator i =
-		       sym_id_vars_to_keep.begin();
-		     i != sym_id_vars_to_keep.end();
-		     ++i)
-		  {
-		    if (*i == sym_id)
-		      {
-			keep = true;
-			break;
-		      }
-		  }
-		if (keep)
-		  unrefed_var_symbols.push_back(*s);
-	      }
-	  }
-
-      comp_elf_symbols_functor comp;
-      std::sort(unrefed_var_symbols.begin(),
-		unrefed_var_symbols.end(),
-		comp);
-    }
-}
-
 /// Get the maps that associate a name to a certain kind of type.
 type_maps&
 corpus::priv::get_types()
@@ -478,6 +352,59 @@ corpus::priv::get_sorted_undefined_fun_symbols() const
   return *sorted_undefined_fun_symbols;
 }
 
+/// Return a list of symbols that are not referenced by any function of
+/// corpus::get_functions().
+///
+/// Note that this function considers the list of function symbols to keep,
+/// that is provided by corpus::get_sym_ids_of_fns_to_keep(). If a given
+/// unreferenced function symbol is not in the list of functions to keep, then
+/// that symbol is dropped and will not be part of the resulting table of
+/// unreferenced symbol that is built.
+const elf_symbols&
+corpus::priv::get_unreferenced_function_symbols() const
+{
+  if (!unrefed_fun_symbols)
+    {
+      unrefed_fun_symbols = elf_symbols();
+      if (symtab_)
+	{
+	  unordered_map<string, bool> refed_funs;
+
+	  for (const auto& function : fns)
+	    if (elf_symbol_sptr sym = function->get_symbol())
+	      {
+		refed_funs[sym->get_id_string()] = true;
+		for (elf_symbol_sptr a = sym->get_next_alias();
+		     a && !a->is_main_symbol(); a = a->get_next_alias())
+		  refed_funs[a->get_id_string()] = true;
+	      }
+
+	  auto filter = symtab_->make_filter();
+	  filter.set_functions();
+	  for (const auto& symbol :
+	       symtab_reader::filtered_symtab(*symtab_, filter))
+	    {
+	      const std::string sym_id = symbol->get_id_string();
+	      if (refed_funs.find(sym_id) == refed_funs.end())
+		{
+		  bool keep = sym_id_fns_to_keep.empty();
+		  for (const auto& id : sym_id_fns_to_keep)
+		    {
+		      if (id == sym_id)
+			{
+			  keep = true;
+			  break;
+			}
+		    }
+		  if (keep)
+		    unrefed_fun_symbols->push_back(symbol);
+		}
+	    }
+	}
+    }
+  return *unrefed_fun_symbols;
+}
+
 /// Getter for the sorted vector of variable symbols for this corpus.
 ///
 /// Note that the first time this function is called, it computes the
@@ -519,6 +446,59 @@ corpus::priv::get_sorted_undefined_var_symbols() const
   return *sorted_undefined_var_symbols;
 }
 
+/// Return a list of symbols that are not referenced by any variable of
+/// corpus::get_variables().
+///
+/// Note that this function considers the list of variable symbols to keep,
+/// that is provided by corpus::get_sym_ids_of_vars_to_keep(). If a given
+/// unreferenced variable symbol is not in the list of variable to keep, then
+/// that symbol is dropped and will not be part of the resulting table of
+/// unreferenced symbol that is built.
+const elf_symbols&
+corpus::priv::get_unreferenced_variable_symbols() const
+{
+  if (!unrefed_var_symbols)
+    {
+      unrefed_var_symbols = elf_symbols();
+      if (symtab_)
+	{
+	  unordered_map<string, bool> refed_vars;
+	  for (const auto& variable : vars)
+	    if (elf_symbol_sptr sym = variable->get_symbol())
+	      {
+		refed_vars[sym->get_id_string()] = true;
+		for (elf_symbol_sptr a = sym->get_next_alias();
+		     a && !a->is_main_symbol(); a = a->get_next_alias())
+		  refed_vars[a->get_id_string()] = true;
+	      }
+
+	  auto filter = symtab_->make_filter();
+	  filter.set_variables();
+	  for (const auto& symbol :
+	       symtab_reader::filtered_symtab(*symtab_, filter))
+	    {
+	      const std::string sym_id = symbol->get_id_string();
+	      if (refed_vars.find(sym_id) == refed_vars.end())
+		{
+		  bool keep = sym_id_vars_to_keep.empty();
+		  for (const auto& id : sym_id_vars_to_keep)
+		    {
+		      if (id == sym_id)
+			{
+			  keep = true;
+			  break;
+			}
+		    }
+		  if (keep)
+		    unrefed_var_symbols->push_back(symbol);
+		}
+	    }
+	}
+    }
+  return *unrefed_var_symbols;
+}
+
+
 /// Getter of the set of pretty representation of types that are
 /// reachable from public interfaces (global functions and variables).
 ///
@@ -1310,12 +1290,7 @@ corpus::sort_variables()
 /// function exported by the current corpus.
 const elf_symbols&
 corpus::get_unreferenced_function_symbols() const
-{
-  if (priv_->unrefed_fun_symbols.empty()
-      && priv_->unrefed_var_symbols.empty())
-    priv_->build_unreferenced_symbols_tables();
-  return priv_->unrefed_fun_symbols;
-}
+{ return priv_->get_unreferenced_function_symbols(); }
 
 /// Getter of the set of variable symbols that are not referenced by
 /// any variable exported by the current corpus.
@@ -1328,12 +1303,7 @@ corpus::get_unreferenced_function_symbols() const
 /// variable exported by the current corpus.
 const elf_symbols&
 corpus::get_unreferenced_variable_symbols() const
-{
-    if (priv_->unrefed_fun_symbols.empty()
-      && priv_->unrefed_var_symbols.empty())
-    priv_->build_unreferenced_symbols_tables();
-  return priv_->unrefed_var_symbols;
-}
+{ return priv_->get_unreferenced_variable_symbols(); }
 
 /// Accessor for the regex patterns describing the functions to drop
 /// from the public decl table.
