diff --git a/include/abg-fwd.h b/include/abg-fwd.h index 50db61ad..9ff0016f 100644 --- a/include/abg-fwd.h +++ b/include/abg-fwd.h @@ -496,6 +496,12 @@ peel_reference_type(const shared_ptr&); const type_base* peel_reference_type(const type_base*); +const shared_ptr +peel_array_type(const shared_ptr&); + +const type_base* +peel_array_type(const type_base*); + shared_ptr peel_typedef_pointer_or_reference_type(const shared_ptr); diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index 9e92e35c..b675ecd7 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -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); diff --git a/src/abg-ir.cc b/src/abg-ir.cc index 9b30959f..eeee1bf6 100644 --- a/src/abg-ir.cc +++ b/src/abg-ir.cc @@ -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);