OSDN Git Service

Put RTTI entries at negative offsets in new ABI.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 28 Mar 2000 19:27:15 +0000 (19:27 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 28 Mar 2000 19:27:15 +0000 (19:27 +0000)
* class.c (dfs_build_vbase_offset_vtbl_entries): Put the first
vbase offset at index -3, not -1.
(build_vtabe_offset_vtbl_entries): Use unmarked_vtable_pathp, not
dfs_vtable_path_unmarked_real_bases_queue_p to walk bases.
(dfs_build_vcall_offset_vtbl_entries): Don't use skip_rtti_stuff.
(build_rtti_vtbl_entries): New function.
(set_rtti_entry): Remove.
(build_primary_vtable): Don't use it.
(build_secondary_vtable): Likewise.
(start_vtable): Remove.
(first_vfun_index): New function.
(set_vindex): Likewise.
(add_virtual_function): Don't call start_vtable.  Do call
set_vindex.
(set_primary_base): Rename parameter.
(determine_primary_base): Likewise.
(num_vfun_entries): Don't use skip_rtti_stuff.
(num_extra_vtbl_entries): Include RTTI information.
(build_vtbl_initializer): Use build_rtti_vtbl_entries.
(skip_rtti_stuff): Remove.
(dfs_modify_vtables): Don't use it.
(modify_all_vtables): Don't use start_vtable.  Do use set_vindex.
(layout_nonempty_base_or_field): Update size handling.
(create_vtable_ptr): Tweak.
(layout_class_type): Adjust parameter names.
(finish_struct_1): Simplify.
* cp-tree.h (CLASSTYPE_VSIZE): Tweak documentation.
(skip_rtti_stuff): Remove.
(first_vfun_index): New function.
(dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
(dfs_vtable_path_marked_real_bases_queue_p): Remove.
(marked_vtable_pathp): Declare.
(unmarked_vtable_pathp): Likewise.
* error.c (dump_expr): Use first_vfun_index to calculate vtable
offsets.
* rtti.c (build_headof): Look for RTTI at negative offsets.
(get_tinfo_decl_dynamic): Likewise.
(tinfo_base_init): Don't take the address of the TINFO_VTABLE_DECL
here.
(create_pseudo_type_info): Do it here instead.  Adjust so that
vptr points at first virtual function.
* search.c (marked_vtable_pathp): Make it global.
(unmarked_vtable_pathp): Likewise.
(dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
(dfs_vtable_path_marked_real_bases_queue_p): Likewise.
(dfs_get_pure_virtuals): Don't use skip_rtti_stuff.
(get_pure_virtuals): Likewise.
(expand_upcast_fixups): Likewise.
* tree.c (debug_binfo): Likewise.
* tinfo.cc (__dynamic_cast): Look for vtable_prefix at appropriate
negative offset.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@32787 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/error.c
gcc/cp/rtti.c
gcc/cp/search.c
gcc/cp/tinfo.cc
gcc/cp/tree.c

index f53dd40..a787eb3 100644 (file)
@@ -1,3 +1,58 @@
+2000-03-28  Mark Mitchell  <mark@codesourcery.com>
+
+       Put RTTI entries at negative offsets in new ABI.
+       * class.c (dfs_build_vbase_offset_vtbl_entries): Put the first
+       vbase offset at index -3, not -1.
+       (build_vtabe_offset_vtbl_entries): Use unmarked_vtable_pathp, not
+       dfs_vtable_path_unmarked_real_bases_queue_p to walk bases.
+       (dfs_build_vcall_offset_vtbl_entries): Don't use skip_rtti_stuff.
+       (build_rtti_vtbl_entries): New function.
+       (set_rtti_entry): Remove.
+       (build_primary_vtable): Don't use it.
+       (build_secondary_vtable): Likewise.
+       (start_vtable): Remove.
+       (first_vfun_index): New function.
+       (set_vindex): Likewise.
+       (add_virtual_function): Don't call start_vtable.  Do call
+       set_vindex.
+       (set_primary_base): Rename parameter.
+       (determine_primary_base): Likewise.
+       (num_vfun_entries): Don't use skip_rtti_stuff.
+       (num_extra_vtbl_entries): Include RTTI information.
+       (build_vtbl_initializer): Use build_rtti_vtbl_entries.
+       (skip_rtti_stuff): Remove.
+       (dfs_modify_vtables): Don't use it.
+       (modify_all_vtables): Don't use start_vtable.  Do use set_vindex.
+       (layout_nonempty_base_or_field): Update size handling.
+       (create_vtable_ptr): Tweak.
+       (layout_class_type): Adjust parameter names.
+       (finish_struct_1): Simplify.
+       * cp-tree.h (CLASSTYPE_VSIZE): Tweak documentation.
+       (skip_rtti_stuff): Remove.
+       (first_vfun_index): New function.
+       (dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
+       (dfs_vtable_path_marked_real_bases_queue_p): Remove.
+       (marked_vtable_pathp): Declare.
+       (unmarked_vtable_pathp): Likewise.
+       * error.c (dump_expr): Use first_vfun_index to calculate vtable
+       offsets.
+       * rtti.c (build_headof): Look for RTTI at negative offsets.
+       (get_tinfo_decl_dynamic): Likewise.
+       (tinfo_base_init): Don't take the address of the TINFO_VTABLE_DECL
+       here.
+       (create_pseudo_type_info): Do it here instead.  Adjust so that
+       vptr points at first virtual function.
+       * search.c (marked_vtable_pathp): Make it global.
+       (unmarked_vtable_pathp): Likewise.
+       (dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
+       (dfs_vtable_path_marked_real_bases_queue_p): Likewise.
+       (dfs_get_pure_virtuals): Don't use skip_rtti_stuff.
+       (get_pure_virtuals): Likewise.
+       (expand_upcast_fixups): Likewise.
+       * tree.c (debug_binfo): Likewise.
+       * tinfo.cc (__dynamic_cast): Look for vtable_prefix at appropriate
+       negative offset.
+       
 Sun Mar 26 20:15:26 2000  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
        * class.c (check_field_decl): Fix typo.
index 1e48e89..a0bbf7f 100644 (file)
@@ -80,7 +80,6 @@ static tree build_vtable_entry PARAMS ((tree, tree, tree));
 static tree get_vtable_name PARAMS ((tree));
 static tree get_derived_offset PARAMS ((tree, tree));
 static tree get_basefndecls PARAMS ((tree, tree));
-static void set_rtti_entry PARAMS ((tree, tree, tree));
 static int build_primary_vtable PARAMS ((tree, tree));
 static int build_secondary_vtable PARAMS ((tree, tree));
 static tree dfs_finish_vtbls PARAMS ((tree, void *));
@@ -142,7 +141,6 @@ static tree dfs_vcall_offset_queue_p PARAMS ((tree, void *));
 static tree dfs_build_vcall_offset_vtbl_entries PARAMS ((tree, void *));
 static tree build_vcall_offset_vtbl_entries PARAMS ((tree, tree));
 static tree dfs_count_virtuals PARAMS ((tree, void *));
-static void start_vtable PARAMS ((tree, int *));
 static void layout_vtable_decl PARAMS ((tree, int));
 static int num_vfun_entries PARAMS ((tree));
 static tree dfs_find_final_overrider PARAMS ((tree, void *));
@@ -162,6 +160,8 @@ static int layout_conflict_p PARAMS ((tree, varray_type));
 static unsigned HOST_WIDE_INT end_of_class PARAMS ((tree, int));
 static void layout_empty_base PARAMS ((tree, tree, varray_type));
 static void accumulate_vtbl_inits PARAMS ((tree, tree));
+static void set_vindex PARAMS ((tree, tree, int *));
+static tree build_rtti_vtbl_entries PARAMS ((tree, tree));
 
 /* Variables shared between class.c and call.c.  */
 
@@ -279,7 +279,7 @@ dfs_build_vbase_offset_vtbl_entries (binfo, data)
         base.  */
       vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), TREE_PURPOSE (list));
       if (!TREE_VALUE (list))
-       BINFO_VPTR_FIELD (vbase) = build_int_2 (-1, 0);
+       BINFO_VPTR_FIELD (vbase) = build_int_2 (-3, 0);
       else
        {
          BINFO_VPTR_FIELD (vbase) = TREE_PURPOSE (TREE_VALUE (list));
@@ -333,11 +333,11 @@ build_vbase_offset_vtbl_entries (binfo, t)
   TREE_TYPE (list) = binfo;
   dfs_walk (binfo,
            dfs_build_vbase_offset_vtbl_entries,
-           dfs_vtable_path_unmarked_real_bases_queue_p,
+           unmarked_vtable_pathp,
            list);
   dfs_walk (binfo,
            dfs_vtable_path_unmark,
-           dfs_vtable_path_marked_real_bases_queue_p,
+           marked_vtable_pathp,
            list);
   inits = nreverse (TREE_VALUE (list));
 
@@ -405,9 +405,7 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data)
 
   /* We chain the offsets on in reverse order.  That's correct --
      build_vtbl_initializer will straighten them out.  */
-  for (virtuals = skip_rtti_stuff (binfo,
-                                  BINFO_TYPE (binfo),
-                                  NULL);
+  for (virtuals = BINFO_VIRTUALS (binfo);
        virtuals;
        virtuals = TREE_CHAIN (virtuals))
     {
@@ -486,6 +484,82 @@ build_vcall_offset_vtbl_entries (binfo, t)
   return vod.inits;
 }
 
+/* Return vtbl initializers for the RTTI entries coresponding to the
+   BINFO's vtable.  BINFO is a part of the hierarchy dominated by 
+   T.  */
+
+static tree
+build_rtti_vtbl_entries (binfo, t)
+     tree binfo;
+     tree t;
+{
+  tree b;
+  tree basetype;
+  tree inits;
+  tree offset;
+  tree decl;
+  tree init;
+
+  basetype = BINFO_TYPE (binfo);
+  inits = NULL_TREE;
+
+  /* For a COM object there is no RTTI entry.  */
+  if (CLASSTYPE_COM_INTERFACE (basetype))
+    return inits;
+
+  /* To find the complete object, we will first convert to our most
+     primary base, and then add the offset in the vtbl to that value.  */
+  b = binfo;
+  while (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (b)))
+    b = BINFO_BASETYPE (b, 
+                       CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (b)));
+  offset = size_diffop (size_zero_node, BINFO_OFFSET (b));
+
+  /* Add the offset-to-top entry.  */
+  if (flag_vtable_thunks)
+    {
+      /* Convert the offset to look like a function pointer, so that
+        we can put it in the vtable.  */
+      init = build1 (NOP_EXPR, vfunc_ptr_type_node, offset);
+      TREE_CONSTANT (init) = 1;
+      inits = tree_cons (NULL_TREE, init, inits);
+    }
+
+  /* The second entry is, in the case of the new ABI, the address of
+     the typeinfo object, or, in the case of the old ABI, a function
+     which returns a typeinfo object.  */
+  if (new_abi_rtti_p ())
+    {
+      if (flag_rtti)
+       decl = build_unary_op (ADDR_EXPR, get_tinfo_decl (t), 0);
+      else
+       decl = integer_zero_node;
+
+      /* Convert the declaration to a type that can be stored in the
+        vtable.  */
+      init = build1 (NOP_EXPR, vfunc_ptr_type_node, decl);
+      TREE_CONSTANT (init) = 1;
+    }
+  else
+    {
+      if (flag_rtti)
+       decl = get_tinfo_decl (t);
+      else
+       decl = abort_fndecl;
+
+      /* Convert the declaration to a type that can be stored in the
+        vtable.  */
+      init = build1 (ADDR_EXPR, vfunc_ptr_type_node, decl);
+      TREE_CONSTANT (init) = 1;
+      init = build_vtable_entry (offset, integer_zero_node, init);
+    }
+
+  /* Hook the RTTI declaration onto the list.  */
+  inits = tree_cons (NULL_TREE, init, inits);
+
+  return inits;
+}
+
 /* Returns a pointer to the virtual base class of EXP that has the
    indicated TYPE.  EXP is of class type, not a pointer type.  */
 
@@ -945,47 +1019,6 @@ get_derived_offset (binfo, type)
   return size_binop (MINUS_EXPR, offset1, offset2);
 }
 
-/* Update the rtti info for this class.  */
-
-static void
-set_rtti_entry (virtuals, offset, type)
-     tree virtuals, offset, type;
-{
-  tree decl;
-
-  if (CLASSTYPE_COM_INTERFACE (type))
-    return;
-
-  if (flag_rtti)
-    decl = get_tinfo_decl (type);
-  else if (!new_abi_rtti_p ())
-    /* If someone tries to get RTTI information for a type compiled
-       without RTTI, they're out of luck.  By calling __pure_virtual
-       in this case, we give a small clue as to what went wrong.  We
-       could consider having a __no_typeinfo function as well, for a
-       more specific hint.  */
-    decl = abort_fndecl;
-  else
-    /* For the new-abi, we just point to the type_info object.  */
-    decl = NULL_TREE;
-
-  if (flag_vtable_thunks)
-    {
-      /* The first slot holds the offset.  */
-      BV_DELTA (virtuals) = offset;
-      BV_VCALL_INDEX (virtuals) = integer_zero_node;
-
-      /* The next node holds the decl.  */
-      virtuals = TREE_CHAIN (virtuals);
-      offset = ssize_int (0);
-    }
-
-  /* This slot holds the function to call.  */
-  BV_DELTA (virtuals) = offset;
-  BV_VCALL_INDEX (virtuals) = integer_zero_node;
-  BV_FN (virtuals) = decl;
-}
-
 /* Create a VAR_DECL for a primary or secondary vtable for
    CLASS_TYPE.  Use NAME for the name of the vtable, and VTABLE_TYPE
    for its type.  */
@@ -1067,8 +1100,6 @@ build_primary_vtable (binfo, type)
   
   if (binfo)
     {
-      tree offset;
-
       if (BINFO_NEW_VTABLE_MARKED (binfo, type))
        /* We have already created a vtable for this base, so there's
           no need to do it again.  */
@@ -1079,11 +1110,6 @@ build_primary_vtable (binfo, type)
       DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (BINFO_VTABLE (binfo)));
       DECL_SIZE_UNIT (decl)
        = TYPE_SIZE_UNIT (TREE_TYPE (BINFO_VTABLE (binfo)));
-
-      /* Now do rtti stuff.  */
-      offset = get_derived_offset (TYPE_BINFO (type), NULL_TREE);
-      offset = size_diffop (size_zero_node, offset);
-      set_rtti_entry (virtuals, offset, type);
     }
   else
     {
@@ -1171,10 +1197,6 @@ build_secondary_vtable (binfo, for_type)
   else
     offset = BINFO_OFFSET (binfo);
 
-  set_rtti_entry (BINFO_VIRTUALS (binfo),
-                 size_diffop (size_zero_node, offset),
-                 for_type);
-
   /* In the new ABI, secondary vtables are laid out as part of the
      same structure as the primary vtable.  */
   if (merge_primary_and_secondary_vtables_p ())
@@ -1349,42 +1371,52 @@ modify_vtable_entry (t, binfo, fndecl, delta, virtuals)
     }
 }
 
-/* Call this function whenever its known that a vtable for T is going
-   to be needed.  It's safe to call it more than once.  *HAS_VIRTUAL_P
-   is initialized to the number of slots that are reserved at the
-   beginning of the vtable for RTTI information.  */
+/* Return the index (in the virtual function table) of the first
+   virtual function.  */
+
+int
+first_vfun_index (t)
+     tree t;
+{
+  /* Under the old ABI, the offset-to-top and RTTI entries are at
+     indices zero and one; under the new ABI, the first virtual
+     function is at index zero.  */
+  if (!CLASSTYPE_COM_INTERFACE (t) && !flag_new_abi)
+    return flag_vtable_thunks ? 2 : 1;
+
+  return 0;
+}
+
+/* Set DECL_VINDEX for DECL.  VINDEX_P is the number of virtual
+   functions present in the vtable so far.  */
 
 static void
-start_vtable (t, has_virtual_p)
+set_vindex (t, decl, vfuns_p)
      tree t;
-     int *has_virtual_p;
+     tree decl;
+     int *vfuns_p;
 {
-  if (*has_virtual_p == 0 && ! CLASSTYPE_COM_INTERFACE (t))
-    {
-      /* If we are using thunks, use two slots at the front, one
-        for the offset pointer, one for the tdesc pointer.
-         For ARM-style vtables, use the same slot for both.  */
-      if (flag_vtable_thunks)
-       *has_virtual_p = 2;
-      else
-       *has_virtual_p = 1;
-    }
+  int vindex;
+
+  vindex = (*vfuns_p)++;
+  vindex += first_vfun_index (t);
+  DECL_VINDEX (decl) = build_shared_int_cst (vindex);
 }
 
 /* Add a virtual function to all the appropriate vtables for the class
    T.  DECL_VINDEX(X) should be error_mark_node, if we want to
    allocate a new slot in our table.  If it is error_mark_node, we
    know that no other function from another vtable is overridden by X.
-   HAS_VIRTUAL keeps track of how many virtuals there are in our main
-   vtable for the type, and we build upon the NEW_VIRTUALS list
+   VFUNS_P keeps track of how many virtuals there are in our
+   main vtable for the type, and we build upon the NEW_VIRTUALS list
    and return it.  */
 
 static void
 add_virtual_function (new_virtuals_p, overridden_virtuals_p,
-                     has_virtual, fndecl, t)
+                     vfuns_p, fndecl, t)
      tree *new_virtuals_p;
      tree *overridden_virtuals_p;
-     int *has_virtual;
+     int *vfuns_p;
      tree fndecl;
      tree t; /* Structure type.  */
 {
@@ -1409,10 +1441,8 @@ add_virtual_function (new_virtuals_p, overridden_virtuals_p,
       /* We remember that this was the base sub-object for rtti.  */
       CLASSTYPE_RTTI (t) = t;
 
-      start_vtable (t, has_virtual);
-
       /* Now assign virtual dispatch information.  */
-      DECL_VINDEX (fndecl) = build_shared_int_cst ((*has_virtual)++);
+      set_vindex (t, fndecl, vfuns_p);
       DECL_VIRTUAL_CONTEXT (fndecl) = t;
 
       /* Save the state we've computed on the NEW_VIRTUALS list.  */
@@ -1969,10 +1999,10 @@ check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p,
 /* Make the Ith baseclass of T its primary base.  */
 
 static void
-set_primary_base (t, i, has_virtual_p)
+set_primary_base (t, i, vfuns_p)
      tree t;
      int i;
-     int *has_virtual_p;
+     int *vfuns_p;
 {
   tree basetype;
 
@@ -1982,15 +2012,15 @@ set_primary_base (t, i, has_virtual_p)
   TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype);
   TYPE_VFIELD (t) = TYPE_VFIELD (basetype);
   CLASSTYPE_RTTI (t) = CLASSTYPE_RTTI (basetype);
-  *has_virtual_p = CLASSTYPE_VSIZE (basetype);
+  *vfuns_p = CLASSTYPE_VSIZE (basetype);
 }
 
 /* Determine the primary class for T.  */
 
 static void
-determine_primary_base (t, has_virtual_p)
+determine_primary_base (t, vfuns_p)
      tree t;
-     int *has_virtual_p;
+     int *vfuns_p;
 {
   int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
 
@@ -1998,7 +2028,7 @@ determine_primary_base (t, has_virtual_p)
   if (n_baseclasses == 0)
     return;
 
-  *has_virtual_p = 0;
+  *vfuns_p = 0;
 
   for (i = 0; i < n_baseclasses; i++)
     {
@@ -2021,7 +2051,7 @@ determine_primary_base (t, has_virtual_p)
 
          if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
            {
-             set_primary_base (t, i, has_virtual_p);
+             set_primary_base (t, i, vfuns_p);
              CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype));
            }
          else
@@ -2039,8 +2069,8 @@ determine_primary_base (t, has_virtual_p)
                                 VF_BASETYPE_VALUE (vfields),
                                 CLASSTYPE_VFIELDS (t));
 
-             if (*has_virtual_p == 0)
-               set_primary_base (t, i, has_virtual_p);
+             if (*vfuns_p == 0)
+               set_primary_base (t, i, vfuns_p);
            }
        }
     }
@@ -2060,7 +2090,7 @@ determine_primary_base (t, has_virtual_p)
        if (TREE_VIA_VIRTUAL (base_binfo) 
            && CLASSTYPE_NEARLY_EMPTY_P (basetype))
          {
-           set_primary_base (t, i, has_virtual_p);
+           set_primary_base (t, i, vfuns_p);
            CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype));
            break;
          }
@@ -2557,9 +2587,7 @@ static int
 num_vfun_entries (binfo)
      tree binfo;
 {
-  return list_length (skip_rtti_stuff (binfo,
-                                      BINFO_TYPE (binfo),
-                                      NULL));
+  return list_length (BINFO_VIRTUALS (binfo));
 }
 
 /* Called from num_extra_vtbl_entries via dfs_walk.  */
@@ -2609,7 +2637,19 @@ num_extra_vtbl_entries (binfo)
       entries += vod.offsets;
     }
       
-  return entries ? size_int (entries) : size_zero_node;
+  /* When laying out COM-compatible classes, there are no RTTI
+     entries.  */
+  if (CLASSTYPE_COM_INTERFACE (type))
+    ;
+  /* When using vtable thunks, there are two RTTI entries: the "offset
+     to top" value and the RTTI entry itself.  */
+  else if (flag_vtable_thunks)
+    entries += 2;
+  /* When not using vtable thunks there is only a single entry.  */
+  else
+    entries += 1;
+
+  return size_int (entries);
 }
 
 /* Returns the offset (in bytes) from the beginning of BINFO's vtable
@@ -2636,7 +2676,6 @@ build_vtbl_initializer (binfo, t)
 {
   tree v = BINFO_VIRTUALS (binfo);
   tree inits = NULL_TREE;
-  tree type = BINFO_TYPE (binfo);
 
   /* Add entries to the vtable that indicate how to adjust the this
      pointer when calling a virtual function in this class.  */
@@ -2646,48 +2685,8 @@ build_vtbl_initializer (binfo, t)
   inits = chainon (build_vbase_offset_vtbl_entries (binfo, t),
                   inits);
 
-  /* Process the RTTI stuff at the head of the list.  If we're not
-     using vtable thunks, then the RTTI entry is just an ordinary
-     function, and we can process it just like the other virtual
-     function entries.  */
-  if (!CLASSTYPE_COM_INTERFACE (type) && flag_vtable_thunks)
-    {
-      tree offset;
-      tree init;
-
-      /* The first entry is an offset.  */
-      offset = TREE_PURPOSE (v);
-      my_friendly_assert (TREE_CODE (offset) == INTEGER_CST,
-                         19990727);
-
-      /* Convert the offset to look like a function pointer, so that
-        we can put it in the vtable.  */
-      init = build1 (NOP_EXPR, vfunc_ptr_type_node, offset);
-      TREE_CONSTANT (init) = 1;
-      inits = tree_cons (NULL_TREE, init, inits);
-
-      v = TREE_CHAIN (v);
-      
-      if (new_abi_rtti_p ())
-        {
-          tree decl = TREE_VALUE (v);
-          
-          if (decl)
-            decl = build_unary_op (ADDR_EXPR, decl, 0);
-          else
-            decl = integer_zero_node;
-          decl = build1 (NOP_EXPR, vfunc_ptr_type_node, decl);
-          TREE_CONSTANT (decl) = 1;
-          decl = build_vtable_entry (integer_zero_node, integer_zero_node,
-                                     decl);
-          inits = tree_cons (NULL_TREE, decl, inits);
-          
-          v = TREE_CHAIN (v);
-        }
-      /* In the old abi the second entry (the tdesc pointer) is
-        just an ordinary function, so it can be dealt with like the
-        virtual functions.  */
-    }
+  /* Add entries to the vtable for RTTI.  */
+  inits = chainon (build_rtti_vtbl_entries (binfo, t), inits);
 
   /* Go through all the ordinary virtual functions, building up
      initializers.  */
@@ -3048,43 +3047,6 @@ find_final_overrider (t, binfo, fn)
   return build_tree_list (ffod.overriding_fn, ffod.overriding_base);
 }
 
-/* Return the BINFO_VIRTUALS list for BINFO, without the RTTI stuff at
-   the front.  If non-NULL, N is set to the number of entries
-   skipped.  */
-
-tree
-skip_rtti_stuff (binfo, t, n)
-     tree binfo;
-     tree t;
-     HOST_WIDE_INT *n;
-{
-  tree virtuals;
-
-  if (CLASSTYPE_COM_INTERFACE (t))
-    return 0;
-
-  if (n)
-    *n = 0;
-  virtuals = BINFO_VIRTUALS (binfo);
-  if (virtuals)
-    {
-      /* We always reserve a slot for the offset/tdesc entry.  */
-      if (n)
-       ++*n;
-      virtuals = TREE_CHAIN (virtuals);
-    }
-  if (flag_vtable_thunks && virtuals)
-    {
-      /* The second slot is reserved for the tdesc pointer when thunks
-         are used.  */
-      if (n)
-       ++*n;
-      virtuals = TREE_CHAIN (virtuals);
-    }
-
-  return virtuals;
-}
-
 /* Called via dfs_walk.  Returns BINFO if BINFO has the same type as
    DATA (which is really an _TYPE node).  */
 
@@ -3125,10 +3087,8 @@ dfs_modify_vtables (binfo, data)
       /* Now, go through each of the virtual functions in the virtual
         function table for BINFO.  Find the final overrider, and
         update the BINFO_VIRTUALS list appropriately.  */
-      for (virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), NULL),
-            old_virtuals = skip_rtti_stuff (TYPE_BINFO (BINFO_TYPE (binfo)),
-                                            BINFO_TYPE (binfo),
-                                            NULL);
+      for (virtuals = BINFO_VIRTUALS (binfo),
+            old_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo)));
           virtuals;
           virtuals = TREE_CHAIN (virtuals),
             old_virtuals = TREE_CHAIN (old_virtuals))
@@ -3138,17 +3098,16 @@ dfs_modify_vtables (binfo, data)
          tree overrider;
          tree vindex;
          tree delta;
-         HOST_WIDE_INT vindex_val, i;
-
+         HOST_WIDE_INT vindex_val;
+         HOST_WIDE_INT i;
 
          /* Find the function which originally caused this vtable
             entry to be present.  */
          fn = BV_FN (old_virtuals);
          vindex = DECL_VINDEX (fn);
          b = dfs_walk (binfo, dfs_find_base, NULL, DECL_VIRTUAL_CONTEXT (fn));
-         fn = skip_rtti_stuff (TYPE_BINFO (BINFO_TYPE (b)),
-                               BINFO_TYPE (b),
-                               &i);
+         fn = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (b)));
+         i = first_vfun_index (BINFO_TYPE (b));
          vindex_val = tree_low_cst (vindex, 0);
          while (i < vindex_val)
            {
@@ -3195,9 +3154,9 @@ dfs_modify_vtables (binfo, data)
    which should therefore be appended to the end of the vtable for T.  */
 
 static tree
-modify_all_vtables (t, has_virtual_p, overridden_virtuals)
+modify_all_vtables (t, vfuns_p, overridden_virtuals)
      tree t;
-     int *has_virtual_p;
+     int *vfuns_p;
      tree overridden_virtuals;
 {
   tree binfo;
@@ -3224,11 +3183,8 @@ modify_all_vtables (t, has_virtual_p, overridden_virtuals)
          if (BINFO_VIRTUALS (binfo)
              && !value_member (fn, BINFO_VIRTUALS (binfo)))
            {
-             /* We know we need a vtable for this class now.  */
-             start_vtable (t, has_virtual_p);
              /* Set the vtable index.  */
-             DECL_VINDEX (fn) 
-               = build_shared_int_cst ((*has_virtual_p)++);
+             set_vindex (t, fn, vfuns_p);
              /* We don't need to convert to a base class when calling
                 this function.  */
              DECL_VIRTUAL_CONTEXT (fn) = t;
@@ -4220,9 +4176,10 @@ layout_nonempty_base_or_field (rli, decl, binfo, v)
       
       /* Now that we know where it wil be placed, update its
         BINFO_OFFSET.  */
-      offset = convert (ssizetype, byte_position (decl));
+      offset = byte_position (decl);
       if (binfo)
-       propagate_binfo_offsets (binfo, offset);
+       propagate_binfo_offsets (binfo, 
+                                convert (ssizetype, offset));
  
       /* We have to check to see whether or not there is already
         something of the same type at the offset we're about to use.
@@ -4243,7 +4200,7 @@ layout_nonempty_base_or_field (rli, decl, binfo, v)
        {
          /* Undo the propogate_binfo_offsets call.  */
          offset = size_diffop (size_zero_node, offset);
-         propagate_binfo_offsets (binfo, offset);
+         propagate_binfo_offsets (binfo, convert (ssizetype, offset));
         
          /* Strip off the size allocated to this field.  That puts us
             at the first place we could have put the field with
@@ -4601,11 +4558,11 @@ check_bases_and_members (t, empty_p)
    responsibility to do that.  */
 
 static tree
-create_vtable_ptr (t, empty_p, has_virtual_p, 
+create_vtable_ptr (t, empty_p, vfuns_p,
                   new_virtuals_p, overridden_virtuals_p)
      tree t;
      int *empty_p;
-     int *has_virtual_p;
+     int *vfuns_p;
      tree *new_virtuals_p;
      tree *overridden_virtuals_p;
 {
@@ -4616,17 +4573,15 @@ create_vtable_ptr (t, empty_p, has_virtual_p,
   for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
     if (DECL_VINDEX (fn))
       add_virtual_function (new_virtuals_p, overridden_virtuals_p,
-                           has_virtual_p, fn, t);
+                           vfuns_p, fn, t);
 
-  /* Even if there weren't any new virtual functions, we might need a
+  /* If we couldn't find an appropriate base class, create a new field
+     here.  Even if there weren't any new virtual functions, we might need a
      new virtual function table if we're supposed to include vptrs in
      all classes that need them.  */
-  if (TYPE_CONTAINS_VPTR_P (t) && vptrs_present_everywhere_p ())
-    start_vtable (t, has_virtual_p);
-    
-  /* If we couldn't find an appropriate base class, create a new field
-     here.  */
-  if (*has_virtual_p && !TYPE_VFIELD (t))
+  if (!TYPE_VFIELD (t)
+      && (*vfuns_p 
+         || (TYPE_CONTAINS_VPTR_P (t) && vptrs_present_everywhere_p ())))
     {
       /* We build this decl with vtbl_ptr_type_node, which is a
         `vtable_entry_type*'.  It might seem more precise to use
@@ -4972,11 +4927,11 @@ end_of_class (t, include_virtuals_p)
    pointer.  */
 
 static void
-layout_class_type (t, empty_p, has_virtual_p, 
+layout_class_type (t, empty_p, vfuns_p, 
                   new_virtuals_p, overridden_virtuals_p)
      tree t;
      int *empty_p;
-     int *has_virtual_p;
+     int *vfuns_p;
      tree *new_virtuals_p;
      tree *overridden_virtuals_p;
 {
@@ -4995,10 +4950,10 @@ layout_class_type (t, empty_p, has_virtual_p,
 
   /* If possible, we reuse the virtual function table pointer from one
      of our base classes.  */
-  determine_primary_base (t, has_virtual_p);
+  determine_primary_base (t, vfuns_p);
 
   /* Create a pointer to our virtual function table.  */
-  vptr = create_vtable_ptr (t, empty_p, has_virtual_p,
+  vptr = create_vtable_ptr (t, empty_p, vfuns_p,
                            new_virtuals_p, overridden_virtuals_p);
 
   /* Under the new ABI, the vptr is always the first thing in the
@@ -5215,7 +5170,7 @@ finish_struct_1 (t)
      tree t;
 {
   tree x;
-  int has_virtual;
+  int vfuns;
   /* The NEW_VIRTUALS is a TREE_LIST.  The TREE_VALUE of each node is
      a FUNCTION_DECL.  Each of these functions is a virtual function
      declared in T that does not override any virtual function from a
@@ -5246,7 +5201,7 @@ finish_struct_1 (t)
   TYPE_SIZE (t) = NULL_TREE;
   CLASSTYPE_GOT_SEMICOLON (t) = 0;
   CLASSTYPE_VFIELD_PARENT (t) = -1;
-  has_virtual = 0;
+  vfuns = 0;
   CLASSTYPE_RTTI (t) = NULL_TREE;
 
   /* Do end-of-class semantic processing: checking the validity of the
@@ -5254,7 +5209,7 @@ finish_struct_1 (t)
   check_bases_and_members (t, &empty);
 
   /* Layout the class itself.  */
-  layout_class_type (t, &empty, &has_virtual,
+  layout_class_type (t, &empty, &vfuns,
                     &new_virtuals, &overridden_virtuals);
 
   /* Set up the DECL_FIELD_BITPOS of the vfield if we need to, as we
@@ -5278,7 +5233,7 @@ finish_struct_1 (t)
     }
 
   overridden_virtuals 
-    = modify_all_vtables (t, &has_virtual, nreverse (overridden_virtuals));
+    = modify_all_vtables (t, &vfuns, nreverse (overridden_virtuals));
 
   /* If necessary, create the primary vtable for this class.  */
   if (new_virtuals
@@ -5288,22 +5243,7 @@ finish_struct_1 (t)
       new_virtuals = nreverse (new_virtuals);
       /* We must enter these virtuals into the table.  */
       if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
-       {
-         if (! CLASSTYPE_COM_INTERFACE (t))
-           {
-             /* The second slot is for the tdesc pointer when thunks
-                are used.  */
-             if (flag_vtable_thunks)
-               new_virtuals = tree_cons (NULL_TREE, NULL_TREE, new_virtuals);
-
-             /* The first slot is for the rtti offset.  */
-             new_virtuals = tree_cons (NULL_TREE, NULL_TREE, new_virtuals);
-
-             set_rtti_entry (new_virtuals,
-                             convert (ssizetype, integer_zero_node), t);
-           }
-         build_primary_vtable (NULL_TREE, t);
-       }
+       build_primary_vtable (NULL_TREE, t);
       else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t), t))
        /* Here we know enough to change the type of our virtual
           function table, but we will wait until later this function.  */
@@ -5346,7 +5286,7 @@ finish_struct_1 (t)
        my_friendly_assert (TYPE_BINFO_VIRTUALS (t) == NULL_TREE,
                            20000116);
 
-      CLASSTYPE_VSIZE (t) = has_virtual;
+      CLASSTYPE_VSIZE (t) = vfuns;
       /* Entries for virtual functions defined in the primary base are
         followed by entries for new functions unique to this class.  */
       TYPE_BINFO_VIRTUALS (t) 
index 57c711f..0433135 100644 (file)
@@ -1545,8 +1545,8 @@ struct lang_type
                     CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (NODE)))       \
    : NULL_TREE)
 
-/* The number of virtual functions defined for this
-   _CLASSTYPE node.  */
+/* The number of virtual functions present in this classes virtual
+   function table.  */
 #define CLASSTYPE_VSIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->vsize)
 
 /* A chain of BINFOs for the direct and indirect virtual base classes
@@ -3685,8 +3685,7 @@ extern void push_lang_context                     PARAMS ((tree));
 extern void pop_lang_context                   PARAMS ((void));
 extern tree instantiate_type                   PARAMS ((tree, tree, int));
 extern void print_class_statistics             PARAMS ((void));
-extern tree skip_rtti_stuff                    PARAMS ((tree, tree,
-                                                        HOST_WIDE_INT *));
+extern int first_vfun_index                     PARAMS ((tree));
 extern void build_self_reference               PARAMS ((void));
 extern void warn_hidden                                PARAMS ((tree));
 extern tree get_enclosing_class                        PARAMS ((tree));
@@ -4212,11 +4211,9 @@ extern tree dfs_skip_nonprimary_vbases_unmarkedp PARAMS ((tree, void *));
 extern tree dfs_skip_nonprimary_vbases_markedp  PARAMS ((tree, void *));
 extern tree dfs_unmarked_real_bases_queue_p     PARAMS ((tree, void *));
 extern tree dfs_marked_real_bases_queue_p       PARAMS ((tree, void *));
-extern tree dfs_vtable_path_unmarked_real_bases_queue_p
-                                                PARAMS ((tree, void *));
-extern tree dfs_vtable_path_marked_real_bases_queue_p
-                                                PARAMS ((tree, void *));
 extern tree dfs_skip_vbases                     PARAMS ((tree, void *));
+extern tree marked_vtable_pathp                 PARAMS ((tree, void *));
+extern tree unmarked_vtable_pathp               PARAMS ((tree, void *));
 extern void mark_primary_bases                  PARAMS ((tree));
 extern tree convert_pointer_to_vbase            PARAMS ((tree, tree));
 extern tree find_vbase_instance                 PARAMS ((tree, tree));
index a0be98f..5600176 100644 (file)
@@ -1857,7 +1857,7 @@ dump_expr (t, flags)
              t = TYPE_METHOD_BASETYPE (t);
              virtuals = TYPE_BINFO_VIRTUALS (TYPE_MAIN_VARIANT (t));
              
-             n = tree_low_cst (idx, 0);
+             n = tree_low_cst (idx, 0) - first_vfun_index (t);
 
              /* Map vtable index back one, to allow for the null pointer to
                 member.  */
index 30a972c..ea21756 100644 (file)
@@ -132,6 +132,7 @@ build_headof (exp)
   tree type = TREE_TYPE (exp);
   tree aref;
   tree offset;
+  tree index;
 
   my_friendly_assert (TREE_CODE (type) == POINTER_TYPE, 20000112);
   type = TREE_TYPE (type);
@@ -151,7 +152,15 @@ build_headof (exp)
   /* We use this a couple of times below, protect it.  */
   exp = save_expr (exp);
 
-  aref = build_vtbl_ref (build_indirect_ref (exp, NULL_PTR), integer_zero_node);
+  /* Under the new ABI, the offset-to-top field is at index -2 from
+     the vptr.  */
+  if (new_abi_rtti_p ())
+    index = build_int_2 (-2, -1);
+  /* But under the old ABI, it is at offset zero.  */
+  else
+    index = integer_zero_node;
+
+  aref = build_vtbl_ref (build_indirect_ref (exp, NULL_PTR), index);
 
   if (flag_vtable_thunks)
     offset = aref;
@@ -230,6 +239,7 @@ get_tinfo_decl_dynamic (exp)
     {
       /* build reference to type_info from vtable.  */
       tree t;
+      tree index;
 
       if (! flag_rtti)
        error ("taking dynamic typeid of object with -fno-rtti");
@@ -247,10 +257,15 @@ get_tinfo_decl_dynamic (exp)
          exp = build_indirect_ref (exp, NULL_PTR);
        }
 
-      if (flag_vtable_thunks)
-       t = build_vfn_ref ((tree *) 0, exp, integer_one_node);
+      /* The RTTI information is always in the vtable, but it's at
+        different indices depending on the ABI.  */
+      if (new_abi_rtti_p ())
+       index = minus_one_node;
+      else if (flag_vtable_thunks)
+       index = integer_one_node;
       else
-       t = build_vfn_ref ((tree *) 0, exp, integer_zero_node);
+       index = integer_zero_node;
+      t = build_vfn_ref ((tree *) 0, exp, index);
       TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
       return t;
     }
@@ -1284,8 +1299,7 @@ tinfo_base_init (desc, target)
   
   if (TINFO_VTABLE_DECL (desc))
     {
-      tree vtbl_ptr = build_unary_op (ADDR_EXPR, TINFO_VTABLE_DECL (desc), 0);
-  
+      tree vtbl_ptr = TINFO_VTABLE_DECL (desc);
       init = tree_cons (NULL_TREE, vtbl_ptr, init);
     }
   
@@ -1616,7 +1630,18 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
   /* Get the vtable decl. */
   real_type = xref_tag (class_type_node, get_identifier (real_name), 1);
   vtable_decl = get_vtable_decl (real_type, /*complete=*/1);
-  
+  vtable_decl = build_unary_op (ADDR_EXPR, vtable_decl, 0);
+
+  /* Under the new ABI, we need to point into the middle of the
+     vtable.  */
+  if (vbase_offsets_in_vtable_p ())
+    {
+      vtable_decl = build (PLUS_EXPR, TREE_TYPE (vtable_decl), 
+                          vtable_decl,
+                          size_extra_vtbl_entries (TYPE_BINFO (real_type)));
+      TREE_CONSTANT (vtable_decl) = 1;
+    }
+
   /* First field is the pseudo type_info base class. */
   fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
   
index cafdfc2..14ceff2 100644 (file)
@@ -104,8 +104,6 @@ static void expand_upcast_fixups
 static void fixup_virtual_upcast_offsets
        PARAMS ((tree, tree, int, int, tree, tree, tree, tree,
               tree *));
-static tree marked_vtable_pathp PARAMS ((tree, void *));
-static tree unmarked_vtable_pathp PARAMS ((tree, void *));
 static tree marked_new_vtablep PARAMS ((tree, void *));
 static tree unmarked_new_vtablep PARAMS ((tree, void *));
 static tree marked_pushdecls_p PARAMS ((tree, void *));
@@ -2346,30 +2344,6 @@ dfs_marked_real_bases_queue_p (binfo, data)
   return binfo ? markedp (binfo, NULL) : NULL_TREE;
 }
 
-/* Like dfs_unmarked_real_bases_queue_p but walks only into things
-   that are not BINFO_VTABLE_PATH_MARKED.  */
-
-tree
-dfs_vtable_path_unmarked_real_bases_queue_p (binfo, data)
-     tree binfo;
-     void *data;
-{
-  binfo = get_shared_vbase_if_not_primary (binfo, data); 
-  return binfo ? unmarked_vtable_pathp (binfo, NULL): NULL_TREE;
-}
-
-/* Like dfs_unmarked_real_bases_queue_p but walks only into things
-   that are BINFO_VTABLE_PATH_MARKED.  */
-
-tree
-dfs_vtable_path_marked_real_bases_queue_p (binfo, data)
-     tree binfo;
-     void *data;
-{
-  binfo = get_shared_vbase_if_not_primary (binfo, data); 
-  return binfo ? marked_vtable_pathp (binfo, NULL): NULL_TREE;
-}
-
 /* A queue function that skips all virtual bases (and their 
    bases).  */
 
@@ -2400,9 +2374,7 @@ dfs_get_pure_virtuals (binfo, data)
     {
       tree virtuals;
       
-      for (virtuals = skip_rtti_stuff (binfo, 
-                                      BINFO_TYPE (binfo), 
-                                      NULL);
+      for (virtuals = BINFO_VIRTUALS (binfo);
           virtuals;
           virtuals = TREE_CHAIN (virtuals))
        if (DECL_PURE_VIRTUAL_P (TREE_VALUE (virtuals)))
@@ -2447,7 +2419,7 @@ get_pure_virtuals (type)
     {
       tree virtuals;
 
-      for (virtuals = skip_rtti_stuff (vbases, BINFO_TYPE (vbases), NULL);
+      for (virtuals = BINFO_VIRTUALS (vbases);
           virtuals;
           virtuals = TREE_CHAIN (virtuals))
        {
@@ -2527,7 +2499,7 @@ unmarkedp (binfo, data)
   return !BINFO_MARKED (binfo) ? binfo : NULL_TREE;
 }
 
-static tree
+tree
 marked_vtable_pathp (binfo, data) 
      tree binfo;
      void *data ATTRIBUTE_UNUSED;
@@ -2535,7 +2507,7 @@ marked_vtable_pathp (binfo, data)
   return BINFO_VTABLE_PATH_MARKED (binfo) ? binfo : NULL_TREE; 
 }
 
-static tree
+tree
 unmarked_vtable_pathp (binfo, data) 
      tree binfo;
      void *data ATTRIBUTE_UNUSED;
@@ -2863,9 +2835,10 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
       *vbase_offsets = delta;
     }
 
-  virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), &n);
-
-  while (virtuals)
+  for (virtuals = BINFO_VIRTUALS (binfo), 
+        n = first_vfun_index (BINFO_TYPE (binfo));
+       virtuals;
+       virtuals = TREE_CHAIN (virtuals), ++n)
     {
       tree current_fndecl = TREE_VALUE (virtuals);
 
@@ -2956,8 +2929,6 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
          finish_expr_stmt (build_modify_expr (new_delta, NOP_EXPR,
                                               old_delta));
        }
-      ++n;
-      virtuals = TREE_CHAIN (virtuals);
     }
 }
 
index 90c3058..3bf3c90 100644 (file)
@@ -1100,9 +1100,8 @@ __dynamic_cast (const void *src_ptr,    // object started from
 {
   const void *vtable = *static_cast <const void *const *> (src_ptr);
   const vtable_prefix *prefix =
-      adjust_pointer <vtable_prefix> (vtable, 0);
-  // FIXME: the above offset should be -offsetof (vtable_prefix, origin));
-  // but we don't currently layout vtables correctly.
+      adjust_pointer <vtable_prefix> (vtable, 
+                                     -offsetof (vtable_prefix, origin));
   const void *whole_ptr =
       adjust_pointer <void> (src_ptr, prefix->whole_object);
   const __class_type_info *whole_type = prefix->whole_type;
index d1c7d2d..e27ff7b 100644 (file)
@@ -925,7 +925,8 @@ debug_binfo (elem)
   else
     fprintf (stderr, "no vtable decl yet\n");
   fprintf (stderr, "virtuals:\n");
-  virtuals = skip_rtti_stuff (elem, BINFO_TYPE (elem), &n);
+  virtuals = BINFO_VIRTUALS (elem);
+  n = first_vfun_index (BINFO_TYPE (elem));
 
   while (virtuals)
     {