OSDN Git Service

Implement class scope using-declarations for functions.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 27 Feb 2000 06:54:04 +0000 (06:54 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 27 Feb 2000 06:54:04 +0000 (06:54 +0000)
        * class.c (handle_using_decl): Call add_method for used functions.
        Use IDENTIFIER_CLASS_VALUE to check for conflicts.
        (add_method): Used functions are hidden by local functions.
        (check_bases_and_members): Handle using-decls before finalizing
        CLASSTYPE_METHOD_VEC.
        * call.c (add_function_candidate): Add ctype parm; if non-zero,
        override the type of 'this' accordingly.
        (add_template_candidate, add_template_candidate_real): Add ctype parm.
        (convert_class_to_reference, build_user_type_conversion_1,
        build_new_function_call, build_object_call, build_new_op,
        build_new_method_call): Pass ctype parm.

        * search.c (lookup_member): Put rval_binfo, not basetype_path, in
        the baselink.
        * call.c (convert_class_to_reference, build_user_type_conversion_1,
        build_new_function_call, build_object_call, build_new_op,
        build_new_method_call, build_op_delete_call): Don't get basetype_path
        from a baselink.
        * typeck.c (build_component_ref): Likewise.
        * init.c (build_offset_ref): Likewise.
        (resolve_offset_ref): Don't call enforce_access.
        Call build_scoped_ref.
        * typeck2.c (build_scoped_ref): Simplify.  Do nothing if it
        would cause an error or if -pedantic.
        * class.c (alter_access): Lose binfo parm.

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

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

index af946b3..f5c9bcf 100644 (file)
@@ -1,3 +1,32 @@
+2000-02-26  Jason Merrill  <jason@casey.cygnus.com>
+
+       Implement class scope using-declarations for functions.
+       * class.c (handle_using_decl): Call add_method for used functions.
+       Use IDENTIFIER_CLASS_VALUE to check for conflicts.
+       (add_method): Used functions are hidden by local functions.
+       (check_bases_and_members): Handle using-decls before finalizing
+       CLASSTYPE_METHOD_VEC.
+       * call.c (add_function_candidate): Add ctype parm; if non-zero,
+       override the type of 'this' accordingly.
+       (add_template_candidate, add_template_candidate_real): Add ctype parm.
+       (convert_class_to_reference, build_user_type_conversion_1, 
+       build_new_function_call, build_object_call, build_new_op,
+       build_new_method_call): Pass ctype parm.
+
+       * search.c (lookup_member): Put rval_binfo, not basetype_path, in
+       the baselink.
+       * call.c (convert_class_to_reference, build_user_type_conversion_1, 
+       build_new_function_call, build_object_call, build_new_op,
+       build_new_method_call, build_op_delete_call): Don't get basetype_path
+       from a baselink.
+       * typeck.c (build_component_ref): Likewise.
+       * init.c (build_offset_ref): Likewise.
+       (resolve_offset_ref): Don't call enforce_access.  
+       Call build_scoped_ref.
+       * typeck2.c (build_scoped_ref): Simplify.  Do nothing if it
+       would cause an error or if -pedantic.
+       * class.c (alter_access): Lose binfo parm.
+
 2000-02-26  Mark Mitchell  <mark@codesourcery.com>
 
        * semantics.c (simplify_aggr_init_exprs_p): Don't walk into
index f672c96..8ced478 100644 (file)
@@ -61,10 +61,10 @@ static tree build_this PARAMS ((tree));
 static struct z_candidate * splice_viable PARAMS ((struct z_candidate *));
 static int any_viable PARAMS ((struct z_candidate *));
 static struct z_candidate * add_template_candidate
-       PARAMS ((struct z_candidate *, tree, tree, tree, tree, int,
+       PARAMS ((struct z_candidate *, tree, tree, tree, tree, tree, int,
               unification_kind_t));
 static struct z_candidate * add_template_candidate_real
-       PARAMS ((struct z_candidate *, tree, tree, tree, tree, int,
+       PARAMS ((struct z_candidate *, tree, tree, tree, tree, tree, int,
               tree, unification_kind_t));
 static struct z_candidate * add_template_conv_candidate 
         PARAMS ((struct z_candidate *, tree, tree, tree, tree));
@@ -81,7 +81,7 @@ static struct z_candidate * build_builtin_candidate
 static struct z_candidate * add_conv_candidate 
        PARAMS ((struct z_candidate *, tree, tree, tree));
 static struct z_candidate * add_function_candidate 
-       PARAMS ((struct z_candidate *, tree, tree, int));
+       PARAMS ((struct z_candidate *, tree, tree, tree, int));
 static tree implicit_conversion PARAMS ((tree, tree, tree, int));
 static tree standard_conversion PARAMS ((tree, tree, tree));
 static tree reference_binding PARAMS ((tree, tree, tree, int));
@@ -91,7 +91,7 @@ static int is_subseq PARAMS ((tree, tree));
 static int maybe_handle_ref_bind PARAMS ((tree*, tree*));
 static void maybe_handle_implicit_object PARAMS ((tree*));
 static struct z_candidate * add_candidate PARAMS ((struct z_candidate *,
-                                                tree, tree, int));
+                                                  tree, tree, int));
 static tree source_type PARAMS ((tree));
 static void add_warning PARAMS ((struct z_candidate *, struct z_candidate *));
 static int reference_related_p PARAMS ((tree, tree));
@@ -879,7 +879,7 @@ convert_class_to_reference (t, s, expr)
     {
       tree fns = TREE_VALUE (conversions);
 
-      while (fns)
+      for (; fns; fns = OVL_NEXT (fns))
        {
          tree f = OVL_CURRENT (fns);
          tree t2 = TREE_TYPE (TREE_TYPE (f));
@@ -891,7 +891,7 @@ convert_class_to_reference (t, s, expr)
            {
              candidates 
                = add_template_candidate (candidates,
-                                         f,
+                                         f, s,
                                          NULL_TREE,
                                          arglist,
                                          build_reference_type (t),
@@ -914,13 +914,11 @@ convert_class_to_reference (t, s, expr)
          else if (TREE_CODE (t2) == REFERENCE_TYPE
                   && reference_compatible_p (t, TREE_TYPE (t2)))
            candidates 
-             = add_function_candidate (candidates, f, arglist, 
+             = add_function_candidate (candidates, f, s, arglist, 
                                        LOOKUP_NORMAL);
 
          if (candidates != old_candidates)
-           candidates->basetype_path = TREE_PURPOSE (conversions);
-
-         fns = OVL_NEXT (fns);
+           candidates->basetype_path = TYPE_BINFO (s);
        }
     }
 
@@ -1235,12 +1233,15 @@ add_candidate (candidates, fn, convs, viable)
 
 /* Create an overload candidate for the function or method FN called with
    the argument list ARGLIST and add it to CANDIDATES.  FLAGS is passed on
-   to implicit_conversion.  */
+   to implicit_conversion.
+
+   CTYPE, if non-NULL, is the type we want to pretend this function
+   comes from for purposes of overload resolution.  */
 
 static struct z_candidate *
-add_function_candidate (candidates, fn, arglist, flags)
+add_function_candidate (candidates, fn, ctype, arglist, flags)
      struct z_candidate *candidates;
-     tree fn, arglist;
+     tree fn, ctype, arglist;
      int flags;
 {
   tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
@@ -1307,25 +1308,31 @@ add_function_candidate (candidates, fn, arglist, flags)
       tree arg = TREE_VALUE (argnode);
       tree argtype = lvalue_type (arg);
       tree t;
+      int is_this;
 
       if (parmnode == void_list_node)
        break;
 
+      is_this = (i == 0 && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+                && ! DECL_CONSTRUCTOR_P (fn));
+
       if (parmnode)
        {
          tree parmtype = TREE_VALUE (parmnode);
 
-         /* [over.match.funcs] For conversion functions, the function is
-            considered to be a member of the class of the implicit object
-            argument for the purpose of defining the type of the implicit
-            object parameter.
+         /* The type of the implicit object parameter ('this') for
+            overload resolution is not always the same as for the
+            function itself; conversion functions are considered to
+            be members of the class being converted, and functions
+            introduced by a using-declaration are considered to be
+            members of the class that uses them.
 
-            Since build_over_call ignores the ICS for the `this' parameter,
-            we can just change the parm type.  */
-         if (DECL_CONV_FN_P (fn) && i == 0)
+            Since build_over_call ignores the ICS for the `this'
+            parameter, we can just change the parm type.  */
+         if (ctype && is_this)
            {
              parmtype
-               = build_qualified_type (TREE_TYPE (argtype),
+               = build_qualified_type (ctype,
                                        TYPE_QUALS (TREE_TYPE (parmtype)));
              parmtype = build_pointer_type (parmtype);
            }
@@ -1338,8 +1345,7 @@ add_function_candidate (candidates, fn, arglist, flags)
          ICS_ELLIPSIS_FLAG (t) = 1;
        }
 
-      if (i == 0 && t && TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
-         && ! DECL_CONSTRUCTOR_P (fn))
+      if (t && is_this)
        ICS_THIS_FLAG (t) = 1;
 
       TREE_VEC_ELT (convs, i) = t;
@@ -2090,16 +2096,16 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
    TMPL is the template.  EXPLICIT_TARGS are any explicit template
    arguments.  ARGLIST is the arguments provided at the call-site.
    The RETURN_TYPE is the desired type for conversion operators.  If
-   OBJ is NULL_TREE, FLAGS are as for add_function_candidate.  If an
-   OBJ is supplied, FLAGS are ignored, and OBJ is as for
+   OBJ is NULL_TREE, FLAGS and CTYPE are as for add_function_candidate.
+   If an OBJ is supplied, FLAGS and CTYPE are ignored, and OBJ is as for
    add_conv_candidate.  */
 
 static struct z_candidate*
-add_template_candidate_real (candidates, tmpl, explicit_targs,
+add_template_candidate_real (candidates, tmpl, ctype, explicit_targs,
                             arglist, return_type, flags,
                             obj, strict)
      struct z_candidate *candidates;
-     tree tmpl, explicit_targs, arglist, return_type;
+     tree tmpl, ctype, explicit_targs, arglist, return_type;
      int flags;
      tree obj;
      unification_kind_t strict;
@@ -2124,7 +2130,8 @@ add_template_candidate_real (candidates, tmpl, explicit_targs,
     /* Aha, this is a conversion function.  */
     cand = add_conv_candidate (candidates, fn, obj, arglist);
   else
-    cand = add_function_candidate (candidates, fn, arglist, flags);
+    cand = add_function_candidate (candidates, fn, ctype,
+                                  arglist, flags);
   if (DECL_TI_TEMPLATE (fn) != tmpl)
     /* This situation can occur if a member template of a template
        class is specialized.  Then, instantiate_template might return
@@ -2152,16 +2159,16 @@ add_template_candidate_real (candidates, tmpl, explicit_targs,
 
 
 static struct z_candidate *
-add_template_candidate (candidates, tmpl, explicit_targs, 
+add_template_candidate (candidates, tmpl, ctype, explicit_targs, 
                        arglist, return_type, flags, strict)
      struct z_candidate *candidates;
-     tree tmpl, explicit_targs, arglist, return_type;
+     tree tmpl, ctype, explicit_targs, arglist, return_type;
      int flags;
      unification_kind_t strict;
 {
   return 
-    add_template_candidate_real (candidates, tmpl, explicit_targs,
-                                arglist, return_type, flags,
+    add_template_candidate_real (candidates, tmpl, ctype,
+                                explicit_targs, arglist, return_type, flags,
                                 NULL_TREE, strict);
 }
 
@@ -2172,8 +2179,8 @@ add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type)
      tree tmpl, obj, arglist, return_type;
 {
   return 
-    add_template_candidate_real (candidates, tmpl, NULL_TREE, arglist,
-                                return_type, 0, obj, DEDUCE_CONV);
+    add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE,
+                                arglist, return_type, 0, obj, DEDUCE_CONV);
 }
 
 
@@ -2290,12 +2297,12 @@ build_user_type_conversion_1 (totype, expr, flags)
        {
          templates = tree_cons (NULL_TREE, ctor, templates);
          candidates = 
-           add_template_candidate (candidates, ctor,
+           add_template_candidate (candidates, ctor, totype,
                                    NULL_TREE, args, NULL_TREE, flags,
                                    DEDUCE_CALL);
        } 
       else 
-       candidates = add_function_candidate (candidates, ctor,
+       candidates = add_function_candidate (candidates, ctor, totype,
                                             args, flags); 
 
       if (candidates) 
@@ -2336,16 +2343,23 @@ build_user_type_conversion_1 (totype, expr, flags)
            tree fn = OVL_CURRENT (fns);
            struct z_candidate *old_candidates = candidates;
 
+           /* [over.match.funcs] For conversion functions, the function is
+              considered to be a member of the class of the implicit object
+              argument for the purpose of defining the type of the implicit
+              object parameter.
+
+              So we pass fromtype as CTYPE to add_*_candidate.  */
+
            if (TREE_CODE (fn) == TEMPLATE_DECL)
              {
                templates = tree_cons (NULL_TREE, fn, templates);
                candidates = 
-                 add_template_candidate (candidates, fn, NULL_TREE,
+                 add_template_candidate (candidates, fn, fromtype, NULL_TREE,
                                          args, totype, flags,
                                          DEDUCE_CONV);
              } 
            else 
-             candidates = add_function_candidate (candidates, fn,
+             candidates = add_function_candidate (candidates, fn, fromtype,
                                                   args, flags); 
 
            if (candidates != old_candidates)
@@ -2356,7 +2370,7 @@ build_user_type_conversion_1 (totype, expr, flags)
                     0, convflags);
 
                candidates->second_conv = ics;
-               candidates->basetype_path = TREE_PURPOSE (convs);
+               candidates->basetype_path = TYPE_BINFO (fromtype);
 
                if (ics == NULL_TREE)
                  candidates->viable = 0;
@@ -2491,21 +2505,17 @@ build_new_function_call (fn, args)
       for (t1 = fn; t1; t1 = OVL_CHAIN (t1))
        {
          tree t = OVL_FUNCTION (t1);
-         struct z_candidate *old_candidates = candidates;
 
          if (TREE_CODE (t) == TEMPLATE_DECL)
            {
              templates = tree_cons (NULL_TREE, t, templates);
              candidates = add_template_candidate
-               (candidates, t, explicit_targs, args, NULL_TREE,
+               (candidates, t, NULL_TREE, explicit_targs, args, NULL_TREE,
                 LOOKUP_NORMAL, DEDUCE_CALL);  
            }
          else if (! template_only)
            candidates = add_function_candidate
-             (candidates, t, args, LOOKUP_NORMAL);
-
-         if (candidates != old_candidates)
-           candidates->basetype_path = CP_DECL_CONTEXT (t);
+             (candidates, t, NULL_TREE, args, LOOKUP_NORMAL);
        }
 
       if (! any_viable (candidates))
@@ -2572,7 +2582,7 @@ build_object_call (obj, args)
 
   if (fns)
     {
-      tree base = TREE_PURPOSE (fns);
+      tree base = BINFO_TYPE (TREE_PURPOSE (fns));
       mem_args = tree_cons (NULL_TREE, build_this (obj), args);
 
       for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns))
@@ -2581,16 +2591,16 @@ build_object_call (obj, args)
          if (TREE_CODE (fn) == TEMPLATE_DECL)
            {
              candidates 
-               = add_template_candidate (candidates, fn, NULL_TREE,
+               = add_template_candidate (candidates, fn, base, NULL_TREE,
                                          mem_args, NULL_TREE, 
                                          LOOKUP_NORMAL, DEDUCE_CALL);
            }
          else
            candidates = add_function_candidate
-             (candidates, fn, mem_args, LOOKUP_NORMAL);
+             (candidates, fn, base, mem_args, LOOKUP_NORMAL);
 
          if (candidates)
-           candidates->basetype_path = base;
+           candidates->basetype_path = TYPE_BINFO (type);
        }
     }
 
@@ -2617,9 +2627,6 @@ build_object_call (obj, args)
              }
            else
              candidates = add_conv_candidate (candidates, fn, obj, args);
-
-           if (candidates)
-             candidates->basetype_path = TREE_PURPOSE (convs);
          }
     }
 
@@ -3184,12 +3191,13 @@ build_new_op (code, flags, arg1, arg2, arg3)
        {
          templates = tree_cons (NULL_TREE, fn, templates);
          candidates 
-           = add_template_candidate (candidates, fn, NULL_TREE,
+           = add_template_candidate (candidates, fn, NULL_TREE, NULL_TREE,
                                      arglist, TREE_TYPE (fnname),
                                      flags, DEDUCE_CALL); 
        }
       else
-       candidates = add_function_candidate (candidates, fn, arglist, flags);
+       candidates = add_function_candidate (candidates, fn, NULL_TREE,
+                                            arglist, flags);
     }
 
   if (IS_AGGR_TYPE (TREE_TYPE (arg1)))
@@ -3203,7 +3211,7 @@ build_new_op (code, flags, arg1, arg2, arg3)
 
   if (fns)
     {
-      tree basetype = TREE_PURPOSE (fns);
+      tree basetype = BINFO_TYPE (TREE_PURPOSE (fns));
       mem_arglist = tree_cons (NULL_TREE, build_this (arg1), TREE_CHAIN (arglist));
       for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns))
        {
@@ -3220,16 +3228,16 @@ build_new_op (code, flags, arg1, arg2, arg3)
              /* A member template. */
              templates = tree_cons (NULL_TREE, fn, templates);
              candidates 
-               = add_template_candidate (candidates, fn, NULL_TREE,
+               = add_template_candidate (candidates, fn, basetype, NULL_TREE,
                                          this_arglist,  TREE_TYPE (fnname),
                                          flags, DEDUCE_CALL); 
            }
          else
            candidates = add_function_candidate
-             (candidates, fn, this_arglist, flags);
+             (candidates, fn, basetype, this_arglist, flags);
 
-         if (candidates) 
-           candidates->basetype_path = basetype;
+         if (candidates)
+           candidates->basetype_path = TYPE_BINFO (TREE_TYPE (arg1));
        }
     }
 
@@ -3547,7 +3555,7 @@ build_op_delete_call (code, addr, size, flags, placement)
     {
       if (TREE_CODE (fns) == TREE_LIST)
        /* Member functions.  */
-       enforce_access (TREE_PURPOSE (fns), fn);
+       enforce_access (type, fn);
       return build_function_call (fn, tree_cons (NULL_TREE, addr, args));
     }
 
@@ -3567,7 +3575,7 @@ build_op_delete_call (code, addr, size, flags, placement)
     {
       if (BASELINK_P (fns))
        /* Member functions.  */
-       enforce_access (TREE_PURPOSE (fns), fn);
+       enforce_access (type, fn);
       return build_function_call
        (fn, tree_cons (NULL_TREE, addr,
                        build_tree_list (NULL_TREE, size)));
@@ -4254,6 +4262,7 @@ build_new_method_call (instance, name, args, basetype_path, flags)
     return error_mark_node;
   if (fns)
     {
+      tree base = BINFO_TYPE (TREE_PURPOSE (fns));
       tree fn = TREE_VALUE (fns);
       if (name == ctor_identifier && TYPE_USES_VIRTUAL_BASECLASSES (basetype)
          && ! (flags & LOOKUP_HAS_IN_CHARGE))
@@ -4282,16 +4291,16 @@ build_new_method_call (instance, name, args, basetype_path, flags)
              /* A member template. */
              templates = tree_cons (NULL_TREE, t, templates);
              candidates = 
-               add_template_candidate (candidates, t, explicit_targs,
+               add_template_candidate (candidates, t, base, explicit_targs,
                                        this_arglist,
                                        TREE_TYPE (name), flags, DEDUCE_CALL); 
            }
          else if (! template_only)
-           candidates = add_function_candidate (candidates, t,
+           candidates = add_function_candidate (candidates, t, base,
                                                 this_arglist, flags);
 
          if (candidates)
-           candidates->basetype_path = TREE_PURPOSE (fns);
+           candidates->basetype_path = basetype_path;
        }
     }
 
index ce3c2e8..d186027 100644 (file)
@@ -91,7 +91,7 @@ static void add_virtual_function PARAMS ((tree *, tree *, int *, tree, tree));
 static tree delete_duplicate_fields_1 PARAMS ((tree, tree));
 static void delete_duplicate_fields PARAMS ((tree));
 static void finish_struct_bits PARAMS ((tree));
-static int alter_access PARAMS ((tree, tree, tree, tree));
+static int alter_access PARAMS ((tree, tree, tree));
 static void handle_using_decl PARAMS ((tree, tree));
 static int overrides PARAMS ((tree, tree));
 static int strictly_overrides PARAMS ((tree, tree));
@@ -1441,8 +1441,7 @@ void
 add_method (type, fields, method)
      tree type, *fields, method;
 {
-  /* Setting the DECL_CONTEXT here is probably redundant.  */
-  DECL_CONTEXT (method) = type;
+  int using = (DECL_CONTEXT (method) != type);
   
   if (fields && *fields)
     *fields = build_overload (method, *fields);
@@ -1558,20 +1557,27 @@ add_method (type, fields, method)
                     same name and the same parameter types cannot be
                     overloaded if any of them is a static member
                     function declaration.  */
-                 if (DECL_STATIC_FUNCTION_P (fn)
-                     != DECL_STATIC_FUNCTION_P (method))
+                 if ((DECL_STATIC_FUNCTION_P (fn)
+                      != DECL_STATIC_FUNCTION_P (method))
+                     || using)
                    {
                      tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn));
                      tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (method));
 
                      if (! DECL_STATIC_FUNCTION_P (fn))
                        parms1 = TREE_CHAIN (parms1);
-                     else
+                     if (! DECL_STATIC_FUNCTION_P (method))
                        parms2 = TREE_CHAIN (parms2);
 
                      if (compparms (parms1, parms2))
-                       cp_error ("`%#D' and `%#D' cannot be overloaded",
-                                 fn, method);
+                       {
+                         if (using)
+                           /* Defer to the local function.  */
+                           return;
+                         else
+                           cp_error ("`%#D' and `%#D' cannot be overloaded",
+                                     fn, method);
+                       }
                    }
 
                  /* Since this is an ordinary function in a
@@ -1715,14 +1721,12 @@ delete_duplicate_fields (fields)
     TREE_CHAIN (x) = delete_duplicate_fields_1 (x, TREE_CHAIN (x));
 }
 
-/* Change the access of FDECL to ACCESS in T.  The access to FDECL is
-   along the path given by BINFO.  Return 1 if change was legit,
-   otherwise return 0.  */
+/* Change the access of FDECL to ACCESS in T.  Return 1 if change was
+   legit, otherwise return 0.  */
 
 static int
-alter_access (t, binfo, fdecl, access)
+alter_access (t, fdecl, access)
      tree t;
-     tree binfo;
      tree fdecl;
      tree access;
 {
@@ -1746,7 +1750,7 @@ alter_access (t, binfo, fdecl, access)
     }
   else
     {
-      enforce_access (binfo, fdecl);
+      enforce_access (t, fdecl);
       DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
       return 1;
     }
@@ -1768,11 +1772,7 @@ handle_using_decl (using_decl, t)
     : access_public_node;
   tree fdecl, binfo;
   tree flist = NULL_TREE;
-  tree fields = TYPE_FIELDS (t);
-  tree method_vec = CLASSTYPE_METHOD_VEC (t);
-  tree tmp;
-  int i;
-  int n_methods;
+  tree old_value;
 
   binfo = binfo_or_else (ctype, t);
   if (! binfo)
@@ -1793,57 +1793,58 @@ handle_using_decl (using_decl, t)
       return;
     }
 
-  /* Functions are represented as TREE_LIST, with the purpose
-     being the type and the value the functions. Other members
-     come as themselves. */
-  if (TREE_CODE (fdecl) == TREE_LIST)
+  if (BASELINK_P (fdecl))
     /* Ignore base type this came from. */
     fdecl = TREE_VALUE (fdecl);
 
-  if (TREE_CODE (fdecl) == OVERLOAD)
+  old_value = IDENTIFIER_CLASS_VALUE (name);
+  if (old_value)
     {
-      /* We later iterate over all functions. */
-      flist = fdecl;
-      fdecl = OVL_FUNCTION (flist);
+      if (is_overloaded_fn (old_value))
+       old_value = OVL_CURRENT (old_value);
+
+      if (DECL_P (old_value) && DECL_CONTEXT (old_value) == t)
+       /* OK */;
+      else
+       old_value = NULL_TREE;
     }
-  
-  name = DECL_NAME (fdecl);
-  n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
-  for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); i++)
-    if (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i)))
-       == name)
-      {
-       cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
-       cp_error_at ("  because of local method `%#D' with same name",
-                    OVL_CURRENT (TREE_VEC_ELT (method_vec, i)));
-       return;
-      }
 
-  if (! DECL_LANG_SPECIFIC (fdecl))
-    /* We don't currently handle DECL_ACCESS for TYPE_DECLs; just return.  */
-    return;
-  
-  for (tmp = fields; tmp; tmp = TREE_CHAIN (tmp))
-    if (DECL_NAME (tmp) == name)
-      {
-       cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
-       cp_error_at ("  because of local field `%#D' with same name", tmp);
-       return;
-      }
-  
-  /* Make type T see field decl FDECL with access ACCESS.*/
-  if (flist)
+  if (is_overloaded_fn (fdecl))
+    flist = fdecl;
+  else if (! DECL_LANG_SPECIFIC (fdecl))
+    my_friendly_abort (20000221);
+
+  if (! old_value)
+    ;
+  else if (is_overloaded_fn (old_value))
     {
-      while (flist)
+      if (flist)
+       /* It's OK to use functions from a base when there are functions with
+          the same name already present in the current class.  */;
+      else
        {
-         if (alter_access (t, binfo, OVL_FUNCTION (flist), 
-                           access) == 0)
-           return;
-         flist = OVL_CHAIN (flist);
+         cp_error ("`%D' invalid in `%#T'", using_decl, t);
+         cp_error_at ("  because of local method `%#D' with same name",
+                      OVL_CURRENT (old_value));
+         return;
        }
     }
   else
-    alter_access (t, binfo, fdecl, access);
+    {
+      cp_error ("`%D' invalid in `%#T'", using_decl, t);
+      cp_error_at ("  because of local field `%#D' with same name", old_value);
+      return;
+    }
+  
+  /* Make type T see field decl FDECL with access ACCESS.*/
+  if (flist)
+    for (; flist; flist = OVL_NEXT (flist))
+      {
+       add_method (t, 0, OVL_CURRENT (flist));
+       alter_access (t, OVL_CURRENT (flist), access);
+      }
+  else
+    alter_access (t, fdecl, access);
 }
 \f
 /* Run through the base clases of T, updating
@@ -4413,17 +4414,12 @@ check_bases_and_members (t, empty_p)
                                   cant_have_const_ctor,
                                   no_const_asn_ref);
 
+  /* Process the using-declarations.  */
+  for (; access_decls; access_decls = TREE_CHAIN (access_decls))
+    handle_using_decl (TREE_VALUE (access_decls), t);
+
   /* Build and sort the CLASSTYPE_METHOD_VEC.  */
   finish_struct_methods (t);
-
-  /* Process the access-declarations.  We wait until now to do this
-     because handle_using_decls requires that the CLASSTYPE_METHOD_VEC
-     be set up correctly.  */
-  while (access_decls)
-    {
-      handle_using_decl (TREE_VALUE (access_decls), t);
-      access_decls = TREE_CHAIN (access_decls);
-    }
 }
 
 /* If T needs a pointer to its virtual function table, set TYPE_VFIELD
index e2f459f..6902232 100644 (file)
@@ -635,15 +635,7 @@ tree
 convert_pointer_to (binfo, expr)
      tree binfo, expr;
 {
-  tree type;
-
-  if (TREE_CODE (binfo) == TREE_VEC)
-    type = BINFO_TYPE (binfo);
-  else if (IS_AGGR_TYPE (binfo))
-    type = binfo;
-  else
-    type = binfo;
-  return convert_pointer_to_real (type, expr);
+  return convert_pointer_to_real (binfo, expr);
 }
 \f
 /* C++ conversions, preference to static cast conversions.  */
index 1c993b3..69a4e3a 100644 (file)
@@ -1611,8 +1611,7 @@ build_offset_ref (type, name)
   if (member == error_mark_node)
     return error_mark_node;
 
-  /* A lot of this logic is now handled in lookup_field and
-     lookup_fnfield.  */
+  /* A lot of this logic is now handled in lookup_member.  */
   if (member && BASELINK_P (member))
     {
       /* Go from the TREE_BASELINK to the member function info.  */
@@ -1648,7 +1647,6 @@ build_offset_ref (type, name)
          t = OVL_CURRENT (t);
 
          /* unique functions are handled easily.  */
-         basebinfo = TREE_PURPOSE (fnfields);
          if (!enforce_access (basebinfo, t))
            return error_mark_node;
          mark_used (t);
@@ -1776,29 +1774,24 @@ resolve_offset_ref (exp)
   if (TREE_CODE (member) == FIELD_DECL
       && (base == current_class_ref || is_dummy_object (base)))
     {
-      tree basetype_path;
       tree expr;
 
+      basetype = DECL_CONTEXT (member);
+
+      /* Try to get to basetype from 'this'; if that doesn't work,
+         nothing will.  */
+      base = current_class_ref;
+
+      /* First convert to the intermediate base specified, if appropriate.  */
       if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
-       basetype = TYPE_OFFSET_BASETYPE (type);
-      else
-       basetype = DECL_CONTEXT (member);
+       base = build_scoped_ref (base, TYPE_OFFSET_BASETYPE (type));
 
-      base = current_class_ptr;
+      addr = build_unary_op (ADDR_EXPR, base, 0);
+      addr = convert_pointer_to (basetype, addr);
+
+      if (addr == error_mark_node)
+       return error_mark_node;
 
-      if (get_base_distance (basetype, TREE_TYPE (TREE_TYPE (base)), 0, &basetype_path) < 0)
-       {
-         error_not_base_type (basetype, TREE_TYPE (TREE_TYPE (base)));
-         return error_mark_node;
-       }
-      /* Kludge: we need to use basetype_path now, because
-        convert_pointer_to will bash it.  */
-      enforce_access (basetype_path, member);
-      addr = convert_pointer_to (basetype, base);
-
-      /* Even in the case of illegal access, we form the
-        COMPONENT_REF; that will allow better error recovery than
-        just feeding back error_mark_node.  */
       expr = build (COMPONENT_REF, TREE_TYPE (member),
                    build_indirect_ref (addr, NULL_PTR), member);
       return convert_from_reference (expr);
index e95262b..4b604eb 100644 (file)
@@ -1606,7 +1606,15 @@ lookup_member (xbasetype, name, protect, want_type)
 
   if (rval && is_overloaded_fn (rval)) 
     {
-      rval = tree_cons (basetype_path, rval, NULL_TREE);
+      /* Note that the binfo we put in the baselink is the binfo where
+        we found the functions, which we need for overload
+        resolution, but which should not be passed to enforce_access;
+        rather, enforce_access wants a binfo which refers to the
+        scope in which we started looking for the function.  This
+        will generally be the binfo passed into this function as
+        xbasetype.  */
+
+      rval = tree_cons (rval_binfo, rval, NULL_TREE);
       SET_BASELINK_P (rval);
     }
 
index 2cc4944..ae01800 100644 (file)
@@ -2151,7 +2151,7 @@ build_component_ref (datum, component, basetype_path, protect)
                  if (DECL_STATIC_FUNCTION_P (TREE_VALUE (fndecls)))
                    {
                      tree fndecl = TREE_VALUE (fndecls);
-                     enforce_access (TREE_PURPOSE (fndecls), fndecl);
+                     enforce_access (basetype_path, fndecl);
                      mark_used (fndecl);
                      return fndecl;
                    }
@@ -2221,7 +2221,8 @@ build_component_ref (datum, component, basetype_path, protect)
          else
            addr = convert_pointer_to (base, addr);
          datum = build_indirect_ref (addr, NULL_PTR);
-         my_friendly_assert (datum != error_mark_node, 311);
+         if (datum == error_mark_node)
+           return error_mark_node;
        }
       basetype = base;
  
index d380953..88ddc89 100644 (file)
@@ -1031,7 +1031,11 @@ process_init_constructor (type, init, elts)
 
    x.A::ii refers to the ii member of the L part of
    the A part of the C object named by X.  In this case,
-   DATUM would be x, and BASETYPE would be A.  */
+   DATUM would be x, and BASETYPE would be A.
+
+   Note that this is nonconformant; the standard specifies that first
+   we look up ii in A, then convert x to an L& and pull out the ii part.
+   But narrowing seems to be standard practice, so let's do it anyway.  */
 
 tree
 build_scoped_ref (datum, basetype)
@@ -1044,43 +1048,15 @@ build_scoped_ref (datum, basetype)
   if (datum == error_mark_node)
     return error_mark_node;
 
-  if (TREE_CODE (type) == REFERENCE_TYPE)
-    type = TREE_TYPE (type);
-
-  type = TYPE_MAIN_VARIANT (type);
+  /* Don't do this if it would cause an error or if we're being pedantic.  */
+  if (! ACCESSIBLY_UNIQUELY_DERIVED_P (basetype, type)
+      || pedantic)
+    return datum;
 
-  /* This is an easy conversion.  */
-  if (is_aggr_type (basetype, 1))
-    {
-      tree binfo = TYPE_BINFO (basetype);
-      if (binfo != TYPE_BINFO (type))
-       {
-         binfo = get_binfo (binfo, type, 1);
-         if (binfo == error_mark_node)
-           return error_mark_node;
-         if (binfo == 0)
-           return error_not_base_type (basetype, type);
-       }
+  ref = build_unary_op (ADDR_EXPR, datum, 0);
+  ref = convert_pointer_to (basetype, ref);
 
-      switch (TREE_CODE (datum))
-       {
-       case NOP_EXPR:
-       case CONVERT_EXPR:
-       case FLOAT_EXPR:
-       case FIX_TRUNC_EXPR:
-       case FIX_FLOOR_EXPR:
-       case FIX_ROUND_EXPR:
-       case FIX_CEIL_EXPR:
-         ref = convert_pointer_to (binfo,
-                                   build_unary_op (ADDR_EXPR, TREE_OPERAND (datum, 0), 0));
-         break;
-       default:
-         ref = convert_pointer_to (binfo,
-                                   build_unary_op (ADDR_EXPR, datum, 0));
-       }
-      return build_indirect_ref (ref, "(compiler error in build_scoped_ref)");
-    }
-  return error_mark_node;
+  return build_indirect_ref (ref, "(compiler error in build_scoped_ref)");
 }
 
 /* Build a reference to an object specified by the C++ `->' operator.