OSDN Git Service

cp:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 29 Nov 2001 17:15:56 +0000 (17:15 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 29 Nov 2001 17:15:56 +0000 (17:15 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@47444 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/init.c
gcc/cp/search.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c

index 7125e6f..029b0e8 100644 (file)
@@ -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.
index eea7f7e..fc1395c 100644 (file)
@@ -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))
index 3afaf5d..97a9da4 100644 (file)
@@ -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
index f82e4fe..b7cfa70 100644 (file)
@@ -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))
 \f
 /* 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));
index e2b9f39..6eb0a7a 100644 (file)
@@ -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;
index 75ba05a..06c1c43 100644 (file)
@@ -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);
        }
     }
 
index 87ebddb..6e5e2e5 100644 (file)
@@ -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 */
 
 \f
-/* 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
index ae4c375..99d2eab 100644 (file)
@@ -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
index ddd4fc7..c3d888c 100644 (file)
@@ -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);
       
index 39e0479..37252ee 100644 (file)
@@ -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);