Commit f376e137 by Mike Stump

47th Cygnus<->FSF merge

From-SVN: r8129
parent 96f218bb
......@@ -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)
{
......
......@@ -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:
......
......@@ -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));
......
......@@ -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);
}
......@@ -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);
......
......@@ -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 *
......
......@@ -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
......
......@@ -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;
}
......
......@@ -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
......
......@@ -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);
}
......@@ -3436,6 +3436,8 @@ label_colon:
}
| PTYPENAME ':'
{ goto do_label; }
| TYPENAME ':'
{ goto do_label; }
;
forhead.1:
......
......@@ -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);
}
}
......
......@@ -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),
......
......@@ -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.
......
......@@ -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))
......
......@@ -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)))))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment