class.c (vcall_offset_data_s): Add last_init and fns.

* class.c (vcall_offset_data_s): Add last_init and fns.
	(overrides): Rename to same_signature_p.
	(dfs_find_final_overrider): Adjust accordingly.
	(mark_overriders): Likewise.
	(warn_hidden): Likewise.
	(build_vtbl_initializer): Reorganize machinery for building things
	at negative offsets.
	(build_vcall_and_vbase_vtbl_entries): Likewise.
	(build_vbase_offset_vtbl_entries): Likewise.
	(dfs_build_vcall_offset_vtbl_entries): Correct order of vcall
	offset entries.  Do not create two entries for functions with the
	same signature.
	(build_vcall_offset_vtbl_entries): Initialize vod->fns.
	(build_rtti_vtbl_entries): Reorganize machinery for building things
	at negative offsets.

From-SVN: r34503
This commit is contained in:
Mark Mitchell 2000-06-12 20:46:28 +00:00 committed by Mark Mitchell
parent f6bf7de2b9
commit 9bab6c9035
2 changed files with 106 additions and 86 deletions

View File

@ -1,5 +1,21 @@
2000-06-12 Mark Mitchell <mark@codesourcery.com>
* class.c (vcall_offset_data_s): Add last_init and fns.
(overrides): Rename to same_signature_p.
(dfs_find_final_overrider): Adjust accordingly.
(mark_overriders): Likewise.
(warn_hidden): Likewise.
(build_vtbl_initializer): Reorganize machinery for building things
at negative offsets.
(build_vcall_and_vbase_vtbl_entries): Likewise.
(build_vbase_offset_vtbl_entries): Likewise.
(dfs_build_vcall_offset_vtbl_entries): Correct order of vcall
offset entries. Do not create two entries for functions with the
same signature.
(build_vcall_offset_vtbl_entries): Initialize vod->fns.
(build_rtti_vtbl_entries): Reorganize machinery for building things
at negative offsets.
* optimize.c (expand_call_inline): Don't recurse into the code
used to initialize the parameters more than once.

View File

@ -66,11 +66,17 @@ typedef struct vcall_offset_data_s
{
/* The binfo for the most-derived type. */
tree derived;
/* The negative-index vtable initializers built up so far. These
are in order from least negative index to most negative index. */
tree inits;
/* The last (i.e., most negative entry in INITS. */
tree* last_init;
/* The binfo for the virtual base for which we're building
initializers. */
tree vbase;
/* The vcall offset initializers built up so far. */
tree inits;
/* The functions in vbase for which we have already provided vcall
offsets. */
varray_type fns;
/* The vtable index of the next vcall or vbase offset. */
tree index;
/* Nonzero if we are building the initializer for the primary
@ -107,7 +113,7 @@ static void delete_duplicate_fields PARAMS ((tree));
static void finish_struct_bits PARAMS ((tree));
static int alter_access PARAMS ((tree, tree, tree));
static void handle_using_decl PARAMS ((tree, tree));
static int overrides PARAMS ((tree, tree));
static int same_signature_p PARAMS ((tree, tree));
static int strictly_overrides PARAMS ((tree, tree));
static void mark_overriders PARAMS ((tree, tree));
static void check_for_override PARAMS ((tree, tree));
@ -174,7 +180,7 @@ 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, tree, tree, tree));
static void set_vindex PARAMS ((tree, tree, int *));
static tree build_rtti_vtbl_entries PARAMS ((tree, tree));
static void build_rtti_vtbl_entries PARAMS ((tree, tree, vcall_offset_data *));
static void build_vcall_and_vbase_vtbl_entries PARAMS ((tree,
vcall_offset_data *));
static tree dfs_mark_primary_bases PARAMS ((tree, void *));
@ -2383,11 +2389,11 @@ layout_vtable_decl (binfo, n)
}
}
/* True if we should override the given BASE_FNDECL with the given
FNDECL. */
/* True iff FNDECL and BASE_FNDECL (both non-static member functions)
have the same signature. */
static int
overrides (fndecl, base_fndecl)
same_signature_p (fndecl, base_fndecl)
tree fndecl, base_fndecl;
{
/* One destructor overrides another if they are the same kind of
@ -2455,7 +2461,8 @@ dfs_find_final_overrider (binfo, data)
for (method = TYPE_METHODS (BINFO_TYPE (TREE_VALUE (path)));
method;
method = TREE_CHAIN (method))
if (DECL_VIRTUAL_P (method) && overrides (method, ffod->fn))
if (DECL_VIRTUAL_P (method)
&& same_signature_p (method, ffod->fn))
break;
if (method)
@ -2826,10 +2833,8 @@ mark_overriders (fndecl, base_fndecls)
tree fndecl, base_fndecls;
{
for (; base_fndecls; base_fndecls = TREE_CHAIN (base_fndecls))
{
if (overrides (fndecl, TREE_VALUE (base_fndecls)))
TREE_PURPOSE (base_fndecls) = fndecl;
}
if (same_signature_p (fndecl, TREE_VALUE (base_fndecls)))
TREE_PURPOSE (base_fndecls) = fndecl;
}
/* If this declaration supersedes the declaration of
@ -2955,15 +2960,13 @@ warn_hidden (t)
/* Now give a warning for all base functions without overriders,
as they are hidden. */
for (; base_fndecls; base_fndecls = TREE_CHAIN (base_fndecls))
{
if (! overrides (TREE_PURPOSE (base_fndecls),
TREE_VALUE (base_fndecls)))
{
/* Here we know it is a hider, and no overrider exists. */
cp_warning_at ("`%D' was hidden", TREE_VALUE (base_fndecls));
cp_warning_at (" by `%D'", TREE_PURPOSE (base_fndecls));
}
}
if (!same_signature_p (TREE_PURPOSE (base_fndecls),
TREE_VALUE (base_fndecls)))
{
/* Here we know it is a hider, and no overrider exists. */
cp_warning_at ("`%D' was hidden", TREE_VALUE (base_fndecls));
cp_warning_at (" by `%D'", TREE_PURPOSE (base_fndecls));
}
}
}
@ -6938,33 +6941,32 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
int *non_fn_entries_p;
{
tree v;
tree inits;
tree vfun_inits;
tree vfun_inits;
tree vbase;
vcall_offset_data vod;
/* Initialize those parts of VOD that matter. */
vod.derived = t;
vod.inits = NULL_TREE;
vod.last_init = &vod.inits;
vod.primary_p = (binfo == TYPE_BINFO (t));
/* The first vbase or vcall offset is at index -3 in the vtable. */
vod.index = build_int_2 (-3, -1);
/* Add entries to the vtable for RTTI. */
build_rtti_vtbl_entries (binfo, rtti_binfo, &vod);
/* Add the vcall and vbase offset entries. */
build_vcall_and_vbase_vtbl_entries (binfo, &vod);
inits = vod.inits;
/* Clear BINFO_VTABLE_PAATH_MARKED; it's set by
/* Clear BINFO_VTABLE_PAATH_MARKED; it's set by
build_vbase_offset_vtbl_entries. */
for (vbase = CLASSTYPE_VBASECLASSES (t);
vbase;
vbase = TREE_CHAIN (vbase))
CLEAR_BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase));
/* Add entries to the vtable for RTTI. */
inits = chainon (inits, build_rtti_vtbl_entries (binfo, rtti_binfo));
if (non_fn_entries_p)
*non_fn_entries_p = list_length (inits);
*non_fn_entries_p = list_length (vod.inits);
/* Go through all the ordinary virtual functions, building up
initializers. */
@ -7005,9 +7007,11 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
order; straighten them out now. */
vfun_inits = nreverse (vfun_inits);
/* The complete initializer is the INITS, followed by the
VFUN_INITS. */
return chainon (inits, vfun_inits);
/* The negative offset initializers are also in reverse order. */
vod.inits = nreverse (vod.inits);
/* Chain the two together. */
return chainon (vod.inits, vfun_inits);
}
/* Sets vod->inits to be the initializers for the vbase and vcall
@ -7019,14 +7023,9 @@ build_vcall_and_vbase_vtbl_entries (binfo, vod)
vcall_offset_data *vod;
{
tree b;
tree inits;
/* If this is a derived class, we must first create entries
corresponding to the base class. These entries must go closer to
the vptr, so we save them up and add them to the end of the list
later. */
inits = vod->inits;
vod->inits = NULL_TREE;
corresponding to the primary base class. */
b = BINFO_PRIMARY_BINFO (binfo);
if (b)
build_vcall_and_vbase_vtbl_entries (b, vod);
@ -7035,8 +7034,6 @@ build_vcall_and_vbase_vtbl_entries (binfo, vod)
build_vbase_offset_vtbl_entries (binfo, vod);
/* Add the vcall entries for this base. */
build_vcall_offset_vtbl_entries (binfo, vod);
vod->inits = chainon (vod->inits, inits);
}
/* Returns the initializers for the vbase offset entries in the vtable
@ -7116,11 +7113,12 @@ build_vbase_offset_vtbl_entries (binfo, vod)
we are walking in inheritance graph order so these end up in
the right order. */
delta = size_diffop (BINFO_OFFSET (b), BINFO_OFFSET (binfo));
vod->inits = tree_cons (NULL_TREE,
fold (build1 (NOP_EXPR,
vtable_entry_type,
delta)),
vod->inits);
*vod->last_init
= build_tree_list (NULL_TREE,
fold (build1 (NOP_EXPR,
vtable_entry_type,
delta)));
vod->last_init = &TREE_CHAIN (*vod->last_init);
}
}
@ -7162,22 +7160,48 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data)
}
/* Make entries for the rest of the virtuals. */
while (base_virtuals)
for (; base_virtuals;
derived_virtuals = TREE_CHAIN (derived_virtuals),
base_virtuals = TREE_CHAIN (base_virtuals))
{
/* Figure out what function we're looking at. */
tree fn = TREE_VALUE (derived_virtuals);
tree base = DECL_CONTEXT (fn);
tree base;
tree base_binfo;
size_t i;
/* If there is already an entry for a function with the same
signature as FN, then we do not need a second vcall offset.
Check the list of functions already present in the derived
class vtable. */
for (i = 0; i < VARRAY_ACTIVE_SIZE (vod->fns); ++i)
{
tree derived_entry;
derived_entry = VARRAY_TREE (vod->fns, i);
if (same_signature_p (TREE_VALUE (derived_entry), fn))
{
BV_VCALL_INDEX (derived_virtuals)
= BV_VCALL_INDEX (derived_entry);
break;
}
}
if (i != VARRAY_ACTIVE_SIZE (vod->fns))
continue;
/* The FN comes from BASE. So, we must caculate the adjustment
from the virtual base that derived from BINFO to BASE. */
tree base_binfo = get_binfo (base, vod->derived, /*protect=*/0);
base = DECL_CONTEXT (fn);
base_binfo = get_binfo (base, vod->derived, /*protect=*/0);
/* Compute the vcall offset. */
binfo_inits
= tree_cons (NULL_TREE,
fold (build1 (NOP_EXPR, vtable_entry_type,
size_diffop (BINFO_OFFSET (base_binfo),
BINFO_OFFSET (vod->vbase)))),
binfo_inits);
*vod->last_init
= (build_tree_list
(NULL_TREE,
fold (build1 (NOP_EXPR, vtable_entry_type,
size_diffop (BINFO_OFFSET (base_binfo),
BINFO_OFFSET (vod->vbase))))));
vod->last_init = &TREE_CHAIN (*vod->last_init);
/* If there is already a vcall index, then we are processing a
construction vtable. The index should be the same as it was
@ -7197,24 +7221,8 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data)
vod->index = fold (build (MINUS_EXPR, integer_type_node,
vod->index, integer_one_node));
/* Go to the next entries in the list. */
derived_virtuals = TREE_CHAIN (derived_virtuals);
base_virtuals = TREE_CHAIN (base_virtuals);
}
/* The offests are built up in reverse order, so we straighten them
here. We simultaneously add them to VOD->INITS; we're walking
the bases in inheritance graph order, and the initializers are
supposed to appear in reverse inheritance order, so that's
correct. */
while (binfo_inits)
{
tree next;
next = TREE_CHAIN (binfo_inits);
TREE_CHAIN (binfo_inits) = vod->inits;
vod->inits = binfo_inits;
binfo_inits = next;
/* Keep track of this function. */
VARRAY_PUSH_TREE (vod->fns, derived_virtuals);
}
return NULL_TREE;
@ -7229,8 +7237,6 @@ build_vcall_offset_vtbl_entries (binfo, vod)
tree binfo;
vcall_offset_data *vod;
{
tree inits;
/* Under the old ABI, the adjustments to the `this' pointer were made
elsewhere. */
if (!vcall_offsets_in_vtable_p ())
@ -7263,24 +7269,24 @@ build_vcall_offset_vtbl_entries (binfo, vod)
appear in the same order as in the base; but the bases themselves
appear in reverse depth-first, left-to-right order. */
vod->vbase = binfo;
inits = vod->inits;
vod->inits = NULL_TREE;
VARRAY_TREE_INIT (vod->fns, 32, "fns");
dfs_walk_real (binfo,
dfs_build_vcall_offset_vtbl_entries,
NULL,
dfs_skip_vbases,
vod);
vod->inits = chainon (vod->inits, inits);
VARRAY_FREE (vod->fns);
}
/* Return vtbl initializers for the RTTI entries coresponding to the
BINFO's vtable. The RTTI entries should indicate the object given
by RTTI_BINFO. */
static tree
build_rtti_vtbl_entries (binfo, rtti_binfo)
static void
build_rtti_vtbl_entries (binfo, rtti_binfo, vod)
tree binfo;
tree rtti_binfo;
vcall_offset_data *vod;
{
tree b;
tree t;
@ -7288,15 +7294,13 @@ build_rtti_vtbl_entries (binfo, rtti_binfo)
tree offset;
tree decl;
tree init;
tree inits;
basetype = BINFO_TYPE (binfo);
inits = NULL_TREE;
t = BINFO_TYPE (rtti_binfo);
/* For a COM object there is no RTTI entry. */
if (CLASSTYPE_COM_INTERFACE (basetype))
return inits;
return;
/* 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. */
@ -7340,7 +7344,8 @@ build_rtti_vtbl_entries (binfo, rtti_binfo)
TREE_CONSTANT (init) = 1;
init = build_vtable_entry (offset, integer_zero_node, init);
}
inits = tree_cons (NULL_TREE, init, inits);
*vod->last_init = build_tree_list (NULL_TREE, init);
vod->last_init = &TREE_CHAIN (*vod->last_init);
/* Add the offset-to-top entry. It comes earlier in the vtable that
the the typeinfo entry. */
@ -7350,10 +7355,9 @@ build_rtti_vtbl_entries (binfo, rtti_binfo)
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);
*vod->last_init = build_tree_list (NULL_TREE, init);
vod->last_init = &TREE_CHAIN (*vod->last_init);
}
return inits;
}
/* Build an entry in the virtual function table. DELTA is the offset