aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMike Stump <mrs@gcc.gnu.org>1994-09-26 20:15:18 +0000
committerMike Stump <mrs@gcc.gnu.org>1994-09-26 20:15:18 +0000
commitf376e137d46ac34615746a297d8bc1d9f9fd7eca (patch)
treef9c0f819ae41cf6e844789463888bb2e000eedcd /gcc
parent96f218bb2aa467606a31c67b3f64c0ac04457f25 (diff)
downloadgcc-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/ChangeLog302
-rw-r--r--gcc/cp/call.c32
-rw-r--r--gcc/cp/class.c89
-rw-r--r--gcc/cp/cp-tree.h11
-rw-r--r--gcc/cp/cvt.c8
-rw-r--r--gcc/cp/decl.c264
-rw-r--r--gcc/cp/decl2.c51
-rw-r--r--gcc/cp/error.c30
-rw-r--r--gcc/cp/except.c94
-rw-r--r--gcc/cp/init.c13
-rw-r--r--gcc/cp/lex.c143
-rw-r--r--gcc/cp/method.c190
-rw-r--r--gcc/cp/parse.y2
-rw-r--r--gcc/cp/pt.c71
-rw-r--r--gcc/cp/sig.c2
-rw-r--r--gcc/cp/tree.c37
-rw-r--r--gcc/cp/typeck.c97
-rw-r--r--gcc/cp/typeck2.c7
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)))))