mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-14 04:20:25 +08:00
89th Cygnus<->FSF quick merge
From-SVN: r12978
This commit is contained in:
parent
170e0690ee
commit
f49422dada
@ -1,3 +1,33 @@
|
||||
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>
|
||||
|
||||
* typeck.c (unary_complex_lvalue): Add code to handle intermediate
|
||||
|
@ -146,7 +146,7 @@ cplib2.ready: $(GCC_PASSES) $(LIBGCC2_DEPS) stmp-int-hdrs
|
||||
else \
|
||||
echo "" > cplib2.new; \
|
||||
fi; \
|
||||
if cmp -s cplib2.new cplib2.txt; then \
|
||||
if cmp -s cplib2.new cplib2.txt; then true; else \
|
||||
touch cplib2.ready; \
|
||||
fi; \
|
||||
rm -f cplib2.new; \
|
||||
|
@ -3635,6 +3635,7 @@ finish_struct_1 (t, warn_anon)
|
||||
|
||||
if (fn_fields)
|
||||
{
|
||||
TYPE_METHODS (t) = fn_fields;
|
||||
method_vec = finish_struct_methods (t, fn_fields, nonprivate_method);
|
||||
|
||||
if (TYPE_HAS_CONSTRUCTOR (t)
|
||||
|
38
gcc/cp/cvt.c
38
gcc/cp/cvt.c
@ -282,6 +282,44 @@ convert_to_pointer_force (type, expr)
|
||||
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)
|
||||
{
|
||||
intype = TYPE_MAIN_VARIANT (intype);
|
||||
|
@ -5647,10 +5647,16 @@ shadow_tag (declspecs)
|
||||
|| (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
|
||||
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))))
|
||||
{
|
||||
tree fn;
|
||||
|
||||
/* ANSI C++ June 5 1992 WP 9.5.3. Anonymous unions may not have
|
||||
function members. */
|
||||
if (TYPE_METHODS (t))
|
||||
error ("an anonymous union cannot have function members");
|
||||
for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
|
||||
if (! DECL_ARTIFICIAL (fn))
|
||||
{
|
||||
error ("an anonymous union cannot have function members");
|
||||
break;
|
||||
}
|
||||
|
||||
if (TYPE_FIELDS (t))
|
||||
{
|
||||
|
@ -137,6 +137,18 @@ cplus_expand_expr (exp, target, tmode, modifier)
|
||||
result. The assumptions are true only if the address was
|
||||
valid to begin with. */
|
||||
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);
|
||||
|
@ -2082,14 +2082,27 @@ resolve_offset_ref (exp)
|
||||
my_friendly_abort (55);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
/* Ensure that we have an object. */
|
||||
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
|
||||
for the dereferenced pointer-to-member construct. */
|
||||
addr = build_unary_op (ADDR_EXPR, base, 0);
|
||||
}
|
||||
|
||||
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));
|
||||
addr = convert_pointer_to (basetype, addr);
|
||||
member = convert (ptrdiff_type_node,
|
||||
|
@ -2858,6 +2858,8 @@ mark_decl_instantiated (result, extern_p)
|
||||
DECL_INTERFACE_KNOWN (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:
|
||||
|
@ -2463,8 +2463,8 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
|
||||
idx = save_expr (build_component_ref (function,
|
||||
index_identifier,
|
||||
NULL_TREE, 0));
|
||||
e1 = build (GT_EXPR, boolean_type_node, idx,
|
||||
convert (delta_type_node, integer_zero_node));
|
||||
e1 = fold (build (GT_EXPR, boolean_type_node, idx,
|
||||
convert (delta_type_node, integer_zero_node)));
|
||||
delta = convert (ptrdiff_type_node,
|
||||
build_component_ref (function, delta_identifier, NULL_TREE, 0));
|
||||
delta2 = DELTA2_FROM_PTRMEMFUNC (function);
|
||||
@ -2473,7 +2473,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
|
||||
instance
|
||||
= convert_pointer_to_real (TYPE_METHOD_BASETYPE (TREE_TYPE (fntype)),
|
||||
instance_ptr);
|
||||
if (instance == error_mark_node)
|
||||
if (instance == error_mark_node && instance_ptr != error_mark_node)
|
||||
return instance;
|
||||
|
||||
vtbl = convert_pointer_to (ptr_type_node, instance);
|
||||
@ -2503,7 +2503,14 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
|
||||
|
||||
e3 = PFN_FROM_PTRMEMFUNC (function);
|
||||
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
|
||||
branches of the COND_EXPR. */
|
||||
@ -5408,7 +5415,11 @@ build_c_cast (type, expr, allow_nonconverting)
|
||||
convert references to their expanded types,
|
||||
but don't convert any other types. */
|
||||
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)) == REFERENCE_TYPE)
|
||||
value = default_conversion (value);
|
||||
|
Loading…
x
Reference in New Issue
Block a user