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. From-SVN: r32787
This commit is contained in:
parent
65a0aad55d
commit
da3d4dfa91
|
@ -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.
|
||||
|
|
400
gcc/cp/class.c
400
gcc/cp/class.c
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue