[C++ patch]: new rtti tweak
Nathan Sidwell
nathan@codesourcery.com
Fri Apr 7 02:35:00 GMT 2000
Hi,
I installed the attached which neatens part of the new-abi
rtti runtime. no change in old-abi.
booted and tested on i686-pc-linux-gnu
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2000-04-06 Nathan Sidwell <nathan@codesourcery.com>
* tinfo.cc (convert_to_base): New function.
(get_vbase_offset): Remove. Move into convert_to_base.
(__vmi_class_type_info::do_find_public_src): Adjust.
(__vmi_class_type_info::do_dyncast): Adjust.
(__vmi_class_type_info::do_upcast): Adjust.
Index: cp/tinfo.cc
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/tinfo.cc,v
retrieving revision 1.21
diff -c -3 -p -r1.21 tinfo.cc
*** tinfo.cc 2000/04/04 18:13:21 1.21
--- tinfo.cc 2000/04/06 13:58:38
*************** adjust_pointer (const void *base, ptrdif
*** 590,601 ****
(reinterpret_cast <const char *> (base) + offset);
}
! inline ptrdiff_t
! get_vbase_offset (const void *object, ptrdiff_t offset)
{
! const char *vtable = *reinterpret_cast <const char *const *> (object);
! vtable += offset;
! return *reinterpret_cast <const ptrdiff_t *> (vtable);
}
// some predicate functions for __class_type_info::sub_kind
--- 590,608 ----
(reinterpret_cast <const char *> (base) + offset);
}
! // ADDR is a pointer to an object. Convert it to a pointer to a base,
! // using OFFSET. IS_VIRTUAL is true, if we are getting a virtual base.
! inline void const *
! convert_to_base (void const *addr, bool is_virtual, ptrdiff_t offset)
{
! if (is_virtual)
! {
! const void *vtable = *static_cast <const void *const *> (addr);
!
! offset = *adjust_pointer<ptrdiff_t> (vtable, offset);
! }
!
! return adjust_pointer<void> (addr, offset);
}
// some predicate functions for __class_type_info::sub_kind
*************** do_find_public_src (ptrdiff_t src2dst,
*** 721,740 ****
const void *base = obj_ptr;
ptrdiff_t offset = base_list[i].offset ();
! if (base_list[i].is_virtual_p ())
{
if (src2dst == -3)
continue; // Not a virtual base, so can't be here.
- offset = get_vbase_offset (base, offset);
}
! base = adjust_pointer <void> (base, offset);
sub_kind base_kind = base_list[i].base->do_find_public_src
(src2dst, base, src_type, src_ptr);
if (contained_p (base_kind))
{
! if (base_list[i].is_virtual_p ())
base_kind = sub_kind (base_kind | contained_virtual_mask);
return base_kind;
}
--- 728,747 ----
const void *base = obj_ptr;
ptrdiff_t offset = base_list[i].offset ();
+ bool is_virtual = base_list[i].is_virtual_p ();
! if (is_virtual)
{
if (src2dst == -3)
continue; // Not a virtual base, so can't be here.
}
! base = convert_to_base (base, is_virtual, offset);
sub_kind base_kind = base_list[i].base->do_find_public_src
(src2dst, base, src_type, src_ptr);
if (contained_p (base_kind))
{
! if (is_virtual)
base_kind = sub_kind (base_kind | contained_virtual_mask);
return base_kind;
}
*************** do_dyncast (ptrdiff_t src2dst,
*** 843,855 ****
void const *base = obj_ptr;
sub_kind base_access = access_path;
ptrdiff_t offset = base_list[i].offset ();
! if (base_list[i].is_virtual_p ())
! {
! base_access = sub_kind (base_access | contained_virtual_mask);
! offset = get_vbase_offset (base, offset);
! }
! base = adjust_pointer <void> (base, offset);
if (!base_list[i].is_public_p ())
base_access = sub_kind (base_access & ~contained_public_mask);
--- 850,860 ----
void const *base = obj_ptr;
sub_kind base_access = access_path;
ptrdiff_t offset = base_list[i].offset ();
+ bool is_virtual = base_list[i].is_virtual_p ();
! if (is_virtual)
! base_access = sub_kind (base_access | contained_virtual_mask);
! base = convert_to_base (base, is_virtual, offset);
if (!base_list[i].is_public_p ())
base_access = sub_kind (base_access & ~contained_public_mask);
*************** do_upcast (sub_kind access_path,
*** 1032,1037 ****
--- 1037,1043 ----
const void *base = obj_ptr;
sub_kind sub_access = access_path;
ptrdiff_t offset = base_list[i].offset ();
+ bool is_virtual = base_list[i].is_virtual_p ();
if (!base_list[i].is_public_p ())
{
*************** do_upcast (sub_kind access_path,
*** 1039,1061 ****
// original cannot have an ambiguous base
continue;
sub_access = sub_kind (sub_access & ~contained_public_mask);
- }
- if (base_list[i].is_virtual_p ())
- {
- sub_access = sub_kind (sub_access | contained_virtual_mask);
-
- if (base)
- offset = get_vbase_offset (base, offset);
}
if (base)
! base = adjust_pointer <void> (base, offset);
if (base_list[i].base->do_upcast (sub_access, dst, base, result2))
return true; // must fail
if (result2.base_type)
{
! if (result2.base_type == nonvirtual_base_type
! && base_list[i].is_virtual_p ())
result2.base_type = base_list[i].base;
if (!result.base_type)
{
--- 1045,1061 ----
// 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)
! base = convert_to_base (base, is_virtual, offset);
if (base_list[i].base->do_upcast (sub_access, dst, base, result2))
return true; // must fail
if (result2.base_type)
{
! if (result2.base_type == nonvirtual_base_type && is_virtual)
result2.base_type = base_list[i].base;
if (!result.base_type)
{
More information about the Gcc-patches
mailing list