diff options
author | nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-10-08 09:33:55 +0000 |
---|---|---|
committer | nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-10-08 09:33:55 +0000 |
commit | 398b91ef0e2238be7cfc61286307d87819b322b0 (patch) | |
tree | 788c086498884f0d4d0b84c27c99cb6582b7f4b9 /gcc/cp/class.c | |
parent | bca30b067fb03fbaeccca1407ad94902cf8c660f (diff) | |
download | gcc-398b91ef0e2238be7cfc61286307d87819b322b0.tar.gz |
* cp-tree.h (dfs_walk, dfs_walk_real, dfs_unmark, markedp,
unmarkedp): Remove.
(dfs_skip_bases, dfs_walk_all, dfs_walk_once): New.
* class.c (struct find_final_overrider_data): Remove most_derived,
vpath_list and vpath fields. Add path field.
(dfs_find_final_ocerrider_1): Add DEPTH parameter. Adjust.
(dfs_find_final_overrider): Rename to ...
(dfs_find_final_overrider_pre): ... here. Adjust.
(dfs_find_final_overrider_post): Adjust.
(dfs_find_final_overrider_q): Fold into
dfs_find_final_overrider_pre.
(find_final_overrider): Adjust dfs searching.
(dfs_modify_vtables): Don't mark binfo here.
(modify_all_vtables): Use dfs_walk_once.
(build_vtt_inits): Likwise. Use dfs_walk_all.
(dfs_build_secondary_vptr_vtt_inits): Don't mark binfo here.
Return dfs_skip_bases as appropriate.
(dfs_fixup_binfo_vtbls): Return dfs_skip_bases as appropriate.
* init.c (dfs_initialized_vtbl_ptrs): Return dfs_skip_bases as
appropriate. Don't mark binfo here.
(initialize_vtbl_ptrs): Use dfs_walk_once.
* search.c (struct vbase_info): Remove unused struct.
(access_in_type): Use dfs_walk_once.
(dfs_access_in_type): Don't mark binfo here.
(dfs_accessible_queue_p, dfs_accessible_p) Remove.
Fold into ...
(accessible_r): ... here. New. Specialize dfs_walk_once.
(accessible_p): Use accessible_r.
(lookup_field_queue_p): Remove. Fold into ...
(lookup_field_r): ... here. Adjust.
(lookup_member): Use dfs_walk_all.
(dfs_walk_real, dfs_walk): Replace with ...
(dfs_walk_all, dfs_walk_once): ... these.
(dfs_walk_once_r, dfs_unmark_r): Workers for dfs_walk_once.
(dfs_unmark, unmarkedp, markedp): Remove.
(dfs_get_pure_virtuals): Don't mark binfo here.
(get_pure_virtuals): Use dfs_walk_once.
(dfs_debug_unmarked_p): Remove. Fold into ...
(dfs_debug_mark): ... here.
(note_debug_info_needed): Use dfs_walk_all.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@88738 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r-- | gcc/cp/class.c | 121 |
1 files changed, 45 insertions, 76 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c index e955560ffcd..d93ee228796 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -155,9 +155,8 @@ static void add_vcall_offset_vtbl_entries_1 (tree, vtbl_init_data *); static void build_vcall_offset_vtbl_entries (tree, vtbl_init_data *); static void add_vcall_offset (tree, tree, vtbl_init_data *); static void layout_vtable_decl (tree, int); -static tree dfs_find_final_overrider (tree, void *); +static tree dfs_find_final_overrider_pre (tree, void *); static tree dfs_find_final_overrider_post (tree, void *); -static tree dfs_find_final_overrider_q (tree, int, void *); static tree find_final_overrider (tree, tree, tree); static int make_new_vtable (tree, tree); static int maybe_indent_hierarchy (FILE *, int, int); @@ -171,15 +170,14 @@ static void dump_thunk (FILE *, int, tree); static tree build_vtable (tree, tree, tree); static void initialize_vtable (tree, tree); static void layout_nonempty_base_or_field (record_layout_info, - tree, tree, splay_tree); + tree, tree, splay_tree); static tree end_of_class (tree, int); static bool layout_empty_base (tree, tree, splay_tree); static void accumulate_vtbl_inits (tree, tree, tree, tree, tree); static tree dfs_accumulate_vtbl_inits (tree, tree, tree, tree, tree); static void build_rtti_vtbl_entries (tree, vtbl_init_data *); -static void build_vcall_and_vbase_vtbl_entries (tree, - vtbl_init_data *); +static void build_vcall_and_vbase_vtbl_entries (tree, vtbl_init_data *); static void clone_constructors_and_destructors (tree); static tree build_clone (tree, tree); static void update_vtable_entry_for_fn (tree, tree, tree, tree *, unsigned); @@ -192,11 +190,11 @@ static tree dfs_fixup_binfo_vtbls (tree, void *); static int record_subobject_offset (tree, tree, splay_tree); static int check_subobject_offset (tree, tree, splay_tree); static int walk_subobject_offsets (tree, subobject_offset_fn, - tree, splay_tree, tree, int); + tree, splay_tree, tree, int); static void record_subobject_offsets (tree, tree, splay_tree, int); static int layout_conflict_p (tree, tree, splay_tree, int); static int splay_tree_compare_integer_csts (splay_tree_key k1, - splay_tree_key k2); + splay_tree_key k2); static void warn_about_ambiguous_bases (tree); static bool type_requires_array_cookie (tree); static bool contains_empty_class_p (tree); @@ -1788,15 +1786,10 @@ typedef struct find_final_overrider_data_s { tree fn; /* The base class in which the function was declared. */ tree declaring_base; - /* The most derived class in the hierarchy. */ - tree most_derived_type; /* The candidate overriders. */ tree candidates; - /* Each entry in this array is the next-most-derived class for a - virtual base class along the current path. */ - tree *vpath_list; - /* A pointer one past the top of the VPATH_LIST. */ - tree *vpath; + /* Path to most derived. */ + VEC (tree) *path; } find_final_overrider_data; /* Add the overrider along the current path to FFOD->CANDIDATES. @@ -1804,22 +1797,18 @@ typedef struct find_final_overrider_data_s { static bool dfs_find_final_overrider_1 (tree binfo, - tree *vpath, - find_final_overrider_data *ffod) + find_final_overrider_data *ffod, + unsigned depth) { tree method; /* If BINFO is not the most derived type, try a more derived class. A definition there will overrider a definition here. */ - if (!same_type_p (BINFO_TYPE (binfo), ffod->most_derived_type)) + if (depth) { - tree derived; - - if (BINFO_VIRTUAL_P (binfo)) - derived = *--vpath; - else - derived = BINFO_INHERITANCE_CHAIN (binfo); - if (dfs_find_final_overrider_1 (derived, vpath, ffod)) + depth--; + if (dfs_find_final_overrider_1 + (VEC_index (tree, ffod->path, depth), ffod, depth)) return true; } @@ -1853,36 +1842,23 @@ dfs_find_final_overrider_1 (tree binfo, /* Called from find_final_overrider via dfs_walk. */ static tree -dfs_find_final_overrider (tree binfo, void* data) +dfs_find_final_overrider_pre (tree binfo, void *data) { find_final_overrider_data *ffod = (find_final_overrider_data *) data; if (binfo == ffod->declaring_base) - dfs_find_final_overrider_1 (binfo, ffod->vpath, ffod); + dfs_find_final_overrider_1 (binfo, ffod, VEC_length (tree, ffod->path)); + VEC_safe_push (tree, ffod->path, binfo); return NULL_TREE; } static tree -dfs_find_final_overrider_q (tree derived, int ix, void *data) -{ - tree binfo = BINFO_BASE_BINFO (derived, ix); - find_final_overrider_data *ffod = (find_final_overrider_data *) data; - - if (BINFO_VIRTUAL_P (binfo)) - *ffod->vpath++ = derived; - - return binfo; -} - -static tree -dfs_find_final_overrider_post (tree binfo, void *data) +dfs_find_final_overrider_post (tree binfo ATTRIBUTE_UNUSED, void *data) { find_final_overrider_data *ffod = (find_final_overrider_data *) data; + VEC_pop (tree, ffod->path); - if (BINFO_VIRTUAL_P (binfo)) - ffod->vpath--; - return NULL_TREE; } @@ -1920,23 +1896,14 @@ find_final_overrider (tree derived, tree binfo, tree fn) /* Determine the depth of the hierarchy. */ ffod.fn = fn; ffod.declaring_base = binfo; - ffod.most_derived_type = BINFO_TYPE (derived); ffod.candidates = NULL_TREE; - /* The virtual depth cannot be greater than the number of virtual - bases. */ - ffod.vpath_list = (tree *) xcalloc - (VEC_length (tree, CLASSTYPE_VBASECLASSES (BINFO_TYPE (derived))), - sizeof (tree)); - ffod.vpath = ffod.vpath_list; - - dfs_walk_real (derived, - dfs_find_final_overrider, - dfs_find_final_overrider_post, - dfs_find_final_overrider_q, - &ffod); + ffod.path = VEC_alloc (tree, 30); - free (ffod.vpath_list); + dfs_walk_all (derived, dfs_find_final_overrider_pre, + dfs_find_final_overrider_post, &ffod); + VEC_free (tree, ffod.path); + /* If there was no winner, issue an error message. */ if (!ffod.candidates || TREE_CHAIN (ffod.candidates)) { @@ -2208,8 +2175,6 @@ dfs_modify_vtables (tree binfo, void* data) &virtuals, ix); } - BINFO_MARKED (binfo) = 1; - return NULL_TREE; } @@ -2229,8 +2194,7 @@ modify_all_vtables (tree t, tree virtuals) tree *fnsp; /* Update all of the vtables. */ - dfs_walk (binfo, dfs_modify_vtables, unmarkedp, t); - dfs_walk (binfo, dfs_unmark, markedp, t); + dfs_walk_once (binfo, NULL, dfs_modify_vtables, t); /* Add virtual functions not already in our primary vtable. These will be both those introduced by this class, and those overridden @@ -6763,7 +6727,7 @@ build_vtt_inits (tree binfo, tree t, tree *inits, tree *index) /* Recursively add the secondary VTTs for non-virtual bases. */ for (i = 0; BINFO_BASE_ITERATE (binfo, i, b); ++i) if (!BINFO_VIRTUAL_P (b)) - inits = build_vtt_inits (BINFO_BASE_BINFO (binfo, i), t, inits, index); + inits = build_vtt_inits (b, t, inits, index); /* Add secondary virtual pointers for all subobjects of BINFO with either virtual bases or reachable along a virtual path, except @@ -6773,9 +6737,7 @@ build_vtt_inits (tree binfo, tree t, tree *inits, tree *index) data.inits = NULL; data.type_being_constructed = BINFO_TYPE (binfo); - dfs_walk_real (binfo, dfs_build_secondary_vptr_vtt_inits, - NULL, unmarkedp, &data); - dfs_walk (binfo, dfs_unmark, markedp, 0); + dfs_walk_once (binfo, dfs_build_secondary_vptr_vtt_inits, NULL, &data); *index = data.index; @@ -6802,7 +6764,7 @@ build_vtt_inits (tree binfo, tree t, tree *inits, tree *index) } else /* Remove the ctor vtables we created. */ - dfs_walk (binfo, dfs_fixup_binfo_vtbls, 0, binfo); + dfs_walk_all (binfo, dfs_fixup_binfo_vtbls, NULL, binfo); return inits; } @@ -6815,27 +6777,25 @@ dfs_build_secondary_vptr_vtt_inits (tree binfo, void *data_) { secondary_vptr_vtt_init_data *data = (secondary_vptr_vtt_init_data *)data_; - BINFO_MARKED (binfo) = 1; - /* We don't care about bases that don't have vtables. */ if (!TYPE_VFIELD (BINFO_TYPE (binfo))) - return NULL_TREE; + return dfs_skip_bases; /* We're only interested in proper subobjects of the type being constructed. */ if (same_type_p (BINFO_TYPE (binfo), data->type_being_constructed)) return NULL_TREE; - /* We're not interested in non-virtual primary bases. */ - if (!BINFO_VIRTUAL_P (binfo) && BINFO_PRIMARY_P (binfo)) - return NULL_TREE; - /* We're only interested in bases with virtual bases or reachable via a virtual path from the type being constructed. */ - if (!CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)) - && !binfo_via_virtual (binfo, data->type_being_constructed)) + if (!(CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)) + || binfo_via_virtual (binfo, data->type_being_constructed))) + return dfs_skip_bases; + + /* We're not interested in non-virtual primary bases. */ + if (!BINFO_VIRTUAL_P (binfo) && BINFO_PRIMARY_P (binfo)) return NULL_TREE; - + /* Record the index where this secondary vptr can be found. */ if (data->top_level_p) { @@ -6873,9 +6833,18 @@ dfs_fixup_binfo_vtbls (tree binfo, void* data) { tree vtable = BINFO_VTABLE (binfo); + if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo))) + /* If this class has no vtable, none of its bases do. */ + return dfs_skip_bases; + + if (!vtable) + /* This might be a primary base, so have no vtable in this + hierarchy. */ + return NULL_TREE; + /* If we scribbled the construction vtable vptr into BINFO, clear it out now. */ - if (vtable && TREE_CODE (vtable) == TREE_LIST + if (TREE_CODE (vtable) == TREE_LIST && (TREE_PURPOSE (vtable) == (tree) data)) BINFO_VTABLE (binfo) = TREE_CHAIN (vtable); |