Commit 9bab6c90 by Mark Mitchell Committed by Mark Mitchell

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