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
This commit is contained in:
Nathan Sidwell 2000-05-24 14:17:27 +00:00 committed by Nathan Sidwell
parent 0543d026a2
commit 01ce976d50
3 changed files with 64 additions and 57 deletions

View File

@ -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

View File

@ -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;
};

View File

@ -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