diff options
author | Mike Stump <mrs@gcc.gnu.org> | 1995-12-19 06:51:14 +0000 |
---|---|---|
committer | Mike Stump <mrs@gcc.gnu.org> | 1995-12-19 06:51:14 +0000 |
commit | 72b7eeff72ff8775207e3708511d808cbe94ef3d (patch) | |
tree | 44f132baadba7e87b171112daeea334c32f37dc2 /gcc/cp | |
parent | f82da7d270d2bf27905b338f28622c3546ad9306 (diff) | |
download | gcc-72b7eeff72ff8775207e3708511d808cbe94ef3d.zip gcc-72b7eeff72ff8775207e3708511d808cbe94ef3d.tar.gz gcc-72b7eeff72ff8775207e3708511d808cbe94ef3d.tar.bz2 |
76th Cygnus<->FSF merge
From-SVN: r10815
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 546 | ||||
-rw-r--r-- | gcc/cp/call.c | 10 | ||||
-rw-r--r-- | gcc/cp/class.c | 107 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 30 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 20 | ||||
-rw-r--r-- | gcc/cp/decl.c | 237 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 122 | ||||
-rw-r--r-- | gcc/cp/errfn.c | 4 | ||||
-rw-r--r-- | gcc/cp/error.c | 6 | ||||
-rw-r--r-- | gcc/cp/except.c | 216 | ||||
-rw-r--r-- | gcc/cp/init.c | 96 | ||||
-rw-r--r-- | gcc/cp/lang-options.h | 2 | ||||
-rw-r--r-- | gcc/cp/lex.c | 30 | ||||
-rw-r--r-- | gcc/cp/method.c | 40 | ||||
-rw-r--r-- | gcc/cp/parse.y | 25 | ||||
-rw-r--r-- | gcc/cp/pt.c | 4 | ||||
-rw-r--r-- | gcc/cp/search.c | 16 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 63 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 21 |
19 files changed, 1163 insertions, 432 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d2ef74f..bfa05f6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,336 @@ +Mon Dec 18 15:51:33 1995 Jason Merrill <jason@yorick.cygnus.com> + + * cp-tree.h, decl2.c (flag_weak): New flag to control the use of + weak symbols. + * lang-options.h: Add -f{no-,}weak. + * decl.c (init_decl_processing): If the target does not support weak + symbols, don't use them. + * decl2.c, pt.c: s/SUPPORTS_WEAK/flag_weak/. + +Sun Dec 17 21:13:23 1995 Rusty Russell <rusty@adelaide.maptek.com.au> + + * init.c (expand_member_init): warning for base init after members. + +Sun Dec 17 22:06:56 1995 Jeffrey A Law (law@cygnus.com) + + * tree.c (tree_copy_lang_decl_for_deferred_output): Handle + CONST_DECLs correctly. + +Fri Dec 15 15:32:18 1995 Jason Merrill <jason@yorick.cygnus.com> + + * cvt.c (build_expr_type_conversion): Don't convert to a reference + type. + +Thu Dec 14 16:05:58 1995 Mike Stump <mrs@cygnus.com> + + * method.c (report_type_mismatch): Improve wording for volatile + mismatches. + +Thu Dec 14 14:16:26 1995 Mike Stump <mrs@cygnus.com> + + * init.c (expand_aggr_init_1): Use expand_aggr_init_1 instead of + expand_assignment, as the later doesn't handle things that have + copy constructors well. The compiler would do bitwise copying, + instead of ctor calling in some cases. + +Wed Dec 13 17:05:54 PST 1995 Paul Eggert <eggert@twinsun.com> + + * g++.c (my_strerror): Return "cannot access" if errno is 0. + (pfatal_with_name, perror_exec): Don't assume that + the returned value from my_strerror contains no '%'s. + (concat): Remove. + (sys_nerror): Declare only if HAVE_STRERROR is not defined. + +Wed Dec 13 16:22:38 1995 Jason Merrill <jason@yorick.cygnus.com> + + Lose CLASSTYPE_METHODS/DECL_NEXT_METHOD chain; make + TYPE_METHODS/TREE_CHAIN mean what they used to. + * decl2.c (constructor_name_full): Refer to CLASSTYPE_METHOD_VEC + instead of TYPE_METHODS. + * decl.c (duplicate_decls): Lose references to DECL_NEXT_METHOD. + * tree.c (tree_copy_lang_decl_for_deferred_output): Ditto. + * cp-tree.h (CLASSTYPE_METHODS): Lose. + (CLASSTYPE_METHOD_VEC): Point to lang_spec->methods instead of + TYPE_METHODS. + (struct lang_decl): Lose next_method field. + (DECL_NEXT_METHOD): Lose. + * class.c (finish_struct_methods): Don't mess with TYPE_METHODS. + (finish_struct): Just use TYPE_METHODS; we don't need fn_fields + anymore. + (finish_struct_methods): Don't mess with the TREE_CHAINs in + fn_fields. + + * search.c (add_conversions): Don't use TREE_CHAIN to traverse method + vector. + + * call.c (build_method_call): Synthesize here even when not inlining. + * typeck.c (build_function_call_real): Ditto. + +Wed Dec 13 15:02:39 1995 Ian Lance Taylor <ian@cygnus.com> + + * cp/lex.c (check_newline): If DBX_DEBUGGING_INFO and write_symbols + == DBX_DEBUG, call dbxout_start_new_source_file and + dbxout_resume_previous_source_file when appropriate. + +Tue Dec 12 20:38:55 1995 Mike Stump <mrs@cygnus.com> + + * except.c (start_anon_func): Push to the top level. + (end_anon_func): Pop from the top level. + +Mon Dec 11 18:56:14 1995 Mike Stump <mrs@cygnus.com> + + * cp-tree.h (build_cleanup): New routine to build cleanups. + * decl.c (expand_static_init): Use build_cleanup to build a cleanup + call at ctor time and use atexit to run it later. + * decl2.c (build_cleanup): New routine, taken from finish_file. + (finish_file): Use build_cleanup instead, and don't put function + local statics in global dtor list. + +Wed Dec 6 14:34:29 1995 Mike Stump <mrs@cygnus.com> + + * except.c (expand_throw): Ensure that we have cleanups, if we try + and expand cleanups. + +Wed Dec 6 11:48:21 1995 Mike Stump <mrs@cygnus.com> + + * except.c (expand_throw): Add logic to manage dynamic cleanups for + the EH object. + (expand_end_catch_block): Use the magic of expand_goto, instead of + emit_jump so that we get the cleanup for any catch clause parameter + and the cleanup for the exception object. Update to reflect label + changes. + (push_eh_cleanup): New routine to register a cleanup for an + exception object. + (empty_fndecl): Used to default cleanup actions to + nothing. + (init_exception_processing): Setup empty_fndecl. Setup + saved_cleanup. + (expand_start_catch_block): Update to reflect label changes. Call + push_eh_object to register the cleanup for the EH object. + (start_anon_func): New routine to start building lambda expressions + from trees. + (end_anon_func): New routine to end them. + (struct labelNode): Change so that we can use tree labels, or rtx + labels. + (saved_cleanup): Object to check for dynamic cleanups for the + exception handling object. + (push_label_entry): Change so that we can use tree labels, or rtx + labels. + (pop_label_entry): Ditto. + (top_label_entry): Ditto. + (expand_start_all_catch): Use tree label instead of rtx label, so + that we can get the magic of expand_goto. + (expand_end_all_catch): Update to reflect label changes. + + * class.c (build_vfn_ref): Remove building_cleanup logic, as we now + use UNSAVE_EXPRs. + typeck.c (get_member_function_from_ptrfunc): Remove remnants of + building_cleanup logic, as we now use UNSAVE_EXPRs. + * cp-tree.h (unsave_expr): Declare it. + * decl.c (building_cleanup): Remove. + (maybe_build_cleanup): Remove building_cleanup logic, and use + UNSAVE_EXPR instead. + +Sun Dec 3 01:34:58 1995 Mike Stump <mrs@cygnus.com> + + * gc.c (build_t_desc): Update error message to say <typeinfo>. + +Thu Nov 30 12:30:05 1995 Brendan Kehoe <brendan@lisa.cygnus.com> + + * decl.c (pushdecl): Only warn about shadowing a local variable if + warn_shadow is true. + +Sun Nov 26 16:06:55 1995 Rusty Russell <rusty@adelaide.maptek.com.au> + + * typeck.c (build_binary_op_nodefault): Added warning about + comparisons between different enum types with -Wall, unless + -fenum-int-equiv set. + +Wed Nov 22 15:44:02 1995 Mike Stump <mrs@cygnus.com> + + * class.c (finish_struct_1): Skip down to the inner type in + multidimensional arrays. Ensures ctors will be made for types that + need constructing. + +Wed Nov 22 14:19:22 1995 Mike Stump <mrs@cygnus.com> + + * decl.c (last_dtor_insn): New to track the last compiler generated + insn in a dtor. + (store_parm_decls): Set it. + (finish_function): Use it to see if the dtor is empty. Avoid doing + vtable setup all the time, if we can. + (struct cp_function): Add last_dtor_insn. + (push_cp_function_context): Save it. + (pop_cp_function_context): Restore it. + +Wed Nov 22 11:52:19 1995 Paul Russell <Rusty.Russell@adelaide.maptek.com.au> + + * typeck.c (build_unary_op): Set TREE_NO_UNUSED_WARNING to avoid + warnings. + +Tue Nov 21 17:15:23 1995 Mike Stump <mrs@cygnus.com> + + * typeck.c (expand_target_expr): Make sure targets get put into the + current temp_slot_level, so that the free_temp_slots call will reuse + them. + +Tue Nov 21 13:32:03 1995 Mike Stump <mrs@cygnus.com> + + * class.c (finish_struct_1): Delay delta fixups for virtual bases + until after we have done the hard virtuals, to avoid a bogus `every + virtual function must have a unique final overrider' for virtual + functions that are only overridden by hard virtuals. + +Thu Nov 9 13:35:30 1995 Jason Merrill <jason@yorick.cygnus.com> + + * pt.c (do_function_instantiation): Don't try to find a file-scope + template for a member function. + +Tue Nov 14 06:20:35 1995 Mike Stump <mrs@cygnus.com> + + * g++.c (main): Add handling of -nodefaultlibs. + +Mon Nov 13 15:45:34 1995 Mike Stump <mrs@cygnus.com> + + * cp-tree.h (INDIRECT_BIND): Add a way for the frontend to + distinguish between direct bindings of reference variables, and + indirect bindings of reference variables. + * cvt.c (build_up_reference): Use it. + * typeck.c (convert_arguments): Use it to indicate this is an + indirect binding. + * decl.c (cp_finish_decl): Ensure that we reuse stack slots as fast + as they are unused. + (expand_static_init): Diotto. + (cplus_expand_expr_stmt): Ditto. + * decl2.c (finish_file): Ditto. + * init.c (perform_member_init): Ditto. + (emit_base_init): Ditto. + (expand_aggr_vbase_init_1): Ditto. + +Fri Nov 10 09:19:31 1995 Jeffrey A Law (law@cygnus.com) + + * tree.c (tree_copy_lang_decl_for_deferred_output): Handle + copying of DECL_ARGUMENTS field. + (tree_copy_lang_type_for_deferred_output): Handle disgusting + re-use of TYPE_LANG_SPECIFIC for pointer to member function + type nodes. + +Fri Nov 10 09:18:09 1995 Brendan Kehoe <brendan@lisa.cygnus.com> + + * decl.c (push_namespace): Rewrite to use build_lang_decl, so we + get a DECL_LANG_SPECIFIC node. + * cp-tree.h (lang_decl_flags): Add new member `level'. + (NAMESPACE_LEVEL): Don't use decl.arguments, instead use the + decl_flags level member. + +Mon Nov 6 18:36:13 1995 Brendan Kehoe <brendan@lisa.cygnus.com> + + * call.c (build_method_call): Make sure instance has a + TYPE_LANG_SPECIFIC node before we dive into it. + +Sat Nov 4 20:01:52 1995 Jason Molenda (crash@phydeaux.cygnus.com) + + * method.c (make_thunk): use TREE_SET_CODE to set thunk's tree code. + +Thu Nov 2 17:56:57 1995 Mike Stump <mrs@cygnus.com> + + * decl.c (duplicate_decls): When smashing decls, smash staticness in + the usual way. + +Thu Nov 2 16:44:02 1995 Mike Stump <mrs@cygnus.com> + + * decl.c (poplevel): Handle the merging of subblocks of cleanups + when finishing blocks that have already been created (usually due to + the fixup goto code). Fixes bad debugging information. + +Wed Nov 1 12:33:53 1995 Jason Merrill <jason@yorick.cygnus.com> + + * method.c (hack_identifier): Don't abort when we get a TREE_LIST + that's not a list of overloaded functions. + +Wed Nov 1 11:38:58 1995 Brendan Kehoe <brendan@lisa.cygnus.com> + + * decl2.c (mark_vtable_entries): Check DECL_LANG_SPECIFIC on fn + before trying to use DECL_ABSTRACT_VIRTUAL_P. + +Tue Oct 31 11:56:55 1995 Jason Merrill <jason@yorick.cygnus.com> + + * decl2.c (mark_used): New function for hooking into setting of + TREE_USED on decls. + * call.c (build_method_call): Use it. + * class.c (instantiate_type): Ditto. + * init.c (build_offset_ref): Ditto. Don't call assemble_external + for all like-named functions. + * method.c (hack_identifier): Ditto. + (emit_thunk): Don't call assemble_external. + (make_thunk): Create thunk as a FUNCTION_DECL so that it + gets the right mode and ENCODE_SECTION_INFO works. + + * parse.y: Use mark_used. Pass operator names to do_identifier. + * lex.c (do_identifier): Handle operator names. + + * decl2.c (grokclassfn): Tweak __in_chrg attributes. + +Thu Oct 26 20:58:59 1995 Jeffrey A Law (law@cygnus.com) + + * cp/tree.c (tree_copy_lang_decl_for_deferred_output): Handle + FIELD_DECLs and VAR_DECLs correctly. + +Thu Oct 26 16:45:58 1995 Brendan Kehoe <brendan@lisa.cygnus.com> + + * errfn.c: Include stdio.h. + (cp_sprintf): Take out decl of sprintf, and cast sprintf to errorfn*. + +Wed Oct 25 18:58:41 1995 Mike Stump <mrs@cygnus.com> + + * typeck2.c (digest_init): Always convert initializers to the + right type. + +Wed Oct 25 13:25:24 1995 Mike Stump <mrs@cygnus.com> + + * init.c (member_init_ok_or_else): Don't allow member initializers + for indirect members, as it is invalid. + +Wed Oct 25 11:35:28 1995 Brendan Kehoe <brendan@lisa.cygnus.com> + + * decl.c (grokdeclarator): Don't allow `friend signed ()'. + +Fri Oct 20 10:30:59 1995 Mike Stump <mrs@cygnus.com> + + * parse.y (for.init.statement): Catch compound statements inside for + initializations, if we're being pedantic. + +Fri Oct 20 10:03:42 1995 Mike Stump <mrs@cygnus.com> + + * decl.c (lookup_tag): Return NULL_TREE if we don't find what we are + looking for. + +Thu Oct 19 14:26:10 1995 Mike Stump <mrs@cygnus.com> + + * error.c (dump_expr): Don't core dump when a boolean expression is + used as a default argument. + +Thu Oct 19 10:36:30 1995 Jason Merrill <jason@yorick.cygnus.com> + + * class.c (finish_struct_bits): Check aggregate_value_p instead of + RETURN_IN_MEMORY. + +Wed Oct 18 18:12:32 1995 Jason Merrill <jason@yorick.cygnus.com> + + * class.c (finish_struct_bits): Also set TREE_ADDRESSABLE on a + BLKmode type that would otherwise be returned in registers. + +Mon Oct 16 12:32:19 1995 Brendan Kehoe <brendan@lisa.cygnus.com> + + * g++.c (WITHLIBC): New macro. + (main): Declare saw_libc. Use WITHLIBC if `-lc' was used; set + saw_libc and pass it at the end if it was set. + +Wed Oct 11 16:30:34 1995 Brendan Kehoe <brendan@lisa.cygnus.com> + + * parse.y (fn.def1): Call split_specs_attrs in + declmods notype_declarator case. + Mon Nov 20 14:06:28 1995 Mike Stump <mrs@cygnus.com> * Version 2.7.2 released. @@ -811,10 +1144,6 @@ Wed Jul 5 14:05:04 1995 Brendan Kehoe <brendan@lisa.cygnus.com> * typeck.c (comptypes, case OFFSET_REF): If either offset basetype is a TEMPLATE_TYPE_PARM, give a match. -Mon Jul 3 15:17:20 1995 Steve Chamberlain <sac@slash.cygnus.com> - - * g++.c (sys/file.h): Remove change of Jun 28. - Fri Jun 30 15:42:57 1995 Mike Stump <mrs@cygnus.com> * method.c (build_overload_value): Handle encoding of null pointer @@ -862,12 +1191,6 @@ Thu Jun 29 03:43:55 1995 Jason Merrill <jason@phydeaux.cygnus.com> * decl.c (revert_static_member_fn): But only if DECL_ARGUMENTS is set. -Wed Jun 28 23:34:58 1995 Steve Chamberlain <sac@slash.cygnus.com> - - * g++.c (pfatal_with_name): Use my_strerror to get error - string. - (sys/file.h): Include if HAVE_FILE_H defined. - Wed Jun 28 18:39:03 1995 Jason Merrill <jason@phydeaux.cygnus.com> * decl.c (revert_static_member_fn): Also remove 'this' from @@ -985,14 +1308,8 @@ Fri Jun 16 13:20:38 1995 Mike Stump <mrs@cygnus.com> * decl.c (get_unique_name): New routine to name unnamed namespaces. (push_namespace): Use get_unique_name for naming unnamed namespaces. -Fri Jun 16 15:07:29 1995 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) - - * Make-lang.in (DEMANGLER_PROG): Add LIBS. - Thu Jun 15 15:00:41 1995 Jason Merrill <jason@phydeaux.cygnus.com> - * decl.c (define_function): Don't set DECL_INTERFACE_KNOWN. - * parse.y: Call cplus_decl_attributes with prefix_attributes where appropriate. @@ -1037,23 +1354,6 @@ Thu Jun 8 15:44:38 1995 Jason Merrill <jason@phydeaux.cygnus.com> * gc.c (build_dynamic_cast): Build up a reference to a parameter of aggregate type. -Wed Jun 7 20:00:31 1995 Mike Stump <mrs@cygnus.com> - - * *.[chy]: Change all callers of finish_decl to cp_finish_decl. - * decl.c (finish_decl): New routine to handle call backs from the - mid end (declare_hidden_char_array). - -Wed Jun 7 19:02:50 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (start_function): Handle setting C_C_D here. - (set_C_C_D): Removed. - (struct saved_scope): Remove class_decl. - (push_to_top_level): Don't save current_class_decl. - (pop_from_top_level): Don't restore current_class_decl or C_C_D. - (struct cp_function): Add C_C_D. - (push_cp_function_context): Save C_C_D. - (pop_cp_function_context): Restore C_C_D. - Wed Jun 7 15:31:57 1995 Brendan Kehoe (brendan@lisa.cygnus.com) * init.c (build_vec_delete): Resolve an offset ref before we try to @@ -1155,29 +1455,6 @@ Mon Jun 5 11:20:34 1995 Gerald Baumgartner (gb@alexander.cs.purdue.edu) to tag and delta, respectively. (build_signature_method_call): Ditto. Use above variables. -Fri Jun 2 11:05:58 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (set_C_C_D): New function. suspend_momentary before - building C_C_D. - (pop_from_top_level): Call it. - (start_function): Ditto. - (pop_cp_function_context): Ditto. - - * class.c, cp-tree.h, decl.c, decl2.c, parse.y: Lose all references - to current_vtable_decl, CLASSTYPE_INST_VAR and CLASSTYPE_VTBL_PTR. - - * decl.c (push_cp_function_context): Save current_class_decl. - (pop_cp_function_context): Restore current_class_decl and set C_C_D. - (pop_from_top_level): Don't use CLASSTYPE_INST_VAR to set C_C_D. - (start_function): Ditto. - - * class.c (popclass): Don't mess with current_class_decl, - current_vtable_decl, or C_C_D. - -Mon May 29 12:45:10 1995 Paul Eggert <eggert@twinsun.com> - - * Make-lang.in (c++.mostlyclean): Remove $(DEMANGLER_PROG). - Thu Jun 1 17:03:51 1995 Jason Merrill <jason@phydeaux.cygnus.com> * decl.c (lookup_name_real): Don't try to look anything up in an @@ -1209,6 +1486,58 @@ Wed May 31 11:39:43 1995 Jason Merrill <jason@phydeaux.cygnus.com> reference type. (build_indirect_ref): Fix check for *&. +Fri Jun 16 06:54:03 1995 Mike Stump <mrs@cygnus.com> + + * Version 2.7.0 released. + +Fri Jun 16 15:07:29 1995 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + * Make-lang.in (DEMANGLER_PROG): Add LIBS. + +Thu Jun 15 15:00:41 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * decl.c (define_function): Don't set DECL_INTERFACE_KNOWN. + +Wed Jun 7 20:00:31 1995 Mike Stump <mrs@cygnus.com> + + * *.[chy]: Change all callers of finish_decl to cp_finish_decl. + * decl.c (finish_decl): New routine to handle call backs from the + mid end (declare_hidden_char_array). + +Wed Jun 7 19:02:50 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * decl.c (start_function): Handle setting C_C_D here. + (set_C_C_D): Removed. + (struct saved_scope): Remove class_decl. + (push_to_top_level): Don't save current_class_decl. + (pop_from_top_level): Don't restore current_class_decl or C_C_D. + (struct cp_function): Add C_C_D. + (push_cp_function_context): Save C_C_D. + (pop_cp_function_context): Restore C_C_D. + +Fri Jun 2 11:05:58 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * decl.c (set_C_C_D): New function. suspend_momentary before + building C_C_D. + (pop_from_top_level): Call it. + (start_function): Ditto. + (pop_cp_function_context): Ditto. + + * class.c, cp-tree.h, decl.c, decl2.c, parse.y: Lose all references + to current_vtable_decl, CLASSTYPE_INST_VAR and CLASSTYPE_VTBL_PTR. + + * decl.c (push_cp_function_context): Save current_class_decl. + (pop_cp_function_context): Restore current_class_decl and set C_C_D. + (pop_from_top_level): Don't use CLASSTYPE_INST_VAR to set C_C_D. + (start_function): Ditto. + + * class.c (popclass): Don't mess with current_class_decl, + current_vtable_decl, or C_C_D. + +Mon May 29 12:45:10 1995 Paul Eggert <eggert@twinsun.com> + + * Make-lang.in (c++.mostlyclean): Remove $(DEMANGLER_PROG). + Wed May 24 15:55:18 1995 Richard Kenner (kenner@vlsi1.ultra.nyu.edu) * decl.c (duplicate_decls): Check simple_cst_equal result against 0. @@ -3366,11 +3695,6 @@ Mon Jan 9 18:16:23 1995 Jason Merrill <jason@phydeaux.cygnus.com> (pushdecl): Set the nested typename if the decl doesn't have one, rather than if the type's canonical decl doesn't have one. -Mon Jan 9 16:48:16 1995 Steve Chamberlain (sac@jonny.cygnus.com) - - * typeck.c (pointer_int_sum): Use offset size when calculating - index expression. - Mon Jan 9 03:44:33 1995 Jason Merrill <jason@phydeaux.cygnus.com> * typeck.c (convert_for_assignment): Complain about contravariance @@ -3778,11 +4102,6 @@ Thu Nov 17 20:11:24 1994 Doug Evans <dje@cygnus.com> (c++.install-man): Use program_transform_name on g++.1. (c++.uninstall): Likewise. -Thu Nov 3 18:48:19 1994 Paul Eggert <eggert@twinsun.com> - - * Makefile.in (spew.o, lex.o, pt.o): - Depend on $(srcdir)/parse.h, not parse.h. - Mon Nov 28 13:53:03 1994 Mike Stump <mrs@cygnus.com> * parse.y (THROW): Fix precedence of throw expressions. @@ -3833,43 +4152,6 @@ Thu Nov 17 15:30:50 1994 Mike Stump <mrs@cygnus.com> to add support for explicit, namespace, typename, and using, support for the rest is already in. -Thu Nov 17 10:56:50 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck2.c (build_m_component_ref): Check the basetype of the - member pointer against the main variant of the object type. - -Mon Nov 14 14:21:52 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * cvt.c (convert_to_reference): Make sure that the original expr - gets its type back when converting a reference. - - * method.c (build_overload_name): Clear numeric_outputed_need_bar here. - (build_decl_overload): Instead of here. - -Tue Nov 8 17:11:24 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * cvt.c (cp_convert): Don't build a TARGET_EXPR if we're not in a - function. - - * typeck.c (convert_for_initialization): Handle initialization from - a TARGET_EXPR. - -Sun Nov 6 01:34:24 1994 Jason Merrill (jason@phydeaux.cygnus.com) - - * pt.c (lookup_nested_type_by_name): Fix list-walking logic. - (tsubst): When replacing a TEMPLATE_TYPE_PARM, propagate - TYPE_READONLY and TYPE_VOLATILE from the argument. - (unify): When unifying with a TEMPLATE_TYPE_PARM, remove cv-quals - present in parm from arg. - (type_unification): Strip REFERENCE_TYPE from the argument type. - (unify): Don't strip REFERENCE_TYPE from the argument type. - -Sat Nov 5 22:42:15 1994 Greg McGary (gkm@magilla.cichlid.com) - - * pt.c (do_type_instantiation): Check to see if there's a - IDENTIFIER_TEMPLATE on a class before calling - instantiate_member_templates(). - Fri Nov 4 19:04:18 1994 Mike Stump <mrs@cygnus.com> * gc.c (get_bad_cast_node): New routine to support compile time @@ -3964,6 +4246,60 @@ Tue Oct 25 13:37:41 1994 Jason Merrill (jason@phydeaux.cygnus.com) * call.c (convert_harshness): Check for TREE_UNSIGNED differences after checking for integral conversions. +Wed Nov 30 19:13:50 1994 Mike Stump <mrs@cygnus.com> + + * Version 2.6.3 released. + +Thu Nov 17 10:56:50 1994 Jason Merrill <jason@phydeaux.cygnus.com> + + * typeck2.c (build_m_component_ref): Check the basetype of the + member pointer against the main variant of the object type. + +Mon Nov 14 14:21:52 1994 Jason Merrill <jason@phydeaux.cygnus.com> + + * cvt.c (convert_to_reference): Make sure that the original expr + gets its type back when converting a reference. + + * method.c (build_overload_name): Clear numeric_outputed_need_bar here. + (build_decl_overload): Instead of here. + +Tue Nov 8 17:11:24 1994 Jason Merrill <jason@phydeaux.cygnus.com> + + * cvt.c (cp_convert): Don't build a TARGET_EXPR if we're not in a + function. + + * typeck.c (convert_for_initialization): Handle initialization from + a TARGET_EXPR. + +Sun Nov 6 01:34:24 1994 Jason Merrill (jason@phydeaux.cygnus.com) + + * pt.c (lookup_nested_type_by_name): Fix list-walking logic. + (tsubst): When replacing a TEMPLATE_TYPE_PARM, propagate + TYPE_READONLY and TYPE_VOLATILE from the argument. + (unify): When unifying with a TEMPLATE_TYPE_PARM, remove cv-quals + present in parm from arg. + (type_unification): Strip REFERENCE_TYPE from the argument type. + (unify): Don't strip REFERENCE_TYPE from the argument type. + +Sat Nov 5 22:42:15 1994 Greg McGary (gkm@magilla.cichlid.com) + + * pt.c (do_type_instantiation): Check to see if there's a + IDENTIFIER_TEMPLATE on a class before calling + instantiate_member_templates(). + +Sat Nov 12 06:35:42 1994 Mike Stump <mrs@cygnus.com> + + * Version 2.6.2 released. + +Thu Nov 3 18:48:19 1994 Paul Eggert <eggert@twinsun.com> + + * Makefile.in (spew.o, lex.o, pt.o): + Depend on $(srcdir)/parse.h, not parse.h. + +Tue Nov 1 19:19:41 1994 Mike Stump <mrs@cygnus.com> + + * Version 2.6.1 released. + Sun Oct 23 13:19:55 1994 Jason Merrill (jason@phydeaux.cygnus.com) * decl2.c: Declare flag_access_control. @@ -4946,6 +5282,10 @@ Tue Jul 19 17:55:37 1994 Jason Merrill (jason@deneb.cygnus.com) * call.c (build_method_call): Accept using a typedef name (or template type parameter) for explicit destructor calls. +Thu Jul 14 09:42:23 1994 Mike Stump <mrs@cygnus.com> + + * Version 2.6.0 released. + Wed Jul 13 03:57:54 1994 Jason Merrill (jason@deneb.cygnus.com) * method.c (hack_identifier): Put back old code so lists of diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 3f293ac..973deaa 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1658,6 +1658,7 @@ build_method_call (instance, name, parms, basetype_path, flags) } /* We already know whether it's needed or not for vec delete. */ else if (name == ansi_opname[(int) VEC_DELETE_EXPR] + && TYPE_LANG_SPECIFIC (TREE_TYPE (instance)) && ! TYPE_VEC_DELETE_TAKES_SIZE (TREE_TYPE (instance))) TREE_CHAIN (parms) = NULL_TREE; @@ -2464,17 +2465,13 @@ build_method_call (instance, name, parms, basetype_path, flags) return build_signature_method_call (basetype, instance, function, parms); function = DECL_MAIN_VARIANT (function); - /* Declare external function if necessary. */ - assemble_external (function); + mark_used (function); -#if 1 /* Is it a synthesized method that needs to be synthesized? */ - if (DECL_ARTIFICIAL (function) && ! flag_no_inline - && ! DECL_INITIAL (function) + if (DECL_ARTIFICIAL (function) && ! DECL_INITIAL (function) /* Kludge: don't synthesize for default args. */ && current_function_decl) synthesize_method (function); -#endif if (pedantic && DECL_THIS_INLINE (function) && ! DECL_ARTIFICIAL (function) && ! DECL_INITIAL (function) && ! DECL_PENDING_INLINE_INFO (function)) @@ -2670,7 +2667,6 @@ build_method_call (instance, name, parms, basetype_path, flags) if (TREE_CODE (function) == FUNCTION_DECL) { is_constructor = DECL_CONSTRUCTOR_P (function); - TREE_USED (function) = 1; function = default_conversion (function); } else diff --git a/gcc/cp/class.c b/gcc/cp/class.c index e289304..fc25b1a 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -424,7 +424,6 @@ build_vfn_ref (ptr_to_instptr, instance, idx) tree *ptr_to_instptr, instance; tree idx; { - extern int building_cleanup; tree vtbl, aref; tree basetype = TREE_TYPE (instance); @@ -481,7 +480,7 @@ build_vfn_ref (ptr_to_instptr, instance, idx) /* Save the intermediate result in a SAVE_EXPR so we don't have to compute each component of the virtual function pointer twice. */ - if (!building_cleanup && TREE_CODE (aref) == INDIRECT_REF) + if (TREE_CODE (aref) == INDIRECT_REF) TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0)); if (flag_vtable_thunks) @@ -1720,8 +1719,14 @@ finish_struct_bits (t, max_has_virtual) /* If this type has a copy constructor, force its mode to be BLKmode, and force its TREE_ADDRESSABLE bit to be nonzero. This will cause it to be passed by invisible reference and prevent it from being returned in - a register. */ - if (! TYPE_HAS_TRIVIAL_INIT_REF (t)) + a register. + + Also do this if the class has BLKmode but can still be returned in + registers, since function_cannot_inline_p won't let us inline + functions returning such a type. This affects the HP-PA. */ + if (! TYPE_HAS_TRIVIAL_INIT_REF (t) + || (TYPE_MODE (t) == BLKmode && ! aggregate_value_p (t) + && CLASSTYPE_NON_AGGREGATE (t))) { tree variants; if (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL) @@ -1812,15 +1817,14 @@ grow_method (fn, method_vec_ptr) us to reduce search time in places like `build_method_call' to consider only reasonably likely functions. */ -static tree +tree finish_struct_methods (t, fn_fields, nonprivate_method) tree t; tree fn_fields; int nonprivate_method; { tree method_vec; - tree save_fn_fields = tree_cons (NULL_TREE, NULL_TREE, fn_fields); - tree lastp; + tree save_fn_fields = fn_fields; tree name = constructor_name (t); int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t); @@ -1837,7 +1841,7 @@ finish_struct_methods (t, fn_fields, nonprivate_method) /* First fill in entry 0 with the constructors, and the next few with type conversion operators (if any). */ - for (lastp = save_fn_fields; fn_fields; fn_fields = TREE_CHAIN (lastp)) + for (; fn_fields; fn_fields = TREE_CHAIN (fn_fields)) { tree fn_name = DECL_NAME (fn_fields); if (fn_name == NULL_TREE) @@ -1887,26 +1891,17 @@ finish_struct_methods (t, fn_fields, nonprivate_method) grow_method (fn_fields, &method_vec); } - else - { - lastp = fn_fields; - continue; - } - - TREE_CHAIN (lastp) = TREE_CHAIN (fn_fields); - TREE_CHAIN (fn_fields) = NULL_TREE; } - fn_fields = TREE_CHAIN (save_fn_fields); - while (fn_fields) + fn_fields = save_fn_fields; + for (; fn_fields; fn_fields = TREE_CHAIN (fn_fields)) { - tree nextp; tree fn_name = DECL_NAME (fn_fields); if (fn_name == NULL_TREE) fn_name = name; - nextp = TREE_CHAIN (fn_fields); - TREE_CHAIN (fn_fields) = NULL_TREE; + if (fn_name == name || IDENTIFIER_TYPENAME_P (fn_name)) + continue; if (fn_name == ansi_opname[(int) MODIFY_EXPR]) { @@ -1922,7 +1917,6 @@ finish_struct_methods (t, fn_fields, nonprivate_method) } grow_method (fn_fields, &method_vec); - fn_fields = nextp; } TREE_VEC_LENGTH (method_vec) = (tree *)obstack_next_free (&class_obstack) @@ -2005,6 +1999,7 @@ finish_struct_methods (t, fn_fields, nonprivate_method) obstack_free (current_obstack, baselink_vec); } +#if 0 /* Now add the methods to the TYPE_METHODS of T, arranged in a chain. */ { tree x, last_x = NULL_TREE; @@ -2040,6 +2035,7 @@ finish_struct_methods (t, fn_fields, nonprivate_method) } TYPE_METHODS (t) = method_vec; +#endif return method_vec; } @@ -2765,7 +2761,7 @@ finish_struct_1 (t, warn_anon) tree name = TYPE_IDENTIFIER (t); enum tree_code code = TREE_CODE (t); tree fields = TYPE_FIELDS (t); - tree fn_fields = CLASSTYPE_METHODS (t); + tree fn_fields = TYPE_METHODS (t); tree x, last_x, method_vec; int needs_virtual_dtor; int all_virtual; @@ -2920,7 +2916,7 @@ finish_struct_1 (t, warn_anon) else all_virtual = 0; - for (x = CLASSTYPE_METHODS (t); x; x = TREE_CHAIN (x)) + for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) { GNU_xref_member (current_class_name, x); @@ -3197,7 +3193,7 @@ finish_struct_1 (t, warn_anon) { tree type = TREE_TYPE (x); - if (TREE_CODE (type) == ARRAY_TYPE) + while (TREE_CODE (type) == ARRAY_TYPE) type = TREE_TYPE (type); if (TYPE_LANG_SPECIFIC (type) && ! ANON_UNION_P (x) @@ -3681,19 +3677,6 @@ finish_struct_1 (t, warn_anon) } } } - - /* Now fixup any virtual function entries from virtual bases - that have different deltas. */ - vbases = CLASSTYPE_VBASECLASSES (t); - while (vbases) - { - /* We might be able to shorten the amount of work we do by - only doing this for vtables that come from virtual bases - that have differing offsets, but don't want to miss any - entries. */ - fixup_vtable_deltas (vbases, 1, t); - vbases = TREE_CHAIN (vbases); - } } /* Set up the DECL_FIELD_BITPOS of the vfield if we need to, as we @@ -3736,6 +3719,27 @@ finish_struct_1 (t, warn_anon) TREE_VALUE (pending_hard_virtuals)); pending_hard_virtuals = TREE_CHAIN (pending_hard_virtuals); } + + if (TYPE_USES_VIRTUAL_BASECLASSES (t)) + { + tree vbases; + /* Now fixup any virtual function entries from virtual bases + that have different deltas. This has to come after we do the + pending hard virtuals, as we might have a function that comes + from multiple virtual base instances that is only overridden + by a hard virtual above. */ + vbases = CLASSTYPE_VBASECLASSES (t); + while (vbases) + { + /* We might be able to shorten the amount of work we do by + only doing this for vtables that come from virtual bases + that have differing offsets, but don't want to miss any + entries. */ + fixup_vtable_deltas (vbases, 1, t); + vbases = TREE_CHAIN (vbases); + } + } + doing_hard_virtuals = 0; /* Under our model of GC, every C++ class gets its own virtual @@ -4045,8 +4049,8 @@ finish_struct (t, list_of_fieldlists, warn_anon) tree list_of_fieldlists; int warn_anon; { - tree fields = NULL_TREE, fn_fields, *tail; - tree *tail_user_methods = &CLASSTYPE_METHODS (t); + tree fields = NULL_TREE; + tree *tail = &TYPE_METHODS (t); tree name = TYPE_NAME (t); tree x, last_x = NULL_TREE; enum access_type access; @@ -4071,7 +4075,6 @@ finish_struct (t, list_of_fieldlists, warn_anon) if (IS_SIGNATURE (t)) append_signature_fields (list_of_fieldlists); - tail = &fn_fields; if (last_x && list_of_fieldlists) TREE_CHAIN (last_x) = TREE_VALUE (list_of_fieldlists); @@ -4130,11 +4133,9 @@ finish_struct (t, list_of_fieldlists, warn_anon) { if (last_x) TREE_CHAIN (last_x) = TREE_CHAIN (x); - /* Link x onto end of fn_fields and CLASSTYPE_METHODS. */ + /* Link x onto end of TYPE_METHODS. */ *tail = x; tail = &TREE_CHAIN (x); - *tail_user_methods = x; - tail_user_methods = &DECL_NEXT_METHOD (x); continue; } @@ -4167,12 +4168,12 @@ finish_struct (t, list_of_fieldlists, warn_anon) } *tail = NULL_TREE; - *tail_user_methods = NULL_TREE; TYPE_FIELDS (t) = fields; if (0 && processing_template_defn) { - CLASSTYPE_METHOD_VEC (t) = finish_struct_methods (t, fn_fields, 1); + CLASSTYPE_METHOD_VEC (t) + = finish_struct_methods (t, TYPE_METHODS (t), 1); return t; } else @@ -4671,6 +4672,7 @@ instantiate_type (lhstype, rhs, complain) return error_mark_node; return build_vfn_ref (&base_ptr, base, DECL_VINDEX (function)); } + mark_used (function); return function; } @@ -4687,6 +4689,7 @@ instantiate_type (lhstype, rhs, complain) if (field) { TREE_OPERAND (rhs, 1) = field; + mark_used (field); return rhs; } @@ -4760,7 +4763,10 @@ instantiate_type (lhstype, rhs, complain) if (! comptypes (lhstype, TREE_TYPE (elem), 1)) elem = DECL_CHAIN (elem); else - return elem; + { + mark_used (elem); + return elem; + } /* No exact match found, look for a compatible template. */ { @@ -4815,6 +4821,7 @@ instantiate_type (lhstype, rhs, complain) } return error_mark_node; } + mark_used (save_elem); return save_elem; } if (complain) @@ -4848,7 +4855,10 @@ instantiate_type (lhstype, rhs, complain) elem = TREE_VALUE (baselink); while (elem) if (comptypes (lhstype, TREE_TYPE (elem), 1)) - return elem; + { + mark_used (elem); + return elem; + } else elem = DECL_CHAIN (elem); } @@ -4874,6 +4884,7 @@ instantiate_type (lhstype, rhs, complain) error ("ambiguous overload for overloaded method requested"); return error_mark_node; } + mark_used (save_elem); return save_elem; } name = DECL_NAME (TREE_VALUE (rhs)); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index fe9855d..ddea575 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -636,10 +636,6 @@ struct lang_type /* The is the VAR_DECL that contains NODE's rtti. */ #define CLASSTYPE_RTTI(NODE) (TYPE_LANG_SPECIFIC(NODE)->rtti) -/* List of all explicit methods (chained using DECL_NEXT_METHOD), - in order they were parsed. */ -#define CLASSTYPE_METHODS(NODE) (TYPE_LANG_SPECIFIC(NODE)->methods) - /* Nonzero means that this _CLASSTYPE node overloads operator(). */ #define TYPE_OVERLOADS_CALL_EXPR(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_call_overloaded) @@ -660,7 +656,7 @@ struct lang_type #define TYPE_USES_VIRTUAL_BASECLASSES(NODE) (TREE_LANG_FLAG_3(NODE)) /* List of lists of member functions defined in this class. */ -#define CLASSTYPE_METHOD_VEC(NODE) TYPE_METHODS(NODE) +#define CLASSTYPE_METHOD_VEC(NODE) (TYPE_LANG_SPECIFIC(NODE)->methods) /* The first type conversion operator in the class (the others can be searched with TREE_CHAIN), or the first non-constructor function if @@ -924,7 +920,7 @@ struct lang_type #define TYPE_RAISES_EXCEPTIONS(NODE) TYPE_NONCOPIED_PARTS (NODE) /* The binding level associated with the namespace. */ -#define NAMESPACE_LEVEL(NODE) ((NODE)->decl.arguments) +#define NAMESPACE_LEVEL(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.level) struct lang_decl_flags { @@ -960,6 +956,7 @@ struct lang_decl_flags tree access; tree context; tree memfunc_pointer_to; + struct binding_level *level; }; struct lang_decl @@ -969,7 +966,6 @@ struct lang_decl struct template_info *template_info; tree main_decl_variant; struct pending_inline *pending_inline_info; - tree next_method; tree chain; }; @@ -1068,9 +1064,6 @@ struct lang_decl #define DECL_CHAIN(NODE) (TREE_CHAIN (NODE)) #endif -/* Next method in CLASSTYPE_METHODS list. */ -#define DECL_NEXT_METHOD(NODE) (DECL_LANG_SPECIFIC(NODE)->next_method) - /* In a VAR_DECL for a variable declared in a for statement, this is the shadowed variable. */ #define DECL_SHADOWED_FOR_VAR(NODE) DECL_RESULT(NODE) @@ -1401,6 +1394,9 @@ extern int flag_new_for_scope; #define UPT_TEMPLATE(NODE) TREE_PURPOSE(TYPE_VALUES(NODE)) #define UPT_PARMS(NODE) TREE_VALUE(TYPE_VALUES(NODE)) +#define builtin_function(NAME, TYPE, CODE, LIBNAME) \ + define_function (NAME, TYPE, CODE, (void (*)())pushdecl, LIBNAME) + /* An enumeration of the kind of tags that C++ accepts. */ enum tag_types { record_type, class_type, union_type, enum_type, signature_type }; @@ -1809,6 +1805,12 @@ extern int flag_alt_external_templates; extern int flag_implicit_templates; +/* Nonzero if we want to emit defined symbols with common-like linkage as + weak symbols where possible, in order to conform to C++ semantics. + Otherwise, emit them as local symbols. */ + +extern int flag_weak; + /* Current end of entries in the gc obstack for stack pointer variables. */ extern int current_function_obstack_index; @@ -1844,6 +1846,9 @@ extern tree current_class_type; /* _TYPE: the type of the current class */ LOOKUP_HAS_IN_CHARGE means that the "in charge" variable is already in the parameter list. LOOKUP_ONLYCONVERTING means that non-conversion constructors are not tried. + INDIRECT_BIND means that if a temporary is created, it should be created so + that it lives only as long as WITH_CLEANUP_EXPRs live, else if a temporary + is created then it should live as long as the current variable bindings. LOOKUP_SPECULATIVELY means return NULL_TREE if we cannot find what we are after. Note, LOOKUP_COMPLAIN is checked and error messages printed before LOOKUP_SPECULATIVELY is checked. @@ -1860,7 +1865,7 @@ extern tree current_class_type; /* _TYPE: the type of the current class */ #define LOOKUP_HAS_IN_CHARGE (32) #define LOOKUP_SPECULATIVELY (64) #define LOOKUP_ONLYCONVERTING (128) -/* 256 is free */ +#define INDIRECT_BIND (256) #define LOOKUP_NO_CONVERSION (512) #define LOOKUP_DESTRUCTOR (512) @@ -2131,6 +2136,8 @@ extern void init_exception_processing PROTO((void)); extern void expand_builtin_throw PROTO((void)); extern void expand_start_eh_spec PROTO((void)); extern void expand_end_eh_spec PROTO((tree)); +extern tree build_cleanup PROTO((tree)); +extern tree start_anon_func PROTO((void)); /* in expr.c */ /* skip cplus_expand_expr */ @@ -2395,6 +2402,7 @@ extern tree array_type_nelts_total PROTO((tree)); extern tree array_type_nelts_top PROTO((tree)); extern tree break_out_target_exprs PROTO((tree)); extern tree build_unsave_expr PROTO((tree)); +extern tree unsave_expr PROTO((tree)); extern int cp_expand_decl_cleanup PROTO((tree, tree)); /* in typeck.c */ diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 56508c1..a4e28ff 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -311,6 +311,7 @@ convert_to_pointer_force (type, expr) value we have to begin with is in ARG. FLAGS controls how we manage access checking. + INDIRECT_BIND in FLAGS controls how any temporarys are generated. CHECKCONST controls if we report error messages on const subversion. */ static tree build_up_reference (type, arg, flags, checkconst) @@ -589,7 +590,15 @@ build_up_reference (type, arg, flags, checkconst) { tree temp; - if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype)) + if (flags&INDIRECT_BIND) + { + tree slot = build (VAR_DECL, argtype); + layout_decl (slot, 0); + rval = build (TARGET_EXPR, argtype, slot, arg, 0); + rval = build1 (ADDR_EXPR, type, rval); + goto done; + } + else if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype)) { temp = build_cplus_new (argtype, targ, 1); if (TREE_CODE (temp) == WITH_CLEANUP_EXPR) @@ -1634,8 +1643,13 @@ build_expr_type_conversion (desires, expr, complain) } if (winner) - return build_type_conversion_1 (TREE_VALUE (winner), basetype, expr, - TREE_PURPOSE (winner), 1); + { + tree type = TREE_VALUE (winner); + if (TREE_CODE (type) == REFERENCE_TYPE) + type = TREE_TYPE (type); + return build_type_conversion_1 (type, basetype, expr, + TREE_PURPOSE (winner), 1); + } return NULL_TREE; } diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 103cb0d..f639140 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -38,6 +38,7 @@ Boston, MA 02111-1307, USA. */ #include <sys/types.h> #include <signal.h> #include "obstack.h" +#include "defaults.h" #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free @@ -267,6 +268,11 @@ tree vtbl_type_node; tree dtor_label; +/* In a destructor, the last insn emitted after the start of the + function and the parms. */ + +rtx last_dtor_insn; + /* In a constructor, the point at which we are ready to return the pointer to the initialized object. */ @@ -1092,15 +1098,30 @@ poplevel (keep, reverse, functionbody) block = make_node (BLOCK); if (block != NULL_TREE) { - BLOCK_VARS (block) = decls; - BLOCK_TYPE_TAGS (block) = tags; - BLOCK_SUBBLOCKS (block) = subblocks; - /* If we created the block earlier on, and we are just diddling it now, - then it already should have a proper BLOCK_END_NOTE value associated - with it, so avoid trashing that. Otherwise, for a new block, install - a new BLOCK_END_NOTE value. */ - if (! block_previously_created) - remember_end_note (block); + if (block_previously_created) + { + if (decls || tags || subblocks) + { + if (BLOCK_VARS (block) || BLOCK_TYPE_TAGS (block) || BLOCK_SUBBLOCKS (block)) + { + warning ("internal compiler error: debugging info corrupted"); + } + BLOCK_VARS (block) = decls; + BLOCK_TYPE_TAGS (block) = tags; + /* Recover from too many blocks by chaining them together. */ + BLOCK_SUBBLOCKS (block) = chainon (BLOCK_SUBBLOCKS (block), subblocks); + } + /* If we created the block earlier on, and we are just diddling it now, then + it already should have a proper BLOCK_END_NOTE value associated with it. */ + } + else + { + BLOCK_VARS (block) = decls; + BLOCK_TYPE_TAGS (block) = tags; + BLOCK_SUBBLOCKS (block) = subblocks; + /* Otherwise, for a new block, install a new BLOCK_END_NOTE value. */ + remember_end_note (block); + } } /* In each subblock, record that this is its superior. */ @@ -1700,7 +1721,7 @@ push_namespace (name) extern tree current_namespace; tree old_id = get_namespace_id (); char *buf; - tree d = make_node (NAMESPACE_DECL); + tree d; if (! name) { @@ -1708,12 +1729,11 @@ push_namespace (name) name = get_unique_name (); } - DECL_NAME (d) = name; - DECL_ASSEMBLER_NAME (d) = name; - /* pushdecl wants to check the size of it to see if it is incomplete... */ - TREE_TYPE (d) = void_type_node; + d = build_lang_decl (NAMESPACE_DECL, name, void_type_node); + /* Mark them as external, so redeclaration_error_message doesn't think they are duplicates. */ + DECL_EXTERNAL (d) = 1; d = pushdecl (d); @@ -1722,12 +1742,10 @@ push_namespace (name) /* This is new for this compilation unit. */ pushlevel (0); declare_namespace_level (); - NAMESPACE_LEVEL (d) = (tree)current_binding_level; + NAMESPACE_LEVEL (d) = current_binding_level; } else - { - resume_level ((struct binding_level*)NAMESPACE_LEVEL (d)); - } + resume_level (NAMESPACE_LEVEL (d)); /* This code is just is bit old now... */ current_namespace = tree_cons (NULL_TREE, name, current_namespace); @@ -2400,8 +2418,20 @@ decls_match (newdecl, olddecl) types_match = TREE_TYPE (newdecl) == NULL_TREE; else if (TREE_TYPE (newdecl) == NULL_TREE) types_match = 0; + /* Qualifiers must match, and they may be present on either, the type + or the decl. */ + else if ((TREE_READONLY (newdecl) + || TYPE_READONLY (TREE_TYPE (newdecl))) + == (TREE_READONLY (olddecl) + || TYPE_READONLY (TREE_TYPE (olddecl))) + && (TREE_THIS_VOLATILE (newdecl) + || TYPE_VOLATILE (TREE_TYPE (newdecl))) + == (TREE_THIS_VOLATILE (olddecl) + || TYPE_VOLATILE (TREE_TYPE (olddecl)))) + types_match = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (newdecl)), + TYPE_MAIN_VARIANT (TREE_TYPE (olddecl)), 1); else - types_match = comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl), 1); + types_match = 0; } return types_match; @@ -2722,8 +2752,6 @@ duplicate_decls (newdecl, olddecl) DECL_CLASS_CONTEXT (newdecl) = DECL_CLASS_CONTEXT (olddecl); if (DECL_CHAIN (newdecl) == NULL_TREE) DECL_CHAIN (newdecl) = DECL_CHAIN (olddecl); - if (DECL_NEXT_METHOD (newdecl) == NULL_TREE) - DECL_NEXT_METHOD (newdecl) = DECL_NEXT_METHOD (olddecl); if (DECL_PENDING_INLINE_INFO (newdecl) == (struct pending_inline *)0) DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl); DECL_STATIC_CONSTRUCTOR (newdecl) |= DECL_STATIC_CONSTRUCTOR (olddecl); @@ -2888,7 +2916,7 @@ duplicate_decls (newdecl, olddecl) if (TREE_CODE (newdecl) == FUNCTION_DECL) { - DECL_C_STATIC (newdecl) = DECL_C_STATIC (olddecl); + DECL_C_STATIC (newdecl) |= DECL_C_STATIC (olddecl); DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl); DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl); } @@ -3379,7 +3407,7 @@ pushdecl (x) if (b->parm_flag == 1) cp_error ("declaration of `%#D' shadows a parameter", name); } - else if (oldlocal != NULL_TREE && b->is_for_scope + else if (warn_shadow && oldlocal != NULL_TREE && b->is_for_scope && !DECL_DEAD_FOR_LOCAL (oldlocal)) { warning ("variable `%s' shadows local", @@ -4173,6 +4201,7 @@ lookup_tag (form, name, binding_level, thislevel_only) /* Definition isn't the kind we were looking for. */ cp_error ("`%#D' redeclared as %C", TREE_VALUE (tail), form); + return NULL_TREE; } return TREE_VALUE (tail); } @@ -4208,6 +4237,7 @@ lookup_tag (form, name, binding_level, thislevel_only) { cp_error ("`%#D' redeclared as %C in class scope", TREE_VALUE (tail), form); + return NULL_TREE; } return TREE_VALUE (tail); } @@ -4690,9 +4720,6 @@ push_overloaded_decl_1 (x) push_overloaded_decl (x, 0); } -#define builtin_function(NAME, TYPE, CODE, LIBNAME) \ - define_function (NAME, TYPE, CODE, (void (*)())pushdecl, LIBNAME) - #ifdef __GNUC__ __inline #endif @@ -5230,21 +5257,21 @@ init_decl_processing () #if 0 /* Support for these has not been written in either expand_builtin or build_function_call. */ - builtin_function ("__builtin_div", default_ftype, BUILT_IN_DIV, 0); - builtin_function ("__builtin_ldiv", default_ftype, BUILT_IN_LDIV, 0); + builtin_function ("__builtin_div", default_ftype, BUILT_IN_DIV, NULL_PTR); + builtin_function ("__builtin_ldiv", default_ftype, BUILT_IN_LDIV, NULL_PTR); builtin_function ("__builtin_ffloor", double_ftype_double, BUILT_IN_FFLOOR, - 0); - builtin_function ("__builtin_fceil", double_ftype_double, BUILT_IN_FCEIL, 0); + NULL_PTR); + builtin_function ("__builtin_fceil", double_ftype_double, BUILT_IN_FCEIL, NULL_PTR); builtin_function ("__builtin_fmod", double_ftype_double_double, - BUILT_IN_FMOD, 0); + BUILT_IN_FMOD, NULL_PTR); builtin_function ("__builtin_frem", double_ftype_double_double, - BUILT_IN_FREM, 0); + BUILT_IN_FREM, NULL_PTR); builtin_function ("__builtin_memset", ptr_ftype_ptr_int_int, BUILT_IN_MEMSET, - 0); + NULL_PTR); builtin_function ("__builtin_getexp", double_ftype_double, BUILT_IN_GETEXP, - 0); + NULL_PTR); builtin_function ("__builtin_getman", double_ftype_double, BUILT_IN_GETMAN, - 0); + NULL_PTR); #endif /* C++ extensions */ @@ -5299,7 +5326,7 @@ init_decl_processing () real gc code. */ if (flag_gc) { - builtin_function ("__gc_main", default_function_type, NOT_BUILT_IN, 0); + builtin_function ("__gc_main", default_function_type, NOT_BUILT_IN, NULL_PTR); pushdecl (lookup_name (get_identifier ("__gc_main"), 0)); } @@ -5553,6 +5580,8 @@ init_decl_processing () } if (flag_cadillac) init_cadillac (); + if (! SUPPORTS_WEAK) + flag_weak = 0; /* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__. */ declare_function_name (); @@ -6819,7 +6848,11 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) } else if (! toplev) { + extern int temp_slot_level; + extern int target_temp_slot_level; tree old_cleanups = cleanups_this_call; + int old_temp_level = target_temp_slot_level; + /* This is a declared decl which must live until the end of the binding contour. It may need a cleanup. */ @@ -6854,6 +6887,10 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) } } + push_temp_slots (); + push_temp_slots (); + target_temp_slot_level = temp_slot_level; + if (DECL_SIZE (decl) && type != error_mark_node) { /* Compute and store the initial value. */ @@ -6883,6 +6920,9 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) } /* Cleanup any temporaries needed for the initial value. */ expand_cleanups_to (old_cleanups); + pop_temp_slots (); + pop_temp_slots (); + target_temp_slot_level = old_temp_level; } finish_end0: @@ -6961,7 +7001,6 @@ expand_static_init (decl, init) tree init; { tree oldstatic = value_member (decl, static_aggregates); - tree old_cleanups; if (oldstatic) { @@ -6973,6 +7012,11 @@ expand_static_init (decl, init) /* Emit code to perform this initialization but once. */ tree temp; + extern int temp_slot_level; + extern int target_temp_slot_level; + tree old_cleanups; + int old_temp_level; + /* Remember this information until end of file. */ push_obstacks (&permanent_obstack, &permanent_obstack); @@ -6982,6 +7026,11 @@ expand_static_init (decl, init) expand_start_cond (build_binary_op (EQ_EXPR, temp, integer_zero_node, 1), 0); old_cleanups = cleanups_this_call; + old_temp_level = target_temp_slot_level; + push_temp_slots (); + push_temp_slots (); + target_temp_slot_level = temp_slot_level; + expand_assignment (temp, integer_one_node, 0, 0); if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)) || (init && TREE_CODE (init) == TREE_LIST)) @@ -6994,6 +7043,44 @@ expand_static_init (decl, init) /* Cleanup any temporaries needed for the initial value. */ expand_cleanups_to (old_cleanups); + pop_temp_slots (); + pop_temp_slots (); + target_temp_slot_level = old_temp_level; + + if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl))) + { + tree cleanup, fcall; + static tree Atexit = 0; + if (Atexit == 0) + { + tree atexit_fndecl, PFV, pfvlist; + /* Remember this information until end of file. */ + push_obstacks (&permanent_obstack, &permanent_obstack); + PFV = build_pointer_type (build_function_type + (void_type_node, void_list_node)); + + pfvlist = tree_cons (NULL_TREE, PFV, void_list_node); + + push_lang_context (lang_name_c); + atexit_fndecl = + builtin_function ("atexit", + build_function_type (void_type_node, + pfvlist), + NOT_BUILT_IN, NULL_PTR); + Atexit = default_conversion (atexit_fndecl); + pop_lang_context (); + pop_obstacks (); + } + + cleanup = start_anon_func (); + expand_expr_stmt (build_cleanup (decl)); + end_anon_func (); + mark_addressable (cleanup); + cleanup = build_unary_op (ADDR_EXPR, cleanup, 0); + fcall = build_function_call (Atexit, tree_cons (NULL_TREE, cleanup, NULL_TREE)); + expand_expr_stmt (fcall); + } + expand_end_cond (); if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl))) { @@ -9439,6 +9526,15 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli { int publicp = 0; + /* We catch the others as conflicts with the builtin + typedefs. */ + if (friendp && declarator == ridpointers[(int) RID_SIGNED]) + { + cp_error ("function `%D' cannot be declared friend", + declarator); + friendp = 0; + } + if (friendp == 0) { if (ctype == NULL_TREE) @@ -11667,6 +11763,7 @@ store_parm_decls () if (insns) store_in_parms (insns); } + last_dtor_insn = get_last_insn (); } /* Bind a name and initialization to the return value of @@ -11793,6 +11890,7 @@ finish_function (lineno, call_poplevel, nested) tree in_charge_node = lookup_name (in_charge_identifier, 0); tree virtual_size; int ok_to_optimize_dtor = 0; + int empty_dtor = get_last_insn () == last_dtor_insn; if (current_function_assigns_this) cond = build (NE_EXPR, boolean_type_node, @@ -11805,7 +11903,7 @@ finish_function (lineno, call_poplevel, nested) whether `this' is NULL in some cases. */ if ((flag_this_is_variable & 1) == 0) ok_to_optimize_dtor = 1; - else if (get_last_insn () == get_first_nonparm_insn ()) + else if (empty_dtor) ok_to_optimize_dtor = (n_baseclasses == 0 || (n_baseclasses == 1 @@ -11926,12 +12024,25 @@ finish_function (lineno, call_poplevel, nested) start_sequence (); - /* Make all virtual function table pointers in non-virtual base - classes point to CURRENT_CLASS_TYPE's virtual function - tables. */ - expand_direct_vtbls_init (binfo, binfo, 1, 0, current_class_decl); - if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) - expand_indirect_vtbls_init (binfo, C_C_D, current_class_decl, 0); + /* If the dtor is empty, and we know there is not possible way we could + use any vtable entries, before they are possibly set by a base class + dtor, we don't have to setup the vtables, as we know that any base + class dtoring will set up any vtables it needs. We avoid MI, + because one base class dtor can do a virtual dispatch to an + overridden function that would need to have a non-related vtable set + up, we cannot avoid setting up vtables in that case. We could + change this to see if there is just one vtable. */ + if (! empty_dtor || TYPE_USES_COMPLEX_INHERITANCE (current_class_type)) + { + /* Make all virtual function table pointers in non-virtual base + classes point to CURRENT_CLASS_TYPE's virtual function + tables. */ + expand_direct_vtbls_init (binfo, binfo, 1, 0, current_class_decl); + + if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) + expand_indirect_vtbls_init (binfo, C_C_D, current_class_decl, 0); + } + if (! ok_to_optimize_dtor) { cond = build_binary_op (NE_EXPR, @@ -12490,15 +12601,6 @@ hack_incomplete_structures (type) } } -/* Nonzero if presently building a cleanup. Needed because - SAVE_EXPRs are not the right things to use inside of cleanups. - They are only ever evaluated once, where the cleanup - might be evaluated several times. In this case, a later evaluation - of the cleanup might fill in the SAVE_EXPR_RTL, and it will - not be valid for an earlier cleanup. */ - -int building_cleanup; - /* If DECL is of a type which needs a cleanup, build that cleanup here. We don't build cleanups if just going for syntax checking, since fixup_cleanups does not know how to not handle them. @@ -12514,8 +12616,6 @@ maybe_build_cleanup (decl) { int temp = 0, flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR; tree rval; - int old_building_cleanup = building_cleanup; - building_cleanup = 1; if (TREE_CODE (decl) != PARM_DECL) temp = suspend_momentary (); @@ -12540,11 +12640,12 @@ maybe_build_cleanup (decl) rval = build_compound_expr (tree_cons (NULL_TREE, rval, build_tree_list (NULL_TREE, build_vbase_delete (type, decl)))); + /* Since this is a cleanup, UNSAVE it now. */ + rval = unsave_expr (rval); + if (TREE_CODE (decl) != PARM_DECL) resume_momentary (temp); - building_cleanup = old_building_cleanup; - return rval; } return 0; @@ -12563,6 +12664,14 @@ void cplus_expand_expr_stmt (exp) tree exp; { + extern int temp_slot_level; + extern int target_temp_slot_level; + tree old_cleanups = cleanups_this_call; + int old_temp_level = target_temp_slot_level; + push_temp_slots (); + push_temp_slots (); + target_temp_slot_level = temp_slot_level; + if (TREE_TYPE (exp) == unknown_type_node) { if (TREE_CODE (exp) == ADDR_EXPR || TREE_CODE (exp) == TREE_LIST) @@ -12590,7 +12699,16 @@ cplus_expand_expr_stmt (exp) /* Clean up any pending cleanups. This happens when a function call returns a cleanup-needing value that nobody uses. */ - expand_cleanups_to (NULL_TREE); + expand_cleanups_to (old_cleanups); + pop_temp_slots (); + pop_temp_slots (); + target_temp_slot_level = old_temp_level; + /* There might something left from building the trees. */ + if (cleanups_this_call) + { + expand_cleanups_to (NULL_TREE); + } + free_temp_slots (); } /* When a stmt has been parsed, this function is called. @@ -12679,6 +12797,7 @@ struct cp_function tree shadowed_labels; tree ctor_label; tree dtor_label; + rtx last_dtor_insn; tree protect_list; tree base_init_list; tree member_init_list; @@ -12717,6 +12836,7 @@ push_cp_function_context (context) p->binding_level = current_binding_level; p->ctor_label = ctor_label; p->dtor_label = dtor_label; + p->last_dtor_insn = last_dtor_insn; p->assigns_this = current_function_assigns_this; p->just_assigned_this = current_function_just_assigned_this; p->parms_stored = current_function_parms_stored; @@ -12768,6 +12888,7 @@ pop_cp_function_context (context) current_binding_level = p->binding_level; ctor_label = p->ctor_label; dtor_label = p->dtor_label; + last_dtor_insn = p->last_dtor_insn; protect_list = p->protect_list; current_function_assigns_this = p->assigns_this; current_function_just_assigned_this = p->just_assigned_this; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 7a3f7d5..437247f 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -36,7 +36,6 @@ Boston, MA 02111-1307, USA. */ #include "decl.h" #include "lex.h" #include "output.h" -#include "defaults.h" extern tree get_file_function_name (); extern tree cleanups_this_call; @@ -369,6 +368,12 @@ int flag_check_new; int flag_new_for_scope = 1; +/* Nonzero if we want to emit defined symbols with common-like linkage as + weak symbols where possible, in order to conform to C++ semantics. + Otherwise, emit them as local symbols. */ + +int flag_weak = 1; + /* Table of language-dependent -f options. STRING is the option name. VARIABLE is the address of the variable. ON_VALUE is the value to store in VARIABLE @@ -416,7 +421,8 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] = {"operator-names", &flag_operator_names, 1}, {"check-new", &flag_check_new, 1}, {"repo", &flag_use_repository, 1}, - {"for-scope", &flag_new_for_scope, 2} + {"for-scope", &flag_new_for_scope, 2}, + {"weak", &flag_weak, 1} }; /* Decode the string P as a language-specific option. @@ -906,7 +912,7 @@ grokclassfn (ctype, cname, function, flags, quals) /* Mark the artificial `__in_chrg' parameter as "artificial". */ SET_DECL_ARTIFICIAL (parm); DECL_ARG_TYPE (parm) = integer_type_node; - DECL_REGISTER (parm) = 1; + TREE_READONLY (parm) = 1; TREE_CHAIN (parm) = last_function_parms; last_function_parms = parm; } @@ -948,18 +954,11 @@ grokclassfn (ctype, cname, function, flags, quals) buf[len] = '\0'; strcat (buf, dbuf); DECL_ASSEMBLER_NAME (function) = get_identifier (buf); - parm = build_decl (PARM_DECL, in_charge_identifier, const_integer_type); + parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node); /* Mark the artificial `__in_chrg' parameter as "artificial". */ SET_DECL_ARTIFICIAL (parm); - TREE_USED (parm) = 1; -#if 0 - /* We don't need to mark the __in_chrg parameter itself as `const' - since its type is already `const int'. In fact we MUST NOT mark - it as `const' cuz that will screw up the debug info (causing it - to say that the type of __in_chrg is `const const int'). */ TREE_READONLY (parm) = 1; -#endif - DECL_ARG_TYPE (parm) = const_integer_type; + DECL_ARG_TYPE (parm) = integer_type_node; /* This is the same chain as DECL_ARGUMENTS (...). */ TREE_CHAIN (last_function_parms) = parm; @@ -2030,7 +2029,7 @@ constructor_name_full (thing) if (IS_AGGR_TYPE_CODE (TREE_CODE (thing))) { if (TYPE_WAS_ANONYMOUS (thing) && TYPE_HAS_CONSTRUCTOR (thing)) - thing = DECL_NAME (TREE_VEC_ELT (TYPE_METHODS (thing), 0)); + thing = DECL_NAME (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (thing), 0)); else thing = TYPE_NAME (thing); } @@ -2479,6 +2478,8 @@ coerce_delete_type (type) return type; } +extern tree abort_fndecl; + static void mark_vtable_entries (decl) tree decl; @@ -2489,16 +2490,12 @@ mark_vtable_entries (decl) for (; entries; entries = TREE_CHAIN (entries)) { - tree fnaddr = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries)); + tree fnaddr = (flag_vtable_thunks ? TREE_VALUE (entries) + : FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries))); tree fn = TREE_OPERAND (fnaddr, 0); TREE_ADDRESSABLE (fn) = 1; - if (DECL_ABSTRACT_VIRTUAL_P (fn)) - { - extern tree abort_fndecl; - if (flag_vtable_thunks) - fnaddr = TREE_VALUE (entries); - TREE_OPERAND (fnaddr, 0) = fn = abort_fndecl; - } + if (DECL_LANG_SPECIFIC (fn) && DECL_ABSTRACT_VIRTUAL_P (fn)) + TREE_OPERAND (fnaddr, 0) = fn = abort_fndecl; assemble_external (fn); } } @@ -2541,8 +2538,8 @@ import_export_vtable (decl, type, final) if (! found && ! final) { tree method; - for (method = CLASSTYPE_METHODS (type); method != NULL_TREE; - method = DECL_NEXT_METHOD (method)) + for (method = TYPE_METHODS (type); method != NULL_TREE; + method = TREE_CHAIN (method)) if (DECL_VINDEX (method) != NULL_TREE && ! DECL_THIS_INLINE (method) && ! DECL_ABSTRACT_VIRTUAL_P (method)) @@ -2558,7 +2555,7 @@ import_export_vtable (decl, type, final) if (TREE_PUBLIC (decl)) cp_error ("all virtual functions redeclared inline"); #endif - if (SUPPORTS_WEAK) + if (flag_weak) DECL_WEAK (decl) = 1; else TREE_PUBLIC (decl) = 0; @@ -2597,8 +2594,8 @@ finish_prevtable_vardecl (prev, vars) && ! CLASSTYPE_TEMPLATE_INSTANTIATION (ctype)) { tree method; - for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE; - method = DECL_NEXT_METHOD (method)) + for (method = TYPE_METHODS (ctype); method != NULL_TREE; + method = TREE_CHAIN (method)) { if (DECL_VINDEX (method) != NULL_TREE && !DECL_THIS_INLINE (method) @@ -2782,7 +2779,7 @@ import_export_inline (decl) { if (DECL_IMPLICIT_INSTANTIATION (decl) && flag_implicit_templates) { - if (SUPPORTS_WEAK) + if (flag_weak) DECL_WEAK (decl) = 1; else TREE_PUBLIC (decl) = 0; @@ -2799,14 +2796,14 @@ import_export_inline (decl) = ! (CLASSTYPE_INTERFACE_ONLY (ctype) || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines)); } - else if (SUPPORTS_WEAK) + else if (flag_weak) DECL_WEAK (decl) = 1; else TREE_PUBLIC (decl) = 0; } else if (DECL_C_STATIC (decl)) TREE_PUBLIC (decl) = 0; - else if (SUPPORTS_WEAK) + else if (flag_weak) DECL_WEAK (decl) = 1; else TREE_PUBLIC (decl) = 0; @@ -2814,6 +2811,26 @@ import_export_inline (decl) DECL_INTERFACE_KNOWN (decl) = 1; } +tree +build_cleanup (decl) + tree decl; +{ + tree temp; + tree type = TREE_TYPE (decl); + + if (TREE_CODE (type) == ARRAY_TYPE) + temp = decl; + else + { + mark_addressable (decl); + temp = build1 (ADDR_EXPR, build_pointer_type (type), decl); + } + temp = build_delete (TREE_TYPE (temp), temp, + integer_two_node, + LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0); + return temp; +} + extern int parse_time, varconst_time; #define TIMEVAR(VAR, BODY) \ @@ -2895,14 +2912,12 @@ finish_file () { tree decl = TREE_VALUE (vars); tree type = TREE_TYPE (decl); - if (TYPE_NEEDS_DESTRUCTOR (type)) + if (TYPE_NEEDS_DESTRUCTOR (type) && ! TREE_STATIC (vars)) { needs_cleaning = 1; - needs_messing_up = 1; break; } - else - needs_messing_up |= TYPE_NEEDS_CONSTRUCTING (type); + vars = TREE_CHAIN (vars); } @@ -2930,23 +2945,10 @@ finish_file () tree type = TREE_TYPE (decl); tree temp = TREE_PURPOSE (vars); - if (TYPE_NEEDS_DESTRUCTOR (type)) + if (TYPE_NEEDS_DESTRUCTOR (type) && ! TREE_STATIC (vars)) { - if (TREE_STATIC (vars)) - expand_start_cond (build_binary_op (NE_EXPR, temp, integer_zero_node, 1), 0); - if (TREE_CODE (type) == ARRAY_TYPE) - temp = decl; - else - { - mark_addressable (decl); - temp = build1 (ADDR_EXPR, build_pointer_type (type), decl); - } - temp = build_delete (TREE_TYPE (temp), temp, - integer_two_node, LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0); + temp = build_cleanup (decl); expand_expr_stmt (temp); - - if (TREE_STATIC (vars)) - expand_end_cond (); } } @@ -2987,9 +2989,15 @@ finish_file () while (vars) { + extern int temp_slot_level; + extern int target_temp_slot_level; tree decl = TREE_VALUE (vars); tree init = TREE_PURPOSE (vars); tree old_cleanups = cleanups_this_call; + int old_temp_level = target_temp_slot_level; + push_temp_slots (); + push_temp_slots (); + target_temp_slot_level = temp_slot_level; /* If this was a static attribute within some function's scope, then don't initialize it here. Also, don't bother @@ -3024,7 +3032,6 @@ finish_file () TREE_VEC_ELT (init, 1), TREE_VEC_ELT (init, 2), 0), const0_rtx, VOIDmode, 0); - free_temp_slots (); } else expand_assignment (decl, init, 0, 0); @@ -3037,14 +3044,12 @@ finish_file () { /* a `new' expression at top level. */ expand_expr (decl, const0_rtx, VOIDmode, 0); - free_temp_slots (); if (TREE_CODE (init) == TREE_VEC) { expand_expr (expand_vec_init (decl, TREE_VEC_ELT (init, 0), TREE_VEC_ELT (init, 1), TREE_VEC_ELT (init, 2), 0), const0_rtx, VOIDmode, 0); - free_temp_slots (); } else expand_aggr_init (build_indirect_ref (decl, NULL_PTR), init, 0, 0); @@ -3053,9 +3058,14 @@ finish_file () else if (decl == error_mark_node) ; else my_friendly_abort (22); - vars = TREE_CHAIN (vars); + /* Cleanup any temporaries needed for the initial value. */ expand_cleanups_to (old_cleanups); + pop_temp_slots (); + pop_temp_slots (); + target_temp_slot_level = old_temp_level; + + vars = TREE_CHAIN (vars); } for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors)) @@ -3509,3 +3519,11 @@ check_default_args (x) } } } + +void +mark_used (decl) + tree decl; +{ + TREE_USED (decl) = 1; + assemble_external (decl); +} diff --git a/gcc/cp/errfn.c b/gcc/cp/errfn.c index f36b0e1..4da07fa 100644 --- a/gcc/cp/errfn.c +++ b/gcc/cp/errfn.c @@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA. */ #include "config.h" #include "tree.h" +#include <stdio.h> #include <ctype.h> /* cp_printer is the type of a function which converts an argument into @@ -195,8 +196,7 @@ cp_sprintf (format, arglist) char *format; arglist_dcl { - extern errorfn sprintf; - cp_thing (sprintf, 0, format, arglist); + cp_thing ((errorfn *) sprintf, 0, format, arglist); } void diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 4eb196e..c6653e7 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -950,12 +950,12 @@ dump_expr (t, nop) } else if (type == boolean_type_node) { - if (t == boolean_false_node) + if (t == boolean_false_node + || (TREE_INT_CST_LOW (t) == 0 + && TREE_INT_CST_HIGH (t) == 0)) OB_PUTS ("false"); else if (t == boolean_true_node) OB_PUTS ("true"); - else - my_friendly_abort (366); } else if (type == char_type_node) { diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 51577f8..88587f0 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -264,6 +264,8 @@ static tree Unwind; /* holds a ready to emit call to "terminate ()". */ static tree TerminateFunctionCall; +static tree empty_fndecl; + /* ====================================================================== */ @@ -275,7 +277,10 @@ static tree TerminateFunctionCall; /* =================================================================== */ struct labelNode { - rtx label; + union { + rtx rlabel; + tree tlabel; + } u; struct labelNode *chain; }; @@ -319,6 +324,8 @@ tree saved_pc; tree saved_throw_type; /* Holds the value being thrown. */ tree saved_throw_value; +/* Holds the cleanup for the value being thrown. */ +tree saved_cleanup; int throw_used; @@ -339,9 +346,9 @@ static rtx push_eh_entry PROTO((struct ehStack *stack)); static struct ehEntry *dequeue_eh_entry PROTO((struct ehQueue *queue)); static void new_eh_queue PROTO((struct ehQueue *queue)); static void new_eh_stack PROTO((struct ehStack *stack)); -static void push_label_entry PROTO((struct labelNode **labelstack, rtx label)); +static void push_label_entry PROTO((struct labelNode **labelstack, rtx rlabel, tree tlabel)); static rtx pop_label_entry PROTO((struct labelNode **labelstack)); -static rtx top_label_entry PROTO((struct labelNode **labelstack)); +static tree top_label_entry PROTO((struct labelNode **labelstack)); static struct ehEntry *copy_eh_entry PROTO((struct ehEntry *entry)); @@ -351,13 +358,17 @@ static struct ehEntry *copy_eh_entry PROTO((struct ehEntry *entry)); ========================================================================= */ static void -push_label_entry (labelstack, label) +push_label_entry (labelstack, rlabel, tlabel) struct labelNode **labelstack; - rtx label; + rtx rlabel; + tree tlabel; { struct labelNode *newnode=(struct labelNode*)xmalloc (sizeof (struct labelNode)); - newnode->label = label; + if (rlabel) + newnode->u.rlabel = rlabel; + else + newnode->u.tlabel = tlabel; newnode->chain = *labelstack; *labelstack = newnode; } @@ -372,20 +383,20 @@ pop_label_entry (labelstack) if (! *labelstack) return NULL_RTX; tempnode = *labelstack; - label = tempnode->label; + label = tempnode->u.rlabel; *labelstack = (*labelstack)->chain; free (tempnode); return label; } -static rtx +static tree top_label_entry (labelstack) struct labelNode **labelstack; { - if (! *labelstack) return NULL_RTX; + if (! *labelstack) return NULL_TREE; - return (*labelstack)->label; + return (*labelstack)->u.tlabel; } /* Push to permanent obstack for rtl generation. @@ -623,41 +634,39 @@ init_exception_processing () push_lang_context (lang_name_c); catch_match_fndecl = - define_function (flag_rtti - ? "__throw_type_match_rtti" - : "__throw_type_match", - build_function_type (ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - void_list_node)))), - NOT_BUILT_IN, - pushdecl, - 0); + builtin_function (flag_rtti + ? "__throw_type_match_rtti" + : "__throw_type_match", + build_function_type (ptr_type_node, + tree_cons (NULL_TREE, ptr_type_node, + tree_cons (NULL_TREE, ptr_type_node, + tree_cons (NULL_TREE, ptr_type_node, + void_list_node)))), + NOT_BUILT_IN, NULL_PTR); find_first_exception_match_fndecl = - define_function ("__find_first_exception_table_match", - build_function_type (ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - void_list_node)), - NOT_BUILT_IN, - pushdecl, - 0); + builtin_function ("__find_first_exception_table_match", + build_function_type (ptr_type_node, + tree_cons (NULL_TREE, ptr_type_node, + void_list_node)), + NOT_BUILT_IN, NULL_PTR); unwind_fndecl = - define_function ("__unwind_function", - build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - void_list_node)), - NOT_BUILT_IN, - pushdecl, - 0); + builtin_function ("__unwind_function", + build_function_type (void_type_node, + tree_cons (NULL_TREE, ptr_type_node, + void_list_node)), + NOT_BUILT_IN, NULL_PTR); throw_fndecl = - define_function ("__throw", - build_function_type (void_type_node, void_list_node), - NOT_BUILT_IN, - pushdecl, - 0); + builtin_function ("__throw", + build_function_type (void_type_node, void_list_node), + NOT_BUILT_IN, NULL_PTR); DECL_EXTERNAL (throw_fndecl) = 0; TREE_PUBLIC (throw_fndecl) = 0; + empty_fndecl = + builtin_function ("__empty", + build_function_type (void_type_node, void_list_node), + NOT_BUILT_IN, NULL_PTR); + DECL_EXTERNAL (empty_fndecl) = 1; + TREE_PUBLIC (empty_fndecl) = 1; Unexpected = default_conversion (unexpected_fndecl); Terminate = default_conversion (terminate_fndecl); @@ -697,6 +706,14 @@ init_exception_processing () DECL_COMMON (d) = 1; cp_finish_decl (d, NULL_TREE, NULL_TREE, 0, 0); saved_throw_value = lookup_name (get_identifier ("__eh_value"), 0); + + declspecs = tree_cons (NULL_TREE, get_identifier ("void"), NULL_TREE); + d = build_parse_node (INDIRECT_REF, get_identifier ("__eh_cleanup")); + d = build_parse_node (CALL_EXPR, d, void_list_node, NULL_TREE); + d = start_decl (d, declspecs, 0, NULL_TREE); + DECL_COMMON (d) = 1; + cp_finish_decl (d, NULL_TREE, NULL_TREE, 0, 0); + saved_cleanup = lookup_name (get_identifier ("__eh_cleanup"), 0); } /* call this to begin a block of unwind protection (ie: when an object is @@ -759,17 +776,17 @@ void expand_start_all_catch () { struct ehEntry *entry; - rtx label; + tree label; if (! doing_eh (1)) return; emit_line_note (input_filename, lineno); - label = gen_label_rtx (); + label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); /* The label for the exception handling block we will save. This is Lresume, in the documention. */ - emit_label (label); + expand_label (label); /* Put in something that takes up space, as otherwise the end address for the EH region could have the exact same address as @@ -778,7 +795,7 @@ expand_start_all_catch () region. */ emit_insn (gen_nop ()); - push_label_entry (&caught_return_label_stack, label); + push_label_entry (&caught_return_label_stack, NULL_RTX, label); /* Start a new sequence for all the catch blocks. We will add this to the gloabl sequence catch_clauses, when we have completed all @@ -821,7 +838,7 @@ expand_end_all_catch () documentation. */ expand_internal_throw (gen_rtx (LABEL_REF, Pmode, - top_label_entry (&caught_return_label_stack))); + DECL_RTL (top_label_entry (&caught_return_label_stack)))); /* Now we have the complete catch sequence. */ new_catch_clause = get_insns (); @@ -884,6 +901,21 @@ build_eh_type (exp) return build_eh_type_type (TREE_TYPE (exp)); } +/* This routine creates the cleanup for the exception handling object. */ +void +push_eh_cleanup () +{ + /* All cleanups must last longer than normal. */ + int yes = suspend_momentary (); + + /* Arrange to do a dynamically scoped cleanup upon exit from this region. */ + tree cleanup = build_function_call (saved_cleanup, NULL_TREE); + cp_expand_decl_cleanup (NULL_TREE, cleanup); + + resume_momentary (yes); +} + + /* call this to start a catch block. Typename is the typename, and identifier is the variable to place the object in or NULL if the variable doesn't matter. If typename is NULL, that means its a "catch (...)" or catch @@ -897,6 +929,7 @@ expand_start_catch_block (declspecs, declarator) rtx protect_label_rtx; tree decl = NULL_TREE; tree init; + tree cleanup; if (! doing_eh (1)) return; @@ -909,8 +942,8 @@ expand_start_catch_block (declspecs, declarator) push_rtl_perm (); protect_label_rtx = gen_label_rtx (); pop_rtl_from_perm (); - push_label_entry (&false_label_stack, false_label_rtx); - push_label_entry (&false_label_stack, protect_label_rtx); + push_label_entry (&false_label_stack, false_label_rtx, NULL_TREE); + push_label_entry (&false_label_stack, protect_label_rtx, NULL_TREE); if (declspecs) { @@ -952,6 +985,8 @@ expand_start_catch_block (declspecs, declarator) /* if it returned FALSE, jump over the catch block, else fall into it */ emit_jump_insn (gen_beq (false_label_rtx)); + push_eh_cleanup (); + init = convert_from_reference (save_expr (make_tree (init_type, call_rtx))); /* Do we need the below two lines? */ @@ -962,6 +997,8 @@ expand_start_catch_block (declspecs, declarator) } else { + push_eh_cleanup (); + /* Fall into the catch all section. */ } @@ -1024,7 +1061,7 @@ void expand_end_catch_block () /* fall to outside the try statement when done executing handler and we fall off end of handler. This is jump Lresume in the documentation. */ - emit_jump (top_label_entry (&caught_return_label_stack)); + expand_goto (top_label_entry (&caught_return_label_stack)); /* We end the rethrow protection region as soon as we hit a label. */ end_protect_label_rtx = expand_leftover_cleanups (); @@ -1039,7 +1076,7 @@ void expand_end_catch_block () emit_label (entry.exception_handler_label); expand_internal_throw (gen_rtx (LABEL_REF, Pmode, - top_label_entry (&caught_return_label_stack))); + DECL_RTL (top_label_entry (&caught_return_label_stack)))); /* No associated finalization. */ entry.finalization = NULL_TREE; @@ -1487,6 +1524,51 @@ expand_exception_blocks () emit_insns (insns); } +tree +start_anon_func () +{ + static int counter = 0; + char name[32]; + tree params; + tree t; + + push_cp_function_context (NULL_TREE); + push_to_top_level (); + + /* No need to mangle this. */ + push_lang_context (lang_name_c); + + params = void_list_node; + /* tcf stands for throw clean funciton. */ + sprintf (name, "__tcf_%d", counter++); + t = build_parse_node (CALL_EXPR, get_identifier (name), params, NULL_TREE); + start_function (decl_tree_cons (NULL_TREE, get_identifier ("static"), + void_list_node), + t, NULL_TREE, NULL_TREE, 0); + store_parm_decls (); + pushlevel (0); + clear_last_expr (); + push_momentary (); + expand_start_bindings (0); + emit_line_note (input_filename, lineno); + + pop_lang_context (); + + return current_function_decl; +} + +void +end_anon_func () +{ + expand_end_bindings (getdecls(), 1, 0); + poplevel (1, 0, 0); + pop_momentary (); + + finish_function (lineno, 0, 0); + + pop_from_top_level (); + pop_cp_function_context (NULL_TREE); +} /* call this to expand a throw statement. This follows the following algorithm: @@ -1515,7 +1597,7 @@ expand_throw (exp) if (exp) { tree throw_type; - tree e; + tree cleanup = empty_fndecl, e; /* throw expression */ /* First, decay it. */ @@ -1528,6 +1610,8 @@ expand_throw (exp) } else { + rtx cleanup_insns; + tree object; /* Make a copy of the thrown object. WP 15.1.5 */ exp = build_new (NULL_TREE, TREE_TYPE (exp), build_tree_list (NULL_TREE, exp), @@ -1536,14 +1620,44 @@ expand_throw (exp) if (exp == error_mark_node) error (" in thrown expression"); - throw_type = build_eh_type (build_indirect_ref (exp, NULL_PTR)); + object = build_indirect_ref (exp, NULL_PTR); + throw_type = build_eh_type (object); + + start_sequence (); + object = build_reinterpret_cast (TREE_TYPE (exp), saved_throw_value); + object = build_indirect_ref (object, NULL_PTR); + cleanup = maybe_build_cleanup (object); + if (cleanup) + expand_expr (cleanup, const0_rtx, VOIDmode, 0); + cleanup_insns = get_insns (); + end_sequence (); + + if (cleanup && cleanup_insns) + { + cleanup = start_anon_func (); + + expand_expr (maybe_build_cleanup (object), const0_rtx, VOIDmode, 0); + + end_anon_func (); + + mark_addressable (cleanup); + } + else + { + cleanup = empty_fndecl; + } } e = build_modify_expr (saved_throw_type, NOP_EXPR, throw_type); expand_expr (e, const0_rtx, VOIDmode, 0); + e = build_modify_expr (saved_throw_value, NOP_EXPR, exp); e = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (e), e); expand_expr (e, const0_rtx, VOIDmode, 0); + + cleanup = build_unary_op (ADDR_EXPR, cleanup, 0); + cleanup = build_modify_expr (saved_cleanup, NOP_EXPR, cleanup); + expand_expr (cleanup, const0_rtx, VOIDmode, 0); } else { diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 9752a9b..2c795bb 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -43,6 +43,8 @@ Boston, MA 02111-1307, USA. */ line. Perhaps this was not intended. */ tree current_base_init_list, current_member_init_list; +extern tree cleanups_this_call; + void emit_base_init (); void check_base_init (); static void expand_aggr_vbase_init (); @@ -160,6 +162,13 @@ perform_member_init (member, name, init, explicit, protect_list) { tree decl; tree type = TREE_TYPE (member); + extern int temp_slot_level; + extern int target_temp_slot_level; + tree old_cleanups = cleanups_this_call; + int old_temp_level = target_temp_slot_level; + push_temp_slots (); + push_temp_slots (); + target_temp_slot_level = temp_slot_level; if (TYPE_NEEDS_CONSTRUCTING (type) || (init && TYPE_HAS_CONSTRUCTOR (type))) @@ -219,7 +228,16 @@ perform_member_init (member, name, init, explicit, protect_list) expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init)); } } - expand_cleanups_to (NULL_TREE); + expand_cleanups_to (old_cleanups); + pop_temp_slots (); + pop_temp_slots (); + target_temp_slot_level = old_temp_level; + /* There might something left from building the trees. */ + if (cleanups_this_call) + { + expand_cleanups_to (NULL_TREE); + } + free_temp_slots (); if (TYPE_NEEDS_DESTRUCTOR (type)) { @@ -577,11 +595,28 @@ emit_base_init (t, immediately) if (init != void_list_node) { + extern int temp_slot_level; + extern int target_temp_slot_level; + tree old_cleanups = cleanups_this_call; + int old_temp_level = target_temp_slot_level; + push_temp_slots (); + push_temp_slots (); + target_temp_slot_level = temp_slot_level; + member = convert_pointer_to_real (base_binfo, current_class_decl); expand_aggr_init_1 (base_binfo, 0, build_indirect_ref (member, NULL_PTR), init, BINFO_OFFSET_ZEROP (base_binfo), LOOKUP_NORMAL); - expand_cleanups_to (NULL_TREE); + expand_cleanups_to (old_cleanups); + pop_temp_slots (); + pop_temp_slots (); + target_temp_slot_level = old_temp_level; + /* There might something left from building the trees. */ + if (cleanups_this_call) + { + expand_cleanups_to (NULL_TREE); + } + free_temp_slots (); } if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))) @@ -749,11 +784,30 @@ expand_aggr_vbase_init_1 (binfo, exp, addr, init_list) { tree init = purpose_member (binfo, init_list); tree ref = build_indirect_ref (addr, NULL_PTR); + + extern int temp_slot_level; + extern int target_temp_slot_level; + tree old_cleanups = cleanups_this_call; + int old_temp_level = target_temp_slot_level; + push_temp_slots (); + push_temp_slots (); + target_temp_slot_level = temp_slot_level; + if (init) init = TREE_VALUE (init); /* Call constructors, but don't set up vtables. */ expand_aggr_init_1 (binfo, exp, ref, init, 0, LOOKUP_COMPLAIN); - expand_cleanups_to (NULL_TREE); + + expand_cleanups_to (old_cleanups); + pop_temp_slots (); + pop_temp_slots (); + target_temp_slot_level = old_temp_level; + /* There might something left from building the trees. */ + if (cleanups_this_call) + { + expand_cleanups_to (NULL_TREE); + } + free_temp_slots (); } /* Initialize this object's virtual base class pointers. This must be @@ -818,8 +872,7 @@ do_member_init (s_id, name, init) /* Function to give error message if member initialization specification is erroneous. FIELD is the member we decided to initialize. TYPE is the type for which the initialization is being performed. - FIELD must be a member of TYPE, or the base type from which FIELD - comes must not need a constructor. + FIELD must be a member of TYPE. MEMBER_NAME is the name of the member. */ @@ -831,23 +884,12 @@ member_init_ok_or_else (field, type, member_name) { if (field == error_mark_node) return 0; - if (field == NULL_TREE) + if (field == NULL_TREE || DECL_CONTEXT (field) != type) { cp_error ("class `%T' does not have any field named `%s'", type, member_name); return 0; } - if (DECL_CONTEXT (field) != type - && TYPE_NEEDS_CONSTRUCTING (DECL_CONTEXT (field))) - { - if (current_function_decl && DECL_CONSTRUCTOR_P (current_function_decl)) - cp_error ("initialization of `%D' inside constructor for `%T'", - field, type); - else - cp_error ("member `%D' comes from base class needing constructor", - field); - return 0; - } if (TREE_STATIC (field)) { cp_error ("field `%#D' is static; only point of initialization is its declaration", @@ -960,6 +1002,12 @@ expand_member_init (exp, name, init) return; } + if (warn_reorder && current_member_init_list) + { + warning ("base initializer for `%s'", IDENTIFIER_POINTER (name)); + warning (" will be re-ordered to precede member initializations"); + } + base_init = build_tree_list (name, init); TREE_TYPE (base_init) = basetype; current_base_init_list = chainon (current_base_init_list, base_init); @@ -1354,12 +1402,15 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags) } else { +#if 0 + /* This causes testcase return2.C to fail. */ init = TREE_OPERAND (init, 1); init = build (CALL_EXPR, init_type, TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), 0); TREE_SIDE_EFFECTS (init) = 1; if (init_list) TREE_VALUE (init_list) = init; +#endif } } @@ -1508,7 +1559,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags) cp_error ("ambiguity between conversion to `%T' and constructor", type); else - expand_assignment (exp, rval, 0, 0); + expand_aggr_init_1 (binfo, true_exp, exp, rval, alias_this, flags); return; } } @@ -1920,7 +1971,7 @@ build_offset_ref (cname, name) if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == CONST_DECL) { - TREE_USED (t) = 1; + mark_used (t); return t; } if (TREE_CODE (t) == FIELD_DECL) @@ -2010,7 +2061,7 @@ build_offset_ref (cname, name) error ("in this context"); return error_mark_node; } - assemble_external (t); + mark_used (t); return build (OFFSET_REF, TREE_TYPE (t), decl, t); } @@ -2037,8 +2088,10 @@ build_offset_ref (cname, name) || ! allocation_temporary_p ())) fnfields = copy_list (fnfields); +#if 0 for (t = TREE_VALUE (fnfields); t; t = DECL_CHAIN (t)) assemble_external (t); +#endif t = build_tree_list (error_mark_node, fnfields); TREE_TYPE (t) = build_offset_type (type, unknown_type_node); @@ -2070,8 +2123,7 @@ build_offset_ref (cname, name) values can be returned without further ado. */ if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == CONST_DECL) { - assemble_external (t); - TREE_USED (t) = 1; + mark_used (t); return t; } diff --git a/gcc/cp/lang-options.h b/gcc/cp/lang-options.h index d551357..2766c1b 100644 --- a/gcc/cp/lang-options.h +++ b/gcc/cp/lang-options.h @@ -86,6 +86,8 @@ Boston, MA 02111-1307, USA. */ "-fno-this-is-variable", "-fvtable-thunks", "-fno-vtable-thunks", + "-fweak", + "-fno-weak", "-fxref", "-fno-xref", diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 1861f9e..7795933 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -883,13 +883,16 @@ yyprint (file, yychar, yylval) static int *reduce_count; int *token_count; +#if 0 #define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0])) #define TOKEN_LENGTH (256 + sizeof (yytname) / sizeof (yytname[0])) +#endif int * init_parse () { #ifdef GATHER_STATISTICS +#ifdef REDUCE_LENGTH reduce_count = (int *)malloc (sizeof (int) * (REDUCE_LENGTH + 1)); bzero (reduce_count, sizeof (int) * (REDUCE_LENGTH + 1)); reduce_count += 1; @@ -897,10 +900,12 @@ init_parse () bzero (token_count, sizeof (int) * (TOKEN_LENGTH + 1)); token_count += 1; #endif +#endif return token_count; } #ifdef GATHER_STATISTICS +#ifdef REDUCE_LENGTH void yyhook (yyn) int yyn; @@ -922,11 +927,13 @@ token_cmp (p, q) return token_count[*q] - token_count[*p]; } #endif +#endif void print_parse_statistics () { #ifdef GATHER_STATISTICS +#ifdef REDUCE_LENGTH #if YYDEBUG != 0 int i; int maxlen = REDUCE_LENGTH; @@ -969,6 +976,7 @@ print_parse_statistics () fprintf (stderr, "\n"); #endif #endif +#endif } /* Sets the value of the 'yydebug' variable to VALUE. @@ -2590,6 +2598,10 @@ linenum: p->name = input_filename; input_file_stack = p; input_file_stack_tick++; +#ifdef DBX_DEBUGGING_INFO + if (write_symbols == DBX_DEBUG) + dbxout_start_new_source_file (input_filename); +#endif #ifdef DWARF_DEBUGGING_INFO if (debug_info_level == DINFO_LEVEL_VERBOSE && write_symbols == DWARF_DEBUG) @@ -2627,6 +2639,10 @@ linenum: input_file_stack = p->next; free (p); input_file_stack_tick++; +#ifdef DBX_DEBUGGING_INFO + if (write_symbols == DBX_DEBUG) + dbxout_resume_previous_source_file (); +#endif #ifdef DWARF_DEBUGGING_INFO if (debug_info_level == DINFO_LEVEL_VERBOSE && write_symbols == DWARF_DEBUG) @@ -2872,6 +2888,9 @@ do_identifier (token) { register tree id = lastiddecl; + if (IDENTIFIER_OPNAME_P (token)) + id = lookup_name (token, 0); + if (yychar == YYEMPTY) yychar = yylex (); /* Scope class declarations before global @@ -2920,7 +2939,14 @@ do_identifier (token) if (id && id != error_mark_node && TREE_TYPE (id) == error_mark_node) return id; } - if (yychar == '(' || yychar == LEFT_RIGHT) + + if (IDENTIFIER_OPNAME_P (token)) + { + if (token != ansi_opname[ERROR_MARK]) + cp_error ("operator %O not defined", token); + id = error_mark_node; + } + else if (yychar == '(' || yychar == LEFT_RIGHT) { id = implicitly_declare (token); } @@ -4360,8 +4386,10 @@ real_yylex () done: /* yylloc.last_line = lineno; */ #ifdef GATHER_STATISTICS +#ifdef REDUCE_LENGTH token_count[value] += 1; #endif +#endif return value; } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index a0e1527..d50ea90 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -178,8 +178,13 @@ report_type_mismatch (cp, parmtypes, name_kind) /* Happens when the implicit object parameter is rejected. */ my_friendly_assert (! TYPE_READONLY (TREE_TYPE (TREE_VALUE (parmtypes))), 241); - cp_error ("call to non-const %s `%#D' with const object", - name_kind, cp->function); + if (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (TREE_VALUE (parmtypes)))) + && ! TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (cp->function)))))) + cp_error ("call to non-volatile %s `%#D' with volatile object", + name_kind, cp->function); + else + cp_error ("call to non-const %s `%#D' with const object", + name_kind, cp->function); return; } @@ -1547,6 +1552,7 @@ hack_identifier (value, name, yychar) if (really_overloaded_fn (value)) { +#if 0 tree t = get_first_fn (value); for (; t; t = DECL_CHAIN (t)) { @@ -1556,22 +1562,20 @@ hack_identifier (value, name, yychar) assemble_external (t); TREE_USED (t) = 1; } +#endif } else if (TREE_CODE (value) == TREE_LIST) { + /* Ambiguous reference to base members, possibly other cases?. */ tree t = value; while (t && TREE_CODE (t) == TREE_LIST) { - assemble_external (TREE_VALUE (t)); - TREE_USED (t) = 1; + mark_used (TREE_VALUE (t)); t = TREE_CHAIN (t); } } else - { - assemble_external (value); - TREE_USED (value) = 1; - } + mark_used (value); if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && DECL_NONLOCAL (value)) { @@ -1800,14 +1804,17 @@ make_thunk (function, delta) } if (thunk == NULL_TREE) { - thunk = build_decl (THUNK_DECL, thunk_id, TREE_TYPE (func_decl)); + thunk = build_decl (FUNCTION_DECL, thunk_id, TREE_TYPE (func_decl)); DECL_RESULT (thunk) = build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (TREE_TYPE (vtable_entry_type))); TREE_READONLY (thunk) = TYPE_READONLY (TREE_TYPE (vtable_entry_type)); TREE_THIS_VOLATILE (thunk) = TYPE_VOLATILE (TREE_TYPE (vtable_entry_type)); make_function_rtl (thunk); + TREE_SET_CODE (thunk, THUNK_DECL); DECL_INITIAL (thunk) = function; THUNK_DELTA (thunk) = delta; + DECL_EXTERNAL (thunk) = 1; + TREE_PUBLIC (thunk) = 1; /* So that finish_file can write out any thunks that need to be: */ pushdecl_top_level (thunk); } @@ -1845,16 +1852,11 @@ emit_thunk (thunk_fndecl) TREE_ASM_WRITTEN (thunk_fndecl) = 1; - if (TREE_PUBLIC (function)) - { - TREE_PUBLIC (thunk_fndecl) = 1; - if (DECL_EXTERNAL (function)) - { - DECL_EXTERNAL (thunk_fndecl) = 1; - assemble_external (thunk_fndecl); - return; - } - } + if (! TREE_PUBLIC (function)) + TREE_PUBLIC (thunk_fndecl) = 0; + if (DECL_EXTERNAL (function)) + return; + DECL_EXTERNAL (thunk_fndecl) = 0; decl_printable_name = thunk_printable_name; if (current_function_decl) diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index fd034af..d36624a 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -661,8 +661,9 @@ fn.def1: reinit_parse_for_function (); $$ = NULL_TREE; } | declmods notype_declarator exception_specification_opt - { tree specs = strip_attrs ($1); - if (! start_function (specs, $2, $3, NULL_TREE, 0)) + { tree specs, attrs; + split_specs_attrs ($1, &specs, &attrs); + if (! start_function (specs, $2, $3, attrs, 0)) YYERROR1; reinit_parse_for_function (); $$ = NULL_TREE; } @@ -1306,18 +1307,6 @@ primary: { if (TREE_CODE ($$) == BIT_NOT_EXPR) $$ = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND ($$, 0)); - else if (IDENTIFIER_OPNAME_P ($$)) - { - tree op = $$; - $$ = lookup_name (op, 0); - if ($$ == NULL_TREE) - { - if (op != ansi_opname[ERROR_MARK]) - error ("operator %s not defined", - operator_name_string (op)); - $$ = error_mark_node; - } - } else $$ = do_identifier ($$); } @@ -1531,10 +1520,9 @@ primary: else { if (TREE_CODE ($$) == ADDR_EXPR) - assemble_external (TREE_OPERAND ($$, 0)); + mark_used (TREE_OPERAND ($$, 0)); else - assemble_external ($$); - TREE_USED ($$) = 1; + mark_used ($$); } if (TREE_CODE ($$) == CONST_DECL) { @@ -3545,6 +3533,9 @@ for.init.statement: { if ($1) cplus_expand_expr_stmt ($1); } | decl | '{' compstmtend + { if (pedantic) + pedwarn ("ANSI C++ forbids compound statements inside for initializations"); + } ; /* Either a type-qualifier or nothing. First thing in an `asm' statement. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3ce0224..b80bff0 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2400,7 +2400,7 @@ do_pending_expansions () if (i->interface == 1) /* OK, it was an implicit instantiation. */ { - if (SUPPORTS_WEAK) + if (flag_weak) DECL_WEAK (t) = 1; else TREE_PUBLIC (t) = 0; @@ -2533,6 +2533,8 @@ do_function_instantiation (declspecs, declarator, storage) fn = IDENTIFIER_GLOBAL_VALUE (name), fn && DECL_TEMPLATE_INSTANTIATION (fn)) result = fn; + else if (fn && DECL_CONTEXT (fn)) + ; else if (name = DECL_NAME (decl), fn = IDENTIFIER_GLOBAL_VALUE (name), fn) { for (fn = get_first_fn (fn); fn; fn = DECL_CHAIN (fn)) diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 0ac50a1..14b8d01 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -3507,11 +3507,17 @@ static void add_conversions (binfo) tree binfo; { - tree tmp = CLASSTYPE_FIRST_CONVERSION (BINFO_TYPE (binfo)); - for (; tmp && IDENTIFIER_TYPENAME_P (DECL_NAME (tmp)); - tmp = TREE_CHAIN (tmp)) - conversions = tree_cons (DECL_NAME (tmp), TREE_TYPE (TREE_TYPE (tmp)), - conversions); + int i; + tree vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo)); + + for (i = 1; i < TREE_VEC_LENGTH (vec); ++i) + { + tree tmp = TREE_VEC_ELT (vec, i); + if (! IDENTIFIER_TYPENAME_P (DECL_NAME (tmp))) + break; + conversions = tree_cons (DECL_NAME (tmp), TREE_TYPE (TREE_TYPE (tmp)), + conversions); + } } tree diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 9247bf0..3cb6d79 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1766,7 +1766,7 @@ build_component_ref (datum, component, basetype_path, protect) my_friendly_assert (datum != error_mark_node, 310); fndecl = build_vfn_ref (&addr, datum, DECL_VINDEX (fndecl)); } - assemble_external (fndecl); + mark_used (fndecl); return fndecl; } if (access == access_protected) @@ -1781,8 +1781,10 @@ build_component_ref (datum, component, basetype_path, protect) not matter unless we're actually calling the function. */ tree t; +#if 0 for (t = TREE_VALUE (fndecls); t; t = DECL_CHAIN (t)) assemble_external (t); +#endif t = build_tree_list (error_mark_node, fndecls); TREE_TYPE (t) = build_offset_type (basetype, @@ -1809,9 +1811,10 @@ build_component_ref (datum, component, basetype_path, protect) cp_error ("invalid use of type decl `%#D' as expression", field); return error_mark_node; } - if (DECL_RTL (field) != 0) - assemble_external (field); - TREE_USED (field) = 1; + else if (DECL_RTL (field) != 0) + mark_used (field); + else + TREE_USED (field) = 1; return field; } } @@ -2347,7 +2350,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function) /* Save the intermediate result in a SAVE_EXPR so we don't have to compute each component of the virtual function pointer twice. */ - if (/* !building_cleanup && */ TREE_CODE (aref) == INDIRECT_REF) + if (TREE_CODE (aref) == INDIRECT_REF) TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0)); delta = build_binary_op (PLUS_EXPR, @@ -2400,7 +2403,7 @@ build_function_call_real (function, params, require_complete, flags) GNU_xref_call (current_function_decl, IDENTIFIER_POINTER (name ? name : TYPE_IDENTIFIER (DECL_CLASS_CONTEXT (function)))); - assemble_external (function); + mark_used (function); fndecl = function; /* Convert anything with function type to a pointer-to-function. */ @@ -2426,8 +2429,7 @@ build_function_call_real (function, params, require_complete, flags) if (DECL_INLINE (function)) { /* Is it a synthesized method that needs to be synthesized? */ - if (DECL_ARTIFICIAL (function) && ! flag_no_inline - && ! DECL_INITIAL (function) + if (DECL_ARTIFICIAL (function) && ! DECL_INITIAL (function) /* Kludge: don't synthesize for default args. */ && current_function_decl) synthesize_method (function); @@ -2438,11 +2440,7 @@ build_function_call_real (function, params, require_complete, flags) function = build1 (ADDR_EXPR, build_pointer_type (fntype), function); } else - { - assemble_external (function); - TREE_USED (function) = 1; - function = default_conversion (function); - } + function = default_conversion (function); } else { @@ -2718,7 +2716,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags) && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) type = integer_type_node; #endif - parmval = convert_for_initialization (return_loc, type, val, flags, + parmval = convert_for_initialization (return_loc, type, val, + flags|INDIRECT_BIND, "argument passing", fndecl, i); #ifdef PROMOTE_PROTOTYPES if ((TREE_CODE (type) == INTEGER_TYPE @@ -3554,6 +3553,17 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) tree primop0 = get_narrower (op0, &unsignedp0); tree primop1 = get_narrower (op1, &unsignedp1); + /* Check for comparison of different enum types. */ + if (flag_int_enum_equivalence == 0 + && TREE_CODE (TREE_TYPE (orig_op0)) == ENUMERAL_TYPE + && TREE_CODE (TREE_TYPE (orig_op1)) == ENUMERAL_TYPE + && TYPE_MAIN_VARIANT (TREE_TYPE (orig_op0)) + != TYPE_MAIN_VARIANT (TREE_TYPE (orig_op1))) + { + cp_warning ("comparison between `%#T' and `%#T'", + TREE_TYPE (orig_op0), TREE_TYPE (orig_op1)); + } + /* Give warnings for comparisons between signed and unsigned quantities that may fail. */ /* Do the checking based on the original operand trees, so that @@ -4068,7 +4078,7 @@ build_unary_op (code, xarg, noconvert) case FIX_ROUND_EXPR: case FIX_CEIL_EXPR: { - tree incremented, modify, value; + tree incremented, modify, value, compound; if (! lvalue_p (arg) && pedantic) pedwarn ("cast to non-reference type used as lvalue"); arg = stabilize_reference (arg); @@ -4081,8 +4091,13 @@ build_unary_op (code, xarg, noconvert) ? PLUS_EXPR : MINUS_EXPR), argtype, value, inc); TREE_SIDE_EFFECTS (incremented) = 1; + modify = build_modify_expr (arg, NOP_EXPR, incremented); - return build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value); + compound = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value); + + /* Eliminate warning about unused result of + or -. */ + TREE_NO_UNUSED_WARNING (compound) = 1; + return compound; } } @@ -4549,8 +4564,6 @@ mark_addressable (exp) TREE_ADDRESSABLE (x) = 1; TREE_USED (x) = 1; TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1; - if (asm_out_file) - assemble_external (x); return 1; default: @@ -5563,9 +5576,19 @@ tree expand_target_expr (t) tree t; { + extern int temp_slot_level; + extern int target_temp_slot_level; + int old_temp_level = target_temp_slot_level; + tree xval = make_node (RTL_EXPR); rtx rtxval; + /* Any TARGET_EXPR temps live only as long as the outer temp level. + Since they are preserved in this new inner level, we know they + will make it into the outer level. */ + push_temp_slots (); + target_temp_slot_level = temp_slot_level; + do_pending_stack_adjust (); start_sequence_for_rtl_expr (xval); emit_note (0, -1); @@ -5576,6 +5599,10 @@ expand_target_expr (t) end_sequence (); RTL_EXPR_RTL (xval) = rtxval; TREE_TYPE (xval) = TREE_TYPE (t); + + pop_temp_slots (); + target_temp_slot_level = old_temp_level; + return xval; } diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 653d6a5..02ac42d 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -569,8 +569,6 @@ store_init_value (decl, init) if (TREE_CODE (init) == CONSTRUCTOR) { tree field; - tree funcs; - int func; /* Check that we're really an aggregate as ARM 8.4.1 defines it. */ if (CLASSTYPE_N_BASECLASSES (type)) @@ -588,16 +586,11 @@ store_init_value (decl, init) cp_error_at ("initializer list construction invalid for `%D'", decl); cp_error_at ("due to non-public access of member `%D'", field); } - funcs = TYPE_METHODS (type); - if (funcs) - for (func = 0; func < TREE_VEC_LENGTH (funcs); func++) + for (field = TYPE_METHODS (type); field; field = TREE_CHAIN (field)) + if (TREE_PRIVATE (field) || TREE_PROTECTED (field)) { - field = TREE_VEC_ELT (funcs, func); - if (field && (TREE_PRIVATE (field) || TREE_PROTECTED (field))) - { - cp_error_at ("initializer list construction invalid for `%D'", decl); - cp_error_at ("due to non-public access of member `%D'", field); - } + cp_error_at ("initializer list construction invalid for `%D'", decl); + cp_error_at ("due to non-public access of member `%D'", field); } } #endif @@ -894,10 +887,16 @@ digest_init (type, init, tail) return process_init_constructor (type, init, (tree *)0); else if (TYPE_NON_AGGREGATE_CLASS (type)) { +#if 0 + /* This isn't true. */ /* This can only be reached when caller is initializing ARRAY_TYPE. In that case, we don't want to convert INIT to TYPE. We will let `expand_vec_init' do it. */ return init; +#else + return convert_for_initialization (0, type, init, LOOKUP_NORMAL, + "initialization", NULL_TREE, 0); +#endif } else if (tail != 0) { |