Commit cf2e003b by Mark Mitchell Committed by Mark Mitchell

cp-tree.h (struct lang_type): Remove search_slot.

	* cp-tree.h (struct lang_type): Remove search_slot.
	(CLASSTYPE_SEARCH_SLOT): Remove.
	(emit_base_init): Change prototype.
	(initialize_vtbl_ptrs): Likewise.
	(expand_indirect_vtbls_init): Likewise.
	(clear_search_slots): Remove.
	* decl.c (lang_mark_tree): Don't mark search_slot.
	* init.c (initialize_vtbl_ptrs): Simplify.
	(emit_base_init): Likewise.
	* search.c (struct vbase_info): Document decl_ptr.
	(convert_pointer_to_single_level): Remove.
	(dfs_find_vbases): Remove.
	(dfs_init_base_pointers): Simplify.
	(dfs_clear_vbase_slots): Remove.
	(dfs_vtable_path_unmark): New function.
	(init_vbase_pointers): Simplify.
	(expand_upcast_fixups): Don't rely on CLASSTYPE_SEARCH_SLOT.
	(expand_indirect_vtbls_init): Simplify.  Don't call
	mark_all_temps_used.
	* semantics.c (setup_vtbl_ptr): Adjust calls to emit_base_init and
	initialize_vtbl_ptrs.

From-SVN: r34067
parent bf5df909
2000-05-21 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (struct lang_type): Remove search_slot.
(CLASSTYPE_SEARCH_SLOT): Remove.
(emit_base_init): Change prototype.
(initialize_vtbl_ptrs): Likewise.
(expand_indirect_vtbls_init): Likewise.
(clear_search_slots): Remove.
* decl.c (lang_mark_tree): Don't mark search_slot.
* init.c (initialize_vtbl_ptrs): Simplify.
(emit_base_init): Likewise.
* search.c (struct vbase_info): Document decl_ptr.
(convert_pointer_to_single_level): Remove.
(dfs_find_vbases): Remove.
(dfs_init_base_pointers): Simplify.
(dfs_clear_vbase_slots): Remove.
(dfs_vtable_path_unmark): New function.
(init_vbase_pointers): Simplify.
(expand_upcast_fixups): Don't rely on CLASSTYPE_SEARCH_SLOT.
(expand_indirect_vtbls_init): Simplify. Don't call
mark_all_temps_used.
* semantics.c (setup_vtbl_ptr): Adjust calls to emit_base_init and
initialize_vtbl_ptrs.
2000-05-20 Zack Weinberg <zack@wolery.cumb.org>
* except.c: Add static prototypes.
......
......@@ -1395,7 +1395,6 @@ struct lang_type
tree vfields;
tree vbases;
tree tags;
tree search_slot;
tree size;
tree size_unit;
tree pure_virtuals;
......@@ -1613,10 +1612,6 @@ struct lang_type
#define CLASSTYPE_N_BASECLASSES(NODE) \
(BINFO_N_BASETYPES (TYPE_BINFO (NODE)))
/* Used for keeping search-specific information. Any search routine
which uses this must define what exactly this slot is used for. */
#define CLASSTYPE_SEARCH_SLOT(NODE) (TYPE_LANG_SPECIFIC(NODE)->search_slot)
/* These are the size and alignment of the type without its virtual
base classes, for when we use this type as a base itself. */
#define CLASSTYPE_SIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->size)
......@@ -4098,7 +4093,7 @@ extern tree do_friend PARAMS ((tree, tree, tree, tree, tree, enum overload_fl
/* in init.c */
extern void init_init_processing PARAMS ((void));
extern void emit_base_init PARAMS ((tree));
extern void emit_base_init PARAMS ((void));
extern void expand_member_init PARAMS ((tree, tree, tree));
extern tree build_aggr_init PARAMS ((tree, tree, int));
extern int is_aggr_type PARAMS ((tree, int));
......@@ -4117,7 +4112,7 @@ extern tree build_vec_delete PARAMS ((tree, tree, tree, int));
extern tree create_temporary_var PARAMS ((tree));
extern void begin_init_stmts PARAMS ((tree *, tree *));
extern tree finish_init_stmts PARAMS ((tree, tree));
extern void initialize_vtbl_ptrs PARAMS ((tree, tree));
extern void initialize_vtbl_ptrs PARAMS ((tree));
extern tree build_java_class_ref PARAMS ((tree));
/* in input.c */
......@@ -4291,8 +4286,7 @@ extern tree lookup_nested_tag PARAMS ((tree, tree));
extern tree get_matching_virtual PARAMS ((tree, tree, int));
extern void get_pure_virtuals PARAMS ((tree));
extern tree init_vbase_pointers PARAMS ((tree, tree));
extern void expand_indirect_vtbls_init PARAMS ((tree, tree));
extern void clear_search_slots PARAMS ((tree));
extern void expand_indirect_vtbls_init PARAMS ((tree));
extern void get_vbase_types PARAMS ((tree));
extern void maybe_suppress_debug_info PARAMS ((tree));
extern void note_debug_info_needed PARAMS ((tree));
......
......@@ -14773,7 +14773,6 @@ lang_mark_tree (t)
ggc_mark_tree (lt->vfields);
ggc_mark_tree (lt->vbases);
ggc_mark_tree (lt->tags);
ggc_mark_tree (lt->search_slot);
ggc_mark_tree (lt->size);
ggc_mark_tree (lt->pure_virtuals);
ggc_mark_tree (lt->friend_classes);
......
......@@ -151,15 +151,18 @@ dfs_initialize_vtbl_ptrs (binfo, data)
return NULL_TREE;
}
/* Initialize all the vtable pointers for the hierarchy dominated by
TYPE. */
/* Initialize all the vtable pointers in the object pointed to by
ADDR. */
void
initialize_vtbl_ptrs (type, addr)
tree type;
initialize_vtbl_ptrs (addr)
tree addr;
{
tree list = build_tree_list (type, addr);
tree list;
tree type;
type = TREE_TYPE (TREE_TYPE (addr));
list = build_tree_list (type, addr);
/* Walk through the hierarchy, initializing the vptr in each base
class. We do these in pre-order because under the new ABI we
......@@ -169,8 +172,7 @@ initialize_vtbl_ptrs (type, addr)
NULL, dfs_unmarked_real_bases_queue_p, list);
dfs_walk (TYPE_BINFO (type), dfs_unmark,
dfs_marked_real_bases_queue_p, type);
if (TYPE_USES_VIRTUAL_BASECLASSES (type))
expand_indirect_vtbls_init (TYPE_BINFO (type), addr);
expand_indirect_vtbls_init (addr);
}
/* Subroutine of emit_base_init. */
......@@ -624,21 +626,16 @@ sort_base_init (t, rbase_ptr, vbase_ptr)
that call with a pushlevel/poplevel pair, since we are technically
at the PARM level of scope.
Argument IMMEDIATELY, if zero, forces a new sequence to be
generated to contain these new insns, so it can be emitted later.
This sequence is saved in the global variable BASE_INIT_EXPR.
Otherwise, the insns are emitted into the current sequence.
Note that emit_base_init does *not* initialize virtual base
classes. That is done specially, elsewhere. */
void
emit_base_init (t)
tree t;
emit_base_init ()
{
tree member;
tree mem_init_list;
tree rbase_init_list, vbase_init_list;
tree t = current_class_type;
tree t_binfo = TYPE_BINFO (t);
tree binfos = BINFO_BASETYPES (t_binfo);
int i;
......@@ -695,7 +692,7 @@ emit_base_init (t)
}
/* Initialize the vtable pointers for the class. */
initialize_vtbl_ptrs (t, current_class_ptr);
initialize_vtbl_ptrs (current_class_ptr);
while (mem_init_list)
{
......
......@@ -80,6 +80,7 @@ struct vbase_info
{
/* The class dominating the hierarchy. */
tree type;
/* A pointer to a complete object of the indicated TYPE. */
tree decl_ptr;
tree inits;
};
......@@ -87,7 +88,6 @@ struct vbase_info
static tree next_baselink PARAMS ((tree));
static tree get_vbase_1 PARAMS ((tree, tree, unsigned int *));
static tree lookup_field_1 PARAMS ((tree, tree));
static tree convert_pointer_to_single_level PARAMS ((tree, tree));
static int lookup_fnfields_here PARAMS ((tree, tree));
static int is_subobject_of_p PARAMS ((tree, tree));
static int hides PARAMS ((tree, tree));
......@@ -107,8 +107,6 @@ static tree marked_pushdecls_p PARAMS ((tree, void *));
static tree unmarked_pushdecls_p PARAMS ((tree, void *));
static tree dfs_debug_unmarkedp PARAMS ((tree, void *));
static tree dfs_debug_mark PARAMS ((tree, void *));
static tree dfs_find_vbases PARAMS ((tree, void *));
static tree dfs_clear_vbase_slots PARAMS ((tree, void *));
static tree dfs_init_vbase_pointers PARAMS ((tree, void *));
static tree dfs_get_vbase_types PARAMS ((tree, void *));
static tree dfs_push_type_decls PARAMS ((tree, void *));
......@@ -151,6 +149,7 @@ static tree get_shared_vbase_if_not_primary PARAMS ((tree, void *));
static tree dfs_find_vbase_instance PARAMS ((tree, void *));
static tree dfs_get_pure_virtuals PARAMS ((tree, void *));
static tree dfs_build_inheritance_graph_order PARAMS ((tree, void *));
static tree dfs_vtable_path_unmark PARAMS ((tree, void *));
/* Allocate a level of searching. */
......@@ -2369,40 +2368,6 @@ next_baselink (baselink)
/* DEPTH-FIRST SEARCH ROUTINES. */
/* This routine converts a pointer to be a pointer of an immediate
base class. The normal convert_pointer_to routine would diagnose
the conversion as ambiguous, under MI code that has the base class
as an ambiguous base class. */
static tree
convert_pointer_to_single_level (to_type, expr)
tree to_type, expr;
{
tree derived;
tree binfo_of_derived;
int i;
derived = TREE_TYPE (TREE_TYPE (expr));
binfo_of_derived = TYPE_BINFO (derived);
my_friendly_assert (BINFO_INHERITANCE_CHAIN (binfo_of_derived) == NULL_TREE,
980827);
for (i = CLASSTYPE_N_BASECLASSES (derived) - 1; i >= 0; --i)
{
tree binfo = BINFO_BASETYPE (binfo_of_derived, i);
my_friendly_assert (BINFO_INHERITANCE_CHAIN (binfo) == binfo_of_derived,
980827);
if (same_type_p (BINFO_TYPE (binfo), to_type))
return build_vbase_path (PLUS_EXPR,
build_pointer_type (to_type),
expr, binfo, 1);
}
my_friendly_abort (19990607);
/* NOTREACHED */
return NULL_TREE;
}
tree
markedp (binfo, data)
tree binfo;
......@@ -2467,39 +2432,6 @@ dfs_unmark (binfo, data)
}
/* Attach to the type of the virtual base class, the pointer to the
virtual base class. */
static tree
dfs_find_vbases (binfo, data)
tree binfo;
void *data;
{
struct vbase_info *vi = (struct vbase_info *) data;
tree binfos = BINFO_BASETYPES (binfo);
int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
for (i = n_baselinks-1; i >= 0; i--)
{
tree base_binfo = TREE_VEC_ELT (binfos, i);
if (TREE_VIA_VIRTUAL (base_binfo)
&& CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (base_binfo)) == 0)
{
tree vbase = BINFO_TYPE (base_binfo);
tree binfo = binfo_for_vbase (vbase, vi->type);
tree ptr_type = build_pointer_type (vbase);
CLASSTYPE_SEARCH_SLOT (vbase)
= build (PLUS_EXPR, ptr_type, vi->decl_ptr,
convert (ptr_type, BINFO_OFFSET (binfo)));
}
}
SET_BINFO_VTABLE_PATH_MARKED (binfo);
return NULL_TREE;
}
static tree
dfs_init_vbase_pointers (binfo, data)
tree binfo;
......@@ -2510,18 +2442,15 @@ dfs_init_vbase_pointers (binfo, data)
tree fields;
tree this_vbase_ptr;
if (BINFO_INHERITANCE_CHAIN (binfo))
{
this_vbase_ptr = TREE_CHAIN (BINFO_INHERITANCE_CHAIN (binfo));
if (TREE_VIA_VIRTUAL (binfo))
this_vbase_ptr = CLASSTYPE_SEARCH_SLOT (type);
else
this_vbase_ptr = convert_pointer_to_single_level (type,
this_vbase_ptr);
TREE_CHAIN (binfo) = this_vbase_ptr;
}
else
this_vbase_ptr = TREE_CHAIN (binfo);
/* Don't initialize the same base more than once. */
SET_BINFO_VTABLE_PATH_MARKED (binfo);
/* We know that VI->DECL_PTR points to the complete object. So,
finding a pointer to this subobject is easy. */
this_vbase_ptr = build (PLUS_EXPR,
build_pointer_type (type),
vi->decl_ptr,
BINFO_OFFSET (binfo));
/* We're going to iterate through all the pointers to virtual
base-classes. They come at the beginning of the class. */
......@@ -2540,10 +2469,18 @@ dfs_init_vbase_pointers (binfo, data)
{
tree ref = build (COMPONENT_REF, TREE_TYPE (fields),
build_indirect_ref (this_vbase_ptr, NULL_PTR), fields);
tree init = CLASSTYPE_SEARCH_SLOT (TREE_TYPE (TREE_TYPE (fields)));
tree init;
tree vbase_type;
tree vbase_binfo;
vbase_type = TREE_TYPE (TREE_TYPE (fields));
vbase_binfo = binfo_for_vbase (vbase_type, vi->type);
init = build (PLUS_EXPR,
build_pointer_type (vbase_type),
vi->decl_ptr,
BINFO_OFFSET (vbase_binfo));
vi->inits
= tree_cons (binfo_for_vbase (TREE_TYPE (TREE_TYPE (fields)),
vi->type),
= tree_cons (vbase_binfo,
build_modify_expr (ref, NOP_EXPR, init),
vi->inits);
fields = TREE_CHAIN (fields);
......@@ -2552,18 +2489,13 @@ dfs_init_vbase_pointers (binfo, data)
return NULL_TREE;
}
/* Sometimes this needs to clear both VTABLE_PATH and NEW_VTABLE. Other
times, just NEW_VTABLE, but optimizer should make both with equal
efficiency (though it does not currently). */
/* Call CLEAR_BINFO_VTABLE_PATH_MARKED for BINFO. */
static tree
dfs_clear_vbase_slots (binfo, data)
dfs_vtable_path_unmark (binfo, data)
tree binfo;
void *data ATTRIBUTE_UNUSED;
{
tree type = BINFO_TYPE (binfo);
CLASSTYPE_SEARCH_SLOT (type) = 0;
CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
return NULL_TREE;
}
......@@ -2588,19 +2520,21 @@ init_vbase_pointers (type, decl_ptr)
vi.decl_ptr = decl_ptr;
vi.inits = NULL_TREE;
dfs_walk (binfo, dfs_find_vbases, unmarked_vtable_pathp, &vi);
/* Build up a list of the initializers. */
TREE_CHAIN (binfo) = decl_ptr;
dfs_walk_real (binfo,
dfs_init_vbase_pointers, 0,
marked_vtable_pathp,
unmarked_vtable_pathp,
&vi);
dfs_walk (binfo,
dfs_vtable_path_unmark,
marked_vtable_pathp,
NULL);
dfs_walk (binfo, dfs_clear_vbase_slots, marked_vtable_pathp, NULL);
flag_this_is_variable = old_flag;
return vi.inits;
}
return 0;
}
......@@ -2664,9 +2598,7 @@ virtual_context (fndecl, t, vbase)
VBASE_OFFSETS is an association list of virtual bases that contains
offset information for the virtual bases, so the offsets are only
calculated once. The offsets are computed by where we think the
vbase should be (as noted by the CLASSTYPE_SEARCH_SLOT) minus where
the vbase really is. */
calculated once. */
static void
expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
......@@ -2688,7 +2620,10 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
delta = purpose_member (vbase, *vbase_offsets);
if (! delta)
{
delta = CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vbase));
delta = build (PLUS_EXPR,
build_pointer_type (BINFO_TYPE (vbase)),
orig_addr,
BINFO_OFFSET (vbase));
delta = build (MINUS_EXPR, ptrdiff_type_node, delta, vbase_addr);
delta = save_expr (delta);
delta = tree_cons (vbase, delta, *vbase_offsets);
......@@ -2767,7 +2702,10 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
if (! vc_delta)
{
tree vc_addr = convert_pointer_to_real (vc, orig_addr);
vc_delta = CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vc));
vc_delta = build (PLUS_EXPR,
build_pointer_type (BINFO_TYPE (vc)),
orig_addr,
BINFO_OFFSET (vc));
vc_delta = build (MINUS_EXPR, ptrdiff_type_node,
vc_delta, vc_addr);
vc_delta = save_expr (vc_delta);
......@@ -2884,41 +2822,19 @@ fixup_all_virtual_upcast_offsets (type, decl_ptr)
}
/* Generate the code needed to initialize all the virtual function
table slots of all the virtual baseclasses. BINFO is the binfo
which determines the virtual baseclasses to use. TRUE_EXP is the
true object we are initializing, and DECL_PTR is the pointer to the
sub-object we are initializing. */
table slots of all the virtual baseclasses. ADDR points to the
address of the complete object we are initializing. */
void
expand_indirect_vtbls_init (binfo, decl_ptr)
tree binfo;
tree decl_ptr;
expand_indirect_vtbls_init (addr)
tree addr;
{
tree type;
type = BINFO_TYPE (binfo);
/* This function executes during the finish_function() segment,
AFTER the auto variables and temporary stack space has been marked
unused...If space is needed for the virtual function tables,
some of them might fit within what the compiler now thinks
are available stack slots... These values are actually initialized at
the beginnning of the function, so when the automatics use their space,
they will overwrite the values that are placed here. Marking all
temporary space as unavailable prevents this from happening. */
mark_all_temps_used();
type = TREE_TYPE (TREE_TYPE (addr));
if (TYPE_USES_VIRTUAL_BASECLASSES (type))
{
struct vbase_info vi;
vi.type = type;
vi.decl_ptr = decl_ptr;
dfs_walk (binfo, dfs_find_vbases, NULL, &vi);
fixup_all_virtual_upcast_offsets (type, vi.decl_ptr);
dfs_walk (binfo, dfs_clear_vbase_slots, marked_vtable_pathp, &vi);
}
fixup_all_virtual_upcast_offsets (type, addr);
}
/* get virtual base class types.
......
......@@ -1247,7 +1247,7 @@ setup_vtbl_ptr ()
add_tree (ctor_stmt);
/* And actually initialize the base-classes and members. */
emit_base_init (current_class_type);
emit_base_init ();
}
}
else if (DECL_DESTRUCTOR_P (current_function_decl)
......@@ -1286,8 +1286,7 @@ setup_vtbl_ptr ()
/* Make all virtual function table pointers in non-virtual base
classes point to CURRENT_CLASS_TYPE's virtual function
tables. */
initialize_vtbl_ptrs (current_class_type,
current_class_ptr);
initialize_vtbl_ptrs (current_class_ptr);
finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
finish_then_clause (if_stmt);
......
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