Do not forget to peel qualified type off when peeling types

When peeling off typedefs, references and pointers to see if a type is
made of a class type, we forget to peel qualified types off.

This is in the context of parsing type info from DWARF and to
determine if we should delay type canonicalization (because a given
type is made of a class) or not.

Fixed thus.

	* include/abg-fwd.h (peel_qualified_type): Declare new function
	...
	* src/abg-ir.cc (peel_qualified_type): ... and define it.
	(peel_typedef_pointer_or_reference_type): Peel qualified types
	here too.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2015-12-06 17:29:50 +01:00
parent 584562bae8
commit 1bee40c075
2 changed files with 68 additions and 6 deletions

View File

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

View File

@ -3509,16 +3509,63 @@ peel_array_type(const type_base* type)
return peel_array_type(t->get_element_type()).get(); return peel_array_type(t->get_element_type()).get();
} }
/// Return the leaf underlying type of a qualified type.
///
/// If the underlying type is itself a qualified type, then
/// recursively return the first underlying type of that qualified
/// type to return the first underlying type that is not a qualified type.
///
/// If the underlying type is NOT a qualified type, then just return
/// that underlying type.
///
/// @param type the qualified type to consider.
///
/// @return the leaf underlying type.
const type_base*
peel_qualified_type(const type_base* type)
{
const qualified_type_def* t = is_qualified_type(type);
if (!t)
return type;
return peel_qualified_type(t->get_underlying_type().get());
}
/// Return the leaf underlying type of a qualified type.
///
/// If the underlying type is itself a qualified type, then
/// recursively return the first underlying type of that qualified
/// type to return the first underlying type that is not a qualified type.
///
/// If the underlying type is NOT a qualified type, then just return
/// that underlying type.
///
/// @param type the qualified type to consider.
///
/// @return the leaf underlying type.
const type_base_sptr
peel_qualified_type(const type_base_sptr& type)
{
const qualified_type_def_sptr t = is_qualified_type(type);
if (!t)
return type;
return peel_qualified_type(t->get_underlying_type());
}
/// Return the leaf underlying or pointed-to type node of a @ref /// Return the leaf underlying or pointed-to type node of a @ref
/// typedef_decl, @ref pointer_type_def or @ref reference_type_def /// typedef_decl, @ref pointer_type_def, @ref reference_type_def or
/// node. /// @ref qualified_type_def node.
/// ///
/// @return the leaf underlying or pointed-to type node of @p type. /// @return the leaf underlying or pointed-to type node of @p type.
type_base_sptr type_base_sptr
peel_typedef_pointer_or_reference_type(const type_base_sptr type) peel_typedef_pointer_or_reference_type(const type_base_sptr type)
{ {
type_base_sptr typ = type; type_base_sptr typ = type;
while (is_typedef(typ) || is_pointer_type(typ) || is_reference_type(typ)) while (is_typedef(typ)
|| is_pointer_type(typ)
|| is_reference_type(typ)
|| is_qualified_type(typ))
{ {
if (typedef_decl_sptr t = is_typedef(typ)) if (typedef_decl_sptr t = is_typedef(typ))
typ = peel_typedef_type(t); typ = peel_typedef_type(t);
@ -3531,20 +3578,26 @@ peel_typedef_pointer_or_reference_type(const type_base_sptr type)
if (array_type_def_sptr t = is_array_type(typ)) if (array_type_def_sptr t = is_array_type(typ))
typ = peel_array_type(t); typ = peel_array_type(t);
if (qualified_type_def_sptr t = is_qualified_type(typ))
typ = peel_qualified_type(t);
} }
return typ; return typ;
} }
/// Return the leaf underlying or pointed-to type node of a @ref /// Return the leaf underlying or pointed-to type node of a @ref
/// typedef_decl, @ref pointer_type_def or @ref reference_type_def /// typedef_decl, @ref pointer_type_def, @ref reference_type_def or
/// node. /// @ref qualified_type_def type node.
/// ///
/// @return the leaf underlying or pointed-to type node of @p type. /// @return the leaf underlying or pointed-to type node of @p type.
type_base* type_base*
peel_typedef_pointer_or_reference_type(const type_base* type) peel_typedef_pointer_or_reference_type(const type_base* type)
{ {
while (is_typedef(type) || is_pointer_type(type) || is_reference_type(type)) while (is_typedef(type)
|| is_pointer_type(type)
|| is_reference_type(type)
|| is_qualified_type(type))
{ {
if (const typedef_decl* t = is_typedef(type)) if (const typedef_decl* t = is_typedef(type))
type = peel_typedef_type(t); type = peel_typedef_type(t);
@ -3557,6 +3610,9 @@ peel_typedef_pointer_or_reference_type(const type_base* type)
if (const array_type_def* t = is_array_type(type)) if (const array_type_def* t = is_array_type(type))
type = peel_array_type(t); type = peel_array_type(t);
if (const qualified_type_def* t = is_qualified_type(type))
type = peel_qualified_type(t);
} }
return const_cast<type_base*>(type); return const_cast<type_base*>(type);