OSDN Git Service

Revamp references to member functions.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Oct 1998 20:08:23 +0000 (20:08 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Oct 1998 20:08:23 +0000 (20:08 +0000)
* method.c (hack_identifier): Call build_component_ref for a
reference to a member function.
* typeck.c (build_component_ref): Only return a single function
if it's static.  Otherwise, return a COMPONENT_REF.
(build_x_function_call): Handle a COMPONENT_REF.
(build_unary_op): Handle all unknown-type things.
* decl2.c (arg_assoc): Handle COMPONENT_REF.
* class.c (instantiate_type): Complain if the function we get is a
nonstatic member function.  Remove code for finding "compatible"
functions.
* pt.c (tsubst_copy): Handle NOP_EXPR.
* tree.c (build_dummy_object): New fn.
(maybe_dummy_object): New fn.
(is_dummy_object): New fn.
* cp-tree.h: Declare them.
* cvt.c (cp_convert_to_pointer): Use maybe_dummy_object.
* error.c (dump_expr, case OFFSET_REF): Use is_dummy_object.
* init.c (build_member_call): Use maybe_dummy_object and
is_dummy_object.
(build_offset_ref): Use maybe_dummy_object.
(resolve_offset_ref): Use is_dummy_object.
* typeck.c (build_x_function_call): Call build_dummy_object.
(unary_complex_lvalue): Call is_dummy_object.
* typeck.c (build_component_addr): Make sure field is a field.
* call.c (build_new_op): Delete obsolete code.
* pt.c (tsubst, TEMPLATE*PARM*): Abort if we don't have any args.

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

13 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl2.c
gcc/cp/error.c
gcc/cp/init.c
gcc/cp/method.c
gcc/cp/pt.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c

index 7b7740b..fb5a81e 100644 (file)
@@ -1,3 +1,36 @@
+1998-10-19  Jason Merrill  <jason@yorick.cygnus.com>
+
+       Revamp references to member functions.
+       * method.c (hack_identifier): Call build_component_ref for a
+       reference to a member function.
+       * typeck.c (build_component_ref): Only return a single function 
+       if it's static.  Otherwise, return a COMPONENT_REF.
+       (build_x_function_call): Handle a COMPONENT_REF.
+       (build_unary_op): Handle all unknown-type things.
+       * decl2.c (arg_assoc): Handle COMPONENT_REF.
+       * class.c (instantiate_type): Complain if the function we get is a
+       nonstatic member function.  Remove code for finding "compatible"
+       functions.
+       * pt.c (tsubst_copy): Handle NOP_EXPR.
+       * tree.c (build_dummy_object): New fn.
+       (maybe_dummy_object): New fn.
+       (is_dummy_object): New fn.
+       * cp-tree.h: Declare them.
+       * cvt.c (cp_convert_to_pointer): Use maybe_dummy_object.
+       * error.c (dump_expr, case OFFSET_REF): Use is_dummy_object.
+       * init.c (build_member_call): Use maybe_dummy_object and
+       is_dummy_object.
+       (build_offset_ref): Use maybe_dummy_object.
+       (resolve_offset_ref): Use is_dummy_object.
+       * typeck.c (build_x_function_call): Call build_dummy_object.
+       (unary_complex_lvalue): Call is_dummy_object.
+
+       * typeck.c (build_component_addr): Make sure field is a field.
+
+       * call.c (build_new_op): Delete obsolete code.
+
+       * pt.c (tsubst, TEMPLATE*PARM*): Abort if we don't have any args.
+
 1998-10-18  Martin von Löwis  <loewis@informatik.hu-berlin.de>
 
        * decl2.c (validate_nonmember_using_decl): Fix using-directives of
index f431885..dc05d19 100644 (file)
@@ -2513,73 +2513,10 @@ build_new_op (code, flags, arg1, arg2, arg3)
     {
     case NEW_EXPR:
     case VEC_NEW_EXPR:
-      {
-       tree rval;
-
-       arglist = scratch_tree_cons (NULL_TREE, arg2, arg3);
-       if (flags & LOOKUP_GLOBAL)
-         return build_new_function_call
-           (lookup_function_nonclass (fnname, arglist), arglist);
-
-       /* FIXME */
-       rval = build_method_call
-         (build_indirect_ref (build1 (NOP_EXPR, arg1, error_mark_node),
-                              "new"),
-          fnname, arglist, NULL_TREE, flags);
-       if (rval == error_mark_node)
-         /* User might declare fancy operator new, but invoke it
-            like standard one.  */
-         return rval;
-
-       TREE_TYPE (rval) = arg1;
-       return rval;
-      }
-
     case VEC_DELETE_EXPR:
     case DELETE_EXPR:
-      {
-       tree rval;
-
-       if (flags & LOOKUP_GLOBAL)
-         {
-           arglist = build_scratch_list (NULL_TREE, arg1);
-           return build_new_function_call
-             (lookup_function_nonclass (fnname, arglist), arglist);
-         }    
-
-       arglist = scratch_tree_cons (NULL_TREE, arg1, build_scratch_list (NULL_TREE, arg2));
-
-       arg1 = TREE_TYPE (arg1);
-
-       /* This handles the case where we're trying to delete
-          X (*a)[10];
-          a=new X[5][10];
-          delete[] a; */
-          
-       if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
-         {
-           /* Strip off the pointer and the array.  */
-           arg1 = TREE_TYPE (TREE_TYPE (arg1));
-
-           while (TREE_CODE (arg1) == ARRAY_TYPE)
-               arg1 = (TREE_TYPE (arg1));
-
-           arg1 = build_pointer_type (arg1);
-         }
-
-       /* FIXME */
-       rval = build_method_call
-         (build_indirect_ref (build1 (NOP_EXPR, arg1,
-                                      error_mark_node),
-                              NULL_PTR),
-          fnname, arglist, NULL_TREE, flags);
-#if 0
-       /* This can happen when operator delete is protected.  */
-       my_friendly_assert (rval != error_mark_node, 250);
-       TREE_TYPE (rval) = void_type_node;
-#endif
-       return rval;
-      }
+      /* Use build_op_new_call and build_op_delete_call instead. */
+      my_friendly_abort (981018);
 
     case CALL_EXPR:
       return build_object_call (arg1, arg2);
@@ -2898,10 +2835,8 @@ build_op_new_call (code, type, args, flags)
   if (IS_AGGR_TYPE (type) && ! (flags & LOOKUP_GLOBAL)
       && (TYPE_GETS_NEW (type) & (1 << (code == VEC_NEW_EXPR))))
     {
-      tree dummy = build1 (NOP_EXPR, build_pointer_type (type),
-                          error_mark_node);
-      dummy = build_indirect_ref (dummy, "new");
-      return build_method_call (dummy, fnname, args, NULL_TREE, flags);
+      return build_method_call (build_dummy_object (type),
+                               fnname, args, NULL_TREE, flags);
     }
   else
     return build_new_function_call 
@@ -3716,8 +3651,7 @@ build_new_method_call (instance, name, args, basetype_path, flags)
       && value_member (cand->fn, get_abstract_virtuals (basetype)))
     cp_error ("abstract virtual `%#D' called from constructor", cand->fn);
   if (TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE
-      && TREE_CODE (instance_ptr) == NOP_EXPR
-      && TREE_OPERAND (instance_ptr, 0) == error_mark_node)
+      && is_dummy_object (instance_ptr))
     cp_error ("cannot call member function `%D' without object", cand->fn);
 
   if (DECL_VINDEX (cand->fn) && ! (flags & LOOKUP_NONVIRTUAL)
index 785279c..70a905f 100644 (file)
@@ -5045,17 +5045,11 @@ instantiate_type (lhstype, rhs, complain)
            if (function == error_mark_node)
              return error_mark_node;
            my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 185);
-           if (DECL_VINDEX (function))
-             {
-               tree base = TREE_OPERAND (rhs, 0);
-               tree base_ptr = build_unary_op (ADDR_EXPR, base, 0);
-               if (base_ptr == error_mark_node)
-                 return error_mark_node;
-               base_ptr = convert_pointer_to (DECL_CONTEXT (function), base_ptr);
-               if (base_ptr == error_mark_node)
-                 return error_mark_node;
-               return build_vfn_ref (&base_ptr, base, DECL_VINDEX (function));
-             }
+
+           if (! DECL_STATIC_FUNCTION_P (function))
+             cp_error ("reference to `%D' can only be used in a call",
+                       function);
+
            mark_used (function);
            return function;
          }
@@ -5293,49 +5287,11 @@ instantiate_type (lhstype, rhs, complain)
                elem = OVL_NEXT (elem);
          }
 
-       /* No exact match found, look for a compatible method.  */
-       for (baselink = rhs; baselink;
-            baselink = next_baselink (baselink))
-         {
-           elem = TREE_VALUE (baselink);
-           for (; elem; elem = OVL_NEXT (elem))
-             if (comp_target_types (lhstype, 
-                                    TREE_TYPE (OVL_CURRENT (elem)), 1) > 0)
-               break;
-           if (elem)
-             {
-               tree save_elem = OVL_CURRENT (elem);
-               for (elem = OVL_NEXT (elem); elem; elem = OVL_NEXT (elem))
-                 if (comp_target_types (lhstype, 
-                                        TREE_TYPE (OVL_CURRENT (elem)), 0) > 0)
-                   break;
-               if (elem)
-                 {
-                   if (complain)
-                     error ("ambiguous overload for overloaded method requested");
-                   return error_mark_node;
-                 }
-               mark_used (save_elem);
-               return save_elem;
-             }
-           name = rhs;
-           while (TREE_CODE (name) == TREE_LIST)
-             name = TREE_VALUE (name);
-           name = DECL_NAME (OVL_CURRENT (name));
-#if 0
-           if (TREE_CODE (lhstype) == FUNCTION_TYPE && globals < 0)
-             {
-               /* Try to instantiate from non-member functions.  */
-               rhs = lookup_name_nonclass (name);
-               if (rhs && TREE_CODE (rhs) == TREE_LIST)
-                 {
-                   /* This code seems to be missing a `return'.  */
-                   my_friendly_abort (4);
-                   instantiate_type (lhstype, rhs, complain);
-                 }
-             }
-#endif
-         }
+       name = rhs;
+       while (TREE_CODE (name) == TREE_LIST)
+         name = TREE_VALUE (name);
+       name = DECL_NAME (OVL_CURRENT (name));
+
        if (complain)
          cp_error ("no compatible member functions named `%D'", name);
        return error_mark_node;
index a7ab145..d499327 100644 (file)
@@ -3084,6 +3084,9 @@ extern tree mapcar                                PROTO((tree, tree (*) (tree)));
 extern tree no_linkage_check                   PROTO((tree));
 extern void debug_binfo                                PROTO((tree));
 extern void push_expression_obstack            PROTO((void));
+extern tree build_dummy_object                 PROTO((tree));
+extern tree maybe_dummy_object                 PROTO((tree, tree *));
+extern int is_dummy_object                     PROTO((tree));
 #define scratchalloc expralloc
 #define scratch_tree_cons expr_tree_cons
 #define build_scratch_list build_expr_list
index a228e27..3058641 100644 (file)
@@ -107,21 +107,8 @@ cp_convert_to_pointer (type, expr)
         functions.  */
       if (TYPE_PTRMEMFUNC_P (intype))
        {
-         tree decl, basebinfo;
          tree fntype = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (intype));
-         tree t = TYPE_METHOD_BASETYPE (fntype);
-
-         if (current_class_type == 0
-             || get_base_distance (t, current_class_type, 0, &basebinfo)
-             == -1)
-           {
-             decl = build1 (NOP_EXPR, t, error_mark_node);
-           }
-         else if (current_class_ptr == 0)
-           decl = build1 (NOP_EXPR, t, error_mark_node);
-         else
-           decl = current_class_ref;
-
+         tree decl = maybe_dummy_object (TYPE_METHOD_BASETYPE (fntype), 0);
          expr = build (OFFSET_REF, fntype, decl, expr);
        }
 
index 1a85dcb..f0b3167 100644 (file)
@@ -4539,9 +4539,13 @@ arg_assoc (k, n)
 
   if (TREE_CODE (n) == ADDR_EXPR)
     n = TREE_OPERAND (n, 0);
+  if (TREE_CODE (n) == COMPONENT_REF)
+    n = TREE_OPERAND (n, 1);
   while (TREE_CODE (n) == TREE_LIST)
     n = TREE_VALUE (n);
 
+  if (TREE_CODE (n) == FUNCTION_DECL)
+    return arg_assoc_type (k, TREE_TYPE (n));
   if (TREE_CODE (n) == TEMPLATE_ID_EXPR)
     {
       /* [basic.lookup.koenig]
@@ -4604,7 +4608,7 @@ arg_assoc (k, n)
       my_friendly_assert (TREE_CODE (n) == OVERLOAD, 980715);
       
       for (; n; n = OVL_CHAIN (n))
-       if (arg_assoc (k, OVL_FUNCTION (n)))
+       if (arg_assoc_type (k, TREE_TYPE (OVL_FUNCTION (n))))
          return 1;
     }
 
index 52c519d..ba5243a 100644 (file)
@@ -1577,8 +1577,7 @@ dump_expr (t, nop)
     case OFFSET_REF:
       {
        tree ob = TREE_OPERAND (t, 0);
-       if (TREE_CODE (ob) == NOP_EXPR
-           && TREE_OPERAND (ob, 0) == error_mark_node)
+       if (is_dummy_object (ob))
          {
            if (TREE_CODE (TREE_OPERAND (t, 1)) == FUNCTION_DECL)
              /* A::f */
index 985718c..47c8355 100644 (file)
@@ -1359,7 +1359,6 @@ build_member_call (type, name, parmlist)
   tree t;
   tree method_name;
   int dtor = 0;
-  int dont_use_this = 0;
   tree basetype_path, decl;
 
   if (TREE_CODE (name) == TEMPLATE_ID_EXPR
@@ -1415,23 +1414,11 @@ build_member_call (type, name, parmlist)
       return error_mark_node;
     }
 
-  /* No object?  Then just fake one up, and let build_method_call
-     figure out what to do.  */
-  if (current_class_type == 0
-      || get_base_distance (type, current_class_type, 0, &basetype_path) == -1)
-    dont_use_this = 1;
+  decl = maybe_dummy_object (type, &basetype_path);
 
-  if (dont_use_this)
-    {
-      basetype_path = TYPE_BINFO (type);
-      decl = build1 (NOP_EXPR, build_pointer_type (type), error_mark_node);
-    }
-  else if (current_class_ptr == 0)
-    {
-      dont_use_this = 1;
-      decl = build1 (NOP_EXPR, build_pointer_type (type), error_mark_node);
-    }
-  else
+  /* Convert 'this' to the specified type to disambiguate conversion
+     to the function's context.  */
+  if (decl == current_class_ref)
     {
       tree olddecl = current_class_ptr;
       tree oldtype = TREE_TYPE (TREE_TYPE (olddecl));
@@ -1440,13 +1427,10 @@ build_member_call (type, name, parmlist)
          tree newtype = build_type_variant (type, TYPE_READONLY (oldtype),
                                             TYPE_VOLATILE (oldtype));
          decl = convert_force (build_pointer_type (newtype), olddecl, 0);
+         decl = build_indirect_ref (decl, NULL_PTR);
        }
-      else
-       decl = olddecl;
     }
 
-  decl = build_indirect_ref (decl, NULL_PTR);
-
   if (method_name == constructor_name (type)
       || method_name == constructor_name_full (type))
     return build_functional_cast (type, parmlist);
@@ -1463,7 +1447,7 @@ build_member_call (type, name, parmlist)
        return error_mark_node;
       if (TREE_CODE (t) == FIELD_DECL)
        {
-         if (dont_use_this)
+         if (is_dummy_object (decl))
            {
              cp_error ("invalid use of non-static field `%D'", t);
              return error_mark_node;
@@ -1569,16 +1553,7 @@ build_offset_ref (type, name)
       return error_mark_node;
     }
 
-  if (current_class_type == 0
-      || get_base_distance (type, current_class_type, 0, &basebinfo) == -1)
-    {
-      basebinfo = TYPE_BINFO (type);
-      decl = build1 (NOP_EXPR, type, error_mark_node);
-    }
-  else if (current_class_ptr == 0)
-    decl = build1 (NOP_EXPR, type, error_mark_node);
-  else
-    decl = current_class_ref;
+  decl = maybe_dummy_object (type, &basebinfo);
 
   fnfields = lookup_fnfields (basebinfo, name, 1);
   fields = lookup_field (basebinfo, name, 0, 0);
@@ -1771,9 +1746,7 @@ resolve_offset_ref (exp)
 
   /* The first case is really just a reference to a member of `this'.  */
   if (TREE_CODE (member) == FIELD_DECL
-      && (base == current_class_ref
-         || (TREE_CODE (base) == NOP_EXPR
-             && TREE_OPERAND (base, 0) == error_mark_node)))
+      && (base == current_class_ref || is_dummy_object (base)))
     {
       tree basetype_path;
       tree access;
@@ -1815,8 +1788,7 @@ resolve_offset_ref (exp)
     }
 
   /* Ensure that we have an object.  */
-  if (TREE_CODE (base) == NOP_EXPR
-      && TREE_OPERAND (base, 0) == error_mark_node)
+  if (is_dummy_object (base))
     addr = error_mark_node;
   else
     /* If this is a reference to a member function, then return the
index 400aead..6d31ce4 100644 (file)
@@ -1866,6 +1866,17 @@ hack_identifier (value, name)
       TREE_USED (value) = 1;
       value = build_component_ref (current_class_ref, name, NULL_TREE, 1);
     }
+  else if (TREE_CODE (value) == FUNCTION_DECL
+          && DECL_FUNCTION_MEMBER_P (value))
+    {
+      tree decl;
+
+      if (IS_SIGNATURE (DECL_CLASS_CONTEXT (value)))
+       return value;
+
+      decl = maybe_dummy_object (DECL_CLASS_CONTEXT (value), 0);
+      value = build_component_ref (decl, name, NULL_TREE, 1);
+    }
   else if (really_overloaded_fn (value))
     {
 #if 0
index cf1ca8c..11c89df 100644 (file)
@@ -5596,6 +5596,8 @@ tsubst (t, args, in_decl)
                  return arg;
              }
          }
+       else
+         my_friendly_abort (981018);
 
        if (level == 1)
          /* This can happen during the attempted tsubst'ing in
@@ -5990,6 +5992,7 @@ tsubst_copy (t, args, in_decl)
     case CONST_CAST_EXPR:
     case STATIC_CAST_EXPR:
     case DYNAMIC_CAST_EXPR:
+    case NOP_EXPR:
       return build1
        (code, tsubst (TREE_TYPE (t), args, in_decl),
         tsubst_copy (TREE_OPERAND (t, 0), args, in_decl));
index 9aa094d..b943b83 100644 (file)
@@ -2629,3 +2629,56 @@ member_p (decl)
   tree ctx = DECL_CONTEXT (decl);
   return (ctx && TREE_CODE_CLASS (TREE_CODE (ctx)) == 't');
 }
+
+/* Create a placeholder for member access where we don't actually have an
+   object that the access is against.  */
+
+tree
+build_dummy_object (type)
+     tree type;
+{
+  tree decl = build1 (NOP_EXPR, build_pointer_type (type), error_mark_node);
+  return build_indirect_ref (decl, NULL_PTR);
+}
+
+/* We've gotten a reference to a member of TYPE.  Return *this if appropriate,
+   or a dummy object otherwise.  If BINFOP is non-0, it is filled with the
+   binfo path from current_class_type to TYPE, or 0.  */
+
+tree
+maybe_dummy_object (type, binfop)
+     tree type;
+     tree *binfop;
+{
+  tree decl, context;
+
+  if (current_class_type
+      && get_base_distance (type, current_class_type, 0, binfop) != -1)
+    context = current_class_type;
+  else
+    {
+      /* Reference from a nested class member function.  */
+      context = type;
+      if (binfop)
+       *binfop = TYPE_BINFO (type);
+    }
+
+  if (current_class_ref && context == current_class_type)
+    decl = current_class_ref;
+  else
+    decl = build_dummy_object (context);
+
+  return decl;
+}
+
+/* Returns 1 if OB is a placeholder object, or a pointer to one.  */
+
+int
+is_dummy_object (ob)
+     tree ob;
+{
+  if (TREE_CODE (ob) == INDIRECT_REF)
+    ob = TREE_OPERAND (ob, 0);
+  return (TREE_CODE (ob) == NOP_EXPR
+         && TREE_OPERAND (ob, 0) == error_mark_node);
+}
index c2f6eba..5cd21f1 100644 (file)
@@ -2078,57 +2078,27 @@ build_component_ref (datum, component, basetype_path, protect)
            return error_mark_node;
          if (fndecls)
            {
+             /* If the function is unique and static, we can resolve it
+                now.  Otherwise, we have to wait and see what context it is
+                used in; a component_ref involving a non-static member
+                function can only be used in a call (expr.ref).  */
              if (TREE_CHAIN (fndecls) == NULL_TREE
-                 && TREE_CODE (TREE_VALUE (fndecls)) != OVERLOAD)
+                 && TREE_CODE (TREE_VALUE (fndecls)) == FUNCTION_DECL
+                 && DECL_STATIC_FUNCTION_P (TREE_VALUE (fndecls)))
                {
-                 tree access, fndecl;
+                 tree fndecl;
 
-                 /* Unique, so use this one now.  */
                  basetype = TYPE_MAIN_VARIANT (TREE_PURPOSE (fndecls));
                  fndecl = TREE_VALUE (fndecls);
-                 access = compute_access (TREE_PURPOSE (fndecls), fndecl);
-                 if (access == access_public_node)
-                   {
-                     if (DECL_VINDEX (fndecl)
-                         && ! resolves_to_fixed_type_p (datum, 0))
-                       {
-                         tree addr = build_unary_op (ADDR_EXPR, datum, 0);
-                         tree fntype = TREE_TYPE (fndecl);
-
-                         addr = convert_pointer_to (DECL_CONTEXT (fndecl),
-                                                    addr);
-                         datum = build_indirect_ref (addr, NULL_PTR);
-                         my_friendly_assert (datum != error_mark_node, 310);
-                         fndecl = build_vfn_ref (&addr, datum,
-                                                 DECL_VINDEX (fndecl));
-                         /* The type of fndecl is a function type,
-                            not a pointer-to-function type, since
-                            build_vfn_ref returns not the correct
-                            vtable slot, but the indirection of the
-                            correct vtable slot.  */
-                         TREE_TYPE (fndecl) = fntype;
-                       }
-                     else
-                       mark_used (fndecl);
-                     return build (OFFSET_REF, TREE_TYPE (fndecl),
-                                   datum, fndecl);
-                   }
-                 if (access == access_protected_node)
-                   cp_error ("member function `%D' is protected", fndecl);
-                 else
-                   cp_error ("member function `%D' is private", fndecl);
-                 return error_mark_node;
+                 enforce_access (TREE_PURPOSE (fndecls), fndecl);
+                 mark_used (fndecl);
+                 return fndecl;
                }
              else
                {
-                 /* Just act like build_offset_ref, since the object does
-                     not matter unless we're actually calling the function.  */
-                 tree t;
-
-                 t = build_tree_list (error_mark_node, fndecls);
-                 TREE_TYPE (t) = build_offset_type (basetype,
-                                                    unknown_type_node);
-                 return t;
+                 ref = build (COMPONENT_REF, unknown_type_node,
+                              datum, fndecls);
+                 return ref;
                }
            }
 
@@ -2622,9 +2592,7 @@ build_x_function_call (function, params, decl)
              return error_mark_node;
            }
          /* Yow: call from a static member function.  */
-         decl = build1 (NOP_EXPR, build_pointer_type (current_class_type),
-                        error_mark_node);
-         decl = build_indirect_ref (decl, NULL_PTR);
+         decl = build_dummy_object (current_class_type);
        }
 
       /* Put back explicit template arguments, if any.  */
@@ -2636,12 +2604,10 @@ build_x_function_call (function, params, decl)
   else if (TREE_CODE (function) == COMPONENT_REF
           && type == unknown_type_node)
     {
-      /* Should we undo what was done in build_component_ref? */
-      if (TREE_CODE (TREE_PURPOSE (TREE_OPERAND (function, 1))) == TREE_VEC)
-       /* Get the name that build_component_ref hid.  */
-       function = DECL_NAME (TREE_VALUE (TREE_OPERAND (function, 1)));
-      else
-       function = TREE_PURPOSE (TREE_OPERAND (function, 1));
+      /* Undo what we did in build_component_ref.  */
+      decl = TREE_OPERAND (function, 0);
+      function = TREE_OPERAND (function, 1);
+      function = DECL_NAME (OVL_CURRENT (TREE_VALUE (function)));
       return build_method_call (decl, function, params,
                                NULL_TREE, LOOKUP_NORMAL);
     }
@@ -4248,6 +4214,8 @@ build_component_addr (arg, argtype, msg)
   tree basetype = decl_type_context (field);
   tree rval = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0);
 
+  my_friendly_assert (TREE_CODE (field) == FIELD_DECL, 981018);
+
   if (DECL_C_BIT_FIELD (field))
     {
       error (msg, IDENTIFIER_POINTER (DECL_NAME (field)));
@@ -4665,24 +4633,7 @@ build_unary_op (code, xarg, noconvert)
          return build1 (ADDR_EXPR, unknown_type_node, arg);
        }
 
-      if (TREE_CODE (arg) == OVERLOAD 
-         || (TREE_CODE (arg) == OFFSET_REF
-             && TREE_CODE (TREE_OPERAND (arg, 1)) == TEMPLATE_ID_EXPR))
-       return build1 (ADDR_EXPR, unknown_type_node, arg);
-      else if (TREE_CODE (arg) == TREE_LIST)
-       {
-         if (TREE_CODE (TREE_VALUE (arg)) == FUNCTION_DECL)
-           /* Unique overloaded non-member function.  */
-           return build_unary_op (ADDR_EXPR, TREE_VALUE (arg), 0);
-         if (TREE_CHAIN (arg) == NULL_TREE
-             && TREE_CODE (TREE_VALUE (arg)) == TREE_LIST
-             && TREE_CODE (TREE_VALUE (TREE_VALUE (arg))) != OVERLOAD)
-           /* Unique overloaded member function.  */
-           return build_unary_op (ADDR_EXPR, TREE_VALUE (TREE_VALUE (arg)),
-                                  0);
-         return build1 (ADDR_EXPR, unknown_type_node, arg);
-       }
-      else if (TREE_CODE (arg) == TEMPLATE_ID_EXPR)
+      if (TREE_CODE (arg) == TEMPLATE_ID_EXPR)
        {
          tree targs;
          tree fn;
@@ -4705,6 +4656,8 @@ build_unary_op (code, xarg, noconvert)
 
          return build1 (ADDR_EXPR, unknown_type_node, arg);
        }
+      else if (type_unknown_p (arg))
+       return build1 (ADDR_EXPR, unknown_type_node, arg);
 
       /* Handle complex lvalues (when permitted)
         by reduction to simpler cases.  */
@@ -4890,9 +4843,7 @@ unary_complex_lvalue (code, arg)
          tree type;
 
          if (TREE_OPERAND (arg, 0)
-             && (TREE_CODE (TREE_OPERAND (arg, 0)) != NOP_EXPR
-                 || (TREE_OPERAND (TREE_OPERAND (arg, 0), 0)
-                     != error_mark_node))
+             && ! is_dummy_object (TREE_OPERAND (arg, 0))
              && TREE_CODE (t) != FIELD_DECL)
            {
              cp_error ("taking address of bound pointer-to-member expression");
@@ -5770,7 +5721,7 @@ build_c_cast (type, expr)
   if (TREE_CODE (type) == VOID_TYPE)
     value = build1 (CONVERT_EXPR, type, value);
   else if (TREE_TYPE (value) == NULL_TREE
-      || type_unknown_p (value))
+          || type_unknown_p (value))
     {
       value = instantiate_type (type, value, 1);
       /* Did we lose?  */
index 14e7ae2..809b89d 100644 (file)
@@ -352,19 +352,14 @@ ack (s, v, v2)
    59 is, so they can understand how to work around it, should they
    ever run into it.
 
-   Note, there will be no more calls in the C++ front end to abort,
-   because the C++ front end is so unreliable still.  The C front end
-   can get away with calling abort, because for most of the calls to
-   abort on most machines, it, I suspect, can be proven that it is
-   impossible to ever call abort.  The same is not yet true for C++,
-   one day, maybe it will be.
-
    We used to tell people to "fix the above error[s] and try recompiling
    the program" via a call to fatal, but that message tended to look
    silly.  So instead, we just do the equivalent of a call to fatal in the
-   same situation (call exit).  */
+   same situation (call exit).
 
-/* First used: 0 (reserved), Last used: 369.  Free: */
+   We used to assign sequential numbers for the aborts; now we use an
+   encoding of the date the abort was added, since that has more meaning
+   when we only see the error message.  */
 
 static int abortcount = 0;