cp-tree.h (build_shared_int_cst): New function.

* cp-tree.h (build_shared_int_cst): New function.
	* call.c (build_over_call): Use DECL_VIRTUAL_CONTEXT, for clarity.
	* class.c (modify_vtable_entry): Likewise.
	(add_virtual_function): Split out code to generated shared
	INTEGER_CSTs to build_share_int_cst.
	(modify_all_vtables): Handle all the overridden functions here.
	Add overridden functions from non-primary virtual bases to the
	primary vtable.
	(finish_struct_1): Adjust call to modify_all_vtables.  Add
	overridden functions from non-primary bases to the vtable.
	* tree.c (build_shared_int_cst): New function.

From-SVN: r31476
This commit is contained in:
Mark Mitchell 2000-01-17 22:54:23 +00:00 committed by Mark Mitchell
parent e41e26be41
commit a68ad5bdee
5 changed files with 124 additions and 45 deletions

View File

@ -1,5 +1,17 @@
2000-01-17 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (build_shared_int_cst): New function.
* call.c (build_over_call): Use DECL_VIRTUAL_CONTEXT, for clarity.
* class.c (modify_vtable_entry): Likewise.
(add_virtual_function): Split out code to generated shared
INTEGER_CSTs to build_share_int_cst.
(modify_all_vtables): Handle all the overridden functions here.
Add overridden functions from non-primary virtual bases to the
primary vtable.
(finish_struct_1): Adjust call to modify_all_vtables. Add
overridden functions from non-primary bases to the vtable.
* tree.c (build_shared_int_cst): New function.
* cp-tree.h (scratchalloc): Remove.
(build_scratch_list): Likewise.
* call.c (convert_class_to_reference): Replace build_scratch_list

View File

@ -4126,7 +4126,7 @@ build_over_call (cand, args, flags)
{
tree t, *p = &TREE_VALUE (converted_args);
tree binfo = get_binfo
(DECL_CONTEXT (fn), TREE_TYPE (TREE_TYPE (*p)), 0);
(DECL_VIRTUAL_CONTEXT (fn), TREE_TYPE (TREE_TYPE (*p)), 0);
*p = convert_pointer_to_real (binfo, *p);
if (TREE_SIDE_EFFECTS (*p))
*p = save_expr (*p);

View File

@ -103,7 +103,7 @@ static tree dfs_get_class_offset PROTO((tree, void *));
static tree get_class_offset PROTO((tree, tree, tree, tree));
static void modify_one_vtable PROTO((tree, tree, tree));
static tree dfs_modify_vtables PROTO((tree, void *));
static void modify_all_vtables PROTO((tree, tree));
static tree modify_all_vtables PROTO((tree, int *, tree));
static void determine_primary_base PROTO((tree, int *));
static void finish_struct_methods PROTO((tree));
static void maybe_warn_about_overly_private_class PROTO ((tree));
@ -1107,7 +1107,7 @@ modify_vtable_entry (old_entry_in_list, new_offset, fndecl)
if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST)
{
DECL_VINDEX (fndecl) = DECL_VINDEX (base_fndecl);
DECL_CONTEXT (fndecl) = DECL_CONTEXT (base_fndecl);
DECL_VIRTUAL_CONTEXT (fndecl) = DECL_VIRTUAL_CONTEXT (base_fndecl);
}
}
@ -1166,8 +1166,6 @@ add_virtual_function (new_virtuals_p, overridden_virtuals_p,
tree fndecl;
tree t; /* Structure type. */
{
my_friendly_assert (DECL_CONTEXT (fndecl) == t, 20000116);
/* If this function doesn't override anything from a base class, we
can just assign it a new DECL_VINDEX now. Otherwise, if it does
override something, we keep it around and assign its DECL_VINDEX
@ -1185,25 +1183,10 @@ add_virtual_function (new_virtuals_p, overridden_virtuals_p,
start_vtable (t, has_virtual);
/* Build a new INT_CST for this DECL_VINDEX. */
{
static tree index_table[256];
tree idx;
/* We skip a slot for the offset/tdesc entry. */
int i = (*has_virtual)++;
/* Now assign virtual dispatch information. */
DECL_VINDEX (fndecl) = build_shared_int_cst ((*has_virtual)++);
DECL_VIRTUAL_CONTEXT (fndecl) = t;
if (i >= 256 || index_table[i] == 0)
{
idx = build_int_2 (i, 0);
if (i < 256)
index_table[i] = idx;
}
else
idx = index_table[i];
/* Now assign virtual dispatch information. */
DECL_VINDEX (fndecl) = idx;
}
/* Save the state we've computed on the NEW_VIRTUALS list. */
*new_virtuals_p = tree_cons (integer_zero_node,
fndecl,
@ -2752,17 +2735,81 @@ dfs_modify_vtables (binfo, data)
return NULL_TREE;
}
static void
modify_all_vtables (t, fndecl)
tree t;
tree fndecl;
{
tree list;
/* Update all of the primary and secondary vtables for T. Create new
vtables as required, and initialize their RTTI information. Each
of the functions in OVERRIDDEN_VIRTUALS overrides a virtual
function from a base class; find and modify the appropriate entries
to point to the overriding functions. Returns a list, in
declaration order, of the functions that are overridden in this
class, but do not appear in the primary base class vtable, and
which should therefore be appended to the end of the vtable for T. */
list = build_tree_list (t, fndecl);
dfs_walk (TYPE_BINFO (t), dfs_modify_vtables,
dfs_unmarked_real_bases_queue_p, list);
dfs_walk (TYPE_BINFO (t), dfs_unmark, dfs_marked_real_bases_queue_p, t);
static tree
modify_all_vtables (t, has_virtual_p, overridden_virtuals)
tree t;
int *has_virtual_p;
tree overridden_virtuals;
{
tree fns;
tree binfo;
binfo = TYPE_BINFO (t);
/* Even if there are no overridden virtuals, we want to go through
the hierarchy updating RTTI information. */
if (!overridden_virtuals && TYPE_CONTAINS_VPTR_P (t) && flag_rtti)
overridden_virtuals = build_tree_list (NULL_TREE, NULL_TREE);
/* Iterate through each of the overriding functions, updating the
base vtables. */
for (fns = overridden_virtuals; fns; fns = TREE_CHAIN (fns))
{
tree list;
list = build_tree_list (t, TREE_VALUE (fns));
dfs_walk (binfo, dfs_modify_vtables,
dfs_unmarked_real_bases_queue_p, list);
dfs_walk (binfo, dfs_unmark, dfs_marked_real_bases_queue_p, t);
}
/* If we should include overriding functions for secondary vtables
in our primary vtable, add them now. */
if (all_overridden_vfuns_in_vtables_p ())
{
tree *fnsp = &overridden_virtuals;
while (*fnsp)
{
tree fn = TREE_VALUE (*fnsp);
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)++);
/* We don't need to convert to a base class when calling
this function. */
DECL_VIRTUAL_CONTEXT (fn) = t;
/* We don't need to adjust the `this' pointer when
calling this function. */
TREE_PURPOSE (*fnsp) = integer_zero_node;
/* This is an overridden function not already in our
vtable. Keep it. */
fnsp = &TREE_CHAIN (*fnsp);
}
else
/* We've already got an entry for this function. Skip
it. */
*fnsp = TREE_CHAIN (*fnsp);
}
}
else
overridden_virtuals = NULL_TREE;
return overridden_virtuals;
}
/* Fixup all the delta entries in this one vtable that need updating. */
@ -4818,22 +4865,15 @@ finish_struct_1 (t)
TYPE_VFIELD (t) = vfield;
}
if (flag_rtti && TYPE_CONTAINS_VPTR_P (t) && !overridden_virtuals)
modify_all_vtables (t, NULL_TREE);
overridden_virtuals
= modify_all_vtables (t, &has_virtual, nreverse (overridden_virtuals));
for (overridden_virtuals = nreverse (overridden_virtuals);
overridden_virtuals;
overridden_virtuals = TREE_CHAIN (overridden_virtuals))
modify_all_vtables (t, TREE_VALUE (overridden_virtuals));
if (TYPE_USES_VIRTUAL_BASECLASSES (t))
{
tree vbases;
/* Now fixup any virtual function entries from virtual bases
that have different deltas. This has to come after we do the
pending hard virtuals, as we might have a function that comes
from multiple virtual base instances that is only overridden
by a hard virtual above. */
overridden virtuals. */
vbases = CLASSTYPE_VBASECLASSES (t);
while (vbases)
{
@ -4851,6 +4891,7 @@ finish_struct_1 (t)
/* If necessary, create the vtable for this class. */
if (new_virtuals
|| overridden_virtuals
|| (TYPE_CONTAINS_VPTR_P (t) && vptrs_present_everywhere_p ()))
{
new_virtuals = nreverse (new_virtuals);
@ -4859,7 +4900,8 @@ finish_struct_1 (t)
{
if (! CLASSTYPE_COM_INTERFACE (t))
{
/* The second slot is for the tdesc pointer when thunks are used. */
/* 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);
@ -4918,6 +4960,10 @@ finish_struct_1 (t)
followed by entries for new functions unique to this class. */
TYPE_BINFO_VIRTUALS (t)
= chainon (TYPE_BINFO_VIRTUALS (t), new_virtuals);
/* Finally, add entries for functions that override virtuals
from non-primary bases. */
TYPE_BINFO_VIRTUALS (t)
= chainon (TYPE_BINFO_VIRTUALS (t), overridden_virtuals);
}
/* Now lay out the virtual function table. */

View File

@ -4199,6 +4199,7 @@ extern tree cp_build_qualified_type_real PROTO((tree, int, int));
extern void remap_save_expr PROTO((tree *, splay_tree, tree, int *));
#define cp_build_qualified_type(TYPE, QUALS) \
cp_build_qualified_type_real ((TYPE), (QUALS), /*complain=*/1)
extern tree build_shared_int_cst PROTO((int));
/* in typeck.c */
extern int string_conv_p PROTO((tree, tree, int));

View File

@ -1,5 +1,5 @@
/* Language-dependent node constructors for parse phase of GNU compiler.
Copyright (C) 1987, 88, 92-98, 1999 Free Software Foundation, Inc.
Copyright (C) 1987, 88, 92-98, 1999, 2000 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
@ -1710,6 +1710,26 @@ build_min VPROTO((enum tree_code code, tree tt, ...))
return t;
}
/* Returns an INTEGER_CST (of type `int') corresponding to I.
Multiple calls with the same value of I may or may not yield the
same node; therefore, callers should never modify the node
returned. */
tree
build_shared_int_cst (i)
int i;
{
static tree cache[256];
if (i >= 256)
return build_int_2 (i, 0);
if (!cache[i])
cache[i] = build_int_2 (i, 0);
return cache[i];
}
tree
get_type_decl (t)
tree t;