Commit 514a1f18 by Jason Merrill Committed by Jason Merrill

cvt.c (convert_pointer_to_real): Tidy.

	* cvt.c (convert_pointer_to_real): Tidy.
	* search.c (get_base_distance_recursive): Simplify.
	(get_base_distance): Likewise.
	* pt.c (unify): Only special-case INTEGER_TYPE if it uses template
	parms.

From-SVN: r22189
parent 84fec828
1998-09-02 Jason Merrill <jason@yorick.cygnus.com>
* cvt.c (convert_pointer_to_real): Tidy.
* search.c (get_base_distance_recursive): Simplify.
(get_base_distance): Likewise.
* pt.c (unify): Only special-case INTEGER_TYPE if it uses template
parms.
Wed Sep 02 09:25:29 1998 Nick Clifton <nickc@cygnus.com> Wed Sep 02 09:25:29 1998 Nick Clifton <nickc@cygnus.com>
* lex.c (check_newline): Call HANDLE_PRAGMA before * lex.c (check_newline): Call HANDLE_PRAGMA before
......
...@@ -852,7 +852,7 @@ struct lang_type ...@@ -852,7 +852,7 @@ struct lang_type
#define CLASSTYPE_N_BASECLASSES(NODE) \ #define CLASSTYPE_N_BASECLASSES(NODE) \
(TYPE_BINFO_BASETYPES (NODE) ? TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES(NODE)) : 0) (TYPE_BINFO_BASETYPES (NODE) ? TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES(NODE)) : 0)
/* Memoize the number of super classes (base classes) tha this node /* Memoize the number of super classes (base classes) that this node
has. That way we can know immediately (albeit conservatively how has. That way we can know immediately (albeit conservatively how
large a multiple-inheritance matrix we need to build to find large a multiple-inheritance matrix we need to build to find
derivation information. */ derivation information. */
......
...@@ -579,21 +579,21 @@ convert_pointer_to_real (binfo, expr) ...@@ -579,21 +579,21 @@ convert_pointer_to_real (binfo, expr)
my_friendly_assert (!integer_zerop (expr), 191); my_friendly_assert (!integer_zerop (expr), 191);
intype = TYPE_MAIN_VARIANT (TREE_TYPE (intype));
if (TREE_CODE (type) == RECORD_TYPE if (TREE_CODE (type) == RECORD_TYPE
&& TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE && TREE_CODE (intype) == RECORD_TYPE
&& type != TYPE_MAIN_VARIANT (TREE_TYPE (intype))) && type != intype)
{ {
tree path; tree path;
int distance int distance
= get_base_distance (binfo, TYPE_MAIN_VARIANT (TREE_TYPE (intype)), = get_base_distance (binfo, intype, 0, &path);
0, &path);
/* This function shouldn't be called with unqualified arguments /* This function shouldn't be called with unqualified arguments
but if it is, give them an error message that they can read. */ but if it is, give them an error message that they can read. */
if (distance < 0) if (distance < 0)
{ {
cp_error ("cannot convert a pointer of type `%T' to a pointer of type `%T'", cp_error ("cannot convert a pointer of type `%T' to a pointer of type `%T'",
TREE_TYPE (intype), type); intype, type);
if (distance == -2) if (distance == -2)
cp_error ("because `%T' is an ambiguous base class", type); cp_error ("because `%T' is an ambiguous base class", type);
......
...@@ -7007,7 +7007,8 @@ unify (tparms, targs, parm, arg, strict, explicit_mask) ...@@ -7007,7 +7007,8 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
if (TREE_CODE (arg) != TREE_CODE (parm)) if (TREE_CODE (arg) != TREE_CODE (parm))
return 1; return 1;
if (TREE_CODE (parm) == INTEGER_TYPE) if (TREE_CODE (parm) == INTEGER_TYPE
&& TREE_CODE (TYPE_MAX_VALUE (parm)) != INTEGER_CST)
{ {
if (TYPE_MIN_VALUE (parm) && TYPE_MIN_VALUE (arg) if (TYPE_MIN_VALUE (parm) && TYPE_MIN_VALUE (arg)
&& unify (tparms, targs, TYPE_MIN_VALUE (parm), && unify (tparms, targs, TYPE_MIN_VALUE (parm),
...@@ -7018,11 +7019,10 @@ unify (tparms, targs, parm, arg, strict, explicit_mask) ...@@ -7018,11 +7019,10 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
TYPE_MAX_VALUE (arg), UNIFY_ALLOW_NONE, explicit_mask)) TYPE_MAX_VALUE (arg), UNIFY_ALLOW_NONE, explicit_mask))
return 1; return 1;
} }
else if (TREE_CODE (parm) == REAL_TYPE
/* We use the TYPE_MAIN_VARIANT since we have already /* We use the TYPE_MAIN_VARIANT since we have already
checked cv-qualification at the top of the checked cv-qualification at the top of the
function. */ function. */
&& !comptypes (TYPE_MAIN_VARIANT (arg), else if (!comptypes (TYPE_MAIN_VARIANT (arg),
TYPE_MAIN_VARIANT (parm), 1)) TYPE_MAIN_VARIANT (parm), 1))
return 1; return 1;
......
...@@ -93,7 +93,7 @@ static void dfs_check_overlap PROTO((tree)); ...@@ -93,7 +93,7 @@ static void dfs_check_overlap PROTO((tree));
static int dfs_no_overlap_yet PROTO((tree)); static int dfs_no_overlap_yet PROTO((tree));
static void envelope_add_decl PROTO((tree, tree, tree *)); static void envelope_add_decl PROTO((tree, tree, tree *));
static int get_base_distance_recursive static int get_base_distance_recursive
PROTO((tree, int, int, int, int *, tree *, tree, tree *, PROTO((tree, int, int, int, int *, tree *, tree,
int, int *, int, int)); int, int *, int, int));
static void expand_upcast_fixups static void expand_upcast_fixups
PROTO((tree, tree, tree, tree, tree, tree, tree *)); PROTO((tree, tree, tree, tree, tree, tree, tree *));
...@@ -156,8 +156,6 @@ pop_search_level (obstack) ...@@ -156,8 +156,6 @@ pop_search_level (obstack)
return stack; return stack;
} }
/* Obstack used for memoizing member and member function lookup. */
static tree _vptr_name; static tree _vptr_name;
/* Variables for gathering statistics. */ /* Variables for gathering statistics. */
...@@ -177,7 +175,10 @@ static tree closed_envelopes = NULL_TREE; ...@@ -177,7 +175,10 @@ static tree closed_envelopes = NULL_TREE;
/* Get a virtual binfo that is found inside BINFO's hierarchy that is /* Get a virtual binfo that is found inside BINFO's hierarchy that is
the same type as the type given in PARENT. To be optimal, we want the same type as the type given in PARENT. To be optimal, we want
the first one that is found by going through the least number of the first one that is found by going through the least number of
virtual bases. */ virtual bases.
This uses a clever algorithm that updates *depth when we find the vbase,
and cuts off other paths of search when they reach that depth. */
static tree static tree
get_vbase_1 (parent, binfo, depth) get_vbase_1 (parent, binfo, depth)
...@@ -216,6 +217,9 @@ get_vbase_1 (parent, binfo, depth) ...@@ -216,6 +217,9 @@ get_vbase_1 (parent, binfo, depth)
return rval; return rval;
} }
/* Return the shortest path to vbase PARENT within BINFO, ignoring
access and ambiguity. */
tree tree
get_vbase (parent, binfo) get_vbase (parent, binfo)
tree parent; tree parent;
...@@ -292,13 +296,13 @@ get_binfo (parent, binfo, protect) ...@@ -292,13 +296,13 @@ get_binfo (parent, binfo, protect)
static int static int
get_base_distance_recursive (binfo, depth, is_private, rval, get_base_distance_recursive (binfo, depth, is_private, rval,
rval_private_ptr, new_binfo_ptr, parent, path_ptr, rval_private_ptr, new_binfo_ptr, parent,
protect, via_virtual_ptr, via_virtual, protect, via_virtual_ptr, via_virtual,
current_scope_in_chain) current_scope_in_chain)
tree binfo; tree binfo;
int depth, is_private, rval; int depth, is_private, rval;
int *rval_private_ptr; int *rval_private_ptr;
tree *new_binfo_ptr, parent, *path_ptr; tree *new_binfo_ptr, parent;
int protect, *via_virtual_ptr, via_virtual; int protect, *via_virtual_ptr, via_virtual;
int current_scope_in_chain; int current_scope_in_chain;
{ {
...@@ -312,38 +316,42 @@ get_base_distance_recursive (binfo, depth, is_private, rval, ...@@ -312,38 +316,42 @@ get_base_distance_recursive (binfo, depth, is_private, rval,
if (BINFO_TYPE (binfo) == parent || binfo == parent) if (BINFO_TYPE (binfo) == parent || binfo == parent)
{ {
int better = 0;
if (rval == -1) if (rval == -1)
/* This is the first time we've found parent. */
better = 1;
else if (tree_int_cst_equal (BINFO_OFFSET (*new_binfo_ptr),
BINFO_OFFSET (binfo))
&& *via_virtual_ptr && via_virtual)
{ {
rval = depth; /* A new path to the same vbase. If this one has better
*rval_private_ptr = is_private; access or is shorter, take it. */
*new_binfo_ptr = binfo;
*via_virtual_ptr = via_virtual; if (protect)
better = *rval_private_ptr - is_private;
if (better == 0)
better = rval - depth;
} }
else else
{ {
int same_object = (tree_int_cst_equal (BINFO_OFFSET (*new_binfo_ptr), /* Ambiguous base class. */
BINFO_OFFSET (binfo)) rval = depth = -2;
&& *via_virtual_ptr && via_virtual);
if (*via_virtual_ptr && via_virtual==0) /* If we get an ambiguity between virtual and non-virtual base
{ class, return the non-virtual in case we are ignoring
*rval_private_ptr = is_private; ambiguity. */
*new_binfo_ptr = binfo; better = *via_virtual_ptr - via_virtual;
*via_virtual_ptr = via_virtual;
} }
else if (same_object)
{ if (better > 0)
if (*rval_private_ptr && ! is_private)
{ {
rval = depth;
*rval_private_ptr = is_private; *rval_private_ptr = is_private;
*new_binfo_ptr = binfo; *new_binfo_ptr = binfo;
*via_virtual_ptr = via_virtual; *via_virtual_ptr = via_virtual;
} }
return rval;
}
rval = -2;
}
return rval; return rval;
} }
...@@ -356,10 +364,6 @@ get_base_distance_recursive (binfo, depth, is_private, rval, ...@@ -356,10 +364,6 @@ get_base_distance_recursive (binfo, depth, is_private, rval,
{ {
tree base_binfo = TREE_VEC_ELT (binfos, i); tree base_binfo = TREE_VEC_ELT (binfos, i);
/* Find any specific instance of a virtual base, when searching with
a binfo... */
if (BINFO_MARKED (base_binfo) == 0 || TREE_CODE (parent) == TREE_VEC)
{
int via_private int via_private
= (protect = (protect
&& (is_private && (is_private
...@@ -368,32 +372,18 @@ get_base_distance_recursive (binfo, depth, is_private, rval, ...@@ -368,32 +372,18 @@ get_base_distance_recursive (binfo, depth, is_private, rval,
&& current_scope_in_chain) && current_scope_in_chain)
&& !is_friend (BINFO_TYPE (binfo), current_scope ())))); && !is_friend (BINFO_TYPE (binfo), current_scope ()))));
int this_virtual = via_virtual || TREE_VIA_VIRTUAL (base_binfo); int this_virtual = via_virtual || TREE_VIA_VIRTUAL (base_binfo);
int was;
/* When searching for a non-virtual, we cannot mark
virtually found binfos. */
if (! this_virtual)
SET_BINFO_MARKED (base_binfo);
#define WATCH_VALUES(rval, via_private) (rval == -1 ? 3 : via_private)
was = WATCH_VALUES (rval, *via_virtual_ptr);
rval = get_base_distance_recursive (base_binfo, depth, via_private, rval = get_base_distance_recursive (base_binfo, depth, via_private,
rval, rval_private_ptr, rval, rval_private_ptr,
new_binfo_ptr, parent, path_ptr, new_binfo_ptr, parent,
protect, via_virtual_ptr, protect, via_virtual_ptr,
this_virtual, this_virtual,
current_scope_in_chain); current_scope_in_chain);
/* watch for updates; only update if path is good. */
if (path_ptr && WATCH_VALUES (rval, *via_virtual_ptr) != was) /* If we've found a non-virtual, ambiguous base class, we don't need
my_friendly_assert (BINFO_INHERITANCE_CHAIN (base_binfo) == binfo, to keep searching. */
980827);
if (rval == -2 && *via_virtual_ptr == 0) if (rval == -2 && *via_virtual_ptr == 0)
return rval; return rval;
#undef WATCH_VALUES
}
} }
return rval; return rval;
...@@ -402,7 +392,7 @@ get_base_distance_recursive (binfo, depth, is_private, rval, ...@@ -402,7 +392,7 @@ get_base_distance_recursive (binfo, depth, is_private, rval,
/* Return the number of levels between type PARENT and the type given /* Return the number of levels between type PARENT and the type given
in BINFO, following the leftmost path to PARENT not found along a in BINFO, following the leftmost path to PARENT not found along a
virtual path, if there are no real PARENTs (all come from virtual virtual path, if there are no real PARENTs (all come from virtual
base classes), then follow the leftmost path to PARENT. base classes), then follow the shortest public path to PARENT.
Return -1 if TYPE is not derived from PARENT. Return -1 if TYPE is not derived from PARENT.
Return -2 if PARENT is an ambiguous base class of TYPE, and PROTECT is Return -2 if PARENT is an ambiguous base class of TYPE, and PROTECT is
...@@ -465,11 +455,9 @@ get_base_distance (parent, binfo, protect, path_ptr) ...@@ -465,11 +455,9 @@ get_base_distance (parent, binfo, protect, path_ptr)
rval = get_base_distance_recursive (binfo, 0, 0, -1, rval = get_base_distance_recursive (binfo, 0, 0, -1,
&rval_private, &new_binfo, parent, &rval_private, &new_binfo, parent,
path_ptr, watch_access, &via_virtual, 0, watch_access, &via_virtual, 0,
0); 0);
dfs_walk (binfo, dfs_unmark, markedp);
/* Access restrictions don't count if we found an ambiguous basetype. */ /* Access restrictions don't count if we found an ambiguous basetype. */
if (rval == -2 && protect >= 0) if (rval == -2 && protect >= 0)
rval_private = 0; rval_private = 0;
...@@ -477,11 +465,13 @@ get_base_distance (parent, binfo, protect, path_ptr) ...@@ -477,11 +465,13 @@ get_base_distance (parent, binfo, protect, path_ptr)
if (rval && protect && rval_private) if (rval && protect && rval_private)
return -3; return -3;
/* find real virtual base classes. */ /* If they gave us the real vbase binfo, which isn't in the main binfo
tree, deal with it. */
if (rval == -1 && TREE_CODE (parent) == TREE_VEC if (rval == -1 && TREE_CODE (parent) == TREE_VEC
&& parent == binfo_member (BINFO_TYPE (parent), && parent == binfo_member (BINFO_TYPE (parent),
CLASSTYPE_VBASECLASSES (type))) CLASSTYPE_VBASECLASSES (type)))
{ {
my_friendly_abort (980901);
my_friendly_assert (BINFO_INHERITANCE_CHAIN (parent) == binfo, 980827); my_friendly_assert (BINFO_INHERITANCE_CHAIN (parent) == binfo, 980827);
new_binfo = parent; new_binfo = parent;
rval = 1; rval = 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment