/* in init.c */
extern void init_init_processing PROTO((void));
-extern void expand_direct_vtbls_init PROTO((tree, tree, int, int, tree));
extern tree emit_base_init PROTO((tree));
extern void check_base_init PROTO((tree));
extern void expand_member_init PROTO((tree, tree, tree));
extern tree create_temporary_var PROTO((tree));
extern void begin_init_stmts PROTO((tree *, tree *));
extern tree finish_init_stmts PROTO((tree, tree));
+extern void initialize_vtbl_ptrs PROTO((tree, tree));
/* in input.c */
extern tree get_matching_virtual PROTO((tree, tree, int));
extern void get_pure_virtuals PROTO((tree));
extern tree init_vbase_pointers PROTO((tree, tree));
-extern void expand_indirect_vtbls_init PROTO((tree, tree, tree));
+extern void expand_indirect_vtbls_init PROTO((tree, tree));
extern void clear_search_slots PROTO((tree));
extern void get_vbase_types PROTO((tree));
extern void maybe_suppress_debug_info PROTO((tree));
extern tree dfs_unmarked_real_bases_queue_p PROTO((tree, void *));
extern tree dfs_marked_real_bases_queue_p PROTO((tree, void *));
extern void mark_primary_bases PROTO((tree));
+extern tree convert_pointer_to_vbase PROTO((tree, tree));
/* in semantics.c */
extern void finish_expr_stmt PROTO((tree));
/* Handle initialization things in C++.
- Copyright (C) 1987, 89, 92-98, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1987, 89, 92-98, 1999, 2000 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
static tree build_java_class_ref PROTO((tree));
static void expand_cleanup_for_base PROTO((tree, tree));
static tree get_temp_regvar PROTO((tree, tree));
+static tree dfs_initialize_vtbl_ptrs PROTO((tree, void *));
/* Set up local variable for this file. MUST BE CALLED AFTER
INIT_DECL_PROCESSING. */
ggc_add_tree_root (&BI_header_size, 1);
}
-/* Subroutine of emit_base_init. For BINFO, initialize all the
- virtual function table pointers, except those that come from
- virtual base classes. Initialize binfo's vtable pointer, if
- INIT_SELF is true. CAN_ELIDE is true when we know that all virtual
- function table pointers in all bases have been initialized already,
- probably because their constructors have just be run. ADDR is the
- pointer to the object whos vtables we are going to initialize.
+/* Called from initialize_vtbl_ptrs via dfs_walk. */
- REAL_BINFO is usually the same as BINFO, except when addr is not of
- pointer to the type of the real derived type that we want to
- initialize for. This is the case when addr is a pointer to a sub
- object of a complete object, and we only want to do part of the
- complete object's initialization of vtable pointers. This is done
- for all virtual table pointers in virtual base classes. REAL_BINFO
- is used to find the BINFO_VTABLE that we initialize with. BINFO is
- used for conversions of addr to subobjects.
+static tree
+dfs_initialize_vtbl_ptrs (binfo, data)
+ tree binfo;
+ void *data;
+{
+ if (!BINFO_PRIMARY_MARKED_P (binfo)
+ && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
+ {
+ tree base_ptr = TREE_VALUE ((tree) data);
- BINFO_TYPE (real_binfo) must be BINFO_TYPE (binfo).
+ if (TREE_VIA_VIRTUAL (binfo))
+ base_ptr = convert_pointer_to_vbase (BINFO_TYPE (binfo),
+ base_ptr);
+ else
+ base_ptr
+ = build_vbase_path (PLUS_EXPR,
+ build_pointer_type (BINFO_TYPE (binfo)),
+ base_ptr,
+ binfo,
+ /*nonnull=*/1);
+
+ expand_virtual_init (binfo, base_ptr);
+ }
- Relies upon binfo being inside TYPE_BINFO (TREE_TYPE (TREE_TYPE
- (addr))). */
+ SET_BINFO_MARKED (binfo);
+
+ return NULL_TREE;
+}
+
+/* Initialize all the vtable pointers for the hierarchy dominated by
+ TYPE. */
void
-expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr)
- tree real_binfo, binfo, addr;
- int init_self, can_elide;
+initialize_vtbl_ptrs (type, addr)
+ tree type;
+ tree addr;
{
- tree real_binfos = BINFO_BASETYPES (real_binfo);
- tree binfos = BINFO_BASETYPES (binfo);
- int i, n_baselinks = real_binfos ? TREE_VEC_LENGTH (real_binfos) : 0;
+ tree list = build_tree_list (type, addr);
- for (i = 0; i < n_baselinks; i++)
- {
- tree real_base_binfo = TREE_VEC_ELT (real_binfos, i);
- tree base_binfo = TREE_VEC_ELT (binfos, i);
- int is_not_base_vtable
- = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (real_binfo));
- if (! TREE_VIA_VIRTUAL (real_base_binfo))
- expand_direct_vtbls_init (real_base_binfo, base_binfo,
- is_not_base_vtable, can_elide, addr);
- }
-#if 0
- /* Before turning this on, make sure it is correct. */
- if (can_elide && ! BINFO_MODIFIED (binfo))
- return;
-#endif
- /* Should we use something besides CLASSTYPE_VFIELDS? */
- if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo)))
- {
- tree base_ptr = convert_pointer_to_real (binfo, addr);
- expand_virtual_init (real_binfo, base_ptr);
- }
+ dfs_walk (TYPE_BINFO (type), dfs_initialize_vtbl_ptrs,
+ 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);
}
+
\f
/* 348 - 351 */
/* Subroutine of emit_base_init. */
rbase_init_list = TREE_CHAIN (rbase_init_list);
}
- /* Initialize all the virtual function table fields that
- do come from virtual base classes. */
- if (TYPE_USES_VIRTUAL_BASECLASSES (t))
- expand_indirect_vtbls_init (t_binfo, current_class_ref, current_class_ptr);
-
- /* Initialize all the virtual function table fields that
- do not come from virtual base classes. */
- expand_direct_vtbls_init (t_binfo, t_binfo, 1, 1, current_class_ptr);
+ /* Initialize the vtable pointers for the class. */
+ initialize_vtbl_ptrs (t, current_class_ptr);
for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member))
{
static tree next_baselink PROTO((tree));
static tree get_vbase_1 PROTO((tree, tree, unsigned int *));
-static tree convert_pointer_to_vbase PROTO((tree, tree));
static tree lookup_field_1 PROTO((tree, tree));
static tree convert_pointer_to_single_level PROTO((tree, tree));
static int lookup_fnfields_here PROTO((tree, tree));
EXPR is a non-null POINTER_TYPE to RECORD_TYPE. We also know that
the type of what expr points to has a virtual base of type TYPE. */
-static tree
+tree
convert_pointer_to_vbase (type, expr)
tree type;
tree expr;
sub-object we are initializing. */
void
-expand_indirect_vtbls_init (binfo, true_exp, decl_ptr)
+expand_indirect_vtbls_init (binfo, decl_ptr)
tree binfo;
- tree true_exp, decl_ptr;
+ tree decl_ptr;
{
tree type = BINFO_TYPE (binfo);
{
tree vbases = CLASSTYPE_VBASECLASSES (type);
struct vbase_info vi;
- vi.decl_ptr = (true_exp ? build_unary_op (ADDR_EXPR, true_exp, 0)
- : decl_ptr);
+ vi.decl_ptr = decl_ptr;
vi.vbase_types = vbases;
dfs_walk (binfo, dfs_find_vbases, unmarked_new_vtablep, &vi);
-
- /* Initialized with vtables of type TYPE. */
- for (; vbases; vbases = TREE_CHAIN (vbases))
- {
- tree addr;
-
- addr = convert_pointer_to_vbase (TREE_TYPE (vbases), vi.decl_ptr);
-
- /* Do all vtables from this virtual base. */
- /* This assumes that virtual bases can never serve as parent
- binfos. (in the CLASSTYPE_VFIELD_PARENT sense) */
- expand_direct_vtbls_init (vbases, TYPE_BINFO (BINFO_TYPE (vbases)),
- 1, 0, addr);
- }
-
- fixup_all_virtual_upcast_offsets (type,
- vi.decl_ptr);
-
+ fixup_all_virtual_upcast_offsets (type, vi.decl_ptr);
dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, 0);
}
}
building RTL. These routines are used both during actual parsing
and during the instantiation of template functions.
- Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
Written by Mark Mitchell (mmitchell@usa.net) based on code found
formerly in parse.y and pt.c.
else if (DECL_DESTRUCTOR_P (current_function_decl)
&& !processing_template_decl)
{
- tree binfo = TYPE_BINFO (current_class_type);
tree if_stmt;
tree compound_stmt;
int saved_cfnd;
/* Make all virtual function table pointers in non-virtual base
classes point to CURRENT_CLASS_TYPE's virtual function
tables. */
- expand_direct_vtbls_init (binfo, binfo, 1, 0, current_class_ptr);
-
- if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))
- expand_indirect_vtbls_init (binfo, current_class_ref,
- current_class_ptr);
+ initialize_vtbl_ptrs (current_class_type,
+ current_class_ptr);
finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
finish_then_clause (if_stmt);