From 1bee40c075f06e4e2eaf97ab03b435007bc320d9 Mon Sep 17 00:00:00 2001 From: Dodji Seketeli Date: Sun, 6 Dec 2015 17:29:50 +0100 Subject: [PATCH] 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 --- include/abg-fwd.h | 6 +++++ src/abg-ir.cc | 68 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/include/abg-fwd.h b/include/abg-fwd.h index 13d6576a..7e8493e0 100644 --- a/include/abg-fwd.h +++ b/include/abg-fwd.h @@ -511,6 +511,12 @@ peel_array_type(const shared_ptr&); const type_base* peel_array_type(const type_base*); +const type_base* +peel_qualified_type(const type_base*); + +const shared_ptr +peel_qualified_type(const shared_ptr&); + shared_ptr peel_typedef_pointer_or_reference_type(const shared_ptr); diff --git a/src/abg-ir.cc b/src/abg-ir.cc index ecc44c44..fed2b27b 100644 --- a/src/abg-ir.cc +++ b/src/abg-ir.cc @@ -3509,16 +3509,63 @@ peel_array_type(const type_base* type) 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 -/// typedef_decl, @ref pointer_type_def or @ref reference_type_def -/// node. +/// typedef_decl, @ref pointer_type_def, @ref reference_type_def or +/// @ref qualified_type_def node. /// /// @return the leaf underlying or pointed-to type node of @p type. type_base_sptr peel_typedef_pointer_or_reference_type(const type_base_sptr 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)) 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)) typ = peel_array_type(t); + + if (qualified_type_def_sptr t = is_qualified_type(typ)) + typ = peel_qualified_type(t); } return typ; } /// Return the leaf underlying or pointed-to type node of a @ref -/// typedef_decl, @ref pointer_type_def or @ref reference_type_def -/// node. +/// typedef_decl, @ref pointer_type_def, @ref reference_type_def or +/// @ref qualified_type_def type node. /// /// @return the leaf underlying or pointed-to type node of @p type. type_base* 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)) 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)) type = peel_array_type(t); + + if (const qualified_type_def* t = is_qualified_type(type)) + type = peel_qualified_type(t); } return const_cast(type); -- 2.43.5