diff options
author | Mike Stump <mrs@gcc.gnu.org> | 1994-09-26 20:15:18 +0000 |
---|---|---|
committer | Mike Stump <mrs@gcc.gnu.org> | 1994-09-26 20:15:18 +0000 |
commit | f376e137d46ac34615746a297d8bc1d9f9fd7eca (patch) | |
tree | f9c0f819ae41cf6e844789463888bb2e000eedcd /gcc | |
parent | 96f218bb2aa467606a31c67b3f64c0ac04457f25 (diff) | |
download | gcc-f376e137d46ac34615746a297d8bc1d9f9fd7eca.zip gcc-f376e137d46ac34615746a297d8bc1d9f9fd7eca.tar.gz gcc-f376e137d46ac34615746a297d8bc1d9f9fd7eca.tar.bz2 |
47th Cygnus<->FSF merge
From-SVN: r8129
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 302 | ||||
-rw-r--r-- | gcc/cp/call.c | 32 | ||||
-rw-r--r-- | gcc/cp/class.c | 89 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 11 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 8 | ||||
-rw-r--r-- | gcc/cp/decl.c | 264 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 51 | ||||
-rw-r--r-- | gcc/cp/error.c | 30 | ||||
-rw-r--r-- | gcc/cp/except.c | 94 | ||||
-rw-r--r-- | gcc/cp/init.c | 13 | ||||
-rw-r--r-- | gcc/cp/lex.c | 143 | ||||
-rw-r--r-- | gcc/cp/method.c | 190 | ||||
-rw-r--r-- | gcc/cp/parse.y | 2 | ||||
-rw-r--r-- | gcc/cp/pt.c | 71 | ||||
-rw-r--r-- | gcc/cp/sig.c | 2 | ||||
-rw-r--r-- | gcc/cp/tree.c | 37 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 97 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 7 |
18 files changed, 1009 insertions, 434 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2159ca5..2515e5c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -3,6 +3,308 @@ Wed Sep 14 10:17:27 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> * g++.c: Include <sys/errno.h> in case `errno' is a macro as permitted by ANSI C. +Thu Sep 22 12:53:03 1994 Per Bothner (bothner@kalessin.cygnus.com) + + * decl2.c (finish_file): Fix Brendan's fix: Only call + register_exception_table if there is a non-empty exception table. + +Thu Sep 22 12:03:46 1994 Brendan Kehoe (brendan@lisa.cygnus.com) + + * decl2.c (finish_file): Only do register_exception_table if + -fhandle-exceptions is being used. + +Wed Sep 21 19:01:51 1994 Per Bothner (bothner@kalessin.cygnus.com) + + * except.c (output_exception_table_entry): Simplify + by using assemble_integer. + (build_exception_table): Change to return a count. + Cleanup to use standard macros, instead of hard-wired + sparc asm format. Don't make __EXCEPTION_TABLE__ global. + (register_exception_table): New function. Generate call to builtin. + * decl2.c (finish_file): Call register_exception_table. + * cp-tree.h (build_exception_table): Fix prototype. + +Wed Sep 21 13:20:42 1994 Brendan Kehoe (brendan@lisa.cygnus.com) + + * tree.c (break_out_calls): Don't try to duplicate the DECL_INITIAL. + + * decl2.c (delete_sanity): Give an error at trying to delete a + function. + +Wed Sep 21 11:47:10 1994 Jason Merrill (jason@deneb.cygnus.com) + + * lex.c (cons_up_default_function): Mark synthesized destructors + inline. + + * decl.c (duplicate_decls): Ignore redeclarations of wchar_t as + something other than __wchar_t, complaining if -pedantic and not in + a system header. + +Tue Sep 20 09:43:28 1994 Jason Merrill (jason@deneb.cygnus.com) + + * decl.c (xref_tag): Set up BINFO_INHERITANCE_CHAIN on base binfos + here. + + * typeck.c (build_modify_expr): Require complete type after checking + for error_mark_node. + + * call.c (build_method_call): Print parmtypes when complaining of + ambiguous call. + + * typeck.c (build_modify_expr): Handle assignment to array from + non-array. + + * decl.c (lookup_name_real): Deal with got_scope == error_mark_node. + + * call.c (build_method_call): Don't bother with the exact match. + +Mon Sep 19 00:51:39 1994 Jason Merrill (jason@deneb.cygnus.com) + + * init.c (expand_aggr_init): If we munge the type of the variable, + also munge the type of the initializer. + + * decl.c (grokdeclarator): Use <= when comparing to RID_LAST_MODIFIER. + (init_decl_processing): Push artificial declaration of wchar_t so + people don't have to declare it before they can use it. + + * error.c (cp_line_of): return lineno in lieu of 0. + + * typeck.c (convert_for_assignment): Handle conversion of pmfs to + int and bool. + (build_component_ref): Fold the COMPONENT_REF in case it can be + reduced. + + * typeck2.c (store_init_value): Don't pedwarn about non-constant + bracketed initializers for automatic variables. + +Sun Sep 18 10:12:12 1994 Jason Merrill (jason@deneb.cygnus.com) + + * error.c (dump_decl): Don't say `typedef enum foo foo'. + + * decl.c (start_decl): Don't set TREE_PUBLIC on template decls just + because they're affected by #pragma i/i. We'll deal with that when + they get instantiated. + + * typeck.c (build_unary_op): Clean up cruft in ADDR_EXPR case. + + * class.c (instantiate_type): Set TREE_CONSTANT on instantiated + ADDR_EXPRs if appropriate. + + * decl.c (build_ptrmemfunc_type): Unset IS_AGGR_TYPE on pmf types. + + * typeck.c (build_ptrmemfunc): Handle &overloaded_method as an + initializer properly. + * typeck2.c (digest_init): Ditto. + + * tree.c (cp_build_type_variant): Like c_build_type_variant, except + it uses build_cplus_array_type. + * *.c: Use cp_build_type_variant instead of c_build_type_variant. + + * pt.c (do_type_instantiation): Don't try to instantiate nested + enums. + +Tue Sep 13 10:56:58 1994 Jason Merrill (jason@deneb.cygnus.com) + + * cvt.c (build_up_reference): Handle preincrement and predecrement + properly. + +Tue Sep 13 09:51:59 1994 Brendan Kehoe (brendan@lisa.cygnus.com) + + * decl.c (finish_decl): Only lay out the rtl for DECL if it is, in + fact, static. + +Mon Sep 12 14:40:30 1994 Brendan Kehoe (brendan@lisa.cygnus.com) + + * decl.c (finish_decl): Lay out the rtl for DECL before doing + grok_reference_init, in case it's static. + +Mon Sep 12 12:45:38 1994 Jason Merrill (jason@deneb.cygnus.com) + + * class.c (finish_struct): Don't synthesize constructors if the + class has a field with the same name as the class. Don't die on + classes with no constructors or destructors. Don't die if the head + and tail of the class are in different files. + + * decl.c (grokdeclarator): Don't treat a function pointer field + with the same name as the class as a constructor. + +Fri Sep 9 13:17:00 1994 Jason Merrill (jason@deneb.cygnus.com) + + * typeck.c (build_c_cast): Pull constant values out of their + variables here. + + * decl.c (duplicate_decls): Only propagate DECL_CHAIN in + FUNCTION_DECLs and TEMPLATE_DECLs. + +Thu Sep 8 10:07:48 1994 Jason Merrill (jason@deneb.cygnus.com) + + * decl.c (duplicate_decls): Propagate DECL_CHAIN in all DECLs that + have it. + + * pt.c (unify): REALs and INTEGERs only unify with their own genus. + (instantiate_member_templates): Don't muck with DECL_EXTERNAL and + TREE_PUBLIC unless -fexternal-templates. + +Wed Sep 7 13:17:10 1994 Jason Merrill (jason@deneb.cygnus.com) + + * pt.c (do_type_instantiation): Call instantiate_member_templates. + Deal with specializations. + (tsubst): Don't stick the mangled name in DECL_NAME for function + instantiations. Don't push them, either. + + * decl2.c (grokfield): Move code for generating the + DECL_ASSEMBLER_NAME for static members from here. + * method.c (build_static_name): To here. + * decl.c (grokvardecl): Call build_static_name. + (duplicate_decls): Keep old DECL_ASSEMBLER_NAME. + +Mon Sep 5 12:49:18 1994 Jason Merrill (jason@deneb.cygnus.com) + + * call.c (build_method_call): if -Wsynth, warn when selecting + synthesized op= over user-supplied one cfront would select. + * decl2.c (lang_decode_option): Handle -Wsynth. + +Fri Sep 2 15:11:59 1994 Jason Merrill (jason@deneb.cygnus.com) + + * decl.c (finish_enum): Overhaul to fix several bugs. + (start_enum): Disable useless code. + +Thu Sep 1 16:04:54 1994 Jason Merrill (jason@deneb.cygnus.com) + + * typeck.c (c_expand_return): Warn about returning a reference to a + temporary. + (convert_arguments): Increment argument counter when using default + arguments, too. + +Wed Aug 31 14:29:22 1994 Jason Merrill (jason@deneb.cygnus.com) + + * decl.c (finish_decl): If the type of decl is error_mark_node, + don't bother trying to do anything. + + * typeck.c (convert_for_initialization): If the rhs contains a + constructor call, pretend the lhs type needs to be constructed. + + * init.c (expand_default_init): If we stick the object inside the + initializer, mark the initializer used. + +Tue Aug 30 13:50:18 1994 Jason Merrill (jason@deneb.cygnus.com) + + * method.c (build_assign_ref): return *this; + (build_assign_ref): Fix base assignment order. + (build_copy_constructor): Fix member init order. + +Mon Aug 29 13:54:39 1994 Brendan Kehoe (brendan@lisa.cygnus.com) + + * g++.c (main): Remember to clear out SAW_SPECLANG after we see + its argument. + +Sat Aug 27 09:36:03 1994 Jason Merrill (jason@deneb.cygnus.com) + + * method.c (build_copy_constructor): Also copy virtual bases. + +Fri Aug 26 17:05:15 1994 Jason Merrill (jason@deneb.cygnus.com) + + * lex.c (do_pending_inlines): Clear out pending_inlines before doing + any synthesis. Also first set deja_vu on all pending_inlines. + + * method.c (build_assign_ref): Use build_member_call to invoke base + operator=, rather than build_modify_expr. And use + build_reference_type instead of TYPE_REFERENCE_TO. + (build_copy_constructor): Use TYPE_NESTED_NAME to identify the + basetype. + + * decl2.c (grokfield): Don't complain about undefined local class + methods. + + * class.c (finish_struct): Don't try to synthesize methods here. + * lex.c (do_pending_inlines): Instead, synthesize them here. + (init_lex): Initialize synth_obstack. + (cons_up_default_function): Stick synthesis request on + pending_inlines. + +Fri Aug 26 12:24:14 1994 Brendan Kehoe (brendan@lisa.cygnus.com) + + * call.c (build_method_call) [PCC_STATIC_STRUCT_RETURN]: Also + accept an RTL_EXPR in what we're about to use for the instance, + since anything which would end up with pcc_struct_return set + inside cplus_expand_expr. + + * cp-tree.h (cons_up_default_function): Note change of prototype. + +Thu Aug 25 23:05:30 1994 Gerald Baumgartner (gb@cs.purdue.edu) + + * class.c (finish_struct): Undid change from Aug 21 testing + CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING. + * parse.y (left_curly): Ditto, undid change from Aug 21. + * decl.c (xref_tag): Undid change from Aug 21, set + CLASSTYPE_INTERFACE correctly, and added comments. + +Thu Aug 25 00:36:31 1994 Jason Merrill (jason@deneb.cygnus.com) + + Rework approach to synthesized methods; don't go through the parser + anymore. + * class.c (finish_struct): Use new synthesis approach. + * lex.c (cons_up_default_function): Now just creates declaration, + not code. + (largest_union_member): #if 0 out. + (default_assign_ref_body): Ditto. + (default_copy_constructor_body): Ditto. + * method.c (build_default_constructor): New function to synthesize X(). + (build_copy_constructor): Synthesize X(X&). + (build_assign_ref): Synthesize X::operator=(X&). + (build_dtor): Synthesize ~X(). + + * error.c (cp_line_of): If we're dealing with an artificial + TYPE_DECL, look at the type instead. + +Wed Aug 24 11:11:50 1994 Jason Merrill (jason@deneb.cygnus.com) + + * init.c (sort_member_init): Check warn_reorder. + * decl2.c (lang_decode_option): Handle -W{no-,}reorder. + + * cp-tree.h (CLASSTYPE_SOURCE_LINE): New macro. + * error.c (cp_line_of): Use CLASSTYPE_SOURCE_LINE for aggregates. + * class.c (finish_struct): Set CLASSTYPE_SOURCE_LINE. + +Tue Aug 23 09:28:35 1994 Mike Stump (mrs@cygnus.com) + + * error.c (dump_decl): Improve wording, so that error messages + dont't read template<, class foo>... + +Mon Aug 22 15:30:51 1994 Brendan Kehoe (brendan@lisa.cygnus.com) + + * parse.y (label_colon): Also match a TYPENAME as a label name, + since they may have declared a class by that name but have also + tried to have a local label under the same name. + + * pt.c (coerce_template_parms): Call cp_error, not cp_error_at, + for the message so they know at what point it was instantiated. + +Sun Aug 21 23:07:35 1994 Gerald Baumgartner (gb@cs.purdue.edu) + + * class.c (finish_struct): Move setting of CLASSTYPE_INTERFACE and + CLASSTYPE_VTABLE_NEEDS_WRITING for signatures up to left_curly time. + * decl.c (xref_tag): Move setting of CLASSTYPE_INTERFACE and + CLASSTYPE_VTABLE_NEEDS_WRITING for signatures down to left_curly time. + * parse.y (left_curly): New final resting place for setting + CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING for signatures. + + * class.c (finish_struct): Don't test for function/field name + conflicts in signatures, since all the fields are compiler-constructed. + +Fri Aug 19 14:04:47 1994 Kung Hsu (kung@mexican.cygnus.com) + + * method.c (build_overload_nested_name): in qualified name + mangling, the template with value instantiation will have numeric + at end and may mixed with the name length of next nested level. + Add a '_' in between. + * method.c (build_overload_name): ditto. + * method.c (build_overload_identifier): ditto. + +Thu Aug 18 16:24:43 1994 Mike Stump (mrs@cygnus.com) + + * error.c (dump_decl): Handle NULL args. + Thu Aug 18 12:48:09 1994 Mike Stump (mrs@cygnus.com) * class.c (finish_struct): Move setting of CLASSTYPE_INTERFACE and diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 05e1d50..89921d6 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1814,7 +1814,11 @@ build_method_call (instance, name, parms, basetype_path, flags) } else { - if (TREE_CODE (instance) != CALL_EXPR) + if (TREE_CODE (instance) != CALL_EXPR +#ifdef PCC_STATIC_STRUCT_RETURN + && TREE_CODE (instance) != RTL_EXPR +#endif + ) my_friendly_abort (125); if (TYPE_NEEDS_CONSTRUCTING (basetype)) instance = build_cplus_new (basetype, instance, 0); @@ -1943,7 +1947,9 @@ build_method_call (instance, name, parms, basetype_path, flags) { constp = 0; volatilep = 0; - parms = tree_cons (NULL_TREE, build1 (NOP_EXPR, TYPE_POINTER_TO (basetype), integer_zero_node), parms); + parms = tree_cons (NULL_TREE, + build1 (NOP_EXPR, TYPE_POINTER_TO (basetype), + integer_zero_node), parms); } else { @@ -2023,6 +2029,7 @@ build_method_call (instance, name, parms, basetype_path, flags) return error_mark_node; +#if 0 /* Now, go look for this method name. We do not find destructors here. Putting `void_list_node' on the end of the parmtypes @@ -2032,6 +2039,7 @@ build_method_call (instance, name, parms, basetype_path, flags) 1 + (name == constructor_name (save_basetype) || name == constructor_name_full (save_basetype))); TREE_CHAIN (last) = NULL_TREE; +#endif for (pass = 0; pass < 2; pass++) { @@ -2073,7 +2081,7 @@ build_method_call (instance, name, parms, basetype_path, flags) { tree new_type; parm = build_indirect_ref (parm, "friendifying parms (compiler error)"); - new_type = c_build_type_variant (TREE_TYPE (parm), constp, + new_type = cp_build_type_variant (TREE_TYPE (parm), constp, volatilep); new_type = build_reference_type (new_type); parm = convert (new_type, parm); @@ -2158,9 +2166,11 @@ build_method_call (instance, name, parms, basetype_path, flags) && ! DECL_STATIC_FUNCTION_P (function)) continue; +#if 0 if (pass == 0 && DECL_ASSEMBLER_NAME (function) == method_name) goto found; +#endif if (pass > 0) { @@ -2255,6 +2265,7 @@ build_method_call (instance, name, parms, basetype_path, flags) if (cp - candidates > 1) { int n_candidates = cp - candidates; + extern int warn_synth; TREE_VALUE (parms) = instance_ptr; cp = ideal_candidate (save_basetype, candidates, n_candidates, parms, len); @@ -2262,14 +2273,25 @@ build_method_call (instance, name, parms, basetype_path, flags) { if (flags & LOOKUP_COMPLAIN) { - cp_error ("call of overloaded %s `%D' is ambiguous", - name_kind, name); + TREE_CHAIN (last) = void_list_node; + cp_error ("call of overloaded %s `%D(%A)' is ambiguous", + name_kind, name, TREE_CHAIN (parmtypes)); print_n_candidates (candidates, n_candidates); } return error_mark_node; } if (cp->h.code & EVIL_CODE) return error_mark_node; + if (warn_synth + && DECL_NAME (cp->function) == ansi_opname[MODIFY_EXPR] + && DECL_ARTIFICIAL (cp->function) + && n_candidates == 2) + { + cp_warning ("using synthesized `%#D' for copy assignment", + cp->function); + cp_warning_at (" where cfront would use `%#D'", + candidates->function); + } } else if (cp[-1].h.code & EVIL_CODE) { diff --git a/gcc/cp/class.c b/gcc/cp/class.c index f907d17..e463d84 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2743,6 +2743,7 @@ finish_struct (t, list_of_fieldlists, warn_anon) will fill in the right line number. (mrs) */ if (DECL_SOURCE_LINE (name)) DECL_SOURCE_LINE (name) = lineno; + CLASSTYPE_SOURCE_LINE (t) = lineno; } name = DECL_NAME (name); } @@ -2772,6 +2773,7 @@ finish_struct (t, list_of_fieldlists, warn_anon) TYPE_SIZE (t) = NULL_TREE; CLASSTYPE_GOT_SEMICOLON (t) = 0; +#if 0 /* This is in general too late to do this. I moved the main case up to left_curly, what else needs to move? */ if (! IS_SIGNATURE (t)) @@ -2779,6 +2781,7 @@ finish_struct (t, list_of_fieldlists, warn_anon) my_friendly_assert (CLASSTYPE_INTERFACE_ONLY (t) == interface_only, 999); my_friendly_assert (CLASSTYPE_INTERFACE_KNOWN (t) == ! interface_unknown, 999); } +#endif if (flag_dossier) build_t_desc (t, 0); @@ -2841,6 +2844,7 @@ finish_struct (t, list_of_fieldlists, warn_anon) needs_virtual_dtor = 0; } +#if 0 /* Both of these should be done before now. */ if (write_virtuals == 3 && CLASSTYPE_INTERFACE_KNOWN (t) && ! IS_SIGNATURE (t)) @@ -2848,6 +2852,7 @@ finish_struct (t, list_of_fieldlists, warn_anon) my_friendly_assert (CLASSTYPE_INTERFACE_ONLY (t) == interface_only, 999); my_friendly_assert (CLASSTYPE_VTABLE_NEEDS_WRITING (t) == ! interface_only, 999); } +#endif /* The three of these are approximations which may later be modified. Needed at this point to make add_virtual_function @@ -3004,6 +3009,9 @@ finish_struct (t, list_of_fieldlists, warn_anon) TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x)); } + if (DECL_NAME (x) == constructor_name (t)) + cant_have_default_ctor = cant_synth_copy_ctor = 1; + if (TREE_TYPE (x) == error_mark_node) continue; @@ -3270,12 +3278,14 @@ finish_struct (t, list_of_fieldlists, warn_anon) CLASSTYPE_REF_FIELDS_NEED_INIT (t) = ref_sans_init; CLASSTYPE_ABSTRACT_VIRTUALS (t) = abstract_virtuals; + /* Synthesize any needed methods. Note that methods will be synthesized + for anonymous unions; grok_x_components undoes that. */ + if (TYPE_NEEDS_DESTRUCTOR (t) && !TYPE_HAS_DESTRUCTOR (t) && !IS_SIGNATURE (t)) { /* Here we must cons up a destructor on the fly. */ - tree dtor = cons_up_default_function (t, name, fields, - needs_virtual_dtor != 0); + tree dtor = cons_up_default_function (t, name, needs_virtual_dtor != 0); /* If we couldn't make it work, then pretend we didn't need it. */ if (dtor == void_type_node) @@ -3304,9 +3314,6 @@ finish_struct (t, list_of_fieldlists, warn_anon) TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_HAS_DESTRUCTOR (t); - /* Synthesize any needed methods. Note that methods will be synthesized - for anonymous unions; grok_x_components undoes that. */ - if (! fn_fields) nonprivate_method = 1; @@ -3324,7 +3331,7 @@ finish_struct (t, list_of_fieldlists, warn_anon) if (! TYPE_HAS_CONSTRUCTOR (t) && ! cant_have_default_ctor && ! IS_SIGNATURE (t)) { - tree default_fn = cons_up_default_function (t, name, fields, 2); + tree default_fn = cons_up_default_function (t, name, 2); TREE_CHAIN (default_fn) = fn_fields; fn_fields = default_fn; } @@ -3335,9 +3342,8 @@ finish_struct (t, list_of_fieldlists, warn_anon) { /* ARM 12.18: You get either X(X&) or X(const X&), but not both. --Chip */ - tree default_fn = - cons_up_default_function (t, name, fields, - cant_have_const_ctor ? 4 : 3); + tree default_fn = cons_up_default_function (t, name, + 3 + cant_have_const_ctor); TREE_CHAIN (default_fn) = fn_fields; fn_fields = default_fn; } @@ -3351,9 +3357,8 @@ finish_struct (t, list_of_fieldlists, warn_anon) if (! TYPE_HAS_ASSIGN_REF (t) && ! cant_synth_asn_ref && ! IS_SIGNATURE (t)) { - tree default_fn = - cons_up_default_function (t, name, fields, - no_const_asn_ref ? 6 : 5); + tree default_fn = cons_up_default_function (t, name, + 5 + no_const_asn_ref); TREE_CHAIN (default_fn) = fn_fields; fn_fields = default_fn; } @@ -3404,7 +3409,7 @@ finish_struct (t, list_of_fieldlists, warn_anon) tree flist = NULL_TREE; tree name; enum access_type access = (enum access_type)TREE_PURPOSE(access_decls); - int i = 0; + int i = TREE_VEC_ELT (method_vec, 0) ? 0 : 1; tree tmp; if (TREE_CODE (fdecl) == TREE_LIST) @@ -3512,30 +3517,26 @@ finish_struct (t, list_of_fieldlists, warn_anon) /* Delete all duplicate fields from the fields */ delete_duplicate_fields (fields); - /* Catch function/field name conflict, removing the field (since it's - easier). */ - { - int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0; - tree last = NULL_TREE; - for (x = fields; x; x = TREE_CHAIN (x)) - { - tree name = DECL_NAME (x); - int i; - for (i = 0; i < n_methods; ++i) - if (DECL_NAME (TREE_VEC_ELT (method_vec, i)) == name) - { - cp_error_at ("data member `%#D' conflicts with", x); - cp_error_at ("function member `%#D'", - TREE_VEC_ELT (method_vec, i)); - if (last) - TREE_CHAIN (last) = TREE_CHAIN (x); - else - fields = TREE_CHAIN (x); - break; - } - last = x; - } - } + /* Catch function/field name conflict. We don't need to do this for a + signature, since it can only contain the fields constructed in + append_signature_fields. */ + if (! IS_SIGNATURE (t)) + { + int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0; + for (x = fields; x; x = TREE_CHAIN (x)) + { + tree name = DECL_NAME (x); + int i = /*TREE_VEC_ELT (method_vec, 0) ? 0 : */ 1; + for (; i < n_methods; ++i) + if (DECL_NAME (TREE_VEC_ELT (method_vec, i)) == name) + { + cp_error_at ("data member `%#D' conflicts with", x); + cp_error_at ("function member `%#D'", + TREE_VEC_ELT (method_vec, i)); + break; + } + } + } /* Now we have the final fieldlist for the data fields. Record it, then lay out the structure or union (including the fields). */ @@ -4967,12 +4968,14 @@ instantiate_type (lhstype, rhs, complain) } TREE_TYPE (rhs) = lhstype; lhstype = TREE_TYPE (lhstype); - TREE_OPERAND (rhs, 0) - = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain); - if (TREE_OPERAND (rhs, 0) == error_mark_node) - return error_mark_node; - - mark_addressable (TREE_OPERAND (rhs, 0)); + { + tree fn = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain); + if (fn == error_mark_node) + return error_mark_node; + mark_addressable (fn); + TREE_OPERAND (rhs, 0) = fn; + TREE_CONSTANT (rhs) = staticp (fn); + } return rhs; case ENTRY_VALUE_EXPR: diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4f848c7..13c21dc 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -502,8 +502,12 @@ struct lang_type union tree_node *signature; union tree_node *signature_pointer_to; union tree_node *signature_reference_to; + + int linenum; }; +#define CLASSTYPE_SOURCE_LINE(NODE) (TYPE_LANG_SPECIFIC(NODE)->linenum) + /* Indicates whether or not (and how) a template was expanded for this class. 0=no information yet/non-template class 1=implicit template instantiation @@ -1355,7 +1359,7 @@ extern void check_function_format PROTO((tree, tree, tree)); /* Print an error message for invalid operands to arith operation CODE. NOP_EXPR is used as a special case (see truthvalue_conversion). */ extern void binary_op_error PROTO((enum tree_code)); -extern tree c_build_type_variant PROTO((tree, int, int)); +extern tree cp_build_type_variant PROTO((tree, int, int)); extern void c_expand_expr_stmt PROTO((tree)); /* Validate the expression after `case' and apply default promotions. */ extern tree check_case_value PROTO((tree)); @@ -2011,7 +2015,7 @@ extern void expand_end_all_catch PROTO((void)); extern void start_catch_block PROTO((tree, tree)); extern void end_catch_block PROTO((void)); extern void expand_throw PROTO((tree)); -extern void build_exception_table PROTO((void)); +extern int build_exception_table PROTO((void)); extern tree build_throw PROTO((tree)); extern void init_exception_processing PROTO((void)); @@ -2091,7 +2095,7 @@ extern void reinit_parse_for_method PROTO((int, tree)); #if 0 extern void reinit_parse_for_block PROTO((int, struct obstack *, int)); #endif -extern tree cons_up_default_function PROTO((tree, tree, tree, int)); +extern tree cons_up_default_function PROTO((tree, tree, int)); extern void check_for_missing_semicolon PROTO((tree)); extern void note_got_semicolon PROTO((tree)); extern void note_list_got_semicolon PROTO((tree)); @@ -2141,6 +2145,7 @@ extern void clear_anon_parm_name PROTO((void)); extern void do_inline_function_hair PROTO((tree, tree)); /* skip report_type_mismatch */ extern char *build_overload_name PROTO((tree, int, int)); +extern tree build_static_name PROTO((tree, tree)); extern tree cplus_exception_name PROTO((tree)); extern tree build_decl_overload PROTO((tree, tree, int)); extern tree build_typename_overload PROTO((tree)); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index a47075be..d804ff2 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -304,7 +304,7 @@ build_up_reference (type, arg, flags, checkconst) /* Pass along const and volatile down into the type. */ if (TYPE_READONLY (type) || TYPE_VOLATILE (type)) - target_type = c_build_type_variant (target_type, TYPE_READONLY (type), + target_type = cp_build_type_variant (target_type, TYPE_READONLY (type), TYPE_VOLATILE (type)); targ = arg; if (TREE_CODE (targ) == SAVE_EXPR) @@ -494,6 +494,8 @@ build_up_reference (type, arg, flags, checkconst) return rval; } + case PREINCREMENT_EXPR: + case PREDECREMENT_EXPR: case MODIFY_EXPR: case INIT_EXPR: { @@ -634,7 +636,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl) { int r = TREE_READONLY (expr); int v = TREE_THIS_VOLATILE (expr); - ttr = c_build_type_variant (TREE_TYPE (expr), r, v); + ttr = cp_build_type_variant (TREE_TYPE (expr), r, v); } if (! lvalue_p (expr) && @@ -2041,5 +2043,5 @@ type_promotes_to (type) else if (type == float_type_node) type = double_type_node; - return c_build_type_variant (type, constp, volatilep); + return cp_build_type_variant (type, constp, volatilep); } diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 233232d..fa99e67 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -162,6 +162,8 @@ tree wchar_type_node; tree signed_wchar_type_node; tree unsigned_wchar_type_node; +tree wchar_decl_node; + tree float_type_node; tree double_type_node; tree long_double_type_node; @@ -2206,16 +2208,21 @@ duplicate_decls (newdecl, olddecl) return 0; } + if (olddecl == wchar_decl_node) + { + if (pedantic && ! DECL_IN_SYSTEM_HEADER (newdecl)) + cp_pedwarn ("redeclaration of wchar_t as `%T'", + TREE_TYPE (newdecl)); + + /* Throw away the redeclaration. */ + return 1; + } + /* Already complained about this, so don't do so again. */ else if (current_class_type == NULL_TREE || IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl)) != current_class_type) { - /* Since we're doing this before finish_struct can set the - line number on NEWDECL, we just do a regular error here. */ - if (DECL_SOURCE_LINE (newdecl) == 0) - cp_error ("conflicting types for `%#D'", newdecl); - else - cp_error_at ("conflicting types for `%#D'", newdecl); + cp_error ("conflicting types for `%#D'", newdecl); cp_error_at ("previous declaration as `%#D'", olddecl); } } @@ -2528,12 +2535,15 @@ duplicate_decls (newdecl, olddecl) DECL_TEMPLATE_MEMBERS (newdecl) = DECL_TEMPLATE_MEMBERS (olddecl); DECL_TEMPLATE_INSTANTIATIONS (newdecl) = DECL_TEMPLATE_INSTANTIATIONS (olddecl); + if (DECL_CHAIN (newdecl) == NULL_TREE) + DECL_CHAIN (newdecl) = DECL_CHAIN (olddecl); } /* Now preserve various other info from the definition. */ TREE_ADDRESSABLE (newdecl) = TREE_ADDRESSABLE (olddecl); TREE_ASM_WRITTEN (newdecl) = TREE_ASM_WRITTEN (olddecl); DECL_COMMON (newdecl) = DECL_COMMON (olddecl); + DECL_ASSEMBLER_NAME (newdecl) = DECL_ASSEMBLER_NAME (olddecl); /* Don't really know how much of the language-specific values we should copy from old to new. */ @@ -3900,7 +3910,9 @@ lookup_name_real (name, prefer_type, nonclass) if (got_scope != NULL_TREE) { - if (got_scope == void_type_node) + if (got_scope == error_mark_node) + return error_mark_node; + else if (got_scope == void_type_node) val = IDENTIFIER_GLOBAL_VALUE (name); else if (TREE_CODE (got_scope) == TEMPLATE_TYPE_PARM /* TFIXME -- don't do this for UPTs in new model. */ @@ -4750,6 +4762,11 @@ init_decl_processing () : signed_wchar_type_node; record_builtin_type (RID_WCHAR, "__wchar_t", wchar_type_node); + /* Artificial declaration of wchar_t -- can be bashed */ + wchar_decl_node = build_decl (TYPE_DECL, get_identifier ("wchar_t"), + wchar_type_node); + pushdecl (wchar_decl_node); + /* This is for wide string constants. */ wchar_array_type_node = build_array_type (wchar_type_node, array_domain_type); @@ -4800,7 +4817,7 @@ init_decl_processing () vtbl_type_node = build_array_type (vtable_entry_type, NULL_TREE); layout_type (vtbl_type_node); - vtbl_type_node = c_build_type_variant (vtbl_type_node, 1, 0); + vtbl_type_node = cp_build_type_variant (vtbl_type_node, 1, 0); record_builtin_type (RID_MAX, NULL_PTR, vtbl_type_node); /* Simplify life by making a "sigtable_entry_type". Give its @@ -5297,8 +5314,7 @@ start_decl (declarator, declspecs, initialized, raises) if (interface_unknown && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (decl)) warn_if_unknown_interface (); - TREE_PUBLIC (d) = TREE_PUBLIC (decl) = - flag_external_templates && !interface_unknown; + TREE_PUBLIC (d) = TREE_PUBLIC (decl); TREE_STATIC (d) = TREE_STATIC (decl); DECL_EXTERNAL (d) = (DECL_EXTERNAL (decl) && !(context && !DECL_THIS_EXTERN (decl))); @@ -5756,6 +5772,9 @@ finish_decl (decl, init, asmspec_tree, need_pop) type = TREE_TYPE (decl); + if (type == error_mark_node) + return; + was_incomplete = (DECL_SIZE (decl) == NULL_TREE); /* Take care of TYPE_DECLs up front. */ @@ -5850,6 +5869,10 @@ finish_decl (decl, init, asmspec_tree, need_pop) else if (TREE_CODE (type) == REFERENCE_TYPE || (TYPE_LANG_SPECIFIC (type) && IS_SIGNATURE_REFERENCE (type))) { + if (TREE_STATIC (decl)) + make_decl_rtl (decl, NULL_PTR, + current_binding_level == global_binding_level + || pseudo_global_level_p ()); grok_reference_init (decl, type, init, &cleanup); init = NULL_TREE; } @@ -6836,6 +6859,7 @@ grokvardecl (type, declarator, specbits, initialized) decl = build_lang_field_decl (VAR_DECL, declarator, type); DECL_CONTEXT (decl) = basetype; DECL_CLASS_CONTEXT (decl) = basetype; + DECL_ASSEMBLER_NAME (decl) = build_static_name (basetype, declarator); } else decl = build_decl (VAR_DECL, declarator, type); @@ -6901,6 +6925,8 @@ build_ptrmemfunc_type (type) /* Let the front-end know this is a pointer to member function. */ TYPE_PTRMEMFUNC_FLAG(t) = 1; + /* and not really an aggregate. */ + IS_AGGR_TYPE (t) = 0; fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier, delta_type_node); @@ -7327,7 +7353,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) goto found; } - for (i = (int) RID_FIRST_MODIFIER; i < (int) RID_LAST_MODIFIER; i++) + for (i = (int) RID_FIRST_MODIFIER; i <= (int) RID_LAST_MODIFIER; i++) { if (ridpointers[i] == id) { @@ -8031,7 +8057,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) type = build_cplus_array_type (type, itype); if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); + type = cp_build_type_variant (type, constp, volatilep); ctype = NULL_TREE; } @@ -8040,6 +8066,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) case CALL_EXPR: { tree arg_types; + int funcdecl_p; + tree inner_parms = TREE_OPERAND (declarator, 1); + tree inner_decl = TREE_OPERAND (declarator, 0); /* Declaring a function type. Make sure we have a valid type for the function to return. */ @@ -8053,7 +8082,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) if (constp || volatilep) { - type = c_build_type_variant (type, constp, volatilep); + type = cp_build_type_variant (type, constp, volatilep); if (IS_AGGR_TYPE (type)) build_pointer_type (type); constp = 0; @@ -8074,8 +8103,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) type = integer_type_node; } + if (inner_decl && TREE_CODE (inner_decl) == SCOPE_REF) + inner_decl = TREE_OPERAND (inner_decl, 1); + + /* Say it's a definition only for the CALL_EXPR + closest to the identifier. */ + funcdecl_p = + inner_decl && TREE_CODE (inner_decl) == IDENTIFIER_NODE; + if (ctype == NULL_TREE && decl_context == FIELD + && funcdecl_p && (friendp == 0 || dname == current_class_name)) ctype = current_class_type; @@ -8189,27 +8227,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) /* Construct the function type and go to the next inner layer of declarator. */ - { - int funcdef_p; - tree inner_parms = TREE_OPERAND (declarator, 1); - tree inner_decl = TREE_OPERAND (declarator, 0); - - declarator = TREE_OPERAND (declarator, 0); - - if (inner_decl && TREE_CODE (inner_decl) == SCOPE_REF) - inner_decl = TREE_OPERAND (inner_decl, 1); - - /* Say it's a definition only for the CALL_EXPR - closest to the identifier. */ - funcdef_p = - (inner_decl && TREE_CODE (inner_decl) == IDENTIFIER_NODE) - ? funcdef_flag : 0; + declarator = TREE_OPERAND (declarator, 0); - /* FIXME: This is where default args should be fully - processed. */ + /* FIXME: This is where default args should be fully + processed. */ - arg_types = grokparms (inner_parms, funcdef_p); - } + arg_types = grokparms (inner_parms, funcdecl_p ? funcdef_flag : 0); if (declarator) { @@ -8264,7 +8287,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) signature pointer/reference itself. */ if (! IS_SIGNATURE (type)) { - type = c_build_type_variant (type, constp, volatilep); + type = cp_build_type_variant (type, constp, volatilep); if (IS_AGGR_TYPE (type)) build_pointer_type (type); constp = 0; @@ -8559,7 +8582,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) /* Note that the grammar rejects storage classes in typenames, fields or parameters. */ if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); + type = cp_build_type_variant (type, constp, volatilep); /* If the user declares "struct {...} foo" then `foo' will have an anonymous name. Fill that name in now. Nothing can @@ -8648,7 +8671,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) if (IS_SIGNATURE (type)) error ("`const' or `volatile' specified with signature type"); else - type = c_build_type_variant (type, constp, volatilep); + type = cp_build_type_variant (type, constp, volatilep); /* Special case: "friend class foo" looks like a TYPENAME context. */ if (friendp) @@ -8730,7 +8753,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) { /* Transfer const-ness of array into that of type pointed to. */ type = build_pointer_type - (c_build_type_variant (TREE_TYPE (type), constp, volatilep)); + (cp_build_type_variant (TREE_TYPE (type), constp, volatilep)); volatilep = constp = 0; } else if (TREE_CODE (type) == FUNCTION_TYPE) @@ -9988,13 +10011,14 @@ xref_tag (code_type_node, name, binfo, globalize) ref = make_lang_type (code); - /* A signature type will contain the fields of the signature - table. Therefore, it's not only an interface. */ if (tag_code == signature_type) { SET_SIGNATURE (ref); + /* Since a signature type will be turned into the type + of signature tables, it's not only an interface. */ CLASSTYPE_INTERFACE_ONLY (ref) = 0; - SET_CLASSTYPE_INTERFACE_UNKNOWN (ref); + SET_CLASSTYPE_INTERFACE_KNOWN (ref); + /* A signature doesn't have a vtable. */ CLASSTYPE_VTABLE_NEEDS_WRITING (ref) = 0; } @@ -10125,6 +10149,7 @@ xref_tag (code_type_node, name, binfo, globalize) TREE_VIA_PUBLIC (base_binfo) = via_public; TREE_VIA_PROTECTED (base_binfo) = via_protected; TREE_VIA_VIRTUAL (base_binfo) = via_virtual; + BINFO_INHERITANCE_CHAIN (base_binfo) = TYPE_BINFO (ref); SET_CLASSTYPE_MARKED (basetype); #if 0 @@ -10226,6 +10251,7 @@ start_enum (name) TREE_ADDRESSABLE (b->tags) = 1; current_local_enum = NULL_TREE; +#if 0 /* This stuff gets cleared in finish_enum anyway. */ if (TYPE_VALUES (enumtype) != NULL_TREE) /* Completely replace its old definition. The old enumerators remain defined, however. */ @@ -10238,7 +10264,8 @@ start_enum (name) TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node); TYPE_SIZE (enumtype) = NULL_TREE; - fixup_unsigned_type (enumtype); + fixup_signed_type (enumtype); +#endif /* We copy this value because enumerated type constants are really of the type of the enumerator, not integer_type_node. */ @@ -10258,84 +10285,78 @@ tree finish_enum (enumtype, values) register tree enumtype, values; { - register tree pair, tem; - register HOST_WIDE_INT maxvalue = 0; - register HOST_WIDE_INT minvalue = 0; - register HOST_WIDE_INT i; - + register tree minnode, maxnode; /* Calculate the maximum value of any enumerator in this type. */ if (values) { + register tree pair; + register tree value = DECL_INITIAL (TREE_VALUE (values)); + /* Speed up the main loop by performing some precalculations */ - - HOST_WIDE_INT value; TREE_TYPE (TREE_VALUE (values)) = enumtype; - TREE_TYPE (DECL_INITIAL (TREE_VALUE (values))) = enumtype; - TREE_VALUE (values) = DECL_INITIAL (TREE_VALUE (values)); - value = TREE_INT_CST_LOW (TREE_VALUE (values)); - minvalue = maxvalue = value; + TREE_TYPE (value) = enumtype; + TREE_VALUE (values) = value; + minnode = maxnode = value; for (pair = TREE_CHAIN (values); pair; pair = TREE_CHAIN (pair)) { + value = DECL_INITIAL (TREE_VALUE (pair)); TREE_TYPE (TREE_VALUE (pair)) = enumtype; - TREE_TYPE (DECL_INITIAL (TREE_VALUE (pair))) = enumtype; - TREE_VALUE (pair) = DECL_INITIAL (TREE_VALUE (pair)); - value = TREE_INT_CST_LOW (TREE_VALUE (pair)); - if (value > maxvalue) - maxvalue = value; - else if (value < minvalue) - minvalue = value; + TREE_TYPE (value) = enumtype; + TREE_VALUE (pair) = value; + if (tree_int_cst_lt (maxnode, value)) + maxnode = value; + else if (tree_int_cst_lt (value, minnode)) + minnode = value; } } + else + maxnode = minnode = integer_zero_node; TYPE_VALUES (enumtype) = values; - if (flag_short_enums) - { - /* Determine the precision this type needs, lay it out, and define - it. */ - - /* First reset precision */ - TYPE_PRECISION (enumtype) = 0; - - for (i = maxvalue; i; i >>= 1) - TYPE_PRECISION (enumtype)++; + { + int unsignedp = tree_int_cst_sgn (minnode) >= 0; + int lowprec = min_precision (minnode, unsignedp); + int highprec = min_precision (maxnode, unsignedp); + int precision = MAX (lowprec, highprec); - if (!TYPE_PRECISION (enumtype)) - TYPE_PRECISION (enumtype) = 1; + if (! flag_short_enums && precision < TYPE_PRECISION (integer_type_node)) + precision = TYPE_PRECISION (integer_type_node); - /* Cancel the laying out previously done for the enum type, - so that fixup_unsigned_type will do it over. */ - TYPE_SIZE (enumtype) = NULL_TREE; + /* Unlike the C frontend, we prefer signed types. */ + if (unsignedp && int_fits_type_p (maxnode, type_for_size (precision, 0))) + unsignedp = 0; + TYPE_PRECISION (enumtype) = precision; + TYPE_SIZE (enumtype) = NULL_TREE; + if (unsignedp) fixup_unsigned_type (enumtype); - } - - TREE_INT_CST_LOW (TYPE_MAX_VALUE (enumtype)) = maxvalue; + else + fixup_signed_type (enumtype); + } - /* An enum can have some negative values; then it is signed. */ - if (minvalue < 0) - { - TREE_INT_CST_LOW (TYPE_MIN_VALUE (enumtype)) = minvalue; - TREE_INT_CST_HIGH (TYPE_MIN_VALUE (enumtype)) = -1; - TREE_UNSIGNED (enumtype) = 0; - } if (flag_cadillac) cadillac_finish_enum (enumtype); - /* Fix up all variant types of this enum type. */ - for (tem = TYPE_MAIN_VARIANT (enumtype); tem; tem = TYPE_NEXT_VARIANT (tem)) - { - TYPE_VALUES (tem) = TYPE_VALUES (enumtype); - TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype); - TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype); - TYPE_SIZE (tem) = TYPE_SIZE (enumtype); - TYPE_MODE (tem) = TYPE_MODE (enumtype); - TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype); - TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype); - TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype); - } + { + register tree tem; + + /* Fix up all variant types of this enum type. */ + for (tem = TYPE_MAIN_VARIANT (enumtype); tem; + tem = TYPE_NEXT_VARIANT (tem)) + { + TYPE_VALUES (tem) = TYPE_VALUES (enumtype); + TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype); + TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype); + TYPE_SIZE (tem) = TYPE_SIZE (enumtype); + TYPE_MODE (tem) = TYPE_MODE (enumtype); + TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype); + TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype); + TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype); + } + } /* Finish debugging output for this type. */ #if 0 @@ -11042,59 +11063,6 @@ store_return_init (return_id, init) } } -#if 0 -/* Generate code for default X() constructor. */ -static void -build_default_constructor (fndecl) - tree fndecl; -{ - int i = CLASSTYPE_N_BASECLASSES (current_class_type); - tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl)); - tree fields = TYPE_FIELDS (current_class_type); - tree binfos = TYPE_BINFO_BASETYPES (current_class_type); - - if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) - parm = TREE_CHAIN (parm); - parm = DECL_REFERENCE_SLOT (parm); - - while (--i >= 0) - { - tree basetype = TREE_VEC_ELT (binfos, i); - if (TYPE_HAS_INIT_REF (basetype)) - { - tree name = TYPE_NAME (basetype); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - current_base_init_list = tree_cons (name, parm, current_base_init_list); - } - } - for (; fields; fields = TREE_CHAIN (fields)) - { - tree name, init; - if (TREE_STATIC (fields)) - continue; - if (TREE_CODE (fields) != FIELD_DECL) - continue; - if (DECL_NAME (fields)) - { - if (VFIELD_NAME_P (DECL_NAME (fields))) - continue; - if (VBASE_NAME_P (DECL_NAME (fields))) - continue; - - /* True for duplicate members. */ - if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields) - continue; - } - - init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields); - init = build_tree_list (NULL_TREE, init); - - current_member_init_list - = tree_cons (DECL_NAME (fields), init, current_member_init_list); - } -} -#endif /* Finish up a function declaration and compile that function all the way to assembler language output. The free the storage diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 25c517d..cc0ab50 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -212,6 +212,12 @@ int warn_nonvdtor; /* Non-zero means warn when a function is declared extern and later inline. */ int warn_extern_inline; +/* Non-zero means warn when the compiler will reorder code. */ +int warn_reorder; + +/* Non-zero means warn when sysnthesis behavior differs from Cfront's. */ +int warn_synth; + /* Nonzero means `$' can be in an identifier. See cccp.c for reasons why this breaks some obscure ANSI C programs. */ @@ -521,6 +527,10 @@ lang_decode_option (p) warn_nonvdtor = setting; else if (!strcmp (p, "extern-inline")) warn_extern_inline = setting; + else if (!strcmp (p, "reorder")) + warn_reorder = setting; + else if (!strcmp (p, "synth")) + warn_synth = setting; else if (!strcmp (p, "comment")) ; /* cpp handles this one. */ else if (!strcmp (p, "comments")) @@ -547,6 +557,7 @@ lang_decode_option (p) if (warn_uninitialized != 1) warn_uninitialized = (setting ? 2 : 0); warn_template_debugging = setting; + warn_reorder = setting; } else if (!strcmp (p, "overloaded-virtual")) @@ -1065,11 +1076,20 @@ delete_sanity (exp, size, doing_vec, use_global_delete) return build1 (NOP_EXPR, void_type_node, t); } - /* You can't delete a pointer to constant. */ - if (code == POINTER_TYPE && TREE_READONLY (TREE_TYPE (type))) + if (code == POINTER_TYPE) { - error ("`const *' cannot be deleted"); - return error_mark_node; + /* You can't delete a pointer to constant. */ + if (TREE_READONLY (TREE_TYPE (type))) + { + error ("`const *' cannot be deleted"); + return error_mark_node; + } + /* You also can't delete functions. */ + if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) + { + error ("cannot delete a function"); + return error_mark_node; + } } #if 0 @@ -1309,19 +1329,10 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree) /* current_class_type can be NULL_TREE in case of error. */ if (asmspec == 0 && current_class_type) { - tree name; - char *buf, *buf2; - - buf2 = build_overload_name (current_class_type, 1, 1); - buf = (char *)alloca (IDENTIFIER_LENGTH (DECL_NAME (value)) - + sizeof (STATIC_NAME_FORMAT) - + strlen (buf2)); - sprintf (buf, STATIC_NAME_FORMAT, buf2, - IDENTIFIER_POINTER (DECL_NAME (value))); - name = get_identifier (buf); TREE_PUBLIC (value) = 1; DECL_INITIAL (value) = error_mark_node; - DECL_ASSEMBLER_NAME (value) = name; + DECL_ASSEMBLER_NAME (value) + = build_static_name (current_class_type, DECL_NAME (value)); } pending_statics = perm_tree_cons (NULL_TREE, value, pending_statics); @@ -1374,9 +1385,11 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree) if (DECL_FRIEND_P (value)) return void_type_node; +#if 0 /* Just because a fn is declared doesn't mean we'll try to define it. */ if (current_function_decl && ! IS_SIGNATURE (current_class_type)) cp_error ("method `%#D' of local class must be defined in class body", value); +#endif DECL_IN_AGGR_P (value) = 1; return value; @@ -2591,8 +2604,7 @@ finish_file () tree fnname; tree vars = static_aggregates; int needs_cleaning = 0, needs_messing_up = 0; - - build_exception_table (); + int have_exception_handlers = build_exception_table (); if (flag_detailed_statistics) dump_tree_statistics (); @@ -2686,7 +2698,7 @@ finish_file () mess_up: /* Must do this while we think we are at the top level. */ vars = nreverse (static_aggregates); - if (vars != NULL_TREE) + if (vars != NULL_TREE || have_exception_handlers) { fnname = get_file_function_name ('I'); start_function (void_list_node, build_parse_node (CALL_EXPR, fnname, void_list_node, NULL_TREE), 0, 0); @@ -2698,6 +2710,9 @@ finish_file () push_momentary (); expand_start_bindings (0); + if (have_exception_handlers) + register_exception_table (); + while (vars) { tree decl = TREE_VALUE (vars); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 4bb9316..b826283 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -571,7 +571,8 @@ dump_decl (t, v) { /* Don't say 'typedef class A' */ tree type = TREE_TYPE (t); - if (IS_AGGR_TYPE (type) && ! TYPE_PTRMEMFUNC_P (type) + if (((IS_AGGR_TYPE (type) && ! TYPE_PTRMEMFUNC_P (type)) + || TREE_CODE (type) == ENUMERAL_TYPE) && type == TYPE_MAIN_VARIANT (type)) { dump_type (type, v); @@ -668,7 +669,7 @@ dump_decl (t, v) case TEMPLATE_DECL: { tree args = DECL_TEMPLATE_PARMS (t); - int i, len = TREE_VEC_LENGTH (args); + int i, len = args ? TREE_VEC_LENGTH (args) : 0; OB_PUTS ("template <"); for (i = 0; i < len; i++) { @@ -691,7 +692,8 @@ dump_decl (t, v) OB_PUTC2 (',', ' '); } - OB_UNPUT (2); + if (len != 0) + OB_UNPUT (2); OB_PUTC2 ('>', ' '); if (DECL_TEMPLATE_IS_CLASS (t)) @@ -1350,12 +1352,26 @@ int cp_line_of (t) tree t; { + int line = 0; if (TREE_CODE (t) == PARM_DECL) - return DECL_SOURCE_LINE (DECL_CONTEXT (t)); - else if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') - return DECL_SOURCE_LINE (TYPE_NAME (t)); + line = DECL_SOURCE_LINE (DECL_CONTEXT (t)); + if (TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t)) + t = TREE_TYPE (t); + + if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') + { + if (IS_AGGR_TYPE (t)) + line = CLASSTYPE_SOURCE_LINE (t); + else + line = DECL_SOURCE_LINE (TYPE_NAME (t)); + } else - return DECL_SOURCE_LINE (t); + line = DECL_SOURCE_LINE (t); + + if (line == 0) + return lineno; + + return line; } char * diff --git a/gcc/cp/except.c b/gcc/cp/except.c index dc91b9d..7d748e9 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -59,11 +59,6 @@ sorry_no_eh () } void -build_exception_table () -{ -} - -void expand_exception_blocks () { } @@ -180,29 +175,9 @@ output_exception_table_entry (file, start_label, end_label, eh_label) { char label[100]; - fprintf (file, "\t%s\t ", ASM_LONG); - if (GET_CODE (start_label) == CODE_LABEL) - { - ASM_GENERATE_INTERNAL_LABEL (label, "L", CODE_LABEL_NUMBER (start_label)); - assemble_name (file, label); - } - else if (GET_CODE (start_label) == SYMBOL_REF) - { - fprintf (stderr, "YYYYYYYYYEEEEEEEESSSSSSSSSSSS!!!!!!!!!!\n"); - assemble_name (file, XSTR (start_label, 0)); - } - putc ('\n', file); - - fprintf (file, "\t%s\t ", ASM_LONG); - ASM_GENERATE_INTERNAL_LABEL (label, "L", CODE_LABEL_NUMBER (end_label)); - assemble_name (file, label); - putc ('\n', file); - - fprintf (file, "\t%s\t ", ASM_LONG); - ASM_GENERATE_INTERNAL_LABEL (label, "L", CODE_LABEL_NUMBER (eh_label)); - assemble_name (file, label); - putc ('\n', file); - + assemble_integer (start_label, BITS_PER_WORD/BITS_PER_UNIT, 1); + assemble_integer (end_label, BITS_PER_WORD/BITS_PER_UNIT, 1); + assemble_integer (eh_label, BITS_PER_WORD/BITS_PER_UNIT, 1); putc ('\n', file); /* blank line */ } @@ -1436,39 +1411,62 @@ expand_throw (exp) emit_jump (throw_label); } +/* end of: my-cp-except.c */ +#endif -/* output the exception table */ -void + +/* Output the exception table. + Return the number of handlers. */ +int build_exception_table () { + int count = 0; +#ifdef TRY_NEW_EH extern FILE *asm_out_file; struct ehEntry *entry; + tree eh_node_decl; if (! doing_eh (0)) - return; - - exception_section (); - - /* Beginning marker for table. */ - fprintf (asm_out_file, " .global ___EXCEPTION_TABLE__\n"); - fprintf (asm_out_file, " .align 4\n"); - fprintf (asm_out_file, "___EXCEPTION_TABLE__:\n"); - fprintf (asm_out_file, " .word 0, 0, 0\n"); + return 0; - while (entry = dequeue_eh_entry (&eh_table_output_queue)) { + while (entry = dequeue_eh_entry (&eh_table_output_queue)) + { + if (count == 0) + { + exception_section (); + + /* Beginning marker for table. */ + ASM_OUTPUT_ALIGN (asm_out_file, 2); + ASM_OUTPUT_LABEL (asm_out_file, "__EXCEPTION_TABLE__"); + fprintf (asm_out_file, " .word 0, 0, 0\n"); + } + count++; output_exception_table_entry (asm_out_file, - entry->start_label, entry->end_label, entry->exception_handler_label); + entry->start_label, entry->end_label, + entry->exception_handler_label); } - /* Ending marker for table. */ - fprintf (asm_out_file, " .global ___EXCEPTION_END__\n"); - fprintf (asm_out_file, "___EXCEPTION_END__:\n"); - fprintf (asm_out_file, " .word -1, -1, -1\n"); -} + if (count) + { + /* Ending marker for table. */ + ASM_OUTPUT_LABEL (asm_out_file, "__EXCEPTION_END__"); + fprintf (asm_out_file, " .word -1, -1, -1\n"); + } -/* end of: my-cp-except.c */ -#endif +#endif /* TRY_NEW_EH */ + return count; +} +void +register_exception_table () +{ +#ifdef TRY_NEW_EH + emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__register_exceptions"), 0, + VOIDmode, 1, + gen_rtx (SYMBOL_REF, PTRmode, "__EXCEPTION_TABLE__"), + Pmode); +#endif /* TRY_NEW_EH */ +} /* Build a throw expression. */ tree diff --git a/gcc/cp/init.c b/gcc/cp/init.c index d259398..08f33c0 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -227,6 +227,7 @@ static tree sort_member_init (t) tree t; { + extern int warn_reorder; tree x, member, name, field, init; tree init_list = NULL_TREE; tree fields_to_unmark = NULL_TREE; @@ -270,7 +271,7 @@ sort_member_init (t) } else { - if (pos < last_pos && extra_warnings) + if (pos < last_pos && warn_reorder) { cp_warning_at ("member initializers for `%#D'", last_field); cp_warning_at (" and `%#D'", field); @@ -1130,7 +1131,11 @@ expand_aggr_init (exp, init, alias_this) int was_const_elts = TYPE_READONLY (TREE_TYPE (type)); tree itype = init ? TREE_TYPE (init) : NULL_TREE; if (was_const_elts) - TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type); + { + TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type); + if (init) + TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype); + } if (init && TREE_TYPE (init) == NULL_TREE) { /* Handle bad initializers like: @@ -1152,7 +1157,8 @@ expand_aggr_init (exp, init, alias_this) init && comptypes (TREE_TYPE (init), TREE_TYPE (exp), 1)); TREE_READONLY (exp) = was_const; TREE_TYPE (exp) = type; - if (init) TREE_TYPE (init) = itype; + if (init) + TREE_TYPE (init) = itype; return; } @@ -1200,6 +1206,7 @@ expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags) else if (TREE_CODE (init) == INDIRECT_REF && TREE_HAS_CONSTRUCTOR (init)) { rval = convert_for_initialization (exp, type, init, 0, 0, 0, 0); + TREE_USED (rval) = 1; expand_expr_stmt (rval); return; } diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index fb6ba52..3a6970b 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -75,6 +75,12 @@ void yyerror (); struct obstack inline_text_obstack; static char *inline_text_firstobj; +/* This obstack is used to hold information about methods to be + synthesized. It should go away when synthesized methods are handled + properly (i.e. only when needed). */ +struct obstack synth_obstack; +static char *synth_firstobj; + int end_of_file; /* Pending language change. @@ -564,6 +570,8 @@ init_lex () init_error (); gcc_obstack_init (&inline_text_obstack); inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0); + gcc_obstack_init (&synth_obstack); + synth_firstobj = (char *) obstack_alloc (&synth_obstack, 0); /* Start it at 0, because check_newline is called at the very beginning and will increment it to 1. */ @@ -1086,30 +1094,60 @@ set_vardecl_interface_info (prev, vars) void do_pending_inlines () { - struct pending_inline *prev = 0, *tail; struct pending_inline *t; /* Oops, we're still dealing with the last batch. */ if (yychar == PRE_PARSED_FUNCTION_DECL) return; - + + /* Note that we've seen these inlines and are dealing with them. */ + for (t = pending_inlines; t; t = t->next) + t->deja_vu = 1; + /* Reverse the pending inline functions, since they were cons'd instead of appended. */ - - for (t = pending_inlines; t; t = tail) - { - t->deja_vu = 1; - tail = t->next; - t->next = prev; - prev = t; - } - /* Reset to zero so that if the inline functions we are currently - processing define inline functions of their own, that is handled - correctly. ??? This hasn't been checked in a while. */ - pending_inlines = 0; - + { + struct pending_inline *prev = 0, *tail; + t = pending_inlines; + pending_inlines = 0; + + for (; t; t = tail) + { + tail = t->next; + + /* This kludge should go away when synthesized methods are handled + properly, i.e. only when needed. */ + if (t->lineno <= 0) + { + tree f = t->fndecl; + DECL_PENDING_INLINE_INFO (f) = 0; + switch (- t->lineno) + { + case 0: case 1: + build_dtor (f); break; + case 2: + build_default_constructor (f); break; + case 3: case 4: + build_copy_constructor (f); break; + case 5: case 6: + build_assign_ref (f); break; + default: + ; + } + obstack_free (&synth_obstack, t); + continue; + } + + t->next = prev; + prev = t; + } + t = prev; + } + + if (t == 0) + return; + /* Now start processing the first inline function. */ - t = prev; my_friendly_assert ((t->parm_vec == NULL_TREE) == (t->bindings == NULL_TREE), 226); if (t->parm_vec) @@ -1651,8 +1689,8 @@ reinit_parse_for_block (yychar, obstackp, is_template) When KIND == 6, build default operator = (X&). */ tree -cons_up_default_function (type, name, fields, kind) - tree type, name, fields; +cons_up_default_function (type, name, kind) + tree type, name; int kind; { extern tree void_list_node; @@ -1676,14 +1714,6 @@ cons_up_default_function (type, name, fields, kind) case 2: /* Default constructor. */ args = void_list_node; - { - if (declspecs) - declspecs = decl_tree_cons (NULL_TREE, - ridpointers [(int) RID_INLINE], - declspecs); - else - declspecs = build_decl_list (NULL_TREE, ridpointers [(int) RID_INLINE]); - } break; case 3: @@ -1691,16 +1721,12 @@ cons_up_default_function (type, name, fields, kind) /* Fall through... */ case 4: /* According to ARM $12.8, the default copy ctor will be declared, but - not defined, unless it's needed. So we mark this as `inline'; that - way, if it's never used it won't be emitted. */ - declspecs = build_decl_list (NULL_TREE, ridpointers [(int) RID_INLINE]); - + not defined, unless it's needed. */ argtype = build_reference_type (type); args = tree_cons (NULL_TREE, build_tree_list (hash_tree_chain (argtype, NULL_TREE), get_identifier ("_ctor_arg")), void_list_node); - default_copy_constructor_body (&func_buf, &func_len, type, fields); break; case 5: @@ -1708,11 +1734,7 @@ cons_up_default_function (type, name, fields, kind) /* Fall through... */ case 6: retref = 1; - declspecs = - decl_tree_cons (NULL_TREE, name, - decl_tree_cons (NULL_TREE, - ridpointers [(int) RID_INLINE], - NULL_TREE)); + declspecs = build_decl_list (NULL_TREE, name); name = ansi_opname [(int) MODIFY_EXPR]; @@ -1721,19 +1743,14 @@ cons_up_default_function (type, name, fields, kind) build_tree_list (hash_tree_chain (argtype, NULL_TREE), get_identifier ("_ctor_arg")), void_list_node); - default_assign_ref_body (&func_buf, &func_len, type, fields); break; default: my_friendly_abort (59); } - if (!func_buf) - { - func_len = 2; - func_buf = obstack_alloc (&inline_text_obstack, func_len); - strcpy (func_buf, "{}"); - } + declspecs = decl_tree_cons (NULL_TREE, ridpointers [(int) RID_INLINE], + declspecs); TREE_PARMLIST (args) = 1; @@ -1742,45 +1759,23 @@ cons_up_default_function (type, name, fields, kind) if (retref) declarator = build_parse_node (ADDR_EXPR, declarator); - fn = start_method (declspecs, declarator, NULL_TREE); + fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE); } if (fn == void_type_node) return fn; - current_base_init_list = NULL_TREE; - current_member_init_list = NULL_TREE; - + /* This kludge should go away when synthesized methods are handled + properly, i.e. only when needed. */ { struct pending_inline *t; - - t = (struct pending_inline *) obstack_alloc (&inline_text_obstack, - sizeof (struct pending_inline)); - t->lineno = lineno; - -#if 1 - t->filename = input_filename; -#else /* This breaks; why? */ -#define MGMSG "(synthetic code at) " - t->filename = obstack_alloc (&inline_text_obstack, - strlen (input_filename) + sizeof (MGMSG) + 1); - strcpy (t->filename, MGMSG); - strcat (t->filename, input_filename); -#endif - t->token = YYEMPTY; - t->token_value = 0; - t->buf = func_buf; - t->len = func_len; - t->can_free = 1; - t->deja_vu = 0; - if (interface_unknown && processing_template_defn && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (fn)) - warn_if_unknown_interface (); - t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2)); + t = (struct pending_inline *) + obstack_alloc (&synth_obstack, sizeof (struct pending_inline)); + t->lineno = -kind; + t->can_free = 0; store_pending_inline (fn, t); } - finish_method (fn); - #ifdef DEBUG_DEFAULT_FUNCTIONS { char *fn_type = NULL; tree t = name; @@ -1802,14 +1797,13 @@ cons_up_default_function (type, name, fields, kind) } #endif /* DEBUG_DEFAULT_FUNCTIONS */ - DECL_CLASS_CONTEXT (fn) = TYPE_MAIN_VARIANT (type); - /* Show that this function was generated by the compiler. */ SET_DECL_ARTIFICIAL (fn); return fn; } +#if 0 /* Used by default_copy_constructor_body. For the anonymous union in TYPE, return the member that is at least as large as the rest of the members, so we can copy it. */ @@ -2155,6 +2149,7 @@ default_copy_constructor_body (bufp, lenp, type, fields) strcpy (*bufp, prologue.object_base); strcat (*bufp, "{}"); } +#endif /* Heuristic to tell whether the user is missing a semicolon after a struct or enum declaration. Emit an error message diff --git a/gcc/cp/method.c b/gcc/cp/method.c index aabd635..61598fa 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -313,6 +313,7 @@ flush_repeats (type) OB_PUTC ('_'); } +static int numeric_outputed_need_bar = 0; static void build_overload_identifier (); static void @@ -476,11 +477,17 @@ build_overload_identifier (name) /* It's a PARM_DECL. */ build_overload_name (TREE_TYPE (parm), 0, 0); build_overload_value (parm, arg); + numeric_outputed_need_bar = 1; } } } else { + if (numeric_outputed_need_bar) + { + OB_PUTC ('_'); + numeric_outputed_need_bar = 0; + } icat (IDENTIFIER_LENGTH (name)); OB_PUTID (name); } @@ -772,6 +779,7 @@ build_overload_name (parmtypes, begin, end) icat (i); if (i > 9) OB_PUTC ('_'); + numeric_outputed_need_bar = 0; build_overload_nested_name (TYPE_NAME (parmtype)); } else @@ -817,6 +825,18 @@ build_overload_name (parmtypes, begin, end) if (end) OB_FINISH (); return (char *)obstack_base (&scratch_obstack); } + +tree +build_static_name (basetype, name) + tree basetype, name; +{ + char *basename = build_overload_name (basetype, 1, 1); + char *buf = (char *) alloca (IDENTIFIER_LENGTH (name) + + sizeof (STATIC_NAME_FORMAT) + + strlen (basename)); + sprintf (buf, STATIC_NAME_FORMAT, basename, IDENTIFIER_POINTER (name)); + return get_identifier (buf); +} /* Generate an identifier that encodes the (ANSI) exception TYPE. */ @@ -1945,3 +1965,173 @@ emit_thunk (thunk_fndecl) decl_printable_name = save_decl_printable_name; current_function_decl = 0; } + +/* Code for synthesizing methods which have default semantics defined. */ + +void +build_default_constructor (fndecl) + tree fndecl; +{ + start_function (NULL_TREE, fndecl, NULL_TREE, 1); + store_parm_decls (); + setup_vtbl_ptr (); + finish_function (lineno, 0); +} + +/* Generate code for default X(X&) constructor. */ +void +build_copy_constructor (fndecl) + tree fndecl; +{ + tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl)); + tree t; + + start_function (NULL_TREE, fndecl, NULL_TREE, 1); + store_parm_decls (); + clear_last_expr (); + push_momentary (); + + if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) + parm = TREE_CHAIN (parm); + parm = convert_from_reference (parm); + + if (! TYPE_HAS_COMPLEX_INIT_REF (current_class_type)) + { + t = build (INIT_EXPR, void_type_node, C_C_D, parm); + TREE_SIDE_EFFECTS (t) = 1; + cplus_expand_expr_stmt (t); + } + else + { + tree fields = TYPE_FIELDS (current_class_type); + int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type); + tree binfos = TYPE_BINFO_BASETYPES (current_class_type); + int i; + + for (t = CLASSTYPE_VBASECLASSES (current_class_type); t; + t = TREE_CHAIN (t)) + { + tree basetype = BINFO_TYPE (t); + tree p = convert (build_reference_type (basetype), parm); + p = convert_from_reference (p); + current_base_init_list = tree_cons (TYPE_NESTED_NAME (basetype), + p, current_base_init_list); + } + + for (i = 0; i < n_bases; ++i) + { + tree p, basetype = TREE_VEC_ELT (binfos, i); + if (TREE_VIA_VIRTUAL (basetype)) + continue; + + basetype = BINFO_TYPE (basetype); + p = convert (build_reference_type (basetype), parm); + p = convert_from_reference (p); + current_base_init_list = tree_cons (TYPE_NESTED_NAME (basetype), + p, current_base_init_list); + } + for (; fields; fields = TREE_CHAIN (fields)) + { + tree name, init; + if (TREE_CODE (fields) != FIELD_DECL) + continue; + if (DECL_NAME (fields)) + { + if (VFIELD_NAME_P (DECL_NAME (fields))) + continue; + if (VBASE_NAME_P (DECL_NAME (fields))) + continue; + + /* True for duplicate members. */ + if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields) + continue; + } + + init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields); + init = build_tree_list (NULL_TREE, init); + + current_member_init_list + = tree_cons (DECL_NAME (fields), init, current_member_init_list); + } + current_member_init_list = nreverse (current_member_init_list); + setup_vtbl_ptr (); + } + + pop_momentary (); + finish_function (lineno, 0); +} + +void +build_assign_ref (fndecl) + tree fndecl; +{ + tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl)); + + start_function (NULL_TREE, fndecl, NULL_TREE, 1); + store_parm_decls (); + push_momentary (); + + parm = convert_from_reference (parm); + + if (! TYPE_HAS_COMPLEX_ASSIGN_REF (current_class_type)) + { + tree t = build (MODIFY_EXPR, void_type_node, C_C_D, parm); + TREE_SIDE_EFFECTS (t) = 1; + cplus_expand_expr_stmt (t); + } + else + { + tree fields = TYPE_FIELDS (current_class_type); + int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type); + tree binfos = TYPE_BINFO_BASETYPES (current_class_type); + int i; + + for (i = 0; i < n_bases; ++i) + { + tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i)); + if (TYPE_HAS_ASSIGN_REF (basetype)) + { + tree p = convert (build_reference_type (basetype), parm); + p = convert_from_reference (p); + p = build_member_call (TYPE_NESTED_NAME (basetype), + ansi_opname [MODIFY_EXPR], + build_tree_list (NULL_TREE, p)); + expand_expr_stmt (p); + } + } + for (; fields; fields = TREE_CHAIN (fields)) + { + tree comp, init; + if (TREE_CODE (fields) != FIELD_DECL) + continue; + if (DECL_NAME (fields)) + { + if (VFIELD_NAME_P (DECL_NAME (fields))) + continue; + if (VBASE_NAME_P (DECL_NAME (fields))) + continue; + + /* True for duplicate members. */ + if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields) + continue; + } + + comp = build (COMPONENT_REF, TREE_TYPE (fields), C_C_D, fields); + init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields); + + expand_expr_stmt (build_modify_expr (comp, NOP_EXPR, init)); + } + } + c_expand_return (C_C_D); + pop_momentary (); + finish_function (lineno, 0); +} + +void +build_dtor (fndecl) + tree fndecl; +{ + start_function (NULL_TREE, fndecl, NULL_TREE, 1); + store_parm_decls (); + finish_function (lineno, 0); +} diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index ce0a637..36c8aac 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -3436,6 +3436,8 @@ label_colon: } | PTYPENAME ':' { goto do_label; } + | TYPENAME ':' + { goto do_label; } ; forhead.1: diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 94dc9fa..ad60480 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -333,7 +333,7 @@ grok_template_type (tvec, type) { /* we are here for cases like const T* etc. */ grok_template_type (tvec, &TYPE_MAIN_VARIANT (*type)); - *type = c_build_type_variant (TYPE_MAIN_VARIANT (*type), + *type = cp_build_type_variant (TYPE_MAIN_VARIANT (*type), TYPE_READONLY (*type), TYPE_VOLATILE (*type)); } @@ -430,7 +430,8 @@ coerce_template_parms (parms, arglist, in_decl) if (is_type != requires_type) { if (in_decl) - cp_error_at ("type/value mismatch in template parameter list for `%D'", in_decl); + cp_error ("type/value mismatch in template parameter list for `%D'", + in_decl); lost++; TREE_VEC_ELT (vec, i) = error_mark_node; continue; @@ -897,15 +898,18 @@ instantiate_member_templates (classname) &TREE_VEC_ELT (parmvec, 0)); type = IDENTIFIER_TYPE_VALUE (id); my_friendly_assert (type != 0, 277); - if (CLASSTYPE_INTERFACE_UNKNOWN (type)) + if (flag_external_templates) { - DECL_EXTERNAL (t2) = 0; - TREE_PUBLIC (t2) = 0; - } - else - { - DECL_EXTERNAL (t2) = CLASSTYPE_INTERFACE_ONLY (type); - TREE_PUBLIC (t2) = 1; + if (CLASSTYPE_INTERFACE_UNKNOWN (type)) + { + DECL_EXTERNAL (t2) = 0; + TREE_PUBLIC (t2) = 0; + } + else + { + DECL_EXTERNAL (t2) = CLASSTYPE_INTERFACE_ONLY (type); + TREE_PUBLIC (t2) = 1; + } } break; case 1: @@ -1157,7 +1161,7 @@ tsubst (t, args, nargs, in_decl) && type != integer_type_node && type != void_type_node && type != char_type_node) - type = c_build_type_variant (tsubst (type, args, nargs, in_decl), + type = cp_build_type_variant (tsubst (type, args, nargs, in_decl), TYPE_READONLY (type), TYPE_VOLATILE (type)); switch (TREE_CODE (t)) @@ -1194,7 +1198,7 @@ tsubst (t, args, nargs, in_decl) tsubst (TYPE_MAX_VALUE (t), args, nargs, in_decl)); case TEMPLATE_TYPE_PARM: - return c_build_type_variant (args[TEMPLATE_TYPE_IDX (t)], + return cp_build_type_variant (args[TEMPLATE_TYPE_IDX (t)], TYPE_READONLY (t), TYPE_VOLATILE (t)); @@ -1388,9 +1392,10 @@ tsubst (t, args, nargs, in_decl) if (!got_it) { - r = build_decl_overload (r, TYPE_VALUES (type), - DECL_CONTEXT (t) != NULL_TREE); + tree a = build_decl_overload (r, TYPE_VALUES (type), + DECL_CONTEXT (t) != NULL_TREE); r = build_lang_decl (FUNCTION_DECL, r, type); + DECL_ASSEMBLER_NAME (r) = a; } else if (DECL_INLINE (r) && DECL_SAVED_INSNS (r)) { @@ -1424,9 +1429,11 @@ tsubst (t, args, nargs, in_decl) make_decl_rtl (r, NULL_PTR, 1); DECL_ARGUMENTS (r) = fnargs; DECL_RESULT (r) = result; +#if 0 if (DECL_CONTEXT (t) == NULL_TREE || TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) != 't') push_overloaded_decl_top_level (r, 0); +#endif return r; } @@ -1504,7 +1511,7 @@ tsubst (t, args, nargs, in_decl) r = build_pointer_type (type); else r = build_reference_type (type); - r = c_build_type_variant (r, TYPE_READONLY (t), TYPE_VOLATILE (t)); + r = cp_build_type_variant (r, TYPE_READONLY (t), TYPE_VOLATILE (t)); /* Will this ever be needed for TYPE_..._TO values? */ layout_type (r); return r; @@ -2137,7 +2144,10 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts) case REAL_TYPE: case INTEGER_TYPE: - if (TREE_CODE (parm) == INTEGER_TYPE && TREE_CODE (arg) == INTEGER_TYPE) + if (TREE_CODE (arg) != TREE_CODE (parm)) + return 1; + + if (TREE_CODE (parm) == INTEGER_TYPE) { if (TYPE_MIN_VALUE (parm) && TYPE_MIN_VALUE (arg) && unify (tparms, targs, ntparms, @@ -2464,22 +2474,32 @@ do_type_instantiation (name, storage) return; } - SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t); - if (! extern_p) + if (! CLASSTYPE_TEMPLATE_SPECIALIZATION (t)) { - SET_CLASSTYPE_INTERFACE_KNOWN (t); - CLASSTYPE_INTERFACE_ONLY (t) = 0; - CLASSTYPE_VTABLE_NEEDS_WRITING (t) = 1; - CLASSTYPE_DEBUG_REQUESTED (t) = 1; - TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0; - rest_of_type_compilation (t, 1); + SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t); + if (! extern_p) + { + SET_CLASSTYPE_INTERFACE_KNOWN (t); + CLASSTYPE_INTERFACE_ONLY (t) = 0; + CLASSTYPE_VTABLE_NEEDS_WRITING (t) = 1; + CLASSTYPE_DEBUG_REQUESTED (t) = 1; + TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0; + rest_of_type_compilation (t, 1); + } } + instantiate_member_templates (TYPE_IDENTIFIER (t)); + /* this should really be done by instantiate_member_templates */ { tree tmp = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0); for (; tmp; tmp = TREE_CHAIN (tmp)) { + if (DECL_TEMPLATE_SPECIALIZATION (tmp) + || (DECL_USE_TEMPLATE (tmp) == 0 + && CLASSTYPE_TEMPLATE_SPECIALIZATION (t))) + continue; + SET_DECL_EXPLICIT_INSTANTIATION (tmp); if (! extern_p) { @@ -2498,7 +2518,8 @@ do_type_instantiation (name, storage) #endif for (tmp = CLASSTYPE_TAGS (t); tmp; tmp = TREE_CHAIN (tmp)) - do_type_instantiation (TREE_VALUE (tmp), storage); + if (IS_AGGR_TYPE (TREE_VALUE (tmp))) + do_type_instantiation (TYPE_MAIN_DECL (TREE_VALUE (tmp)), storage); } } diff --git a/gcc/cp/sig.c b/gcc/cp/sig.c index 1426168..65938b3 100644 --- a/gcc/cp/sig.c +++ b/gcc/cp/sig.c @@ -177,7 +177,7 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp) } else { - tree sig_tbl_type = c_build_type_variant (to_type, 1, 0); + tree sig_tbl_type = cp_build_type_variant (to_type, 1, 0); sptr = build_lang_field_decl (FIELD_DECL, get_identifier (SIGNATURE_SPTR_NAME), diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index e22ec29..f598fe0e 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -230,12 +230,15 @@ break_out_calls (exp) return exp; case 'd': /* A decl node */ +#if 0 /* This is bogus. jason 9/21/94 */ + t1 = break_out_calls (DECL_INITIAL (exp)); if (t1 != DECL_INITIAL (exp)) { exp = copy_node (exp); DECL_INITIAL (exp) = t1; } +#endif return exp; case 'b': /* A block node */ @@ -388,6 +391,40 @@ build_cplus_array_type (elt_type, index_type) return t; } +/* Make a variant type in the proper way for C/C++, propagating qualifiers + down to the element type of an array. */ + +tree +cp_build_type_variant (type, constp, volatilep) + tree type; + int constp, volatilep; +{ + if (TREE_CODE (type) == ARRAY_TYPE) + { + tree real_main_variant = TYPE_MAIN_VARIANT (type); + + push_obstacks (TYPE_OBSTACK (real_main_variant), + TYPE_OBSTACK (real_main_variant)); + type = build_cplus_array_type (cp_build_type_variant (TREE_TYPE (type), + constp, volatilep), + TYPE_DOMAIN (type)); + + /* TYPE must be on same obstack as REAL_MAIN_VARIANT. If not, + make a copy. (TYPE might have come from the hash table and + REAL_MAIN_VARIANT might be in some function's obstack.) */ + + if (TYPE_OBSTACK (type) != TYPE_OBSTACK (real_main_variant)) + { + type = copy_node (type); + TYPE_POINTER_TO (type) = TYPE_REFERENCE_TO (type) = 0; + } + + TYPE_MAIN_VARIANT (type) = real_main_variant; + pop_obstacks (); + } + return build_type_variant (type, constp, volatilep); +} + /* Add OFFSET to all base types of T. OFFSET, which is a type offset, is number of bytes. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 4d7e334..b4b7e2d 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -161,7 +161,7 @@ qualify_type (type, like) int constflag = TYPE_READONLY (type) || TYPE_READONLY (like); int volflag = TYPE_VOLATILE (type) || TYPE_VOLATILE (like); /* @@ Must do member pointers here. */ - return c_build_type_variant (type, constflag, volflag); + return cp_build_type_variant (type, constflag, volflag); } /* Return the common type of two parameter lists. @@ -372,7 +372,7 @@ common_type (t1, t2) = TYPE_READONLY (TREE_TYPE (t1)) || TYPE_READONLY (TREE_TYPE (t2)); int volatilep = TYPE_VOLATILE (TREE_TYPE (t1)) || TYPE_VOLATILE (TREE_TYPE (t2)); - target = c_build_type_variant (target, constp, volatilep); + target = cp_build_type_variant (target, constp, volatilep); if (code1 == POINTER_TYPE) t1 = build_pointer_type (target); else @@ -1378,7 +1378,7 @@ default_conversion (exp) restype = TREE_TYPE (type); if (TYPE_READONLY (type) || TYPE_VOLATILE (type) || constp || volatilep) - restype = c_build_type_variant (restype, + restype = cp_build_type_variant (restype, TYPE_READONLY (type) || constp, TYPE_VOLATILE (type) || volatilep); ptrtype = build_pointer_type (restype); @@ -1533,8 +1533,7 @@ build_component_ref (datum, component, basetype_path, protect) register tree field = NULL; register tree ref; - /* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference inside it - unless we are not to support things not strictly ANSI. */ + /* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference inside it. */ switch (TREE_CODE (datum)) { case COMPOUND_EXPR: @@ -1706,7 +1705,8 @@ build_component_ref (datum, component, basetype_path, protect) datum = build_indirect_ref (addr, NULL_PTR); my_friendly_assert (datum != error_mark_node, 311); } - ref = build (COMPONENT_REF, TREE_TYPE (field), break_out_cleanups (datum), field); + ref = fold (build (COMPONENT_REF, TREE_TYPE (field), + break_out_cleanups (datum), field)); if (TREE_READONLY (datum) || TREE_READONLY (field)) TREE_READONLY (ref) = 1; @@ -2619,7 +2619,7 @@ convert_arguments (return_loc, typelist, values, fndecl, flags) /* See if there are default arguments that can be used */ if (TREE_PURPOSE (typetail)) { - while (typetail != void_list_node) + for (; typetail != void_list_node; ++i) { tree type = TREE_VALUE (typetail); tree val = TREE_PURPOSE (typetail); @@ -4102,42 +4102,16 @@ build_unary_op (code, xarg, noconvert) if (TREE_CODE (arg) == TREE_LIST) { - /* Look at methods with only this name. */ - if (TREE_CODE (TREE_VALUE (arg)) == FUNCTION_DECL) - { - tree targ = TREE_VALUE (arg); - - /* If this function is unique, or it is a unique - constructor, we can take its address easily. */ - if (DECL_CHAIN (targ) == NULL_TREE - || (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (targ)) - && DECL_CHAIN (DECL_CHAIN (targ)) == NULL_TREE)) - { - if (DECL_CHAIN (targ)) - targ = DECL_CHAIN (targ); - if (DECL_CLASS_CONTEXT (targ)) - targ = build (OFFSET_REF, TREE_TYPE (targ), C_C_D, targ); - - val = unary_complex_lvalue (ADDR_EXPR, targ); - if (val) - return val; - } - - /* This possible setting of TREE_CONSTANT is what makes it possible - with an initializer list to emit the entire thing in the data - section, rather than a run-time initialization. */ - arg = build1 (ADDR_EXPR, unknown_type_node, arg); - if (staticp (targ)) - TREE_CONSTANT (arg) = 1; - return arg; - } + if (TREE_CODE (TREE_VALUE (arg)) == FUNCTION_DECL + && DECL_CHAIN (TREE_VALUE (arg)) == NULL_TREE) + /* Unique overloaded non-member function. */ + return build_unary_op (ADDR_EXPR, TREE_VALUE (arg), 0); if (TREE_CHAIN (arg) == NULL_TREE && TREE_CODE (TREE_VALUE (arg)) == TREE_LIST && DECL_CHAIN (TREE_VALUE (TREE_VALUE (arg))) == NULL_TREE) - { - /* Unique overloaded member function. */ - return build_unary_op (ADDR_EXPR, TREE_VALUE (TREE_VALUE (arg)), 0); - } + /* Unique overloaded member function. */ + return build_unary_op (ADDR_EXPR, TREE_VALUE (TREE_VALUE (arg)), + 0); return build1 (ADDR_EXPR, unknown_type_node, arg); } @@ -4179,7 +4153,7 @@ build_unary_op (code, xarg, noconvert) || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r') { if (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg)) - argtype = c_build_type_variant (argtype, + argtype = cp_build_type_variant (argtype, TREE_READONLY (arg), TREE_THIS_VOLATILE (arg)); } @@ -4587,7 +4561,7 @@ build_conditional_expr (ifexp, op1, op2) else if (TREE_READONLY_DECL_P (op2)) op2 = decl_constant_value (op2); if (type1 != type2) - type1 = c_build_type_variant + type1 = cp_build_type_variant (type1, TREE_READONLY (op1) || TREE_READONLY (op2), TREE_THIS_VOLATILE (op1) || TREE_THIS_VOLATILE (op2)); @@ -4636,7 +4610,7 @@ build_conditional_expr (ifexp, op1, op2) if (type1 == type2) result_type = type1; else - result_type = c_build_type_variant + result_type = cp_build_type_variant (type1, TREE_READONLY (op1) || TREE_READONLY (op2), TREE_THIS_VOLATILE (op1) || TREE_THIS_VOLATILE (op2)); @@ -5025,6 +4999,9 @@ build_c_cast (type, expr) warning ("cast to pointer from integer of different size"); #endif + if (TREE_READONLY_DECL_P (value)) + value = decl_constant_value (value); + ovalue = value; value = convert_force (type, value); @@ -5349,13 +5326,13 @@ build_modify_expr (lhs, modifycode, rhs) tree olhstype = lhstype; tree olhs = lhs; - /* Types that aren't fully specified cannot be used in assignments. */ - lhs = require_complete_type (lhs); - /* Avoid duplicate error messages from operands that had errors. */ if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK) return error_mark_node; + /* Types that aren't fully specified cannot be used in assignments. */ + lhs = require_complete_type (lhs); + /* Decide early if we are going to protect RHS from GC before assigning it to LHS. */ if (type_needs_gc_entry (TREE_TYPE (rhs)) @@ -5786,10 +5763,12 @@ build_modify_expr (lhs, modifycode, rhs) if (TREE_CODE (lhstype) == ARRAY_TYPE) { + int from_array; + /* Allow array assignment in compiler-generated code. */ if ((pedantic || flag_ansi) && ! DECL_ARTIFICIAL (current_function_decl)) - pedwarn ("ANSI C++ forbids assignment between arrays"); + pedwarn ("ANSI C++ forbids assignment of arrays"); /* Have to wrap this in RTL_EXPR for two cases: in base or member initialization and if we @@ -5805,8 +5784,10 @@ build_modify_expr (lhs, modifycode, rhs) /* As a matter of principle, `start_sequence' should do this. */ emit_note (0, -1); + from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE + ? 1 + (modifycode != INIT_EXPR): 0; expand_vec_init (lhs, lhs, array_type_nelts (lhstype), newrhs, - 1 + (modifycode != INIT_EXPR)); + from_array); do_pending_stack_adjust (); @@ -6124,12 +6105,15 @@ build_ptrmemfunc (type, pfn, force) return digest_init (TYPE_GET_PTRMEMFUNC_TYPE (type), u, (tree*)0); } - if (TREE_CODE (pfn) == TREE_LIST) + if (TREE_CODE (pfn) == TREE_LIST + || (TREE_CODE (pfn) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (pfn, 0)) == TREE_LIST)) { pfn = instantiate_type (type, pfn, 1); if (pfn == error_mark_node) return error_mark_node; - pfn = build_unary_op (ADDR_EXPR, pfn, 0); + if (TREE_CODE (pfn) != ADDR_EXPR) + pfn = build_unary_op (ADDR_EXPR, pfn, 0); } /* Allow pointer to member conversions here. */ @@ -6585,10 +6569,11 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) } return null_pointer_node; } - else if (codel == INTEGER_TYPE + else if ((codel == INTEGER_TYPE || codel == BOOLEAN_TYPE) && (coder == POINTER_TYPE || (coder == RECORD_TYPE && (IS_SIGNATURE_POINTER (rhstype) + || TYPE_PTRMEMFUNC_FLAG (rhstype) || IS_SIGNATURE_REFERENCE (rhstype))))) { if (fndecl) @@ -6741,7 +6726,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum) && (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type))) return build_signature_pointer_constructor (type, rhs); - if (IS_AGGR_TYPE (type) && TYPE_NEEDS_CONSTRUCTING (type)) + if (IS_AGGR_TYPE (type) + && (TYPE_NEEDS_CONSTRUCTING (type) || TREE_HAS_CONSTRUCTOR (rhs))) { if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype)) { @@ -6997,8 +6983,11 @@ c_expand_return (retval) while (TREE_CODE (whats_returned) == NEW_EXPR || TREE_CODE (whats_returned) == TARGET_EXPR || TREE_CODE (whats_returned) == WITH_CLEANUP_EXPR) - /* Get the target. */ - whats_returned = TREE_OPERAND (whats_returned, 0); + { + /* Get the target. */ + whats_returned = TREE_OPERAND (whats_returned, 0); + warning ("returning reference to temporary"); + } } if (TREE_CODE (whats_returned) == VAR_DECL && DECL_NAME (whats_returned)) diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 8813b48..65e4ba7 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -599,6 +599,7 @@ store_init_value (decl, init) )) return value; +#if 0 /* No, that's C. jason 9/19/94 */ else { if (pedantic && TREE_CODE (value) == CONSTRUCTOR @@ -613,6 +614,7 @@ store_init_value (decl, init) pedwarn ("ANSI C++ forbids non-constant aggregate initializer expressions"); } } +#endif DECL_INITIAL (decl) = value; return NULL_TREE; } @@ -659,8 +661,9 @@ digest_init (type, init, tail) if (init && TYPE_PTRMEMFUNC_P (type) && ((TREE_CODE (init) == ADDR_EXPR - && TREE_CODE (TREE_TYPE (init)) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (TREE_TYPE (init))) == METHOD_TYPE) + && ((TREE_CODE (TREE_TYPE (init)) == POINTER_TYPE + && TREE_CODE (TREE_TYPE (TREE_TYPE (init))) == METHOD_TYPE) + || TREE_CODE (TREE_OPERAND (init, 0)) == TREE_LIST)) || TREE_CODE (init) == TREE_LIST || integer_zerop (init) || (TREE_TYPE (init) && TYPE_PTRMEMFUNC_P (TREE_TYPE (init))))) |