Commit 01ce976d by Nathan Sidwell Committed by Nathan Sidwell

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
parent 0543d026
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> 2000-05-23 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (lang_decl_flags): Rename mutable_flag to uninlinable * cp-tree.h (lang_decl_flags): Rename mutable_flag to uninlinable
......
...@@ -266,11 +266,9 @@ protected: ...@@ -266,11 +266,9 @@ protected:
public: public:
/* Helper for upcast. See if DST is us, or one of our bases. ACCESS_PATH */ /* Helper for upcast. See if DST is us, or one of our bases. */
/* gives the access from the start object. Return TRUE if we know the upcast */ /* Return false if not found, true if found. */
/* fails. */ virtual bool __do_upcast (const __class_type_info *__dst,
virtual bool __do_upcast (__sub_kind __access_path,
const __class_type_info *__dst,
const void *__obj, const void *__obj,
__upcast_result &__restrict __result) const; __upcast_result &__restrict __result) const;
...@@ -341,8 +339,7 @@ protected: ...@@ -341,8 +339,7 @@ protected:
const void *__obj_ptr, const void *__obj_ptr,
const __class_type_info *__src_type, const __class_type_info *__src_type,
const void *__sub_ptr) const; const void *__sub_ptr) const;
virtual bool __do_upcast (__sub_kind __access_path, virtual bool __do_upcast (const __class_type_info *__dst,
const __class_type_info *__dst,
const void *__obj, const void *__obj,
__upcast_result &__restrict __result) const; __upcast_result &__restrict __result) const;
}; };
...@@ -391,8 +388,7 @@ protected: ...@@ -391,8 +388,7 @@ protected:
const void *__obj_ptr, const void *__obj_ptr,
const __class_type_info *__src_type, const __class_type_info *__src_type,
const void *__src_ptr) const; const void *__src_ptr) const;
virtual bool __do_upcast (__sub_kind __access_path, virtual bool __do_upcast (const __class_type_info *__dst,
const __class_type_info *__dst,
const void *__obj, const void *__obj,
__upcast_result &__restrict __result) const; __upcast_result &__restrict __result) const;
}; };
......
...@@ -662,7 +662,7 @@ __vmi_class_type_info:: ...@@ -662,7 +662,7 @@ __vmi_class_type_info::
struct __class_type_info::__upcast_result struct __class_type_info::__upcast_result
{ {
const void *dst_ptr; // pointer to caught object 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 int src_details; // hints about the source type heirarchy
const __class_type_info *base_type; // where we found the target, const __class_type_info *base_type; // where we found the target,
// if in vbase the __class_type_info of vbase // if in vbase the __class_type_info of vbase
...@@ -670,7 +670,7 @@ struct __class_type_info::__upcast_result ...@@ -670,7 +670,7 @@ struct __class_type_info::__upcast_result
// else NULL // else NULL
public: public:
__upcast_result (int d) __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, ...@@ -709,10 +709,11 @@ __do_upcast (const __class_type_info *dst_type,
{ {
__upcast_result result (__vmi_class_type_info::__flags_unknown_mask); __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; return false;
*obj_ptr = const_cast <void *> (result.dst_ptr); *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:: inline __class_type_info::__sub_kind __class_type_info::
...@@ -1025,47 +1026,35 @@ __do_dyncast (ptrdiff_t src2dst, ...@@ -1025,47 +1026,35 @@ __do_dyncast (ptrdiff_t src2dst,
} }
bool __class_type_info:: bool __class_type_info::
__do_upcast (__sub_kind access_path, __do_upcast (const __class_type_info *dst, const void *obj,
const __class_type_info *dst, const void *obj,
__upcast_result &__restrict result) const __upcast_result &__restrict result) const
{ {
if (*this == *dst) if (*this == *dst)
{ {
result.dst_ptr = obj; result.dst_ptr = obj;
result.base_type = nonvirtual_base_type; result.base_type = nonvirtual_base_type;
result.whole2dst = access_path; result.part2dst = __contained_public;
return contained_nonpublic_p (access_path); return true;
} }
return false; return false;
} }
bool __si_class_type_info:: bool __si_class_type_info::
__do_upcast (__sub_kind access_path, __do_upcast (const __class_type_info *dst, const void *obj_ptr,
const __class_type_info *dst, const void *obj_ptr,
__upcast_result &__restrict result) const __upcast_result &__restrict result) const
{ {
if (*this == *dst) if (__class_type_info::__do_upcast (dst, obj_ptr, result))
{ return true;
result.dst_ptr = obj_ptr;
result.base_type = nonvirtual_base_type; return base->__do_upcast (dst, obj_ptr, result);
result.whole2dst = access_path;
return contained_nonpublic_p (access_path);
}
return base->__do_upcast (access_path, dst, obj_ptr, result);
} }
bool __vmi_class_type_info:: bool __vmi_class_type_info::
__do_upcast (__sub_kind access_path, __do_upcast (const __class_type_info *dst, const void *obj_ptr,
const __class_type_info *dst, const void *obj_ptr,
__upcast_result &__restrict result) const __upcast_result &__restrict result) const
{ {
if (*this == *dst) if (__class_type_info::__do_upcast (dst, obj_ptr, result))
{ return true;
result.dst_ptr = obj_ptr;
result.base_type = nonvirtual_base_type;
result.whole2dst = access_path;
return contained_nonpublic_p (access_path);
}
int src_details = result.src_details; int src_details = result.src_details;
if (src_details & __flags_unknown_mask) if (src_details & __flags_unknown_mask)
...@@ -1075,47 +1064,53 @@ __do_upcast (__sub_kind access_path, ...@@ -1075,47 +1064,53 @@ __do_upcast (__sub_kind access_path,
{ {
__upcast_result result2 (src_details); __upcast_result result2 (src_details);
const void *base = obj_ptr; const void *base = obj_ptr;
__sub_kind sub_access = access_path;
ptrdiff_t offset = vmi_bases[i].__offset (); ptrdiff_t offset = vmi_bases[i].__offset ();
bool is_virtual = vmi_bases[i].__is_virtual_p (); 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 (!is_public && !(src_details & non_diamond_repeat_mask))
{ // original cannot have an ambiguous base, so skip private bases
if (!(src_details & non_diamond_repeat_mask)) continue;
// 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 (base) if (base)
base = convert_to_base (base, is_virtual, offset); base = convert_to_base (base, is_virtual, offset);
if (vmi_bases[i].base->__do_upcast (sub_access, dst, base, result2)) if (vmi_bases[i].base->__do_upcast (dst, base, result2))
return true; // must fail
if (result2.base_type)
{ {
if (result2.base_type == nonvirtual_base_type && is_virtual) if (result2.base_type == nonvirtual_base_type && is_virtual)
result2.base_type = vmi_bases[i].base; 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) if (!result.base_type)
{ {
result = result2; result = result2;
if (!(vmi_flags & non_diamond_repeat_mask)) if (!contained_p (result.part2dst))
// cannot have an ambiguous other base return true; // found ambiguously
return false;
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) else if (result.dst_ptr != result2.dst_ptr)
{ {
// Found an ambiguity. // Found an ambiguity.
result.dst_ptr = NULL; result.dst_ptr = NULL;
result.whole2dst = __contained_ambig; result.part2dst = __contained_ambig;
return true; return true;
} }
else if (result.dst_ptr) else if (result.dst_ptr)
{ {
// Ok, found real object via a virtual path. // Ok, found real object via a virtual path.
result.whole2dst result.part2dst
= __sub_kind (result.whole2dst | result2.whole2dst); = __sub_kind (result.part2dst | result2.part2dst);
} }
else else
{ {
...@@ -1127,13 +1122,13 @@ __do_upcast (__sub_kind access_path, ...@@ -1127,13 +1122,13 @@ __do_upcast (__sub_kind access_path,
{ {
// Already ambiguous, not virtual or via different virtuals. // Already ambiguous, not virtual or via different virtuals.
// Cannot match. // Cannot match.
result.whole2dst = __contained_ambig; result.part2dst = __contained_ambig;
return true; return true;
} }
} }
} }
} }
return false; return result.part2dst != __unknown;
} }
// this is the external interface to the dynamic cast machinery // this is the external interface to the dynamic cast machinery
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment