aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2001-11-29 17:15:56 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2001-11-29 17:15:56 +0000
commit2db1ab2d04e6a7a31595eee66b1e2177ce3e3fc6 (patch)
tree624478b68ddb523b54c5fed43f98606f42633e04 /gcc
parent298d914f05b115f26f7e40895f273dfa4fcb7388 (diff)
downloadgcc-2db1ab2d04e6a7a31595eee66b1e2177ce3e3fc6.zip
gcc-2db1ab2d04e6a7a31595eee66b1e2177ce3e3fc6.tar.gz
gcc-2db1ab2d04e6a7a31595eee66b1e2177ce3e3fc6.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog33
-rw-r--r--gcc/cp/call.c4
-rw-r--r--gcc/cp/class.c28
-rw-r--r--gcc/cp/cp-tree.h37
-rw-r--r--gcc/cp/cvt.c2
-rw-r--r--gcc/cp/init.c3
-rw-r--r--gcc/cp/search.c297
-rw-r--r--gcc/cp/tree.c29
-rw-r--r--gcc/cp/typeck.c26
-rw-r--r--gcc/cp/typeck2.c29
10 files changed, 138 insertions, 350 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7125e6f..029b0e8 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,36 @@
+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>
* Make-lang.in (c++.generated-manpages): New dummy target.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index eea7f7e8..fc1395c 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -787,7 +787,7 @@ standard_conversion (to, from, expr)
{
tree fbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (from));
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)
&& (same_type_ignoring_top_level_qualifiers_p
@@ -835,7 +835,7 @@ standard_conversion (to, from, expr)
tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to));
tree fbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fromfn)));
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)
|| !same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn))
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 3afaf5d..97a9da4 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -2669,18 +2669,21 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals)
}
/* 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
strictly_overrides (fndecl1, fndecl2)
tree fndecl1, fndecl2;
{
- int distance = get_base_distance (DECL_CONTEXT (fndecl2),
- DECL_CONTEXT (fndecl1),
- 0, (tree *)0);
- if (distance == -2 || distance > 0)
- return 1;
- return 0;
+ base_kind kind;
+
+ return (lookup_base (DECL_CONTEXT (fndecl1), DECL_CONTEXT (fndecl2),
+ ba_ignore | ba_quiet, &kind)
+ && kind != bk_same_type);
}
/* Get the base virtual function declarations in T that are either
@@ -4677,7 +4680,7 @@ layout_virtual_bases (t, offsets)
/* Now, go through the TYPE_BINFO hierarchy, setting the
BINFO_OFFSETs correctly for all non-primary copies of the virtual
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. */
dfs_walk (TYPE_BINFO (t), dfs_set_offset_for_unshared_vbases, NULL, t);
@@ -4703,7 +4706,8 @@ layout_virtual_bases (t, offsets)
vbases = TREE_CHAIN (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",
basetype, t);
}
@@ -4773,7 +4777,7 @@ warn_about_ambiguous_direct_bases (t)
{
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",
basetype, t);
}
@@ -6385,7 +6389,7 @@ is_base_of_enclosing_class (base, type)
{
while (type)
{
- if (get_binfo (base, type, 0))
+ if (lookup_base (type, base, ba_any, NULL))
return 1;
type = get_enclosing_class (type);
@@ -7889,7 +7893,7 @@ add_vcall_offset_vtbl_entries_1 (binfo, vid)
were multiple copies, there would not be a unique final overrider
and vid->derived would be ill-formed. */
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. */
/* As mentioned above, the vbase we're working on is a primary base of
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f82e4fe..b7cfa70 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1165,13 +1165,17 @@ enum languages { lang_c, lang_cplusplus, lang_java };
&& IS_AGGR_TYPE (TREE_TYPE (NODE))) \
|| IS_AGGR_TYPE (NODE))
-/* Nonzero iff TYPE is uniquely derived from PARENT. Under MI, PARENT can
- be an ambiguous base class of TYPE, and this macro will be false. */
-#define UNIQUELY_DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) >= 0)
-#define ACCESSIBLY_DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, -1, (tree *)0) >= 0)
-#define ACCESSIBLY_UNIQUELY_DERIVED_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 1, (tree *)0) >= 0)
-#define PUBLICLY_UNIQUELY_DERIVED_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 2, (tree *)0) >= 0)
-#define DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) != -1)
+/* Nonzero iff TYPE is derived from PARENT. Ignores accessibility and
+ ambiguity issues. */
+#define DERIVED_FROM_P(PARENT, TYPE) (lookup_base (TYPE, PARENT, ba_any, NULL))
+/* Nonzero iff TYPE is uniquely derived from PARENT. Ignores
+ accessibility. */
+#define UNIQUELY_DERIVED_FROM_P(PARENT, TYPE) (lookup_base (TYPE, PARENT, ba_ignore | ba_quiet, NULL))
+/* 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
what is provide in the ordinary tree_type. In the past, we used it
@@ -1551,8 +1555,7 @@ struct lang_type
base can be separately marked. */
#define BINFO_UNSHARED_MARKED(NODE) TREE_LANG_FLAG_0(NODE)
-/* Nonzero means marked by DFS or BFS search, including searches
- by `get_binfo' and `get_base_distance'. */
+/* Nonzero means marked by DFS or BFS search. */
#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
expressions to be lvalues. Grr! */
@@ -3020,16 +3023,17 @@ typedef enum instantiate_type_flags {
/* The kind of checking we can do looking in a class heirarchy. */
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 */
- ba_ignore = -1, /* Do not check access */
- ba_check = 0, /* Check access */
- ba_not_special /* Do not consider special privilege
- current_class_type might give. */
+ ba_ignore = 1, /* Do not check access */
+ ba_check = 2, /* Check access */
+ ba_not_special = 3, /* Do not consider special privilege
+ current_class_type might give. */
+ ba_quiet = 4, /* Do not issue error messages (bit mask). */
} base_access;
/* 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 {
bk_inaccessible = -3, /* The base is inaccessible */
bk_ambig = -2, /* The base is ambiguous */
@@ -4005,8 +4009,6 @@ extern int emit_tinfo_decl PARAMS((tree *, void *));
extern tree lookup_base PARAMS ((tree, tree, base_access, base_kind *));
extern int types_overlap_p 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 void type_access_control PARAMS ((tree, tree));
extern void skip_type_access_control PARAMS ((void));
@@ -4186,7 +4188,6 @@ extern tree hash_tree_cons PARAMS ((tree, tree, tree));
extern tree hash_tree_chain PARAMS ((tree, tree));
extern tree hash_chainon PARAMS ((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 int count_functions PARAMS ((tree));
extern int is_overloaded_fn PARAMS ((tree));
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index e2b9f39..6eb0a7a 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -401,7 +401,7 @@ build_up_reference (type, arg, flags, decl)
&& IS_AGGR_TYPE (argtype)
&& 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);
if (binfo == error_mark_node)
return error_mark_node;
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 75ba05a..06c1c43 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1473,7 +1473,8 @@ build_member_call (type, name, parmlist)
tree ns = lookup_name (type, 0);
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);
}
}
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 87ebddb..6e5e2e5 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -87,12 +87,8 @@ static tree lookup_field_1 PARAMS ((tree, tree));
static int is_subobject_of_p PARAMS ((tree, tree, tree));
static tree dfs_check_overlap 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
- PARAMS ((tree, tree, base_access,
- int, int, int, tree *));
+ PARAMS ((tree, tree, base_access, int, int, int, tree *));
static int dynamic_cast_base_recurse PARAMS ((tree, tree, int, tree *));
static tree marked_pushdecls_p PARAMS ((tree, void *));
static tree unmarked_pushdecls_p PARAMS ((tree, void *));
@@ -171,237 +167,6 @@ static int n_contexts_saved;
#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,
BASE is the RECORD_TYPE we are searching for. ACCESS is the
required access checks. WITHIN_CURRENT_SCOPE, IS_NON_PUBLIC and
@@ -457,13 +222,11 @@ lookup_base_r (binfo, base, access, within_current_scope,
{
if (access != ba_any)
*binfo_ptr = NULL;
- else if (found != is_virtual)
+ else if (!is_virtual)
/* Prefer a non-virtual base. */
*binfo_ptr = binfo;
found = bk_ambig;
}
- else if (found == bk_via_virtual)
- *binfo_ptr = binfo;
return found;
}
@@ -525,10 +288,8 @@ lookup_base_r (binfo, base, access, within_current_scope,
break;
case bk_via_virtual:
- my_friendly_assert (found == bk_not_base
- || found == bk_via_virtual
- || found == bk_inaccessible, 20010723);
- found = bk;
+ if (found != bk_ambig)
+ found = bk;
break;
case bk_not_base:
@@ -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
ACCESS specifies. Return the binfo we discover (which might not be
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
- discovered, and return error_mark_node. */
+ If ba_quiet bit is set in ACCESS, then do not issue an error, and
+ return NULL_TREE for failure. */
tree
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. */
base_kind bk;
-
+
if (t == error_mark_node || base == error_mark_node)
{
if (kind_ptr)
*kind_ptr = bk_not_base;
return error_mark_node;
}
+ my_friendly_assert (TYPE_P (t) && TYPE_P (base), 20011127);
- t = TYPE_MAIN_VARIANT (t);
- base = TYPE_MAIN_VARIANT (base);
+ /* Ensure that the types are instantiated. */
+ 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)
{
case bk_inaccessible:
- cp_error ("`%T' is an inaccessible base of `%T'", base, t);
- binfo = error_mark_node;
+ binfo = NULL_TREE;
+ if (!(access & ba_quiet))
+ {
+ cp_error ("`%T' is an inaccessible base of `%T'", base, t);
+ binfo = error_mark_node;
+ }
break;
case bk_ambig:
if (access != ba_any)
{
- cp_error ("`%T' is an ambiguous base of `%T'", base, t);
- binfo = error_mark_node;
+ binfo = NULL_TREE;
+ if (!(access & ba_quiet))
+ {
+ cp_error ("`%T' is an ambiguous base of `%T'", base, t);
+ binfo = error_mark_node;
+ }
}
break;
-
default:;
}
@@ -1991,6 +1762,7 @@ covariant_return_p (brettype, drettype)
tree brettype, drettype;
{
tree binfo;
+ base_kind kind;
if (TREE_CODE (brettype) == FUNCTION_DECL)
{
@@ -2022,16 +1794,13 @@ covariant_return_p (brettype, drettype)
if (! IS_AGGR_TYPE (drettype) || ! IS_AGGR_TYPE (brettype))
return -1;
- binfo = get_binfo (brettype, drettype, 1);
-
- /* If we get an error_mark_node from get_binfo, it already complained,
- so let's just succeed. */
- if (binfo == error_mark_node)
+ binfo = lookup_base (drettype, brettype, ba_check | ba_quiet, &kind);
+
+ if (!binfo)
+ return 0;
+ if (BINFO_OFFSET_ZEROP (binfo) && kind != bk_via_virtual)
return 1;
-
- if (! BINFO_OFFSET_ZEROP (binfo) || TREE_VIA_VIRTUAL (binfo))
- return 2;
- return 1;
+ return 2;
}
/* Check that virtual overrider OVERRIDER is acceptable for base function
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index ae4c375..99d2eab 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -827,23 +827,6 @@ make_binfo (offset, binfo, vtable, virtuals)
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
BINFO_INHERITANCE_CHAIN for BINFO, but in the opposite order. In
other words, while the BINFO_INHERITANCE_CHAIN goes from base
@@ -1833,18 +1816,22 @@ maybe_dummy_object (type, binfop)
tree *binfop;
{
tree decl, context;
-
+ tree binfo;
+
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;
else
{
/* Reference from a nested class member function. */
context = type;
- if (binfop)
- *binfop = TYPE_BINFO (type);
+ binfo = TYPE_BINFO (type);
}
+ if (binfop)
+ *binfop = binfo;
+
if (current_class_ref && context == current_class_type)
decl = current_class_ref;
else
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index ddd4fc7..c3d888c 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -5114,12 +5114,12 @@ build_static_cast (type, expr)
{
/* They're pointers to objects. They must be aggregates that
are related non-virtually. */
-
- tree binfo;
+ base_kind kind;
if (IS_AGGR_TYPE (TREE_TYPE (type)) && IS_AGGR_TYPE (TREE_TYPE (intype))
- && (binfo = get_binfo (TREE_TYPE (intype), TREE_TYPE (type), 0))
- && !binfo_from_vbase (binfo))
+ && lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
+ ba_ignore | ba_quiet, &kind)
+ && kind != bk_via_virtual)
ok = 1;
}
else if (TREE_CODE (intype) != BOOLEAN_TYPE
@@ -5933,21 +5933,15 @@ get_delta_difference (from, to, force)
tree delta = integer_zero_node;
tree binfo;
tree virt_binfo;
+ base_kind kind;
- if (to == from)
- return delta;
-
- /* 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)
+ binfo = lookup_base (to, from, ba_check, &kind);
+ if (kind == bk_inaccessible || kind == bk_ambig)
{
error (" in pointer to member function conversion");
return delta;
}
- if (binfo == 0)
+ if (!binfo)
{
if (!force)
{
@@ -5955,8 +5949,8 @@ get_delta_difference (from, to, force)
error (" in pointer to member conversion");
return delta;
}
- binfo = get_binfo (to, from, 1);
- if (binfo == 0 || binfo == error_mark_node)
+ binfo = lookup_base (from, to, ba_check, &kind);
+ if (binfo == 0)
return delta;
virt_binfo = binfo_from_vbase (binfo);
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 39e0479..37252ee 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -56,20 +56,16 @@ error_not_base_type (basetype, type)
}
tree
-binfo_or_else (parent_or_type, type)
- tree parent_or_type, type;
+binfo_or_else (base, type)
+ tree base, type;
{
- tree binfo;
- if (TYPE_MAIN_VARIANT (parent_or_type) == TYPE_MAIN_VARIANT (type))
- return TYPE_BINFO (parent_or_type);
- if ((binfo = get_binfo (parent_or_type, TYPE_MAIN_VARIANT (type), 0)))
- {
- if (binfo == error_mark_node)
- return NULL_TREE;
- return binfo;
- }
- error_not_base_type (parent_or_type, type);
- return NULL_TREE;
+ tree binfo = lookup_base (type, base, ba_ignore, NULL);
+
+ if (binfo == error_mark_node)
+ return NULL_TREE;
+ else if (!binfo)
+ error_not_base_type (base, type);
+ return binfo;
}
/* According to ARM $7.1.6, "A `const' object may be initialized, but its
@@ -1003,6 +999,8 @@ build_scoped_ref (datum, basetype)
return error_mark_node;
binfo = lookup_base (TREE_TYPE (datum), basetype, ba_check, NULL);
+ if (binfo == error_mark_node)
+ return error_mark_node;
if (!binfo)
return error_not_base_type (TREE_TYPE (datum), basetype);
@@ -1145,8 +1143,9 @@ build_m_component_ref (datum, component)
return error_mark_node;
}
- binfo = get_binfo (TYPE_METHOD_BASETYPE (type), objtype, 1);
- if (binfo == NULL_TREE)
+ binfo = lookup_base (objtype, TYPE_METHOD_BASETYPE (type),
+ ba_check, NULL);
+ if (!binfo)
{
cp_error ("member type `%T::' incompatible with object type `%T'",
TYPE_METHOD_BASETYPE (type), objtype);