Avoid declaring a type several times in the same TU in the XML format

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>
This commit is contained in:
Dodji Seketeli 2015-08-15 00:03:07 +02:00
parent dc3211e647
commit 88ae73fdf9
2 changed files with 91 additions and 8 deletions

View 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;
}

View File

@ -1136,7 +1136,6 @@
<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'>
@ -4498,7 +4497,6 @@
<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'>
@ -7466,7 +7464,6 @@
<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'>
@ -9302,7 +9299,6 @@
<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'>
@ -10527,7 +10523,6 @@
<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'>
@ -13152,7 +13147,6 @@
<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'>
@ -14818,7 +14812,6 @@
<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'>
@ -15310,7 +15303,6 @@
<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'>