[1/3] Improve and stabilise sort of member functions

Message ID 20201029122100.765143-1-maennich@google.com
State New
Headers
Series [1/3] Improve and stabilise sort of member functions |

Commit Message

Matthias Männich Oct. 29, 2020, 12:20 p.m. UTC
  From: Giuliano Procida <gprocida@google.com>

The functor virtual_member_function_less_than did not take into
account linkage name which can be the only difference when multiple
destructors with differing mangled names are present.

This change adds a check for linkage names and also flattens the
control flow in the comparison method to make the logic clearer.

Lastly, this change also uses std::stable_sort, in case all that
remains is insertion order.

	* src/abg-ir.cc
	(virtual_member_function_less_than::operator()): Name
	temporaries like offsets and symbols to reduce repetition;
	test each pair of elements (including symbol presence) and
	return immediately if there's a difference; add a comparison
	of linkage name just after comparing symbol names.
	(sort_virtual_member_functions): Use stable_sort instead of
	sort.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
	Update with new ordering of member functions.
	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
	Likewise.

Signed-off-by: Giuliano Procida <gprocida@google.com>
Signed-off-by: Matthias Maennich <maennich@google.com>
---
 src/abg-ir.cc                                 | 82 +++++++++----------
 .../PR22015-libboost_iostreams.so.abi         |  8 +-
 .../test22-pr19097-libstdc++.so.6.0.17.so.abi | 78 +++++++++---------
 3 files changed, 80 insertions(+), 88 deletions(-)
  

Comments

Matthias Männich Oct. 29, 2020, 12:30 p.m. UTC | #1
On Thu, Oct 29, 2020 at 12:21:00PM +0000, Matthias Maennich wrote:
>Location expressions might occasionally be of length 0. E.g. a reason
>for that are thread local variables that do not exactly have a location
>to refer to. Compilers/Linkers may choose an odd representation. E.g.
>see the dwarfdump output for the added testcase based on libandroid.so
>(from AOSP).
>
>$ dwarfdump libandroid.so|egrep -B9 "gChoreographerE$"
>
>LOCAL_SYMBOLS:
>< 1><0x00000022> DW_TAG_namespace
>                   DW_AT_name           android
>< 2><0x00000027>   DW_TAG_variable
>                     DW_AT_name           gChoreographer
>                     DW_AT_type           <0x00000b65>
>                     DW_AT_decl_file      0x00000003 .../choreographer.cpp
>                     DW_AT_decl_line      0x00000059
>                     DW_AT_location       len 0x0000: :
>                     DW_AT_linkage_name   _ZN7androidL14gChoreographerE
>
>The DW_AT_location is properly read by elfutils' dwarf_location(), but
>is not useful for us to proceed with. Hence early exit on this.
>
>	* src/abg-dwarf-reader.cc (die_location_expr): Ignore zero
>	  length location expressions.
>	* tests/data/Makefile.am: Add new test files.
>	* tests/data/test-read-dwarf/test-libandroid.so: New test file.
>	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
>	* tests/test-read-dwarf.cc: Add new test case.
>
>Reported-by: Dan Albert <danalbert@google.com>
>Reviewed-by: Giuliano Procida <gprocida@google.com>
>Cc: Mark Wielaard <mark@klomp.org>
>Signed-off-by: Matthias Maennich <maennich@google.com>
>---
> src/abg-dwarf-reader.cc                       |    10 +-
> tests/data/Makefile.am                        |     2 +
> tests/data/test-read-dwarf/test-libandroid.so |   Bin 0 -> 2579424 bytes
> .../test-read-dwarf/test-libandroid.so.abi    | 86949 ++++++++++++++++
> tests/test-read-dwarf.cc                      |     7 +
> 5 files changed, 86965 insertions(+), 3 deletions(-)
> create mode 100644 tests/data/test-read-dwarf/test-libandroid.so
> create mode 100644 tests/data/test-read-dwarf/test-libandroid.so.abi
>

Since this hit the mailing list size limit, I posted this series to
github:

https://github.com/metti/libabigail/tree/xml-stability-fixes

Cheers,
Matthias
  
Mark Wielaard Oct. 29, 2020, 2 p.m. UTC | #2
Hi,

On Thu, 2020-10-29 at 12:30 +0000, Matthias Maennich wrote:
> On Thu, Oct 29, 2020 at 12:21:00PM +0000, Matthias Maennich wrote:
> > Location expressions might occasionally be of length 0. E.g. a reason
> > for that are thread local variables that do not exactly have a location
> > to refer to. Compilers/Linkers may choose an odd representation. E.g.
> > see the dwarfdump output for the added testcase based on libandroid.so
> > (from AOSP).

I don't think it is "odd", it is simply an empty location expression,
which is defined as no location known.

> > The DW_AT_location is properly read by elfutils' dwarf_location(), but
> > is not useful for us to proceed with. Hence early exit on this.
> > 
> > 	* src/abg-dwarf-reader.cc (die_location_expr): Ignore zero
> > 	  length location expressions.
> > 	* tests/data/Makefile.am: Add new test files.
> > 	* tests/data/test-read-dwarf/test-libandroid.so: New test file.
> > 	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
> > 	* tests/test-read-dwarf.cc: Add new test case.
> > 
> > Reported-by: Dan Albert <danalbert@google.com>
> > Reviewed-by: Giuliano Procida <gprocida@google.com>
> > Cc: Mark Wielaard <mark@klomp.org>
> > Signed-off-by: Matthias Maennich <maennich@google.com>

> [...]

>   // Ignore invalid location expressions where reading them succeeded but their
>   // length is 0.
>   result &= len > 0;

The actual code change looks correct, but I would like the comment to
not say they are invalid (if they were dwarf_getlocation would have
returned an error), but that an empty location expression represents an
unknown location (and so it is indeed not very useful).

See also DWARFv5 2.6.1.1.1 Empty Location Descriptions

   An empty location description consists of a DWARF expression
   containing no operations. It represents a piece or all of an object
   that is present in the source but not in the object code (perhaps
   due to optimization).

Cheers,

Mark
  
Matthias Männich Oct. 29, 2020, 2:29 p.m. UTC | #3
Hi Mark!

On Thu, Oct 29, 2020 at 03:00:20PM +0100, Mark Wielaard wrote:
>Hi,
>
>On Thu, 2020-10-29 at 12:30 +0000, Matthias Maennich wrote:
>> On Thu, Oct 29, 2020 at 12:21:00PM +0000, Matthias Maennich wrote:
>> > Location expressions might occasionally be of length 0. E.g. a reason
>> > for that are thread local variables that do not exactly have a location
>> > to refer to. Compilers/Linkers may choose an odd representation. E.g.
>> > see the dwarfdump output for the added testcase based on libandroid.so
>> > (from AOSP).
>
>I don't think it is "odd", it is simply an empty location expression,
>which is defined as no location known.

You are right. I will use the 'empty location expression' terminology
instead.

>
>> > The DW_AT_location is properly read by elfutils' dwarf_location(), but
>> > is not useful for us to proceed with. Hence early exit on this.
>> >
>> > 	* src/abg-dwarf-reader.cc (die_location_expr): Ignore zero
>> > 	  length location expressions.
>> > 	* tests/data/Makefile.am: Add new test files.
>> > 	* tests/data/test-read-dwarf/test-libandroid.so: New test file.
>> > 	* tests/data/test-read-dwarf/test-libandroid.so.abi: Likewise.
>> > 	* tests/test-read-dwarf.cc: Add new test case.
>> >
>> > Reported-by: Dan Albert <danalbert@google.com>
>> > Reviewed-by: Giuliano Procida <gprocida@google.com>
>> > Cc: Mark Wielaard <mark@klomp.org>
>> > Signed-off-by: Matthias Maennich <maennich@google.com>
>
>> [...]
>
>>   // Ignore invalid location expressions where reading them succeeded but their
>>   // length is 0.
>>   result &= len > 0;
>
>The actual code change looks correct, but I would like the comment to
>not say they are invalid (if they were dwarf_getlocation would have
>returned an error), but that an empty location expression represents an
>unknown location (and so it is indeed not very useful).
>
>See also DWARFv5 2.6.1.1.1 Empty Location Descriptions
>
>   An empty location description consists of a DWARF expression
>   containing no operations. It represents a piece or all of an object
>   that is present in the source but not in the object code (perhaps
>   due to optimization).
>

I dropped the "invalid" wording everywhere after your last comment, but
forgot to change this very line :-/

I updated code change and commit message and pushed a new version to
Github:
https://github.com/metti/libabigail/commit/eb8c694cbc1e8a8c3d08872930af1a30df9f6d05

Cheers,
Matthias

>Cheers,
>
>Mark
  
Dodji Seketeli Nov. 2, 2020, 3:34 p.m. UTC | #4
Matthias Maennich <maennich@google.com> a écrit:

> From: Giuliano Procida <gprocida@google.com>
>
> The functor virtual_member_function_less_than did not take into
> account linkage name which can be the only difference when multiple
> destructors with differing mangled names are present.
>
> This change adds a check for linkage names and also flattens the
> control flow in the comparison method to make the logic clearer.
>
> Lastly, this change also uses std::stable_sort, in case all that
> remains is insertion order.
>
> 	* src/abg-ir.cc
> 	(virtual_member_function_less_than::operator()): Name
> 	temporaries like offsets and symbols to reduce repetition;
> 	test each pair of elements (including symbol presence) and
> 	return immediately if there's a difference; add a comparison
> 	of linkage name just after comparing symbol names.
> 	(sort_virtual_member_functions): Use stable_sort instead of
> 	sort.
> 	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi:
> 	Update with new ordering of member functions.
> 	* tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi:
> 	Likewise.
>
> Signed-off-by: Giuliano Procida <gprocida@google.com>
> Signed-off-by: Matthias Maennich <maennich@google.com>

Applied to master.

Thanks!
  
Dodji Seketeli Nov. 2, 2020, 4:48 p.m. UTC | #5
Matthias Maennich <maennich@google.com> a écrit:

[...]

> Since this hit the mailing list size limit,

Oops ,I didn't notice the email notification telling me about the list
size limit.  I approved the patch anyway so you should see it on the
list now.

> I posted this series to
> github:
>
> https://github.com/metti/libabigail/tree/xml-stability-fixes

Thanks!

Cheers,
  
Dodji Seketeli Nov. 2, 2020, 5:08 p.m. UTC | #6
Hey,

Matthias Maennich <maennich@google.com> a écrit:

[...]

> I updated code change and commit message and pushed a new version to
> Github:
> https://github.com/metti/libabigail/commit/eb8c694cbc1e8a8c3d08872930af1a30df9f6d05

Thanks.  In the future, I think you can just keep sending the patches to
the list.  I should be able to make them move through the pipe once I
receive the notification from mailman.

Applied to master!

Cheers,
  

Patch

diff --git a/src/abg-ir.cc b/src/abg-ir.cc
index e491528922d3..29711db6057c 100644
--- a/src/abg-ir.cc
+++ b/src/abg-ir.cc
@@ -20487,53 +20487,45 @@  struct virtual_member_function_less_than
     ABG_ASSERT(get_member_function_is_virtual(f));
     ABG_ASSERT(get_member_function_is_virtual(s));
 
-    if (get_member_function_vtable_offset(f)
-	== get_member_function_vtable_offset(s))
+    ssize_t f_offset = get_member_function_vtable_offset(f);
+    ssize_t s_offset = get_member_function_vtable_offset(s);
+    if (f_offset != s_offset) return f_offset < s_offset;
+
+    string fn, sn;
+
+    // If the functions have symbols, then compare their symbol-id
+    // string.
+    elf_symbol_sptr f_sym = f.get_symbol();
+    elf_symbol_sptr s_sym = s.get_symbol();
+    if ((!f_sym) != (!s_sym)) return !f_sym;
+    if (f_sym && s_sym)
       {
-	string fn, sn;
-
-	// If the functions have symbols, then compare their symbol-id
-	// string.
-	if (f.get_symbol() && s.get_symbol())
-	  {
-	    fn = f.get_symbol()->get_id_string();
-	    sn = s.get_symbol()->get_id_string();
-	  }
-	else if (f.get_symbol())
-	  return false;
-	else if (s.get_symbol())
-	  return true;
-	else
-	  {
-	    // None of the functions have symbols, so compare their
-	    // pretty representation.
-	    if (fn.empty())
-	      {
-		fn = f.get_pretty_representation();
-		sn = s.get_pretty_representation();
-	      }
-	  }
-
-	/// If it's just the file paths that are different then sort
-	/// them too.
-	if (fn == sn)
-	  {
-	    string fn_filepath, sn_filepath;
-	    unsigned line = 0, column = 0;
-	    location fn_loc = f.get_location(), sn_loc = s.get_location();
-	    if (fn_loc)
-	      fn_loc.expand(fn_filepath, line, column);
-	    if (sn_loc)
-	      sn_loc.expand(sn_filepath, line, column);
-
-	    if (!fn_filepath.empty() && !sn_filepath.empty())
-	      return fn_filepath < sn_filepath;
-	  }
-	return fn < sn;
+	fn = f_sym->get_id_string();
+	sn = s_sym->get_id_string();
+	if (fn != sn) return fn < sn;
       }
 
-    return (get_member_function_vtable_offset(f)
-	    < get_member_function_vtable_offset(s));
+    // Try the linkage names (important for destructors).
+    fn = f.get_linkage_name();
+    sn = s.get_linkage_name();
+    if (fn != sn) return fn < sn;
+
+    // None of the functions have symbols or linkage names that
+    // distinguish them, so compare their pretty representation.
+    fn = f.get_pretty_representation();
+    sn = s.get_pretty_representation();
+    if (fn != sn) return fn < sn;
+
+    /// If it's just the file paths that are different then sort them
+    /// too.
+    string fn_filepath, sn_filepath;
+    unsigned line = 0, column = 0;
+    location fn_loc = f.get_location(), sn_loc = s.get_location();
+    if (fn_loc)
+      fn_loc.expand(fn_filepath, line, column);
+    if (sn_loc)
+      sn_loc.expand(sn_filepath, line, column);
+    return fn_filepath < sn_filepath;
   }
 
   /// The less than operator.  First, it sorts the methods by their
@@ -20560,7 +20552,7 @@  static void
 sort_virtual_member_functions(class_decl::member_functions& mem_fns)
 {
   virtual_member_function_less_than lt;
-  std::sort(mem_fns.begin(), mem_fns.end(), lt);
+  std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
 }
 
 /// Add a member function to the current instance of @ref class_or_union.
diff --git a/tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi b/tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi
index c4b1e75499f2..00921cd53016 100644
--- a/tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi
+++ b/tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi
@@ -1031,13 +1031,13 @@ 
             </function-decl>
           </member-function>
           <member-function access='public' destructor='yes' vtable-offset='0'>
-            <function-decl name='~clone_impl' mangled-name='_ZN5boost16exception_detail10clone_implINS0_19error_info_injectorINSt8ios_base7failureB5cxx11EEEED1Ev' filepath='src/third_party/boost-1.60.0/boost/exception/exception.hpp' line='462' column='1' visibility='default' binding='global' size-in-bits='64'>
+            <function-decl name='~clone_impl' mangled-name='_ZN5boost16exception_detail10clone_implINS0_19error_info_injectorINSt8ios_base7failureB5cxx11EEEED0Ev' filepath='src/third_party/boost-1.60.0/boost/exception/exception.hpp' line='462' column='1' visibility='default' binding='global' size-in-bits='64'>
               <parameter type-id='type-id-76' is-artificial='yes'/>
               <return type-id='type-id-18'/>
             </function-decl>
           </member-function>
           <member-function access='public' destructor='yes' vtable-offset='0'>
-            <function-decl name='~clone_impl' mangled-name='_ZN5boost16exception_detail10clone_implINS0_19error_info_injectorINSt8ios_base7failureB5cxx11EEEED0Ev' filepath='src/third_party/boost-1.60.0/boost/exception/exception.hpp' line='462' column='1' visibility='default' binding='global' size-in-bits='64'>
+            <function-decl name='~clone_impl' mangled-name='_ZN5boost16exception_detail10clone_implINS0_19error_info_injectorINSt8ios_base7failureB5cxx11EEEED1Ev' filepath='src/third_party/boost-1.60.0/boost/exception/exception.hpp' line='462' column='1' visibility='default' binding='global' size-in-bits='64'>
               <parameter type-id='type-id-76' is-artificial='yes'/>
               <return type-id='type-id-18'/>
             </function-decl>
@@ -1072,13 +1072,13 @@ 
             </function-decl>
           </member-function>
           <member-function access='public' destructor='yes' vtable-offset='0'>
-            <function-decl name='~error_info_injector' mangled-name='_ZN5boost16exception_detail19error_info_injectorINSt8ios_base7failureB5cxx11EED2Ev' filepath='src/third_party/boost-1.60.0/boost/exception/exception.hpp' line='336' column='1' visibility='default' binding='global' size-in-bits='64'>
+            <function-decl name='~error_info_injector' mangled-name='_ZN5boost16exception_detail19error_info_injectorINSt8ios_base7failureB5cxx11EED0Ev' filepath='src/third_party/boost-1.60.0/boost/exception/exception.hpp' line='336' column='1' visibility='default' binding='global' size-in-bits='64'>
               <parameter type-id='type-id-80' is-artificial='yes'/>
               <return type-id='type-id-18'/>
             </function-decl>
           </member-function>
           <member-function access='public' destructor='yes' vtable-offset='0'>
-            <function-decl name='~error_info_injector' mangled-name='_ZN5boost16exception_detail19error_info_injectorINSt8ios_base7failureB5cxx11EED0Ev' filepath='src/third_party/boost-1.60.0/boost/exception/exception.hpp' line='336' column='1' visibility='default' binding='global' size-in-bits='64'>
+            <function-decl name='~error_info_injector' mangled-name='_ZN5boost16exception_detail19error_info_injectorINSt8ios_base7failureB5cxx11EED2Ev' filepath='src/third_party/boost-1.60.0/boost/exception/exception.hpp' line='336' column='1' visibility='default' binding='global' size-in-bits='64'>
               <parameter type-id='type-id-80' is-artificial='yes'/>
               <return type-id='type-id-18'/>
             </function-decl>
diff --git a/tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi b/tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi
index b6faf148d63e..0c3611ebbf7b 100644
--- a/tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi
+++ b/tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi
@@ -4518,14 +4518,14 @@ 
           </function-decl>
         </member-function>
         <member-function access='private' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~__forced_unwind' mangled-name='_ZN10__cxxabiv115__forced_unwindD2Ev' filepath='../../.././libstdc++-v3/libsupc++/eh_exception.cc' line='35' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~__forced_unwind' mangled-name='_ZN10__cxxabiv115__forced_unwindD0Ev' filepath='../../.././libstdc++-v3/libsupc++/eh_exception.cc' line='35' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-98' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
           </function-decl>
         </member-function>
         <member-function access='private' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~__forced_unwind' mangled-name='_ZN10__cxxabiv115__forced_unwindD0Ev' filepath='../../.././libstdc++-v3/libsupc++/eh_exception.cc' line='35' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~__forced_unwind' mangled-name='_ZN10__cxxabiv115__forced_unwindD2Ev' filepath='../../.././libstdc++-v3/libsupc++/eh_exception.cc' line='35' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-98' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
@@ -4547,14 +4547,14 @@ 
           </function-decl>
         </member-function>
         <member-function access='private' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~__foreign_exception' mangled-name='_ZN10__cxxabiv119__foreign_exceptionD2Ev' filepath='../../.././libstdc++-v3/libsupc++/eh_exception.cc' line='37' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~__foreign_exception' mangled-name='_ZN10__cxxabiv119__foreign_exceptionD0Ev' filepath='../../.././libstdc++-v3/libsupc++/eh_exception.cc' line='37' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-100' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
           </function-decl>
         </member-function>
         <member-function access='private' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~__foreign_exception' mangled-name='_ZN10__cxxabiv119__foreign_exceptionD0Ev' filepath='../../.././libstdc++-v3/libsupc++/eh_exception.cc' line='37' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~__foreign_exception' mangled-name='_ZN10__cxxabiv119__foreign_exceptionD2Ev' filepath='../../.././libstdc++-v3/libsupc++/eh_exception.cc' line='37' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-100' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
@@ -5081,14 +5081,14 @@ 
           </function-decl>
         </member-function>
         <member-function access='private' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~recursive_init_error' mangled-name='_ZN9__gnu_cxx20recursive_init_errorD2Ev' filepath='../../.././libstdc++-v3/libsupc++/guard_error.cc' line='29' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~recursive_init_error' mangled-name='_ZN9__gnu_cxx20recursive_init_errorD0Ev' filepath='../../.././libstdc++-v3/libsupc++/guard_error.cc' line='29' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-131' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
           </function-decl>
         </member-function>
         <member-function access='private' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~recursive_init_error' mangled-name='_ZN9__gnu_cxx20recursive_init_errorD0Ev' filepath='../../.././libstdc++-v3/libsupc++/guard_error.cc' line='29' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~recursive_init_error' mangled-name='_ZN9__gnu_cxx20recursive_init_errorD2Ev' filepath='../../.././libstdc++-v3/libsupc++/guard_error.cc' line='29' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-131' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
@@ -28550,14 +28550,14 @@ 
           </function-decl>
         </member-function>
         <member-function access='protected' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~__codecvt_abstract_base' mangled-name='_ZNSt23__codecvt_abstract_baseIcc11__mbstate_tED2Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/codecvt.h' line='228' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~__codecvt_abstract_base' mangled-name='_ZNSt23__codecvt_abstract_baseIcc11__mbstate_tED0Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/codecvt.h' line='228' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-2058' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
           </function-decl>
         </member-function>
         <member-function access='protected' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~__codecvt_abstract_base' mangled-name='_ZNSt23__codecvt_abstract_baseIcc11__mbstate_tED0Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/codecvt.h' line='228' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~__codecvt_abstract_base' mangled-name='_ZNSt23__codecvt_abstract_baseIcc11__mbstate_tED2Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/codecvt.h' line='228' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-2058' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
@@ -28722,14 +28722,14 @@ 
           </function-decl>
         </member-function>
         <member-function access='protected' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~__codecvt_abstract_base' mangled-name='_ZNSt23__codecvt_abstract_baseIwc11__mbstate_tED2Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/codecvt.h' line='228' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~__codecvt_abstract_base' mangled-name='_ZNSt23__codecvt_abstract_baseIwc11__mbstate_tED0Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/codecvt.h' line='228' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-2060' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
           </function-decl>
         </member-function>
         <member-function access='protected' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~__codecvt_abstract_base' mangled-name='_ZNSt23__codecvt_abstract_baseIwc11__mbstate_tED0Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/codecvt.h' line='228' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~__codecvt_abstract_base' mangled-name='_ZNSt23__codecvt_abstract_baseIwc11__mbstate_tED2Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/codecvt.h' line='228' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-2060' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
@@ -30889,14 +30889,14 @@ 
           </function-decl>
         </member-function>
         <member-function access='protected' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~__ctype_abstract_base' mangled-name='_ZNSt21__ctype_abstract_baseIwED2Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='357' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~__ctype_abstract_base' mangled-name='_ZNSt21__ctype_abstract_baseIwED0Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='357' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-2263' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
           </function-decl>
         </member-function>
         <member-function access='protected' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~__ctype_abstract_base' mangled-name='_ZNSt21__ctype_abstract_baseIwED0Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='357' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~__ctype_abstract_base' mangled-name='_ZNSt21__ctype_abstract_baseIwED2Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='357' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-2263' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
@@ -32608,13 +32608,6 @@ 
             <return type-id='type-id-5'/>
           </function-decl>
         </member-function>
-        <member-function access='protected' const='yes' vtable-offset='2'>
-          <function-decl name='do_toupper' mangled-name='_ZNKSt5ctypeIcE10do_toupperEc' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='1007' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZNKSt5ctypeIcE10do_toupperEc@@GLIBCXX_3.4'>
-            <parameter type-id='type-id-2350' is-artificial='yes'/>
-            <parameter type-id='type-id-2351'/>
-            <return type-id='type-id-2351'/>
-          </function-decl>
-        </member-function>
         <member-function access='protected' const='yes' vtable-offset='2'>
           <function-decl name='do_toupper' mangled-name='_ZNKSt5ctypeIcE10do_toupperEc' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/src/c++98/ctype_configure_char.cc' line='166' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZNKSt5ctypeIcE10do_toupperEc@@GLIBCXX_3.4'>
             <parameter type-id='type-id-2350' is-artificial='yes'/>
@@ -32622,12 +32615,11 @@ 
             <return type-id='type-id-186'/>
           </function-decl>
         </member-function>
-        <member-function access='protected' const='yes' vtable-offset='3'>
-          <function-decl name='do_toupper' mangled-name='_ZNKSt5ctypeIcE10do_toupperEPcPKc' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='1024' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZNKSt5ctypeIcE10do_toupperEPcPKc@@GLIBCXX_3.4'>
+        <member-function access='protected' const='yes' vtable-offset='2'>
+          <function-decl name='do_toupper' mangled-name='_ZNKSt5ctypeIcE10do_toupperEc' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='1007' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZNKSt5ctypeIcE10do_toupperEc@@GLIBCXX_3.4'>
             <parameter type-id='type-id-2350' is-artificial='yes'/>
-            <parameter type-id='type-id-2357'/>
-            <parameter type-id='type-id-2353'/>
-            <return type-id='type-id-2353'/>
+            <parameter type-id='type-id-2351'/>
+            <return type-id='type-id-2351'/>
           </function-decl>
         </member-function>
         <member-function access='protected' const='yes' vtable-offset='3'>
@@ -32638,11 +32630,12 @@ 
             <return type-id='type-id-4'/>
           </function-decl>
         </member-function>
-        <member-function access='protected' const='yes' vtable-offset='4'>
-          <function-decl name='do_tolower' mangled-name='_ZNKSt5ctypeIcE10do_tolowerEc' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='1040' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZNKSt5ctypeIcE10do_tolowerEc@@GLIBCXX_3.4'>
+        <member-function access='protected' const='yes' vtable-offset='3'>
+          <function-decl name='do_toupper' mangled-name='_ZNKSt5ctypeIcE10do_toupperEPcPKc' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='1024' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZNKSt5ctypeIcE10do_toupperEPcPKc@@GLIBCXX_3.4'>
             <parameter type-id='type-id-2350' is-artificial='yes'/>
-            <parameter type-id='type-id-2351'/>
-            <return type-id='type-id-2351'/>
+            <parameter type-id='type-id-2357'/>
+            <parameter type-id='type-id-2353'/>
+            <return type-id='type-id-2353'/>
           </function-decl>
         </member-function>
         <member-function access='protected' const='yes' vtable-offset='4'>
@@ -32652,12 +32645,11 @@ 
             <return type-id='type-id-186'/>
           </function-decl>
         </member-function>
-        <member-function access='protected' const='yes' vtable-offset='5'>
-          <function-decl name='do_tolower' mangled-name='_ZNKSt5ctypeIcE10do_tolowerEPcPKc' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='1057' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZNKSt5ctypeIcE10do_tolowerEPcPKc@@GLIBCXX_3.4'>
+        <member-function access='protected' const='yes' vtable-offset='4'>
+          <function-decl name='do_tolower' mangled-name='_ZNKSt5ctypeIcE10do_tolowerEc' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='1040' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZNKSt5ctypeIcE10do_tolowerEc@@GLIBCXX_3.4'>
             <parameter type-id='type-id-2350' is-artificial='yes'/>
-            <parameter type-id='type-id-2357'/>
-            <parameter type-id='type-id-2353'/>
-            <return type-id='type-id-2353'/>
+            <parameter type-id='type-id-2351'/>
+            <return type-id='type-id-2351'/>
           </function-decl>
         </member-function>
         <member-function access='protected' const='yes' vtable-offset='5'>
@@ -32668,6 +32660,14 @@ 
             <return type-id='type-id-4'/>
           </function-decl>
         </member-function>
+        <member-function access='protected' const='yes' vtable-offset='5'>
+          <function-decl name='do_tolower' mangled-name='_ZNKSt5ctypeIcE10do_tolowerEPcPKc' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='1057' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZNKSt5ctypeIcE10do_tolowerEPcPKc@@GLIBCXX_3.4'>
+            <parameter type-id='type-id-2350' is-artificial='yes'/>
+            <parameter type-id='type-id-2357'/>
+            <parameter type-id='type-id-2353'/>
+            <return type-id='type-id-2353'/>
+          </function-decl>
+        </member-function>
         <member-function access='protected' const='yes' vtable-offset='6'>
           <function-decl name='do_widen' mangled-name='_ZNKSt5ctypeIcE8do_widenEc' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='1077' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZNKSt5ctypeIcE8do_widenEc@@GLIBCXX_3.4'>
             <parameter type-id='type-id-2350' is-artificial='yes'/>
@@ -32955,14 +32955,14 @@ 
           </function-decl>
         </member-function>
         <member-function access='private' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~stdio_filebuf' mangled-name='_ZN9__gnu_cxx13stdio_filebufIwSt11char_traitsIwEED2Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/ext/stdio_filebuf.h' line='124' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~stdio_filebuf' mangled-name='_ZN9__gnu_cxx13stdio_filebufIwSt11char_traitsIwEED0Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/ext/stdio_filebuf.h' line='124' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-2428' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
           </function-decl>
         </member-function>
         <member-function access='private' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~stdio_filebuf' mangled-name='_ZN9__gnu_cxx13stdio_filebufIwSt11char_traitsIwEED0Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/ext/stdio_filebuf.h' line='124' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~stdio_filebuf' mangled-name='_ZN9__gnu_cxx13stdio_filebufIwSt11char_traitsIwEED2Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/ext/stdio_filebuf.h' line='124' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-2428' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
@@ -33042,14 +33042,14 @@ 
           </function-decl>
         </member-function>
         <member-function access='private' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~stdio_filebuf' mangled-name='_ZN9__gnu_cxx13stdio_filebufIcSt11char_traitsIcEED2Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/ext/stdio_filebuf.h' line='124' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~stdio_filebuf' mangled-name='_ZN9__gnu_cxx13stdio_filebufIcSt11char_traitsIcEED0Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/ext/stdio_filebuf.h' line='124' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-2426' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
           </function-decl>
         </member-function>
         <member-function access='private' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~stdio_filebuf' mangled-name='_ZN9__gnu_cxx13stdio_filebufIcSt11char_traitsIcEED0Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/ext/stdio_filebuf.h' line='124' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~stdio_filebuf' mangled-name='_ZN9__gnu_cxx13stdio_filebufIcSt11char_traitsIcEED2Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/ext/stdio_filebuf.h' line='124' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-2426' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
@@ -35377,14 +35377,14 @@ 
           </function-decl>
         </member-function>
         <member-function access='protected' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~__ctype_abstract_base' mangled-name='_ZNSt21__ctype_abstract_baseIcED2Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='357' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~__ctype_abstract_base' mangled-name='_ZNSt21__ctype_abstract_baseIcED0Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='357' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-2718' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>
           </function-decl>
         </member-function>
         <member-function access='protected' destructor='yes' vtable-offset='-1'>
-          <function-decl name='~__ctype_abstract_base' mangled-name='_ZNSt21__ctype_abstract_baseIcED0Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='357' column='1' visibility='default' binding='global' size-in-bits='64'>
+          <function-decl name='~__ctype_abstract_base' mangled-name='_ZNSt21__ctype_abstract_baseIcED2Ev' filepath='/tmp/legendre/spack-stage/spack-stage-wfh0ig/gcc-4.7.4/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/locale_facets.h' line='357' column='1' visibility='default' binding='global' size-in-bits='64'>
             <parameter type-id='type-id-2718' is-artificial='yes'/>
             <parameter type-id='type-id-6' is-artificial='yes'/>
             <return type-id='type-id-5'/>