This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++] Fix some dfs_walk uses
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 27 Sep 2004 13:02:05 +0100
- Subject: [C++] Fix some dfs_walk uses
- Organization: Codesourcery LLC
This patch removes some unnecessary dfs_walk calls, and replaces
the truely baroque get_template_base with a more sane version. You'll
notice that it was marking only those bases that it could ever reach
once. I suspect it merely _needs_ to traverse the bases once, and I'll
get to that once I've improved dfs_walk itself.
booted & tested on i686-pc-linux-gnu.
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
2004-09-27 Nathan Sidwell <nathan@codesourcery.com>
* class.c (struct count_depth_data): Remove.
(dfs_depth_post, dfs_depth_q): Remove.
(find_final_overrider): Use number of vbase classes as depth
bound.
* cp-tree.h (types_overlap_p): Remove.
* search.c (struct overlap_info): Remove.
(dfs_check_overlap, dfs_no_overlap_yet, types_overlap_p): Remove.
* pt.c (GTB_VIA_VIRTUAL, GTB_IGNORE_TYPE): Remove.
(get_template_base_recursive): Remove. Replace with ...
(get_template_base_r): ... this.
(struct get_template_base_data_s): New.
(get_template_base): Use get_template_base_r via dfs_walk. Always
return NULL on failure.
(unify): Remove error_mark_node check from get_template_base result.
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.676
diff -c -3 -p -r1.676 class.c
*** cp/class.c 21 Sep 2004 15:38:50 -0000 1.676
--- cp/class.c 27 Sep 2004 11:57:14 -0000
*************** base_derived_from (tree derived, tree ba
*** 1801,1836 ****
return false;
}
- typedef struct count_depth_data {
- /* The depth of the current subobject, with "1" as the depth of the
- most derived object in the hierarchy. */
- size_t depth;
- /* The maximum depth found so far. */
- size_t max_depth;
- } count_depth_data;
-
- /* Called from find_final_overrider via dfs_walk. */
-
- static tree
- dfs_depth_post (tree binfo ATTRIBUTE_UNUSED, void *data)
- {
- count_depth_data *cd = (count_depth_data *) data;
- if (cd->depth > cd->max_depth)
- cd->max_depth = cd->depth;
- cd->depth--;
- return NULL_TREE;
- }
-
- /* Called from find_final_overrider via dfs_walk. */
-
- static tree
- dfs_depth_q (tree derived, int i, void *data)
- {
- count_depth_data *cd = (count_depth_data *) data;
- cd->depth++;
- return BINFO_BASE_BINFO (derived, i);
- }
-
typedef struct find_final_overrider_data_s {
/* The function for which we are trying to find a final overrider. */
tree fn;
--- 1801,1806 ----
*************** static tree
*** 1943,1949 ****
find_final_overrider (tree derived, tree binfo, tree fn)
{
find_final_overrider_data ffod;
- count_depth_data cd;
/* Getting this right is a little tricky. This is valid:
--- 1913,1918 ----
*************** find_final_overrider (tree derived, tree
*** 1967,1981 ****
fn = THUNK_TARGET (fn);
/* Determine the depth of the hierarchy. */
- cd.depth = 0;
- cd.max_depth = 0;
- dfs_walk (derived, dfs_depth_post, dfs_depth_q, &cd);
-
ffod.fn = fn;
ffod.declaring_base = binfo;
ffod.most_derived_type = BINFO_TYPE (derived);
ffod.candidates = NULL_TREE;
! ffod.vpath_list = (tree *) xcalloc (cd.max_depth, sizeof (tree));
ffod.vpath = ffod.vpath_list;
dfs_walk_real (derived,
--- 1936,1950 ----
fn = THUNK_TARGET (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,
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1052
diff -c -3 -p -r1.1052 cp-tree.h
*** cp/cp-tree.h 22 Sep 2004 18:12:04 -0000 1.1052
--- cp/cp-tree.h 27 Sep 2004 11:57:24 -0000
*************** extern bool emit_tinfo_decl (tree);
*** 3981,3987 ****
/* in search.c */
extern bool accessible_base_p (tree, tree);
extern tree lookup_base (tree, tree, base_access, base_kind *);
- extern int types_overlap_p (tree, tree);
extern tree get_dynamic_cast_base_type (tree, tree);
extern int accessible_p (tree, tree);
extern tree lookup_field_1 (tree, tree, bool);
--- 3981,3986 ----
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.926
diff -c -3 -p -r1.926 pt.c
*** cp/pt.c 21 Sep 2004 15:38:58 -0000 1.926
--- cp/pt.c 27 Sep 2004 11:57:49 -0000
*************** static htab_t local_specializations;
*** 87,98 ****
#define UNIFY_ALLOW_OUTER_LESS_CV_QUAL 64
#define UNIFY_ALLOW_MAX_CORRECTION 128
- #define GTB_VIA_VIRTUAL 1 /* The base class we are examining is
- virtual, or a base class of a virtual
- base. */
- #define GTB_IGNORE_TYPE 2 /* We don't need to try to unify the current
- type with the desired type. */
-
static void push_access_scope (tree);
static void pop_access_scope (tree);
static int resolve_overloaded_unification (tree, tree, tree, tree,
--- 87,92 ----
*************** static tree process_partial_specializati
*** 154,160 ****
static void set_current_access_from_decl (tree);
static void check_default_tmpl_args (tree, tree, int, int);
static tree tsubst_call_declarator_parms (tree, tree, tsubst_flags_t, tree);
! static tree get_template_base_recursive (tree, tree, tree, tree, tree, int);
static tree get_template_base (tree, tree, tree, tree);
static int verify_class_unification (tree, tree, tree);
static tree try_class_unification (tree, tree, tree, tree);
--- 148,154 ----
static void set_current_access_from_decl (tree);
static void check_default_tmpl_args (tree, tree, int, int);
static tree tsubst_call_declarator_parms (tree, tree, tsubst_flags_t, tree);
! static tree get_template_base_r (tree, void *);
static tree get_template_base (tree, tree, tree, tree);
static int verify_class_unification (tree, tree, tree);
static tree try_class_unification (tree, tree, tree, tree);
*************** try_class_unification (tree tparms, tree
*** 9475,9545 ****
return arg;
}
! /* Subroutine of get_template_base. RVAL, if non-NULL, is a base we
! have already discovered to be satisfactory. ARG_BINFO is the binfo
! for the base class of ARG that we are currently examining. */
static tree
! get_template_base_recursive (tree tparms,
! tree targs,
! tree parm,
! tree arg_binfo,
! tree rval,
! int flags)
{
! tree base_binfo;
! int i;
! tree arg = BINFO_TYPE (arg_binfo);
! if (!(flags & GTB_IGNORE_TYPE))
{
! tree r = try_class_unification (tparms, targs,
! parm, arg);
!
! /* If there is more than one satisfactory baseclass, then:
!
! [temp.deduct.call]
!
! If they yield more than one possible deduced A, the type
! deduction fails.
! applies. */
! if (r && rval && !same_type_p (r, rval))
! return error_mark_node;
! else if (r)
! rval = r;
! }
! /* Process base types. */
! for (i = 0; BINFO_BASE_ITERATE (arg_binfo, i, base_binfo); i++)
! {
! int this_virtual;
! /* Skip this base, if we've already seen it. */
! if (BINFO_MARKED (base_binfo))
! continue;
! this_virtual =
! (flags & GTB_VIA_VIRTUAL) || BINFO_VIRTUAL_P (base_binfo);
!
! /* When searching for a non-virtual, we cannot mark virtually
! found binfos. */
! if (! this_virtual)
! BINFO_MARKED (base_binfo) = 1;
!
! rval = get_template_base_recursive (tparms, targs,
! parm,
! base_binfo,
! rval,
! GTB_VIA_VIRTUAL * this_virtual);
!
! /* If we discovered more than one matching base class, we can
! stop now. */
! if (rval == error_mark_node)
! return error_mark_node;
}
! return rval;
}
/* Given a template type PARM and a class type ARG, find the unique
--- 9469,9521 ----
return arg;
}
! typedef struct get_template_base_data_s
! {
! /* Parameters for unification. */
! tree tparms;
! tree targs;
! tree parm;
! /* Base we've found to be satisfactory. */
! tree rval;
! } get_template_base_data;
!
! /* Called from get_template_base via dfs_walk. */
static tree
! get_template_base_r (tree arg_binfo,
! void *data_)
{
! get_template_base_data *data = data_;
! /* Do not look at the most derived binfo -- that's not a proper
! base. */
! if (BINFO_INHERITANCE_CHAIN (arg_binfo))
{
! tree r = try_class_unification (data->tparms, data->targs,
! data->parm, BINFO_TYPE (arg_binfo));
! if (r)
! {
! /* If there is more than one satisfactory baseclass, then:
! [temp.deduct.call]
! If they yield more than one possible deduced A, the type
! deduction fails.
! applies. */
! if (data->rval && !same_type_p (r, data->rval))
! {
! data->rval = NULL_TREE;
! /* Terminate the walk with any non-NULL value. */
! return r;
! }
!
! data->rval = r;
! }
}
! return NULL_TREE;
}
/* Given a template type PARM and a class type ARG, find the unique
*************** get_template_base_recursive (tree tparms
*** 9552,9558 ****
static tree
get_template_base (tree tparms, tree targs, tree parm, tree arg)
{
! tree rval;
tree arg_binfo;
gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)));
--- 9528,9534 ----
static tree
get_template_base (tree tparms, tree targs, tree parm, tree arg)
{
! get_template_base_data data;
tree arg_binfo;
gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)));
*************** get_template_base (tree tparms, tree tar
*** 9561,9577 ****
if (!arg_binfo)
/* The type could not be completed. */
return NULL_TREE;
-
- rval = get_template_base_recursive (tparms, targs,
- parm, arg_binfo,
- NULL_TREE,
- GTB_IGNORE_TYPE);
-
- /* Since get_template_base_recursive marks the bases classes, we
- must unmark them here. */
- dfs_walk (arg_binfo, dfs_unmark, markedp, 0);
! return rval;
}
/* Returns the level of DECL, which declares a template parameter. */
--- 9537,9551 ----
if (!arg_binfo)
/* The type could not be completed. */
return NULL_TREE;
! data.tparms = tparms;
! data.targs = targs;
! data.parm = parm;
! data.rval = NULL_TREE;
!
! dfs_walk_real (arg_binfo, get_template_base_r, 0, 0, &data);
!
! return data.rval;
}
/* Returns the level of DECL, which declares a template parameter. */
*************** unify (tree tparms, tree targs, tree par
*** 10058,10067 ****
a class of the form template-id, A can be a
pointer to a derived class pointed to by the
deduced A. */
! t = get_template_base (tparms, targs,
! parm, arg);
! if (! t || t == error_mark_node)
return 1;
}
}
--- 10032,10040 ----
a class of the form template-id, A can be a
pointer to a derived class pointed to by the
deduced A. */
! t = get_template_base (tparms, targs, parm, arg);
! if (!t)
return 1;
}
}
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v
retrieving revision 1.322
diff -c -3 -p -r1.322 search.c
*** cp/search.c 24 Sep 2004 14:04:47 -0000 1.322
--- cp/search.c 27 Sep 2004 11:57:54 -0000
*************** struct vbase_info
*** 46,53 ****
};
static int is_subobject_of_p (tree, tree);
- static tree dfs_check_overlap (tree, void *);
- static tree dfs_no_overlap_yet (tree, int, void *);
static base_kind lookup_base_r (tree, tree, base_access, bool, tree *);
static int dynamic_cast_base_recurse (tree, tree, bool, tree *);
static tree dfs_debug_unmarkedp (tree, int, void *);
--- 46,51 ----
*************** lookup_conversions (tree type)
*** 2272,2336 ****
return list;
}
- struct overlap_info
- {
- tree compare_type;
- int found_overlap;
- };
-
- /* Check whether the empty class indicated by EMPTY_BINFO is also present
- at offset 0 in COMPARE_TYPE, and set found_overlap if so. */
-
- static tree
- dfs_check_overlap (tree empty_binfo, void *data)
- {
- struct overlap_info *oi = (struct overlap_info *) data;
- tree binfo;
-
- for (binfo = TYPE_BINFO (oi->compare_type);
- ;
- binfo = BINFO_BASE_BINFO (binfo, 0))
- {
- if (BINFO_TYPE (binfo) == BINFO_TYPE (empty_binfo))
- {
- oi->found_overlap = 1;
- break;
- }
- else if (!BINFO_N_BASE_BINFOS (binfo))
- break;
- }
-
- return NULL_TREE;
- }
-
- /* Trivial function to stop base traversal when we find something. */
-
- static tree
- dfs_no_overlap_yet (tree derived, int ix, void *data)
- {
- tree binfo = BINFO_BASE_BINFO (derived, ix);
- struct overlap_info *oi = (struct overlap_info *) data;
-
- return !oi->found_overlap ? binfo : NULL_TREE;
- }
-
- /* Returns nonzero if EMPTY_TYPE or any of its bases can also be found at
- offset 0 in NEXT_TYPE. Used in laying out empty base class subobjects. */
-
- int
- types_overlap_p (tree empty_type, tree next_type)
- {
- struct overlap_info oi;
-
- if (! IS_AGGR_TYPE (next_type))
- return 0;
- oi.compare_type = next_type;
- oi.found_overlap = 0;
- dfs_walk (TYPE_BINFO (empty_type), dfs_check_overlap,
- dfs_no_overlap_yet, &oi);
- return oi.found_overlap;
- }
-
/* Returns the binfo of the first direct or indirect virtual base derived
from BINFO, or NULL if binfo is not via virtual. */
--- 2270,2275 ----