aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2000-06-12 20:46:28 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2000-06-12 20:46:28 +0000
commit9bab6c90356bd4ffe3db5d851fc7dbb64a1747f5 (patch)
tree36f07f4544366a1f7930292cebeee4893b84379f
parentf6bf7de2b9e0bd59913451e1fb33acf1ddaead19 (diff)
downloadgcc-9bab6c90356bd4ffe3db5d851fc7dbb64a1747f5.zip
gcc-9bab6c90356bd4ffe3db5d851fc7dbb64a1747f5.tar.gz
gcc-9bab6c90356bd4ffe3db5d851fc7dbb64a1747f5.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog16
-rw-r--r--gcc/cp/class.c176
2 files changed, 106 insertions, 86 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 17000bd..5920a04 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index c34deb0..4d9d399 100644
--- a/gcc/cp/class.c
+++ b/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