aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2000-05-24 14:17:27 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2000-05-24 14:17:27 +0000
commit01ce976d50cf5b93c0026f8ff206af8a1544493e (patch)
tree7a15c653bab43cdfe24d767be7f58578104e59ce /gcc
parent0543d026a2a6366375b25b55dd318eb1cca6876c (diff)
downloadgcc-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/ChangeLog16
-rw-r--r--gcc/cp/inc/cxxabi.h14
-rw-r--r--gcc/cp/tinfo.cc91
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