Commit 51924768 by Jason Merrill Committed by Jason Merrill

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
parent 4f2905fb
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 Lwis <loewis@informatik.hu-berlin.de>
* decl2.c (validate_nonmember_using_decl): Fix using-directives of
......
......@@ -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)
......
......@@ -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;
......
......@@ -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
......
......@@ -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);
}
......
......@@ -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;
}
......
......@@ -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 */
......
......@@ -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
......
......@@ -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
......
......@@ -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));
......
......@@ -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);
}
......@@ -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? */
......
......@@ -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;
......
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