diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index dee8d5a1d4d..16533f75683 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,22 @@ +2004-09-27 Nathan Sidwell + + * 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. + 2004-09-24 Paolo Bonzini * parser.c (cp_parser_expression_stack): Clarify why it is diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 071cd80344f..f32f9ccfba9 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1801,36 +1801,6 @@ base_derived_from (tree derived, tree base) 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; @@ -1943,7 +1913,6 @@ static tree 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: @@ -1967,15 +1936,15 @@ find_final_overrider (tree derived, tree binfo, tree fn) 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)); + /* 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, diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c439864c1b1..4976894703a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3981,7 +3981,6 @@ extern bool emit_tinfo_decl (tree); /* 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); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 42f652a5b9e..3125c83baff 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -87,12 +87,6 @@ static htab_t local_specializations; #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, @@ -154,7 +148,7 @@ static tree process_partial_specialization (tree); 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_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); @@ -9475,71 +9469,53 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg) 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. */ +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_recursive (tree tparms, - tree targs, - tree parm, - tree arg_binfo, - tree rval, - int flags) +get_template_base_r (tree arg_binfo, + void *data_) { - tree base_binfo; - int i; - tree arg = BINFO_TYPE (arg_binfo); + get_template_base_data *data = data_; - if (!(flags & GTB_IGNORE_TYPE)) + /* 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 (tparms, targs, - parm, arg); + tree r = try_class_unification (data->tparms, data->targs, + data->parm, BINFO_TYPE (arg_binfo)); - /* If there is more than one satisfactory baseclass, then: + if (r) + { + /* If there is more than one satisfactory baseclass, then: - [temp.deduct.call] + [temp.deduct.call] - If they yield more than one possible deduced A, the type - deduction fails. + 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; + 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; + } } - /* 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; + return NULL_TREE; } /* Given a template type PARM and a class type ARG, find the unique @@ -9552,7 +9528,7 @@ get_template_base_recursive (tree tparms, static tree get_template_base (tree tparms, tree targs, tree parm, tree arg) { - tree rval; + get_template_base_data data; tree arg_binfo; gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg))); @@ -9561,17 +9537,15 @@ get_template_base (tree tparms, tree targs, tree parm, tree arg) 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); + data.tparms = tparms; + data.targs = targs; + data.parm = parm; + data.rval = NULL_TREE; - return rval; + 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. */ @@ -10058,10 +10032,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) 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); + t = get_template_base (tparms, targs, parm, arg); - if (! t || t == error_mark_node) + if (!t) return 1; } } diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 67b891f85e3..96d273be195 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -46,8 +46,6 @@ struct vbase_info }; 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 *); @@ -2272,65 +2270,6 @@ lookup_conversions (tree type) 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. */