Commit f49422da by Mike Stump

89th Cygnus<->FSF quick merge

From-SVN: r12978
parent 170e0690
Thu Oct 17 11:31:59 1996 Mike Stump <mrs@cygnus.com>
* cvt.c (convert_to_pointer_force): Add code to support pointer to
member function to pointer to function conversions.
* init.c (resolve_offset_ref): Add code to allow faked up objects,
ignoring them if they are not used, and giving an error, if they
are needed.
* typeck.c (get_member_function_from_ptrfunc): Fold e1 to improve
code, and so that we can give an error, if we needed an object,
and one was not provided.
(build_c_cast): Don't call default_conversion when we want to
convert to pointer to function from a METHOD_TYPE.
Mon Oct 14 00:28:51 1996 Jason Merrill <jason@yorick.cygnus.com>
* Make-lang.in (cplib2.ready): Fix logic.
* decl.c (shadow_tag): Only complain about non-artificial function
members.
* class.c (finish_struct_1): Add synthesized methods to TYPE_METHODS.
Fri Oct 11 16:12:40 1996 Jason Merrill <jason@yorick.cygnus.com>
* expr.c (cplus_expand_expr): Pre-tweak call_target like
expand_inline_function would.
* pt.c (mark_decl_instantiated): If extern_p, call
mark_inline_for_output.
Thu Oct 10 15:58:08 1996 Mike Stump <mrs@cygnus.com> Thu Oct 10 15:58:08 1996 Mike Stump <mrs@cygnus.com>
* typeck.c (unary_complex_lvalue): Add code to handle intermediate * typeck.c (unary_complex_lvalue): Add code to handle intermediate
......
...@@ -146,7 +146,7 @@ cplib2.ready: $(GCC_PASSES) $(LIBGCC2_DEPS) stmp-int-hdrs ...@@ -146,7 +146,7 @@ cplib2.ready: $(GCC_PASSES) $(LIBGCC2_DEPS) stmp-int-hdrs
else \ else \
echo "" > cplib2.new; \ echo "" > cplib2.new; \
fi; \ fi; \
if cmp -s cplib2.new cplib2.txt; then \ if cmp -s cplib2.new cplib2.txt; then true; else \
touch cplib2.ready; \ touch cplib2.ready; \
fi; \ fi; \
rm -f cplib2.new; \ rm -f cplib2.new; \
......
...@@ -3635,6 +3635,7 @@ finish_struct_1 (t, warn_anon) ...@@ -3635,6 +3635,7 @@ finish_struct_1 (t, warn_anon)
if (fn_fields) if (fn_fields)
{ {
TYPE_METHODS (t) = fn_fields;
method_vec = finish_struct_methods (t, fn_fields, nonprivate_method); method_vec = finish_struct_methods (t, fn_fields, nonprivate_method);
if (TYPE_HAS_CONSTRUCTOR (t) if (TYPE_HAS_CONSTRUCTOR (t)
......
...@@ -282,6 +282,44 @@ convert_to_pointer_force (type, expr) ...@@ -282,6 +282,44 @@ convert_to_pointer_force (type, expr)
form = TREE_CODE (intype); form = TREE_CODE (intype);
} }
if (TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
{
/* Allow an implicit this pointer for pointer to member
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;
expr = build (OFFSET_REF, fntype, decl, expr);
intype = TREE_TYPE (expr);
}
if (TREE_CODE (expr) == OFFSET_REF && TREE_CODE (intype) == 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)
{
if (pedantic
&& TREE_CODE (TREE_TYPE (TREE_TYPE (expr))) == METHOD_TYPE)
cp_pedwarn ("cannot convert `%T' to `%T'", intype, type);
return build1 (NOP_EXPR, type, expr);
}
}
if (form == POINTER_TYPE) if (form == POINTER_TYPE)
{ {
intype = TYPE_MAIN_VARIANT (intype); intype = TYPE_MAIN_VARIANT (intype);
......
...@@ -5647,10 +5647,16 @@ shadow_tag (declspecs) ...@@ -5647,10 +5647,16 @@ shadow_tag (declspecs)
|| (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL || (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))))) && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))))
{ {
tree fn;
/* ANSI C++ June 5 1992 WP 9.5.3. Anonymous unions may not have /* ANSI C++ June 5 1992 WP 9.5.3. Anonymous unions may not have
function members. */ function members. */
if (TYPE_METHODS (t)) for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
if (! DECL_ARTIFICIAL (fn))
{
error ("an anonymous union cannot have function members"); error ("an anonymous union cannot have function members");
break;
}
if (TYPE_FIELDS (t)) if (TYPE_FIELDS (t))
{ {
......
...@@ -137,6 +137,18 @@ cplus_expand_expr (exp, target, tmode, modifier) ...@@ -137,6 +137,18 @@ cplus_expand_expr (exp, target, tmode, modifier)
result. The assumptions are true only if the address was result. The assumptions are true only if the address was
valid to begin with. */ valid to begin with. */
call_target = validize_mem (call_target); call_target = validize_mem (call_target);
/* If this is a reference to a symbol, expand_inline_function
will do this transformation and return a different target
than the one we gave it, though functionally equivalent. Do
the transformation here to avoid confusion. */
if (! cse_not_expected && GET_CODE (call_target) == MEM
&& GET_CODE (XEXP (call_target, 0)) == SYMBOL_REF)
{
call_target = gen_rtx
(MEM, mode, memory_address (mode, XEXP (call_target, 0)));
MEM_IN_STRUCT_P (call_target) = 1;
}
} }
call_exp = build (CALL_EXPR, type, func, args, NULL_TREE); call_exp = build (CALL_EXPR, type, func, args, NULL_TREE);
......
...@@ -2082,14 +2082,27 @@ resolve_offset_ref (exp) ...@@ -2082,14 +2082,27 @@ resolve_offset_ref (exp)
my_friendly_abort (55); my_friendly_abort (55);
} }
/* If this is a reference to a member function, then return /* Ensure that we have an object. */
the address of the member function (which may involve going if (TREE_CODE (base) == NOP_EXPR
&& TREE_OPERAND (base, 0) == error_mark_node)
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 through the object's vtable), otherwise, return an expression
for the dereferenced pointer-to-member construct. */ for the dereferenced pointer-to-member construct. */
addr = build_unary_op (ADDR_EXPR, base, 0); addr = build_unary_op (ADDR_EXPR, base, 0);
}
if (TREE_CODE (TREE_TYPE (member)) == OFFSET_TYPE) if (TREE_CODE (TREE_TYPE (member)) == OFFSET_TYPE)
{ {
if (addr == error_mark_node)
{
cp_error ("object missing in `%E'", exp);
return error_mark_node;
}
basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (member)); basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (member));
addr = convert_pointer_to (basetype, addr); addr = convert_pointer_to (basetype, addr);
member = convert (ptrdiff_type_node, member = convert (ptrdiff_type_node,
......
...@@ -2858,6 +2858,8 @@ mark_decl_instantiated (result, extern_p) ...@@ -2858,6 +2858,8 @@ mark_decl_instantiated (result, extern_p)
DECL_INTERFACE_KNOWN (result) = 1; DECL_INTERFACE_KNOWN (result) = 1;
DECL_NOT_REALLY_EXTERN (result) = 1; DECL_NOT_REALLY_EXTERN (result) = 1;
} }
else if (TREE_CODE (result) == FUNCTION_DECL)
mark_inline_for_output (result);
} }
/* Given two function templates PAT1 and PAT2, return: /* Given two function templates PAT1 and PAT2, return:
......
...@@ -2463,8 +2463,8 @@ get_member_function_from_ptrfunc (instance_ptrptr, function) ...@@ -2463,8 +2463,8 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
idx = save_expr (build_component_ref (function, idx = save_expr (build_component_ref (function,
index_identifier, index_identifier,
NULL_TREE, 0)); NULL_TREE, 0));
e1 = build (GT_EXPR, boolean_type_node, idx, e1 = fold (build (GT_EXPR, boolean_type_node, idx,
convert (delta_type_node, integer_zero_node)); convert (delta_type_node, integer_zero_node)));
delta = convert (ptrdiff_type_node, delta = convert (ptrdiff_type_node,
build_component_ref (function, delta_identifier, NULL_TREE, 0)); build_component_ref (function, delta_identifier, NULL_TREE, 0));
delta2 = DELTA2_FROM_PTRMEMFUNC (function); delta2 = DELTA2_FROM_PTRMEMFUNC (function);
...@@ -2473,7 +2473,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function) ...@@ -2473,7 +2473,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
instance instance
= convert_pointer_to_real (TYPE_METHOD_BASETYPE (TREE_TYPE (fntype)), = convert_pointer_to_real (TYPE_METHOD_BASETYPE (TREE_TYPE (fntype)),
instance_ptr); instance_ptr);
if (instance == error_mark_node) if (instance == error_mark_node && instance_ptr != error_mark_node)
return instance; return instance;
vtbl = convert_pointer_to (ptr_type_node, instance); vtbl = convert_pointer_to (ptr_type_node, instance);
...@@ -2503,7 +2503,14 @@ get_member_function_from_ptrfunc (instance_ptrptr, function) ...@@ -2503,7 +2503,14 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
e3 = PFN_FROM_PTRMEMFUNC (function); e3 = PFN_FROM_PTRMEMFUNC (function);
TREE_TYPE (e2) = TREE_TYPE (e3); TREE_TYPE (e2) = TREE_TYPE (e3);
function = build_conditional_expr (e1, e2, e3); e1 = build_conditional_expr (e1, e2, e3);
if (instance_ptr == error_mark_node
&& TREE_CODE (e1) != ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (e1, 0)) != FUNCTION_DECL)
cp_error ("object missing in `%E'", function);
function = e1;
/* Make sure this doesn't get evaluated first inside one of the /* Make sure this doesn't get evaluated first inside one of the
branches of the COND_EXPR. */ branches of the COND_EXPR. */
...@@ -5408,7 +5415,11 @@ build_c_cast (type, expr, allow_nonconverting) ...@@ -5408,7 +5415,11 @@ build_c_cast (type, expr, allow_nonconverting)
convert references to their expanded types, convert references to their expanded types,
but don't convert any other types. */ but don't convert any other types. */
if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE || (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE
/* Don't do the default conversion if we want a
pointer to a function. */
&& TREE_CODE (type) != POINTER_TYPE
&& TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
|| TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE) || TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
value = default_conversion (value); value = default_conversion (value);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment