From 0059501924049e53b3a019bacfe12eff6a1827a3 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Thu, 18 Aug 1994 20:50:43 +0000 Subject: [PATCH] 46 Cygnus<->FSF merge From-SVN: r7943 --- gcc/cp/ChangeLog | 208 +++++++++++++++++++++++++++++++++++++++++++++++ gcc/cp/call.c | 23 +++++- gcc/cp/class.c | 114 +++++++++++++++++--------- gcc/cp/cp-tree.h | 2 +- gcc/cp/cvt.c | 8 +- gcc/cp/decl.c | 139 +++++++++++++++++-------------- gcc/cp/decl2.c | 98 ++++++++++++++-------- gcc/cp/errfn.c | 26 ++++-- gcc/cp/error.c | 10 +++ gcc/cp/init.c | 48 +++++++---- gcc/cp/lex.c | 28 ++----- gcc/cp/lex.h | 11 ++- gcc/cp/method.c | 11 ++- gcc/cp/parse.y | 88 +++++++++++++++----- gcc/cp/pt.c | 28 ++++--- gcc/cp/tree.c | 25 ++++++ gcc/cp/typeck.c | 45 ++++++---- gcc/cp/typeck2.c | 2 +- 18 files changed, 663 insertions(+), 251 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7ee24e6d47d..3df3180fda7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,211 @@ +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) * class.c (get_class_offset_1, get_class_offset): New routine to diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 254fd34e346..05e1d50c9f5 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -700,11 +700,17 @@ compute_conversion_costs (function, tta_in, cp, arglen) int strike_index = 0, win; struct harshness_code lose; + extern int cp_silent; #ifdef GATHER_STATISTICS n_compute_conversion_costs++; #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->arg = tta ? TREE_VALUE (tta) : NULL_TREE; cp->u.bad_arg = 0; /* optimistic! */ @@ -812,6 +818,7 @@ compute_conversion_costs (function, tta_in, cp, arglen) { cp->h.code = EVIL_CODE; cp->u.bad_arg = -1; + cp_silent = 0; return; } else @@ -833,6 +840,7 @@ compute_conversion_costs (function, tta_in, cp, arglen) { cp->h.code = EVIL_CODE; cp->u.bad_arg = -2; + cp_silent = 0; return; } /* Store index of first default. */ @@ -855,6 +863,7 @@ compute_conversion_costs (function, tta_in, cp, arglen) if (dont_convert_types) { cp->h.code = EVIL_CODE; + cp_silent = 0; return; } @@ -1002,6 +1011,7 @@ compute_conversion_costs (function, tta_in, cp, arglen) cp->h.code |= ELLIPSIS_CODE; if (user_strikes) cp->h.code |= USER_CODE; + cp_silent = 0; #ifdef DEBUG_MATCHING cp_error ("final eval %s", print_harshness (&cp->h)); #endif @@ -1428,7 +1438,9 @@ build_scoped_method_call (exp, scopes, name, parms) if (type != basetype) cp_error ("type of `%E' does not match destructor type `%T' (type was `%T')", 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) cp_error ("qualified type `%T' does not match destructor type `%T'", basetype, name); @@ -1604,17 +1616,19 @@ build_method_call (instance, name, parms, basetype_path, flags) if (parms) error ("destructors take no parameters"); basetype = TREE_TYPE (instance); + if (TREE_CODE (basetype) == REFERENCE_TYPE) + basetype = TREE_TYPE (basetype); if (! ((IS_AGGR_TYPE (basetype) && name == constructor_name (basetype)) || basetype == get_type_value (name))) { cp_error ("destructor name `~%D' does not match type `%T' of expression", name, basetype); - return void_zero_node; + return convert (void_type_node, instance); } if (! TYPE_HAS_DESTRUCTOR (basetype)) - return void_zero_node; + return convert (void_type_node, instance); instance = default_conversion (instance); instance_ptr = build_unary_op (ADDR_EXPR, instance, 0); return build_delete (build_pointer_type (basetype), @@ -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); } +#if 0 + /* This breaks reference-to-array parameters. */ if (TREE_CODE (t) == ARRAY_TYPE) { /* Perform the conversion from ARRAY_TYPE to POINTER_TYPE in place. @@ -1898,6 +1914,7 @@ build_method_call (instance, name, parms, basetype_path, flags) TREE_VALUE (parm) = default_conversion (TREE_VALUE (parm)); t = TREE_TYPE (TREE_VALUE (parm)); } +#endif if (t == error_mark_node) return error_mark_node; last = build_tree_list (NULL_TREE, t); diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 6c767bbe2d3..f907d17f012 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -992,20 +992,18 @@ add_method (type, fields, method) not duplicates, they are just anonymous fields. This happens when we have unnamed bitfields, for example. */ static tree -delete_duplicate_fields_1 (field, field_ptr, fields) - tree field, *field_ptr, fields; +delete_duplicate_fields_1 (field, fields) + tree field, fields; { tree x; - tree prev = field_ptr ? *field_ptr : 0; + tree prev = 0; if (DECL_NAME (field) == 0) { if (TREE_CODE (TREE_TYPE (field)) != UNION_TYPE) return fields; for (x = TYPE_FIELDS (TREE_TYPE (field)); x; x = TREE_CHAIN (x)) - fields = delete_duplicate_fields_1 (x, field_ptr, fields); - if (prev) - TREE_CHAIN (prev) = fields; + fields = delete_duplicate_fields_1 (x, fields); return fields; } else @@ -1017,7 +1015,7 @@ delete_duplicate_fields_1 (field, field_ptr, fields) if (TREE_CODE (TREE_TYPE (x)) != UNION_TYPE) continue; 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 (prev == 0) @@ -1039,7 +1037,7 @@ delete_duplicate_fields_1 (field, field_ptr, fields) x); else if (TREE_CODE (field) == 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 || TREE_CODE (x) == TYPE_DECL) cp_error_at ("duplicate field `%D' (as type and non-type)", @@ -1063,7 +1061,7 @@ delete_duplicate_fields (fields) { tree 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. @@ -1937,8 +1935,8 @@ finish_struct_methods (t, fn_fields, nonprivate_method) && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE && warn_ctor_dtor_privacy) - warning ("class `%s' only defines a private destructor and has no friends", - TYPE_NAME_STRING (t)); + cp_warning ("`%#T' only defines a private destructor and has no friends", + t); break; } } @@ -2774,17 +2772,12 @@ finish_struct (t, list_of_fieldlists, warn_anon) TYPE_SIZE (t) = NULL_TREE; CLASSTYPE_GOT_SEMICOLON (t) = 0; - /* A signature type will contain the fields of the signature table. - Therefore, it's not only an interface. */ - if (IS_SIGNATURE (t)) + /* This is in general too late to do this. I moved the main case up to + left_curly, what else needs to move? */ + if (! IS_SIGNATURE (t)) { - CLASSTYPE_INTERFACE_ONLY (t) = 0; - SET_CLASSTYPE_INTERFACE_KNOWN (t); - } - else - { - CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); + my_friendly_assert (CLASSTYPE_INTERFACE_ONLY (t) == interface_only, 999); + my_friendly_assert (CLASSTYPE_INTERFACE_KNOWN (t) == ! interface_unknown, 999); } if (flag_dossier) @@ -2848,14 +2841,13 @@ finish_struct (t, list_of_fieldlists, warn_anon) needs_virtual_dtor = 0; } + /* Both of these should be done before now. */ if (write_virtuals == 3 && CLASSTYPE_INTERFACE_KNOWN (t) && ! IS_SIGNATURE (t)) { - CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! interface_only; + my_friendly_assert (CLASSTYPE_INTERFACE_ONLY (t) == interface_only, 999); + 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 modified. Needed at this point to make add_virtual_function @@ -3520,6 +3512,31 @@ finish_struct (t, list_of_fieldlists, warn_anon) /* Delete all duplicate fields from the 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, then lay out the structure or union (including the fields). */ @@ -4701,11 +4718,42 @@ instantiate_type (lhstype, rhs, complain) { elem = get_first_fn (rhs); while (elem) - if (TREE_TYPE (elem) != lhstype) + if (! comptypes (lhstype, TREE_TYPE (elem), 1)) elem = DECL_CHAIN (elem); else 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); while (elem && ! comp_target_types (lhstype, TREE_TYPE (elem), 1)) elem = DECL_CHAIN (elem); @@ -4727,18 +4775,6 @@ instantiate_type (lhstype, rhs, complain) } 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; } if (complain) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index b6db6954190..4f848c727c5 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2359,7 +2359,7 @@ extern void GNU_xref_end PROTO((int)); extern void GNU_xref_file PROTO((char *)); 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_def PROTO((tree, char *)); +extern void GNU_xref_ref PROTO((tree, char *)); extern void GNU_xref_decl PROTO((tree, tree)); extern void GNU_xref_call PROTO((tree, char *)); extern void GNU_xref_function PROTO((tree, tree)); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 04f9bd3eb2c..a47075be560 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -1233,11 +1233,9 @@ cp_convert (type, expr, convtype, flags) { tree rval; rval = build_type_conversion (CONVERT_EXPR, type, e, 1); - if (rval) return rval; - if (code == BOOLEAN_TYPE) - cp_error ("`%#T' used where a `bool' was expected", intype); - else - cp_error ("`%#T' used where an `int' was expected", intype); + if (rval) + return rval; + cp_error ("`%#T' used where a `%T' was expected", intype, type); return error_mark_node; } if (code == BOOLEAN_TYPE) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 11ea6a2ca0a..233232d0d40 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -401,6 +401,11 @@ extern int flag_short_double; extern int flag_no_builtin; +/* Nonzero means don't recognize the non-ANSI builtin functions. + -ansi sets this. */ + +extern int flag_no_nonansi_builtin; + /* Nonzero means disable GNU extensions. */ extern int flag_ansi; @@ -1743,6 +1748,7 @@ pushtag (name, type, globalize) #else d = build_decl (TYPE_DECL, name, type); #endif + SET_DECL_ARTIFICIAL (d); #ifdef DWARF_DEBUGGING_INFO if (write_symbols == DWARF_DEBUG) { @@ -1778,6 +1784,7 @@ pushtag (name, type, globalize) /* Make nested declarations go into class-level scope. */ newdecl = 1; d = build_decl (TYPE_DECL, name, type); + SET_DECL_ARTIFICIAL (d); #ifdef DWARF_DEBUGGING_INFO if (write_symbols == DWARF_DEBUG) { @@ -1981,11 +1988,11 @@ decls_match (newdecl, olddecl) for (i = 0; i < len; i++) { - tree newarg = TREE_VEC_ELT (newargs, i); - tree oldarg = TREE_VEC_ELT (oldargs, i); + tree newarg = TREE_VALUE (TREE_VEC_ELT (newargs, i)); + tree oldarg = TREE_VALUE (TREE_VEC_ELT (oldargs, i)); if (TREE_CODE (newarg) != TREE_CODE (oldarg)) return 0; - else if (TREE_CODE (newarg) == IDENTIFIER_NODE) + else if (TREE_CODE (newarg) == TYPE_DECL) /* continue */; else if (! comptypes (TREE_TYPE (newarg), TREE_TYPE (oldarg), 1)) return 0; @@ -2104,6 +2111,7 @@ duplicate_decls (newdecl, olddecl) after implicit decl. */ ; else if (TREE_CODE (olddecl) == FUNCTION_DECL + && DECL_ARTIFICIAL (olddecl) && (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl))) { /* If you declare a built-in or predefined function name as static, @@ -2188,9 +2196,8 @@ duplicate_decls (newdecl, olddecl) newdecl); cp_error_at ("previous declaration `%#D' here", olddecl); } - - if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), - TYPE_ARG_TYPES (TREE_TYPE (olddecl)), 2)) + else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), + TYPE_ARG_TYPES (TREE_TYPE (olddecl)), 2)) { cp_error ("new declaration `%#D'", newdecl); cp_error_at ("ambiguates old declaration `%#D'", olddecl); @@ -2678,7 +2685,8 @@ pushdecl (x) /* don't do anything just yet */; else if (TREE_CODE (t) != TREE_CODE (x)) { - if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (x) == TYPE_DECL) + if ((TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t)) + || (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x))) { /* We do nothing special here, because C++ does such nasty things with TYPE_DECLs. Instead, just let the TYPE_DECL @@ -4540,14 +4548,31 @@ init_decl_processing () sizetype, endlink)), BUILT_IN_ALLOCA, "alloca"); -#if 0 - builtin_function ("alloca", - build_function_type (ptr_type_node, - tree_cons (NULL_TREE, - sizetype, - endlink)), - BUILT_IN_ALLOCA, NULL_PTR); + /* Define alloca, ffs as builtins. + Declare _exit just to mark it as volatile. */ + if (! flag_no_builtin && !flag_no_nonansi_builtin) + { +#if 0 /* Why is this disabled? (jason 8/9/94) */ + temp = builtin_function ("alloca", + build_function_type (ptr_type_node, + tree_cons (NULL_TREE, + sizetype, + endlink)), + BUILT_IN_ALLOCA, NULL_PTR); + /* Suppress error if redefined as a non-function. */ + DECL_BUILT_IN_NONANSI (temp) = 1; #endif + temp = builtin_function ("ffs", int_ftype_int, BUILT_IN_FFS, NULL_PTR); + /* Suppress error if redefined as a non-function. */ + DECL_BUILT_IN_NONANSI (temp) = 1; + temp = builtin_function ("_exit", build_function_type (void_type_node, + int_endlink), + NOT_BUILT_IN, NULL_PTR); + TREE_THIS_VOLATILE (temp) = 1; + TREE_SIDE_EFFECTS (temp) = 1; + /* Suppress error if redefined as a non-function. */ + DECL_BUILT_IN_NONANSI (temp) = 1; + } builtin_function ("__builtin_abs", int_ftype_int, BUILT_IN_ABS, NULL_PTR); @@ -4647,6 +4672,23 @@ init_decl_processing () builtin_function ("strlen", sizet_ftype_string, BUILT_IN_STRLEN, NULL_PTR); builtin_function ("sin", double_ftype_double, BUILT_IN_SIN, NULL_PTR); builtin_function ("cos", double_ftype_double, BUILT_IN_COS, NULL_PTR); + + /* Declare these functions volatile + to avoid spurious "control drops through" warnings. */ + temp = builtin_function ("abort", + build_function_type (void_type_node, endlink), + NOT_BUILT_IN, NULL_PTR); + TREE_THIS_VOLATILE (temp) = 1; + TREE_SIDE_EFFECTS (temp) = 1; + /* Well, these are actually ANSI, but we can't set DECL_BUILT_IN on + them... */ + DECL_BUILT_IN_NONANSI (temp) = 1; + temp = builtin_function ("exit", build_function_type (void_type_node, + int_endlink), + NOT_BUILT_IN, NULL_PTR); + TREE_THIS_VOLATILE (temp) = 1; + TREE_SIDE_EFFECTS (temp) = 1; + DECL_BUILT_IN_NONANSI (temp) = 1; } #if 0 @@ -6315,9 +6357,11 @@ finish_decl (decl, init, asmspec_tree, need_pop) expand_aggr_init (decl, init, 0); } - /* Set this to 0 so we can tell whether an aggregate - which was initialized was ever used. */ - if (TYPE_NEEDS_CONSTRUCTING (type)) + /* Set this to 0 so we can tell whether an aggregate which + was initialized was ever used. Don't do this if it has a + destructor, so we don't complain about the 'resource + allocation is initialization' idiom. */ + if (TYPE_NEEDS_CONSTRUCTING (type) && cleanup == NULL_TREE) TREE_USED (decl) = 0; /* Store the cleanup, if there was one. */ @@ -7283,7 +7327,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) goto found; } - for (i = (int) RID_FIRST_MODIFIER; i < (int) RID_MAX; i++) + for (i = (int) RID_FIRST_MODIFIER; i < (int) RID_LAST_MODIFIER; i++) { if (ridpointers[i] == id) { @@ -8965,14 +9009,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep), TREE_TYPE (type), TYPE_ARG_TYPES (type)); - /* Record presence of `static'. In C++, `inline' is like `static'. - Methods of classes should be public, unless we're dropping them - into some other file, so we don't clear TREE_PUBLIC for them. */ + /* Record presence of `static'. In C++, `inline' is like `static'. */ publicp - = ((ctype - && CLASSTYPE_INTERFACE_KNOWN (ctype)) - || !(RIDBIT_SETP (RID_STATIC, specbits) - || RIDBIT_SETP (RID_INLINE, specbits))); + = !(RIDBIT_SETP (RID_STATIC, specbits) + || RIDBIT_SETP (RID_INLINE, specbits)); decl = grokfndecl (ctype, type, original_name, virtualp, flags, quals, @@ -8993,7 +9033,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) declaring main to be static. */ if (TREE_CODE (type) == METHOD_TYPE) { - cp_error_at ("cannot declare member function `%D' to have static linkage", decl); + cp_pedwarn ("cannot declare member function `%D' to have static linkage", decl); illegal_static = 1; } else if (! ctype @@ -9795,6 +9835,7 @@ xref_defn_tag (code_type_node, name, binfo) if (! ANON_AGGRNAME_P (name)) { register tree type_decl = build_decl (TYPE_DECL, ncp, rv); + SET_DECL_ARTIFICIAL (type_decl); #ifdef DWARF_DEBUGGING_INFO /* Mark the TYPE_DECL node created just above as a gratuitous one so that dwarfout.c will know not to generate a TAG_typedef DIE @@ -9943,9 +9984,7 @@ xref_tag (code_type_node, name, binfo, globalize) } else { - extern tree pending_vtables; struct binding_level *old_b = class_binding_level; - int needs_writing; ref = make_lang_type (code); @@ -9955,36 +9994,10 @@ xref_tag (code_type_node, name, binfo, globalize) { SET_SIGNATURE (ref); CLASSTYPE_INTERFACE_ONLY (ref) = 0; - CLASSTYPE_INTERFACE_UNKNOWN (ref) = 0; + SET_CLASSTYPE_INTERFACE_UNKNOWN (ref); + CLASSTYPE_VTABLE_NEEDS_WRITING (ref) = 0; } - /* 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 (ref) - && CLASSTYPE_INTERFACE_KNOWN (ref); - break; - default: - needs_writing = 0; - } - - /* Signatures don't have a vtable. As long as we don't have default - implementations, they behave as if `write_virtuals' were 3. */ - if (tag_code == signature_type) - CLASSTYPE_VTABLE_NEEDS_WRITING (ref) = 0; - else - CLASSTYPE_VTABLE_NEEDS_WRITING (ref) = needs_writing; - #ifdef NONNESTED_CLASSES /* Class types don't nest the way enums do. */ class_binding_level = (struct binding_level *)0; @@ -10682,15 +10695,14 @@ start_function (declspecs, declarator, raises, pre_parsed_p) /* If this function belongs to an interface, it is public. If it belongs to someone else's interface, it is also external. It doesn't matter whether it's inline or not. */ - if (interface_unknown == 0) + if (interface_unknown == 0 + && ! TREE_PUBLIC (decl1)) { TREE_PUBLIC (decl1) = 1; DECL_EXTERNAL (decl1) = (interface_only || (DECL_INLINE (decl1) && ! flag_implement_inlines)); } - else if (DECL_EXPLICIT_INSTANTIATION (decl1)) - /* PUBLIC and EXTERNAL set by do_*_instantiation */; else { /* This is a definition, not a reference. @@ -10699,7 +10711,10 @@ start_function (declspecs, declarator, raises, pre_parsed_p) defining how to inline. So set DECL_EXTERNAL in that case. */ DECL_EXTERNAL (decl1) = current_extern_inline; - DECL_DEFER_OUTPUT (decl1) = DECL_INLINE (decl1); + DECL_DEFER_OUTPUT (decl1) + = DECL_INLINE (decl1) && ! TREE_PUBLIC (decl1) + && (DECL_FUNCTION_MEMBER_P (decl1) + || DECL_TEMPLATE_INSTANTIATION (decl1)); } if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)) @@ -11567,8 +11582,8 @@ finish_function (lineno, call_poplevel) rest_of_compilation (fndecl); } - if (DECL_INLINE (fndecl) - && !TREE_ASM_WRITTEN (fndecl) && DECL_FUNCTION_MEMBER_P (fndecl)) + if (DECL_INLINE (fndecl) && !TREE_ASM_WRITTEN (fndecl) + && DECL_DEFER_OUTPUT (fndecl)) { mark_inline_for_output (fndecl); } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 6579fe77141..25c517d2c94 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -84,6 +84,11 @@ int flag_no_asm; 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. */ int flag_traditional; @@ -361,6 +366,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] = {"conserve-space", &flag_conserve_space, 1}, {"vtable-thunks", &flag_vtable_thunks, 1}, {"short-temps", &flag_short_temps, 1}, + {"nonansi-builtins", &flag_no_nonansi_builtin, 0} }; /* Decode the string P as a language-specific option. @@ -447,6 +453,10 @@ lang_decode_option (p) flag_alt_external_templates = 0; found = 1; } + else if (!strcmp (p, "ansi-overloading")) + { + warning ("-fansi-overloading is no longer meaningful"); + } else for (j = 0; !found && j < sizeof (lang_f_options) / sizeof (lang_f_options[0]); j++) @@ -544,7 +554,8 @@ lang_decode_option (p) else return 0; } 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 /* 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 @@ -983,7 +994,7 @@ grok_array_decl (array_expr, index_exp) if (TYPE_LANG_SPECIFIC (type) && TYPE_OVERLOADS_ARRAY_REF (type)) return build_opfncall (ARRAY_REF, LOOKUP_NORMAL, - array_expr, index_exp, NULL_TREE); + array_expr, index_exp, NULL_TREE); /* Otherwise, create an ARRAY_REF for a pointer or array type. */ if (TREE_CODE (type) == POINTER_TYPE @@ -1000,17 +1011,14 @@ grok_array_decl (array_expr, index_exp) || TREE_CODE (type) == REFERENCE_TYPE) type = TREE_TYPE (type); - if (TYPE_LANG_SPECIFIC (type) - && TYPE_OVERLOADS_ARRAY_REF (type)) - error ("array expression backwards"); - else if (TREE_CODE (type) == POINTER_TYPE - || TREE_CODE (type) == ARRAY_TYPE) + if (TREE_CODE (type) == POINTER_TYPE + || TREE_CODE (type) == ARRAY_TYPE) return build_array_ref (index_exp, array_expr); - else - error("`[]' applied to non-pointer type"); - /* We gave an error, so give an error. Huh? */ - return error_mark_node; + /* The expression E1[E2] is identical (by definition) to *((E1)+(E2)). */ + 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 @@ -1128,13 +1136,13 @@ check_classfn (ctype, cname, function) } if (methods != end) - cp_error ("argument list for `%D' does not match any in class `%T'", - fn_name, ctype); + cp_error ("argument list for `%#D' does not match any in class `%T'", + function, ctype); else { methods = 0; - cp_error ("no `%D' member function declared in class `%T'", - fn_name, ctype); + cp_error ("no `%#D' member function declared in class `%T'", + function, ctype); } /* If we did not find the method in the class, add it to @@ -2067,9 +2075,13 @@ finish_anon_union (anon_union_decl) 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. */ DECL_INITIAL (decl) = error_mark_node; TREE_PUBLIC (decl) = public_p; @@ -2096,7 +2108,6 @@ finish_anon_union (anon_union_decl) TREE_PURPOSE of the following TREE_LIST. */ elems = tree_cons (NULL_TREE, decl, elems); TREE_TYPE (elems) = type; - field = TREE_CHAIN (field); } if (static_p) { @@ -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; #define TIMEVAR(VAR, BODY) \ @@ -2835,24 +2877,12 @@ finish_file () 0; don't crash. */ if (TREE_ASM_WRITTEN (decl) || DECL_SAVED_INSNS (decl) == 0) continue; - if (DECL_FUNCTION_MEMBER_P (decl) && !TREE_PUBLIC (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)); - } - } + import_export_inline (decl); if (TREE_PUBLIC (decl) || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) || flag_keep_inline_functions) { - if (DECL_EXTERNAL (decl) - || (DECL_IMPLICIT_INSTANTIATION (decl) - && ! flag_implicit_templates)) + if (DECL_EXTERNAL (decl)) assemble_external (decl); else { @@ -2879,9 +2909,7 @@ finish_file () if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) && ! TREE_ASM_WRITTEN (decl)) { - if (DECL_EXTERNAL (decl) - || (DECL_IMPLICIT_INSTANTIATION (decl) - && ! flag_implicit_templates)) + if (DECL_EXTERNAL (decl)) assemble_external (decl); else { diff --git a/gcc/cp/errfn.c b/gcc/cp/errfn.c index 1b345fda9c2..2f78164b146 100644 --- a/gcc/cp/errfn.c +++ b/gcc/cp/errfn.c @@ -30,6 +30,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ typedef char* cp_printer PROTO((HOST_WIDE_INT, int)); 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 */ extern char* cp_file_of PROTO((tree)); @@ -150,7 +155,8 @@ cp_error (format, arglist) arglist_dcl { extern errorfn error; - cp_thing (error, 0, format, arglist); + if (! cp_silent) + cp_thing (error, 0, format, arglist); } void @@ -159,7 +165,8 @@ cp_warning (format, arglist) arglist_dcl { extern errorfn warning; - cp_thing (warning, 0, format, arglist); + if (! cp_silent) + cp_thing (warning, 0, format, arglist); } void @@ -168,7 +175,8 @@ cp_pedwarn (format, arglist) arglist_dcl { extern errorfn pedwarn; - cp_thing (pedwarn, 0, format, arglist); + if (! cp_silent) + cp_thing (pedwarn, 0, format, arglist); } void @@ -177,7 +185,8 @@ cp_compiler_error (format, arglist) arglist_dcl { extern errorfn compiler_error; - cp_thing (compiler_error, 0, format, arglist); + if (! cp_silent) + cp_thing (compiler_error, 0, format, arglist); } void @@ -195,7 +204,8 @@ cp_error_at (format, arglist) arglist_dcl { extern errorfn error_with_file_and_line; - cp_thing (error_with_file_and_line, 1, format, arglist); + if (! cp_silent) + cp_thing (error_with_file_and_line, 1, format, arglist); } void @@ -204,7 +214,8 @@ cp_warning_at (format, arglist) arglist_dcl { extern errorfn warning_with_file_and_line; - cp_thing (warning_with_file_and_line, 1, format, arglist); + if (! cp_silent) + cp_thing (warning_with_file_and_line, 1, format, arglist); } void @@ -213,5 +224,6 @@ cp_pedwarn_at (format, arglist) arglist_dcl { extern errorfn pedwarn_with_file_and_line; - cp_thing (pedwarn_with_file_and_line, 1, format, arglist); + if (! cp_silent) + cp_thing (pedwarn_with_file_and_line, 1, format, arglist); } diff --git a/gcc/cp/error.c b/gcc/cp/error.c index c42724396d5..4bb9316b22d 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -104,6 +104,8 @@ dump_readonly_or_volatile (t, p) if (p == before) OB_PUTC (' '); if (TYPE_READONLY (t)) OB_PUTS ("const"); + if (TYPE_READONLY (t) && TYPE_VOLATILE (t)) + OB_PUTC (' '); if (TYPE_VOLATILE (t)) OB_PUTS ("volatile"); if (p == after) OB_PUTC (' '); @@ -1228,6 +1230,14 @@ dump_expr (t, nop) 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. It is very important that `sorry' does not call `report_error_function'. That could cause an infinite loop. */ diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 4aec96a4867..d259398948c 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -217,6 +217,7 @@ perform_member_init (member, name, init, explicit) expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init)); } } + expand_cleanups_to (NULL_TREE); 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); } @@ -230,11 +231,14 @@ sort_member_init (t) tree init_list = NULL_TREE; tree fields_to_unmark = NULL_TREE; int found; + int last_pos = 0; + tree last_field; for (member = TYPE_FIELDS (t); member ; member = TREE_CHAIN (member)) { + int pos; 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 (TREE_PURPOSE (x) == NULL_TREE) @@ -264,6 +268,17 @@ sort_member_init (t) field); 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, build_tree_list (name, TREE_VALUE (x))); @@ -500,9 +515,10 @@ emit_base_init (t, immediately) continue; 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, - BINFO_OFFSET_ZEROP (binfo), LOOKUP_COMPLAIN); + BINFO_OFFSET_ZEROP (binfo), LOOKUP_NORMAL); + expand_cleanups_to (NULL_TREE); } if (pass == 0) @@ -568,9 +584,10 @@ emit_base_init (t, immediately) current_class_decl, BINFO_OFFSET (base_binfo)); 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), - LOOKUP_COMPLAIN); + LOOKUP_NORMAL); + expand_cleanups_to (NULL_TREE); } } CLEAR_BINFO_BASEINIT_MARKED (base_binfo); @@ -655,11 +672,6 @@ emit_base_init (t, immediately) 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) { extern rtx base_init_insns; @@ -734,6 +746,7 @@ expand_aggr_vbase_init_1 (binfo, exp, addr, init_list) /* Call constructors, but don't set up vtables. */ expand_aggr_init_1 (binfo, exp, ref, init, 0, LOOKUP_COMPLAIN|LOOKUP_SPECULATIVELY); + expand_cleanups_to (NULL_TREE); CLEAR_BINFO_VBASE_INIT_MARKED (binfo); } @@ -1966,12 +1979,6 @@ build_offset_ref (cname, name) name, NULL_TREE, 1); #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 || get_base_distance (type, current_class_type, 0, &basetypes) == -1) { @@ -1986,6 +1993,12 @@ build_offset_ref (cname, name) else 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 lookup_fnfield. */ if (fnfields) @@ -2018,7 +2031,6 @@ build_offset_ref (cname, name) { extern int flag_save_memoized_contexts; - /* This does not handle access checking yet. */ if (DECL_CHAIN (t) == NULL_TREE || dtor) { enum access_type access; @@ -3261,7 +3273,7 @@ build_new (placement, decl, init, use_global_new) build_tree_list (NULL_TREE, rval)))); } - return save_expr (rval); + return rval; } /* `expand_vec_init' performs initialization of a vector of aggregate diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 2d41cc61492..fb6ba526530 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -960,15 +960,6 @@ set_yydebug (value) #endif } -#ifdef SPEW_DEBUG -const char * -debug_yytranslate (value) - int value; -{ - return yytname[YYTRANSLATE (value)]; -} - -#endif /* Functions and data structures for #pragma interface. @@ -1786,13 +1777,6 @@ cons_up_default_function (type, name, fields, kind) warn_if_unknown_interface (); t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2)); 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); @@ -2182,17 +2166,17 @@ check_for_missing_semicolon (type) if (yychar < 0) yychar = yylex (); - if (yychar > 255 - && yychar != SCSPEC - && yychar != IDENTIFIER - && yychar != TYPENAME) + if ((yychar > 255 + && yychar != SCSPEC + && yychar != IDENTIFIER + && yychar != TYPENAME) + || end_of_file) { if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) error ("semicolon missing after %s declaration", TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct"); else - error ("semicolon missing after declaration of `%s'", - TYPE_NAME_STRING (type)); + cp_error ("semicolon missing after declaration of `%T'", type); shadow_tag (build_tree_list (0, type)); } /* Could probably also hack cases where class { ... } f (); appears. */ diff --git a/gcc/cp/lex.h b/gcc/cp/lex.h index 3da46356afc..291b9cde6e3 100644 --- a/gcc/cp/lex.h +++ b/gcc/cp/lex.h @@ -58,14 +58,16 @@ enum rid RID_VOLATILE, RID_FRIEND, RID_VIRTUAL, + RID_SIGNED, + RID_AUTO, + RID_MUTABLE, + + /* This is where grokdeclarator ends its search when setting the specbits. */ + RID_PUBLIC, RID_PRIVATE, RID_PROTECTED, - RID_SIGNED, RID_EXCEPTION, - RID_RAISES, - RID_AUTO, - RID_MUTABLE, RID_TEMPLATE, RID_SIGNATURE, /* Before adding enough to get up to 64, the RIDBIT_* macros @@ -76,6 +78,7 @@ enum rid #define NORID RID_UNUSED #define RID_FIRST_MODIFIER RID_EXTERN +#define RID_LAST_MODIFIER RID_MUTABLE /* The type that can represent all values of RIDBIT. */ /* We assume that we can stick in at least 32 bits into this. */ diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 853ada186fe..aabd63550e3 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -852,18 +852,17 @@ build_decl_overload (dname, parms, for_method) /* member operators new and delete look like methods at this point. */ if (! for_method && parms != NULL_TREE && TREE_CODE (parms) == TREE_LIST) { - if (TREE_VALUE (parms) == sizetype - && TREE_CHAIN (parms) == void_list_node) + 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"); + else if (TREE_CHAIN (parms) == void_list_node) { if (dname == ansi_opname[(int) NEW_EXPR]) return get_identifier ("__builtin_new"); else if (dname == ansi_opname[(int) VEC_NEW_EXPR]) 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 (); diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 9251a34d2ed..ce0a6376cc7 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -895,7 +895,8 @@ paren_expr_or_null: cond_stmt_keyword); $$ = integer_zero_node; } | '(' expr ')' - { $$ = $2; } + { $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node, + bool_truthvalue_conversion ($2)); } ; paren_cond_or_null: @@ -904,13 +905,16 @@ paren_cond_or_null: cond_stmt_keyword); $$ = integer_zero_node; } | '(' condition ')' - { $$ = $2; } + { $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node, + bool_truthvalue_conversion ($2)); } ; xcond: /* empty */ { $$ = NULL_TREE; } | condition + { $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node, + bool_truthvalue_conversion ($$)); } | error { $$ = NULL_TREE; } ; @@ -1548,7 +1552,7 @@ primary: if (TREE_CODE (TREE_TYPE ($1)) != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($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 { @@ -1557,7 +1561,7 @@ primary: if (TREE_CODE (TREE_TYPE ($1)) != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($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: ; left_curly: '{' - { tree t; + { tree t = $0; push_obstacks_nochange (); end_temporary_allocation (); - if (! IS_AGGR_TYPE ($0)) + if (! IS_AGGR_TYPE (t)) { - $0 = make_lang_type (RECORD_TYPE); - TYPE_NAME ($0) = get_identifier ("erroneous type"); + t = $0 = make_lang_type (RECORD_TYPE); + TYPE_NAME (t) = get_identifier ("erroneous type"); } - if (TYPE_SIZE ($0)) - duplicate_tag_error ($0); - if (TYPE_SIZE ($0) || TYPE_BEING_DEFINED ($0)) + if (TYPE_SIZE (t)) + duplicate_tag_error (t); + if (TYPE_SIZE (t) || TYPE_BEING_DEFINED (t)) { - t = make_lang_type (TREE_CODE ($0)); + t = make_lang_type (TREE_CODE (t)); pushtag (TYPE_IDENTIFIER ($0), t, 0); $0 = t; } - pushclass ($0, 0); - TYPE_BEING_DEFINED ($0) = 1; + pushclass (t, 0); + 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 t = TYPE_IDENTIFIER ($0); if (t && IDENTIFIER_TEMPLATE (t)) @@ -3053,7 +3091,7 @@ simple_if: { cond_stmt_keyword = "if"; } .pushlevel paren_cond_or_null { emit_line_note (input_filename, lineno); - expand_start_cond (bool_truthvalue_conversion ($4), 0); } + expand_start_cond ($4, 0); } implicitly_scoped_stmt ; @@ -3108,7 +3146,7 @@ simple_stmt: expand_start_loop (1); cond_stmt_keyword = "while"; } .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 { expand_end_bindings (getdecls (), kept_level_p (), 1); poplevel (kept_level_p (), 1, 0); @@ -3124,7 +3162,7 @@ simple_stmt: cond_stmt_keyword = "do"; } paren_expr_or_null ';' { 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 (); clear_momentary (); finish_stmt (); } @@ -3135,7 +3173,7 @@ simple_stmt: expand_start_loop_continue_elsewhere (1); } .pushlevel xcond ';' { 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 ')' /* Don't let the tree nodes for $7 be discarded by clear_momentary during the parsing of the next stmt. */ @@ -3156,7 +3194,7 @@ simple_stmt: expand_start_loop_continue_elsewhere (1); } .pushlevel xcond ';' { 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 ')' /* Don't let the tree nodes for $7 be discarded by clear_momentary during the parsing of the next stmt. */ @@ -3175,7 +3213,7 @@ simple_stmt: } | SWITCH .pushlevel '(' condition ')' { emit_line_note (input_filename, lineno); - c_expand_start_case ($4); + c_expand_start_case ($4); /* Don't let the tree nodes for $4 be discarded by clear_momentary during the parsing of the next stmt. */ push_momentary (); } @@ -3761,3 +3799,13 @@ operator_name: ; %% + +#ifdef SPEW_DEBUG +const char * +debug_yytranslate (value) + int value; +{ + return yytname[YYTRANSLATE (value)]; +} + +#endif diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e17354adea6..94dc9fad940 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2408,16 +2408,19 @@ do_function_instantiation (declspecs, declarator, storage) if (flag_external_templates) return; - if (DECL_EXPLICIT_INSTANTIATION (result) && ! DECL_EXTERNAL (result)) + if (DECL_EXPLICIT_INSTANTIATION (result) && TREE_PUBLIC (result)) return; SET_DECL_EXPLICIT_INSTANTIATION (result); - TREE_PUBLIC (result) = 1; 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]) - DECL_EXTERNAL (result) = 1; + ; else cp_error ("storage class `%D' applied to template instantiation", storage); @@ -2454,7 +2457,7 @@ do_type_instantiation (name, storage) } /* 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) cp_pedwarn ("multiple explicit instantiation of `%#T'", t); @@ -2462,11 +2465,11 @@ do_type_instantiation (name, storage) } 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) { + SET_CLASSTYPE_INTERFACE_KNOWN (t); + CLASSTYPE_INTERFACE_ONLY (t) = 0; + CLASSTYPE_VTABLE_NEEDS_WRITING (t) = 1; CLASSTYPE_DEBUG_REQUESTED (t) = 1; TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0; rest_of_type_compilation (t, 1); @@ -2478,9 +2481,12 @@ do_type_instantiation (name, storage) for (; tmp; tmp = TREE_CHAIN (tmp)) { SET_DECL_EXPLICIT_INSTANTIATION (tmp); - TREE_PUBLIC (tmp) = 1; - DECL_EXTERNAL (tmp) - = (extern_p || (DECL_INLINE (tmp) && ! flag_implement_inlines)); + if (! extern_p) + { + TREE_PUBLIC (tmp) = 1; + DECL_EXTERNAL (tmp) = (DECL_INLINE (tmp) + && ! flag_implement_inlines); + } } #if 0 diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 7d92b4e6671..e22ec293aa3 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1626,6 +1626,31 @@ make_deep_copy (t) TREE_OPERAND (t, 0) = make_deep_copy (TREE_OPERAND (t, 0)); 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. It is very important that `sorry' does not call `report_error_function'. That could cause an infinite loop. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index a25e1430505..4d7e3346f9f 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -734,8 +734,6 @@ comp_target_types (ttl, ttr, nptrs) ttr = TYPE_MAIN_VARIANT (ttr); if (ttl == ttr) return 1; - if (TREE_CODE (ttr) == TEMPLATE_TYPE_PARM) - return 1; if (TREE_CODE (ttr) != TREE_CODE (ttl)) return 0; @@ -813,12 +811,14 @@ common_base_type (tt1, tt2) if (UNIQUELY_DERIVED_FROM_P (tt2, tt1)) return tt2; +#if 0 /* If they share a virtual baseclass, that's good enough. */ for (tmp = CLASSTYPE_VBASECLASSES (tt1); tmp; tmp = TREE_CHAIN (tmp)) { if (binfo_member (BINFO_TYPE (tmp), CLASSTYPE_VBASECLASSES (tt2))) return BINFO_TYPE (tmp); } +#endif /* Otherwise, try to find a unique baseclass of TT1 that is shared by TT2, and follow that down. */ @@ -904,6 +904,8 @@ compparms (parms1, parms2, strict) return t2 == void_list_node && TREE_PURPOSE (t1); 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)) { int cmp = simple_cst_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2)); @@ -912,6 +914,7 @@ compparms (parms1, parms2, strict) if (cmp == 0) return 0; } +#endif t1 = TREE_CHAIN (t1); t2 = TREE_CHAIN (t2); @@ -959,8 +962,6 @@ comp_target_parms (parms1, parms2, strict) p2 = TREE_VALUE (t2); if (p1 == p2) continue; - if (TREE_CODE (p2) == TEMPLATE_TYPE_PARM) - continue; if ((TREE_CODE (p1) == POINTER_TYPE && TREE_CODE (p2) == POINTER_TYPE) || (TREE_CODE (p1) == REFERENCE_TYPE && TREE_CODE (p2) == REFERENCE_TYPE)) @@ -970,9 +971,6 @@ comp_target_parms (parms1, parms2, strict) == TYPE_MAIN_VARIANT (TREE_TYPE (p2)))) continue; - if (TREE_CODE (TREE_TYPE (p2)) == TEMPLATE_TYPE_PARM) - continue; - /* The following is wrong for contravariance, but many programs depend on it. */ if (TREE_TYPE (p1) == void_type_node) @@ -2530,13 +2528,15 @@ convert_arguments (return_loc, typelist, values, fndecl, flags) && (type == 0 || TREE_CODE (type) != REFERENCE_TYPE)) val = TREE_OPERAND (val, 0); - if ((type == 0 || TREE_CODE (type) != REFERENCE_TYPE) - && (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE + if (type == 0 || TREE_CODE (type) != REFERENCE_TYPE) + { + if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (val)) == METHOD_TYPE)) - val = default_conversion (val); + || TREE_CODE (TREE_TYPE (val)) == METHOD_TYPE) + val = default_conversion (val); - val = require_complete_type (val); + val = require_complete_type (val); + } if (val == error_mark_node) continue; @@ -2555,7 +2555,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags) } else { -#ifdef PROMOTE_PROTOTYPES +#if 0 && defined (PROMOTE_PROTOTYPES) + /* This breaks user-defined conversions. */ /* Rather than truncating and then reextending, convert directly to int, if that's the type we will want. */ if (! flag_traditional @@ -4682,11 +4683,20 @@ build_conditional_expr (ifexp, op1, op2) { if (result_type == error_mark_node) { - message_2_types (error, "common base type of types `%s' and `%s' is ambiguous", - TREE_TYPE (type1), TREE_TYPE (type2)); + cp_error ("common base type of types `%T' and `%T' is ambiguous", + TREE_TYPE (type1), TREE_TYPE (type2)); 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 { @@ -7210,7 +7220,8 @@ c_expand_start_case (exp) 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; } diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 87cf58cbc46..8813b4808f3 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -631,7 +631,7 @@ digest_init (type, init, tail) tree type, init, *tail; { enum tree_code code = TREE_CODE (type); - tree element = 0; + tree element = NULL_TREE; tree old_tail_contents; /* Nonzero if INIT is a braced grouping, which comes in as a CONSTRUCTOR tree node which has no TREE_TYPE. */