diff options
author | Jason Merrill <jason@yorick.cygnus.com> | 1998-10-19 20:08:23 +0000 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 1998-10-19 16:08:23 -0400 |
commit | 51924768e7b22cfc001c93ae562c4ce7c2af60ee (patch) | |
tree | a80a7239efe1c828f5d785068f86b4c524aee0ee /gcc | |
parent | 4f2905fb4b3857320f2a3218f8419d8b3616ce63 (diff) | |
download | gcc-51924768e7b22cfc001c93ae562c4ce7c2af60ee.zip gcc-51924768e7b22cfc001c93ae562c4ce7c2af60ee.tar.gz gcc-51924768e7b22cfc001c93ae562c4ce7c2af60ee.tar.bz2 |
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.
From-SVN: r23186
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 33 | ||||
-rw-r--r-- | gcc/cp/call.c | 76 | ||||
-rw-r--r-- | gcc/cp/class.c | 64 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 15 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 6 | ||||
-rw-r--r-- | gcc/cp/error.c | 3 | ||||
-rw-r--r-- | gcc/cp/init.c | 46 | ||||
-rw-r--r-- | gcc/cp/method.c | 11 | ||||
-rw-r--r-- | gcc/cp/pt.c | 3 | ||||
-rw-r--r-- | gcc/cp/tree.c | 53 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 99 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 13 |
13 files changed, 163 insertions, 262 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7b7740b..fb5a81e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f431885..dc05d19 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 785279c..70a905f 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a7ab145..d499327 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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 diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index a228e27..3058641 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -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); } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 1a85dcb..f0b3167 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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; } diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 52c519d..ba5243a 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -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 */ diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 985718c..47c8355 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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 diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 400aead..6d31ce4 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -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 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index cf1ca8c..11c89df 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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)); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 9aa094d..b943b83 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -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); +} diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index c2f6eba..5cd21f1 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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? */ diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 14e7ae2..809b89d 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -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; |