OSDN Git Service

* call.c (build_addr_func): Handle bound pointers-to-members.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 4 Jul 2003 05:05:19 +0000 (05:05 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 4 Jul 2003 05:05:19 +0000 (05:05 +0000)
(build_method_call): Do not call resolve_offset_ref.
(implicit_conversion): Likewise.
(resolve_scoped_fn_name): Use finish_non_static_data_member, not
resolve_offset_ref.
(resolve_args): Do not call resolve_offset_ref.
(build_conditional_expr): Likewise.
(build_new_method_call): Likewise.
* cp-tree.def (OFFSET_REF): Update documentation.
(cp_convert_to_pointer): Update handling of conversions from
pointers to members to pointers.
(ocp_convert): Do not call resolve_offset_ref.
(convert_to_void): Likewise.
(build_expr_type_conversion): Likewise.
(delete_sanity): Likewise.
(resolve_offset_ref): Simplify greatly.
(build_vec_delete): Do not call resolve_offset_ref.
* parser.c (cp_parser_postfix_expression): Call resolve_offset_ref
if appropriate.
(cp_parser_unary_expression): Use
cp_parser_simple_cast_expression.
(cp_parser_delete_expression): Likewise.
(cp_parser_cast_expression): Likewise.
(cp_parser_pm_expression): Use cp_parser_binary_op.
(cp_parser_simple_cast_expression): New function.
* rtti.c (build_dynamic_cast_1): Do not call resolve_offset_ref.
* semantics.c (finish_increment_expr): Likewise.
(finish_typeof): Likewise.
* tree.c (lvalue_p_1): Do not handle OFFSET_REF.
* typeck.c (require_complete_type): Do not handle OFFSET_REFs.
(decay_conversion): Do not call resolve_offset_ref.
(finish_class_member_access_expr): Likewise.
(convert_arguments): Likewise.
(build_x_binary_op): Handle DOTSTAR_EXPR.
(condition_conversion): Do not call resolve_offset_ref.
(unary_complex_lvalue): Likewise.
(build_static_cast): Likewise.
(build_reinterpret_cast): Likewise.
(build_const_cast): Likewise.
(build_c_cast): Likewise.
(build_modify_expr): Likewise.
(convert_for_assignment): Likewise.
(convert_for_initialization): Likewise.
* typeck2.c (build_x_arrow): Likewise.
(build_m_component_ref): Simplify.

* g++.old-deja/g++.jason/typeid1.C: Add dg-error marker.
* g++.old-deja/g++.mike/net36.C: Tweak error messages.

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

15 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.def
gcc/cp/cvt.c
gcc/cp/decl2.c
gcc/cp/init.c
gcc/cp/parser.c
gcc/cp/rtti.c
gcc/cp/semantics.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.jason/typeid1.C
gcc/testsuite/g++.old-deja/g++.mike/net36.C

index ba6abbe..076dcbd 100644 (file)
@@ -6,6 +6,52 @@
 
 2003-07-03  Mark Mitchell  <mark@codesourcery.com>
 
+       * call.c (build_addr_func): Handle bound pointers-to-members.
+       (build_method_call): Do not call resolve_offset_ref.
+       (implicit_conversion): Likewise.
+       (resolve_scoped_fn_name): Use finish_non_static_data_member, not
+       resolve_offset_ref.
+       (resolve_args): Do not call resolve_offset_ref.
+       (build_conditional_expr): Likewise.
+       (build_new_method_call): Likewise.
+       * cp-tree.def (OFFSET_REF): Update documentation.
+       (cp_convert_to_pointer): Update handling of conversions from
+       pointers to members to pointers.
+       (ocp_convert): Do not call resolve_offset_ref.
+       (convert_to_void): Likewise.
+       (build_expr_type_conversion): Likewise.
+       (delete_sanity): Likewise.
+       (resolve_offset_ref): Simplify greatly.
+       (build_vec_delete): Do not call resolve_offset_ref.
+       * parser.c (cp_parser_postfix_expression): Call resolve_offset_ref
+       if appropriate.
+       (cp_parser_unary_expression): Use
+       cp_parser_simple_cast_expression.
+       (cp_parser_delete_expression): Likewise.
+       (cp_parser_cast_expression): Likewise.
+       (cp_parser_pm_expression): Use cp_parser_binary_op.
+       (cp_parser_simple_cast_expression): New function.
+       * rtti.c (build_dynamic_cast_1): Do not call resolve_offset_ref.
+       * semantics.c (finish_increment_expr): Likewise.
+       (finish_typeof): Likewise.
+       * tree.c (lvalue_p_1): Do not handle OFFSET_REF.
+       * typeck.c (require_complete_type): Do not handle OFFSET_REFs.
+       (decay_conversion): Do not call resolve_offset_ref.
+       (finish_class_member_access_expr): Likewise.
+       (convert_arguments): Likewise.
+       (build_x_binary_op): Handle DOTSTAR_EXPR.
+       (condition_conversion): Do not call resolve_offset_ref.
+       (unary_complex_lvalue): Likewise.
+       (build_static_cast): Likewise.
+       (build_reinterpret_cast): Likewise.
+       (build_const_cast): Likewise.
+       (build_c_cast): Likewise.
+       (build_modify_expr): Likewise.
+       (convert_for_assignment): Likewise.
+       (convert_for_initialization): Likewise.
+       * typeck2.c (build_x_arrow): Likewise.
+       (build_m_component_ref): Simplify.
+       
        * call.c (build_scoped_method_call): Use convert_to_void.
        (build_method_call): Likewise.
        * class.c (check_field_decls): Remove dead code.
index bc1179b..e8a54dc 100644 (file)
@@ -317,21 +317,13 @@ build_addr_func (tree function)
      functions.  */
   if (TREE_CODE (type) == METHOD_TYPE)
     {
-      tree addr;
-
-      type = build_pointer_type (type);
-
-      if (!cxx_mark_addressable (function))
-       return error_mark_node;
-
-      addr = build1 (ADDR_EXPR, type, function);
-
-      /* Address of a static or external variable or function counts
-        as a constant */
-      if (staticp (function))
-       TREE_CONSTANT (addr) = 1;
-
-      function = addr;
+      if (TREE_CODE (function) == OFFSET_REF)
+       {
+         tree object = build_address (TREE_OPERAND (function, 0));
+         return get_member_function_from_ptrfunc (&object,
+                                                  TREE_OPERAND (function, 1));
+       }
+      function = build_address (function);
     }
   else
     function = default_conversion (function);
@@ -477,8 +469,6 @@ build_method_call (tree instance, tree name, tree parms,
   if (processing_template_decl)
     return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, NULL_TREE);
 
-  if (TREE_CODE (instance) == OFFSET_REF)
-    instance = resolve_offset_ref (instance);
   if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
     instance = convert_from_reference (instance);
   object_type = TREE_TYPE (instance);
@@ -1295,14 +1285,6 @@ implicit_conversion (tree to, tree from, tree expr, int flags)
 {
   tree conv;
 
-  /* Resolve expressions like `A::p' that we thought might become
-     pointers-to-members.  */
-  if (expr && TREE_CODE (expr) == OFFSET_REF)
-    {
-      expr = resolve_offset_ref (expr);
-      from = TREE_TYPE (expr);
-    }
-
   if (from == error_mark_node || to == error_mark_node
       || expr == error_mark_node)
     return NULL_TREE;
@@ -2790,7 +2772,7 @@ resolve_scoped_fn_name (tree scope, tree name)
 
       /* It might be the name of a function pointer member.  */
       if (fn && TREE_CODE (fn) == FIELD_DECL)
-       fn = resolve_offset_ref (build_offset_ref (scope, fn));
+       fn = finish_non_static_data_member (fn, scope);
     }
   
   if (!fn)
@@ -2831,8 +2813,6 @@ resolve_args (tree args)
          error ("invalid use of void expression");
          return error_mark_node;
        }
-      else if (TREE_CODE (arg) == OFFSET_REF)
-       arg = resolve_offset_ref (arg);
       arg = convert_from_reference (arg);
       TREE_VALUE (t) = arg;
     }
@@ -3565,8 +3545,6 @@ prep_operand (tree operand)
 {
   if (operand)
     {
-      if (TREE_CODE (operand) == OFFSET_REF)
-       operand = resolve_offset_ref (operand);
       operand = convert_from_reference (operand);
       if (CLASS_TYPE_P (TREE_TYPE (operand))
          && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (operand)))
@@ -5025,8 +5003,6 @@ build_new_method_call (tree instance, tree fns, tree args,
   if (args == error_mark_node)
     return error_mark_node;
 
-  if (TREE_CODE (instance) == OFFSET_REF)
-    instance = resolve_offset_ref (instance);
   if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
     instance = convert_from_reference (instance);
   basetype = TYPE_MAIN_VARIANT (TREE_TYPE (instance));
index 7d65731..e988a4e 100644 (file)
@@ -26,22 +26,22 @@ Boston, MA 02111-1307, USA.  */
 /* An OFFSET_REF is used in two situations:
 
    1. An expression of the form `A::m' where `A' is a class and `m' is
-      a non-static data member.  In this case, operand 0 will be a
-      TYPE (corresponding to `A') and operand 1 will be a FIELD_DECL
-      (corresponding to `m'.
+      a non-static member.  In this case, operand 0 will be a TYPE
+      (corresponding to `A') and operand 1 will be a FIELD_DECL,
+      BASELINK, or TEMPLATE_ID_EXPR (corresponding to `m').
 
       The expression is a pointer-to-member if its address is taken,
       but simply denotes a member of the object if its address isnot
       taken.  In the latter case, resolve_offset_ref is used to
       convert it to a representation of the member referred to by the
       OFFSET_REF.
+      
+      This form is only used during the parsing phase; once semantic
+      analysis has taken place they are eliminated.
 
    2. An expression of the form `x.*p'.  In this case, operand 0 will
       be an expression corresponding to `x' and operand 1 will be an
-      expression with pointer-to-member type.
-
-   OFFSET_REFs are only used during the parsing phase; once semantic
-   analysis has taken place they are eliminated.  */
+      expression with pointer-to-member type.  */
 DEFTREECODE (OFFSET_REF, "offset_ref", 'r', 2)
 
 /* A pointer-to-member constant.  For a pointer-to-member constant
index 29f0222..24a3416 100644 (file)
@@ -109,24 +109,26 @@ cp_convert_to_pointer (tree type, tree expr, bool force)
         functions.  */
       if (TYPE_PTRMEMFUNC_P (intype))
        {
-         tree fntype = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (intype));
-         tree decl = maybe_dummy_object (TYPE_METHOD_BASETYPE (fntype), 0);
-         expr = build (OFFSET_REF, fntype, decl, expr);
+         if (pedantic || warn_pmf2ptr)
+           pedwarn ("converting from `%T' to `%T'", intype, type);
+         if (TREE_CODE (expr) == PTRMEM_CST)
+           expr = build_address (PTRMEM_CST_MEMBER (expr));
+         else
+           {
+             tree decl = maybe_dummy_object (TYPE_PTRMEM_CLASS_TYPE (intype), 
+                                             0);
+             decl = build_address (decl);
+             expr = get_member_function_from_ptrfunc (&decl, expr);
+           }
        }
-
-      if (TREE_CODE (expr) == OFFSET_REF
-         && TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
-       expr = resolve_offset_ref (expr);
-      if (TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
-       expr = build_addr_func (expr);
-      if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
+      else if (TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
        {
-         if (TREE_CODE (TREE_TYPE (TREE_TYPE (expr))) == METHOD_TYPE)
-           if (pedantic || warn_pmf2ptr)
-             pedwarn ("converting from `%T' to `%T'", TREE_TYPE (expr),
-                         type);
-         return build1 (NOP_EXPR, type, expr);
+         if (pedantic || warn_pmf2ptr)
+           pedwarn ("converting from `%T' to `%T'", intype, type);
+         expr = build_addr_func (expr);
        }
+      if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
+       return build_nop (type, expr);
       intype = TREE_TYPE (expr);
     }
 
@@ -233,6 +235,19 @@ cp_convert_to_pointer (tree type, tree expr, bool force)
     return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0);
   else if (TYPE_PTRMEMFUNC_P (intype))
     {
+      if (!warn_pmf2ptr)
+       {
+         if (TREE_CODE (expr) == PTRMEM_CST)
+           return cp_convert_to_pointer (type,
+                                         PTRMEM_CST_MEMBER (expr),
+                                         force);
+         else if (TREE_CODE (expr) == OFFSET_REF)
+           {
+             tree object = TREE_OPERAND (expr, 0);
+             return get_member_function_from_ptrfunc (&object,
+                                                      TREE_OPERAND (expr, 1));
+           }
+       }
       error ("cannot convert `%E' from type `%T' to type `%T'",
                expr, intype, type);
       return error_mark_node;
@@ -663,9 +678,6 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
       code = TREE_CODE (type);
     }
 
-  if (TREE_CODE (e) == OFFSET_REF)
-    e = resolve_offset_ref (e);
-
   if (INTEGRAL_CODE_P (code))
     {
       tree intype = TREE_TYPE (e);
@@ -879,10 +891,6 @@ convert_to_void (tree expr, const char *implicit)
         break;
       }
 
-    case OFFSET_REF:
-      expr = resolve_offset_ref (expr);
-      break;
-
     default:;
     }
   {
@@ -1023,8 +1031,6 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
       && !(desires & WANT_NULL))
     warning ("converting NULL to non-pointer type");
     
-  if (TREE_CODE (expr) == OFFSET_REF)
-    expr = resolve_offset_ref (expr);
   expr = convert_from_reference (expr);
   basetype = TREE_TYPE (expr);
 
index f701037..78e84ca 100644 (file)
@@ -481,8 +481,6 @@ delete_sanity (tree exp, tree size, int doing_vec, int use_global_delete)
       return t;
     }
 
-  if (TREE_CODE (exp) == OFFSET_REF)
-    exp = resolve_offset_ref (exp);
   exp = convert_from_reference (exp);
   t = build_expr_type_conversion (WANT_POINTER, exp, true);
 
index b88f1f2..e1a19b1 100644 (file)
@@ -1689,121 +1689,45 @@ build_offset_ref (tree type, tree name)
 tree
 resolve_offset_ref (tree exp)
 {
-  tree type = TREE_TYPE (exp);
-  tree base = NULL_TREE;
   tree member;
-  tree basetype, addr;
-
-  if (TREE_CODE (exp) == OFFSET_REF)
-    {
-      member = TREE_OPERAND (exp, 1);
-      base = TREE_OPERAND (exp, 0);
-    }
-  else
-    {
-      my_friendly_assert (TREE_CODE (type) == OFFSET_TYPE, 214);
-      if (TYPE_OFFSET_BASETYPE (type) != current_class_type)
-       {
-         error ("object missing in use of pointer-to-member construct");
-         return error_mark_node;
-       }
-      member = exp;
-      type = TREE_TYPE (type);
-      base = current_class_ref;
-    }
-
-  if (BASELINK_P (member) || TREE_CODE (member) == TEMPLATE_ID_EXPR)
-    return build_unary_op (ADDR_EXPR, exp, 0);
-  
-  if (TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE)
-    {
-      if (!flag_ms_extensions)
-        /* A single non-static member, make sure we don't allow a
-           pointer-to-member.  */
-        exp = ovl_cons (member, NULL_TREE);
-      
-      return build_unary_op (ADDR_EXPR, exp, 0);
-    }
-  
-  if ((TREE_CODE (member) == VAR_DECL
-       && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (member))
-       && ! TYPE_PTRMEM_P (TREE_TYPE (member)))
-      || TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE)
-    {
-      /* These were static members.  */
-      if (!cxx_mark_addressable (member))
-       return error_mark_node;
-      return member;
-    }
 
-  if (TREE_CODE (TREE_TYPE (member)) == POINTER_TYPE
-      && TREE_CODE (TREE_TYPE (TREE_TYPE (member))) == METHOD_TYPE)
-    return member;
+  my_friendly_assert (TREE_CODE (exp) == OFFSET_REF, 20030703);
 
-  /* Syntax error can cause a member which should
-     have been seen as static to be grok'd as non-static.  */
-  if (TREE_CODE (member) == FIELD_DECL && current_class_ref == NULL_TREE)
-    {
-      cp_error_at ("member `%D' is non-static but referenced as a static member",
-                  member);
-      error ("at this point in file");
-      return error_mark_node;
-    }
+  member = TREE_OPERAND (exp, 1);
 
-  /* The first case is really just a reference to a member of `this'.  */
-  if (TREE_CODE (member) == FIELD_DECL
-      && (base == current_class_ref || is_dummy_object (base)))
-    {
-      tree binfo = NULL_TREE;
+  /* If MEMBER is non-static, then the program has fallen afoul of
+     [expr.prim]:
 
-      /* Try to get to basetype from 'this'; if that doesn't work,
-         nothing will.  */
-      base = current_class_ref;
+       An id-expression that denotes a nonstatic data member or
+       nonstatic member function of a class can only be used:
 
-      /* First convert to the intermediate base specified, if appropriate.  */
-      if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
-       base = build_scoped_ref (base, TYPE_OFFSET_BASETYPE (type), &binfo);
+       -- as part of a class member access (_expr.ref_) in which the
+       object-expression refers to the member's class or a class
+       derived from that class, or
 
-      return build_class_member_access_expr (base, member,
-                                            /*access_path=*/NULL_TREE,
-                                            /*preserve_reference=*/false);
-    }
+       -- to form a pointer to member (_expr.unary.op_), or
 
-  /* Ensure that we have an object.  */
-  if (is_dummy_object (base))
-    addr = error_mark_node;
-  else
-    /* If this is a reference to a member function, then return the
-       address of the member function (which may involve going
-       through the object's vtable), otherwise, return an expression
-       for the dereferenced pointer-to-member construct.  */
-    addr = build_unary_op (ADDR_EXPR, base, 0);
+       -- in the body of a nonstatic member function of that class or
+       of a class derived from that class (_class.mfct.nonstatic_), or
 
-  if (TYPE_PTRMEM_P (TREE_TYPE (member)))
+       -- in a mem-initializer for a constructor for that class or for
+       a class derived from that class (_class.base.init_).  */
+  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (member))
     {
-      if (addr == error_mark_node)
-       {
-         error ("object missing in `%E'", exp);
-         return error_mark_node;
-       }
-
-      basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (TREE_TYPE (member)));
-      basetype = lookup_base (TREE_TYPE (TREE_TYPE (addr)),
-                             basetype, ba_check, NULL);
-      addr = build_base_path (PLUS_EXPR, addr, basetype, 1);
-      
-      member = cp_convert (ptrdiff_type_node, member);
-
-      addr = build (PLUS_EXPR, build_pointer_type (type), addr, member);
-      return build_indirect_ref (addr, 0);
+      /* In Microsoft mode, treat a non-static member function as if
+        it were a pointer-to-member.  */
+      if (flag_ms_extensions)
+       return build_unary_op (ADDR_EXPR, exp, 0);
+      error ("invalid use of non-static member function `%D'", member);
+      return error_mark_node;
     }
-  else if (TYPE_PTRMEMFUNC_P (TREE_TYPE (member)))
+  else if (TREE_CODE (member) == FIELD_DECL)
     {
-      return get_member_function_from_ptrfunc (&addr, member);
+      error ("invalid use of non-static data member `%D'", member);
+      return error_mark_node;
     }
-  abort ();
-  /* NOTREACHED */
-  return NULL_TREE;
+
+  return member;
 }
 
 /* If DECL is a `const' declaration, and its value is a known
@@ -3300,9 +3224,6 @@ build_vec_delete (tree base, tree maxindex,
   tree rval;
   tree base_init = NULL_TREE;
 
-  if (TREE_CODE (base) == OFFSET_REF)
-    base = resolve_offset_ref (base);
-
   type = TREE_TYPE (base);
 
   if (TREE_CODE (type) == POINTER_TYPE)
index 6155af4..d19e403 100644 (file)
@@ -1667,6 +1667,8 @@ static bool cp_parser_check_declarator_template_parameters
   (cp_parser *, tree);
 static bool cp_parser_check_template_parameters
   (cp_parser *, unsigned);
+static tree cp_parser_simple_cast_expression
+  (cp_parser *);
 static tree cp_parser_binary_expression
   (cp_parser *, const cp_parser_token_tree_map, cp_parser_expression_fn);
 static tree cp_parser_global_scope_opt
@@ -3846,8 +3848,15 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
                  BASELINK_ACCESS_BINFO (postfix_expression),
                  /*preserve_reference=*/false));
          else if (done)
-           return build_offset_ref (qualifying_class,
-                                    postfix_expression);
+           {
+             /* The expression is a qualified name whose address is not
+                being taken.  */
+             postfix_expression = build_offset_ref (qualifying_class,
+                                                    postfix_expression);
+             if (TREE_CODE (postfix_expression) == OFFSET_REF)
+               postfix_expression = resolve_offset_ref (postfix_expression);
+             return postfix_expression;
+           }
        }
     }
 
@@ -4379,7 +4388,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p)
            /* Save away the PEDANTIC flag.  */
            cp_parser_extension_opt (parser, &saved_pedantic);
            /* Parse the cast-expression.  */
-           expr = cp_parser_cast_expression (parser, /*address_p=*/false);
+           expr = cp_parser_simple_cast_expression (parser);
            /* Restore the PEDANTIC flag.  */
            pedantic = saved_pedantic;
 
@@ -4394,8 +4403,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p)
            /* Consume the `__real__' or `__imag__' token.  */
            cp_lexer_consume_token (parser->lexer);
            /* Parse the cast-expression.  */
-           expression = cp_parser_cast_expression (parser,
-                                                   /*address_p=*/false);
+           expression = cp_parser_simple_cast_expression (parser);
            /* Create the complete representation.  */
            return build_x_unary_op ((keyword == RID_REALPART
                                      ? REALPART_EXPR : IMAGPART_EXPR),
@@ -4817,7 +4825,7 @@ cp_parser_delete_expression (cp_parser* parser)
     array_p = false;
 
   /* Parse the cast-expression.  */
-  expression = cp_parser_cast_expression (parser, /*address_p=*/false);
+  expression = cp_parser_simple_cast_expression (parser);
 
   return delete_sanity (expression, NULL_TREE, array_p, global_scope_p);
 }
@@ -4897,7 +4905,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p)
          ctor of T, but looks like a cast to function returning T
          without a dependent expression.  */
       if (!cp_parser_error_occurred (parser))
-       expr = cp_parser_cast_expression (parser, /*address_p=*/false);
+       expr = cp_parser_simple_cast_expression (parser);
 
       if (cp_parser_parse_definitely (parser))
        {
@@ -4943,42 +4951,14 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p)
 static tree
 cp_parser_pm_expression (cp_parser* parser)
 {
-  tree cast_expr;
-  tree pm_expr;
-
-  /* Parse the cast-expresion.  */
-  cast_expr = cp_parser_cast_expression (parser, /*address_p=*/false);
-  pm_expr = cast_expr;
-  /* Now look for pointer-to-member operators.  */
-  while (true)
-    {
-      cp_token *token;
-      enum cpp_ttype token_type;
-
-      /* Peek at the next token.  */
-      token = cp_lexer_peek_token (parser->lexer);
-      token_type = token->type;
-      /* If it's not `.*' or `->*' there's no pointer-to-member
-        operation.  */
-      if (token_type != CPP_DOT_STAR 
-         && token_type != CPP_DEREF_STAR)
-       break;
-
-      /* Consume the token.  */
-      cp_lexer_consume_token (parser->lexer);
-
-      /* Parse another cast-expression.  */
-      cast_expr = cp_parser_cast_expression (parser, /*address_p=*/false);
-
-      /* Build the representation of the pointer-to-member 
-        operation.  */
-      if (token_type == CPP_DEREF_STAR)
-       pm_expr = build_x_binary_op (MEMBER_REF, pm_expr, cast_expr);
-      else
-       pm_expr = build_m_component_ref (pm_expr, cast_expr);
-    }
+  static const cp_parser_token_tree_map map = {
+    { CPP_DEREF_STAR, MEMBER_REF },
+    { CPP_DOT_STAR, DOTSTAR_EXPR },
+    { CPP_EOF, ERROR_MARK }
+  };
 
-  return pm_expr;
+  return cp_parser_binary_expression (parser, map, 
+                                     cp_parser_simple_cast_expression);
 }
 
 /* Parse a multiplicative-expression.
@@ -14025,6 +14005,14 @@ cp_parser_single_declaration (cp_parser* parser,
   return decl;
 }
 
+/* Parse a cast-expression that is not the operand of a unary "&".  */
+
+static tree
+cp_parser_simple_cast_expression (cp_parser *parser)
+{
+  return cp_parser_cast_expression (parser, /*address_p=*/false);
+}
+
 /* Parse a functional cast to TYPE.  Returns an expression
    representing the cast.  */
 
index 74b7c90..af494e3 100644 (file)
@@ -473,12 +473,6 @@ build_dynamic_cast_1 (tree type, tree expr)
       goto fail;
     }
 
-  if (TREE_CODE (expr) == OFFSET_REF)
-    {
-      expr = resolve_offset_ref (expr);
-      exprtype = TREE_TYPE (expr);
-    }
-
   if (tc == POINTER_TYPE)
     expr = convert_from_reference (expr);
   else if (TREE_CODE (exprtype) != REFERENCE_TYPE)
index 382bee5..3664590 100644 (file)
@@ -1476,13 +1476,6 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual)
 tree 
 finish_increment_expr (tree expr, enum tree_code code)
 {
-  /* If we get an OFFSET_REF, turn it into what it really means (e.g.,
-     a COMPONENT_REF).  This way if we've got, say, a reference to a
-     static member that's being operated on, we don't end up trying to
-     find a member operator for the class it's in.  */
-
-  if (TREE_CODE (expr) == OFFSET_REF)
-    expr = resolve_offset_ref (expr);
   return build_x_unary_op (code, expr);  
 }
 
@@ -2083,9 +2076,6 @@ finish_typeof (tree expr)
       return type;
     }
 
-  if (TREE_CODE (expr) == OFFSET_REF)
-    expr = resolve_offset_ref (expr);
-
   type = TREE_TYPE (expr);
 
   if (!type || type == unknown_type_node)
index 6c6d9b9..9f8a119 100644 (file)
@@ -133,10 +133,6 @@ lvalue_p_1 (tree ref,
       /* A currently unresolved scope ref.  */
     case SCOPE_REF:
       abort ();
-    case OFFSET_REF:
-      if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL)
-       return clk_ordinary;
-      /* Fall through.  */
     case MAX_EXPR:
     case MIN_EXPR:
       op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
index 4900cbf..96b74fa 100644 (file)
@@ -105,17 +105,6 @@ require_complete_type (tree value)
   if (COMPLETE_TYPE_P (type))
     return value;
 
-  /* If we see X::Y, we build an OFFSET_TYPE which has
-     not been laid out.  Try to avoid an error by interpreting
-     it as this->X::Y, if reasonable.  */
-  if (TREE_CODE (value) == OFFSET_REF
-      && current_class_ref != 0
-      && TREE_OPERAND (value, 0) == current_class_ref)
-    {
-      value = resolve_offset_ref (value);
-      return require_complete_type (value);
-    }
-
   if (complete_type_or_else (type, value))
     return value;
   else
@@ -1486,11 +1475,6 @@ expr_sizeof (tree e)
       cxx_incomplete_type_error (e, TREE_TYPE (e));
       return c_sizeof (char_type_node);
     }
-  /* It's invalid to say `sizeof (X::i)' for `i' a non-static data
-     member unless you're in a non-static member of X.  So hand off to
-     resolve_offset_ref.  [expr.prim]  */
-  else if (TREE_CODE (e) == OFFSET_REF)
-    e = resolve_offset_ref (e);
 
   if (e == error_mark_node)
     return e;
@@ -1511,9 +1495,6 @@ decay_conversion (tree exp)
   register tree type;
   register enum tree_code code;
 
-  if (TREE_CODE (exp) == OFFSET_REF)
-    exp = resolve_offset_ref (exp);
-
   type = TREE_TYPE (exp);
   code = TREE_CODE (type);
 
@@ -1555,7 +1536,10 @@ decay_conversion (tree exp)
       return error_mark_node;
     }
   if (code == METHOD_TYPE)
-    abort ();
+    {
+      error ("invalid use of non-static member function");
+      return error_mark_node;
+    }
   if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
     return build_unary_op (ADDR_EXPR, exp, 0);
   if (code == ARRAY_TYPE)
@@ -2047,9 +2031,6 @@ finish_class_member_access_expr (tree object, tree name)
   if (processing_template_decl)
     return build_min_nt (COMPONENT_REF, object, name);
   
-  if (TREE_CODE (object) == OFFSET_REF)
-    object = resolve_offset_ref (object);
-
   object_type = TREE_TYPE (object);
   if (TREE_CODE (object_type) == REFERENCE_TYPE)
     {
@@ -2749,9 +2730,6 @@ convert_arguments (typelist, values, fndecl, flags)
          break;
        }
 
-      if (TREE_CODE (val) == OFFSET_REF)
-       val = resolve_offset_ref (val);
-
       /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
         Strip such NOP_EXPRs, since VAL is used in non-lvalue context.  */
       if (TREE_CODE (val) == NOP_EXPR
@@ -2865,6 +2843,9 @@ build_x_binary_op (code, arg1, arg2)
   if (processing_template_decl)
     return build_min_nt (code, arg1, arg2);
 
+  if (code == DOTSTAR_EXPR)
+    return build_m_component_ref (arg1, arg2);
+
   return build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE);
 }
 
@@ -3973,8 +3954,6 @@ condition_conversion (expr)
   tree t;
   if (processing_template_decl)
     return expr;
-  if (TREE_CODE (expr) == OFFSET_REF)
-    expr = resolve_offset_ref (expr);
   t = perform_implicit_conversion (boolean_type_node, expr);
   t = fold (build1 (CLEANUP_POINT_EXPR, boolean_type_node, t));
   return t;
@@ -4560,15 +4539,7 @@ unary_complex_lvalue (enum tree_code code, tree arg)
              return error_mark_node;
            }
          if (!PTRMEM_OK_P (arg))
-           {
-             /* This cannot form a pointer to method, so we must
-                resolve the offset ref, and take the address of the
-                result.  For instance,
-                       &(C::m)       */
-             arg = resolve_offset_ref (arg);
-
-             return build_unary_op (code, arg, 0);
-           }
+           return build_unary_op (code, arg, 0);
          
          if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
            {
@@ -4792,9 +4763,6 @@ build_static_cast (tree type, tree expr)
   if (type == error_mark_node || expr == error_mark_node)
     return error_mark_node;
 
-  if (TREE_CODE (expr) == OFFSET_REF)
-    expr = resolve_offset_ref (expr);
-
   if (processing_template_decl)
     {
       tree t = build_min (STATIC_CAST_EXPR, type, expr); 
@@ -4965,9 +4933,6 @@ build_reinterpret_cast (tree type, tree expr)
   if (type == error_mark_node || expr == error_mark_node)
     return error_mark_node;
 
-  if (TREE_CODE (expr) == OFFSET_REF)
-    expr = resolve_offset_ref (expr);
-
   if (processing_template_decl)
     {
       tree t = build_min (REINTERPRET_CAST_EXPR, type, expr);
@@ -5055,9 +5020,6 @@ build_const_cast (tree type, tree expr)
   if (type == error_mark_node || expr == error_mark_node)
     return error_mark_node;
 
-  if (TREE_CODE (expr) == OFFSET_REF)
-    expr = resolve_offset_ref (expr);
-
   if (processing_template_decl)
     {
       tree t = build_min (CONST_CAST_EXPR, type, expr);
@@ -5139,9 +5101,6 @@ build_c_cast (tree type, tree expr)
       && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
     value = TREE_OPERAND (value, 0);
 
-  if (TREE_CODE (value) == OFFSET_REF)
-    value = resolve_offset_ref (value);
-
   if (TREE_CODE (type) == ARRAY_TYPE)
     {
       /* Allow casting from T1* to T2[] because Cfront allows it.
@@ -5361,12 +5320,6 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
        return build (COMPOUND_EXPR, TREE_TYPE (lhs), preeval, cond);
       }
       
-    case OFFSET_REF:
-      lhs = resolve_offset_ref (lhs);
-      if (lhs == error_mark_node)
-       return error_mark_node;
-      olhstype = lhstype = TREE_TYPE (lhs);
-    
     default:
       break;
     }
@@ -6008,9 +5961,6 @@ convert_for_assignment (tree type, tree rhs,
   if (codel == OFFSET_TYPE)
     abort ();
 
-  if (TREE_CODE (rhs) == OFFSET_REF)
-    rhs = resolve_offset_ref (rhs);
-
   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
   if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
     rhs = TREE_OPERAND (rhs, 0);
@@ -6117,13 +6067,6 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags,
       || (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node))
     return error_mark_node;
 
-  if (TREE_CODE (rhs) == OFFSET_REF)
-    {
-      rhs = resolve_offset_ref (rhs);
-      if (rhs == error_mark_node)
-       return error_mark_node;
-    }
-
   if (TREE_CODE (TREE_TYPE (rhs)) == REFERENCE_TYPE)
     rhs = convert_from_reference (rhs);
 
index 0587816..9d9ade1 100644 (file)
@@ -993,12 +993,6 @@ build_x_arrow (tree datum)
   if (processing_template_decl)
     return build_min_nt (ARROW_EXPR, rval);
 
-  if (TREE_CODE (rval) == OFFSET_REF)
-    {
-      rval = resolve_offset_ref (datum);
-      type = TREE_TYPE (rval);
-    }
-
   if (TREE_CODE (type) == REFERENCE_TYPE)
     {
       rval = convert_from_reference (rval);
@@ -1048,72 +1042,32 @@ build_x_arrow (tree datum)
   return error_mark_node;
 }
 
-/* Make an expression to refer to the COMPONENT field of
-   structure or union value DATUM.  COMPONENT is an arbitrary
-   expression.  DATUM has not already been checked out to be of
-   aggregate type.
-
-   For C++, COMPONENT may be a TREE_LIST.  This happens when we must
-   return an object of member type to a method of the current class,
-   but there is not yet enough typing information to know which one.
-   As a special case, if there is only one method by that name,
-   it is returned.  Otherwise we return an expression which other
-   routines will have to know how to deal with later.  */
+/* Return an expression for "DATUM .* COMPONENT".  DATUM has not
+   already been checked out to be of aggregate type.  */
 
 tree
 build_m_component_ref (tree datum, tree component)
 {
-  tree type;
+  tree ptrmem_type;
   tree objtype;
-  tree field_type;
-  int type_quals;
+  tree type;
   tree binfo;
 
-  if (processing_template_decl)
-    return build_min_nt (DOTSTAR_EXPR, datum, component);
-
   datum = decay_conversion (datum);
 
   if (datum == error_mark_node || component == error_mark_node)
     return error_mark_node;
 
-  objtype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));  
-
-  if (TYPE_PTRMEMFUNC_P (TREE_TYPE (component)))
-    {
-      type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (component)));
-      field_type = type;
-    }
-  else if (TYPE_PTRMEM_P (TREE_TYPE (component)))
-    {
-      type = TREE_TYPE (TREE_TYPE (component));
-      field_type = TREE_TYPE (type);
-      
-      /* Compute the type of the field, as described in [expr.ref].  */
-      type_quals = TYPE_UNQUALIFIED;
-      if (TREE_CODE (field_type) == REFERENCE_TYPE)
-       /* The standard says that the type of the result should be the
-                  type referred to by the reference.  But for now, at least,
-                  we do the conversion from reference type later.  */
-       ;
-      else
-       {
-         type_quals = (cp_type_quals (field_type)  
-                       | cp_type_quals (TREE_TYPE (datum)));
-
-         /* There's no such thing as a mutable pointer-to-member, so
-            things are not as complex as they are for references to
-            non-static data members.  */
-         field_type = cp_build_qualified_type (field_type, type_quals);
-       }
-    }
-  else
+  ptrmem_type = TREE_TYPE (component);
+  if (!TYPE_PTRMEM_P (ptrmem_type) 
+      && !TYPE_PTRMEMFUNC_P (ptrmem_type))
     {
       error ("`%E' cannot be used as a member pointer, since it is of type `%T'", 
-               component, TREE_TYPE (component));
+            component, ptrmem_type);
       return error_mark_node;
     }
-
+    
+  objtype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));  
   if (! IS_AGGR_TYPE (objtype))
     {
       error ("cannot apply member pointer `%E' to `%E', which is of non-aggregate type `%T'",
@@ -1121,21 +1075,35 @@ build_m_component_ref (tree datum, tree component)
       return error_mark_node;
     }
 
-  binfo = lookup_base (objtype, TYPE_METHOD_BASETYPE (type),
+  type = TYPE_PTRMEM_POINTED_TO_TYPE (ptrmem_type);
+  binfo = lookup_base (objtype, TYPE_PTRMEM_CLASS_TYPE (ptrmem_type),
                       ba_check, NULL);
   if (!binfo)
     {
       error ("member type `%T::' incompatible with object type `%T'",
-               TYPE_METHOD_BASETYPE (type), objtype);
+            type, objtype);
       return error_mark_node;
     }
   else if (binfo == error_mark_node)
     return error_mark_node;
 
-  component = build (OFFSET_REF, field_type, datum, component);
-  if (TREE_CODE (type) == OFFSET_TYPE)
-    component = resolve_offset_ref (component);
-  return component;
+  if (TYPE_PTRMEM_P (ptrmem_type))
+    {
+      /* Compute the type of the field, as described in [expr.ref].
+        There's no such thing as a mutable pointer-to-member, so
+        things are not as complex as they are for references to
+        non-static data members.  */
+      type = cp_build_qualified_type (type,
+                                     (cp_type_quals (type)  
+                                      | cp_type_quals (TREE_TYPE (datum))));
+
+      datum = build_base_path (PLUS_EXPR, build_address (datum), binfo, 1);
+      component = cp_convert (ptrdiff_type_node, component);
+      datum = build (PLUS_EXPR, build_pointer_type (type), datum, component);
+      return build_indirect_ref (datum, 0);
+    }
+  else
+    return build (OFFSET_REF, type, datum, component);
 }
 
 /* Return a tree node for the expression TYPENAME '(' PARMS ')'.  */
index b2db902..344cb39 100644 (file)
@@ -1,3 +1,8 @@
+2003-07-03  Mark Mitchell  <mark@codesourcery.com>
+
+       * g++.old-deja/g++.jason/typeid1.C: Add dg-error marker.
+       * g++.old-deja/g++.mike/net36.C: Tweak error messages.
+
 2003-07-03  Roger Sayle  <roger@eyesopen.com>
 
        * gcc.dg/builtins-25.c: New testcase.
index 83a0b09..678ab5f 100644 (file)
@@ -8,5 +8,5 @@ int main() {
   double f (int);
   const std::type_info &r = typeid (f);
   std::cout << typeid(f).name() << std::endl;
-  std::cout << typeid(foo::f).name() << std::endl;
+  std::cout << typeid(foo::f).name() << std::endl; /* { dg-error "" } */
 }
index 7d21d56..3ffa60e 100644 (file)
@@ -11,7 +11,7 @@ typedef void (A::*handler) (X*);
 
 class B {
 public:
-  void setHandler(handler); // { dg-error "" } candidate
+  void setHandler(handler);
 };
 
 void f(B* b) {