class.c (struct count_depth_data): Remove.
* 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. From-SVN: r88169
This commit is contained in:
parent
75e50bd288
commit
8d83768f78
|
@ -1,3 +1,22 @@
|
||||||
|
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.
|
||||||
|
|
||||||
2004-09-24 Paolo Bonzini <bonzini@gnu.org>
|
2004-09-24 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
|
||||||
* parser.c (cp_parser_expression_stack): Clarify why it is
|
* parser.c (cp_parser_expression_stack): Clarify why it is
|
||||||
|
|
|
@ -1801,36 +1801,6 @@ base_derived_from (tree derived, tree base)
|
||||||
return false;
|
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 {
|
typedef struct find_final_overrider_data_s {
|
||||||
/* The function for which we are trying to find a final overrider. */
|
/* The function for which we are trying to find a final overrider. */
|
||||||
tree fn;
|
tree fn;
|
||||||
|
@ -1943,7 +1913,6 @@ static tree
|
||||||
find_final_overrider (tree derived, tree binfo, tree fn)
|
find_final_overrider (tree derived, tree binfo, tree fn)
|
||||||
{
|
{
|
||||||
find_final_overrider_data ffod;
|
find_final_overrider_data ffod;
|
||||||
count_depth_data cd;
|
|
||||||
|
|
||||||
/* Getting this right is a little tricky. This is valid:
|
/* 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);
|
fn = THUNK_TARGET (fn);
|
||||||
|
|
||||||
/* Determine the depth of the hierarchy. */
|
/* 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.fn = fn;
|
||||||
ffod.declaring_base = binfo;
|
ffod.declaring_base = binfo;
|
||||||
ffod.most_derived_type = BINFO_TYPE (derived);
|
ffod.most_derived_type = BINFO_TYPE (derived);
|
||||||
ffod.candidates = NULL_TREE;
|
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;
|
ffod.vpath = ffod.vpath_list;
|
||||||
|
|
||||||
dfs_walk_real (derived,
|
dfs_walk_real (derived,
|
||||||
|
|
|
@ -3981,7 +3981,6 @@ extern bool emit_tinfo_decl (tree);
|
||||||
/* in search.c */
|
/* in search.c */
|
||||||
extern bool accessible_base_p (tree, tree);
|
extern bool accessible_base_p (tree, tree);
|
||||||
extern tree lookup_base (tree, tree, base_access, base_kind *);
|
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 tree get_dynamic_cast_base_type (tree, tree);
|
||||||
extern int accessible_p (tree, tree);
|
extern int accessible_p (tree, tree);
|
||||||
extern tree lookup_field_1 (tree, tree, bool);
|
extern tree lookup_field_1 (tree, tree, bool);
|
||||||
|
|
121
gcc/cp/pt.c
121
gcc/cp/pt.c
|
@ -87,12 +87,6 @@ static htab_t local_specializations;
|
||||||
#define UNIFY_ALLOW_OUTER_LESS_CV_QUAL 64
|
#define UNIFY_ALLOW_OUTER_LESS_CV_QUAL 64
|
||||||
#define UNIFY_ALLOW_MAX_CORRECTION 128
|
#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 push_access_scope (tree);
|
||||||
static void pop_access_scope (tree);
|
static void pop_access_scope (tree);
|
||||||
static int resolve_overloaded_unification (tree, tree, tree, 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 set_current_access_from_decl (tree);
|
||||||
static void check_default_tmpl_args (tree, tree, int, int);
|
static void check_default_tmpl_args (tree, tree, int, int);
|
||||||
static tree tsubst_call_declarator_parms (tree, tree, tsubst_flags_t, tree);
|
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 tree get_template_base (tree, tree, tree, tree);
|
||||||
static int verify_class_unification (tree, tree, tree);
|
static int verify_class_unification (tree, tree, tree);
|
||||||
static tree try_class_unification (tree, 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;
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Subroutine of get_template_base. RVAL, if non-NULL, is a base we
|
typedef struct get_template_base_data_s
|
||||||
have already discovered to be satisfactory. ARG_BINFO is the binfo
|
{
|
||||||
for the base class of ARG that we are currently examining. */
|
/* 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
|
static tree
|
||||||
get_template_base_recursive (tree tparms,
|
get_template_base_r (tree arg_binfo,
|
||||||
tree targs,
|
void *data_)
|
||||||
tree parm,
|
|
||||||
tree arg_binfo,
|
|
||||||
tree rval,
|
|
||||||
int flags)
|
|
||||||
{
|
{
|
||||||
tree base_binfo;
|
get_template_base_data *data = data_;
|
||||||
int i;
|
|
||||||
tree arg = BINFO_TYPE (arg_binfo);
|
|
||||||
|
|
||||||
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,
|
tree r = try_class_unification (data->tparms, data->targs,
|
||||||
parm, arg);
|
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
|
If they yield more than one possible deduced A, the type
|
||||||
deduction fails.
|
deduction fails.
|
||||||
|
|
||||||
applies. */
|
applies. */
|
||||||
if (r && rval && !same_type_p (r, rval))
|
if (data->rval && !same_type_p (r, data->rval))
|
||||||
return error_mark_node;
|
{
|
||||||
else if (r)
|
data->rval = NULL_TREE;
|
||||||
rval = r;
|
/* Terminate the walk with any non-NULL value. */
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->rval = r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process base types. */
|
return NULL_TREE;
|
||||||
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
|
/* 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
|
static tree
|
||||||
get_template_base (tree tparms, tree targs, tree parm, tree arg)
|
get_template_base (tree tparms, tree targs, tree parm, tree arg)
|
||||||
{
|
{
|
||||||
tree rval;
|
get_template_base_data data;
|
||||||
tree arg_binfo;
|
tree arg_binfo;
|
||||||
|
|
||||||
gcc_assert (IS_AGGR_TYPE_CODE (TREE_CODE (arg)));
|
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)
|
if (!arg_binfo)
|
||||||
/* The type could not be completed. */
|
/* The type could not be completed. */
|
||||||
return NULL_TREE;
|
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
|
data.tparms = tparms;
|
||||||
must unmark them here. */
|
data.targs = targs;
|
||||||
dfs_walk (arg_binfo, dfs_unmark, markedp, 0);
|
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. */
|
/* 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
|
a class of the form template-id, A can be a
|
||||||
pointer to a derived class pointed to by the
|
pointer to a derived class pointed to by the
|
||||||
deduced A. */
|
deduced A. */
|
||||||
t = get_template_base (tparms, targs,
|
t = get_template_base (tparms, targs, parm, arg);
|
||||||
parm, arg);
|
|
||||||
|
|
||||||
if (! t || t == error_mark_node)
|
if (!t)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,6 @@ struct vbase_info
|
||||||
};
|
};
|
||||||
|
|
||||||
static int is_subobject_of_p (tree, tree);
|
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 base_kind lookup_base_r (tree, tree, base_access, bool, tree *);
|
||||||
static int dynamic_cast_base_recurse (tree, tree, bool, tree *);
|
static int dynamic_cast_base_recurse (tree, tree, bool, tree *);
|
||||||
static tree dfs_debug_unmarkedp (tree, int, void *);
|
static tree dfs_debug_unmarkedp (tree, int, void *);
|
||||||
|
@ -2272,65 +2270,6 @@ lookup_conversions (tree type)
|
||||||
return list;
|
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
|
/* Returns the binfo of the first direct or indirect virtual base derived
|
||||||
from BINFO, or NULL if binfo is not via virtual. */
|
from BINFO, or NULL if binfo is not via virtual. */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue