Commit 00595019 by Mike Stump

46 Cygnus<->FSF merge

From-SVN: r7943
parent 07d0cbdd
Thu Aug 18 12:48:09 1994 Mike Stump (mrs@cygnus.com)
* class.c (finish_struct): Move setting of CLASSTYPE_INTERFACE and
CLASSTYPE_VTABLE_NEEDS_WRITING up to left_curly time.
* decl.c (xref_tag): Move setting of CLASSTYPE_INTERFACE and
CLASSTYPE_VTABLE_NEEDS_WRITING down to left_curly time.
* parse.y (left_curly): New final resting place for setting
CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING.
Thu Aug 11 11:32:42 1994 H.J. Lu (hjl@nynexst.com)
* g++.c (main): Only decrement "added" and set "library" to
NULL when "library" != NULL.
Sat Aug 13 00:14:52 1994 Jason Merrill (jason@deneb.cygnus.com)
* decl.c (grokdeclarator): Don't set TREE_PUBLIC on a function decl
just because its class has a known interface.
(decls_match): Deal with new format of template parms.
* lex.c (cons_up_default_function): Don't play with TREE_PUBLIC and
DECL_EXTERNAL here.
Fri Aug 12 01:55:15 1994 Jason Merrill (jason@deneb.cygnus.com)
* decl.c (pushtag): SET_DECL_ARTIFICIAL on gratuitous typedefs.
(xref_defn_tag): Ditto.
(pushdecl): Only allow artificial typedefs to be shadowed.
* init.c (emit_base_init): Pass the right binfos to
expand_aggr_init_1.
* class.c (delete_duplicate_fields_1): Make it work right.
(finish_struct): Catch function/field name conflict.
* decl2.c (check_classfn): Pass the function to cp_error, not just
the name.
* init.c (sort_member_init): Warn when order of member initializers
does not match order of member declarations.
(emit_base_init): Call expand_aggr_init_1 with LOOKUP_PROTECT.
* error.c (dump_expr): Handle lists of functions.
* decl.c (start_function): #pragma interface only affects functions
that would otherwise be static.
(finish_decl): Don't warn about an unused variable if it has both
constructor and destructor, since the 'resource allocation is
initialization' idiom is relatively common.
* typeck.c (comp_target_types): Don't handle TEMPLATE_TYPE_PARMs.
(comp_target_parms): Ditto.
(compparms): Never consider default parms.
(common_base_type): Don't choose a virtual baseclass if there is a
more derived class in common.
(build_conditional_expr): If pedantic, pedwarn about conversion to
common base in conditional expr.
* class.c (instantiate_type): Handle template instantiation better.
* typeck.c (convert_arguments): Don't try to get tricky and convert
to int directly when PROMOTE_PROTOTYPES is set, as it breaks
user-defined conversions.
* lex.c (check_for_missing_semicolon): Also give error at end of
file.
* call.c (build_method_call): Don't promote arrays to pointers here.
* typeck.c (convert_arguments): Don't require the actual parameter
to be of a complete type if the formal parameter is a reference.
Thu Aug 11 15:21:40 1994 Jason Merrill (jason@deneb.cygnus.com)
* decl.c (grokdeclarator): Soften 'static' on member function error
to pedwarn.
* init.c (build_new): Don't automatically save rval.
(build_offset_ref): Do field lookup with proper basetype_path.
Thu Aug 11 12:46:54 1994 Brendan Kehoe (brendan@lisa.cygnus.com)
* errfn.c (cp_silent): Declare to mark when we should avoid
emitting warnings and errors.
(cp_error): Check it.
(cp_warning): Likewise.
(cp_pedwarn): Likewise.
(cp_compiler_error): Likewise.
(cp_error_at): Likewise.
(cp_warning_at): Likewise.
(cp_pedwarn_at): Likewise.
* call.c (compute_conversion_costs): Set CP_SILENT when we start
out, and make sure we turn it off before we leave.
Thu Aug 11 00:02:54 1994 Jason Merrill (jason@deneb.cygnus.com)
* decl2.c (grok_array_decl): Try computing *(A+B) if neither
argument is obviously an array.
Wed Aug 10 15:32:04 1994 Jason Merrill (jason@deneb.cygnus.com)
* typeck.c (c_expand_start_case): Do cleanups here.
* parse.y (xcond): Do bool conversion here, too.
(simple_stmt, SWITCH case): Don't do cleanups here.
* decl.c (duplicate_decls): Don't treat builtins that have been
explicitly declared specially.
Tue Aug 9 01:16:09 1994 Jason Merrill (jason@deneb.cygnus.com)
* tree.c (make_deep_copy): Support copying pointer, reference,
function, array, offset and method types.
* decl.c (init_decl_processing): Mark exit and abort as
BUILT_IN_NONANSI so that duplicate_decls is kinder about
redeclaration.
(duplicate_decls): Don't give two errors for redeclaring a C
function with the same parms but a different return type.
* parse.y (paren_cond_or_null): Do cleanup and bool conversion here.
(condition): Instead of here.
(simple_stmt, SWITCH case): Also do cleanup here.
* decl2.c (finish_anon_union): Only break out FIELD_DECLs.
* call.c (build_method_call): Don't throw away the side effects of
the object in a call to a non-existent constructor.
* parse.y (primary): Ditto.
* method.c (build_decl_overload): Oop.
* decl2.c (lang_decode_option): Deal with flag_no_nonansi_builtin,
warn about uselessness of specifying -fansi-overloading.
* method.c (build_decl_overload): Treat any non-member new with one
parameter as __builtin_new.
* decl.c (init_decl_processing): Setup built-in meanings of exit,
_exit and abort.
Mon Aug 8 15:03:30 1994 Jason Merrill (jason@deneb.cygnus.com)
* error.c (dump_readonly_or_volatile): Put a space between const and
volatile if both apply.
* init.c (perform_member_init): Clean up after this initialization.
(emit_base_init): Clean up after each base init, not after all have
been done.
(expand_aggr_vbase_init_1): Clean up after this init.
Sun Aug 7 14:55:05 1994 Jason Merrill (jason@deneb.cygnus.com)
* call.c (build_method_call): Deal with destroying references.
* parse.y (condition): Do bool_truthvalue_conversion here.
(paren_expr_or_null): And here.
(simple_if): Not here.
(simple_stmt): Or here.
Sat Aug 6 22:29:45 1994 Jason Merrill (jason@deneb.cygnus.com)
* parse.y (paren_expr_or_null): Wrap the expression in a
CLEANUP_POINT_EXPR.
(condition): Ditto.
Sat Aug 6 19:46:37 1994 Rohan Lenard (rjl@easams.com.au)
* call.c (build_scoped_method_call): Fix error message when
destructor call refers to a nonexistent type.
Sat Apr 16 22:43:30 1993 Gerald Baumgartner (gb@cs.purdue.edu)
* lex.h (rid): Deleted RID_RAISES, it's never used.
Moved RID_PUBLIC, RID_PRIVATE, RID_PROTECTED, RID_EXCEPTION,
RID_TEMPLATE and RID_SIGNATURE to the end of the enumeration,
they don't need to be touched in `grokdeclarator.'
(RID_LAST_MODIFIER): Defined macro to be RID_MUTABLE.
* decl.c (grokdeclarator): Use RID_LAST_MODIFIER instead of
RID_MAX as loop limit for finding declaration specifiers.
Sat Apr 3 21:59:07 1993 Gerald Baumgartner (gb@cs.purdue.edu)
* lex.c (debug_yytranslate): Moved to parse.y since it needs to
access `yytname,' which is static in parse.c.
Fri Apr 2 23:36:57 1993 Gerald Baumgarnter (gb@cs.purdue.edu)
* cp-tree.h (GNU_xref_ref): Fixed typo in extern declaration, it
was `GNU_xref_def' instead of `GNU_xref_ref.'
Fri Aug 5 14:20:16 1994 Jason Merrill (jason@deneb.cygnus.com)
* pt.c (do_function_instantiation): Don't set TREE_PUBLIC and
DECL_EXTERNAL on 'extern' instantiations; wait until EOF to do that.
(do_type_instantiation): Ditto.
* decl2.c (import_export_inline): Decides at EOF what an inline's
linkage should be.
(finish_file): Call it.
* decl.c (start_function): Don't rely on the settings of TREE_PUBLIC
and DECL_EXTERNAL from do_*_instantiation. Only set
DECL_DEFER_OUTPUT on inlines whose linkage might actually change.
(finish_function): Use DECL_DEFER_OUTPUT to decide which inlines to
mark for later consideration, rather than DECL_FUNCTION_MEMBER_P.
Fri Aug 5 01:12:20 1994 Mike Stump (mrs@cygnus.com) Fri Aug 5 01:12:20 1994 Mike Stump (mrs@cygnus.com)
* class.c (get_class_offset_1, get_class_offset): New routine to * class.c (get_class_offset_1, get_class_offset): New routine to
......
...@@ -700,11 +700,17 @@ compute_conversion_costs (function, tta_in, cp, arglen) ...@@ -700,11 +700,17 @@ compute_conversion_costs (function, tta_in, cp, arglen)
int strike_index = 0, win; int strike_index = 0, win;
struct harshness_code lose; struct harshness_code lose;
extern int cp_silent;
#ifdef GATHER_STATISTICS #ifdef GATHER_STATISTICS
n_compute_conversion_costs++; n_compute_conversion_costs++;
#endif #endif
#ifndef DEBUG_MATCHING
/* We don't emit any warnings or errors while trying out each candidate. */
cp_silent = 1;
#endif
cp->function = function; cp->function = function;
cp->arg = tta ? TREE_VALUE (tta) : NULL_TREE; cp->arg = tta ? TREE_VALUE (tta) : NULL_TREE;
cp->u.bad_arg = 0; /* optimistic! */ cp->u.bad_arg = 0; /* optimistic! */
...@@ -812,6 +818,7 @@ compute_conversion_costs (function, tta_in, cp, arglen) ...@@ -812,6 +818,7 @@ compute_conversion_costs (function, tta_in, cp, arglen)
{ {
cp->h.code = EVIL_CODE; cp->h.code = EVIL_CODE;
cp->u.bad_arg = -1; cp->u.bad_arg = -1;
cp_silent = 0;
return; return;
} }
else else
...@@ -833,6 +840,7 @@ compute_conversion_costs (function, tta_in, cp, arglen) ...@@ -833,6 +840,7 @@ compute_conversion_costs (function, tta_in, cp, arglen)
{ {
cp->h.code = EVIL_CODE; cp->h.code = EVIL_CODE;
cp->u.bad_arg = -2; cp->u.bad_arg = -2;
cp_silent = 0;
return; return;
} }
/* Store index of first default. */ /* Store index of first default. */
...@@ -855,6 +863,7 @@ compute_conversion_costs (function, tta_in, cp, arglen) ...@@ -855,6 +863,7 @@ compute_conversion_costs (function, tta_in, cp, arglen)
if (dont_convert_types) if (dont_convert_types)
{ {
cp->h.code = EVIL_CODE; cp->h.code = EVIL_CODE;
cp_silent = 0;
return; return;
} }
...@@ -1002,6 +1011,7 @@ compute_conversion_costs (function, tta_in, cp, arglen) ...@@ -1002,6 +1011,7 @@ compute_conversion_costs (function, tta_in, cp, arglen)
cp->h.code |= ELLIPSIS_CODE; cp->h.code |= ELLIPSIS_CODE;
if (user_strikes) if (user_strikes)
cp->h.code |= USER_CODE; cp->h.code |= USER_CODE;
cp_silent = 0;
#ifdef DEBUG_MATCHING #ifdef DEBUG_MATCHING
cp_error ("final eval %s", print_harshness (&cp->h)); cp_error ("final eval %s", print_harshness (&cp->h));
#endif #endif
...@@ -1428,7 +1438,9 @@ build_scoped_method_call (exp, scopes, name, parms) ...@@ -1428,7 +1438,9 @@ build_scoped_method_call (exp, scopes, name, parms)
if (type != basetype) if (type != basetype)
cp_error ("type of `%E' does not match destructor type `%T' (type was `%T')", cp_error ("type of `%E' does not match destructor type `%T' (type was `%T')",
exp, basetype, type); exp, basetype, type);
name = IDENTIFIER_TYPE_VALUE (TREE_OPERAND (name, 0)); name = TREE_OPERAND (name, 0);
if (IDENTIFIER_HAS_TYPE_VALUE (name))
name = IDENTIFIER_TYPE_VALUE (name);
if (basetype != name) if (basetype != name)
cp_error ("qualified type `%T' does not match destructor type `%T'", cp_error ("qualified type `%T' does not match destructor type `%T'",
basetype, name); basetype, name);
...@@ -1604,17 +1616,19 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -1604,17 +1616,19 @@ build_method_call (instance, name, parms, basetype_path, flags)
if (parms) if (parms)
error ("destructors take no parameters"); error ("destructors take no parameters");
basetype = TREE_TYPE (instance); basetype = TREE_TYPE (instance);
if (TREE_CODE (basetype) == REFERENCE_TYPE)
basetype = TREE_TYPE (basetype);
if (! ((IS_AGGR_TYPE (basetype) if (! ((IS_AGGR_TYPE (basetype)
&& name == constructor_name (basetype)) && name == constructor_name (basetype))
|| basetype == get_type_value (name))) || basetype == get_type_value (name)))
{ {
cp_error ("destructor name `~%D' does not match type `%T' of expression", cp_error ("destructor name `~%D' does not match type `%T' of expression",
name, basetype); name, basetype);
return void_zero_node; return convert (void_type_node, instance);
} }
if (! TYPE_HAS_DESTRUCTOR (basetype)) if (! TYPE_HAS_DESTRUCTOR (basetype))
return void_zero_node; return convert (void_type_node, instance);
instance = default_conversion (instance); instance = default_conversion (instance);
instance_ptr = build_unary_op (ADDR_EXPR, instance, 0); instance_ptr = build_unary_op (ADDR_EXPR, instance, 0);
return build_delete (build_pointer_type (basetype), return build_delete (build_pointer_type (basetype),
...@@ -1891,6 +1905,8 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -1891,6 +1905,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
{ {
TREE_VALUE (parm) = build_unary_op (ADDR_EXPR, TREE_VALUE (parm), 0); TREE_VALUE (parm) = build_unary_op (ADDR_EXPR, TREE_VALUE (parm), 0);
} }
#if 0
/* This breaks reference-to-array parameters. */
if (TREE_CODE (t) == ARRAY_TYPE) if (TREE_CODE (t) == ARRAY_TYPE)
{ {
/* Perform the conversion from ARRAY_TYPE to POINTER_TYPE in place. /* Perform the conversion from ARRAY_TYPE to POINTER_TYPE in place.
...@@ -1898,6 +1914,7 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -1898,6 +1914,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
TREE_VALUE (parm) = default_conversion (TREE_VALUE (parm)); TREE_VALUE (parm) = default_conversion (TREE_VALUE (parm));
t = TREE_TYPE (TREE_VALUE (parm)); t = TREE_TYPE (TREE_VALUE (parm));
} }
#endif
if (t == error_mark_node) if (t == error_mark_node)
return error_mark_node; return error_mark_node;
last = build_tree_list (NULL_TREE, t); last = build_tree_list (NULL_TREE, t);
......
...@@ -992,20 +992,18 @@ add_method (type, fields, method) ...@@ -992,20 +992,18 @@ add_method (type, fields, method)
not duplicates, they are just anonymous fields. This happens not duplicates, they are just anonymous fields. This happens
when we have unnamed bitfields, for example. */ when we have unnamed bitfields, for example. */
static tree static tree
delete_duplicate_fields_1 (field, field_ptr, fields) delete_duplicate_fields_1 (field, fields)
tree field, *field_ptr, fields; tree field, fields;
{ {
tree x; tree x;
tree prev = field_ptr ? *field_ptr : 0; tree prev = 0;
if (DECL_NAME (field) == 0) if (DECL_NAME (field) == 0)
{ {
if (TREE_CODE (TREE_TYPE (field)) != UNION_TYPE) if (TREE_CODE (TREE_TYPE (field)) != UNION_TYPE)
return fields; return fields;
for (x = TYPE_FIELDS (TREE_TYPE (field)); x; x = TREE_CHAIN (x)) for (x = TYPE_FIELDS (TREE_TYPE (field)); x; x = TREE_CHAIN (x))
fields = delete_duplicate_fields_1 (x, field_ptr, fields); fields = delete_duplicate_fields_1 (x, fields);
if (prev)
TREE_CHAIN (prev) = fields;
return fields; return fields;
} }
else else
...@@ -1017,7 +1015,7 @@ delete_duplicate_fields_1 (field, field_ptr, fields) ...@@ -1017,7 +1015,7 @@ delete_duplicate_fields_1 (field, field_ptr, fields)
if (TREE_CODE (TREE_TYPE (x)) != UNION_TYPE) if (TREE_CODE (TREE_TYPE (x)) != UNION_TYPE)
continue; continue;
TYPE_FIELDS (TREE_TYPE (x)) TYPE_FIELDS (TREE_TYPE (x))
= delete_duplicate_fields_1 (field, (tree *)0, TYPE_FIELDS (TREE_TYPE (x))); = delete_duplicate_fields_1 (field, TYPE_FIELDS (TREE_TYPE (x)));
if (TYPE_FIELDS (TREE_TYPE (x)) == 0) if (TYPE_FIELDS (TREE_TYPE (x)) == 0)
{ {
if (prev == 0) if (prev == 0)
...@@ -1039,7 +1037,7 @@ delete_duplicate_fields_1 (field, field_ptr, fields) ...@@ -1039,7 +1037,7 @@ delete_duplicate_fields_1 (field, field_ptr, fields)
x); x);
else if (TREE_CODE (field) == TYPE_DECL else if (TREE_CODE (field) == TYPE_DECL
&& TREE_CODE (x) == TYPE_DECL) && TREE_CODE (x) == TYPE_DECL)
cp_error_at ("duplicate class scope type `%D'", x); cp_error_at ("duplicate nested type `%D'", x);
else if (TREE_CODE (field) == TYPE_DECL else if (TREE_CODE (field) == TYPE_DECL
|| TREE_CODE (x) == TYPE_DECL) || TREE_CODE (x) == TYPE_DECL)
cp_error_at ("duplicate field `%D' (as type and non-type)", cp_error_at ("duplicate field `%D' (as type and non-type)",
...@@ -1063,7 +1061,7 @@ delete_duplicate_fields (fields) ...@@ -1063,7 +1061,7 @@ delete_duplicate_fields (fields)
{ {
tree x; tree x;
for (x = fields; x && TREE_CHAIN (x); x = TREE_CHAIN (x)) for (x = fields; x && TREE_CHAIN (x); x = TREE_CHAIN (x))
TREE_CHAIN (x) = delete_duplicate_fields_1 (x, &x, TREE_CHAIN (x)); TREE_CHAIN (x) = delete_duplicate_fields_1 (x, TREE_CHAIN (x));
} }
/* Change the access of FDECL to ACCESS in T. /* Change the access of FDECL to ACCESS in T.
...@@ -1937,8 +1935,8 @@ finish_struct_methods (t, fn_fields, nonprivate_method) ...@@ -1937,8 +1935,8 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
&& CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
&& DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE
&& warn_ctor_dtor_privacy) && warn_ctor_dtor_privacy)
warning ("class `%s' only defines a private destructor and has no friends", cp_warning ("`%#T' only defines a private destructor and has no friends",
TYPE_NAME_STRING (t)); t);
break; break;
} }
} }
...@@ -2774,17 +2772,12 @@ finish_struct (t, list_of_fieldlists, warn_anon) ...@@ -2774,17 +2772,12 @@ finish_struct (t, list_of_fieldlists, warn_anon)
TYPE_SIZE (t) = NULL_TREE; TYPE_SIZE (t) = NULL_TREE;
CLASSTYPE_GOT_SEMICOLON (t) = 0; CLASSTYPE_GOT_SEMICOLON (t) = 0;
/* A signature type will contain the fields of the signature table. /* This is in general too late to do this. I moved the main case up to
Therefore, it's not only an interface. */ left_curly, what else needs to move? */
if (IS_SIGNATURE (t)) if (! IS_SIGNATURE (t))
{
CLASSTYPE_INTERFACE_ONLY (t) = 0;
SET_CLASSTYPE_INTERFACE_KNOWN (t);
}
else
{ {
CLASSTYPE_INTERFACE_ONLY (t) = interface_only; my_friendly_assert (CLASSTYPE_INTERFACE_ONLY (t) == interface_only, 999);
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); my_friendly_assert (CLASSTYPE_INTERFACE_KNOWN (t) == ! interface_unknown, 999);
} }
if (flag_dossier) if (flag_dossier)
...@@ -2848,14 +2841,13 @@ finish_struct (t, list_of_fieldlists, warn_anon) ...@@ -2848,14 +2841,13 @@ finish_struct (t, list_of_fieldlists, warn_anon)
needs_virtual_dtor = 0; needs_virtual_dtor = 0;
} }
/* Both of these should be done before now. */
if (write_virtuals == 3 && CLASSTYPE_INTERFACE_KNOWN (t) if (write_virtuals == 3 && CLASSTYPE_INTERFACE_KNOWN (t)
&& ! IS_SIGNATURE (t)) && ! IS_SIGNATURE (t))
{ {
CLASSTYPE_INTERFACE_ONLY (t) = interface_only; my_friendly_assert (CLASSTYPE_INTERFACE_ONLY (t) == interface_only, 999);
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! interface_only; my_friendly_assert (CLASSTYPE_VTABLE_NEEDS_WRITING (t) == ! interface_only, 999);
} }
else if (IS_SIGNATURE (t))
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = 0;
/* The three of these are approximations which may later be /* The three of these are approximations which may later be
modified. Needed at this point to make add_virtual_function modified. Needed at this point to make add_virtual_function
...@@ -3520,6 +3512,31 @@ finish_struct (t, list_of_fieldlists, warn_anon) ...@@ -3520,6 +3512,31 @@ finish_struct (t, list_of_fieldlists, warn_anon)
/* Delete all duplicate fields from the fields */ /* Delete all duplicate fields from the fields */
delete_duplicate_fields (fields); delete_duplicate_fields (fields);
/* Catch function/field name conflict, removing the field (since it's
easier). */
{
int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
tree last = NULL_TREE;
for (x = fields; x; x = TREE_CHAIN (x))
{
tree name = DECL_NAME (x);
int i;
for (i = 0; i < n_methods; ++i)
if (DECL_NAME (TREE_VEC_ELT (method_vec, i)) == name)
{
cp_error_at ("data member `%#D' conflicts with", x);
cp_error_at ("function member `%#D'",
TREE_VEC_ELT (method_vec, i));
if (last)
TREE_CHAIN (last) = TREE_CHAIN (x);
else
fields = TREE_CHAIN (x);
break;
}
last = x;
}
}
/* Now we have the final fieldlist for the data fields. Record it, /* Now we have the final fieldlist for the data fields. Record it,
then lay out the structure or union (including the fields). */ then lay out the structure or union (including the fields). */
...@@ -4701,11 +4718,42 @@ instantiate_type (lhstype, rhs, complain) ...@@ -4701,11 +4718,42 @@ instantiate_type (lhstype, rhs, complain)
{ {
elem = get_first_fn (rhs); elem = get_first_fn (rhs);
while (elem) while (elem)
if (TREE_TYPE (elem) != lhstype) if (! comptypes (lhstype, TREE_TYPE (elem), 1))
elem = DECL_CHAIN (elem); elem = DECL_CHAIN (elem);
else else
return elem; return elem;
/* No exact match found, look for a compatible function. */
/* No exact match found, look for a compatible template. */
{
tree save_elem = 0;
for (elem = get_first_fn (rhs); elem; elem = DECL_CHAIN (elem))
if (TREE_CODE (elem) == TEMPLATE_DECL)
{
int n = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (elem));
tree *t = (tree *) alloca (sizeof (tree) * n);
int i, d;
i = type_unification (DECL_TEMPLATE_PARMS (elem), t,
TYPE_ARG_TYPES (TREE_TYPE (elem)),
TYPE_ARG_TYPES (lhstype), &d, 0);
if (i == 0)
{
if (save_elem)
{
cp_error ("ambiguous template instantiation converting to `%#T'", lhstype);
return error_mark_node;
}
save_elem = instantiate_template (elem, t);
/* Check the return type. */
if (! comptypes (TREE_TYPE (lhstype),
TREE_TYPE (TREE_TYPE (save_elem)), 1))
save_elem = 0;
}
}
if (save_elem)
return save_elem;
}
/* No match found, look for a compatible function. */
elem = get_first_fn (rhs); elem = get_first_fn (rhs);
while (elem && ! comp_target_types (lhstype, TREE_TYPE (elem), 1)) while (elem && ! comp_target_types (lhstype, TREE_TYPE (elem), 1))
elem = DECL_CHAIN (elem); elem = DECL_CHAIN (elem);
...@@ -4727,18 +4775,6 @@ instantiate_type (lhstype, rhs, complain) ...@@ -4727,18 +4775,6 @@ instantiate_type (lhstype, rhs, complain)
} }
return error_mark_node; return error_mark_node;
} }
if (TREE_CODE (save_elem) == TEMPLATE_DECL)
{
int ntparms = TREE_VEC_LENGTH
(DECL_TEMPLATE_PARMS (save_elem));
tree *targs = (tree *) alloca (sizeof (tree) * ntparms);
int i, dummy;
i = type_unification
(DECL_TEMPLATE_PARMS (save_elem), targs,
TYPE_ARG_TYPES (TREE_TYPE (save_elem)),
TYPE_ARG_TYPES (lhstype), &dummy, 0);
save_elem = instantiate_template (save_elem, targs);
}
return save_elem; return save_elem;
} }
if (complain) if (complain)
......
...@@ -2359,7 +2359,7 @@ extern void GNU_xref_end PROTO((int)); ...@@ -2359,7 +2359,7 @@ extern void GNU_xref_end PROTO((int));
extern void GNU_xref_file PROTO((char *)); extern void GNU_xref_file PROTO((char *));
extern void GNU_xref_start_scope PROTO((HOST_WIDE_INT)); extern void GNU_xref_start_scope PROTO((HOST_WIDE_INT));
extern void GNU_xref_end_scope PROTO((HOST_WIDE_INT, HOST_WIDE_INT, int, int, int)); extern void GNU_xref_end_scope PROTO((HOST_WIDE_INT, HOST_WIDE_INT, int, int, int));
extern void GNU_xref_def PROTO((tree, char *)); extern void GNU_xref_ref PROTO((tree, char *));
extern void GNU_xref_decl PROTO((tree, tree)); extern void GNU_xref_decl PROTO((tree, tree));
extern void GNU_xref_call PROTO((tree, char *)); extern void GNU_xref_call PROTO((tree, char *));
extern void GNU_xref_function PROTO((tree, tree)); extern void GNU_xref_function PROTO((tree, tree));
......
...@@ -1233,11 +1233,9 @@ cp_convert (type, expr, convtype, flags) ...@@ -1233,11 +1233,9 @@ cp_convert (type, expr, convtype, flags)
{ {
tree rval; tree rval;
rval = build_type_conversion (CONVERT_EXPR, type, e, 1); rval = build_type_conversion (CONVERT_EXPR, type, e, 1);
if (rval) return rval; if (rval)
if (code == BOOLEAN_TYPE) return rval;
cp_error ("`%#T' used where a `bool' was expected", intype); cp_error ("`%#T' used where a `%T' was expected", intype, type);
else
cp_error ("`%#T' used where an `int' was expected", intype);
return error_mark_node; return error_mark_node;
} }
if (code == BOOLEAN_TYPE) if (code == BOOLEAN_TYPE)
......
...@@ -84,6 +84,11 @@ int flag_no_asm; ...@@ -84,6 +84,11 @@ int flag_no_asm;
int flag_no_builtin; int flag_no_builtin;
/* Nonzero means don't recognize the non-ANSI builtin functions.
-ansi sets this. */
int flag_no_nonansi_builtin;
/* Nonzero means do some things the same way PCC does. */ /* Nonzero means do some things the same way PCC does. */
int flag_traditional; int flag_traditional;
...@@ -361,6 +366,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] = ...@@ -361,6 +366,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
{"conserve-space", &flag_conserve_space, 1}, {"conserve-space", &flag_conserve_space, 1},
{"vtable-thunks", &flag_vtable_thunks, 1}, {"vtable-thunks", &flag_vtable_thunks, 1},
{"short-temps", &flag_short_temps, 1}, {"short-temps", &flag_short_temps, 1},
{"nonansi-builtins", &flag_no_nonansi_builtin, 0}
}; };
/* Decode the string P as a language-specific option. /* Decode the string P as a language-specific option.
...@@ -447,6 +453,10 @@ lang_decode_option (p) ...@@ -447,6 +453,10 @@ lang_decode_option (p)
flag_alt_external_templates = 0; flag_alt_external_templates = 0;
found = 1; found = 1;
} }
else if (!strcmp (p, "ansi-overloading"))
{
warning ("-fansi-overloading is no longer meaningful");
}
else for (j = 0; else for (j = 0;
!found && j < sizeof (lang_f_options) / sizeof (lang_f_options[0]); !found && j < sizeof (lang_f_options) / sizeof (lang_f_options[0]);
j++) j++)
...@@ -544,7 +554,8 @@ lang_decode_option (p) ...@@ -544,7 +554,8 @@ lang_decode_option (p)
else return 0; else return 0;
} }
else if (!strcmp (p, "-ansi")) else if (!strcmp (p, "-ansi"))
flag_no_asm = 1, dollars_in_ident = 0, flag_ansi = 1; flag_no_asm = 1, dollars_in_ident = 0, flag_no_nonansi_builtin = 1,
flag_ansi = 1;
#ifdef SPEW_DEBUG #ifdef SPEW_DEBUG
/* Undocumented, only ever used when you're invoking cc1plus by hand, since /* Undocumented, only ever used when you're invoking cc1plus by hand, since
it's probably safe to assume no sane person would ever want to use this it's probably safe to assume no sane person would ever want to use this
...@@ -1000,17 +1011,14 @@ grok_array_decl (array_expr, index_exp) ...@@ -1000,17 +1011,14 @@ grok_array_decl (array_expr, index_exp)
|| TREE_CODE (type) == REFERENCE_TYPE) || TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type); type = TREE_TYPE (type);
if (TYPE_LANG_SPECIFIC (type) if (TREE_CODE (type) == POINTER_TYPE
&& TYPE_OVERLOADS_ARRAY_REF (type))
error ("array expression backwards");
else if (TREE_CODE (type) == POINTER_TYPE
|| TREE_CODE (type) == ARRAY_TYPE) || TREE_CODE (type) == ARRAY_TYPE)
return build_array_ref (index_exp, array_expr); return build_array_ref (index_exp, array_expr);
else
error("`[]' applied to non-pointer type");
/* We gave an error, so give an error. Huh? */ /* The expression E1[E2] is identical (by definition) to *((E1)+(E2)). */
return error_mark_node; return build_indirect_ref (build_binary_op (PLUS_EXPR, array_expr,
index_exp, 1),
"array indexing");
} }
/* Given the cast expression EXP, checking out its validity. Either return /* Given the cast expression EXP, checking out its validity. Either return
...@@ -1128,13 +1136,13 @@ check_classfn (ctype, cname, function) ...@@ -1128,13 +1136,13 @@ check_classfn (ctype, cname, function)
} }
if (methods != end) if (methods != end)
cp_error ("argument list for `%D' does not match any in class `%T'", cp_error ("argument list for `%#D' does not match any in class `%T'",
fn_name, ctype); function, ctype);
else else
{ {
methods = 0; methods = 0;
cp_error ("no `%D' member function declared in class `%T'", cp_error ("no `%#D' member function declared in class `%T'",
fn_name, ctype); function, ctype);
} }
/* If we did not find the method in the class, add it to /* If we did not find the method in the class, add it to
...@@ -2067,9 +2075,13 @@ finish_anon_union (anon_union_decl) ...@@ -2067,9 +2075,13 @@ finish_anon_union (anon_union_decl)
return; return;
} }
while (field) for (; field; field = TREE_CHAIN (field))
{ {
tree decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field)); tree decl;
if (TREE_CODE (field) != FIELD_DECL)
continue;
decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field));
/* tell `pushdecl' that this is not tentative. */ /* tell `pushdecl' that this is not tentative. */
DECL_INITIAL (decl) = error_mark_node; DECL_INITIAL (decl) = error_mark_node;
TREE_PUBLIC (decl) = public_p; TREE_PUBLIC (decl) = public_p;
...@@ -2096,7 +2108,6 @@ finish_anon_union (anon_union_decl) ...@@ -2096,7 +2108,6 @@ finish_anon_union (anon_union_decl)
TREE_PURPOSE of the following TREE_LIST. */ TREE_PURPOSE of the following TREE_LIST. */
elems = tree_cons (NULL_TREE, decl, elems); elems = tree_cons (NULL_TREE, decl, elems);
TREE_TYPE (elems) = type; TREE_TYPE (elems) = type;
field = TREE_CHAIN (field);
} }
if (static_p) if (static_p)
{ {
...@@ -2530,6 +2541,37 @@ walk_sigtables (typedecl_fn, vardecl_fn) ...@@ -2530,6 +2541,37 @@ walk_sigtables (typedecl_fn, vardecl_fn)
} }
} }
/* Determines the proper settings of TREE_PUBLIC and DECL_EXTERNAL for an
inline function at end-of-file. */
void
import_export_inline (decl)
tree decl;
{
if (TREE_PUBLIC (decl))
return;
/* If an explicit instantiation doesn't have TREE_PUBLIC set, it was with
'extern'. */
if (DECL_EXPLICIT_INSTANTIATION (decl)
|| (DECL_IMPLICIT_INSTANTIATION (decl) && ! flag_implicit_templates))
{
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = 1;
}
else if (DECL_FUNCTION_MEMBER_P (decl))
{
tree ctype = DECL_CLASS_CONTEXT (decl);
if (CLASSTYPE_INTERFACE_KNOWN (ctype))
{
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl)
= (CLASSTYPE_INTERFACE_ONLY (ctype)
|| (DECL_INLINE (decl) && ! flag_implement_inlines));
}
}
}
extern int parse_time, varconst_time; extern int parse_time, varconst_time;
#define TIMEVAR(VAR, BODY) \ #define TIMEVAR(VAR, BODY) \
...@@ -2835,24 +2877,12 @@ finish_file () ...@@ -2835,24 +2877,12 @@ finish_file ()
0; don't crash. */ 0; don't crash. */
if (TREE_ASM_WRITTEN (decl) || DECL_SAVED_INSNS (decl) == 0) if (TREE_ASM_WRITTEN (decl) || DECL_SAVED_INSNS (decl) == 0)
continue; continue;
if (DECL_FUNCTION_MEMBER_P (decl) && !TREE_PUBLIC (decl)) import_export_inline (decl);
{
tree ctype = DECL_CLASS_CONTEXT (decl);
if (CLASSTYPE_INTERFACE_KNOWN (ctype))
{
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl)
= (CLASSTYPE_INTERFACE_ONLY (ctype)
|| (DECL_INLINE (decl) && ! flag_implement_inlines));
}
}
if (TREE_PUBLIC (decl) if (TREE_PUBLIC (decl)
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
|| flag_keep_inline_functions) || flag_keep_inline_functions)
{ {
if (DECL_EXTERNAL (decl) if (DECL_EXTERNAL (decl))
|| (DECL_IMPLICIT_INSTANTIATION (decl)
&& ! flag_implicit_templates))
assemble_external (decl); assemble_external (decl);
else else
{ {
...@@ -2879,9 +2909,7 @@ finish_file () ...@@ -2879,9 +2909,7 @@ finish_file ()
if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
&& ! TREE_ASM_WRITTEN (decl)) && ! TREE_ASM_WRITTEN (decl))
{ {
if (DECL_EXTERNAL (decl) if (DECL_EXTERNAL (decl))
|| (DECL_IMPLICIT_INSTANTIATION (decl)
&& ! flag_implicit_templates))
assemble_external (decl); assemble_external (decl);
else else
{ {
......
...@@ -30,6 +30,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ...@@ -30,6 +30,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
typedef char* cp_printer PROTO((HOST_WIDE_INT, int)); typedef char* cp_printer PROTO((HOST_WIDE_INT, int));
extern cp_printer * cp_printers[256]; extern cp_printer * cp_printers[256];
/* Whether or not we should try to be quiet for errors and warnings; this is
used to avoid being too talkative about problems with tentative choices
when we're computing the conversion costs for a method call. */
int cp_silent = 0;
typedef void errorfn (); /* deliberately vague */ typedef void errorfn (); /* deliberately vague */
extern char* cp_file_of PROTO((tree)); extern char* cp_file_of PROTO((tree));
...@@ -150,6 +155,7 @@ cp_error (format, arglist) ...@@ -150,6 +155,7 @@ cp_error (format, arglist)
arglist_dcl arglist_dcl
{ {
extern errorfn error; extern errorfn error;
if (! cp_silent)
cp_thing (error, 0, format, arglist); cp_thing (error, 0, format, arglist);
} }
...@@ -159,6 +165,7 @@ cp_warning (format, arglist) ...@@ -159,6 +165,7 @@ cp_warning (format, arglist)
arglist_dcl arglist_dcl
{ {
extern errorfn warning; extern errorfn warning;
if (! cp_silent)
cp_thing (warning, 0, format, arglist); cp_thing (warning, 0, format, arglist);
} }
...@@ -168,6 +175,7 @@ cp_pedwarn (format, arglist) ...@@ -168,6 +175,7 @@ cp_pedwarn (format, arglist)
arglist_dcl arglist_dcl
{ {
extern errorfn pedwarn; extern errorfn pedwarn;
if (! cp_silent)
cp_thing (pedwarn, 0, format, arglist); cp_thing (pedwarn, 0, format, arglist);
} }
...@@ -177,6 +185,7 @@ cp_compiler_error (format, arglist) ...@@ -177,6 +185,7 @@ cp_compiler_error (format, arglist)
arglist_dcl arglist_dcl
{ {
extern errorfn compiler_error; extern errorfn compiler_error;
if (! cp_silent)
cp_thing (compiler_error, 0, format, arglist); cp_thing (compiler_error, 0, format, arglist);
} }
...@@ -195,6 +204,7 @@ cp_error_at (format, arglist) ...@@ -195,6 +204,7 @@ cp_error_at (format, arglist)
arglist_dcl arglist_dcl
{ {
extern errorfn error_with_file_and_line; extern errorfn error_with_file_and_line;
if (! cp_silent)
cp_thing (error_with_file_and_line, 1, format, arglist); cp_thing (error_with_file_and_line, 1, format, arglist);
} }
...@@ -204,6 +214,7 @@ cp_warning_at (format, arglist) ...@@ -204,6 +214,7 @@ cp_warning_at (format, arglist)
arglist_dcl arglist_dcl
{ {
extern errorfn warning_with_file_and_line; extern errorfn warning_with_file_and_line;
if (! cp_silent)
cp_thing (warning_with_file_and_line, 1, format, arglist); cp_thing (warning_with_file_and_line, 1, format, arglist);
} }
...@@ -213,5 +224,6 @@ cp_pedwarn_at (format, arglist) ...@@ -213,5 +224,6 @@ cp_pedwarn_at (format, arglist)
arglist_dcl arglist_dcl
{ {
extern errorfn pedwarn_with_file_and_line; extern errorfn pedwarn_with_file_and_line;
if (! cp_silent)
cp_thing (pedwarn_with_file_and_line, 1, format, arglist); cp_thing (pedwarn_with_file_and_line, 1, format, arglist);
} }
...@@ -104,6 +104,8 @@ dump_readonly_or_volatile (t, p) ...@@ -104,6 +104,8 @@ dump_readonly_or_volatile (t, p)
if (p == before) OB_PUTC (' '); if (p == before) OB_PUTC (' ');
if (TYPE_READONLY (t)) if (TYPE_READONLY (t))
OB_PUTS ("const"); OB_PUTS ("const");
if (TYPE_READONLY (t) && TYPE_VOLATILE (t))
OB_PUTC (' ');
if (TYPE_VOLATILE (t)) if (TYPE_VOLATILE (t))
OB_PUTS ("volatile"); OB_PUTS ("volatile");
if (p == after) OB_PUTC (' '); if (p == after) OB_PUTC (' ');
...@@ -1228,6 +1230,14 @@ dump_expr (t, nop) ...@@ -1228,6 +1230,14 @@ dump_expr (t, nop)
break; break;
} }
case TREE_LIST:
if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL)
{
OB_PUTID (DECL_NAME (TREE_VALUE (t)));
break;
}
/* else fall through */
/* This list is incomplete, but should suffice for now. /* This list is incomplete, but should suffice for now.
It is very important that `sorry' does not call It is very important that `sorry' does not call
`report_error_function'. That could cause an infinite loop. */ `report_error_function'. That could cause an infinite loop. */
......
...@@ -217,6 +217,7 @@ perform_member_init (member, name, init, explicit) ...@@ -217,6 +217,7 @@ perform_member_init (member, name, init, explicit)
expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init)); expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
} }
} }
expand_cleanups_to (NULL_TREE);
if (flag_handle_exceptions && TYPE_NEEDS_DESTRUCTOR (type)) if (flag_handle_exceptions && TYPE_NEEDS_DESTRUCTOR (type))
cp_warning ("caution, member `%D' may not be destroyed in the presense of an exception during construction", member); cp_warning ("caution, member `%D' may not be destroyed in the presense of an exception during construction", member);
} }
...@@ -230,11 +231,14 @@ sort_member_init (t) ...@@ -230,11 +231,14 @@ sort_member_init (t)
tree init_list = NULL_TREE; tree init_list = NULL_TREE;
tree fields_to_unmark = NULL_TREE; tree fields_to_unmark = NULL_TREE;
int found; int found;
int last_pos = 0;
tree last_field;
for (member = TYPE_FIELDS (t); member ; member = TREE_CHAIN (member)) for (member = TYPE_FIELDS (t); member ; member = TREE_CHAIN (member))
{ {
int pos;
found = 0; found = 0;
for (x = current_member_init_list ; x ; x = TREE_CHAIN (x)) for (x = current_member_init_list, pos = 0; x; x = TREE_CHAIN (x), ++pos)
{ {
/* If we cleared this out, then pay no attention to it. */ /* If we cleared this out, then pay no attention to it. */
if (TREE_PURPOSE (x) == NULL_TREE) if (TREE_PURPOSE (x) == NULL_TREE)
...@@ -264,6 +268,17 @@ sort_member_init (t) ...@@ -264,6 +268,17 @@ sort_member_init (t)
field); field);
continue; continue;
} }
else
{
if (pos < last_pos && extra_warnings)
{
cp_warning_at ("member initializers for `%#D'", last_field);
cp_warning_at (" and `%#D'", field);
warning (" will be re-ordered to match declaration order");
}
last_pos = pos;
last_field = field;
}
init_list = chainon (init_list, init_list = chainon (init_list,
build_tree_list (name, TREE_VALUE (x))); build_tree_list (name, TREE_VALUE (x)));
...@@ -500,9 +515,10 @@ emit_base_init (t, immediately) ...@@ -500,9 +515,10 @@ emit_base_init (t, immediately)
continue; continue;
member = convert_pointer_to (binfo, current_class_decl); member = convert_pointer_to (binfo, current_class_decl);
expand_aggr_init_1 (t_binfo, 0, expand_aggr_init_1 (binfo, 0,
build_indirect_ref (member, NULL_PTR), init, build_indirect_ref (member, NULL_PTR), init,
BINFO_OFFSET_ZEROP (binfo), LOOKUP_COMPLAIN); BINFO_OFFSET_ZEROP (binfo), LOOKUP_NORMAL);
expand_cleanups_to (NULL_TREE);
} }
if (pass == 0) if (pass == 0)
...@@ -568,9 +584,10 @@ emit_base_init (t, immediately) ...@@ -568,9 +584,10 @@ emit_base_init (t, immediately)
current_class_decl, BINFO_OFFSET (base_binfo)); current_class_decl, BINFO_OFFSET (base_binfo));
ref = build_indirect_ref (base, NULL_PTR); ref = build_indirect_ref (base, NULL_PTR);
expand_aggr_init_1 (t_binfo, 0, ref, NULL_TREE, expand_aggr_init_1 (base_binfo, 0, ref, NULL_TREE,
BINFO_OFFSET_ZEROP (base_binfo), BINFO_OFFSET_ZEROP (base_binfo),
LOOKUP_COMPLAIN); LOOKUP_NORMAL);
expand_cleanups_to (NULL_TREE);
} }
} }
CLEAR_BINFO_BASEINIT_MARKED (base_binfo); CLEAR_BINFO_BASEINIT_MARKED (base_binfo);
...@@ -655,11 +672,6 @@ emit_base_init (t, immediately) ...@@ -655,11 +672,6 @@ emit_base_init (t, immediately)
current_member_init_list = NULL_TREE; current_member_init_list = NULL_TREE;
/* It is possible for the initializers to need cleanups.
Expand those cleanups now that all the initialization
has been done. */
expand_cleanups_to (NULL_TREE);
if (! immediately) if (! immediately)
{ {
extern rtx base_init_insns; extern rtx base_init_insns;
...@@ -734,6 +746,7 @@ expand_aggr_vbase_init_1 (binfo, exp, addr, init_list) ...@@ -734,6 +746,7 @@ expand_aggr_vbase_init_1 (binfo, exp, addr, init_list)
/* Call constructors, but don't set up vtables. */ /* Call constructors, but don't set up vtables. */
expand_aggr_init_1 (binfo, exp, ref, init, 0, expand_aggr_init_1 (binfo, exp, ref, init, 0,
LOOKUP_COMPLAIN|LOOKUP_SPECULATIVELY); LOOKUP_COMPLAIN|LOOKUP_SPECULATIVELY);
expand_cleanups_to (NULL_TREE);
CLEAR_BINFO_VBASE_INIT_MARKED (binfo); CLEAR_BINFO_VBASE_INIT_MARKED (binfo);
} }
...@@ -1966,12 +1979,6 @@ build_offset_ref (cname, name) ...@@ -1966,12 +1979,6 @@ build_offset_ref (cname, name)
name, NULL_TREE, 1); name, NULL_TREE, 1);
#endif #endif
fnfields = lookup_fnfields (TYPE_BINFO (type), name, 1);
fields = lookup_field (type, name, 0, 0);
if (fields == error_mark_node || fnfields == error_mark_node)
return error_mark_node;
if (current_class_type == 0 if (current_class_type == 0
|| get_base_distance (type, current_class_type, 0, &basetypes) == -1) || get_base_distance (type, current_class_type, 0, &basetypes) == -1)
{ {
...@@ -1986,6 +1993,12 @@ build_offset_ref (cname, name) ...@@ -1986,6 +1993,12 @@ build_offset_ref (cname, name)
else else
decl = C_C_D; decl = C_C_D;
fnfields = lookup_fnfields (basetypes, name, 1);
fields = lookup_field (basetypes, name, 0, 0);
if (fields == error_mark_node || fnfields == error_mark_node)
return error_mark_node;
/* A lot of this logic is now handled in lookup_field and /* A lot of this logic is now handled in lookup_field and
lookup_fnfield. */ lookup_fnfield. */
if (fnfields) if (fnfields)
...@@ -2018,7 +2031,6 @@ build_offset_ref (cname, name) ...@@ -2018,7 +2031,6 @@ build_offset_ref (cname, name)
{ {
extern int flag_save_memoized_contexts; extern int flag_save_memoized_contexts;
/* This does not handle access checking yet. */
if (DECL_CHAIN (t) == NULL_TREE || dtor) if (DECL_CHAIN (t) == NULL_TREE || dtor)
{ {
enum access_type access; enum access_type access;
...@@ -3261,7 +3273,7 @@ build_new (placement, decl, init, use_global_new) ...@@ -3261,7 +3273,7 @@ build_new (placement, decl, init, use_global_new)
build_tree_list (NULL_TREE, rval)))); build_tree_list (NULL_TREE, rval))));
} }
return save_expr (rval); return rval;
} }
/* `expand_vec_init' performs initialization of a vector of aggregate /* `expand_vec_init' performs initialization of a vector of aggregate
......
...@@ -960,15 +960,6 @@ set_yydebug (value) ...@@ -960,15 +960,6 @@ set_yydebug (value)
#endif #endif
} }
#ifdef SPEW_DEBUG
const char *
debug_yytranslate (value)
int value;
{
return yytname[YYTRANSLATE (value)];
}
#endif
/* Functions and data structures for #pragma interface. /* Functions and data structures for #pragma interface.
...@@ -1786,13 +1777,6 @@ cons_up_default_function (type, name, fields, kind) ...@@ -1786,13 +1777,6 @@ cons_up_default_function (type, name, fields, kind)
warn_if_unknown_interface (); warn_if_unknown_interface ();
t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2)); t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2));
store_pending_inline (fn, t); store_pending_inline (fn, t);
if (interface_unknown)
TREE_PUBLIC (fn) = 0;
else
{
TREE_PUBLIC (fn) = 1;
DECL_EXTERNAL (fn) = interface_only;
}
} }
finish_method (fn); finish_method (fn);
...@@ -2182,17 +2166,17 @@ check_for_missing_semicolon (type) ...@@ -2182,17 +2166,17 @@ check_for_missing_semicolon (type)
if (yychar < 0) if (yychar < 0)
yychar = yylex (); yychar = yylex ();
if (yychar > 255 if ((yychar > 255
&& yychar != SCSPEC && yychar != SCSPEC
&& yychar != IDENTIFIER && yychar != IDENTIFIER
&& yychar != TYPENAME) && yychar != TYPENAME)
|| end_of_file)
{ {
if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))
error ("semicolon missing after %s declaration", error ("semicolon missing after %s declaration",
TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct"); TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct");
else else
error ("semicolon missing after declaration of `%s'", cp_error ("semicolon missing after declaration of `%T'", type);
TYPE_NAME_STRING (type));
shadow_tag (build_tree_list (0, type)); shadow_tag (build_tree_list (0, type));
} }
/* Could probably also hack cases where class { ... } f (); appears. */ /* Could probably also hack cases where class { ... } f (); appears. */
......
...@@ -58,14 +58,16 @@ enum rid ...@@ -58,14 +58,16 @@ enum rid
RID_VOLATILE, RID_VOLATILE,
RID_FRIEND, RID_FRIEND,
RID_VIRTUAL, RID_VIRTUAL,
RID_SIGNED,
RID_AUTO,
RID_MUTABLE,
/* This is where grokdeclarator ends its search when setting the specbits. */
RID_PUBLIC, RID_PUBLIC,
RID_PRIVATE, RID_PRIVATE,
RID_PROTECTED, RID_PROTECTED,
RID_SIGNED,
RID_EXCEPTION, RID_EXCEPTION,
RID_RAISES,
RID_AUTO,
RID_MUTABLE,
RID_TEMPLATE, RID_TEMPLATE,
RID_SIGNATURE, RID_SIGNATURE,
/* Before adding enough to get up to 64, the RIDBIT_* macros /* Before adding enough to get up to 64, the RIDBIT_* macros
...@@ -76,6 +78,7 @@ enum rid ...@@ -76,6 +78,7 @@ enum rid
#define NORID RID_UNUSED #define NORID RID_UNUSED
#define RID_FIRST_MODIFIER RID_EXTERN #define RID_FIRST_MODIFIER RID_EXTERN
#define RID_LAST_MODIFIER RID_MUTABLE
/* The type that can represent all values of RIDBIT. */ /* The type that can represent all values of RIDBIT. */
/* We assume that we can stick in at least 32 bits into this. */ /* We assume that we can stick in at least 32 bits into this. */
......
...@@ -852,18 +852,17 @@ build_decl_overload (dname, parms, for_method) ...@@ -852,18 +852,17 @@ build_decl_overload (dname, parms, for_method)
/* member operators new and delete look like methods at this point. */ /* member operators new and delete look like methods at this point. */
if (! for_method && parms != NULL_TREE && TREE_CODE (parms) == TREE_LIST) if (! for_method && parms != NULL_TREE && TREE_CODE (parms) == TREE_LIST)
{ {
if (TREE_VALUE (parms) == sizetype if (dname == ansi_opname[(int) DELETE_EXPR])
&& TREE_CHAIN (parms) == void_list_node) return get_identifier ("__builtin_delete");
else if (dname == ansi_opname[(int) VEC_DELETE_EXPR])
return get_identifier ("__builtin_vec_delete");
else if (TREE_CHAIN (parms) == void_list_node)
{ {
if (dname == ansi_opname[(int) NEW_EXPR]) if (dname == ansi_opname[(int) NEW_EXPR])
return get_identifier ("__builtin_new"); return get_identifier ("__builtin_new");
else if (dname == ansi_opname[(int) VEC_NEW_EXPR]) else if (dname == ansi_opname[(int) VEC_NEW_EXPR])
return get_identifier ("__builtin_vec_new"); return get_identifier ("__builtin_vec_new");
} }
else if (dname == ansi_opname[(int) DELETE_EXPR])
return get_identifier ("__builtin_delete");
else if (dname == ansi_opname[(int) VEC_DELETE_EXPR])
return get_identifier ("__builtin_vec_delete");
} }
OB_INIT (); OB_INIT ();
......
...@@ -895,7 +895,8 @@ paren_expr_or_null: ...@@ -895,7 +895,8 @@ paren_expr_or_null:
cond_stmt_keyword); cond_stmt_keyword);
$$ = integer_zero_node; } $$ = integer_zero_node; }
| '(' expr ')' | '(' expr ')'
{ $$ = $2; } { $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node,
bool_truthvalue_conversion ($2)); }
; ;
paren_cond_or_null: paren_cond_or_null:
...@@ -904,13 +905,16 @@ paren_cond_or_null: ...@@ -904,13 +905,16 @@ paren_cond_or_null:
cond_stmt_keyword); cond_stmt_keyword);
$$ = integer_zero_node; } $$ = integer_zero_node; }
| '(' condition ')' | '(' condition ')'
{ $$ = $2; } { $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node,
bool_truthvalue_conversion ($2)); }
; ;
xcond: xcond:
/* empty */ /* empty */
{ $$ = NULL_TREE; } { $$ = NULL_TREE; }
| condition | condition
{ $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node,
bool_truthvalue_conversion ($$)); }
| error | error
{ $$ = NULL_TREE; } { $$ = NULL_TREE; }
; ;
...@@ -1548,7 +1552,7 @@ primary: ...@@ -1548,7 +1552,7 @@ primary:
if (TREE_CODE (TREE_TYPE ($1)) if (TREE_CODE (TREE_TYPE ($1))
!= TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($3)))) != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($3))))
cp_error ("`%E' is not of type `%T'", $1, $3); cp_error ("`%E' is not of type `%T'", $1, $3);
$$ = void_zero_node; $$ = convert (void_type_node, $1);
} }
| object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT | object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT
{ {
...@@ -1557,7 +1561,7 @@ primary: ...@@ -1557,7 +1561,7 @@ primary:
if (TREE_CODE (TREE_TYPE ($1)) if (TREE_CODE (TREE_TYPE ($1))
!= TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($2)))) != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($2))))
cp_error ("`%E' is not of type `%T'", $1, $2); cp_error ("`%E' is not of type `%T'", $1, $2);
$$ = void_zero_node; $$ = convert (void_type_node, $1);
} }
; ;
...@@ -2398,25 +2402,59 @@ base_class_access_list: ...@@ -2398,25 +2402,59 @@ base_class_access_list:
; ;
left_curly: '{' left_curly: '{'
{ tree t; { tree t = $<ttype>0;
push_obstacks_nochange (); push_obstacks_nochange ();
end_temporary_allocation (); end_temporary_allocation ();
if (! IS_AGGR_TYPE ($<ttype>0)) if (! IS_AGGR_TYPE (t))
{ {
$<ttype>0 = make_lang_type (RECORD_TYPE); t = $<ttype>0 = make_lang_type (RECORD_TYPE);
TYPE_NAME ($<ttype>0) = get_identifier ("erroneous type"); TYPE_NAME (t) = get_identifier ("erroneous type");
} }
if (TYPE_SIZE ($<ttype>0)) if (TYPE_SIZE (t))
duplicate_tag_error ($<ttype>0); duplicate_tag_error (t);
if (TYPE_SIZE ($<ttype>0) || TYPE_BEING_DEFINED ($<ttype>0)) if (TYPE_SIZE (t) || TYPE_BEING_DEFINED (t))
{ {
t = make_lang_type (TREE_CODE ($<ttype>0)); t = make_lang_type (TREE_CODE (t));
pushtag (TYPE_IDENTIFIER ($<ttype>0), t, 0); pushtag (TYPE_IDENTIFIER ($<ttype>0), t, 0);
$<ttype>0 = t; $<ttype>0 = t;
} }
pushclass ($<ttype>0, 0); pushclass (t, 0);
TYPE_BEING_DEFINED ($<ttype>0) = 1; TYPE_BEING_DEFINED (t) = 1;
/* Reset the interface data, at the earliest possible
moment, as it might have been set via a class foo;
before. */
/* Don't change signatures. */
if (! IS_SIGNATURE (t))
{
extern tree pending_vtables;
int needs_writing;
tree name = TYPE_IDENTIFIER (t);
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
/* Record how to set the access of this class's
virtual functions. If write_virtuals == 2 or 3, then
inline virtuals are ``extern inline''. */
switch (write_virtuals)
{
case 0:
case 1:
needs_writing = 1;
break;
case 2:
needs_writing = !! value_member (name, pending_vtables);
break;
case 3:
needs_writing = ! CLASSTYPE_INTERFACE_ONLY (t)
&& CLASSTYPE_INTERFACE_KNOWN (t);
break;
default:
needs_writing = 0;
}
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = needs_writing;
}
#if 0 #if 0
t = TYPE_IDENTIFIER ($<ttype>0); t = TYPE_IDENTIFIER ($<ttype>0);
if (t && IDENTIFIER_TEMPLATE (t)) if (t && IDENTIFIER_TEMPLATE (t))
...@@ -3053,7 +3091,7 @@ simple_if: ...@@ -3053,7 +3091,7 @@ simple_if:
{ cond_stmt_keyword = "if"; } { cond_stmt_keyword = "if"; }
.pushlevel paren_cond_or_null .pushlevel paren_cond_or_null
{ emit_line_note (input_filename, lineno); { emit_line_note (input_filename, lineno);
expand_start_cond (bool_truthvalue_conversion ($4), 0); } expand_start_cond ($4, 0); }
implicitly_scoped_stmt implicitly_scoped_stmt
; ;
...@@ -3108,7 +3146,7 @@ simple_stmt: ...@@ -3108,7 +3146,7 @@ simple_stmt:
expand_start_loop (1); expand_start_loop (1);
cond_stmt_keyword = "while"; } cond_stmt_keyword = "while"; }
.pushlevel paren_cond_or_null .pushlevel paren_cond_or_null
{ expand_exit_loop_if_false (0, bool_truthvalue_conversion ($4)); } { expand_exit_loop_if_false (0, $4); }
already_scoped_stmt already_scoped_stmt
{ expand_end_bindings (getdecls (), kept_level_p (), 1); { expand_end_bindings (getdecls (), kept_level_p (), 1);
poplevel (kept_level_p (), 1, 0); poplevel (kept_level_p (), 1, 0);
...@@ -3124,7 +3162,7 @@ simple_stmt: ...@@ -3124,7 +3162,7 @@ simple_stmt:
cond_stmt_keyword = "do"; } cond_stmt_keyword = "do"; }
paren_expr_or_null ';' paren_expr_or_null ';'
{ emit_line_note (input_filename, lineno); { emit_line_note (input_filename, lineno);
expand_exit_loop_if_false (0, bool_truthvalue_conversion ($6)); expand_exit_loop_if_false (0, $6);
expand_end_loop (); expand_end_loop ();
clear_momentary (); clear_momentary ();
finish_stmt (); } finish_stmt (); }
...@@ -3135,7 +3173,7 @@ simple_stmt: ...@@ -3135,7 +3173,7 @@ simple_stmt:
expand_start_loop_continue_elsewhere (1); } expand_start_loop_continue_elsewhere (1); }
.pushlevel xcond ';' .pushlevel xcond ';'
{ emit_line_note (input_filename, lineno); { emit_line_note (input_filename, lineno);
if ($4) expand_exit_loop_if_false (0, bool_truthvalue_conversion ($4)); } if ($4) expand_exit_loop_if_false (0, $4); }
xexpr ')' xexpr ')'
/* Don't let the tree nodes for $7 be discarded /* Don't let the tree nodes for $7 be discarded
by clear_momentary during the parsing of the next stmt. */ by clear_momentary during the parsing of the next stmt. */
...@@ -3156,7 +3194,7 @@ simple_stmt: ...@@ -3156,7 +3194,7 @@ simple_stmt:
expand_start_loop_continue_elsewhere (1); } expand_start_loop_continue_elsewhere (1); }
.pushlevel xcond ';' .pushlevel xcond ';'
{ emit_line_note (input_filename, lineno); { emit_line_note (input_filename, lineno);
if ($4) expand_exit_loop_if_false (0, bool_truthvalue_conversion ($4)); } if ($4) expand_exit_loop_if_false (0, $4); }
xexpr ')' xexpr ')'
/* Don't let the tree nodes for $7 be discarded /* Don't let the tree nodes for $7 be discarded
by clear_momentary during the parsing of the next stmt. */ by clear_momentary during the parsing of the next stmt. */
...@@ -3761,3 +3799,13 @@ operator_name: ...@@ -3761,3 +3799,13 @@ operator_name:
; ;
%% %%
#ifdef SPEW_DEBUG
const char *
debug_yytranslate (value)
int value;
{
return yytname[YYTRANSLATE (value)];
}
#endif
...@@ -2408,16 +2408,19 @@ do_function_instantiation (declspecs, declarator, storage) ...@@ -2408,16 +2408,19 @@ do_function_instantiation (declspecs, declarator, storage)
if (flag_external_templates) if (flag_external_templates)
return; return;
if (DECL_EXPLICIT_INSTANTIATION (result) && ! DECL_EXTERNAL (result)) if (DECL_EXPLICIT_INSTANTIATION (result) && TREE_PUBLIC (result))
return; return;
SET_DECL_EXPLICIT_INSTANTIATION (result); SET_DECL_EXPLICIT_INSTANTIATION (result);
TREE_PUBLIC (result) = 1;
if (storage == NULL_TREE) if (storage == NULL_TREE)
DECL_EXTERNAL (result) = DECL_INLINE (result) && ! flag_implement_inlines; {
TREE_PUBLIC (result) = 1;
DECL_EXTERNAL (result) = (DECL_INLINE (result)
&& ! flag_implement_inlines);
}
else if (storage == ridpointers[(int) RID_EXTERN]) else if (storage == ridpointers[(int) RID_EXTERN])
DECL_EXTERNAL (result) = 1; ;
else else
cp_error ("storage class `%D' applied to template instantiation", cp_error ("storage class `%D' applied to template instantiation",
storage); storage);
...@@ -2454,7 +2457,7 @@ do_type_instantiation (name, storage) ...@@ -2454,7 +2457,7 @@ do_type_instantiation (name, storage)
} }
/* We've already instantiated this. */ /* We've already instantiated this. */
if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && ! CLASSTYPE_INTERFACE_ONLY (t)) if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && CLASSTYPE_INTERFACE_KNOWN (t))
{ {
if (! extern_p) if (! extern_p)
cp_pedwarn ("multiple explicit instantiation of `%#T'", t); cp_pedwarn ("multiple explicit instantiation of `%#T'", t);
...@@ -2462,11 +2465,11 @@ do_type_instantiation (name, storage) ...@@ -2462,11 +2465,11 @@ do_type_instantiation (name, storage)
} }
SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t); SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t);
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! extern_p;
SET_CLASSTYPE_INTERFACE_KNOWN (t);
CLASSTYPE_INTERFACE_ONLY (t) = extern_p;
if (! extern_p) if (! extern_p)
{ {
SET_CLASSTYPE_INTERFACE_KNOWN (t);
CLASSTYPE_INTERFACE_ONLY (t) = 0;
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = 1;
CLASSTYPE_DEBUG_REQUESTED (t) = 1; CLASSTYPE_DEBUG_REQUESTED (t) = 1;
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0; TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0;
rest_of_type_compilation (t, 1); rest_of_type_compilation (t, 1);
...@@ -2478,9 +2481,12 @@ do_type_instantiation (name, storage) ...@@ -2478,9 +2481,12 @@ do_type_instantiation (name, storage)
for (; tmp; tmp = TREE_CHAIN (tmp)) for (; tmp; tmp = TREE_CHAIN (tmp))
{ {
SET_DECL_EXPLICIT_INSTANTIATION (tmp); SET_DECL_EXPLICIT_INSTANTIATION (tmp);
if (! extern_p)
{
TREE_PUBLIC (tmp) = 1; TREE_PUBLIC (tmp) = 1;
DECL_EXTERNAL (tmp) DECL_EXTERNAL (tmp) = (DECL_INLINE (tmp)
= (extern_p || (DECL_INLINE (tmp) && ! flag_implement_inlines)); && ! flag_implement_inlines);
}
} }
#if 0 #if 0
......
...@@ -1626,6 +1626,31 @@ make_deep_copy (t) ...@@ -1626,6 +1626,31 @@ make_deep_copy (t)
TREE_OPERAND (t, 0) = make_deep_copy (TREE_OPERAND (t, 0)); TREE_OPERAND (t, 0) = make_deep_copy (TREE_OPERAND (t, 0));
return t; return t;
case POINTER_TYPE:
return build_pointer_type (make_deep_copy (TREE_TYPE (t)));
case REFERENCE_TYPE:
return build_reference_type (make_deep_copy (TREE_TYPE (t)));
case FUNCTION_TYPE:
return build_function_type (make_deep_copy (TREE_TYPE (t)),
make_deep_copy (TYPE_ARG_TYPES (t)));
case ARRAY_TYPE:
return build_array_type (make_deep_copy (TREE_TYPE (t)),
make_deep_copy (TYPE_DOMAIN (t)));
case OFFSET_TYPE:
return build_offset_type (make_deep_copy (TYPE_OFFSET_BASETYPE (t)),
make_deep_copy (TREE_TYPE (t)));
case METHOD_TYPE:
return build_method_type
(make_deep_copy (TYPE_METHOD_BASETYPE (t)),
build_function_type
(make_deep_copy (TREE_TYPE (t)),
make_deep_copy (TREE_CHAIN (TYPE_ARG_TYPES (t)))));
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (t))
return build_ptrmemfunc_type
(make_deep_copy (TYPE_PTRMEMFUNC_FN_TYPE (t)));
/* else fall through */
/* This list is incomplete, but should suffice for now. /* This list is incomplete, but should suffice for now.
It is very important that `sorry' does not call It is very important that `sorry' does not call
`report_error_function'. That could cause an infinite loop. */ `report_error_function'. That could cause an infinite loop. */
......
...@@ -734,8 +734,6 @@ comp_target_types (ttl, ttr, nptrs) ...@@ -734,8 +734,6 @@ comp_target_types (ttl, ttr, nptrs)
ttr = TYPE_MAIN_VARIANT (ttr); ttr = TYPE_MAIN_VARIANT (ttr);
if (ttl == ttr) if (ttl == ttr)
return 1; return 1;
if (TREE_CODE (ttr) == TEMPLATE_TYPE_PARM)
return 1;
if (TREE_CODE (ttr) != TREE_CODE (ttl)) if (TREE_CODE (ttr) != TREE_CODE (ttl))
return 0; return 0;
...@@ -813,12 +811,14 @@ common_base_type (tt1, tt2) ...@@ -813,12 +811,14 @@ common_base_type (tt1, tt2)
if (UNIQUELY_DERIVED_FROM_P (tt2, tt1)) if (UNIQUELY_DERIVED_FROM_P (tt2, tt1))
return tt2; return tt2;
#if 0
/* If they share a virtual baseclass, that's good enough. */ /* If they share a virtual baseclass, that's good enough. */
for (tmp = CLASSTYPE_VBASECLASSES (tt1); tmp; tmp = TREE_CHAIN (tmp)) for (tmp = CLASSTYPE_VBASECLASSES (tt1); tmp; tmp = TREE_CHAIN (tmp))
{ {
if (binfo_member (BINFO_TYPE (tmp), CLASSTYPE_VBASECLASSES (tt2))) if (binfo_member (BINFO_TYPE (tmp), CLASSTYPE_VBASECLASSES (tt2)))
return BINFO_TYPE (tmp); return BINFO_TYPE (tmp);
} }
#endif
/* Otherwise, try to find a unique baseclass of TT1 /* Otherwise, try to find a unique baseclass of TT1
that is shared by TT2, and follow that down. */ that is shared by TT2, and follow that down. */
...@@ -904,6 +904,8 @@ compparms (parms1, parms2, strict) ...@@ -904,6 +904,8 @@ compparms (parms1, parms2, strict)
return t2 == void_list_node && TREE_PURPOSE (t1); return t2 == void_list_node && TREE_PURPOSE (t1);
return TREE_PURPOSE (t1) || TREE_PURPOSE (t2); return TREE_PURPOSE (t1) || TREE_PURPOSE (t2);
} }
#if 0
/* Default parms are not part of the type of a function. */
if (strict != 3 && TREE_PURPOSE (t1) && TREE_PURPOSE (t2)) if (strict != 3 && TREE_PURPOSE (t1) && TREE_PURPOSE (t2))
{ {
int cmp = simple_cst_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2)); int cmp = simple_cst_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2));
...@@ -912,6 +914,7 @@ compparms (parms1, parms2, strict) ...@@ -912,6 +914,7 @@ compparms (parms1, parms2, strict)
if (cmp == 0) if (cmp == 0)
return 0; return 0;
} }
#endif
t1 = TREE_CHAIN (t1); t1 = TREE_CHAIN (t1);
t2 = TREE_CHAIN (t2); t2 = TREE_CHAIN (t2);
...@@ -959,8 +962,6 @@ comp_target_parms (parms1, parms2, strict) ...@@ -959,8 +962,6 @@ comp_target_parms (parms1, parms2, strict)
p2 = TREE_VALUE (t2); p2 = TREE_VALUE (t2);
if (p1 == p2) if (p1 == p2)
continue; continue;
if (TREE_CODE (p2) == TEMPLATE_TYPE_PARM)
continue;
if ((TREE_CODE (p1) == POINTER_TYPE && TREE_CODE (p2) == POINTER_TYPE) if ((TREE_CODE (p1) == POINTER_TYPE && TREE_CODE (p2) == POINTER_TYPE)
|| (TREE_CODE (p1) == REFERENCE_TYPE && TREE_CODE (p2) == REFERENCE_TYPE)) || (TREE_CODE (p1) == REFERENCE_TYPE && TREE_CODE (p2) == REFERENCE_TYPE))
...@@ -970,9 +971,6 @@ comp_target_parms (parms1, parms2, strict) ...@@ -970,9 +971,6 @@ comp_target_parms (parms1, parms2, strict)
== TYPE_MAIN_VARIANT (TREE_TYPE (p2)))) == TYPE_MAIN_VARIANT (TREE_TYPE (p2))))
continue; continue;
if (TREE_CODE (TREE_TYPE (p2)) == TEMPLATE_TYPE_PARM)
continue;
/* The following is wrong for contravariance, /* The following is wrong for contravariance,
but many programs depend on it. */ but many programs depend on it. */
if (TREE_TYPE (p1) == void_type_node) if (TREE_TYPE (p1) == void_type_node)
...@@ -2530,13 +2528,15 @@ convert_arguments (return_loc, typelist, values, fndecl, flags) ...@@ -2530,13 +2528,15 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
&& (type == 0 || TREE_CODE (type) != REFERENCE_TYPE)) && (type == 0 || TREE_CODE (type) != REFERENCE_TYPE))
val = TREE_OPERAND (val, 0); val = TREE_OPERAND (val, 0);
if ((type == 0 || TREE_CODE (type) != REFERENCE_TYPE) if (type == 0 || TREE_CODE (type) != REFERENCE_TYPE)
&& (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE {
if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE || TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (val)) == METHOD_TYPE)) || TREE_CODE (TREE_TYPE (val)) == METHOD_TYPE)
val = default_conversion (val); val = default_conversion (val);
val = require_complete_type (val); val = require_complete_type (val);
}
if (val == error_mark_node) if (val == error_mark_node)
continue; continue;
...@@ -2555,7 +2555,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags) ...@@ -2555,7 +2555,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
} }
else else
{ {
#ifdef PROMOTE_PROTOTYPES #if 0 && defined (PROMOTE_PROTOTYPES)
/* This breaks user-defined conversions. */
/* Rather than truncating and then reextending, /* Rather than truncating and then reextending,
convert directly to int, if that's the type we will want. */ convert directly to int, if that's the type we will want. */
if (! flag_traditional if (! flag_traditional
...@@ -4682,11 +4683,20 @@ build_conditional_expr (ifexp, op1, op2) ...@@ -4682,11 +4683,20 @@ build_conditional_expr (ifexp, op1, op2)
{ {
if (result_type == error_mark_node) if (result_type == error_mark_node)
{ {
message_2_types (error, "common base type of types `%s' and `%s' is ambiguous", cp_error ("common base type of types `%T' and `%T' is ambiguous",
TREE_TYPE (type1), TREE_TYPE (type2)); TREE_TYPE (type1), TREE_TYPE (type2));
result_type = ptr_type_node; result_type = ptr_type_node;
} }
else result_type = TYPE_POINTER_TO (result_type); else
{
if (pedantic
&& result_type != TREE_TYPE (type1)
&& result_type != TREE_TYPE (type2))
cp_pedwarn ("`%T' and `%T' converted to `%T *' in conditional expression",
type1, type2, result_type);
result_type = TYPE_POINTER_TO (result_type);
}
} }
else else
{ {
...@@ -7210,7 +7220,8 @@ c_expand_start_case (exp) ...@@ -7210,7 +7220,8 @@ c_expand_start_case (exp)
exp = index; exp = index;
} }
expand_start_case (1, exp, type, "switch statement"); expand_start_case (1, build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp),
type, "switch statement");
return exp; return exp;
} }
......
...@@ -631,7 +631,7 @@ digest_init (type, init, tail) ...@@ -631,7 +631,7 @@ digest_init (type, init, tail)
tree type, init, *tail; tree type, init, *tail;
{ {
enum tree_code code = TREE_CODE (type); enum tree_code code = TREE_CODE (type);
tree element = 0; tree element = NULL_TREE;
tree old_tail_contents; tree old_tail_contents;
/* Nonzero if INIT is a braced grouping, which comes in as a CONSTRUCTOR /* Nonzero if INIT is a braced grouping, which comes in as a CONSTRUCTOR
tree node which has no TREE_TYPE. */ tree node which has no TREE_TYPE. */
......
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