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] more new abi rtti


Hi,
I've installed the attached with brings in more of the updated
new abi spec. Primarily moving fields around the type_info
structures.

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-03-28  Nathan Sidwell  <nathan@codesourcery.com>

	* rtti.c (class_hint_flags): Rename flags.
	(class_initializer): Remove flags.
	(synthesize_tinfo_var): Combine offset and flags. Add flags
	for __vmi_class_type_info.
	(create_tinfo_types): Remove flags from __class_type_info and
	__si_class_type_info. Merge flags and offset from
	base_class_type_info.
	* inc/cxxabi.h (__base_class_info): Merge offset and vmi_flags.
	(__base_class_info::is_virtual_p): Adjust.
	(__base_class_info::is_public_p): Adjust.
	(__base_class_info::offset): New accessor.
	(__class_type_info::details): Remove member.
	(__class_type_info::__class_type_info): Lose details.
	(__class_type_info::detail_masks): Remove.
	(__si_class_type_info::__si_class_type_info): Lose details.
	(__vmi_class_type_info::details): New member.
	(__vmi_class_type_info::__vmi_class_type_info): Adjust.
	(__vmi_class_type_info::detail_masks): New member.
	* tinfo.cc (__class_type_info::do_upcast): Initialize result
	with unknown_details_mask.
	(__vmi_class_type_info::do_find_public_src): Adjust
	(__vmi_class_type_info::do_dyncast): Adjust.
	(__vmi_class_type_info::do_upcast): Set result details, if
	needed. Adjust.
	(__dynamic_cast): Temporarily #if out optimization.

Index: cp/rtti.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/rtti.c,v
retrieving revision 1.74
diff -c -3 -p -r1.74 rtti.c
*** rtti.c	2000/03/24 16:36:06	1.74
--- rtti.c	2000/03/25 10:33:39
*************** class_hint_flags (type)
*** 1384,1395 ****
       tree type;
  {
    int hint_flags = 0;
-   hint_flags |= 0x1;  /* contains multiply inherited sub object */
-   hint_flags |= 0x4;  /* has virtual bases */
-   hint_flags |= 0x8;  /* has private base */
-   if (TYPE_POLYMORPHIC_P (type))
-     hint_flags |= 0x2;
    
    return hint_flags;
  }
          
--- 1385,1396 ----
       tree type;
  {
    int hint_flags = 0;
    
+   hint_flags |= 0x1;  /* non-diamond shaped repeated base */
+   hint_flags |= 0x2;  /* diamond shaped */
+   hint_flags |= 0x4;  /* non-public base */
+   hint_flags |= 0x8;  /* public base */
+   type = 0; /* FIXME: Use it! */
    return hint_flags;
  }
          
*************** class_initializer (desc, target, trail)
*** 1404,1412 ****
       tree trail;
  {
    tree init = tinfo_base_init (desc, target);
-   int flags = class_hint_flags (target);
    
-   trail = tree_cons (NULL_TREE, build_int_2 (flags, 0), trail);
    TREE_CHAIN (init) = trail;
    init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, init);
    TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
--- 1405,1411 ----
*************** synthesize_tinfo_var (target_type, real_
*** 1512,1519 ****
                  }
                is_simple = 0;
                
!               base_init = tree_cons
!                   (NULL_TREE, build_int_2 (flags, 0), base_init);
                base_init = tree_cons (NULL_TREE, offset, base_init);
                base_init = tree_cons (NULL_TREE, tinfo, base_init);
                base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init);
--- 1511,1521 ----
                  }
                is_simple = 0;
                
!               /* combine offset and flags into one field */
!               offset = build_binary_op (LSHIFT_EXPR, offset,
!                                         build_int_2 (8, 0));
!               offset = build_binary_op (BIT_IOR_EXPR, offset,
!                                         build_int_2 (flags, 0));
                base_init = tree_cons (NULL_TREE, offset, base_init);
                base_init = tree_cons (NULL_TREE, tinfo, base_init);
                base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init);
*************** synthesize_tinfo_var (target_type, real_
*** 1524,1535 ****
              var_type = si_class_desc_type_node;
            else
              {
!               /* Prepend the number of bases.  */
                base_inits = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_inits);
                base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
                base_inits = tree_cons (NULL_TREE,
                                        build_int_2 (nbases, 0), base_inits);
!           
                var_type = get_vmi_pseudo_type_info (nbases);
              }
            var_init = class_initializer (var_type, target_type, base_inits);
--- 1526,1541 ----
              var_type = si_class_desc_type_node;
            else
              {
!               int hint = class_hint_flags (target_type);
!               
                base_inits = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_inits);
                base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
+               /* Prepend the number of bases.  */
                base_inits = tree_cons (NULL_TREE,
                                        build_int_2 (nbases, 0), base_inits);
!               /* Prepend the hint flags. */
!               base_inits = tree_cons (NULL_TREE,
!                                       build_int_2 (hint, 0), base_inits);
                var_type = get_vmi_pseudo_type_info (nbases);
              }
            var_init = class_initializer (var_type, target_type, base_inits);
*************** create_tinfo_types ()
*** 1742,1768 ****
    /* Class type_info. Add a flags field.  */
    class_desc_type_node = create_pseudo_type_info
          ("__class_type_info", 0,
-          build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
           NULL);
    
    /* Single public non-virtual base class. Add pointer to base class.  */
    si_class_desc_type_node = create_pseudo_type_info
             ("__si_class_type_info", 0,
-             build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
              build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
              NULL);
    
    /* Base class internal helper. Pointer to base type, offset to base,
       flags. */
    {
!     tree fields[3];
      
!     fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
!     fields[1] = build_lang_decl (FIELD_DECL, NULL_TREE, ptrdiff_type_node),
!     fields[2] = build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
      base_desc_type_node = make_aggr_type (RECORD_TYPE);
      finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo",
!                          fields, 2, ptr_type_node);
      TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1;
    }
    
--- 1748,1771 ----
    /* Class type_info. Add a flags field.  */
    class_desc_type_node = create_pseudo_type_info
          ("__class_type_info", 0,
           NULL);
    
    /* Single public non-virtual base class. Add pointer to base class.  */
    si_class_desc_type_node = create_pseudo_type_info
             ("__si_class_type_info", 0,
              build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
              NULL);
    
    /* Base class internal helper. Pointer to base type, offset to base,
       flags. */
    {
!     tree fields[2];
      
!     fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info);
!     fields[1] = build_lang_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
      base_desc_type_node = make_aggr_type (RECORD_TYPE);
      finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo",
!                          fields, 1, ptr_type_node);
      TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1;
    }
    
Index: cp/inc/cxxabi.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/inc/cxxabi.h,v
retrieving revision 1.1
diff -c -3 -p -r1.1 cxxabi.h
*** cxxabi.h	2000/03/21 16:12:25	1.1
--- cxxabi.h	2000/03/25 10:33:39
*************** class __base_class_info
*** 160,211 ****
  /* abi defined member variables */
  public:
    const __class_type_info *base;    /* base class type */
!   std::ptrdiff_t offset;            /* offset to the sub object */
!   int vmi_flags;                    /* about the base */
  
  /* implementation defined types */
  public:
    enum vmi_masks {
      virtual_mask = 0x1,
      public_mask = 0x2,
!     hwm_bit = 2
    };
    
  /* implementation defined member functions */
  public:
    bool is_virtual_p () const
!     { return vmi_flags & virtual_mask; }
    bool is_public_p () const
!     { return vmi_flags & public_mask; }
  };
  
  /* type information for a class */
  class __class_type_info
    : public std::type_info
  {
- /* abi defined member variables */
- public:
-   int details;      /* details about the class heirarchy */
- 
  /* abi defined member functions */
  public:
    virtual ~__class_type_info ();
  public:
!   explicit __class_type_info (const char *n_,
!                               int details_)
!     : type_info (n_), details (details_)
      { }
  
  /* implementation defined types */
  public:
-   enum detail_masks {
-     multiple_base_mask = 0x1,   /* multiple inheritance of the same base type */
-     polymorphic_mask = 0x2,     /* is a polymorphic type */
-     virtual_base_mask = 0x4,    /* has virtual bases (direct or indirect) */
-     private_base_mask = 0x8     /* has private bases (direct or indirect) */
-   };
- 
- public:
    /* sub_kind tells us about how a base object is contained within a derived
       object. We often do this lazily, hence the UNKNOWN value. At other times
       we may use NOT_CONTAINED to mean not publicly contained. */
--- 160,200 ----
  /* abi defined member variables */
  public:
    const __class_type_info *base;    /* base class type */
!   long vmi_offset_flags;            /* offset and info */
  
  /* implementation defined types */
  public:
    enum vmi_masks {
      virtual_mask = 0x1,
      public_mask = 0x2,
!     hwm_bit = 2,
!     offset_shift = 8          /* bits to shift offset by */
    };
    
  /* implementation defined member functions */
  public:
    bool is_virtual_p () const
!     { return vmi_offset_flags & virtual_mask; }
    bool is_public_p () const
!     { return vmi_offset_flags & public_mask; }
!   std::ptrdiff_t offset () const
!     { return std::ptrdiff_t (vmi_offset_flags) >> offset_shift; }
  };
  
  /* type information for a class */
  class __class_type_info
    : public std::type_info
  {
  /* abi defined member functions */
  public:
    virtual ~__class_type_info ();
  public:
!   explicit __class_type_info (const char *n_)
!     : type_info (n_)
      { }
  
  /* implementation defined types */
  public:
    /* sub_kind tells us about how a base object is contained within a derived
       object. We often do this lazily, hence the UNKNOWN value. At other times
       we may use NOT_CONTAINED to mean not publicly contained. */
*************** public:  
*** 230,236 ****
    {
      const void *dst_ptr;        /* pointer to caught object */
      sub_kind whole2dst;         /* path from most derived object to target */
!     int src_details;            /* hints about the source type */
      const __class_type_info *base_type; /* where we found the target, */
                                  /* if in vbase the __class_type_info of vbase */
                                  /* if a non-virtual base then 1 */
--- 219,225 ----
    {
      const void *dst_ptr;        /* pointer to caught object */
      sub_kind whole2dst;         /* path from most derived object 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 */
                                  /* if a non-virtual base then 1 */
*************** public:
*** 320,328 ****
    virtual ~__si_class_type_info ();
  public:
    explicit __si_class_type_info (const char *n_,
-                                  int details_,
                                   const __class_type_info *base_)
!     : __class_type_info (n_, details_), base (base_)
      { }
  
  /* implementation defined member functions */
--- 309,316 ----
    virtual ~__si_class_type_info ();
  public:
    explicit __si_class_type_info (const char *n_,
                                   const __class_type_info *base_)
!     : __class_type_info (n_), base (base_)
      { }
  
  /* implementation defined member functions */
*************** protected:
*** 342,348 ****
  /* type information for a class with multiple and/or virtual bases */
  class __vmi_class_type_info : public __class_type_info {
  /* abi defined member variables */
! protected:
    int n_bases;      /* number of direct bases */
    __base_class_info base_list[1]; /* array of bases */
    /* The array of bases uses the trailing array struct hack
--- 330,337 ----
  /* type information for a class with multiple and/or virtual bases */
  class __vmi_class_type_info : public __class_type_info {
  /* abi defined member variables */
! public:
!   int details;      /* details about the class heirarchy */
    int n_bases;      /* number of direct bases */
    __base_class_info base_list[1]; /* array of bases */
    /* The array of bases uses the trailing array struct hack
*************** public:
*** 355,362 ****
  public:
    explicit __vmi_class_type_info (const char *n_,
                                    int details_)
!     : __class_type_info (n_, details_), n_bases (0)
      { }
  
  /* implementation defined member functions */
  protected:
--- 344,362 ----
  public:
    explicit __vmi_class_type_info (const char *n_,
                                    int details_)
!     : __class_type_info (n_), details (details_), n_bases (0)
      { }
+ 
+ /* implementation defined types */
+ public:
+   enum detail_masks {
+     non_diamond_repeat_mask = 0x1,   /* distinct instance of repeated base */
+     diamond_shaped_mask = 0x2,       /* diamond shaped multiple inheritance */
+     non_public_base_mask = 0x4,      /* has non-public direct or indirect base */
+     public_base_mask = 0x8,          /* has public base (direct) */
+     
+     details_unknown_mask = 0x10
+   };
  
  /* implementation defined member functions */
  protected:

Index: cp/tinfo.cc
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/tinfo.cc,v
retrieving revision 1.18
diff -c -3 -p -r1.18 tinfo.cc
*** tinfo.cc	2000/03/21 16:12:24	1.18
--- tinfo.cc	2000/03/25 10:33:39
*************** do_catch (const type_info *thr_type, voi
*** 652,658 ****
  bool __class_type_info::
  do_upcast (const __class_type_info *dst_type, void **obj_ptr) const
  {
!   upcast_result result (details);
    
    if (do_upcast (contained_public, dst_type, *obj_ptr, result))
      return false;
--- 652,658 ----
  bool __class_type_info::
  do_upcast (const __class_type_info *dst_type, void **obj_ptr) const
  {
!   upcast_result result (__vmi_class_type_info::details_unknown_mask);
    
    if (do_upcast (contained_public, dst_type, *obj_ptr, result))
      return false;
*************** do_find_public_src (ptrdiff_t src2dst,
*** 712,718 ****
          continue; // Not public, can't be here.
        
        const void *base = obj_ptr;
!       ptrdiff_t offset = base_list[i].offset;
        
        if (base_list[i].is_virtual_p ())
          {
--- 712,718 ----
          continue; // Not public, can't be here.
        
        const void *base = obj_ptr;
!       ptrdiff_t offset = base_list[i].offset ();
        
        if (base_list[i].is_virtual_p ())
          {
*************** do_dyncast (ptrdiff_t src2dst,
*** 836,842 ****
        dyncast_result result2;
        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 ())
          {
--- 836,842 ----
        dyncast_result result2;
        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 ())
          {
*************** do_upcast (sub_kind access_path,
*** 1018,1033 ****
        return contained_nonpublic_p (access_path);
      }
    
    for (size_t i = n_bases; i--;)
      {
!       upcast_result result2 (result.src_details);
        const void *base = obj_ptr;
        sub_kind sub_access = access_path;
!       ptrdiff_t offset = base_list[i].offset;
        
        if (!base_list[i].is_public_p ())
          {
!           if (!(result.src_details & multiple_base_mask))
              // original cannot have an ambiguous base
              continue;
            sub_access = sub_kind (sub_access & ~contained_public_mask);
--- 1018,1037 ----
        return contained_nonpublic_p (access_path);
      }
    
+   int src_details = result.src_details;
+   if (src_details & details_unknown_mask)
+     src_details = details;
+   
    for (size_t i = n_bases; i--;)
      {
!       upcast_result result2 (src_details);
        const void *base = obj_ptr;
        sub_kind sub_access = access_path;
!       ptrdiff_t offset = base_list[i].offset ();
        
        if (!base_list[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);
*************** do_upcast (sub_kind access_path,
*** 1055,1061 ****
            if (!result.base_type)
              {
                result = result2;
!               if (!(details & multiple_base_mask))
                  // cannot have an ambiguous other base
                  return false;
              }
--- 1059,1065 ----
            if (!result.base_type)
              {
                result = result2;
!               if (!(details & non_diamond_repeat_mask))
                  // cannot have an ambiguous other base
                  return false;
              }
*************** __dynamic_cast (const void *src_ptr,    
*** 1120,1128 ****
--- 1124,1134 ----
    if (contained_nonvirtual_p (result.whole2src))
      // Found an invalid cross cast, which cannot also be a down cast
      return NULL;
+   #if 0 // FIXME: we need to discover this lazily
    if (!(whole_type->details & __class_type_info::private_base_mask))
      // whole type has no private bases
      return const_cast <void *> (result.dst_ptr);
+   #endif
    if (result.dst2src == __class_type_info::unknown)
      result.dst2src = dst_type->find_public_src (src2dst, result.dst_ptr,
                                                  src_type, src_ptr);

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