diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2001-11-29 17:15:56 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2001-11-29 17:15:56 +0000 |
commit | 2db1ab2d04e6a7a31595eee66b1e2177ce3e3fc6 (patch) | |
tree | 624478b68ddb523b54c5fed43f98606f42633e04 /gcc | |
parent | 298d914f05b115f26f7e40895f273dfa4fcb7388 (diff) | |
download | gcc-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/ChangeLog | 33 | ||||
-rw-r--r-- | gcc/cp/call.c | 4 | ||||
-rw-r--r-- | gcc/cp/class.c | 28 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 37 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 2 | ||||
-rw-r--r-- | gcc/cp/init.c | 3 | ||||
-rw-r--r-- | gcc/cp/search.c | 297 | ||||
-rw-r--r-- | gcc/cp/tree.c | 29 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 26 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 29 |
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); |