rtti.c (class_hint_flags): Rename flags.
authorNathan Sidwell <nathan@codesourcery.com>
Thu, 30 Mar 2000 12:08:26 +0000 (12:08 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 30 Mar 2000 12:08:26 +0000 (12:08 +0000)
* 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.

From-SVN: r32828

gcc/cp/ChangeLog
gcc/cp/inc/cxxabi.h
gcc/cp/rtti.c
gcc/cp/tinfo.cc

index 2faca96ac391971a7c2147b8a8338a0f496d178a..da0b96f90ab749d2760b39a5773dd4f66e2f47d8 100644 (file)
@@ -1,3 +1,31 @@
+2000-03-30  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.
+
 2000-03-29  Nathan Sidwell  <nathan@codesourcery.com>
 
        * rtti.c (get_tinfo_decl): Mark used.
index b140a15f648b1f0974f5909fb4f7bf0bcce081b8..26cec3fae0a6840add39275a64b0c7cd8e8ec5ad 100644 (file)
@@ -160,51 +160,40 @@ class __base_class_info
 /* 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 */
+  long vmi_offset_flags;            /* offset and info */
 
 /* implementation defined types */
 public:
   enum vmi_masks {
     virtual_mask = 0x1,
     public_mask = 0x2,
-    hwm_bit = 2
+    hwm_bit = 2,
+    offset_shift = 8          /* bits to shift offset by */
   };
   
 /* implementation defined member functions */
 public:
   bool is_virtual_p () const
-    { return vmi_flags & virtual_mask; }
+    { return vmi_offset_flags & virtual_mask; }
   bool is_public_p () const
-    { return vmi_flags & public_mask; }
+    { 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 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_)
+  explicit __class_type_info (const char *n_)
+    : type_info (n_)
     { }
 
 /* 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
@@ -230,7 +219,7 @@ public:
   {
     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 */
+    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 */
@@ -320,9 +309,8 @@ public:
   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_)
+    : __class_type_info (n_), base (base_)
     { }
 
 /* implementation defined member functions */
@@ -342,7 +330,8 @@ protected:
 /* 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:
+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
@@ -355,9 +344,20 @@ public:
 public:
   explicit __vmi_class_type_info (const char *n_,
                                   int details_)
-    : __class_type_info (n_details_), n_bases (0)
+    : __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:
   virtual bool do_dyncast (std::ptrdiff_t src2dst, sub_kind access_path,
index 13f5b0950103f043c49e1daf635e4ea6f2949916..a91bef857b49b9ebfadc335aebe40bf23897252d 100644 (file)
@@ -1392,12 +1392,12 @@ class_hint_flags (type)
      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;
   
+  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;
 }
         
@@ -1412,9 +1412,7 @@ class_initializer (desc, target, trail)
      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;
@@ -1520,8 +1518,11 @@ synthesize_tinfo_var (target_type, real_name)
                 }
               is_simple = 0;
               
-              base_init = tree_cons
-                  (NULL_TREE, build_int_2 (flags, 0), base_init);
+              /* 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);
@@ -1532,12 +1533,16 @@ synthesize_tinfo_var (target_type, real_name)
             var_type = si_class_desc_type_node;
           else
             {
-              /* Prepend the number of bases.  */
+              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);
@@ -1761,27 +1766,24 @@ create_tinfo_types ()
   /* 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];
+    tree fields[2];
     
-    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),
+    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, 2, ptr_type_node);
+                         fields, 1, ptr_type_node);
     TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1;
   }
   
index 3bf3c90a2d8339240e35d9273546e089a7e7b379..71e5c2847c4e9a24f521b3e95b8fc01447d1633b 100644 (file)
@@ -652,7 +652,7 @@ do_catch (const type_info *thr_type, void **thr_obj,
 bool __class_type_info::
 do_upcast (const __class_type_info *dst_type, void **obj_ptr) const
 {
-  upcast_result result (details);
+  upcast_result result (__vmi_class_type_info::details_unknown_mask);
   
   if (do_upcast (contained_public, dst_type, *obj_ptr, result))
     return false;
@@ -712,7 +712,7 @@ do_find_public_src (ptrdiff_t src2dst,
         continue; // Not public, can't be here.
       
       const void *base = obj_ptr;
-      ptrdiff_t offset = base_list[i].offset;
+      ptrdiff_t offset = base_list[i].offset ();
       
       if (base_list[i].is_virtual_p ())
         {
@@ -836,7 +836,7 @@ do_dyncast (ptrdiff_t src2dst,
       dyncast_result result2;
       void const *base = obj_ptr;
       sub_kind base_access = access_path;
-      ptrdiff_t offset = base_list[i].offset;
+      ptrdiff_t offset = base_list[i].offset ();
       
       if (base_list[i].is_virtual_p ())
         {
@@ -1018,16 +1018,20 @@ do_upcast (sub_kind access_path,
       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 (result.src_details);
+      upcast_result result2 (src_details);
       const void *base = obj_ptr;
       sub_kind sub_access = access_path;
-      ptrdiff_t offset = base_list[i].offset;
+      ptrdiff_t offset = base_list[i].offset ();
       
       if (!base_list[i].is_public_p ())
         {
-          if (!(result.src_details & multiple_base_mask))
+          if (!(src_details & non_diamond_repeat_mask))
             // original cannot have an ambiguous base
             continue;
           sub_access = sub_kind (sub_access & ~contained_public_mask);
@@ -1055,7 +1059,7 @@ do_upcast (sub_kind access_path,
           if (!result.base_type)
             {
               result = result2;
-              if (!(details & multiple_base_mask))
+              if (!(details & non_diamond_repeat_mask))
                 // cannot have an ambiguous other base
                 return false;
             }
@@ -1119,9 +1123,11 @@ __dynamic_cast (const void *src_ptr,    // object started from
   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);