mirror of
git://sourceware.org/git/libabigail.git
synced 2025-01-05 00:39:31 +00:00
reader: Avoid duplicating recursive types
Sometimes, building a sub-type of a complex type can trigger the building of the complex type itself. This is in the case of a recursive complex type where one of its sub-types has the complex type as a sub-type. In those cases, the complex type should not be duplicated. This patch ensures that. * src/abg-reader.cc (build_qualified_type_decl) (build_pointer_type_def, build_reference_type_def) (build_ptr_to_mbr_type, build_subrange_type, build_array_type_def) (build_enum_type_decl, build_typedef_decl): After a sub-type is built, check if the complex type we are looking at is built too. If it is, then return it. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
217ba7fdb8
commit
a75424b6e5
@ -4291,6 +4291,13 @@ build_qualified_type_decl(reader& rdr,
|
||||
rdr.build_or_get_type_decl(type_id, true);
|
||||
ABG_ASSERT(underlying_type);
|
||||
|
||||
if (type_base_sptr t = rdr.get_type_decl(id))
|
||||
{
|
||||
qualified_type_def_sptr result = is_qualified_type(t);
|
||||
ABG_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
qualified_type_def_sptr decl;
|
||||
if (type_base_sptr t = rdr.get_type_decl(id))
|
||||
{
|
||||
@ -4368,6 +4375,13 @@ build_pointer_type_def(reader& rdr,
|
||||
rdr.build_or_get_type_decl(type_id, true);
|
||||
ABG_ASSERT(pointed_to_type);
|
||||
|
||||
if (type_base_sptr t = rdr.get_type_decl(id))
|
||||
{
|
||||
pointer_type_def_sptr result = is_pointer_type(t);
|
||||
ABG_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
pointer_type_def_sptr t;
|
||||
if (rdr.get_environment().is_void_type(pointed_to_type))
|
||||
t = is_pointer_type(build_ir_node_for_void_pointer_type(rdr));
|
||||
@ -4457,6 +4471,15 @@ build_reference_type_def(reader& rdr,
|
||||
rdr.build_or_get_type_decl(type_id, /*add_to_current_scope=*/ true);
|
||||
ABG_ASSERT(pointed_to_type);
|
||||
|
||||
// The call to rdr.build_or_get_type_decl above might have triggered
|
||||
// the building of the current type. If so, then return it.
|
||||
if (type_base_sptr t = rdr.get_type_decl(id))
|
||||
{
|
||||
reference_type_def_sptr result = is_reference_type(t);
|
||||
ABG_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Create the reference type /before/ the pointed-to type. After
|
||||
// the creation, the type is 'keyed' using
|
||||
// rdr.push_and_key_type_decl. This means that the type can be
|
||||
@ -4538,6 +4561,13 @@ build_ptr_to_mbr_type(reader& rdr,
|
||||
if (!member_type)
|
||||
return nil;
|
||||
|
||||
if (type_base_sptr t = rdr.get_type_decl(id))
|
||||
{
|
||||
ptr_to_mbr_type_sptr result = is_ptr_to_mbr_type(t);
|
||||
ABG_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
string containing_type_id;
|
||||
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "containing-type-id"))
|
||||
containing_type_id = CHAR_STR(s);
|
||||
@ -4548,6 +4578,13 @@ build_ptr_to_mbr_type(reader& rdr,
|
||||
if (!is_typedef_of_maybe_qualified_class_or_union_type(containing_type))
|
||||
return nil;
|
||||
|
||||
if (type_base_sptr t = rdr.get_type_decl(id))
|
||||
{
|
||||
ptr_to_mbr_type_sptr result = is_ptr_to_mbr_type(t);
|
||||
ABG_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result.reset(new ptr_to_mbr_type(rdr.get_environment(),
|
||||
member_type, containing_type,
|
||||
size_in_bits, alignment_in_bits,
|
||||
@ -4755,6 +4792,13 @@ build_subrange_type(reader& rdr,
|
||||
ABG_ASSERT(underlying_type);
|
||||
}
|
||||
|
||||
if (type_base_sptr t = rdr.get_type_decl(id))
|
||||
{
|
||||
array_type_def::subrange_sptr result = is_subrange_type(t);
|
||||
ABG_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
location loc;
|
||||
read_location(rdr, node, loc);
|
||||
|
||||
@ -4846,16 +4890,6 @@ build_array_type_def(reader& rdr,
|
||||
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
|
||||
type_id = CHAR_STR(s);
|
||||
|
||||
// maybe building the type of array elements triggered building this
|
||||
// one in the mean time ...
|
||||
if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
|
||||
{
|
||||
array_type_def_sptr result =
|
||||
dynamic_pointer_cast<array_type_def>(d);
|
||||
ABG_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t size_in_bits = 0, alignment_in_bits = 0;
|
||||
bool has_size_in_bits = false;
|
||||
char *endptr;
|
||||
@ -4908,6 +4942,15 @@ build_array_type_def(reader& rdr,
|
||||
rdr.build_or_get_type_decl(type_id, true);
|
||||
ABG_ASSERT(type);
|
||||
|
||||
// maybe building the type of array elements triggered building this
|
||||
// one in the mean time ...
|
||||
if (type_base_sptr t = rdr.get_type_decl(id))
|
||||
{
|
||||
array_type_def_sptr result = is_array_type(t);
|
||||
ABG_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
array_type_def_sptr ar_type(new array_type_def(type, subranges, loc));
|
||||
// Read the stash from the XML node and stash it into the IR node.
|
||||
read_hash_and_stash(node, ar_type);
|
||||
@ -5040,6 +5083,13 @@ build_enum_type_decl(reader& rdr,
|
||||
|
||||
ABG_ASSERT(!id.empty());
|
||||
|
||||
if (type_base_sptr t = rdr.get_type_decl(id))
|
||||
{
|
||||
enum_type_decl_sptr result = is_enum_type(t);
|
||||
ABG_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
string base_type_id;
|
||||
enum_type_decl::enumerators enums;
|
||||
for (xmlNodePtr n = xmlFirstElementChild(node);
|
||||
@ -5082,6 +5132,13 @@ build_enum_type_decl(reader& rdr,
|
||||
rdr.build_or_get_type_decl(base_type_id, true);
|
||||
ABG_ASSERT(underlying_type);
|
||||
|
||||
if (type_base_sptr t = rdr.get_type_decl(id))
|
||||
{
|
||||
enum_type_decl_sptr result = is_enum_type(t);
|
||||
ABG_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
enum_type_decl_sptr t(new enum_type_decl(name, loc,
|
||||
underlying_type,
|
||||
enums, linkage_name));
|
||||
@ -5133,6 +5190,13 @@ build_typedef_decl(reader& rdr,
|
||||
id = CHAR_STR(s);
|
||||
ABG_ASSERT(!id.empty());
|
||||
|
||||
if (type_base_sptr t = rdr.get_type_decl(id))
|
||||
{
|
||||
typedef_decl_sptr result = is_typedef(t);
|
||||
ABG_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
string name;
|
||||
if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
|
||||
name = xml::unescape_xml_string(CHAR_STR(s));
|
||||
@ -5148,6 +5212,15 @@ build_typedef_decl(reader& rdr,
|
||||
type_base_sptr underlying_type(rdr.build_or_get_type_decl(type_id, true));
|
||||
ABG_ASSERT(underlying_type);
|
||||
|
||||
// Maybe the building of the underlying type triggered the building
|
||||
// of the current type. If so, then return it.
|
||||
if (type_base_sptr t = rdr.get_type_decl(id))
|
||||
{
|
||||
typedef_decl_sptr result = is_typedef(t);
|
||||
ABG_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef_decl_sptr t(new typedef_decl(name, underlying_type, loc));
|
||||
maybe_set_artificial_location(rdr, node, t);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user