This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

C++ PATCH: dynamic cast hint value


Hi,
I've installed the attached, reviewed, patch which remaps the base
offset hint values for dynamic cast. This makes the old abi and the new
abi use the same magic values, and hence make maintainance easier.
It doesn't implement any of the new abi stuff though. It breaks binary
compatibility between snapshots. It doesn't break compatibility between
release and snapshot, nor will it break it between releases (cos this
wasn't in the last release).

nathan
-- 
Dr Nathan Sidwell :: sidwell@codesourcery.com
nathan@acm.org  http://www.cs.bris.ac.uk/~nathan/  nathan@cs.bris.ac.uk
2000-01-20  Nathan Sidwell  <sidwell@codesourcery.com>

	Remap dynamic cast hint values to be consistent across ABIs.
	* search.c (dynamic_cast_base_recurse): Remap generated value.
	(get_dynamic_cast_base_type): Adjust documentation.
	* tinfo.h (__user_type_info::dyncast): Likewise.
	(__user_type_info::find_public_subobj): Remap BOFF meaning.
	* tinfo.cc (__si_type_info::do_dyncast): Remap BOFF meaning.
	(__class_type_info::do_dyncast): Likewise.
	(__class_type_info::do_find_public_subobj): Likewise.
	* tinfo2.cc (__dynamic_cast): Remap BOFF parameter.	

Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/search.c,v
retrieving revision 1.148
diff -c -3 -p -r1.148 search.c
*** search.c	2000/01/17 04:08:01	1.148
--- search.c	2000/01/20 10:45:57
*************** dynamic_cast_base_recurse (subtype, binf
*** 503,514 ****
  {
    tree binfos;
    int i, n_baselinks;
!   int worst = -3;
    
    if (BINFO_TYPE (binfo) == subtype)
      {
        if (via_virtual)
!         return -2;
        else
          {
            *offset_ptr = BINFO_OFFSET (binfo);
--- 503,514 ----
  {
    tree binfos;
    int i, n_baselinks;
!   int worst = -2;
    
    if (BINFO_TYPE (binfo) == subtype)
      {
        if (via_virtual)
!         return -1;
        else
          {
            *offset_ptr = BINFO_OFFSET (binfo);
*************** dynamic_cast_base_recurse (subtype, binf
*** 528,553 ****
        rval = dynamic_cast_base_recurse
               (subtype, base_binfo,
                via_virtual || TREE_VIA_VIRTUAL (base_binfo), offset_ptr);
!       if (worst == -3)
          worst = rval;
        else if (rval >= 0)
!         worst = worst >= 0 ? -1 : worst;
!       else if (rval > -3)
!         worst = worst < rval ? worst : rval;
      }
    return worst;
  }
  
! /* The dynamic cast runtime needs a hint about how the static SUBTYPE type started
!    from is related to the required TARGET type, in order to optimize the
!    inheritance graph search. This information is independant of the
     current context, and ignores private paths, hence get_base_distance is
     inappropriate. Return a TREE specifying the base offset, BOFF.
     BOFF >= 0, there is only one public non-virtual SUBTYPE base at offset BOFF,
        and there are no public virtual SUBTYPE bases.
!    BOFF == -1, SUBTYPE occurs as multiple public non-virtual bases.
!    BOFF == -2, SUBTYPE occurs as multiple public virtual or non-virtual bases.
!    BOFF == -3, SUBTYPE is not a public base.  */
  
  tree
  get_dynamic_cast_base_type (subtype, target)
--- 528,555 ----
        rval = dynamic_cast_base_recurse
               (subtype, base_binfo,
                via_virtual || TREE_VIA_VIRTUAL (base_binfo), offset_ptr);
!       if (worst == -2)
          worst = rval;
        else if (rval >= 0)
!         worst = worst >= 0 ? -3 : worst;
!       else if (rval == -1)
!         worst = -1;
!       else if (rval == -3 && worst != -1)
!         worst = -3;
      }
    return worst;
  }
  
! /* The dynamic cast runtime needs a hint about how the static SUBTYPE type
!    started from is related to the required TARGET type, in order to optimize
!    the inheritance graph search. This information is independant of the
     current context, and ignores private paths, hence get_base_distance is
     inappropriate. Return a TREE specifying the base offset, BOFF.
     BOFF >= 0, there is only one public non-virtual SUBTYPE base at offset BOFF,
        and there are no public virtual SUBTYPE bases.
!    BOFF == -1, SUBTYPE occurs as multiple public virtual or non-virtual bases.
!    BOFF == -2, SUBTYPE is not a public base.
!    BOFF == -3, SUBTYPE occurs as multiple public non-virtual bases.  */
  
  tree
  get_dynamic_cast_base_type (subtype, target)
Index: cp/tinfo.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/tinfo.h,v
retrieving revision 1.8
diff -c -3 -p -r1.8 tinfo.h
*** tinfo.h	2000/01/17 04:08:01	1.8
--- tinfo.h	2000/01/20 10:45:57
*************** struct __user_type_info : public std::ty
*** 24,35 ****
    // BOFF >= 0, there is only one public non-virtual SUBTYPE base at offset
    //    BOFF, and there are no public virtual SUBTYPE bases.
    //    Therefore check if SUBOBJ is at offset BOFF when we find a target
!   // BOFF == -1, SUBTYPE occurs as multiple public non-virtual bases.
!   //    Lazily search the non-virtual bases of TARGET.
!   // BOFF == -2, SUBTYPE occurs as multiple public virtual or non-virtual bases.
    //    Lazily search all the bases of TARGET.
!   // BOFF == -3, SUBTYPE is not a public base.
!   // For backwards compatibility set BOFF to -2, that is the safe `don't know'
    // value. We don't care about SUBTYPES as private bases of TARGET, as they
    // can never succeed as downcasts, only as crosscasts -- and then only if
    // they are virtual. This is more complicated that it might seem.
--- 24,35 ----
    // BOFF >= 0, there is only one public non-virtual SUBTYPE base at offset
    //    BOFF, and there are no public virtual SUBTYPE bases.
    //    Therefore check if SUBOBJ is at offset BOFF when we find a target
!   // BOFF == -1, SUBTYPE occurs as multiple public virtual or non-virtual bases.
    //    Lazily search all the bases of TARGET.
!   // BOFF == -2, SUBTYPE is not a public base.
!   // BOFF == -3, SUBTYPE occurs as multiple public non-virtual bases.
!   //    Lazily search the non-virtual bases of TARGET.
!   // For backwards compatibility set BOFF to -1, that is the safe `don't know'
    // value. We don't care about SUBTYPES as private bases of TARGET, as they
    // can never succeed as downcasts, only as crosscasts -- and then only if
    // they are virtual. This is more complicated that it might seem.
*************** struct __user_type_info : public std::ty
*** 131,137 ****
      if (boff >= 0)
        return ((char *)subptr - (char *)objptr) == boff
                ? contained_public : not_contained;
!     if (boff == -3)
        return not_contained;
      return do_find_public_subobj (boff, subtype, objptr, subptr);
    }
--- 131,137 ----
      if (boff >= 0)
        return ((char *)subptr - (char *)objptr) == boff
                ? contained_public : not_contained;
!     if (boff == -2)
        return not_contained;
      return do_find_public_subobj (boff, subtype, objptr, subptr);
    }
Index: cp/tinfo.cc
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/tinfo.cc,v
retrieving revision 1.13
diff -c -3 -p -r1.13 tinfo.cc
*** tinfo.cc	2000/01/17 04:08:01	1.13
--- tinfo.cc	2000/01/20 10:45:57
*************** do_dyncast (int boff, sub_kind access_pa
*** 243,249 ****
        if (boff >= 0)
          result.target2sub = ((char *)subptr - (char *)objptr) == boff
                ? contained_public : not_contained;
!       else if (boff == -3)
          result.target2sub = not_contained;
        return false;
      }
--- 243,249 ----
        if (boff >= 0)
          result.target2sub = ((char *)subptr - (char *)objptr) == boff
                ? contained_public : not_contained;
!       else if (boff == -2)
          result.target2sub = not_contained;
        return false;
      }
*************** do_dyncast (int boff, sub_kind access_pa
*** 361,367 ****
        if (boff >= 0)
          result.target2sub = ((char *)subptr - (char *)objptr) == boff
                ? contained_public : not_contained;
!       else if (boff == -3)
          result.target2sub = not_contained;
        return false;
      }
--- 361,367 ----
        if (boff >= 0)
          result.target2sub = ((char *)subptr - (char *)objptr) == boff
                ? contained_public : not_contained;
!       else if (boff == -2)
          result.target2sub = not_contained;
        return false;
      }
*************** do_find_public_subobj (int boff, const t
*** 519,525 ****
          continue; // Not public, can't be here.
        void *p;
  
!       if (base_list[i].is_virtual && boff == -1)
  	// Not a virtual base, so can't be here.
  	continue;
        
--- 519,525 ----
          continue; // Not public, can't be here.
        void *p;
  
!       if (base_list[i].is_virtual && boff == -3)
  	// Not a virtual base, so can't be here.
  	continue;
        
Index: cp/tinfo2.cc
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/tinfo2.cc,v
retrieving revision 1.12
diff -c -3 -p -r1.12 tinfo2.cc
*** tinfo2.cc	1999/09/21 14:40:13	1.12
--- tinfo2.cc	2000/01/20 10:45:57
***************
*** 1,5 ****
  // Methods for type_info for -*- C++ -*- Run Time Type Identification.
! // Copyright (C) 1994, 96-97, 1998, 1999 Free Software Foundation
  
  // This file is part of GNU CC.
  
--- 1,5 ----
  // Methods for type_info for -*- C++ -*- Run Time Type Identification.
! // Copyright (C) 1994, 96-97, 1998, 1999, 2000 Free Software Foundation
  
  // This file is part of GNU CC.
  
*************** __dynamic_cast (const type_info& (*from)
*** 274,280 ****
  {
    if (!require_public) abort();
    return static_cast <__user_type_info const &> (from ()).dyncast
!       (/*boff=*/-2, to (), address, sub (), subptr);
  }
  
  extern "C" void *
--- 274,280 ----
  {
    if (!require_public) abort();
    return static_cast <__user_type_info const &> (from ()).dyncast
!       (/*boff=*/-1, to (), address, sub (), subptr);
  }
  
  extern "C" void *

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]