Late canonicalize all types that reference classes when reading DWARF

Until now, the DWARF reader would late canonicalize typedefs to
classes, as well as classes.  That is not enough.  Let's also
late-canonicalize pointers, references and array of classes too.  This
is because classes that might not be finished yet might be referenced
by those types, and so we want to wait until they are finished before
we canonicalize them.

	* include/abg-fwd.h (peel_array_type): Declare new function.
	* src/abg-ir.cc (peel_array_type): Define it.
	(peel_typedef_pointer_or_reference_type): Peel arrays too, to get
	the type of its element.
	* src/abg-dwarf-reader.cc (maybe_canonicalize_type): If a pointer,
	reference, array or typedef references a class, then do
	late-canonicalize this type.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2015-10-04 12:08:08 +02:00
parent c20c8c79e7
commit 6e36a4381d
3 changed files with 60 additions and 1 deletions

View File

@ -496,6 +496,12 @@ peel_reference_type(const shared_ptr<type_base>&);
const type_base*
peel_reference_type(const type_base*);
const shared_ptr<type_base>
peel_array_type(const shared_ptr<type_base>&);
const type_base*
peel_array_type(const type_base*);
shared_ptr<type_base>
peel_typedef_pointer_or_reference_type(const shared_ptr<type_base>);

View File

@ -7618,7 +7618,14 @@ maybe_canonicalize_type(Dwarf_Off die_offset,
type_base_sptr t = ctxt.lookup_type_from_die_offset(die_offset, in_alt_di);
assert(t);
if (class_decl_sptr klass = is_class_type(peel_typedef_type(t)))
if (class_decl_sptr klass =
is_class_type(peel_typedef_pointer_or_reference_type(t)))
// We delay canonicalization of classes or typedef, pointers,
// references and array to classes. 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.
ctxt.schedule_type_for_late_canonicalization(die_offset, in_alt_di);
else if(type_has_non_canonicalized_subtype(t))
ctxt.schedule_type_for_late_canonicalization(die_offset, in_alt_di);

View File

@ -3277,6 +3277,46 @@ peel_reference_type(const type_base* type)
return peel_reference_type(t->get_pointed_to_type()).get();
}
/// Return the leaf element type of an array.
///
/// If the element type is itself an array, then recursively return
/// the element type of that array itself.
///
/// @param type the array type to consider. If this is not an array
/// type, this type is returned by the function.
///
/// @return the leaf element type of the array @p type, or, if it's
/// not an array type, then just return @p.
const type_base_sptr
peel_array_type(const type_base_sptr& type)
{
const array_type_def_sptr t = is_array_type(type);
if (!t)
return type;
return peel_array_type(t->get_element_type());
}
/// Return the leaf element type of an array.
///
/// If the element type is itself an array, then recursively return
/// the element type of that array itself.
///
/// @param type the array type to consider. If this is not an array
/// type, this type is returned by the function.
///
/// @return the leaf element type of the array @p type, or, if it's
/// not an array type, then just return @p.
const type_base*
peel_array_type(const type_base* type)
{
const array_type_def* t = is_array_type(type);
if (!t)
return type;
return peel_array_type(t->get_element_type()).get();
}
/// Return the leaf underlying or pointed-to type node of a @ref
/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
/// node.
@ -3296,6 +3336,9 @@ peel_typedef_pointer_or_reference_type(const type_base_sptr type)
if (reference_type_def_sptr t = is_reference_type(typ))
typ = peel_reference_type(t);
if (array_type_def_sptr t = is_array_type(typ))
typ = peel_array_type(t);
}
return typ;
@ -3319,6 +3362,9 @@ peel_typedef_pointer_or_reference_type(const type_base* type)
if (const reference_type_def* t = is_reference_type(type))
type = peel_reference_type(t);
if (const array_type_def* t = is_array_type(type))
type = peel_array_type(t);
}
return const_cast<type_base*>(type);