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:
parent
f6bf7de2b9
commit
9bab6c9035
@ -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.
|
||||
|
||||
|
176
gcc/cp/class.c
176
gcc/cp/class.c
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user