diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2000-05-24 14:17:27 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2000-05-24 14:17:27 +0000 |
commit | 01ce976d50cf5b93c0026f8ff206af8a1544493e (patch) | |
tree | 7a15c653bab43cdfe24d767be7f58578104e59ce /gcc | |
parent | 0543d026a2a6366375b25b55dd318eb1cca6876c (diff) | |
download | gcc-01ce976d50cf5b93c0026f8ff206af8a1544493e.zip gcc-01ce976d50cf5b93c0026f8ff206af8a1544493e.tar.gz gcc-01ce976d50cf5b93c0026f8ff206af8a1544493e.tar.bz2 |
Update new-abi upcast algorithm.
* inc/cxxabi.h (__class_type_info::__do_upcast): Change
prototype and meaning of return value.
(__si_class_type_info::__do_upcast): Likewise.
(__vmi_class_type_info::__do_upcast): Likewise.
* tinfo.cc (__class_type_info::__upcast_result): Replace
whole2dst with part2dst. Adjust ctor.
(__class_type_info::__do_upcast): Adjust call of worker function.
(__class_type_info::__do_upcast): Adjust.
(__si_class_type_info::__do_upcast): Adjust. Use parent's
__do_upcast.
(__vmi_class_type_info::__do_upcast): Likewise. Fix private
virtual base in diamond heirarchy bug.
From-SVN: r34132
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/cp/inc/cxxabi.h | 14 | ||||
-rw-r--r-- | gcc/cp/tinfo.cc | 91 |
3 files changed, 64 insertions, 57 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 97b525d..e6e1381 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,19 @@ +2000-05-24 Nathan Sidwell <nathan@codesourcery.com> + + Update new-abi upcast algorithm. + * inc/cxxabi.h (__class_type_info::__do_upcast): Change + prototype and meaning of return value. + (__si_class_type_info::__do_upcast): Likewise. + (__vmi_class_type_info::__do_upcast): Likewise. + * tinfo.cc (__class_type_info::__upcast_result): Replace + whole2dst with part2dst. Adjust ctor. + (__class_type_info::__do_upcast): Adjust call of worker function. + (__class_type_info::__do_upcast): Adjust. + (__si_class_type_info::__do_upcast): Adjust. Use parent's + __do_upcast. + (__vmi_class_type_info::__do_upcast): Likewise. Fix private + virtual base in diamond heirarchy bug. + 2000-05-23 Mark Mitchell <mark@codesourcery.com> * cp-tree.h (lang_decl_flags): Rename mutable_flag to uninlinable diff --git a/gcc/cp/inc/cxxabi.h b/gcc/cp/inc/cxxabi.h index 55b01b7..c5eec5c 100644 --- a/gcc/cp/inc/cxxabi.h +++ b/gcc/cp/inc/cxxabi.h @@ -266,11 +266,9 @@ protected: public: - /* Helper for upcast. See if DST is us, or one of our bases. ACCESS_PATH */ - /* gives the access from the start object. Return TRUE if we know the upcast */ - /* fails. */ - virtual bool __do_upcast (__sub_kind __access_path, - const __class_type_info *__dst, + /* Helper for upcast. See if DST is us, or one of our bases. */ + /* Return false if not found, true if found. */ + virtual bool __do_upcast (const __class_type_info *__dst, const void *__obj, __upcast_result &__restrict __result) const; @@ -341,8 +339,7 @@ protected: const void *__obj_ptr, const __class_type_info *__src_type, const void *__sub_ptr) const; - virtual bool __do_upcast (__sub_kind __access_path, - const __class_type_info *__dst, + virtual bool __do_upcast (const __class_type_info *__dst, const void *__obj, __upcast_result &__restrict __result) const; }; @@ -391,8 +388,7 @@ protected: const void *__obj_ptr, const __class_type_info *__src_type, const void *__src_ptr) const; - virtual bool __do_upcast (__sub_kind __access_path, - const __class_type_info *__dst, + virtual bool __do_upcast (const __class_type_info *__dst, const void *__obj, __upcast_result &__restrict __result) const; }; diff --git a/gcc/cp/tinfo.cc b/gcc/cp/tinfo.cc index ec2d262..375249c 100644 --- a/gcc/cp/tinfo.cc +++ b/gcc/cp/tinfo.cc @@ -662,7 +662,7 @@ __vmi_class_type_info:: struct __class_type_info::__upcast_result { const void *dst_ptr; // pointer to caught object - __sub_kind whole2dst; // path from most derived object to target + __sub_kind part2dst; // path from current base to target int src_details; // hints about the source type heirarchy const __class_type_info *base_type; // where we found the target, // if in vbase the __class_type_info of vbase @@ -670,7 +670,7 @@ struct __class_type_info::__upcast_result // else NULL public: __upcast_result (int d) - :dst_ptr (NULL), whole2dst (__unknown), src_details (d), base_type (NULL) + :dst_ptr (NULL), part2dst (__unknown), src_details (d), base_type (NULL) {} }; @@ -709,10 +709,11 @@ __do_upcast (const __class_type_info *dst_type, { __upcast_result result (__vmi_class_type_info::__flags_unknown_mask); - if (__do_upcast (__contained_public, dst_type, *obj_ptr, result)) + __do_upcast (dst_type, *obj_ptr, result); + if (!contained_public_p (result.part2dst)) return false; *obj_ptr = const_cast <void *> (result.dst_ptr); - return contained_public_p (result.whole2dst); + return true; } inline __class_type_info::__sub_kind __class_type_info:: @@ -1025,47 +1026,35 @@ __do_dyncast (ptrdiff_t src2dst, } bool __class_type_info:: -__do_upcast (__sub_kind access_path, - const __class_type_info *dst, const void *obj, +__do_upcast (const __class_type_info *dst, const void *obj, __upcast_result &__restrict result) const { if (*this == *dst) { result.dst_ptr = obj; result.base_type = nonvirtual_base_type; - result.whole2dst = access_path; - return contained_nonpublic_p (access_path); + result.part2dst = __contained_public; + return true; } return false; } bool __si_class_type_info:: -__do_upcast (__sub_kind access_path, - const __class_type_info *dst, const void *obj_ptr, +__do_upcast (const __class_type_info *dst, const void *obj_ptr, __upcast_result &__restrict result) const { - if (*this == *dst) - { - result.dst_ptr = obj_ptr; - result.base_type = nonvirtual_base_type; - result.whole2dst = access_path; - return contained_nonpublic_p (access_path); - } - return base->__do_upcast (access_path, dst, obj_ptr, result); + if (__class_type_info::__do_upcast (dst, obj_ptr, result)) + return true; + + return base->__do_upcast (dst, obj_ptr, result); } bool __vmi_class_type_info:: -__do_upcast (__sub_kind access_path, - const __class_type_info *dst, const void *obj_ptr, +__do_upcast (const __class_type_info *dst, const void *obj_ptr, __upcast_result &__restrict result) const { - if (*this == *dst) - { - result.dst_ptr = obj_ptr; - result.base_type = nonvirtual_base_type; - result.whole2dst = access_path; - return contained_nonpublic_p (access_path); - } + if (__class_type_info::__do_upcast (dst, obj_ptr, result)) + return true; int src_details = result.src_details; if (src_details & __flags_unknown_mask) @@ -1075,47 +1064,53 @@ __do_upcast (__sub_kind access_path, { __upcast_result result2 (src_details); const void *base = obj_ptr; - __sub_kind sub_access = access_path; ptrdiff_t offset = vmi_bases[i].__offset (); bool is_virtual = vmi_bases[i].__is_virtual_p (); + bool is_public = vmi_bases[i].__is_public_p (); - if (!vmi_bases[i].__is_public_p ()) - { - if (!(src_details & non_diamond_repeat_mask)) - // original cannot have an ambiguous base - continue; - sub_access = __sub_kind (sub_access & ~__contained_public_mask); - } - if (is_virtual) - sub_access = __sub_kind (sub_access | __contained_virtual_mask); + if (!is_public && !(src_details & non_diamond_repeat_mask)) + // original cannot have an ambiguous base, so skip private bases + continue; + if (base) base = convert_to_base (base, is_virtual, offset); - if (vmi_bases[i].base->__do_upcast (sub_access, dst, base, result2)) - return true; // must fail - if (result2.base_type) + if (vmi_bases[i].base->__do_upcast (dst, base, result2)) { if (result2.base_type == nonvirtual_base_type && is_virtual) result2.base_type = vmi_bases[i].base; + if (contained_p (result2.part2dst) && !is_public) + result2.part2dst = __sub_kind (result2.part2dst & ~__contained_public_mask); + if (!result.base_type) { result = result2; - if (!(vmi_flags & non_diamond_repeat_mask)) - // cannot have an ambiguous other base - return false; + if (!contained_p (result.part2dst)) + return true; // found ambiguously + + if (result.part2dst & __contained_public_mask) + { + if (!(vmi_flags & non_diamond_repeat_mask)) + return true; // cannot have an ambiguous other base + } + else + { + if (!(vmi_flags & diamond_shaped_mask)) + return true; // cannot have a more accessible base + } } else if (result.dst_ptr != result2.dst_ptr) { // Found an ambiguity. result.dst_ptr = NULL; - result.whole2dst = __contained_ambig; + result.part2dst = __contained_ambig; return true; } else if (result.dst_ptr) { // Ok, found real object via a virtual path. - result.whole2dst - = __sub_kind (result.whole2dst | result2.whole2dst); + result.part2dst + = __sub_kind (result.part2dst | result2.part2dst); } else { @@ -1127,13 +1122,13 @@ __do_upcast (__sub_kind access_path, { // Already ambiguous, not virtual or via different virtuals. // Cannot match. - result.whole2dst = __contained_ambig; + result.part2dst = __contained_ambig; return true; } } } } - return false; + return result.part2dst != __unknown; } // this is the external interface to the dynamic cast machinery |