[applied] dwarf-reader: Simplify the canonicalization decision of types added to IR

Message ID 878rmxkcil.fsf@redhat.com
State New
Headers
Series [applied] dwarf-reader: Simplify the canonicalization decision of types added to IR |

Commit Message

Dodji Seketeli Sept. 5, 2022, 4:32 p.m. UTC
  Hello,

This is a long overdue clean-up.

Back in the day when we had no DWARF type DIE canonicalization, there
could be a LOT of IR types to be canonicalized.  To store set of those
types to be canonicalized, we the used the already existing
association type DIE offset -> IR types that we had, and so we only
had to store the DIE offsets of the IR types that we wanted to
canonicalize.  At canonicalization time, we'd walk the set of DIE
offsets we stored on the side, use the association type DIE offset ->
IR types to retrieve the IR type to canonicalize and we'd canonicalize
it.  This is somewhat complicated.

Now that we have DWARF DIEs canonicalization, the number of IR types
dropped significantly so this complicated scheme is no more warranted.

So this patch drops that indirection and stores the IR types to be
canonicalize into a vector of IR types and that's it.  Yay, less code.

	* src/abg-dwarf-reader.cc (maybe_canonicalize_type): Remove
	the overload that takes a Dwarf_Die* parameter.
	(operator++(die_source& source)): Likewise.
	(read_context::{types_to_canonicalize_,
	alt_types_to_canonicalize_,
	type_unit_types_to_canonicalize_}): Remove these data members
	of type vector<Dwarf_Off>.  (read_context::initialize): Remove
	invocations to alt_types_to_canonicalize_.clear(),
	type_unit_types_to_canonicalize_.clear(), and
	extra_types_to_canonicalize_.clear().
	(read_context::extra_types_to_canonicalize_): Rename this into
	read_context::types_to_canonicalize_, of type
	vector<type_base_sptr>.
	(read_context::types_to_canonicalize): Remove these member
	functions that take a parameter of type die_source.
	(read_context::extra_types_to_canonicalize): Rename this
	function into types_to_canonicalize.  It returns a type const
	vector<type_base_sptr>&.
	(read_context::schedule_type_for_late_canonicalization):
	Remove this overload that takes a type const Dwarf_Die*.  In
	the overload that takes a parameter const type_base_sptr
	however, rename the invocation to
	extra_types_to_canonicalize_.push_back(t) into
	types_to_canonicalize_.push_back(t).
	(read_context::canonicalize_types_scheduled): This doesn't
	take a die_source parameter anymore.  It now only cycles
	through the types retrieved by types_to_canonicalize() to
	canonicalize them.
	(read_context::add_late_canonicalized_types_stats): Remove the
	die_source parameter.  Use types_to_canonicalize().
	(read_context::perform_late_type_canonicalizing): Just call
	read_context::canonicalize_types_scheduled().
	(build_ir_node_from_die): Adjust calls to maybe_canonicalize_type.
	Also, really canonicalize the function type when a function decl is
	constructed.
	* tests/data/test-annotate/test13-pr18894.so.abi: Adjust.
	* tests/data/test-annotate/test15-pr18892.so.abi: Likewise.
	* tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-annotate/test21-pr19092.so.abi: Likewise.
	* tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt:
	Likewise.
	* tests/data/test-read-dwarf/PR22122-libftdc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.
	* tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi:
	Likewise.
	* tests/data/test-read-dwarf/test21-pr19092.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Applied to master.

---
 src/abg-dwarf-reader.cc                       | 300 ++----------------
 .../data/test-annotate/test13-pr18894.so.abi  |  36 +--
 .../data/test-annotate/test15-pr18892.so.abi  |  74 ++---
 ...st20-pr19025-libvtkParallelCore-6.1.so.abi |  10 +-
 .../data/test-annotate/test21-pr19092.so.abi  |  36 +--
 .../nss-3.23.0-1.0.fc23.x86_64-report-0.txt   |   4 +-
 .../test-read-dwarf/PR22122-libftdc.so.abi    |  34 +-
 .../test-read-dwarf/test12-pr18844.so.abi     |   6 +-
 .../test-read-dwarf/test13-pr18894.so.abi     |  20 +-
 .../test-read-dwarf/test15-pr18892.so.abi     |  40 +--
 .../test-read-dwarf/test16-pr18904.so.abi     |  10 +-
 ...st20-pr19025-libvtkParallelCore-6.1.so.abi |   6 +-
 .../test-read-dwarf/test21-pr19092.so.abi     |  20 +-
 13 files changed, 179 insertions(+), 417 deletions(-)
  

Patch

diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc
index 35027c57..56909540 100644
--- a/src/abg-dwarf-reader.cc
+++ b/src/abg-dwarf-reader.cc
@@ -91,17 +91,6 @@  enum die_source
 				// enumerator
 };
 
-/// Prefix increment operator for @ref die_source.
-///
-/// @param source the die_source to increment.
-/// @return the incremented source.
-static die_source&
-operator++(die_source& source)
-{
-  source = static_cast<die_source>(source + 1);
-  return source;
-}
-
 /// A functor used by @ref dwfl_sptr.
 struct dwfl_deleter
 {
@@ -519,10 +508,6 @@  die_pretty_print(read_context& ctxt,
 		 const Dwarf_Die* die,
 		 size_t where_offset);
 
-static void
-maybe_canonicalize_type(const Dwarf_Die* die,
-			read_context& ctxt);
-
 static void
 maybe_canonicalize_type(const type_base_sptr&	t,
 			read_context&		ctxt);
@@ -2125,10 +2110,7 @@  public:
   die_function_type_map_type	alternate_die_wip_function_types_map_;
   die_function_type_map_type	type_unit_die_wip_function_types_map_;
   die_function_decl_map_type	die_function_with_no_symbol_map_;
-  vector<Dwarf_Off>		types_to_canonicalize_;
-  vector<Dwarf_Off>		alt_types_to_canonicalize_;
-  vector<Dwarf_Off>		type_unit_types_to_canonicalize_;
-  vector<type_base_sptr>	extra_types_to_canonicalize_;
+  vector<type_base_sptr>	types_to_canonicalize_;
   string_classes_map		decl_only_classes_map_;
   string_enums_map		decl_only_enums_map_;
   die_tu_map_type		die_tu_map_;
@@ -2274,9 +2256,6 @@  public:
     type_unit_die_wip_function_types_map_.clear();
     die_function_with_no_symbol_map_.clear();
     types_to_canonicalize_.clear();
-    alt_types_to_canonicalize_.clear();
-    type_unit_types_to_canonicalize_.clear();
-    extra_types_to_canonicalize_.clear();
     decl_only_classes_map_.clear();
     die_tu_map_.clear();
     cur_corpus_group_.reset();
@@ -4677,38 +4656,6 @@  public:
     fns_with_no_symbol.clear();
   }
 
-  /// Return a reference to the vector containing the offsets of the
-  /// types that need late canonicalizing.
-  ///
-  /// @param source whe DIEs referred to by the offsets contained in
-  /// the vector to return are from.
-  vector<Dwarf_Off>&
-  types_to_canonicalize(die_source source)
-  {
-    switch (source)
-      {
-      case PRIMARY_DEBUG_INFO_DIE_SOURCE:
-	break;
-      case ALT_DEBUG_INFO_DIE_SOURCE:
-	return alt_types_to_canonicalize_;
-      case TYPE_UNIT_DIE_SOURCE:
-	return type_unit_types_to_canonicalize_;
-      case NO_DEBUG_INFO_DIE_SOURCE:
-      case NUMBER_OF_DIE_SOURCES:
-	ABG_ASSERT_NOT_REACHED;
-      }
-    return types_to_canonicalize_;
-  }
-
-  /// Return a reference to the vector containing the offsets of the
-  /// types that need late canonicalizing.
-  ///
-  /// @param source where the DIEs referred to by the offset in the
-  /// returned vector are from.
-  const vector<Dwarf_Off>&
-  types_to_canonicalize(die_source source) const
-  {return const_cast<read_context*>(this)->types_to_canonicalize(source);}
-
   /// Return a reference to the vector containing the types created
   /// during the binary analysis but that are not tied to a given
   /// DWARF DIE.
@@ -4717,48 +4664,14 @@  public:
   /// during the binary analysis but that are not tied to a given
   /// DWARF DIE.
   const vector<type_base_sptr>&
-  extra_types_to_canonicalize() const
-  {return extra_types_to_canonicalize_;}
+  types_to_canonicalize() const
+  {return types_to_canonicalize_;}
 
   /// Clear the containers holding types to canonicalize.
   void
   clear_types_to_canonicalize()
   {
     types_to_canonicalize_.clear();
-    alt_types_to_canonicalize_.clear();
-    type_unit_types_to_canonicalize_.clear();
-    extra_types_to_canonicalize_.clear();
-  }
-
-  /// Put the offset of a DIE representing a type on a side vector so
-  /// that when the reading of the debug info of the current
-  /// translation unit is done, we can get back to the type DIE and
-  /// from there, to the type it's associated to, and then
-  /// canonicalize it.  This what we call late canonicalization.
-  ///
-  /// @param die the type DIE to schedule for late type
-  /// canonicalization.
-  void
-  schedule_type_for_late_canonicalization(const Dwarf_Die *die)
-  {
-    Dwarf_Off o;
-
-    Dwarf_Die equiv_die;
-    ABG_ASSERT(get_canonical_die(die, equiv_die,
-				  /*where=*/0,
-				 /*die_as_type=*/true));
-
-    const die_source source = get_die_source(&equiv_die);
-    o = dwarf_dieoffset(&equiv_die);
-
-    const die_artefact_map_type& m =
-      type_die_artefact_maps().get_container(*this, die);
-
-    die_artefact_map_type::const_iterator i = m.find(o);
-    ABG_ASSERT(i != m.end());
-
-    // Then really do the scheduling.
-    types_to_canonicalize(source).push_back(o);
   }
 
   /// Types that were created but not tied to a particular DIE, must
@@ -4768,7 +4681,7 @@  public:
   void
   schedule_type_for_late_canonicalization(const type_base_sptr &t)
   {
-    extra_types_to_canonicalize_.push_back(t);
+    types_to_canonicalize_.push_back(t);
   }
 
   /// Canonicalize types which DIE offsets are stored in vectors on
@@ -4778,7 +4691,7 @@  public:
   /// @param source where the DIE of the types to canonicalize are
   /// from.
   void
-  canonicalize_types_scheduled(die_source source)
+  canonicalize_types_scheduled()
   {
     tools_utils::timer cn_timer;
     if (do_log())
@@ -4787,74 +4700,38 @@  public:
 	corpus_sptr c = current_corpus();
 	if (c)
 	  cerr << " of corpus " << current_corpus()->get_path();
-	cerr << " (DIEs source: " << source << ")\n";
 	cn_timer.start();
       }
 
-    if (!types_to_canonicalize(source).empty()
-	|| !extra_types_to_canonicalize().empty())
+    if (!types_to_canonicalize().empty())
       {
 	tools_utils::timer single_type_cn_timer;
-	size_t total = types_to_canonicalize(source).size();
+	size_t total = types_to_canonicalize().size();
 	if (do_log())
-	  cerr << total << " types to canonicalize\n";
-	for (size_t i = 0; i < total; ++i)
+	  cerr << total << " Types to canonicalize\n";
+	size_t i = 1;
+	for (vector<type_base_sptr>::const_iterator it =
+	       types_to_canonicalize().begin();
+	     it != types_to_canonicalize().end();
+	     ++it, ++i)
 	  {
-	    Dwarf_Off element = types_to_canonicalize(source)[i];
-	    type_base_sptr t =
-	      lookup_type_from_die_offset(element, source);
-	    ABG_ASSERT(t);
 	    if (do_log())
 	      {
 		cerr << "canonicalizing type "
-		     << get_pretty_representation(t, false)
-		     << " [" << i + 1 << "/" << total << "]";
+		     << get_pretty_representation(*it, false)
+		     << " [" << i << "/" << total << "]";
 		if (corpus_sptr c = current_corpus())
 		  cerr << "@" << c->get_path();
 		cerr << " ...";
 		single_type_cn_timer.start();
 	      }
-	    canonicalize(t);
+	    canonicalize(*it);
 	    if (do_log())
 	      {
-		cerr << " DONE";
 		single_type_cn_timer.stop();
-		cerr << ":" <<single_type_cn_timer << "\n";
-	      }
-	  }
-
-	// Now canonicalize types that were created but not tied to
-	// any DIE.
-	if (!extra_types_to_canonicalize().empty())
-	  {
-	    tools_utils::timer single_type_cn_timer;
-	    size_t total = extra_types_to_canonicalize().size();
-	    if (do_log())
-	      cerr << total << " extra types to canonicalize\n";
-	    size_t i = 1;
-	    for (vector<type_base_sptr>::const_iterator it =
-		   extra_types_to_canonicalize().begin();
-		 it != extra_types_to_canonicalize().end();
-		 ++it, ++i)
-	      {
-		if (do_log())
-		  {
-		    cerr << "canonicalizing extra type "
-			 << get_pretty_representation(*it, false)
-			 << " [" << i << "/" << total << "]";
-		    if (corpus_sptr c = current_corpus())
-		      cerr << "@" << c->get_path();
-		    cerr << " ...";
-		    single_type_cn_timer.start();
-		  }
-		canonicalize(*it);
-		if (do_log())
-		  {
-		    single_type_cn_timer.stop();
-		    cerr << "DONE:"
-			 << single_type_cn_timer
-			 << "\n";
-		  }
+		cerr << "DONE:"
+		     << single_type_cn_timer
+		     << "\n";
 	      }
 	  }
       }
@@ -4866,10 +4743,7 @@  public:
 	corpus_sptr c = current_corpus();
 	if (c)
 	  cerr << " of corpus " << current_corpus()->get_path();
-	cerr << " (DIEs source: "
-	     << source << "):"
-	     << cn_timer
-	     << "\n";
+	cerr << ": (" << cn_timer << ")\n";
       }
   }
 
@@ -4886,16 +4760,11 @@  public:
   /// canonicalization and which couldn't be canonicalized (for a
   /// reason) is added to the value already present in this parameter.
   void
-  add_late_canonicalized_types_stats(die_source	source,
-				     size_t&		canonicalized,
+  add_late_canonicalized_types_stats(size_t&		canonicalized,
 				     size_t&		missed) const
   {
-    for (vector<Dwarf_Off>::const_iterator i =
-	   types_to_canonicalize(source).begin();
-	 i != types_to_canonicalize(source).end();
-	 ++i)
+    for (auto t : types_to_canonicalize())
       {
-        type_base_sptr t = lookup_type_from_die_offset(*i, source);
 	if (t->get_canonical_type())
 	  ++canonicalized;
 	else
@@ -4903,34 +4772,12 @@  public:
       }
   }
 
-  /// Compute the number of canonicalized and missed types in the late
-  /// canonicalization phase.
-  ///
-  /// @param canonicalized the number of types that got canonicalized
-  /// is added to the value already present in this parameter.
-  ///
-  /// @param missed the number of types scheduled for late
-  /// canonicalization and which couldn't be canonicalized (for a
-  /// reason) is added to the value already present in this parameter.
-  void
-  add_late_canonicalized_types_stats(size_t& canonicalized,
-				     size_t& missed) const
-  {
-    for (die_source source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
-	 source < NUMBER_OF_DIE_SOURCES;
-	 ++source)
-      add_late_canonicalized_types_stats(source, canonicalized, missed);
-  }
-
   // Look at the types that need to be canonicalized after the
   // translation unit has been constructed and canonicalize them.
   void
   perform_late_type_canonicalizing()
   {
-    for (die_source source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
-	 source < NUMBER_OF_DIE_SOURCES;
-	 ++source)
-      canonicalize_types_scheduled(source);
+    canonicalize_types_scheduled();
 
     if (show_stats())
       {
@@ -15270,94 +15117,9 @@  read_debug_info_into_corpus(read_context& ctxt)
 /// all of its sub-types are canonicalized themselve.  Non composite
 /// types are always deemed suitable for early canonicalization.
 ///
-/// Note that this function doesn't work on *ANONYMOUS* classes,
-/// structs, unions or enums because it first does some
-/// canonicalization of the DWARF DIE @p die.  That canonicalization
-/// is done by looking up @p die by name; and because these are
-/// anonymous types, they don't have names! and so that
-/// canonicalization fails.  So the type artifact associated to @p
-/// die often ends being *NOT* canonicalized.  This later leads to
-/// extreme slowness of operation, especially when comparisons are
-/// later performed on these anonymous types.
-///
-/// So when you have classes, structs, unions, or enums that can be
-/// anonymous, please use this overload instead:
-///
-///     void
-///     maybe_canonicalize_type(const Dwarf_Die*	die,
-///				const type_base_sptr&	t,
-///				read_context&		ctxt);
-///
-/// It knows how to deal with anonymous types.
-///
-/// @p looks up the type artifact
-/// associated to @p die.  During that lookup, ; but then those types don't have
-/// names because they are anonymous.
-///
-/// @param die the type DIE to consider for canonicalization.  Note
-/// that this DIE must have been associated with its type using the
-/// function read_context::associate_die_to_type() prior to calling
-/// this function.
-///
-/// @param ctxt the @ref read_context to use.
-static void
-maybe_canonicalize_type(const Dwarf_Die *die, read_context& ctxt)
-{
-  const die_source source = ctxt.get_die_source(die);
-
-  size_t die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
-  type_base_sptr t = ctxt.lookup_type_from_die(die);
-
-  if (!t)
-    return;
-
-  type_base_sptr peeled_type = peel_typedef_pointer_or_reference_type(t);
-  if (is_class_type(peeled_type)
-      || is_union_type(peeled_type)
-      || is_function_type(peeled_type)
-      || is_array_type(peeled_type)
-      || is_qualified_type(peeled_type)
-      || is_enum_type(peeled_type)
-      || is_typedef(t))
-    // We delay canonicalization of classes/unions or typedef,
-    // pointers, references and array to classes/unions.  This is
-    // because the (underlying) class might not be finished yet and we
-    // might not be able to able detect it here (thinking about
-    // classes that are work-in-progress, or classes that might be
-    // later amended by some DWARF construct).  So we err on the safe
-    // side.  We also delay canonicalization for array and qualified
-    // types because they can be edited (in particular by
-    // maybe_strip_qualification) after they are initially built.
-    ctxt.schedule_type_for_late_canonicalization(die);
-  else if (is_decl(t) && is_decl(t)->get_is_anonymous())
-    ctxt.schedule_type_for_late_canonicalization(t);
-  else if ((is_function_type(t)
-	    && ctxt.is_wip_function_type_die_offset(die_offset, source))
-	   || type_has_non_canonicalized_subtype(t))
-    ctxt.schedule_type_for_late_canonicalization(die);
-  else
-    canonicalize(t);
-}
-
-/// Canonicalize a type if it's suitable for early canonicalizing, or,
-/// if it's not, schedule it for late canonicalization, after the
-/// debug info of the current translation unit has been fully read.
-///
-/// A (composite) type is deemed suitable for early canonicalizing iff
-/// all of its sub-types are canonicalized themselve.  Non composite
-/// types are always deemed suitable for early canonicalization.
-///
-/// Note that this function nows how to deal with anonymous classes,
+/// Note that this function knows how to deal with anonymous classes,
 /// structs and enums, unlike the overload below:
 ///
-///     void maybe_canonicalize_type(const Dwarf_Die *die, read_context& ctxt)
-///
-/// The problem, though is that this function is much slower that that
-/// overload above because of how the types that are meant for later
-/// canonicalization are stored.  So the idea is that this function
-/// should be used only for the smallest possible subset of types that
-/// are anonymous and thus cannot be handled by the overload above.
-///
 /// @param t the type DIE to consider for canonicalization.
 ///
 /// @param ctxt the @ref read_context to use.
@@ -15558,7 +15320,7 @@  build_ir_node_from_die(read_context&	ctxt,
 	if (result)
 	  {
 	    maybe_set_member_type_access_specifier(is_decl(result), die);
-	    maybe_canonicalize_type(die, ctxt);
+	    maybe_canonicalize_type(t, ctxt);
 	  }
       }
       break;
@@ -15574,7 +15336,7 @@  build_ir_node_from_die(read_context&	ctxt,
 	    result =
 	      add_decl_to_scope(p, ctxt.cur_transl_unit()->get_global_scope());
 	    ABG_ASSERT(result->get_translation_unit());
-	    maybe_canonicalize_type(die, ctxt);
+	    maybe_canonicalize_type(p, ctxt);
 	  }
       }
       break;
@@ -15592,7 +15354,7 @@  build_ir_node_from_die(read_context&	ctxt,
 	      add_decl_to_scope(r, ctxt.cur_transl_unit()->get_global_scope());
 
 	    ctxt.associate_die_to_type(die, r, where_offset);
-	    maybe_canonicalize_type(die, ctxt);
+	    maybe_canonicalize_type(r, ctxt);
 	  }
       }
       break;
@@ -15752,7 +15514,7 @@  build_ir_node_from_die(read_context&	ctxt,
 	  {
 	    result = f;
 	    result->set_is_artificial(false);
-	    maybe_canonicalize_type(die, ctxt);
+	    maybe_canonicalize_type(f, ctxt);
 	  }
       }
       break;
@@ -15767,7 +15529,7 @@  build_ir_node_from_die(read_context&	ctxt,
 	    result =
 	      add_decl_to_scope(a, ctxt.cur_transl_unit()->get_global_scope());
 	    ctxt.associate_die_to_type(die, a, where_offset);
-	    maybe_canonicalize_type(die, ctxt);
+	    maybe_canonicalize_type(a, ctxt);
 	  }
 	break;
       }
@@ -15783,7 +15545,7 @@  build_ir_node_from_die(read_context&	ctxt,
 	    result =
 	      add_decl_to_scope(s, ctxt.cur_transl_unit()->get_global_scope());
 	    ctxt.associate_die_to_type(die, s, where_offset);
-	    maybe_canonicalize_type(die, ctxt);
+	    maybe_canonicalize_type(s, ctxt);
 	  }
       }
       break;
@@ -15981,7 +15743,7 @@  build_ir_node_from_die(read_context&	ctxt,
 	    ctxt.maybe_add_fn_to_exported_decls(fn.get());
 	    ctxt.associate_die_to_decl(die, fn, where_offset,
 				       /*associate_by_repr=*/false);
-	    maybe_canonicalize_type(die, ctxt);
+	    maybe_canonicalize_type(fn->get_type(), ctxt);
 	  }
 
 	ctxt.scope_stack().pop();
diff --git a/tests/data/test-annotate/test13-pr18894.so.abi b/tests/data/test-annotate/test13-pr18894.so.abi
index d73aa81e..addb886e 100644
--- a/tests/data/test-annotate/test13-pr18894.so.abi
+++ b/tests/data/test-annotate/test13-pr18894.so.abi
@@ -2259,6 +2259,24 @@ 
       <!-- typedef dbus_bool_t -->
       <return type-id='type-id-24'/>
     </function-type>
+    <!-- dbus_bool_t (DBusTimeout*, void*) -->
+    <function-type size-in-bits='64' id='type-id-103'>
+      <!-- parameter of type 'DBusTimeout*' -->
+      <parameter type-id='type-id-84'/>
+      <!-- parameter of type 'void*' -->
+      <parameter type-id='type-id-6'/>
+      <!-- typedef dbus_bool_t -->
+      <return type-id='type-id-24'/>
+    </function-type>
+    <!-- dbus_bool_t (DBusWatch*, void*) -->
+    <function-type size-in-bits='64' id='type-id-105'>
+      <!-- parameter of type 'DBusWatch*' -->
+      <parameter type-id='type-id-88'/>
+      <!-- parameter of type 'void*' -->
+      <parameter type-id='type-id-6'/>
+      <!-- typedef dbus_bool_t -->
+      <return type-id='type-id-24'/>
+    </function-type>
     <!-- void (DBusConnection*, DBusDispatchStatus, void*) -->
     <function-type size-in-bits='64' id='type-id-108'>
       <!-- parameter of type 'DBusConnection*' -->
@@ -2279,24 +2297,6 @@ 
       <!-- void -->
       <return type-id='type-id-22'/>
     </function-type>
-    <!-- dbus_bool_t (DBusTimeout*, void*) -->
-    <function-type size-in-bits='64' id='type-id-103'>
-      <!-- parameter of type 'DBusTimeout*' -->
-      <parameter type-id='type-id-84'/>
-      <!-- parameter of type 'void*' -->
-      <parameter type-id='type-id-6'/>
-      <!-- typedef dbus_bool_t -->
-      <return type-id='type-id-24'/>
-    </function-type>
-    <!-- dbus_bool_t (DBusWatch*, void*) -->
-    <function-type size-in-bits='64' id='type-id-105'>
-      <!-- parameter of type 'DBusWatch*' -->
-      <parameter type-id='type-id-88'/>
-      <!-- parameter of type 'void*' -->
-      <parameter type-id='type-id-6'/>
-      <!-- typedef dbus_bool_t -->
-      <return type-id='type-id-24'/>
-    </function-type>
     <!-- void (DBusTimeout*, void*) -->
     <function-type size-in-bits='64' id='type-id-112'>
       <!-- parameter of type 'DBusTimeout*' -->
diff --git a/tests/data/test-annotate/test15-pr18892.so.abi b/tests/data/test-annotate/test15-pr18892.so.abi
index 642b2b6b..6d71ed97 100644
--- a/tests/data/test-annotate/test15-pr18892.so.abi
+++ b/tests/data/test-annotate/test15-pr18892.so.abi
@@ -3326,6 +3326,21 @@ 
       <!-- void* -->
       <return type-id='type-id-3'/>
     </function-decl>
+    <!-- void (backtrace_state*, uintptr_t, backtrace_syminfo_callback, backtrace_error_callback, void*) -->
+    <function-type size-in-bits='64' id='type-id-20'>
+      <!-- parameter of type 'backtrace_state*' -->
+      <parameter type-id='type-id-28'/>
+      <!-- parameter of type 'typedef uintptr_t' -->
+      <parameter type-id='type-id-29'/>
+      <!-- parameter of type 'typedef backtrace_syminfo_callback' -->
+      <parameter type-id='type-id-27'/>
+      <!-- parameter of type 'typedef backtrace_error_callback' -->
+      <parameter type-id='type-id-23'/>
+      <!-- parameter of type 'void*' -->
+      <parameter type-id='type-id-3'/>
+      <!-- void -->
+      <return type-id='type-id-31'/>
+    </function-type>
     <!-- int (backtrace_state*, uintptr_t, backtrace_full_callback, backtrace_error_callback, void*) -->
     <function-type size-in-bits='64' id='type-id-18'>
       <!-- parameter of type 'backtrace_state*' -->
@@ -3365,21 +3380,6 @@ 
       <!-- int -->
       <return type-id='type-id-6'/>
     </function-type>
-    <!-- void (backtrace_state*, uintptr_t, backtrace_syminfo_callback, backtrace_error_callback, void*) -->
-    <function-type size-in-bits='64' id='type-id-20'>
-      <!-- parameter of type 'backtrace_state*' -->
-      <parameter type-id='type-id-28'/>
-      <!-- parameter of type 'typedef uintptr_t' -->
-      <parameter type-id='type-id-29'/>
-      <!-- parameter of type 'typedef backtrace_syminfo_callback' -->
-      <parameter type-id='type-id-27'/>
-      <!-- parameter of type 'typedef backtrace_error_callback' -->
-      <parameter type-id='type-id-23'/>
-      <!-- parameter of type 'void*' -->
-      <parameter type-id='type-id-3'/>
-      <!-- void -->
-      <return type-id='type-id-31'/>
-    </function-type>
     <!-- void (void*, const char*, int) -->
     <function-type size-in-bits='64' id='type-id-36'>
       <!-- parameter of type 'void*' -->
@@ -6799,12 +6799,14 @@ 
     <typedef-decl name='uint64_t' type-id='type-id-1' filepath='/usr/include/stdint.h' line='56' column='1' id='type-id-245'/>
     <!-- typedef long int int64_t -->
     <typedef-decl name='int64_t' type-id='type-id-42' filepath='/usr/include/sys/types.h' line='198' column='1' id='type-id-246'/>
-    <!-- void (void*, __sanitizer::uptr) -->
-    <function-type size-in-bits='64' id='type-id-230'>
+    <!-- void (int, void*, void*) -->
+    <function-type size-in-bits='64' id='type-id-228'>
+      <!-- parameter of type 'int' -->
+      <parameter type-id='type-id-6'/>
+      <!-- parameter of type 'void*' -->
+      <parameter type-id='type-id-3'/>
       <!-- parameter of type 'void*' -->
       <parameter type-id='type-id-3'/>
-      <!-- parameter of type 'typedef __sanitizer::uptr' -->
-      <parameter type-id='type-id-90'/>
       <!-- void -->
       <return type-id='type-id-31'/>
     </function-type>
@@ -6822,14 +6824,12 @@ 
       <!-- void -->
       <return type-id='type-id-31'/>
     </function-type>
-    <!-- void (int, void*, void*) -->
-    <function-type size-in-bits='64' id='type-id-228'>
-      <!-- parameter of type 'int' -->
-      <parameter type-id='type-id-6'/>
-      <!-- parameter of type 'void*' -->
-      <parameter type-id='type-id-3'/>
+    <!-- void (void*, __sanitizer::uptr) -->
+    <function-type size-in-bits='64' id='type-id-230'>
       <!-- parameter of type 'void*' -->
       <parameter type-id='type-id-3'/>
+      <!-- parameter of type 'typedef __sanitizer::uptr' -->
+      <parameter type-id='type-id-90'/>
       <!-- void -->
       <return type-id='type-id-31'/>
     </function-type>
@@ -26505,7 +26505,7 @@ 
     <!-- __sanitizer::uptr (void*, __sanitizer::uptr, __sanitizer::uptr, void*) -->
     <function-type size-in-bits='64' id='type-id-852'>
       <!-- parameter of type 'void*' -->
-      <parameter type-id='type-id-3' name='ptr'/>
+      <parameter type-id='type-id-3' name='p'/>
       <!-- parameter of type 'typedef __sanitizer::uptr' -->
       <parameter type-id='type-id-90' name='size'/>
       <!-- parameter of type 'typedef __sanitizer::uptr' -->
@@ -26738,17 +26738,6 @@ 
       <!-- void* -->
       <return type-id='type-id-3'/>
     </function-type>
-    <!-- void* (void*, void*, __sanitizer::uptr) -->
-    <function-type size-in-bits='64' id='type-id-902'>
-      <!-- parameter of type 'void*' -->
-      <parameter type-id='type-id-3' name='dst'/>
-      <!-- parameter of type 'void*' -->
-      <parameter type-id='type-id-3' name='src'/>
-      <!-- parameter of type 'typedef __sanitizer::uptr' -->
-      <parameter type-id='type-id-90' name='size'/>
-      <!-- void* -->
-      <return type-id='type-id-3'/>
-    </function-type>
     <!-- char* (const char*) -->
     <function-type size-in-bits='64' id='type-id-529'>
       <!-- parameter of type 'const char*' -->
@@ -26790,6 +26779,17 @@ 
       <!-- void* -->
       <return type-id='type-id-3'/>
     </function-type>
+    <!-- void* (void*, void*, __sanitizer::uptr) -->
+    <function-type size-in-bits='64' id='type-id-902'>
+      <!-- parameter of type 'void*' -->
+      <parameter type-id='type-id-3' name='dst'/>
+      <!-- parameter of type 'void*' -->
+      <parameter type-id='type-id-3' name='src'/>
+      <!-- parameter of type 'typedef __sanitizer::uptr' -->
+      <parameter type-id='type-id-90' name='size'/>
+      <!-- void* -->
+      <return type-id='type-id-3'/>
+    </function-type>
   </abi-instr>
   <abi-instr address-size='64' path='../../.././libsanitizer/tsan/tsan_interface.cc' comp-dir-path='/tmp/legendre/spack-stage/spack-stage-ImG4Cf/gcc-4.9.2/x86_64-unknown-linux-gnu/libsanitizer/tsan' language='LANG_C_plus_plus'>
     <!-- unsigned short int -->
diff --git a/tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi b/tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi
index 927cd170..b2016e79 100644
--- a/tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi
+++ b/tests/data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi
@@ -9691,11 +9691,6 @@ 
       <!-- int -->
       <return type-id='type-id-14'/>
     </function-type>
-    <!-- void () -->
-    <function-type size-in-bits='64' id='type-id-370'>
-      <!-- void -->
-      <return type-id='type-id-30'/>
-    </function-type>
     <!-- std::basic_ostream<char, std::char_traits<char> >& (std::basic_ostream<char, std::char_traits<char> >&) -->
     <function-type size-in-bits='64' id='type-id-348'>
       <!-- parameter of type 'std::basic_ostream<char, std::char_traits<char> >&' -->
@@ -9703,6 +9698,11 @@ 
       <!-- std::basic_ostream<char, std::char_traits<char> >& -->
       <return type-id='type-id-347'/>
     </function-type>
+    <!-- void () -->
+    <function-type size-in-bits='64' id='type-id-370'>
+      <!-- void -->
+      <return type-id='type-id-30'/>
+    </function-type>
   </abi-instr>
   <abi-instr address-size='64' path='/tmp/legendre/spack-stage/spack-stage-R_crTC/VTK-6.1.0/Parallel/Core/vtkDummyCommunicator.cxx' comp-dir-path='/tmp/legendre/spack-stage/spack-stage-R_crTC/VTK-6.1.0/spack-build/Parallel/Core' language='LANG_C_plus_plus'>
     <!-- class vtkDummyCommunicator -->
diff --git a/tests/data/test-annotate/test21-pr19092.so.abi b/tests/data/test-annotate/test21-pr19092.so.abi
index 263e9a17..befbb376 100644
--- a/tests/data/test-annotate/test21-pr19092.so.abi
+++ b/tests/data/test-annotate/test21-pr19092.so.abi
@@ -2541,6 +2541,11 @@ 
       <!-- int -->
       <return type-id='type-id-4'/>
     </function-type>
+    <!-- void () -->
+    <function-type size-in-bits='64' id='type-id-127'>
+      <!-- void -->
+      <return type-id='type-id-137'/>
+    </function-type>
     <!-- void (diagnostic_context*, const char*, va_list*) -->
     <function-type size-in-bits='64' id='type-id-129'>
       <!-- parameter of type 'diagnostic_context*' -->
@@ -2568,6 +2573,13 @@ 
       <!-- void -->
       <return type-id='type-id-137'/>
     </function-type>
+    <!-- void (void*) -->
+    <function-type size-in-bits='64' id='type-id-134'>
+      <!-- parameter of type 'void*' -->
+      <parameter type-id='type-id-27'/>
+      <!-- void -->
+      <return type-id='type-id-137'/>
+    </function-type>
     <!-- void (void*, _obstack_chunk*) -->
     <function-type size-in-bits='64' id='type-id-136'>
       <!-- parameter of type 'void*' -->
@@ -2584,18 +2596,6 @@ 
       <!-- void* -->
       <return type-id='type-id-27'/>
     </function-type>
-    <!-- void () -->
-    <function-type size-in-bits='64' id='type-id-127'>
-      <!-- void -->
-      <return type-id='type-id-137'/>
-    </function-type>
-    <!-- void (void*) -->
-    <function-type size-in-bits='64' id='type-id-134'>
-      <!-- parameter of type 'void*' -->
-      <parameter type-id='type-id-27'/>
-      <!-- void -->
-      <return type-id='type-id-137'/>
-    </function-type>
   </abi-instr>
   <abi-instr address-size='64' path='../.././gcc/diagnostic.c' comp-dir-path='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/host-x86_64-unknown-linux-gnu/gcc' language='LANG_C_plus_plus'>
     <!-- struct maps_info -->
@@ -4566,8 +4566,10 @@ 
       <!-- void -->
       <return type-id='type-id-137'/>
     </function-type>
-    <!-- void* (size_t, size_t) -->
-    <function-type size-in-bits='64' id='type-id-205'>
+    <!-- void* (void*, size_t, size_t) -->
+    <function-type size-in-bits='64' id='type-id-207'>
+      <!-- parameter of type 'void*' -->
+      <parameter type-id='type-id-27'/>
       <!-- parameter of type 'typedef size_t' -->
       <parameter type-id='type-id-2'/>
       <!-- parameter of type 'typedef size_t' -->
@@ -4575,10 +4577,8 @@ 
       <!-- void* -->
       <return type-id='type-id-27'/>
     </function-type>
-    <!-- void* (void*, size_t, size_t) -->
-    <function-type size-in-bits='64' id='type-id-207'>
-      <!-- parameter of type 'void*' -->
-      <parameter type-id='type-id-27'/>
+    <!-- void* (size_t, size_t) -->
+    <function-type size-in-bits='64' id='type-id-205'>
       <!-- parameter of type 'typedef size_t' -->
       <parameter type-id='type-id-2'/>
       <!-- parameter of type 'typedef size_t' -->
diff --git a/tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt b/tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt
index c78ed700..546942fe 100644
--- a/tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt
+++ b/tests/data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt
@@ -68,7 +68,7 @@ 
 ================ end of changes of 'libssl3.so'===============
 
 ================ changes of 'libsmime3.so'===============
-  Functions changes summary: 0 Removed, 1 Changed (145 filtered out), 0 Added functions
+  Functions changes summary: 0 Removed, 1 Changed (127 filtered out), 0 Added functions
   Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
 
   1 function with some indirect sub-type change:
@@ -87,7 +87,7 @@ 
                       in pointed to type 'typedef NSSCMSEncryptedData' at cmst.h:65:1:
                         underlying type 'struct NSSCMSEncryptedDataStr' at cmst.h:468:1 changed:
                           type size hasn't changed
-                          1 data member changes (2 filtered):
+                          1 data member changes (1 filtered):
                             type of 'NSSCMSAttribute** unprotectedAttr' changed:
                               in pointed to type 'NSSCMSAttribute*':
                                 in pointed to type 'typedef NSSCMSAttribute' at cmst.h:69:1:
diff --git a/tests/data/test-read-dwarf/PR22122-libftdc.so.abi b/tests/data/test-read-dwarf/PR22122-libftdc.so.abi
index 844ddd39..e226982c 100644
--- a/tests/data/test-read-dwarf/PR22122-libftdc.so.abi
+++ b/tests/data/test-read-dwarf/PR22122-libftdc.so.abi
@@ -2854,6 +2854,9 @@ 
       <parameter type-id='type-id-113'/>
       <return type-id='type-id-16'/>
     </function-type>
+    <function-type size-in-bits='64' id='type-id-110'>
+      <return type-id='type-id-112'/>
+    </function-type>
     <namespace-decl name='__gnu_cxx'>
       <class-decl name='__anonymous_struct__2' is-struct='yes' is-anonymous='yes' visibility='default' is-declaration-only='yes' id='type-id-133'>
         <member-type access='public'>
@@ -2924,9 +2927,6 @@ 
         </member-type>
       </class-decl>
     </namespace-decl>
-    <function-type size-in-bits='64' id='type-id-110'>
-      <return type-id='type-id-112'/>
-    </function-type>
   </abi-instr>
   <abi-instr address-size='64' path='src/mongo/db/ftdc/collector.cpp' comp-dir-path='/home/andrew/Documents/10gen/dev/src/mongodb' language='LANG_C_plus_plus'>
     <reference-type-def kind='lvalue' type-id='type-id-168' size-in-bits='64' id='type-id-169'/>
@@ -3921,18 +3921,21 @@ 
     <array-type-def dimensions='1' type-id='type-id-2' size-in-bits='280' id='type-id-328'>
       <subrange length='35' type-id='type-id-4' id='type-id-329'/>
     </array-type-def>
-    <array-type-def dimensions='1' type-id='type-id-10' size-in-bits='152' id='type-id-330'>
+    <array-type-def dimensions='1' type-id='type-id-10' size-in-bits='128' id='type-id-330'>
+      <subrange length='16' type-id='type-id-4' id='type-id-325'/>
+    </array-type-def>
+    <array-type-def dimensions='1' type-id='type-id-10' size-in-bits='152' id='type-id-331'>
       <subrange length='19' type-id='type-id-4' id='type-id-327'/>
     </array-type-def>
-    <array-type-def dimensions='1' type-id='type-id-10' size-in-bits='280' id='type-id-331'>
+    <array-type-def dimensions='1' type-id='type-id-10' size-in-bits='280' id='type-id-332'>
       <subrange length='35' type-id='type-id-4' id='type-id-329'/>
     </array-type-def>
-    <pointer-type-def type-id='type-id-332' size-in-bits='64' id='type-id-333'/>
-    <qualified-type-def type-id='type-id-334' const='yes' id='type-id-335'/>
-    <pointer-type-def type-id='type-id-335' size-in-bits='64' id='type-id-336'/>
-    <reference-type-def kind='lvalue' type-id='type-id-337' size-in-bits='64' id='type-id-338'/>
-    <reference-type-def kind='lvalue' type-id='type-id-330' size-in-bits='64' id='type-id-339'/>
-    <reference-type-def kind='lvalue' type-id='type-id-331' size-in-bits='64' id='type-id-340'/>
+    <pointer-type-def type-id='type-id-333' size-in-bits='64' id='type-id-334'/>
+    <qualified-type-def type-id='type-id-335' const='yes' id='type-id-336'/>
+    <pointer-type-def type-id='type-id-336' size-in-bits='64' id='type-id-337'/>
+    <reference-type-def kind='lvalue' type-id='type-id-330' size-in-bits='64' id='type-id-338'/>
+    <reference-type-def kind='lvalue' type-id='type-id-331' size-in-bits='64' id='type-id-339'/>
+    <reference-type-def kind='lvalue' type-id='type-id-332' size-in-bits='64' id='type-id-340'/>
     <qualified-type-def type-id='type-id-341' const='yes' id='type-id-342'/>
     <pointer-type-def type-id='type-id-342' size-in-bits='64' id='type-id-343'/>
     <qualified-type-def type-id='type-id-101' const='yes' id='type-id-344'/>
@@ -4190,7 +4193,7 @@ 
       <namespace-decl name='filesystem'>
         <class-decl name='__anonymous_struct__' is-anonymous='yes' visibility='default' is-declaration-only='yes' id='type-id-39'>
           <member-type access='private'>
-            <typedef-decl name='value_type' type-id='type-id-2' filepath='src/third_party/boost-1.60.0/boost/filesystem/path.hpp' line='67' column='1' id='type-id-334'/>
+            <typedef-decl name='value_type' type-id='type-id-2' filepath='src/third_party/boost-1.60.0/boost/filesystem/path.hpp' line='67' column='1' id='type-id-335'/>
           </member-type>
         </class-decl>
       </namespace-decl>
@@ -4199,7 +4202,7 @@ 
       <namespace-decl name='optional_detail'>
         <class-decl name='__anonymous_struct__8' is-anonymous='yes' visibility='default' is-declaration-only='yes' id='type-id-39'>
           <member-type access='private'>
-            <typedef-decl name='internal_type' type-id='type-id-275' filepath='src/third_party/boost-1.60.0/boost/optional/optional.hpp' line='205' column='1' id='type-id-332'/>
+            <typedef-decl name='internal_type' type-id='type-id-275' filepath='src/third_party/boost-1.60.0/boost/optional/optional.hpp' line='205' column='1' id='type-id-333'/>
           </member-type>
         </class-decl>
       </namespace-decl>
@@ -4273,9 +4276,6 @@ 
     <array-type-def dimensions='1' type-id='type-id-2' size-in-bits='64' id='type-id-368'>
       <subrange length='8' type-id='type-id-4' id='type-id-369'/>
     </array-type-def>
-    <array-type-def dimensions='1' type-id='type-id-10' size-in-bits='128' id='type-id-337'>
-      <subrange length='16' type-id='type-id-4' id='type-id-325'/>
-    </array-type-def>
     <array-type-def dimensions='1' type-id='type-id-10' size-in-bits='32' id='type-id-370'>
       <subrange length='4' type-id='type-id-4' id='type-id-371'/>
     </array-type-def>
@@ -4316,7 +4316,7 @@ 
       </namespace-decl>
     </namespace-decl>
     <namespace-decl name='mongo'>
-      <var-decl name='kFTDCInterimFile' type-id='type-id-337' mangled-name='_ZN5mongo16kFTDCInterimFileE' visibility='default' filepath='src/mongo/db/ftdc/util.cpp' line='51' column='1' elf-symbol-id='_ZN5mongo16kFTDCInterimFileE'/>
+      <var-decl name='kFTDCInterimFile' type-id='type-id-330' mangled-name='_ZN5mongo16kFTDCInterimFileE' visibility='default' filepath='src/mongo/db/ftdc/util.cpp' line='51' column='1' elf-symbol-id='_ZN5mongo16kFTDCInterimFileE'/>
       <var-decl name='kFTDCArchiveFile' type-id='type-id-377' mangled-name='_ZN5mongo16kFTDCArchiveFileE' visibility='default' filepath='src/mongo/db/ftdc/util.cpp' line='53' column='1' elf-symbol-id='_ZN5mongo16kFTDCArchiveFileE'/>
       <var-decl name='kFTDCIdField' type-id='type-id-370' mangled-name='_ZN5mongo12kFTDCIdFieldE' visibility='default' filepath='src/mongo/db/ftdc/util.cpp' line='55' column='1' elf-symbol-id='_ZN5mongo12kFTDCIdFieldE'/>
       <var-decl name='kFTDCTypeField' type-id='type-id-372' mangled-name='_ZN5mongo14kFTDCTypeFieldE' visibility='default' filepath='src/mongo/db/ftdc/util.cpp' line='56' column='1' elf-symbol-id='_ZN5mongo14kFTDCTypeFieldE'/>
diff --git a/tests/data/test-read-dwarf/test12-pr18844.so.abi b/tests/data/test-read-dwarf/test12-pr18844.so.abi
index 5018c1fd..a5419962 100644
--- a/tests/data/test-read-dwarf/test12-pr18844.so.abi
+++ b/tests/data/test-read-dwarf/test12-pr18844.so.abi
@@ -25568,6 +25568,9 @@ 
       <parameter type-id='type-id-2295'/>
       <return type-id='type-id-2295'/>
     </function-type>
+    <function-type size-in-bits='64' id='type-id-2693'>
+      <return type-id='type-id-2727'/>
+    </function-type>
     <function-type size-in-bits='64' id='type-id-2695'>
       <parameter type-id='type-id-381'/>
       <parameter type-id='type-id-1211'/>
@@ -25604,9 +25607,6 @@ 
       <parameter type-id='type-id-1199'/>
       <return type-id='type-id-2727'/>
     </function-type>
-    <function-type size-in-bits='64' id='type-id-2693'>
-      <return type-id='type-id-2727'/>
-    </function-type>
   </abi-instr>
   <abi-instr address-size='64' path='src/mongo/db/repl/scatter_gather_algorithm.cpp' comp-dir-path='/home/andrew/Documents/10gen/dev/src/mongodb' language='LANG_C_plus_plus'>
     <qualified-type-def type-id='type-id-3603' const='yes' id='type-id-3604'/>
diff --git a/tests/data/test-read-dwarf/test13-pr18894.so.abi b/tests/data/test-read-dwarf/test13-pr18894.so.abi
index 71bb9af8..187f8048 100644
--- a/tests/data/test-read-dwarf/test13-pr18894.so.abi
+++ b/tests/data/test-read-dwarf/test13-pr18894.so.abi
@@ -1357,6 +1357,16 @@ 
       <parameter type-id='type-id-6'/>
       <return type-id='type-id-24'/>
     </function-type>
+    <function-type size-in-bits='64' id='type-id-103'>
+      <parameter type-id='type-id-84'/>
+      <parameter type-id='type-id-6'/>
+      <return type-id='type-id-24'/>
+    </function-type>
+    <function-type size-in-bits='64' id='type-id-105'>
+      <parameter type-id='type-id-88'/>
+      <parameter type-id='type-id-6'/>
+      <return type-id='type-id-24'/>
+    </function-type>
     <function-type size-in-bits='64' id='type-id-108'>
       <parameter type-id='type-id-30'/>
       <parameter type-id='type-id-47'/>
@@ -1368,16 +1378,6 @@ 
       <parameter type-id='type-id-6'/>
       <return type-id='type-id-22'/>
     </function-type>
-    <function-type size-in-bits='64' id='type-id-103'>
-      <parameter type-id='type-id-84'/>
-      <parameter type-id='type-id-6'/>
-      <return type-id='type-id-24'/>
-    </function-type>
-    <function-type size-in-bits='64' id='type-id-105'>
-      <parameter type-id='type-id-88'/>
-      <parameter type-id='type-id-6'/>
-      <return type-id='type-id-24'/>
-    </function-type>
     <function-type size-in-bits='64' id='type-id-112'>
       <parameter type-id='type-id-84'/>
       <parameter type-id='type-id-6'/>
diff --git a/tests/data/test-read-dwarf/test15-pr18892.so.abi b/tests/data/test-read-dwarf/test15-pr18892.so.abi
index 01ea8828..0970c836 100644
--- a/tests/data/test-read-dwarf/test15-pr18892.so.abi
+++ b/tests/data/test-read-dwarf/test15-pr18892.so.abi
@@ -1696,6 +1696,14 @@ 
       <parameter type-id='type-id-33'/>
       <return type-id='type-id-3'/>
     </function-decl>
+    <function-type size-in-bits='64' id='type-id-20'>
+      <parameter type-id='type-id-28'/>
+      <parameter type-id='type-id-29'/>
+      <parameter type-id='type-id-27'/>
+      <parameter type-id='type-id-23'/>
+      <parameter type-id='type-id-3'/>
+      <return type-id='type-id-31'/>
+    </function-type>
     <function-type size-in-bits='64' id='type-id-18'>
       <parameter type-id='type-id-28'/>
       <parameter type-id='type-id-29'/>
@@ -1717,14 +1725,6 @@ 
       <parameter type-id='type-id-3'/>
       <return type-id='type-id-6'/>
     </function-type>
-    <function-type size-in-bits='64' id='type-id-20'>
-      <parameter type-id='type-id-28'/>
-      <parameter type-id='type-id-29'/>
-      <parameter type-id='type-id-27'/>
-      <parameter type-id='type-id-23'/>
-      <parameter type-id='type-id-3'/>
-      <return type-id='type-id-31'/>
-    </function-type>
     <function-type size-in-bits='64' id='type-id-36'>
       <parameter type-id='type-id-3'/>
       <parameter type-id='type-id-4'/>
@@ -3906,9 +3906,10 @@ 
     <typedef-decl name='Elf64_Dyn' type-id='type-id-205' filepath='/usr/include/elf.h' line='650' column='1' id='type-id-204'/>
     <typedef-decl name='uint64_t' type-id='type-id-1' filepath='/usr/include/stdint.h' line='56' column='1' id='type-id-245'/>
     <typedef-decl name='int64_t' type-id='type-id-42' filepath='/usr/include/sys/types.h' line='198' column='1' id='type-id-246'/>
-    <function-type size-in-bits='64' id='type-id-230'>
+    <function-type size-in-bits='64' id='type-id-228'>
+      <parameter type-id='type-id-6'/>
+      <parameter type-id='type-id-3'/>
       <parameter type-id='type-id-3'/>
-      <parameter type-id='type-id-90'/>
       <return type-id='type-id-31'/>
     </function-type>
     <function-type size-in-bits='64' id='type-id-247'>
@@ -3919,10 +3920,9 @@ 
       <parameter type-id='type-id-6'/>
       <return type-id='type-id-31'/>
     </function-type>
-    <function-type size-in-bits='64' id='type-id-228'>
-      <parameter type-id='type-id-6'/>
-      <parameter type-id='type-id-3'/>
+    <function-type size-in-bits='64' id='type-id-230'>
       <parameter type-id='type-id-3'/>
+      <parameter type-id='type-id-90'/>
       <return type-id='type-id-31'/>
     </function-type>
   </abi-instr>
@@ -14984,7 +14984,7 @@ 
       <return type-id='type-id-419'/>
     </function-type>
     <function-type size-in-bits='64' id='type-id-852'>
-      <parameter type-id='type-id-3' name='ptr'/>
+      <parameter type-id='type-id-3' name='p'/>
       <parameter type-id='type-id-90' name='size'/>
       <parameter type-id='type-id-90' name='nmemb'/>
       <parameter type-id='type-id-3' name='f'/>
@@ -15112,12 +15112,6 @@ 
       <parameter type-id='type-id-90' name='size'/>
       <return type-id='type-id-3'/>
     </function-type>
-    <function-type size-in-bits='64' id='type-id-902'>
-      <parameter type-id='type-id-3' name='dst'/>
-      <parameter type-id='type-id-3' name='src'/>
-      <parameter type-id='type-id-90' name='size'/>
-      <return type-id='type-id-3'/>
-    </function-type>
     <function-type size-in-bits='64' id='type-id-529'>
       <parameter type-id='type-id-4' name='str'/>
       <return type-id='type-id-32'/>
@@ -15141,6 +15135,12 @@ 
       <parameter type-id='type-id-90' name='size'/>
       <return type-id='type-id-3'/>
     </function-type>
+    <function-type size-in-bits='64' id='type-id-902'>
+      <parameter type-id='type-id-3' name='dst'/>
+      <parameter type-id='type-id-3' name='src'/>
+      <parameter type-id='type-id-90' name='size'/>
+      <return type-id='type-id-3'/>
+    </function-type>
   </abi-instr>
   <abi-instr address-size='64' path='../../.././libsanitizer/tsan/tsan_interface.cc' comp-dir-path='/tmp/legendre/spack-stage/spack-stage-ImG4Cf/gcc-4.9.2/x86_64-unknown-linux-gnu/libsanitizer/tsan' language='LANG_C_plus_plus'>
     <type-decl name='unsigned short int' size-in-bits='16' id='type-id-232'/>
diff --git a/tests/data/test-read-dwarf/test16-pr18904.so.abi b/tests/data/test-read-dwarf/test16-pr18904.so.abi
index 8fcf470f..4ae32b8e 100644
--- a/tests/data/test-read-dwarf/test16-pr18904.so.abi
+++ b/tests/data/test-read-dwarf/test16-pr18904.so.abi
@@ -23044,11 +23044,6 @@ 
       <parameter type-id='type-id-146'/>
       <return type-id='type-id-2878'/>
     </function-type>
-    <function-type size-in-bits='64' id='type-id-3017'>
-      <parameter type-id='type-id-150'/>
-      <parameter type-id='type-id-150'/>
-      <return type-id='type-id-154'/>
-    </function-type>
     <function-type size-in-bits='64' id='type-id-3015'>
       <parameter type-id='type-id-152'/>
       <parameter type-id='type-id-150'/>
@@ -23078,6 +23073,11 @@ 
       <parameter type-id='type-id-150' name='ptr'/>
       <return type-id='type-id-154'/>
     </function-type>
+    <function-type size-in-bits='64' id='type-id-3017'>
+      <parameter type-id='type-id-150'/>
+      <parameter type-id='type-id-150'/>
+      <return type-id='type-id-154'/>
+    </function-type>
     <function-type size-in-bits='64' id='type-id-3022'>
       <parameter type-id='type-id-195' name='size'/>
       <parameter type-id='type-id-195' name='align'/>
diff --git a/tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi b/tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi
index b3253452..e4a19af4 100644
--- a/tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi
+++ b/tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi
@@ -5891,13 +5891,13 @@ 
       <parameter type-id='type-id-22'/>
       <return type-id='type-id-14'/>
     </function-type>
-    <function-type size-in-bits='64' id='type-id-370'>
-      <return type-id='type-id-30'/>
-    </function-type>
     <function-type size-in-bits='64' id='type-id-348'>
       <parameter type-id='type-id-347'/>
       <return type-id='type-id-347'/>
     </function-type>
+    <function-type size-in-bits='64' id='type-id-370'>
+      <return type-id='type-id-30'/>
+    </function-type>
   </abi-instr>
   <abi-instr address-size='64' path='/tmp/legendre/spack-stage/spack-stage-R_crTC/VTK-6.1.0/Parallel/Core/vtkDummyCommunicator.cxx' comp-dir-path='/tmp/legendre/spack-stage/spack-stage-R_crTC/VTK-6.1.0/spack-build/Parallel/Core' language='LANG_C_plus_plus'>
     <class-decl name='vtkDummyCommunicator' size-in-bits='576' visibility='default' filepath='/tmp/legendre/spack-stage/spack-stage-R_crTC/VTK-6.1.0/Parallel/Core/vtkDummyCommunicator.h' line='32' column='1' id='type-id-448'>
diff --git a/tests/data/test-read-dwarf/test21-pr19092.so.abi b/tests/data/test-read-dwarf/test21-pr19092.so.abi
index 9ae0cc8d..de771031 100644
--- a/tests/data/test-read-dwarf/test21-pr19092.so.abi
+++ b/tests/data/test-read-dwarf/test21-pr19092.so.abi
@@ -1518,6 +1518,9 @@ 
       <parameter type-id='type-id-27'/>
       <return type-id='type-id-4'/>
     </function-type>
+    <function-type size-in-bits='64' id='type-id-127'>
+      <return type-id='type-id-137'/>
+    </function-type>
     <function-type size-in-bits='64' id='type-id-129'>
       <parameter type-id='type-id-114'/>
       <parameter type-id='type-id-3'/>
@@ -1533,6 +1536,10 @@ 
       <parameter type-id='type-id-4'/>
       <return type-id='type-id-137'/>
     </function-type>
+    <function-type size-in-bits='64' id='type-id-134'>
+      <parameter type-id='type-id-27'/>
+      <return type-id='type-id-137'/>
+    </function-type>
     <function-type size-in-bits='64' id='type-id-136'>
       <parameter type-id='type-id-27'/>
       <parameter type-id='type-id-33'/>
@@ -1542,13 +1549,6 @@ 
       <parameter type-id='type-id-21'/>
       <return type-id='type-id-27'/>
     </function-type>
-    <function-type size-in-bits='64' id='type-id-127'>
-      <return type-id='type-id-137'/>
-    </function-type>
-    <function-type size-in-bits='64' id='type-id-134'>
-      <parameter type-id='type-id-27'/>
-      <return type-id='type-id-137'/>
-    </function-type>
   </abi-instr>
   <abi-instr address-size='64' path='../.././gcc/diagnostic.c' comp-dir-path='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/host-x86_64-unknown-linux-gnu/gcc' language='LANG_C_plus_plus'>
     <class-decl name='maps_info' size-in-bits='192' is-struct='yes' visibility='default' filepath='../.././gcc/../libcpp/include/line-map.h' line='244' column='1' id='type-id-149'>
@@ -3007,13 +3007,13 @@ 
       <parameter type-id='type-id-27'/>
       <return type-id='type-id-137'/>
     </function-type>
-    <function-type size-in-bits='64' id='type-id-205'>
+    <function-type size-in-bits='64' id='type-id-207'>
+      <parameter type-id='type-id-27'/>
       <parameter type-id='type-id-2'/>
       <parameter type-id='type-id-2'/>
       <return type-id='type-id-27'/>
     </function-type>
-    <function-type size-in-bits='64' id='type-id-207'>
-      <parameter type-id='type-id-27'/>
+    <function-type size-in-bits='64' id='type-id-205'>
       <parameter type-id='type-id-2'/>
       <parameter type-id='type-id-2'/>
       <return type-id='type-id-27'/>