]> sourceware.org Git - libabigail.git/commitdiff
Avoid declaring a type several times in the same TU in the XML format
authorDodji Seketeli <dodji@redhat.com>
Fri, 14 Aug 2015 22:03:07 +0000 (00:03 +0200)
committerDodji Seketeli <dodji@redhat.com>
Fri, 14 Aug 2015 22:03:07 +0000 (00:03 +0200)
It appears a lot of duplicated type declarations can appear in a given
translation unit.  This patch avoids that.

* src/abg-writer.cc (write_context::{record_type_id_as_emitted,
record_type_as_emitted, type_id_is_emitted, type_is_emitted,
clear_emitted_types_map}): New member functions.
(write_context::m_emitted_type_id_map): New data member.
(write_translation_unit): Clear the per-translation unit map of
emitted types.  Do not emit a type that has already been emitted
in this translation unit.
(write_namespace_decl): Do not emit a type that has already been
emitted in this translation unit.
(write_type_decl, write_qualified_type_def)
(write_pointer_type_def, write_reference_type_def)
(write_array_type_def, write_typedef_decl, write_class_decl)
(write_type_tparameter, write_template_tparameter): Record the
type we've just written as having been written out.
* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Adjust as
duplicated declarations got removed.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
src/abg-writer.cc
tests/data/test-read-dwarf/test9-pr18818-clang.so.abi

index e0dcc969ce25258536a481fca131c224e83464ce..28ba7f034b8e7696fb7caeff0ccb3cc744f5d06d 100644 (file)
@@ -200,6 +200,56 @@ public:
   clear_type_id_map()
   {m_type_id_map.clear();}
 
+  /// Record a given type id as belonging to a type that as been
+  /// written out to the XML output.
+  ///
+  /// @param id the ID of the type.
+  void
+  record_type_id_as_emitted(const string& id)
+  {m_emitted_type_id_map[id] = true;}
+
+  /// Flag a type as having been written out to the XML output.
+  ///
+  /// @param t the type to flag.
+  void
+  record_type_as_emitted(const type_base_sptr& t)
+  {
+    string id = get_id_for_type(t);
+    record_type_id_as_emitted(id);
+  }
+
+  /// Test if a given type ID belongs to a type that has been written
+  /// out to the XML output.
+  ///
+  /// @param id the ID of the type to test.
+  ///
+  /// @return true if the type has already been emitted, false
+  /// otherwise.
+  bool
+  type_id_is_emitted(const string& id)
+  {return m_emitted_type_id_map.find(id) != m_emitted_type_id_map.end();}
+
+  /// Test if a given type has been written out to the XML output.
+  ///
+  /// @param the type to test for.
+  ///
+  /// @return true if the type has already been emitted, false
+  /// otherwise.
+  bool
+  type_is_emitted(const type_base_sptr& t)
+  {
+    if (!type_has_existing_id(t))
+      return false;
+    string id = get_id_for_type(t);
+    return type_id_is_emitted(id);
+  }
+
+  /// Clear the map that contains the IDs of the types that has been
+  /// recorded as having been written out to the XML output.
+  void
+  clear_emitted_types_map()
+  {m_emitted_type_id_map.clear();}
+
   const string_elf_symbol_sptr_map_type&
   get_fun_symbol_map() const
   {return m_fun_symbol_map;}
@@ -213,6 +263,7 @@ private:
   config                               m_config;
   ostream&                             m_ostream;
   type_ptr_map                         m_type_id_map;
+  unordered_map<string, bool>          m_emitted_type_id_map;
   fn_tmpl_shared_ptr_map               m_fn_tmpl_id_map;
   class_tmpl_shared_ptr_map            m_class_tmpl_id_map;
   string_elf_symbol_sptr_map_type      m_fun_symbol_map;
@@ -858,6 +909,15 @@ write_translation_unit(const translation_unit&     tu,
   ostream& o = ctxt.get_ostream();
   const config& c = ctxt.get_config();
 
+  // In a given translation unit, we'd like to ensure that a given
+  // type is defined only once.  The same type can be present in
+  // several translation units, though.  They'll be canonicalized
+  // later, by the reader's code.
+  //
+  // So lets clear the map that contains the types that are emitted in
+  // the translation unit tu.
+  ctxt.clear_emitted_types_map();
+
   do_indent(o, indent);
 
   o << "<abi-instr version='"
@@ -890,6 +950,11 @@ write_translation_unit(const translation_unit&     tu,
 
   for (const_iterator i = d.begin(); i != d.end(); ++i)
     {
+      if (type_base_sptr t = is_type(*i))
+       if (ctxt.type_is_emitted(t))
+         // This type has already been written out to the current
+         // translation unit, so do not emit it again.
+         continue;
       o << "\n";
       write_decl(*i, ctxt, indent + c.get_xml_element_indent());
     }
@@ -996,6 +1061,8 @@ write_type_decl(const type_decl_sptr d,
 
   o << " id='" << ctxt.get_id_for_type(d) << "'" <<  "/>";
 
+  ctxt.record_type_as_emitted(d);
+
   return true;
 }
 
@@ -1030,6 +1097,11 @@ write_namespace_decl(const shared_ptr<namespace_decl> decl,
 
   for (const_iterator i = d.begin(); i != d.end(); ++i)
     {
+      if (type_base_sptr t = is_type(*i))
+       if (ctxt.type_is_emitted(t))
+         // This type has already been emitted to the current
+         // translation unit so do not emit it again.
+         continue;
       o << "\n";
       write_decl(*i, ctxt, indent + c.get_xml_element_indent());
     }
@@ -1091,6 +1163,8 @@ write_qualified_type_def(const qualified_type_def_sptr            decl,
 
   o<< " id='" << i << "'/>";
 
+  ctxt.record_type_as_emitted(decl);
+
   return true;
 }
 
@@ -1155,6 +1229,8 @@ write_pointer_type_def(const pointer_type_def_sptr        decl,
   write_location(static_pointer_cast<decl_base>(decl), o);
   o << "/>";
 
+  ctxt.record_type_as_emitted(decl);
+
   return true;
 }
 
@@ -1222,6 +1298,9 @@ write_reference_type_def(const reference_type_def_sptr            decl,
   write_location(static_pointer_cast<decl_base>(decl), o);
 
   o << "/>";
+
+  ctxt.record_type_as_emitted(decl);
+
   return true;
 }
 
@@ -1315,6 +1394,8 @@ write_array_type_def(const array_type_def_sptr            decl,
       o << "</array-type-def>";
     }
 
+  ctxt.record_type_as_emitted(decl);
+
   return true;
 }
 
@@ -1392,6 +1473,8 @@ write_enum_type_decl(const enum_type_decl_sptr    decl,
   do_indent(o, indent);
   o << "</enum-decl>";
 
+  ctxt.record_type_as_emitted(decl);
+
   return true;
 }
 
@@ -1565,6 +1648,8 @@ write_typedef_decl(const typedef_decl_sptr        decl,
 
   o << " id='" << i << "'/>";
 
+  ctxt.record_type_as_emitted(decl);
+
   return true;
 }
 
@@ -1924,6 +2009,8 @@ write_class_decl(const class_decl_sptr    decl,
       o << "</class-decl>";
     }
 
+  ctxt.record_type_as_emitted(decl);
+
   return true;
 }
 
@@ -2032,6 +2119,8 @@ write_type_tparameter(const type_tparameter_sptr  decl,
 
   o << "/>";
 
+  ctxt.record_type_as_emitted(decl);
+
   return true;
 }
 
@@ -2117,6 +2206,8 @@ write_template_tparameter (const template_tparameter_sptr decl,
   do_indent_to_level(ctxt, indent, 0);
   o << "</template-template-parameter>";
 
+  ctxt.record_type_as_emitted(decl);
+
   return true;
 }
 
index 6b65ffe5935086ec0af6a2b21e92aa985094a2a4..e2d456c01577a71d1a4d016115ed4becec58a040 100644 (file)
     <function-decl name='fgetc' filepath='/usr/include/stdio.h' line='531' column='1' visibility='default' binding='global' size-in-bits='64'>
       <return type-id='type-id-3'/>
     </function-decl>
-    <class-decl name='__anonymous_struct__' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-22'/>
     <typedef-decl name='_G_fpos_t' type-id='type-id-22' filepath='/usr/include/_G_config.h' line='25' column='1' id='type-id-48'/>
     <typedef-decl name='fpos_t' type-id='type-id-48' filepath='/usr/include/stdio.h' line='110' column='1' id='type-id-49'/>
     <function-decl name='fgetpos' filepath='/usr/include/stdio.h' line='798' column='1' visibility='default' binding='global' size-in-bits='64'>
     <function-decl name='fgetc' filepath='/usr/include/stdio.h' line='531' column='1' visibility='default' binding='global' size-in-bits='64'>
       <return type-id='type-id-3'/>
     </function-decl>
-    <class-decl name='__anonymous_struct__' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-22'/>
     <typedef-decl name='_G_fpos64_t' type-id='type-id-22' filepath='/usr/include/_G_config.h' line='30' column='1' id='type-id-200'/>
     <typedef-decl name='fpos_t' type-id='type-id-200' filepath='/usr/include/stdio.h' line='112' column='1' id='type-id-201'/>
     <function-decl name='fgetpos' mangled-name='fgetpos64' filepath='/usr/include/stdio.h' line='806' column='1' visibility='default' binding='global' size-in-bits='64'>
     <function-decl name='fgetc' filepath='/usr/include/stdio.h' line='531' column='1' visibility='default' binding='global' size-in-bits='64'>
       <return type-id='type-id-3'/>
     </function-decl>
-    <class-decl name='__anonymous_struct__' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-22'/>
     <typedef-decl name='_G_fpos_t' type-id='type-id-22' filepath='/usr/include/_G_config.h' line='25' column='1' id='type-id-48'/>
     <typedef-decl name='fpos_t' type-id='type-id-48' filepath='/usr/include/stdio.h' line='110' column='1' id='type-id-49'/>
     <function-decl name='fgetpos' filepath='/usr/include/stdio.h' line='798' column='1' visibility='default' binding='global' size-in-bits='64'>
     <function-decl name='fgetc' filepath='/usr/include/stdio.h' line='531' column='1' visibility='default' binding='global' size-in-bits='64'>
       <return type-id='type-id-3'/>
     </function-decl>
-    <class-decl name='__anonymous_struct__' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-22'/>
     <typedef-decl name='_G_fpos_t' type-id='type-id-22' filepath='/usr/include/_G_config.h' line='25' column='1' id='type-id-48'/>
     <typedef-decl name='fpos_t' type-id='type-id-48' filepath='/usr/include/stdio.h' line='110' column='1' id='type-id-49'/>
     <function-decl name='fgetpos' filepath='/usr/include/stdio.h' line='798' column='1' visibility='default' binding='global' size-in-bits='64'>
     <function-decl name='fgetc' filepath='/usr/include/stdio.h' line='531' column='1' visibility='default' binding='global' size-in-bits='64'>
       <return type-id='type-id-3'/>
     </function-decl>
-    <class-decl name='__anonymous_struct__' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-22'/>
     <typedef-decl name='_G_fpos_t' type-id='type-id-22' filepath='/usr/include/_G_config.h' line='25' column='1' id='type-id-48'/>
     <typedef-decl name='fpos_t' type-id='type-id-48' filepath='/usr/include/stdio.h' line='110' column='1' id='type-id-49'/>
     <function-decl name='fgetpos' filepath='/usr/include/stdio.h' line='798' column='1' visibility='default' binding='global' size-in-bits='64'>
     <function-decl name='fgetc' filepath='/usr/include/stdio.h' line='531' column='1' visibility='default' binding='global' size-in-bits='64'>
       <return type-id='type-id-3'/>
     </function-decl>
-    <class-decl name='__anonymous_struct__' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-22'/>
     <typedef-decl name='_G_fpos_t' type-id='type-id-22' filepath='/usr/include/_G_config.h' line='25' column='1' id='type-id-48'/>
     <typedef-decl name='fpos_t' type-id='type-id-48' filepath='/usr/include/stdio.h' line='110' column='1' id='type-id-49'/>
     <function-decl name='fgetpos' filepath='/usr/include/stdio.h' line='798' column='1' visibility='default' binding='global' size-in-bits='64'>
     <function-decl name='fgetc' filepath='/usr/include/stdio.h' line='531' column='1' visibility='default' binding='global' size-in-bits='64'>
       <return type-id='type-id-3'/>
     </function-decl>
-    <class-decl name='__anonymous_struct__' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-22'/>
     <typedef-decl name='_G_fpos_t' type-id='type-id-22' filepath='/usr/include/_G_config.h' line='25' column='1' id='type-id-48'/>
     <typedef-decl name='fpos_t' type-id='type-id-48' filepath='/usr/include/stdio.h' line='110' column='1' id='type-id-49'/>
     <function-decl name='fgetpos' filepath='/usr/include/stdio.h' line='798' column='1' visibility='default' binding='global' size-in-bits='64'>
     <function-decl name='getwchar' filepath='/usr/include/wchar.h' line='752' column='1' visibility='default' binding='global' size-in-bits='64'>
       <return type-id='type-id-35'/>
     </function-decl>
-    <class-decl name='__anonymous_struct__' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-22'/>
     <typedef-decl name='__mbstate_t' type-id='type-id-22' filepath='/usr/include/wchar.h' line='94' column='1' id='type-id-268'/>
     <typedef-decl name='mbstate_t' type-id='type-id-268' filepath='/usr/include/wchar.h' line='106' column='1' id='type-id-269'/>
     <function-decl name='mbrlen' filepath='/usr/include/wchar.h' line='376' column='1' visibility='default' binding='global' size-in-bits='64'>
This page took 0.068346 seconds and 5 git commands to generate.