Commit da3d4dfa by Mark Mitchell Committed by Mark Mitchell

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
parent 65a0aad5
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.
......
......@@ -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)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment