Commit 2db1ab2d by Nathan Sidwell Committed by Nathan Sidwell

cp-tree.h (UNIQUELY_DERIVED_FROM_P): Use lookup base.

cp:
	* cp-tree.h (UNIQUELY_DERIVED_FROM_P): Use lookup base.
	(ACCESSIBLY_UNIQUELY_DERIVED_FROM_P): Likewise.
	(PUBLICLY_UNIQUELY_DERIVED_FROM_P: Likewise.
	(DERIVED_FROM_P): Likewise.
	(enum base_access): Renumber, add ba_quiet bit mask.
	(get_binfo): Remove.
	(get_base_distance): Remove.
	(binfo_value): Remove.
	(ACCESSIBLY_DERIVED_FROM_P): Remove.
	* call.c (standard_conversion): Use lookup_base.
	* class.c (strictly_overrides): Likewise.
	(layout_virtual_bases): Likewise.
	(warn_about_ambiguous_direct_bases): Likewise.
	(is_base_of_enclosing_class): Likewise.
	(add_vcall_offset_vtbl_entries_1): Likewise.
	* cvt.c (build_up_reference): Adjust comment.
	* init.c (build_member_call): Reformat.
	* search.c (get_binfo): Remove.
	(get_base_distance_recursive): Remove.
	(get_base_distance): Remove.
	(lookup_base_r): Tweak.
	(lookup_base): Add ba_quiet control. Complete the types here.
	(covariant_return_p): Use lookup_base.
	* tree.c (binfo_value): Remove.
	(maybe_dummy_object): Use lookup_base.
	* typeck.c (build_static_cast): Use lookup_base.
	(get_delta_difference): Likewise.
	* typeck2.c (binfo_or_else): Use lookup_base.
	(build_scoped_ref): Add back error_mark_check.
	(build_m_component_ref): Use lookup_base.

From-SVN: r47444
parent 298d914f
2001-11-28 Nathan Sidwell <nathan@codesourcery.com>
* cp-tree.h (UNIQUELY_DERIVED_FROM_P): Use lookup base.
(ACCESSIBLY_UNIQUELY_DERIVED_FROM_P): Likewise.
(PUBLICLY_UNIQUELY_DERIVED_FROM_P: Likewise.
(DERIVED_FROM_P): Likewise.
(enum base_access): Renumber, add ba_quiet bit mask.
(get_binfo): Remove.
(get_base_distance): Remove.
(binfo_value): Remove.
(ACCESSIBLY_DERIVED_FROM_P): Remove.
* call.c (standard_conversion): Use lookup_base.
* class.c (strictly_overrides): Likewise.
(layout_virtual_bases): Likewise.
(warn_about_ambiguous_direct_bases): Likewise.
(is_base_of_enclosing_class): Likewise.
(add_vcall_offset_vtbl_entries_1): Likewise.
* cvt.c (build_up_reference): Adjust comment.
* init.c (build_member_call): Reformat.
* search.c (get_binfo): Remove.
(get_base_distance_recursive): Remove.
(get_base_distance): Remove.
(lookup_base_r): Tweak.
(lookup_base): Add ba_quiet control. Complete the types here.
(covariant_return_p): Use lookup_base.
* tree.c (binfo_value): Remove.
(maybe_dummy_object): Use lookup_base.
* typeck.c (build_static_cast): Use lookup_base.
(get_delta_difference): Likewise.
* typeck2.c (binfo_or_else): Use lookup_base.
(build_scoped_ref): Add back error_mark_check.
(build_m_component_ref): Use lookup_base.
2001-11-29 Joseph S. Myers <jsm28@cam.ac.uk> 2001-11-29 Joseph S. Myers <jsm28@cam.ac.uk>
* Make-lang.in (c++.generated-manpages): New dummy target. * Make-lang.in (c++.generated-manpages): New dummy target.
......
...@@ -787,7 +787,7 @@ standard_conversion (to, from, expr) ...@@ -787,7 +787,7 @@ standard_conversion (to, from, expr)
{ {
tree fbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (from)); tree fbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (from));
tree tbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (to)); tree tbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (to));
tree binfo = get_binfo (fbase, tbase, 1); tree binfo = lookup_base (tbase, fbase, ba_check, NULL);
if (binfo && !binfo_from_vbase (binfo) if (binfo && !binfo_from_vbase (binfo)
&& (same_type_ignoring_top_level_qualifiers_p && (same_type_ignoring_top_level_qualifiers_p
...@@ -835,7 +835,7 @@ standard_conversion (to, from, expr) ...@@ -835,7 +835,7 @@ standard_conversion (to, from, expr)
tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to)); tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to));
tree fbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fromfn))); tree fbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fromfn)));
tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn))); tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn)));
tree binfo = get_binfo (fbase, tbase, 1); tree binfo = lookup_base (tbase, fbase, ba_check, NULL);
if (!binfo || binfo_from_vbase (binfo) if (!binfo || binfo_from_vbase (binfo)
|| !same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn)) || !same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn))
......
...@@ -2669,18 +2669,21 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals) ...@@ -2669,18 +2669,21 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals)
} }
/* Here, we already know that they match in every respect. /* Here, we already know that they match in every respect.
All we have to check is where they had their declarations. */ All we have to check is where they had their declarations.
Return non-zero iff FNDECL1 is declared in a class which has a
proper base class containing FNDECL2. We don't care about
ambiguity or accessibility. */
static int static int
strictly_overrides (fndecl1, fndecl2) strictly_overrides (fndecl1, fndecl2)
tree fndecl1, fndecl2; tree fndecl1, fndecl2;
{ {
int distance = get_base_distance (DECL_CONTEXT (fndecl2), base_kind kind;
DECL_CONTEXT (fndecl1),
0, (tree *)0); return (lookup_base (DECL_CONTEXT (fndecl1), DECL_CONTEXT (fndecl2),
if (distance == -2 || distance > 0) ba_ignore | ba_quiet, &kind)
return 1; && kind != bk_same_type);
return 0;
} }
/* Get the base virtual function declarations in T that are either /* Get the base virtual function declarations in T that are either
...@@ -4677,7 +4680,7 @@ layout_virtual_bases (t, offsets) ...@@ -4677,7 +4680,7 @@ layout_virtual_bases (t, offsets)
/* Now, go through the TYPE_BINFO hierarchy, setting the /* Now, go through the TYPE_BINFO hierarchy, setting the
BINFO_OFFSETs correctly for all non-primary copies of the virtual BINFO_OFFSETs correctly for all non-primary copies of the virtual
bases and their direct and indirect bases. The ambiguity checks bases and their direct and indirect bases. The ambiguity checks
in get_base_distance depend on the BINFO_OFFSETs being set in lookup_base depend on the BINFO_OFFSETs being set
correctly. */ correctly. */
dfs_walk (TYPE_BINFO (t), dfs_set_offset_for_unshared_vbases, NULL, t); dfs_walk (TYPE_BINFO (t), dfs_set_offset_for_unshared_vbases, NULL, t);
...@@ -4703,7 +4706,8 @@ layout_virtual_bases (t, offsets) ...@@ -4703,7 +4706,8 @@ layout_virtual_bases (t, offsets)
vbases = TREE_CHAIN (vbases)) vbases = TREE_CHAIN (vbases))
{ {
tree basetype = BINFO_TYPE (TREE_VALUE (vbases)); tree basetype = BINFO_TYPE (TREE_VALUE (vbases));
if (get_base_distance (basetype, t, 0, (tree*)0) == -2)
if (!lookup_base (t, basetype, ba_ignore | ba_quiet, NULL))
cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity", cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
basetype, t); basetype, t);
} }
...@@ -4773,7 +4777,7 @@ warn_about_ambiguous_direct_bases (t) ...@@ -4773,7 +4777,7 @@ warn_about_ambiguous_direct_bases (t)
{ {
tree basetype = TYPE_BINFO_BASETYPE (t, i); tree basetype = TYPE_BINFO_BASETYPE (t, i);
if (get_base_distance (basetype, t, 0, NULL) == -2) if (!lookup_base (t, basetype, ba_ignore | ba_quiet, NULL))
cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity", cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
basetype, t); basetype, t);
} }
...@@ -6385,7 +6389,7 @@ is_base_of_enclosing_class (base, type) ...@@ -6385,7 +6389,7 @@ is_base_of_enclosing_class (base, type)
{ {
while (type) while (type)
{ {
if (get_binfo (base, type, 0)) if (lookup_base (type, base, ba_any, NULL))
return 1; return 1;
type = get_enclosing_class (type); type = get_enclosing_class (type);
...@@ -7889,7 +7893,7 @@ add_vcall_offset_vtbl_entries_1 (binfo, vid) ...@@ -7889,7 +7893,7 @@ add_vcall_offset_vtbl_entries_1 (binfo, vid)
were multiple copies, there would not be a unique final overrider were multiple copies, there would not be a unique final overrider
and vid->derived would be ill-formed. */ and vid->derived would be ill-formed. */
base = DECL_CONTEXT (fn); base = DECL_CONTEXT (fn);
base_binfo = get_binfo (base, vid->derived, /*protect=*/0); base_binfo = lookup_base (vid->derived, base, ba_any, NULL);
/* Compute the vcall offset. */ /* Compute the vcall offset. */
/* As mentioned above, the vbase we're working on is a primary base of /* As mentioned above, the vbase we're working on is a primary base of
......
...@@ -1165,13 +1165,17 @@ enum languages { lang_c, lang_cplusplus, lang_java }; ...@@ -1165,13 +1165,17 @@ enum languages { lang_c, lang_cplusplus, lang_java };
&& IS_AGGR_TYPE (TREE_TYPE (NODE))) \ && IS_AGGR_TYPE (TREE_TYPE (NODE))) \
|| IS_AGGR_TYPE (NODE)) || IS_AGGR_TYPE (NODE))
/* Nonzero iff TYPE is uniquely derived from PARENT. Under MI, PARENT can /* Nonzero iff TYPE is derived from PARENT. Ignores accessibility and
be an ambiguous base class of TYPE, and this macro will be false. */ ambiguity issues. */
#define UNIQUELY_DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) >= 0) #define DERIVED_FROM_P(PARENT, TYPE) (lookup_base (TYPE, PARENT, ba_any, NULL))
#define ACCESSIBLY_DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, -1, (tree *)0) >= 0) /* Nonzero iff TYPE is uniquely derived from PARENT. Ignores
#define ACCESSIBLY_UNIQUELY_DERIVED_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 1, (tree *)0) >= 0) accessibility. */
#define PUBLICLY_UNIQUELY_DERIVED_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 2, (tree *)0) >= 0) #define UNIQUELY_DERIVED_FROM_P(PARENT, TYPE) (lookup_base (TYPE, PARENT, ba_ignore | ba_quiet, NULL))
#define DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) != -1) /* Nonzero iff TYPE is accessible in the current scope and uniquely
derived from PARENT. */
#define ACCESSIBLY_UNIQUELY_DERIVED_P(PARENT, TYPE) (lookup_base (TYPE, PARENT, ba_check | ba_quiet, NULL))
/* Nonzero iff TYPE is publicly & uniquely derived from PARENT. */
#define PUBLICLY_UNIQUELY_DERIVED_P(PARENT, TYPE) (lookup_base (TYPE, PARENT, ba_not_special | ba_quiet, NULL))
/* This structure provides additional information above and beyond /* This structure provides additional information above and beyond
what is provide in the ordinary tree_type. In the past, we used it what is provide in the ordinary tree_type. In the past, we used it
...@@ -1551,8 +1555,7 @@ struct lang_type ...@@ -1551,8 +1555,7 @@ struct lang_type
base can be separately marked. */ base can be separately marked. */
#define BINFO_UNSHARED_MARKED(NODE) TREE_LANG_FLAG_0(NODE) #define BINFO_UNSHARED_MARKED(NODE) TREE_LANG_FLAG_0(NODE)
/* Nonzero means marked by DFS or BFS search, including searches /* Nonzero means marked by DFS or BFS search. */
by `get_binfo' and `get_base_distance'. */
#define BINFO_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED(BINFO_TYPE(NODE)):TREE_LANG_FLAG_0(NODE)) #define BINFO_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED(BINFO_TYPE(NODE)):TREE_LANG_FLAG_0(NODE))
/* Macros needed because of C compilers that don't allow conditional /* Macros needed because of C compilers that don't allow conditional
expressions to be lvalues. Grr! */ expressions to be lvalues. Grr! */
...@@ -3020,16 +3023,17 @@ typedef enum instantiate_type_flags { ...@@ -3020,16 +3023,17 @@ typedef enum instantiate_type_flags {
/* The kind of checking we can do looking in a class heirarchy. */ /* The kind of checking we can do looking in a class heirarchy. */
typedef enum base_access { typedef enum base_access {
ba_any = -2, /* Do not check access, allow an ambiguous base, ba_any = 0, /* Do not check access, allow an ambiguous base,
prefer a non-virtual base */ prefer a non-virtual base */
ba_ignore = -1, /* Do not check access */ ba_ignore = 1, /* Do not check access */
ba_check = 0, /* Check access */ ba_check = 2, /* Check access */
ba_not_special /* Do not consider special privilege ba_not_special = 3, /* Do not consider special privilege
current_class_type might give. */ current_class_type might give. */
ba_quiet = 4, /* Do not issue error messages (bit mask). */
} base_access; } base_access;
/* The kind of base we can find, looking in a class heirarchy. /* The kind of base we can find, looking in a class heirarchy.
values <0 indicate we failed. */ Values <0 indicate we failed. */
typedef enum base_kind { typedef enum base_kind {
bk_inaccessible = -3, /* The base is inaccessible */ bk_inaccessible = -3, /* The base is inaccessible */
bk_ambig = -2, /* The base is ambiguous */ bk_ambig = -2, /* The base is ambiguous */
...@@ -4005,8 +4009,6 @@ extern int emit_tinfo_decl PARAMS((tree *, void *)); ...@@ -4005,8 +4009,6 @@ extern int emit_tinfo_decl PARAMS((tree *, void *));
extern tree lookup_base PARAMS ((tree, tree, base_access, base_kind *)); extern tree lookup_base PARAMS ((tree, tree, base_access, base_kind *));
extern int types_overlap_p PARAMS ((tree, tree)); extern int types_overlap_p PARAMS ((tree, tree));
extern tree get_vbase PARAMS ((tree, tree)); extern tree get_vbase PARAMS ((tree, tree));
extern tree get_binfo PARAMS ((tree, tree, int));
extern int get_base_distance PARAMS ((tree, tree, int, tree *));
extern tree get_dynamic_cast_base_type PARAMS ((tree, tree)); extern tree get_dynamic_cast_base_type PARAMS ((tree, tree));
extern void type_access_control PARAMS ((tree, tree)); extern void type_access_control PARAMS ((tree, tree));
extern void skip_type_access_control PARAMS ((void)); extern void skip_type_access_control PARAMS ((void));
...@@ -4186,7 +4188,6 @@ extern tree hash_tree_cons PARAMS ((tree, tree, tree)); ...@@ -4186,7 +4188,6 @@ extern tree hash_tree_cons PARAMS ((tree, tree, tree));
extern tree hash_tree_chain PARAMS ((tree, tree)); extern tree hash_tree_chain PARAMS ((tree, tree));
extern tree hash_chainon PARAMS ((tree, tree)); extern tree hash_chainon PARAMS ((tree, tree));
extern tree make_binfo PARAMS ((tree, tree, tree, tree)); extern tree make_binfo PARAMS ((tree, tree, tree, tree));
extern tree binfo_value PARAMS ((tree, tree));
extern tree reverse_path PARAMS ((tree)); extern tree reverse_path PARAMS ((tree));
extern int count_functions PARAMS ((tree)); extern int count_functions PARAMS ((tree));
extern int is_overloaded_fn PARAMS ((tree)); extern int is_overloaded_fn PARAMS ((tree));
......
...@@ -401,7 +401,7 @@ build_up_reference (type, arg, flags, decl) ...@@ -401,7 +401,7 @@ build_up_reference (type, arg, flags, decl)
&& IS_AGGR_TYPE (argtype) && IS_AGGR_TYPE (argtype)
&& IS_AGGR_TYPE (target_type)) && IS_AGGR_TYPE (target_type))
{ {
/* We go through get_binfo for the access control. */ /* We go through lookup_base for the access control. */
tree binfo = lookup_base (argtype, target_type, ba_check, NULL); tree binfo = lookup_base (argtype, target_type, ba_check, NULL);
if (binfo == error_mark_node) if (binfo == error_mark_node)
return error_mark_node; return error_mark_node;
......
...@@ -1473,7 +1473,8 @@ build_member_call (type, name, parmlist) ...@@ -1473,7 +1473,8 @@ build_member_call (type, name, parmlist)
tree ns = lookup_name (type, 0); tree ns = lookup_name (type, 0);
if (ns && TREE_CODE (ns) == NAMESPACE_DECL) if (ns && TREE_CODE (ns) == NAMESPACE_DECL)
{ {
return build_x_function_call (build_offset_ref (type, name), parmlist, current_class_ref); return build_x_function_call (build_offset_ref (type, name),
parmlist, current_class_ref);
} }
} }
......
...@@ -87,12 +87,8 @@ static tree lookup_field_1 PARAMS ((tree, tree)); ...@@ -87,12 +87,8 @@ static tree lookup_field_1 PARAMS ((tree, tree));
static int is_subobject_of_p PARAMS ((tree, tree, tree)); static int is_subobject_of_p PARAMS ((tree, tree, tree));
static tree dfs_check_overlap PARAMS ((tree, void *)); static tree dfs_check_overlap PARAMS ((tree, void *));
static tree dfs_no_overlap_yet PARAMS ((tree, void *)); static tree dfs_no_overlap_yet PARAMS ((tree, void *));
static int get_base_distance_recursive
PARAMS ((tree, int, int, int, int *, tree *, tree,
int, int *, int, int));
static base_kind lookup_base_r static base_kind lookup_base_r
PARAMS ((tree, tree, base_access, PARAMS ((tree, tree, base_access, int, int, int, tree *));
int, int, int, tree *));
static int dynamic_cast_base_recurse PARAMS ((tree, tree, int, tree *)); static int dynamic_cast_base_recurse PARAMS ((tree, tree, int, tree *));
static tree marked_pushdecls_p PARAMS ((tree, void *)); static tree marked_pushdecls_p PARAMS ((tree, void *));
static tree unmarked_pushdecls_p PARAMS ((tree, void *)); static tree unmarked_pushdecls_p PARAMS ((tree, void *));
...@@ -171,237 +167,6 @@ static int n_contexts_saved; ...@@ -171,237 +167,6 @@ static int n_contexts_saved;
#endif /* GATHER_STATISTICS */ #endif /* GATHER_STATISTICS */
/* Check whether the type given in BINFO is derived from PARENT. If
it isn't, return 0. If it is, but the derivation is MI-ambiguous
AND protect != 0, emit an error message and return error_mark_node.
Otherwise, if TYPE is derived from PARENT, return the actual base
information, unless a one of the protection violations below
occurs, in which case emit an error message and return error_mark_node.
If PROTECT is 1, then check if access to a public field of PARENT
would be private. Also check for ambiguity. */
tree
get_binfo (parent, binfo, protect)
register tree parent, binfo;
int protect;
{
tree type = NULL_TREE;
int dist;
tree rval = NULL_TREE;
if (TREE_CODE (parent) == TREE_VEC)
parent = BINFO_TYPE (parent);
else if (! IS_AGGR_TYPE_CODE (TREE_CODE (parent)))
my_friendly_abort (89);
if (TREE_CODE (binfo) == TREE_VEC)
type = BINFO_TYPE (binfo);
else if (IS_AGGR_TYPE_CODE (TREE_CODE (binfo)))
type = binfo;
else
my_friendly_abort (90);
dist = get_base_distance (parent, binfo, protect, &rval);
if (dist == -3)
{
cp_error ("fields of `%T' are inaccessible in `%T' due to private inheritance",
parent, type);
return error_mark_node;
}
else if (dist == -2 && protect)
{
cp_error ("type `%T' is ambiguous base class for type `%T'", parent,
type);
return error_mark_node;
}
return rval;
}
/* This is the newer depth first get_base_distance routine. */
static int
get_base_distance_recursive (binfo, depth, is_private, rval,
rval_private_ptr, new_binfo_ptr, parent,
protect, via_virtual_ptr, via_virtual,
current_scope_in_chain)
tree binfo;
int depth, is_private, rval;
int *rval_private_ptr;
tree *new_binfo_ptr, parent;
int protect, *via_virtual_ptr, via_virtual;
int current_scope_in_chain;
{
tree binfos;
int i, n_baselinks;
if (protect == 1
&& !current_scope_in_chain
&& is_friend (BINFO_TYPE (binfo), current_scope ()))
current_scope_in_chain = 1;
if (BINFO_TYPE (binfo) == parent || binfo == parent)
{
int better = 0;
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)
{
/* A new path to the same vbase. If this one has better
access or is shorter, take it. */
if (protect)
better = *rval_private_ptr - is_private;
if (better == 0)
better = rval - depth;
}
else
{
/* Ambiguous base class. */
rval = depth = -2;
/* If we get an ambiguity between virtual and non-virtual base
class, return the non-virtual in case we are ignoring
ambiguity. */
better = *via_virtual_ptr - via_virtual;
}
if (better > 0)
{
rval = depth;
*rval_private_ptr = is_private;
*new_binfo_ptr = binfo;
*via_virtual_ptr = via_virtual;
}
return rval;
}
binfos = BINFO_BASETYPES (binfo);
n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
depth += 1;
/* Process base types. */
for (i = 0; i < n_baselinks; i++)
{
tree base_binfo = TREE_VEC_ELT (binfos, i);
int via_private
= ((protect == 1
&& (is_private
|| (!TREE_VIA_PUBLIC (base_binfo)
&& !(TREE_VIA_PROTECTED (base_binfo)
&& current_scope_in_chain)
&& !is_friend (BINFO_TYPE (binfo), current_scope ()))))
|| (protect > 1
&& (is_private || !TREE_VIA_PUBLIC (base_binfo))));
int this_virtual = via_virtual || TREE_VIA_VIRTUAL (base_binfo);
rval = get_base_distance_recursive (base_binfo, depth, via_private,
rval, rval_private_ptr,
new_binfo_ptr, parent,
protect, via_virtual_ptr,
this_virtual,
current_scope_in_chain);
/* If we've found a non-virtual, ambiguous base class, we don't need
to keep searching. */
if (rval == -2 && *via_virtual_ptr == 0)
return rval;
}
return rval;
}
/* Return the number of levels between type PARENT and the type given
in BINFO, following the leftmost path to PARENT not found along a
virtual path, if there are no real PARENTs (all come from virtual
base classes), then follow the shortest public path to PARENT.
Return -1 if TYPE is not derived from PARENT.
Return -2 if PARENT is an ambiguous base class of TYPE, and PROTECT is
non-negative.
Return -3 if PARENT is not accessible in TYPE, and PROTECT is non-zero.
If PATH_PTR is non-NULL, then also build the list of types
from PARENT to TYPE, with TREE_VIA_VIRTUAL and TREE_VIA_PUBLIC
set.
If PROTECT is greater than 1, ignore any special access the current
scope might have when determining whether PARENT is inaccessible.
If BINFO is a binfo, its BINFO_INHERITANCE_CHAIN will be left alone. */
int
get_base_distance (parent, binfo, protect, path_ptr)
register tree parent, binfo;
int protect;
tree *path_ptr;
{
int rval;
int rval_private = 0;
tree type = NULL_TREE;
tree new_binfo = NULL_TREE;
int via_virtual;
int watch_access = protect;
/* Should we be completing types here? */
if (TREE_CODE (parent) != TREE_VEC)
parent = complete_type (TYPE_MAIN_VARIANT (parent));
else
complete_type (TREE_TYPE (parent));
if (TREE_CODE (binfo) == TREE_VEC)
type = BINFO_TYPE (binfo);
else if (IS_AGGR_TYPE_CODE (TREE_CODE (binfo)))
{
type = complete_type (binfo);
binfo = TYPE_BINFO (type);
if (path_ptr)
my_friendly_assert (BINFO_INHERITANCE_CHAIN (binfo) == NULL_TREE,
980827);
}
else
my_friendly_abort (92);
if (parent == type || parent == binfo)
{
/* If the distance is 0, then we don't really need
a path pointer, but we shouldn't let garbage go back. */
if (path_ptr)
*path_ptr = binfo;
return 0;
}
if (path_ptr && watch_access == 0)
watch_access = 1;
rval = get_base_distance_recursive (binfo, 0, 0, -1,
&rval_private, &new_binfo, parent,
watch_access, &via_virtual, 0,
0);
/* Access restrictions don't count if we found an ambiguous basetype. */
if (rval == -2 && protect >= 0)
rval_private = 0;
if (rval && protect && rval_private)
return -3;
if (path_ptr)
*path_ptr = new_binfo;
return rval;
}
/* Worker for lookup_base. BINFO is the binfo we are searching at, /* Worker for lookup_base. BINFO is the binfo we are searching at,
BASE is the RECORD_TYPE we are searching for. ACCESS is the BASE is the RECORD_TYPE we are searching for. ACCESS is the
required access checks. WITHIN_CURRENT_SCOPE, IS_NON_PUBLIC and required access checks. WITHIN_CURRENT_SCOPE, IS_NON_PUBLIC and
...@@ -457,13 +222,11 @@ lookup_base_r (binfo, base, access, within_current_scope, ...@@ -457,13 +222,11 @@ lookup_base_r (binfo, base, access, within_current_scope,
{ {
if (access != ba_any) if (access != ba_any)
*binfo_ptr = NULL; *binfo_ptr = NULL;
else if (found != is_virtual) else if (!is_virtual)
/* Prefer a non-virtual base. */ /* Prefer a non-virtual base. */
*binfo_ptr = binfo; *binfo_ptr = binfo;
found = bk_ambig; found = bk_ambig;
} }
else if (found == bk_via_virtual)
*binfo_ptr = binfo;
return found; return found;
} }
...@@ -525,10 +288,8 @@ lookup_base_r (binfo, base, access, within_current_scope, ...@@ -525,10 +288,8 @@ lookup_base_r (binfo, base, access, within_current_scope,
break; break;
case bk_via_virtual: case bk_via_virtual:
my_friendly_assert (found == bk_not_base if (found != bk_ambig)
|| found == bk_via_virtual found = bk;
|| found == bk_inaccessible, 20010723);
found = bk;
break; break;
case bk_not_base: case bk_not_base:
...@@ -541,10 +302,10 @@ lookup_base_r (binfo, base, access, within_current_scope, ...@@ -541,10 +302,10 @@ lookup_base_r (binfo, base, access, within_current_scope,
/* Lookup BASE in the hierarchy dominated by T. Do access checking as /* Lookup BASE in the hierarchy dominated by T. Do access checking as
ACCESS specifies. Return the binfo we discover (which might not be ACCESS specifies. Return the binfo we discover (which might not be
canonical). If KIND_PTR is non-NULL, fill with information about canonical). If KIND_PTR is non-NULL, fill with information about
what kind of base we discoveded. what kind of base we discovered.
Issue an error message if an inaccessible or ambiguous base is If ba_quiet bit is set in ACCESS, then do not issue an error, and
discovered, and return error_mark_node. */ return NULL_TREE for failure. */
tree tree
lookup_base (t, base, access, kind_ptr) lookup_base (t, base, access, kind_ptr)
...@@ -554,33 +315,43 @@ lookup_base (t, base, access, kind_ptr) ...@@ -554,33 +315,43 @@ lookup_base (t, base, access, kind_ptr)
{ {
tree binfo = NULL; /* The binfo we've found so far. */ tree binfo = NULL; /* The binfo we've found so far. */
base_kind bk; base_kind bk;
if (t == error_mark_node || base == error_mark_node) if (t == error_mark_node || base == error_mark_node)
{ {
if (kind_ptr) if (kind_ptr)
*kind_ptr = bk_not_base; *kind_ptr = bk_not_base;
return error_mark_node; return error_mark_node;
} }
my_friendly_assert (TYPE_P (t) && TYPE_P (base), 20011127);
t = TYPE_MAIN_VARIANT (t); /* Ensure that the types are instantiated. */
base = TYPE_MAIN_VARIANT (base); t = complete_type (TYPE_MAIN_VARIANT (t));
base = complete_type (TYPE_MAIN_VARIANT (base));
bk = lookup_base_r (TYPE_BINFO (t), base, access, 0, 0, 0, &binfo); bk = lookup_base_r (TYPE_BINFO (t), base, access & ~ba_quiet,
0, 0, 0, &binfo);
switch (bk) switch (bk)
{ {
case bk_inaccessible: case bk_inaccessible:
cp_error ("`%T' is an inaccessible base of `%T'", base, t); binfo = NULL_TREE;
binfo = error_mark_node; if (!(access & ba_quiet))
{
cp_error ("`%T' is an inaccessible base of `%T'", base, t);
binfo = error_mark_node;
}
break; break;
case bk_ambig: case bk_ambig:
if (access != ba_any) if (access != ba_any)
{ {
cp_error ("`%T' is an ambiguous base of `%T'", base, t); binfo = NULL_TREE;
binfo = error_mark_node; if (!(access & ba_quiet))
{
cp_error ("`%T' is an ambiguous base of `%T'", base, t);
binfo = error_mark_node;
}
} }
break; break;
default:; default:;
} }
...@@ -1991,6 +1762,7 @@ covariant_return_p (brettype, drettype) ...@@ -1991,6 +1762,7 @@ covariant_return_p (brettype, drettype)
tree brettype, drettype; tree brettype, drettype;
{ {
tree binfo; tree binfo;
base_kind kind;
if (TREE_CODE (brettype) == FUNCTION_DECL) if (TREE_CODE (brettype) == FUNCTION_DECL)
{ {
...@@ -2022,16 +1794,13 @@ covariant_return_p (brettype, drettype) ...@@ -2022,16 +1794,13 @@ covariant_return_p (brettype, drettype)
if (! IS_AGGR_TYPE (drettype) || ! IS_AGGR_TYPE (brettype)) if (! IS_AGGR_TYPE (drettype) || ! IS_AGGR_TYPE (brettype))
return -1; return -1;
binfo = get_binfo (brettype, drettype, 1); binfo = lookup_base (drettype, brettype, ba_check | ba_quiet, &kind);
/* If we get an error_mark_node from get_binfo, it already complained, if (!binfo)
so let's just succeed. */ return 0;
if (binfo == error_mark_node) if (BINFO_OFFSET_ZEROP (binfo) && kind != bk_via_virtual)
return 1; return 1;
return 2;
if (! BINFO_OFFSET_ZEROP (binfo) || TREE_VIA_VIRTUAL (binfo))
return 2;
return 1;
} }
/* Check that virtual overrider OVERRIDER is acceptable for base function /* Check that virtual overrider OVERRIDER is acceptable for base function
......
...@@ -827,23 +827,6 @@ make_binfo (offset, binfo, vtable, virtuals) ...@@ -827,23 +827,6 @@ make_binfo (offset, binfo, vtable, virtuals)
return new_binfo; return new_binfo;
} }
/* Return the binfo value for ELEM in TYPE. */
tree
binfo_value (elem, type)
tree elem;
tree type;
{
if (get_base_distance (elem, type, 0, (tree *)0) == -2)
compiler_error ("base class `%s' ambiguous in binfo_value",
TYPE_NAME_STRING (elem));
if (elem == type)
return TYPE_BINFO (type);
if (TREE_CODE (elem) == RECORD_TYPE && TYPE_BINFO (elem) == type)
return type;
return get_binfo (elem, type, 0);
}
/* Return a TREE_LIST whose TREE_VALUE nodes along the /* Return a TREE_LIST whose TREE_VALUE nodes along the
BINFO_INHERITANCE_CHAIN for BINFO, but in the opposite order. In BINFO_INHERITANCE_CHAIN for BINFO, but in the opposite order. In
other words, while the BINFO_INHERITANCE_CHAIN goes from base other words, while the BINFO_INHERITANCE_CHAIN goes from base
...@@ -1833,18 +1816,22 @@ maybe_dummy_object (type, binfop) ...@@ -1833,18 +1816,22 @@ maybe_dummy_object (type, binfop)
tree *binfop; tree *binfop;
{ {
tree decl, context; tree decl, context;
tree binfo;
if (current_class_type if (current_class_type
&& get_base_distance (type, current_class_type, 0, binfop) != -1) && (binfo = lookup_base (current_class_type, type,
ba_ignore | ba_quiet, NULL)))
context = current_class_type; context = current_class_type;
else else
{ {
/* Reference from a nested class member function. */ /* Reference from a nested class member function. */
context = type; context = type;
if (binfop) binfo = TYPE_BINFO (type);
*binfop = TYPE_BINFO (type);
} }
if (binfop)
*binfop = binfo;
if (current_class_ref && context == current_class_type) if (current_class_ref && context == current_class_type)
decl = current_class_ref; decl = current_class_ref;
else else
......
...@@ -5114,12 +5114,12 @@ build_static_cast (type, expr) ...@@ -5114,12 +5114,12 @@ build_static_cast (type, expr)
{ {
/* They're pointers to objects. They must be aggregates that /* They're pointers to objects. They must be aggregates that
are related non-virtually. */ are related non-virtually. */
base_kind kind;
tree binfo;
if (IS_AGGR_TYPE (TREE_TYPE (type)) && IS_AGGR_TYPE (TREE_TYPE (intype)) if (IS_AGGR_TYPE (TREE_TYPE (type)) && IS_AGGR_TYPE (TREE_TYPE (intype))
&& (binfo = get_binfo (TREE_TYPE (intype), TREE_TYPE (type), 0)) && lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
&& !binfo_from_vbase (binfo)) ba_ignore | ba_quiet, &kind)
&& kind != bk_via_virtual)
ok = 1; ok = 1;
} }
else if (TREE_CODE (intype) != BOOLEAN_TYPE else if (TREE_CODE (intype) != BOOLEAN_TYPE
...@@ -5933,21 +5933,15 @@ get_delta_difference (from, to, force) ...@@ -5933,21 +5933,15 @@ get_delta_difference (from, to, force)
tree delta = integer_zero_node; tree delta = integer_zero_node;
tree binfo; tree binfo;
tree virt_binfo; tree virt_binfo;
base_kind kind;
if (to == from) binfo = lookup_base (to, from, ba_check, &kind);
return delta; if (kind == bk_inaccessible || kind == bk_ambig)
/* Should get_base_distance here, so we can check if any thing along
the path is virtual, and we need to make sure we stay inside the
real binfos when going through virtual bases. Maybe we should
replace virtual bases with BINFO_FOR_VBASE ... (mrs) */
binfo = get_binfo (from, to, 1);
if (binfo == error_mark_node)
{ {
error (" in pointer to member function conversion"); error (" in pointer to member function conversion");
return delta; return delta;
} }
if (binfo == 0) if (!binfo)
{ {
if (!force) if (!force)
{ {
...@@ -5955,8 +5949,8 @@ get_delta_difference (from, to, force) ...@@ -5955,8 +5949,8 @@ get_delta_difference (from, to, force)
error (" in pointer to member conversion"); error (" in pointer to member conversion");
return delta; return delta;
} }
binfo = get_binfo (to, from, 1); binfo = lookup_base (from, to, ba_check, &kind);
if (binfo == 0 || binfo == error_mark_node) if (binfo == 0)
return delta; return delta;
virt_binfo = binfo_from_vbase (binfo); virt_binfo = binfo_from_vbase (binfo);
......
...@@ -56,20 +56,16 @@ error_not_base_type (basetype, type) ...@@ -56,20 +56,16 @@ error_not_base_type (basetype, type)
} }
tree tree
binfo_or_else (parent_or_type, type) binfo_or_else (base, type)
tree parent_or_type, type; tree base, type;
{ {
tree binfo; tree binfo = lookup_base (type, base, ba_ignore, NULL);
if (TYPE_MAIN_VARIANT (parent_or_type) == TYPE_MAIN_VARIANT (type))
return TYPE_BINFO (parent_or_type); if (binfo == error_mark_node)
if ((binfo = get_binfo (parent_or_type, TYPE_MAIN_VARIANT (type), 0))) return NULL_TREE;
{ else if (!binfo)
if (binfo == error_mark_node) error_not_base_type (base, type);
return NULL_TREE; return binfo;
return binfo;
}
error_not_base_type (parent_or_type, type);
return NULL_TREE;
} }
/* According to ARM $7.1.6, "A `const' object may be initialized, but its /* According to ARM $7.1.6, "A `const' object may be initialized, but its
...@@ -1003,6 +999,8 @@ build_scoped_ref (datum, basetype) ...@@ -1003,6 +999,8 @@ build_scoped_ref (datum, basetype)
return error_mark_node; return error_mark_node;
binfo = lookup_base (TREE_TYPE (datum), basetype, ba_check, NULL); binfo = lookup_base (TREE_TYPE (datum), basetype, ba_check, NULL);
if (binfo == error_mark_node)
return error_mark_node;
if (!binfo) if (!binfo)
return error_not_base_type (TREE_TYPE (datum), basetype); return error_not_base_type (TREE_TYPE (datum), basetype);
...@@ -1145,8 +1143,9 @@ build_m_component_ref (datum, component) ...@@ -1145,8 +1143,9 @@ build_m_component_ref (datum, component)
return error_mark_node; return error_mark_node;
} }
binfo = get_binfo (TYPE_METHOD_BASETYPE (type), objtype, 1); binfo = lookup_base (objtype, TYPE_METHOD_BASETYPE (type),
if (binfo == NULL_TREE) ba_check, NULL);
if (!binfo)
{ {
cp_error ("member type `%T::' incompatible with object type `%T'", cp_error ("member type `%T::' incompatible with object type `%T'",
TYPE_METHOD_BASETYPE (type), objtype); TYPE_METHOD_BASETYPE (type), objtype);
......
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