Commit 6467930b by Mike Stump

*** empty log message ***

From-SVN: r12602
parent 7a389b48
......@@ -238,7 +238,7 @@ search.o : search.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../stack.h $(srcdir)/../
tree.o : tree.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h
ptree.o : ptree.c $(CONFIG_H) $(CXX_TREE_H)
rtti.o : rtti.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h
except.o : except.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H)
except.o : except.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) $(srcdir)/../except.h
expr.o : expr.c $(CONFIG_H) $(CXX_TREE_H) $(RTL_H) $(srcdir)/../flags.h \
$(srcdir)/../expr.h ../insn-codes.h
xref.o : xref.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../input.h
......
......@@ -2792,7 +2792,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, require_complete)
i = type_unification (DECL_TEMPLATE_PARMS (function), targs,
TYPE_ARG_TYPES (TREE_TYPE (function)),
parms, &template_cost, 0);
parms, &template_cost, 0, 0);
if (i == 0)
{
function = instantiate_template (function, targs);
......
......@@ -3017,8 +3017,8 @@ extern int interface_only, interface_unknown;
or otherwise in a type-consistent manner. */
tree
finish_struct_1 (t, attributes, warn_anon)
tree t, attributes;
finish_struct_1 (t, warn_anon)
tree t;
int warn_anon;
{
int old;
......@@ -3073,8 +3073,6 @@ finish_struct_1 (t, attributes, warn_anon)
TYPE_SIZE (t) = NULL_TREE;
CLASSTYPE_GOT_SEMICOLON (t) = 0;
cplus_decl_attributes (t, attributes, NULL_TREE);
#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? */
......@@ -4371,6 +4369,8 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
*tail = NULL_TREE;
TYPE_FIELDS (t) = fields;
cplus_decl_attributes (t, attributes, NULL_TREE);
if (processing_template_decl)
{
tree d = getdecls ();
......@@ -4395,7 +4395,7 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon)
TYPE_SIZE (t) = integer_zero_node;
}
else
t = finish_struct_1 (t, attributes, warn_anon);
t = finish_struct_1 (t, warn_anon);
TYPE_BEING_DEFINED (t) = 0;
......@@ -4997,7 +4997,7 @@ instantiate_type (lhstype, rhs, complain)
int i, d = 0;
i = type_unification (DECL_TEMPLATE_PARMS (elem), t,
TYPE_ARG_TYPES (TREE_TYPE (elem)),
TYPE_ARG_TYPES (lhstype), &d, 0);
TYPE_ARG_TYPES (lhstype), &d, 0, 1);
if (i == 0)
{
if (save_elem)
......
......@@ -138,7 +138,7 @@ DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", "e", 2)
DEFTREECODE (CASE_LABEL, "case_label", "e", 2)
DEFTREECODE (RETURN_INIT, "return_init", "e", 2)
DEFTREECODE (EXACT_CONV, "exact_conv", "e", 1)
DEFTREECODE (IDENTITY_CONV, "identity_conv", "e", 1)
DEFTREECODE (LVALUE_CONV, "lvalue_conv", "e", 1)
DEFTREECODE (QUAL_CONV, "qual_conv", "e", 1)
DEFTREECODE (STD_CONV, "std_conv", "e", 1)
......@@ -148,3 +148,4 @@ DEFTREECODE (BASE_CONV, "base_conv", "e", 1)
DEFTREECODE (REF_BIND, "ref_bind", "e", 1)
DEFTREECODE (USER_CONV, "user_conv", "e", 4)
DEFTREECODE (AMBIG_CONV, "ambig_conv", "e", 1)
DEFTREECODE (RVALUE_CONV, "rvalue_conv", "e", 1)
......@@ -295,11 +295,6 @@ extern int flag_elide_constructors;
extern int flag_ansi;
/* Nonzero means recognize and handle ansi-style exception handling
constructs. */
extern int flag_handle_exceptions;
/* Nonzero means recognize and handle signature language constructs. */
extern int flag_handle_signatures;
......@@ -336,8 +331,8 @@ enum languages { lang_c, lang_cplusplus };
#define IS_AGGR_TYPE_2(TYPE1,TYPE2) \
(TREE_CODE (TYPE1) == TREE_CODE (TYPE2) \
&& IS_AGGR_TYPE (TYPE1)&IS_AGGR_TYPE (TYPE2))
#define IS_OVERLOAD_TYPE_CODE(t) (IS_AGGR_TYPE_CODE (t) || t == ENUMERAL_TYPE)
#define IS_OVERLOAD_TYPE(t) (IS_OVERLOAD_TYPE_CODE (TREE_CODE (t)))
#define IS_OVERLOAD_TYPE(t) \
(IS_AGGR_TYPE (t) || TREE_CODE (t) == ENUMERAL_TYPE)
/* In a *_TYPE, nonzero means a built-in type. */
#define TYPE_BUILT_IN(NODE) TYPE_LANG_FLAG_6(NODE)
......@@ -1951,7 +1946,7 @@ extern void add_method PROTO((tree, tree *, tree));
extern tree get_vfield_offset PROTO((tree));
extern void duplicate_tag_error PROTO((tree));
extern tree finish_struct PROTO((tree, tree, tree, int));
extern tree finish_struct_1 PROTO((tree, tree, int));
extern tree finish_struct_1 PROTO((tree, int));
extern tree finish_struct_methods PROTO((tree, tree, int));
extern int resolves_to_fixed_type_p PROTO((tree, int *));
extern void init_class_processing PROTO((void));
......@@ -2122,9 +2117,9 @@ extern void mark_used PROTO((tree));
/* in except.c */
extern tree protect_list;
extern void start_protect PROTO((void));
extern void end_protect PROTO((tree));
extern void end_protect_partials ();
extern void expand_eh_region_start PROTO((void));
extern void expand_eh_region_end PROTO((tree));
extern void end_protect_partials PROTO((void));
extern void expand_exception_blocks PROTO((void));
extern void expand_start_try_stmts PROTO((void));
extern void expand_end_try_stmts PROTO((void));
......@@ -2133,8 +2128,6 @@ 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 int might_have_exceptions_p PROTO((void));
extern void emit_exception_table PROTO((void));
extern tree build_throw PROTO((tree));
extern void init_exception_processing PROTO((void));
extern void expand_builtin_throw PROTO((void));
......@@ -2292,7 +2285,7 @@ extern int uses_template_parms PROTO((tree));
extern tree instantiate_class_template PROTO((tree));
extern tree instantiate_template PROTO((tree, tree *));
extern void overload_template_name PROTO((tree));
extern int type_unification PROTO((tree, tree *, tree, tree, int *, int));
extern int type_unification PROTO((tree, tree *, tree, tree, int *, int, int));
struct tinst_level *tinst_for_decl PROTO((void));
extern void mark_decl_instantiated PROTO((tree, int));
extern void mark_class_instantiated PROTO((tree, int));
......
......@@ -126,8 +126,6 @@ static struct stack_level *decl_stack;
static tree grokparms PROTO((tree, int));
static tree lookup_nested_type PROTO((tree, tree));
static char *redeclaration_error_message PROTO((tree, tree));
extern void* push_eh_context PROTO(());
extern void pop_eh_context PROTO((void *));
tree define_function
PROTO((char *, tree, enum built_in_function, void (*)(), char *));
......@@ -5493,7 +5491,7 @@ init_decl_processing ()
init_search_processing ();
init_rtti_processing ();
if (flag_handle_exceptions)
if (flag_exceptions)
init_exception_processing ();
if (flag_no_inline)
{
......@@ -10892,7 +10890,6 @@ start_function (declspecs, declarator, raises, attrs, pre_parsed_p)
current_function_parms_stored = 0;
original_result_rtx = NULL_RTX;
base_init_expr = NULL_TREE;
protect_list = NULL_TREE;
current_base_init_list = NULL_TREE;
current_member_init_list = NULL_TREE;
ctor_label = dtor_label = NULL_TREE;
......@@ -11092,7 +11089,11 @@ start_function (declspecs, declarator, raises, attrs, pre_parsed_p)
= (interface_only
|| (DECL_THIS_INLINE (decl1) && ! flag_implement_inlines));
else
DECL_EXTERNAL (decl1) = 0;
{
DECL_EXTERNAL (decl1) = 0;
if (DECL_C_STATIC (decl1))
TREE_PUBLIC (decl1) = 0;
}
DECL_NOT_REALLY_EXTERN (decl1) = 0;
DECL_INTERFACE_KNOWN (decl1) = 1;
}
......@@ -11227,27 +11228,44 @@ start_function (declspecs, declarator, raises, attrs, pre_parsed_p)
}
void
expand_start_early_try_stmts ()
{
rtx insns;
start_sequence ();
expand_start_try_stmts ();
insns = get_insns ();
end_sequence ();
store_in_parms (insns);
}
void
store_in_parms (insns)
store_after_parms (insns)
rtx insns;
{
rtx last_parm_insn;
rtx x;
for (x = get_insns (); x; x = next_insn (x))
{
if (GET_CODE (x) == NOTE && NOTE_LINE_NUMBER (x) == NOTE_INSN_FUNCTION_BEG)
{
emit_insns_after (insns, x);
return;
}
}
#if 0
/* This doesn't work, because the inline output routine doesn't reset
last_parm_insn correctly for get_first_nonparm_insn () to work. */
last_parm_insn = get_first_nonparm_insn ();
if (last_parm_insn == NULL_RTX)
emit_insns (insns);
else
emit_insns_before (insns, previous_insn (last_parm_insn));
emit_insns_before (insns, last_parm_insn);
#endif
}
void
expand_start_early_try_stmts ()
{
rtx insns;
start_sequence ();
expand_start_try_stmts ();
insns = get_insns ();
end_sequence ();
#if 1
emit_insns_after (insns, get_insns ());
#else
store_after_parms (insns);
#endif
}
/* Store the parameter declarations into the current function declaration.
......@@ -11395,23 +11413,27 @@ store_parm_decls ()
}
/* Take care of exception handling things. */
if (! current_template_parms && flag_handle_exceptions)
if (! current_template_parms && flag_exceptions)
{
rtx insns;
start_sequence ();
#if 0
/* Mark the start of a stack unwinder if we need one. */
start_eh_unwinder ();
#endif
#if 0
/* Do the starting of the exception specifications, if we have any. */
if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
expand_start_eh_spec ();
#endif
insns = get_insns ();
end_sequence ();
if (insns)
store_in_parms (insns);
store_after_parms (insns);
}
last_dtor_insn = get_last_insn ();
}
......@@ -11915,7 +11937,7 @@ finish_function (lineno, call_poplevel, nested)
/* Generate rtl for function exit. */
expand_function_end (input_filename, lineno, 1);
if (flag_handle_exceptions)
if (flag_exceptions)
expand_exception_blocks ();
}
......@@ -12478,7 +12500,6 @@ struct cp_function
tree ctor_label;
tree dtor_label;
rtx last_dtor_insn;
tree protect_list;
tree base_init_list;
tree member_init_list;
tree base_init_expr;
......@@ -12487,7 +12508,6 @@ struct cp_function
rtx result_rtx;
struct cp_function *next;
struct binding_level *binding_level;
void* eh_context;
};
......@@ -12525,14 +12545,11 @@ push_cp_function_context (context)
p->parms_stored = current_function_parms_stored;
p->result_rtx = original_result_rtx;
p->base_init_expr = base_init_expr;
p->protect_list = protect_list;
p->temp_name_counter = temp_name_counter;
p->base_init_list = current_base_init_list;
p->member_init_list = current_member_init_list;
p->current_class_ptr = current_class_ptr;
p->current_class_ref = current_class_ref;
p->eh_context = push_eh_context ();
}
/* Restore the variables used during compilation of a C++ function. */
......@@ -12563,7 +12580,6 @@ pop_cp_function_context (context)
ctor_label = p->ctor_label;
dtor_label = p->dtor_label;
last_dtor_insn = p->last_dtor_insn;
protect_list = p->protect_list;
current_function_assigns_this = p->assigns_this;
current_function_just_assigned_this = p->just_assigned_this;
current_function_parms_stored = p->parms_stored;
......@@ -12575,8 +12591,6 @@ pop_cp_function_context (context)
current_class_ptr = p->current_class_ptr;
current_class_ref = p->current_class_ref;
pop_eh_context (p->eh_context);
free (p);
}
......
......@@ -155,7 +155,7 @@ int warn_implicit = 1;
int warn_ctor_dtor_privacy = 1;
/* True if we want to implement vtables using "thunks".
The default is off by default, on if explicitly supported. */
The default is off. */
int flag_vtable_thunks;
......@@ -301,11 +301,6 @@ int write_virtuals;
int flag_elide_constructors;
/* Nonzero means recognize and handle exception handling constructs.
Use ansi syntax and semantics. WORK IN PROGRESS! */
int flag_handle_exceptions;
/* Nonzero means recognize and handle signature language constructs. */
int flag_handle_signatures;
......@@ -405,7 +400,6 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
{"all-virtual", &flag_all_virtual, 1},
{"memoize-lookups", &flag_memoize_lookups, 1},
{"elide-constructors", &flag_elide_constructors, 1},
{"handle-exceptions", &flag_handle_exceptions, 1},
{"handle-signatures", &flag_handle_signatures, 1},
{"default-inline", &flag_default_inline, 1},
{"dollars-in-identifiers", &dollars_in_ident, 1},
......@@ -2542,10 +2536,6 @@ import_export_vtable (decl, type, final)
TREE_PUBLIC (decl) = 1;
DECL_WEAK (decl) = 1;
}
#ifdef ASM_OUTPUT_EXTERNAL
else if (TREE_PUBLIC (decl))
cp_error ("all virtual functions redeclared inline");
#endif
else
TREE_PUBLIC (decl) = 0;
DECL_EXTERNAL (decl) = 0;
......@@ -2995,7 +2985,7 @@ finish_file ()
vars = static_aggregates;
if (static_ctors || vars || might_have_exceptions_p ())
if (static_ctors || vars || exception_table_p ())
needs_messing_up = 1;
if (static_dtors)
needs_cleaning = 1;
......@@ -3096,7 +3086,7 @@ finish_file ()
push_momentary ();
expand_start_bindings (0);
if (might_have_exceptions_p ())
if (exception_table_p ())
register_exception_table ();
while (vars)
......@@ -3318,9 +3308,6 @@ finish_file ()
TREE_PUBLIC (vars) = 0;
}
if (might_have_exceptions_p ())
emit_exception_table ();
if (write_virtuals == 2)
{
/* Now complain about an virtual function tables promised
......
......@@ -720,6 +720,8 @@ dump_decl (t, v)
if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
dump_type (TREE_TYPE (t), v);
else if (TREE_TYPE (t) == NULL_TREE)
my_friendly_abort (353);
else switch (NEXT_CODE (t))
{
case METHOD_TYPE:
......@@ -738,7 +740,7 @@ dump_decl (t, v)
break;
case CONST_DECL:
if (NEXT_CODE (t) == ENUMERAL_TYPE
if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE)
|| TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_CONST_PARM)
goto general;
else
......@@ -1075,7 +1077,7 @@ dump_expr (t, nop)
if (TREE_CODE (fn) == ADDR_EXPR)
fn = TREE_OPERAND (fn, 0);
if (NEXT_CODE (fn) == METHOD_TYPE)
if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE)
{
tree ob = TREE_VALUE (args);
if (TREE_CODE (ob) == ADDR_EXPR)
......@@ -1198,7 +1200,8 @@ dump_expr (t, nop)
}
else
{
if (NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
if (TREE_OPERAND (t,0) != NULL_TREE
&& NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
dump_expr (TREE_OPERAND (t, 0), nop);
else
dump_unary_op ("*", t, nop);
......@@ -1225,7 +1228,7 @@ dump_expr (t, nop)
/* FIXME: This is a KLUDGE workaround for a parsing problem. There
should be another level of INDIRECT_REF so that I don't have to do
this. */
if (NEXT_CODE (t) == POINTER_TYPE)
if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE)
{
tree next = TREE_TYPE (TREE_TYPE (t));
......@@ -1251,7 +1254,7 @@ dump_expr (t, nop)
case CONSTRUCTOR:
OB_PUTC ('{');
dump_expr_list (CONSTRUCTOR_ELTS (t), 0);
dump_expr_list (CONSTRUCTOR_ELTS (t));
OB_PUTC ('}');
break;
......@@ -1296,7 +1299,7 @@ dump_expr (t, nop)
{
dump_type (TREE_TYPE (t), 0);
OB_PUTC ('(');
dump_expr_list (TREE_OPERAND (t, 0), 0);
dump_expr_list (TREE_OPERAND (t, 0));
OB_PUTC (')');
}
else
......
......@@ -245,7 +245,7 @@ perform_member_init (member, name, init, explicit, protect_list)
if (expr != error_mark_node)
{
start_protect ();
expand_eh_region_start ();
*protect_list = tree_cons (NULL_TREE, expr, *protect_list);
}
}
......@@ -618,7 +618,7 @@ emit_base_init (t, immediately)
if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)))
{
start_protect ();
expand_eh_region_start ();
/* All cleanups must be on the function_obstack. */
push_obstacks_nochange ();
......@@ -3369,7 +3369,7 @@ expand_vec_init (decl, base, maxindex, init, from_array)
expand_start_cond (build (GE_EXPR, boolean_type_node,
iterator, integer_zero_node), 0);
if (TYPE_NEEDS_DESTRUCTOR (type))
start_protect ();
expand_eh_region_start ();
expand_start_loop_continue_elsewhere (1);
if (from_array)
......@@ -3429,7 +3429,7 @@ expand_vec_init (decl, base, maxindex, init, from_array)
use_variable (DECL_RTL (base2));
}
expand_end_loop ();
if (TYPE_NEEDS_DESTRUCTOR (type) && flag_handle_exceptions)
if (TYPE_NEEDS_DESTRUCTOR (type) && flag_exceptions)
{
/* We have to ensure that this can live to the cleanup
expansion time, since we know it is only ever needed
......@@ -3450,7 +3450,7 @@ expand_vec_init (decl, base, maxindex, init, from_array)
expand_expr (e1, const0_rtx, VOIDmode, 0);
RTL_EXPR_SEQUENCE (e2) = get_insns ();
end_sequence ();
end_protect (e2);
expand_eh_region_end (e2);
}
pop_obstacks ();
}
......
......@@ -50,8 +50,6 @@ Boston, MA 02111-1307, USA. */
"-fno-for-scope",
"-fgnu-keywords",
"-fno-gnu-keywords",
"-fhandle-exceptions",
"-fno-handle-exceptions",
"-fhandle-signatures",
"-fno-handle-signatures",
"-fhuge-objects",
......
......@@ -676,14 +676,14 @@ init_lex ()
opname_tab[(int) COMPONENT_REF] = "->";
opname_tab[(int) MEMBER_REF] = "->*";
opname_tab[(int) METHOD_CALL_EXPR] = "->()";
opname_tab[(int) INDIRECT_REF] = "(unary *)";
opname_tab[(int) INDIRECT_REF] = "*";
opname_tab[(int) ARRAY_REF] = "[]";
opname_tab[(int) MODIFY_EXPR] = "=";
opname_tab[(int) NEW_EXPR] = "new";
opname_tab[(int) DELETE_EXPR] = "delete";
opname_tab[(int) VEC_NEW_EXPR] = "new []";
opname_tab[(int) VEC_DELETE_EXPR] = "delete []";
opname_tab[(int) COND_EXPR] = "... ? ... : ...";
opname_tab[(int) COND_EXPR] = "?:";
opname_tab[(int) CALL_EXPR] = "()";
opname_tab[(int) PLUS_EXPR] = "+";
opname_tab[(int) MINUS_EXPR] = "-";
......@@ -720,9 +720,9 @@ init_lex ()
opname_tab[(int) EQ_EXPR] = "==";
opname_tab[(int) NE_EXPR] = "!=";
opname_tab[(int) IN_EXPR] = "in";
opname_tab[(int) RANGE_EXPR] = "..";
opname_tab[(int) CONVERT_EXPR] = "(unary +)";
opname_tab[(int) ADDR_EXPR] = "(unary &)";
opname_tab[(int) RANGE_EXPR] = "...";
opname_tab[(int) CONVERT_EXPR] = "+";
opname_tab[(int) ADDR_EXPR] = "&";
opname_tab[(int) PREDECREMENT_EXPR] = "--";
opname_tab[(int) PREINCREMENT_EXPR] = "++";
opname_tab[(int) POSTDECREMENT_EXPR] = "--";
......@@ -764,7 +764,7 @@ init_lex ()
#if 0
/* let's parse things, and if they use it, then give them an error. */
if (!flag_handle_exceptions)
if (!flag_exceptions)
{
UNSET_RESERVED_WORD ("throw");
UNSET_RESERVED_WORD ("try");
......@@ -3039,7 +3039,7 @@ real_yylex ()
|| strcmp ("try", token_buffer) == 0)
{
static int did_warn = 0;
if (! did_warn && ! flag_handle_exceptions)
if (! did_warn && ! flag_exceptions)
{
pedwarn ("`catch', `throw', and `try' are all C++ reserved words");
did_warn = 1;
......
......@@ -1193,6 +1193,10 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
int try_second;
int binary_is_unary;
#ifdef NEW_OVER
return build_new_op (code, flags, xarg1, xarg2, arg3);
#endif
if (xarg1 == error_mark_node)
return error_mark_node;
......@@ -2203,7 +2207,12 @@ synthesize_method (fndecl)
/* Turn off DECL_INLINE for the moment so function_cannot_inline_p
will check our size. */
DECL_INLINE (fndecl) = 0;
if (function_cannot_inline_p (fndecl) == 0)
/* We say !at_eof because at the end of the file some of the rtl
for fndecl may have been allocated on the temporary obstack.
(The function_obstack is the temporary one if we're not in a
function). */
if ((! at_eof) && function_cannot_inline_p (fndecl) == 0)
DECL_INLINE (fndecl) = 1;
}
......
......@@ -1181,6 +1181,8 @@ instantiate_class_template (type)
= TYPE_USES_COMPLEX_INHERITANCE (pattern);
TYPE_USES_VIRTUAL_BASECLASSES (type)
= TYPE_USES_VIRTUAL_BASECLASSES (pattern);
TYPE_PACKED (type) = TYPE_PACKED (pattern);
TYPE_ALIGN (type) = TYPE_ALIGN (pattern);
if (! uses_template_parms (type))
{
......@@ -1189,8 +1191,7 @@ instantiate_class_template (type)
if (TREE_CODE (tmp) == FIELD_DECL)
require_complete_type (tmp);
/* XXX handle attributes */
type = finish_struct_1 (type, NULL_TREE, 0);
type = finish_struct_1 (type, 0);
CLASSTYPE_GOT_SEMICOLON (type) = 1;
repo_template_used (type);
......@@ -2265,6 +2266,13 @@ tsubst_expr (t, args, nargs, in_decl)
error ("break statement not within loop or switch");
break;
case CONTINUE_STMT:
lineno = TREE_COMPLEXITY (t);
emit_line_note (input_filename, lineno);
if (! expand_continue_loop (0))
error ("continue statement not within a loop");
break;
case SWITCH_STMT:
{
tree val, tmp;
......@@ -2403,12 +2411,15 @@ overload_template_name (type)
If SUBR is 1, we're being called recursively (to unify the arguments of
a function or method parameter of a function template), so don't zero
out targs and don't fail on an incomplete match. */
out targs and don't fail on an incomplete match.
If STRICT is 1, the match must be exact (for casts of overloaded
addresses, explicit instantiation, and more_specialized). */
int
type_unification (tparms, targs, parms, args, nsubsts, subr)
type_unification (tparms, targs, parms, args, nsubsts, subr, strict)
tree tparms, *targs, parms, args;
int *nsubsts, subr;
int *nsubsts, subr, strict;
{
tree parm, arg;
int i;
......@@ -2472,7 +2483,7 @@ type_unification (tparms, targs, parms, args, nsubsts, subr)
parm = tree_cons (NULL_TREE, parm, NULL_TREE);
return type_unification (DECL_TEMPLATE_PARMS (arg), targs,
TYPE_ARG_TYPES (TREE_TYPE (arg)),
parm, &nsubsts, 0);
parm, &nsubsts, 0, strict);
}
arg = TREE_TYPE (arg);
}
......@@ -2491,7 +2502,7 @@ type_unification (tparms, targs, parms, args, nsubsts, subr)
arg = TYPE_MAIN_VARIANT (arg);
}
switch (unify (tparms, targs, ntparms, parm, arg, nsubsts))
switch (unify (tparms, targs, ntparms, parm, arg, nsubsts, strict))
{
case 0:
break;
......@@ -2521,9 +2532,9 @@ type_unification (tparms, targs, parms, args, nsubsts, subr)
/* Tail recursion is your friend. */
static int
unify (tparms, targs, ntparms, parm, arg, nsubsts)
unify (tparms, targs, ntparms, parm, arg, nsubsts, strict)
tree tparms, *targs, parm, arg;
int *nsubsts, ntparms;
int *nsubsts, ntparms, strict;
{
int idx;
......@@ -2546,6 +2557,9 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
case TEMPLATE_TYPE_PARM:
(*nsubsts)++;
idx = TEMPLATE_TYPE_IDX (parm);
if (strict && (TYPE_READONLY (arg) < TYPE_READONLY (parm)
|| TYPE_VOLATILE (arg) < TYPE_VOLATILE (parm)))
return 1;
#if 0
/* Template type parameters cannot contain cv-quals; i.e.
template <class T> void f (T& a, T& b) will not generate
......@@ -2606,26 +2620,27 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
case POINTER_TYPE:
if (TREE_CODE (arg) == RECORD_TYPE && TYPE_PTRMEMFUNC_FLAG (arg))
return unify (tparms, targs, ntparms, parm,
TYPE_PTRMEMFUNC_FN_TYPE (arg), nsubsts);
TYPE_PTRMEMFUNC_FN_TYPE (arg), nsubsts, strict);
if (TREE_CODE (arg) != POINTER_TYPE)
return 1;
return unify (tparms, targs, ntparms, TREE_TYPE (parm), TREE_TYPE (arg),
nsubsts);
nsubsts, strict);
case REFERENCE_TYPE:
if (TREE_CODE (arg) == REFERENCE_TYPE)
arg = TREE_TYPE (arg);
return unify (tparms, targs, ntparms, TREE_TYPE (parm), arg, nsubsts);
return unify (tparms, targs, ntparms, TREE_TYPE (parm), arg,
nsubsts, strict);
case ARRAY_TYPE:
if (TREE_CODE (arg) != ARRAY_TYPE)
return 1;
if (unify (tparms, targs, ntparms, TYPE_DOMAIN (parm), TYPE_DOMAIN (arg),
nsubsts) != 0)
nsubsts, strict) != 0)
return 1;
return unify (tparms, targs, ntparms, TREE_TYPE (parm), TREE_TYPE (arg),
nsubsts);
nsubsts, strict);
case REAL_TYPE:
case INTEGER_TYPE:
......@@ -2635,12 +2650,12 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
if (TREE_CODE (parm) == INTEGER_TYPE)
{
if (TYPE_MIN_VALUE (parm) && TYPE_MIN_VALUE (arg)
&& unify (tparms, targs, ntparms,
TYPE_MIN_VALUE (parm), TYPE_MIN_VALUE (arg), nsubsts))
&& unify (tparms, targs, ntparms, TYPE_MIN_VALUE (parm),
TYPE_MIN_VALUE (arg), nsubsts, strict))
return 1;
if (TYPE_MAX_VALUE (parm) && TYPE_MAX_VALUE (arg)
&& unify (tparms, targs, ntparms,
TYPE_MAX_VALUE (parm), TYPE_MAX_VALUE (arg), nsubsts))
&& unify (tparms, targs, ntparms, TYPE_MAX_VALUE (parm),
TYPE_MAX_VALUE (arg), nsubsts, strict))
return 1;
}
/* As far as unification is concerned, this wins. Later checks
......@@ -2660,7 +2675,7 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
t2 = TREE_OPERAND (parm, 1);
return unify (tparms, targs, ntparms, t1,
fold (build (PLUS_EXPR, integer_type_node, arg, t2)),
nsubsts);
nsubsts, strict);
}
case TREE_VEC:
......@@ -2673,7 +2688,7 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
for (i = TREE_VEC_LENGTH (parm) - 1; i >= 0; i--)
if (unify (tparms, targs, ntparms,
TREE_VEC_ELT (parm, i), TREE_VEC_ELT (arg, i),
nsubsts))
nsubsts, strict))
return 1;
return 0;
}
......@@ -2681,7 +2696,7 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_FLAG (parm))
return unify (tparms, targs, ntparms, TYPE_PTRMEMFUNC_FN_TYPE (parm),
arg, nsubsts);
arg, nsubsts, strict);
/* Allow trivial conversions. */
if (TREE_CODE (arg) != RECORD_TYPE
......@@ -2689,13 +2704,22 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
|| TYPE_VOLATILE (parm) < TYPE_VOLATILE (arg))
return 1;
if (CLASSTYPE_TEMPLATE_INFO (parm) && CLASSTYPE_TEMPLATE_INFO (arg)
&& uses_template_parms (parm))
if (CLASSTYPE_TEMPLATE_INFO (parm) && uses_template_parms (parm))
{
if (CLASSTYPE_TI_TEMPLATE (parm) != CLASSTYPE_TI_TEMPLATE (arg))
tree t = NULL_TREE;
#ifdef NEW_OVER
if (! strict)
t = get_template_base (CLASSTYPE_TI_TEMPLATE (parm), arg);
else
#endif
if (CLASSTYPE_TEMPLATE_INFO (arg)
&& CLASSTYPE_TI_TEMPLATE (parm) == CLASSTYPE_TI_TEMPLATE (arg))
t = arg;
if (! t || t == error_mark_node)
return 1;
return unify (tparms, targs, ntparms, CLASSTYPE_TI_ARGS (parm),
CLASSTYPE_TI_ARGS (arg), nsubsts);
CLASSTYPE_TI_ARGS (t), nsubsts, strict);
}
else if (TYPE_MAIN_VARIANT (parm) != TYPE_MAIN_VARIANT (arg))
return 1;
......@@ -2711,19 +2735,19 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
return 1;
check_args:
if (unify (tparms, targs, ntparms, TREE_TYPE (parm),
TREE_TYPE (arg), nsubsts))
TREE_TYPE (arg), nsubsts, strict))
return 1;
return type_unification (tparms, targs, TYPE_ARG_TYPES (parm),
TYPE_ARG_TYPES (arg), nsubsts, 1);
TYPE_ARG_TYPES (arg), nsubsts, 1, strict);
case OFFSET_TYPE:
if (TREE_CODE (arg) != OFFSET_TYPE)
return 1;
if (unify (tparms, targs, ntparms, TYPE_OFFSET_BASETYPE (parm),
TYPE_OFFSET_BASETYPE (arg), nsubsts))
TYPE_OFFSET_BASETYPE (arg), nsubsts, strict))
return 1;
return unify (tparms, targs, ntparms, TREE_TYPE (parm),
TREE_TYPE (arg), nsubsts);
TREE_TYPE (arg), nsubsts, strict);
default:
sorry ("use of `%s' in template type unification",
......@@ -2748,6 +2772,44 @@ mark_decl_instantiated (result, extern_p)
}
}
/* Given two function templates PAT1 and PAT2, return:
1 if PAT1 is more specialized than PAT2 as described in [temp.func.order].
-1 if PAT2 is more specialized than PAT1.
0 if neither is more specialized. */
int
more_specialized (pat1, pat2)
tree pat1, pat2;
{
int ntparms = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (pat1));
tree *targs = (tree *) malloc (sizeof (tree) * ntparms);
int i, dummy = 0, winner = 0;
i = type_unification (DECL_TEMPLATE_PARMS (pat1), targs,
TYPE_ARG_TYPES (TREE_TYPE (pat1)),
TYPE_ARG_TYPES (TREE_TYPE (pat2)),
&dummy, 0, 1);
free (targs);
if (i == 0)
--winner;
ntparms = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (pat2));
targs = (tree *) malloc (sizeof (tree) * ntparms);
i = type_unification (DECL_TEMPLATE_PARMS (pat2), targs,
TYPE_ARG_TYPES (TREE_TYPE (pat2)),
TYPE_ARG_TYPES (TREE_TYPE (pat1)),
&dummy, 0, 1);
free (targs);
if (i == 0)
++winner;
return winner;
}
/* called from the parser. */
void
......@@ -2794,11 +2856,19 @@ do_function_instantiation (declspecs, declarator, storage)
i = type_unification (DECL_TEMPLATE_PARMS (fn), targs,
TYPE_ARG_TYPES (TREE_TYPE (fn)),
TYPE_ARG_TYPES (TREE_TYPE (decl)),
&dummy, 0);
&dummy, 0, 1);
if (i == 0)
{
if (result)
cp_error ("ambiguous template instantiation for `%D' requested", decl);
{
int win = more_specialized (DECL_TI_TEMPLATE (result), fn);
if (win == 0)
cp_error ("ambiguous template instantiation for `%D' requested", decl);
else if (win == -1)
result = instantiate_template (fn, targs);
/* else keep current winner */
}
else
result = instantiate_template (fn, targs);
}
......
......@@ -919,7 +919,7 @@ compute_access (basetype_path, field)
{
if (current_class_type
&& static_mem
&& ACCESSIBLY_DERIVED_FROM_P (context, current_class_type))
&& ACCESSIBLY_DERIVED_FROM_P (context, current_class_type))
PUBLIC_RETURN;
else
PROTECTED_RETURN;
......@@ -1580,7 +1580,7 @@ lookup_fnfields_1 (type, name)
which gives the following information (in a list):
TREE_TYPE: list of basetypes needed to get to...
TREE_VALUE: list of all functions in of given type
TREE_VALUE: list of all functions in a given type
which have name NAME.
No access information is computed by this function,
......@@ -1898,7 +1898,7 @@ lookup_fnfields (basetype_path, name, complain)
/* Search a multiple inheritance hierarchy by breadth-first search.
TYPE is an aggregate type, possibly in a multiple-inheritance hierarchy.
BINFO is an aggregate type, possibly in a multiple-inheritance hierarchy.
TESTFN is a function, which, if true, means that our condition has been met,
and its return value should be returned.
QFN, if non-NULL, is a predicate dictating whether the type should
......@@ -3084,11 +3084,14 @@ build_mi_matrix (type)
}
#endif
dfs_walk (binfo, dfs_number, unnumberedp);
mi_size = CLASSTYPE_N_SUPERCLASSES (type) + CLASSTYPE_N_VBASECLASSES (type);
if (mi_size < cid)
mi_size = cid;
mi_matrix = (char *)xmalloc ((mi_size + 1) * (mi_size + 1));
mi_type = type;
bzero (mi_matrix, (mi_size + 1) * (mi_size + 1));
dfs_walk (binfo, dfs_number, unnumberedp);
dfs_walk (binfo, dfs_record_inheritance, unmarkedp);
dfs_walk (binfo, dfs_unmark, markedp);
}
......@@ -3559,3 +3562,82 @@ lookup_conversions (type)
dfs_walk (TYPE_BINFO (type), add_conversions, 0);
return conversions;
}
/* Subroutine of get_template_base. */
static tree
get_template_base_recursive (binfo, rval, template, via_virtual)
tree binfo, template, rval;
int via_virtual;
{
tree binfos;
int i, n_baselinks;
tree type = BINFO_TYPE (binfo);
if (CLASSTYPE_TEMPLATE_INFO (type)
&& CLASSTYPE_TI_TEMPLATE (type) == template)
{
if (rval == NULL_TREE || rval == type)
return type;
else
return error_mark_node;
}
binfos = BINFO_BASETYPES (binfo);
n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
/* Process base types. */
for (i = 0; i < n_baselinks; i++)
{
tree base_binfo = TREE_VEC_ELT (binfos, i);
/* Find any specific instance of a virtual base, when searching with
a binfo... */
if (BINFO_MARKED (base_binfo) == 0)
{
int this_virtual = via_virtual || TREE_VIA_VIRTUAL (base_binfo);
/* When searching for a non-virtual, we cannot mark
virtually found binfos. */
if (! this_virtual)
SET_BINFO_MARKED (base_binfo);
rval = get_template_base_recursive
(base_binfo, rval, template, this_virtual);
if (rval == error_mark_node)
return rval;
}
}
return rval;
}
/* Given a class template TEMPLATE and a class type or binfo node BINFO,
find the unique base type in BINFO that is an instance of TEMPLATE.
If there are more than one, return error_mark_node. Used by unify. */
tree
get_template_base (template, binfo)
register tree template, binfo;
{
tree type, rval;
if (TREE_CODE (binfo) == TREE_VEC)
type = BINFO_TYPE (binfo);
else if (IS_AGGR_TYPE_CODE (TREE_CODE (binfo)))
{
type = complete_type (binfo);
binfo = TYPE_BINFO (type);
}
else
my_friendly_abort (92);
if (CLASSTYPE_TEMPLATE_INFO (type)
&& CLASSTYPE_TI_TEMPLATE (type) == template)
return type;
rval = get_template_base_recursive (binfo, NULL_TREE, template, 0);
dfs_walk (binfo, dfs_unmark, markedp);
return rval;
}
......@@ -132,8 +132,9 @@ complete_type (type)
else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
{
tree t = complete_type (TREE_TYPE (type));
if (TYPE_SIZE (t) != NULL_TREE)
type = build_cplus_array_type (t, TYPE_DOMAIN (type));
if (TYPE_SIZE (t) != NULL_TREE
&& current_template_parms == NULL_TREE)
layout_type (type);
}
else if (IS_AGGR_TYPE (type) && CLASSTYPE_TEMPLATE_INSTANTIATION (type))
instantiate_class_template (TYPE_MAIN_VARIANT (type));
......@@ -1632,65 +1633,7 @@ build_component_ref_1 (datum, field, protect)
tree datum, field;
int protect;
{
register tree basetype = TREE_TYPE (datum);
register enum tree_code code = TREE_CODE (basetype);
register tree ref;
if (code == REFERENCE_TYPE)
{
datum = convert_from_reference (datum);
basetype = TREE_TYPE (datum);
code = TREE_CODE (basetype);
}
if (! IS_AGGR_TYPE_CODE (code))
{
if (code != ERROR_MARK)
cp_error ("request for member `%D' in `%E', which is of non-aggregate type `%T'",
field, datum, basetype);
return error_mark_node;
}
if (TYPE_SIZE (basetype) == 0)
{
incomplete_type_error (0, basetype);
return error_mark_node;
}
/* Look up component name in the structure type definition. */
if (field == error_mark_node)
my_friendly_abort (115);
if (TREE_STATIC (field))
return field;
if (datum == current_class_ref)
{
tree access = compute_access (TYPE_BINFO (current_class_type), field);
if (access == access_private_node)
{
cp_error ("field `%D' is private", field);
return error_mark_node;
}
else if (access == access_protected_node)
{
cp_error ("field `%D' is protected", field);
return error_mark_node;
}
}
ref = build (COMPONENT_REF, TREE_TYPE (field), datum, field);
if (TREE_READONLY (datum) || TREE_READONLY (field))
TREE_READONLY (ref) = 1;
if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (field))
TREE_THIS_VOLATILE (ref) = 1;
if (DECL_MUTABLE_P (field))
TREE_READONLY (ref) = 0;
return ref;
return build_component_ref (datum, field, NULL_TREE, protect);
}
/* Given a COND_EXPR in T, return it in a form that we can, for
......@@ -2414,8 +2357,7 @@ build_x_function_call (function, params, decl)
if (TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type);
if (TYPE_LANG_SPECIFIC (type)
&& TYPE_OVERLOADS_CALL_EXPR (complete_type (type)))
if (IS_AGGR_TYPE (type))
return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, function, params, NULL_TREE);
}
......@@ -5586,10 +5528,8 @@ build_modify_expr (lhs, modifycode, rhs)
else if (TYPE_HAS_TRIVIAL_ASSIGN_REF (lhstype)
&& TYPE_MAIN_VARIANT (lhstype) == TYPE_MAIN_VARIANT (TREE_TYPE (newrhs)))
{
if (warn_synth)
/* If we care about this, do overload resolution. */
build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL,
lhs, rhs, make_node (NOP_EXPR));
build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL,
lhs, rhs, make_node (NOP_EXPR));
/* Do the default thing */;
}
......@@ -6778,6 +6718,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
if (TREE_CODE (rhstype) == REFERENCE_TYPE)
rhstype = TREE_TYPE (rhstype);
type = complete_type (type);
if (TYPE_LANG_SPECIFIC (type)
&& (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type)))
return build_signature_pointer_constructor (type, rhs);
......
......@@ -302,7 +302,7 @@ ack (s, v, v2)
silly. So instead, we just do the equivalent of a call to fatal in the
same situation (call exit). */
/* First used: 0 (reserved), Last used: 366. Free: */
/* First used: 0 (reserved), Last used: 367. Free: */
static int abortcount = 0;
......@@ -1091,7 +1091,8 @@ process_init_constructor (type, init, elts)
/* Find the first named field. ANSI decided in September 1990
that only named fields count here. */
while (field && DECL_NAME (field) == 0)
while (field && (DECL_NAME (field) == 0
|| TREE_CODE (field) != FIELD_DECL))
field = TREE_CHAIN (field);
/* If this element specifies a field, initialize via that field. */
......
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