[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