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:
parent
e41e26be41
commit
a68ad5bdee
@ -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
|
||||
|
@ -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);
|
||||
|
132
gcc/cp/class.c
132
gcc/cp/class.c
@ -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. */
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user