Commit 5566b478 by Mike Stump

83rd Cygnus<->FSF merge

From-SVN: r11362
parent 8bd04c56
......@@ -168,7 +168,6 @@ OBJDEPS = ../stamp-objlist ../c-common.o ../c-pragma.o
compiler: ../cc1plus
../cc1plus: $(P) $(CXX_OBJS) $(OBJDEPS) $(LIBDEPS)
rm -f ../cc1plus$(exeext)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
$(CXX_OBJS) $(OBJS) $(LIBS)
......@@ -196,7 +195,7 @@ parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \
`echo $(PARSE_C) | sed 's,^\./,,'`
CONFLICTS = expect 7 shift/reduce conflicts and 38 reduce/reduce conflicts.
CONFLICTS = expect 12 shift/reduce conflicts and 39 reduce/reduce conflicts.
$(PARSE_H) : $(PARSE_C)
$(PARSE_C) : $(srcdir)/parse.y
@echo $(CONFLICTS)
......
......@@ -175,8 +175,8 @@ convert_harshness (type, parmtype, parm)
if (! lvalue && ! (parm && TYPE_READONLY (ttl)))
return EVIL_RETURN (h);
if (TYPE_READONLY (ttl) < constp
|| TYPE_VOLATILE (ttl) < volatilep)
if ((TYPE_READONLY (ttl) < constp)
|| (TYPE_VOLATILE (ttl) < volatilep))
return EVIL_RETURN (h);
/* When passing a non-const argument into a const reference, dig it a
......@@ -646,9 +646,8 @@ convert_harshness (type, parmtype, parm)
overload resolution. */
int
user_harshness (type, parmtype, parm)
user_harshness (type, parmtype)
register tree type, parmtype;
tree parm;
{
tree conv;
tree winner = NULL_TREE;
......@@ -668,7 +667,7 @@ user_harshness (type, parmtype, parm)
continue;
if (tmp = convert_harshness (type, TREE_VALUE (conv), NULL_TREE),
tmp.code < USER_CODE && tmp.distance >= 0)
(tmp.code < USER_CODE) && (tmp.distance >= 0))
{
if (winner)
return EVIL_CODE;
......@@ -692,7 +691,7 @@ can_convert (to, from)
{
struct harshness_code h;
h = convert_harshness (to, from, NULL_TREE);
return h.code < USER_CODE && h.distance >= 0;
return (h.code < USER_CODE) && (h.distance >= 0);
}
int
......@@ -701,7 +700,7 @@ can_convert_arg (to, from, arg)
{
struct harshness_code h;
h = convert_harshness (to, from, arg);
return h.code < USER_CODE && h.distance >= 0;
return (h.code < USER_CODE) && (h.distance >= 0);
}
#ifdef DEBUG_MATCHING
......@@ -1091,11 +1090,9 @@ strictly_better (x, y)
LEN is the length of the parameter list. */
static struct candidate *
ideal_candidate (basetype, candidates, n_candidates, parms, len)
tree basetype;
ideal_candidate (candidates, n_candidates, len)
struct candidate *candidates;
int n_candidates;
tree parms;
int len;
{
struct candidate *cp = candidates+n_candidates;
......@@ -1347,15 +1344,6 @@ find_scoped_type (type, inner_name, inner_types)
tags = TREE_CHAIN (tags);
}
#if 0
/* XXX This needs to be fixed better. */
if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE)
{
sorry ("nested class lookup in template type");
return NULL_TREE;
}
#endif
/* Look for a TYPE_DECL. */
for (tags = TYPE_FIELDS (type); tags; tags = TREE_CHAIN (tags))
if (TREE_CODE (tags) == TYPE_DECL && DECL_NAME (tags) == inner_name)
......@@ -1477,6 +1465,17 @@ build_scoped_method_call (exp, basetype, name, parms)
|| basetype == error_mark_node)
return error_mark_node;
if (current_template_parms)
{
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
tree type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 1);
name = build_min_nt (BIT_NOT_EXPR, type);
}
name = build_min_nt (SCOPE_REF, basetype, name);
return build_min_nt (METHOD_CALL_EXPR, name, exp, parms, 0);
}
if (TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type);
......@@ -1489,7 +1488,7 @@ build_scoped_method_call (exp, basetype, name, parms)
cp_error ("type of `%E' does not match destructor type `%T' (type was `%T')",
exp, basetype, type);
name = TREE_OPERAND (name, 0);
if (basetype != get_type_value (name))
if (basetype != name && basetype != get_type_value (name))
cp_error ("qualified type `%T' does not match destructor name `~%T'",
basetype, name);
return convert (void_type_node, exp);
......@@ -1520,7 +1519,8 @@ build_scoped_method_call (exp, basetype, name, parms)
{
/* Explicit call to destructor. */
name = TREE_OPERAND (name, 0);
if (! (name == constructor_name (TREE_TYPE (decl))
if (! (name == TYPE_MAIN_VARIANT (TREE_TYPE (decl))
|| name == constructor_name (TREE_TYPE (decl))
|| TREE_TYPE (decl) == get_type_value (name)))
{
cp_error
......@@ -1607,7 +1607,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
{
register tree function, fntype, value_type;
register tree basetype, save_basetype;
register tree baselink, result, method_name, parmtypes, parm;
register tree baselink, result, parmtypes, parm;
#if 0
register tree method_name;
#endif
tree last;
int pass;
tree access = access_public_node;
......@@ -1636,6 +1639,17 @@ build_method_call (instance, name, parms, basetype_path, flags)
|| (instance != NULL_TREE && TREE_TYPE (instance) == error_mark_node))
return error_mark_node;
if (current_template_parms)
{
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
tree type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 1);
name = build_min_nt (BIT_NOT_EXPR, type);
}
return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, 0);
}
/* This is the logic that magically deletes the second argument to
operator delete, if it is not needed. */
if (name == ansi_opname[(int) DELETE_EXPR] && list_length (parms)==2)
......@@ -1668,8 +1682,9 @@ build_method_call (instance, name, parms, basetype_path, flags)
basetype = TREE_TYPE (instance);
if (TREE_CODE (basetype) == REFERENCE_TYPE)
basetype = TREE_TYPE (basetype);
if (! ((IS_AGGR_TYPE (basetype)
&& name == constructor_name (basetype))
if (! (name == basetype
|| (IS_AGGR_TYPE (basetype)
&& name == constructor_name (basetype))
|| basetype == get_type_value (name)))
{
cp_error ("destructor name `~%D' does not match type `%T' of expression",
......@@ -1734,7 +1749,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
else if (IDENTIFIER_HAS_TYPE_VALUE (name))
{
basetype = IDENTIFIER_TYPE_VALUE (name);
name = constructor_name_full (basetype);
name = constructor_name (basetype);
}
else
{
......@@ -1884,7 +1899,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
if (TREE_CODE (instance) != CALL_EXPR)
my_friendly_abort (125);
if (TYPE_NEEDS_CONSTRUCTING (basetype))
instance = build_cplus_new (basetype, instance, 0);
instance = build_cplus_new (basetype, instance);
else
{
instance = get_temp_name (basetype, 0);
......@@ -1942,7 +1957,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
}
}
if (TYPE_SIZE (basetype) == 0)
if (TYPE_SIZE (complete_type (basetype)) == 0)
{
/* This is worth complaining about, I think. */
cp_error ("cannot lookup method in incomplete type `%T'", basetype);
......@@ -2033,8 +2048,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
if ((IDENTIFIER_HAS_TYPE_VALUE (name)
&& ! IDENTIFIER_OPNAME_P (name)
&& IS_AGGR_TYPE (IDENTIFIER_TYPE_VALUE (name))
&& TREE_CODE (IDENTIFIER_TYPE_VALUE (name)) != UNINSTANTIATED_P_TYPE)
&& IS_AGGR_TYPE (IDENTIFIER_TYPE_VALUE (name)))
|| name == constructor_name (basetype))
{
tree tmp = NULL_TREE;
......@@ -2301,8 +2315,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
int n_candidates = cp - candidates;
extern int warn_synth;
TREE_VALUE (parms) = instance_ptr;
cp = ideal_candidate (save_basetype, candidates,
n_candidates, parms, len);
cp = ideal_candidate (candidates, n_candidates, len);
if (cp == (struct candidate *)0)
{
if (flags & LOOKUP_COMPLAIN)
......@@ -2529,7 +2542,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
value_type = TREE_TYPE (fntype) ? TREE_TYPE (fntype) : void_type_node;
if (TYPE_SIZE (value_type) == 0)
if (TYPE_SIZE (complete_type (value_type)) == 0)
{
if (flags & LOOKUP_COMPLAIN)
incomplete_type_error (0, value_type);
......@@ -2710,7 +2723,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
int buildxxx;
{
/* must check for overloading here */
tree overload_name, functions, function, parm;
tree functions, function, parm;
tree parmtypes = NULL_TREE, last = NULL_TREE;
register tree outer;
int length;
......@@ -2831,7 +2844,6 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
function = outer;
if (TREE_CODE (function) != FUNCTION_DECL
&& ! (TREE_CODE (function) == TEMPLATE_DECL
&& ! DECL_TEMPLATE_IS_CLASS (function)
&& TREE_CODE (DECL_TEMPLATE_RESULT (function)) == FUNCTION_DECL))
{
enum tree_code code = TREE_CODE (function);
......@@ -2869,7 +2881,11 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
TYPE_ARG_TYPES (TREE_TYPE (function)),
parms, &template_cost, 0);
if (i == 0)
function = instantiate_template (function, targs);
{
function = instantiate_template (function, targs);
if (function == error_mark_node)
return function;
}
}
if (TREE_CODE (function) == TEMPLATE_DECL)
......@@ -2924,8 +2940,7 @@ build_overload_call_real (fnname, parms, flags, final_cp, buildxxx)
if (cp - candidates > 1)
{
struct candidate *best_cp
= ideal_candidate (NULL_TREE, candidates,
cp - candidates, parms, parmlength);
= ideal_candidate (candidates, cp - candidates, parmlength);
if (best_cp == (struct candidate *)0)
{
if (flags & LOOKUP_COMPLAIN)
......
......@@ -90,18 +90,13 @@ DEFTREECODE (TEMPLATE_DECL, "template_decl", "d", 0)
Use TYPE_FIELDS to find parmlist and index. */
DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", "t", 0)
/* A type designated by 'typename T::t'. */
DEFTREECODE (TYPENAME_TYPE, "typename_type", "t", 0)
/* Index into a template parameter list. This parameter must not be a
type. */
DEFTREECODE (TEMPLATE_CONST_PARM, "template_const_parm", "c", 2)
/* For uninstantiated parameterized types.
TYPE_VALUES tree list:
TREE_PURPOSE template decl
TREE_VALUE parm vector
TREE_CHAIN null
Other useful fields to be defined later. */
DEFTREECODE (UNINSTANTIATED_P_TYPE, "uninstantiated_p_type", "t", 0)
/* A thunk is a stub function.
Thunks are used to implement multiple inheritance:
......@@ -118,3 +113,27 @@ DEFTREECODE (NAMESPACE_DECL, "namespace_decl", "d", 0)
/* A using declaration. DECL_INITIAL contains the specified scope.
This is not an alias, but is later expanded into multiple aliases. */
DEFTREECODE (USING_DECL, "using_decl", "d", 0)
DEFTREECODE (LOOKUP_EXPR, "lookup_expr", "e", 2)
DEFTREECODE (MODOP_EXPR, "modop_expr", "e", 3)
DEFTREECODE (CAST_EXPR, "cast_expr", "e", 1)
DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", "e", 1)
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", "e", 1)
DEFTREECODE (ARROW_EXPR, "arrow_expr", "e", 1)
DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", "e", 2)
DEFTREECODE (EXPR_STMT, "expr_stmt", "e", 1)
DEFTREECODE (COMPOUND_STMT, "compound_stmt", "e", 1)
DEFTREECODE (DECL_STMT, "decl_stmt", "e", 4)
DEFTREECODE (IF_STMT, "if_stmt", "e", 3)
DEFTREECODE (FOR_STMT, "for_stmt", "e", 4)
DEFTREECODE (WHILE_STMT, "while_stmt", "e", 2)
DEFTREECODE (DO_STMT, "do_stmt", "e", 2)
DEFTREECODE (RETURN_STMT, "return_stmt", "e", 1)
DEFTREECODE (BREAK_STMT, "break_stmt", "e", 0)
DEFTREECODE (CONTINUE_STMT, "continue_stmt", "e", 0)
DEFTREECODE (SWITCH_STMT, "switch_stmt", "e", 2)
DEFTREECODE (GOTO_STMT, "goto_stmt", "e", 1)
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", "e", 2)
DEFTREECODE (CASE_LABEL, "case_label", "e", 2)
......@@ -356,7 +356,7 @@ build_up_reference (type, arg, flags, checkconst)
initializing until now: it needs to initialize a temporary. */
if (TREE_HAS_CONSTRUCTOR (targ))
{
tree temp = build_cplus_new (argtype, TREE_OPERAND (targ, 0), 1);
tree temp = build_cplus_new (argtype, TREE_OPERAND (targ, 0));
TREE_HAS_CONSTRUCTOR (targ) = 0;
return build_up_reference (type, temp, flags, 1);
}
......@@ -586,7 +586,7 @@ build_up_reference (type, arg, flags, checkconst)
if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype))
{
temp = build_cplus_new (argtype, targ, 1);
temp = build_cplus_new (argtype, targ);
rval = build1 (ADDR_EXPR, type, temp);
goto done;
}
......@@ -809,7 +809,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
if (init == error_mark_node)
return error_mark_node;
rval = build_cplus_new (type, init, 1);
rval = build_cplus_new (type, init);
rval = build_up_reference (reftype, rval, flags, 1);
}
rval_as_ctor = rval;
......@@ -888,7 +888,11 @@ convert_to_aggr (type, expr, msgp, protect)
tree basetype = type;
tree name = TYPE_IDENTIFIER (basetype);
tree function, fndecl, fntype, parmtypes, parmlist, result;
tree method_name, access;
#if 0
/* See code below that used this. */
tree method_name;
#endif
tree access;
int can_be_private, can_be_protected;
if (! TYPE_HAS_CONSTRUCTOR (basetype))
......@@ -1229,7 +1233,6 @@ cp_convert (type, expr, convtype, flags)
if (INTEGRAL_CODE_P (code))
{
tree intype = TREE_TYPE (e);
enum tree_code form = TREE_CODE (intype);
/* enum = enum, enum = int, enum = float are all errors. */
if (flag_int_enum_equivalence == 0
&& TREE_CODE (type) == ENUMERAL_TYPE
......@@ -1328,7 +1331,7 @@ cp_convert (type, expr, convtype, flags)
return conversion;
}
if (TYPE_HAS_CONSTRUCTOR (type))
if (TYPE_HAS_CONSTRUCTOR (complete_type (type)))
ctor = build_method_call (NULL_TREE, constructor_name_full (type),
build_tree_list (NULL_TREE, e),
TYPE_BINFO (type),
......@@ -1357,7 +1360,7 @@ cp_convert (type, expr, convtype, flags)
return conversion;
else if (ctor)
{
ctor = build_cplus_new (type, ctor, 0);
ctor = build_cplus_new (type, ctor);
return ctor;
}
}
......
......@@ -212,11 +212,6 @@ dump_type (t, v)
OB_PUTID (TYPE_IDENTIFIER (t));
break;
case UNINSTANTIATED_P_TYPE:
OB_PUTID (DECL_NAME (UPT_TEMPLATE (t)));
OB_PUTS ("<...>");
break;
/* This is not always necessary for pointers and such, but doing this
reduces code size. */
case ARRAY_TYPE:
......@@ -230,6 +225,13 @@ dump_type (t, v)
dump_type_suffix (t, v);
break;
case TYPENAME_TYPE:
OB_PUTS ("typename ");
dump_type (TYPE_CONTEXT (t), 0);
OB_PUTS ("::");
OB_PUTID (TYPE_IDENTIFIER (t));
break;
default:
sorry ("`%s' not supported by dump_type",
tree_code_name[(int) TREE_CODE (t)]);
......@@ -422,10 +424,10 @@ dump_type_prefix (t, v)
case TREE_LIST:
case TYPE_DECL:
case TREE_VEC:
case UNINSTANTIATED_P_TYPE:
case UNION_TYPE:
case UNKNOWN_TYPE:
case VOID_TYPE:
case TYPENAME_TYPE:
dump_type (t, v);
break;
......@@ -494,10 +496,10 @@ dump_type_suffix (t, v)
case TREE_LIST:
case TYPE_DECL:
case TREE_VEC:
case UNINSTANTIATED_P_TYPE:
case UNION_TYPE:
case UNKNOWN_TYPE:
case VOID_TYPE:
case TYPENAME_TYPE:
break;
default:
......@@ -711,11 +713,8 @@ dump_decl (t, v)
OB_UNPUT (2);
OB_PUTC2 ('>', ' ');
if (DECL_TEMPLATE_IS_CLASS (t))
{
OB_PUTS ("class ");
OB_PUTID (DECL_NAME (t));
}
if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
dump_type (TREE_TYPE (t), v);
else switch (NEXT_CODE (t))
{
case METHOD_TYPE:
......@@ -734,7 +733,8 @@ dump_decl (t, v)
break;
case CONST_DECL:
if (NEXT_CODE (t) == ENUMERAL_TYPE)
if (NEXT_CODE (t) == ENUMERAL_TYPE
|| TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_CONST_PARM)
goto general;
else
dump_expr (DECL_INITIAL (t), 0);
......@@ -1262,6 +1262,27 @@ dump_expr (t, nop)
break;
}
case TEMPLATE_CONST_PARM:
{
tree r = TREE_VEC_ELT (TREE_VALUE (current_template_parms),
TEMPLATE_CONST_IDX (t));
dump_decl (TREE_VALUE (r), -1);
break;
}
case IDENTIFIER_NODE:
OB_PUTID (t);
break;
case SCOPE_REF:
dump_type (TREE_OPERAND (t, 0), 0);
OB_PUTS ("::");
dump_expr (TREE_OPERAND (t, 1), 0);
break;
case CAST_EXPR:
break; /* XXX */
case TREE_LIST:
if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL)
{
......@@ -1312,8 +1333,8 @@ dump_unary_op (opstring, t, nop)
}
char *
fndecl_as_string (cname, fndecl, print_ret_type_p)
tree cname, fndecl;
fndecl_as_string (fndecl, print_ret_type_p)
tree fndecl;
int print_ret_type_p;
{
return decl_as_string (fndecl, print_ret_type_p);
......@@ -1389,12 +1410,7 @@ cp_line_of (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));
}
line = DECL_SOURCE_LINE (TYPE_NAME (t));
else
line = DECL_SOURCE_LINE (t);
......
......@@ -37,6 +37,7 @@ tree protect_list;
extern void (*interim_eh_hook) PROTO((tree));
rtx expand_builtin_return_addr PROTO((enum built_in_function, int, rtx));
static void end_eh_unwinder PROTO((rtx));
/* holds the fndecl for __builtin_return_address () */
tree builtin_return_address_fndecl;
......@@ -90,8 +91,6 @@ output_exception_table_entry (file, start_label, end_label, eh_label)
FILE *file;
rtx start_label, end_label, eh_label;
{
char label[100];
assemble_integer (start_label, GET_MODE_SIZE (Pmode), 1);
assemble_integer (end_label, GET_MODE_SIZE (Pmode), 1);
assemble_integer (eh_label, GET_MODE_SIZE (Pmode), 1);
......@@ -146,7 +145,7 @@ asm (TEXT_SECTION_ASM_OP);
#endif
void
static void
exception_section ()
{
#ifdef ASM_OUTPUT_SECTION_NAME
......@@ -320,15 +319,15 @@ struct ehQueue {
========================================================================= */
/* Holds the pc for doing "throw" */
tree saved_pc;
static tree saved_pc;
/* Holds the type of the thing being thrown. */
tree saved_throw_type;
static tree saved_throw_type;
/* Holds the value being thrown. */
tree saved_throw_value;
static tree saved_throw_value;
/* Holds the cleanup for the value being thrown. */
tree saved_cleanup;
static tree saved_cleanup;
int throw_used;
static int throw_used;
static rtx catch_clauses;
......@@ -454,7 +453,8 @@ top_label_entry (labelstack)
/* Push to permanent obstack for rtl generation.
One level only! */
static struct obstack *saved_rtl_obstack;
void
static void
push_rtl_perm ()
{
extern struct obstack permanent_obstack;
......@@ -468,9 +468,7 @@ push_rtl_perm ()
static void
pop_rtl_from_perm ()
{
extern struct obstack permanent_obstack;
extern struct obstack *rtl_obstack;
rtl_obstack = saved_rtl_obstack;
}
......@@ -587,7 +585,7 @@ new_eh_stack (stack)
}
/* cheesyness to save some typing. returns the return value rtx */
rtx
static rtx
do_function_call (func, params, return_type)
tree func, params, return_type;
{
......@@ -603,8 +601,6 @@ static void
expand_internal_throw (pc)
rtx pc;
{
tree params;
emit_move_insn (DECL_RTL (saved_pc), pc);
#ifdef JUMP_TO_THROW
emit_indirect_jump (gen_rtx (SYMBOL_REF, Pmode, "__throw"));
......@@ -616,7 +612,7 @@ expand_internal_throw (pc)
/* ========================================================================= */
void
static void
lang_interim_eh (finalization)
tree finalization;
{
......@@ -946,7 +942,7 @@ build_eh_type (exp)
}
/* This routine creates the cleanup for the exception handling object. */
void
static void
push_eh_cleanup ()
{
/* All cleanups must last longer than normal. */
......@@ -973,7 +969,6 @@ expand_start_catch_block (declspecs, declarator)
rtx protect_label_rtx;
tree decl = NULL_TREE;
tree init;
tree cleanup;
if (! doing_eh (1))
return;
......@@ -1243,7 +1238,7 @@ do_unwind (inner_throw_label)
/* Given the return address, compute the new pc to throw. This has to
work for the current frame of the current function, and the one
above it in the case of throw. */
rtx
static rtx
eh_outer_context (addr)
rtx addr;
{
......@@ -1306,8 +1301,6 @@ expand_builtin_throw ()
rtx return_val_rtx;
rtx gotta_rethrow_it;
rtx gotta_call_terminate;
rtx unwind_and_throw;
rtx goto_unwind_and_throw;
rtx top_of_loop;
rtx unwind_first;
tree t;
......@@ -1331,8 +1324,6 @@ expand_builtin_throw ()
gotta_rethrow_it = gen_label_rtx ();
gotta_call_terminate = gen_label_rtx ();
unwind_and_throw = gen_label_rtx ();
goto_unwind_and_throw = gen_label_rtx ();
top_of_loop = gen_label_rtx ();
unwind_first = gen_label_rtx ();
......@@ -1421,7 +1412,7 @@ expand_start_eh_spec ()
start_protect ();
}
void
static void
expand_end_eh_spec (raises)
tree raises;
{
......@@ -1771,7 +1762,6 @@ emit_exception_table ()
int count = 0;
extern FILE *asm_out_file;
struct ehEntry *entry;
tree eh_node_decl;
if (! doing_eh (0))
return;
......@@ -1826,11 +1816,13 @@ build_throw (e)
return e;
}
void
start_eh_unwinder ()
{
start_protect ();
}
static void
end_eh_unwinder (end)
rtx end;
{
......
......@@ -359,3 +359,85 @@ extract_init (decl, init)
return 1;
#endif
}
void
do_case (start, end)
tree start, end;
{
tree value1 = NULL_TREE, value2 = NULL_TREE, label;
if (end && pedantic)
pedwarn ("ANSI C++ forbids range expressions in switch statement");
if (current_template_parms)
{
add_tree (build_min_nt (CASE_LABEL, start, end));
return;
}
if (start)
value1 = check_cp_case_value (start);
if (end)
value2 = check_cp_case_value (end);
label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
if (value1 != error_mark_node
&& value2 != error_mark_node)
{
tree duplicate;
int success;
if (end)
success = pushcase_range (value1, value2, convert_and_check,
label, &duplicate);
else if (start)
success = pushcase (value1, convert_and_check, label, &duplicate);
else
success = pushcase (NULL_TREE, 0, label, &duplicate);
if (success == 1)
{
if (end)
error ("case label not within a switch statement");
else if (start)
cp_error ("case label `%E' not within a switch statement", start);
else
error ("default label not within a switch statement");
}
else if (success == 2)
{
if (end)
{
error ("duplicate (or overlapping) case value");
cp_error_at ("this is the first entry overlapping that value",
duplicate);
}
else if (start)
{
cp_error ("duplicate case value `%E'", start);
cp_error_at ("previously used here", duplicate);
}
else
{
error ("multiple default labels in one switch");
cp_error_at ("this is the first default label", duplicate);
}
}
else if (success == 3)
warning ("case value out of range");
else if (success == 4)
warning ("empty range specified");
else if (success == 5)
{
if (end)
error ("case label within scope of cleanup or variable array");
else
cp_error ("case label `%E' within scope of cleanup or variable array", start);
}
}
if (start)
define_case_label (label);
else
define_case_label (NULL_TREE);
}
......@@ -52,8 +52,6 @@ void expand_member_init ();
void expand_aggr_init ();
static void expand_aggr_init_1 ();
static void expand_recursive_init_1 ();
static void expand_recursive_init ();
static void expand_virtual_init PROTO((tree, tree));
tree expand_vec_init ();
......@@ -70,7 +68,7 @@ static tree minus_one;
/* Set up local variable for this file. MUST BE CALLED AFTER
INIT_DECL_PROCESSING. */
tree BI_header_type, BI_header_size;
static tree BI_header_type, BI_header_size;
void init_init_processing ()
{
......@@ -257,9 +255,8 @@ static tree
sort_member_init (t)
tree t;
{
tree x, member, name, field, init;
tree x, member, name, field;
tree init_list = NULL_TREE;
tree fields_to_unmark = NULL_TREE;
int last_pos = 0;
tree last_field;
......@@ -281,6 +278,8 @@ sort_member_init (t)
name = TREE_PURPOSE (x);
#if 0
/* This happens in templates, since the IDENTIFIER is replaced
with the COMPONENT_REF in tsubst_expr. */
field = (TREE_CODE (name) == COMPONENT_REF
? TREE_OPERAND (name, 1) : IDENTIFIER_CLASS_VALUE (name));
#else
......@@ -520,9 +519,7 @@ emit_base_init (t, immediately)
tree t;
int immediately;
{
extern tree in_charge_identifier;
tree member, x;
tree member;
tree mem_init_list;
tree rbase_init_list, vbase_init_list;
tree t_binfo = TYPE_BINFO (t);
......@@ -571,7 +568,6 @@ emit_base_init (t, immediately)
/* Now, perform initialization of non-virtual base classes. */
for (i = 0; i < n_baseclasses; i++)
{
tree base = current_class_decl;
tree base_binfo = TREE_VEC_ELT (binfos, i);
tree init = void_list_node;
......@@ -653,10 +649,15 @@ emit_base_init (t, immediately)
init = TREE_VALUE (mem_init_list);
from_init_list = 1;
#if 0
if (TREE_CODE (name) == COMPONENT_REF)
name = DECL_NAME (TREE_OPERAND (name, 1));
#else
/* Also see if it's ever a COMPONENT_REF here. If it is, we
need to do `expand_assignment (name, init, 0, 0);' and
a continue. */
my_friendly_assert (TREE_CODE (name) != COMPONENT_REF, 349);
#endif
}
else
{
......@@ -993,7 +994,7 @@ expand_member_init (exp, name, init)
else
{
if (basetype != type
&& ! binfo_member (basetype, TYPE_BINFO (type))
&& ! vec_binfo_member (basetype, TYPE_BINFO_BASETYPES (type))
&& ! binfo_member (basetype, CLASSTYPE_VBASECLASSES (type)))
{
if (IDENTIFIER_CLASS_VALUE (name))
......@@ -1783,6 +1784,9 @@ build_offset_ref (type, name)
tree basetypes = NULL_TREE;
int dtor = 0;
if (current_template_parms)
return build_min_nt (SCOPE_REF, type, name);
/* Handle namespace names fully here. */
if (TREE_CODE (type) == IDENTIFIER_NODE
&& get_aggr_from_typedef (type, 0) == 0)
......@@ -1813,7 +1817,10 @@ build_offset_ref (type, name)
if (TYPE_SIZE (type) == 0)
{
t = IDENTIFIER_CLASS_VALUE (name);
if (type == current_class_type)
t = IDENTIFIER_CLASS_VALUE (name);
else
t = NULL_TREE;
if (t == 0)
{
cp_error ("incomplete type `%T' does not have member `%D'", type,
......@@ -2190,12 +2197,12 @@ is_friend (type, supplicant)
if (name == TREE_PURPOSE (list))
{
tree friends = TREE_VALUE (list);
name = DECL_ASSEMBLER_NAME (supplicant);
for (; friends ; friends = TREE_CHAIN (friends))
{
if (ctype == TREE_PURPOSE (friends))
return 1;
if (name == DECL_ASSEMBLER_NAME (TREE_VALUE (friends)))
if (comptypes (TREE_TYPE (supplicant),
TREE_TYPE (TREE_VALUE (friends)), 1))
return 1;
}
break;
......@@ -2401,10 +2408,11 @@ make_friend_class (type, friend_type)
QUALS say what special qualifies should apply to the object
pointed to by `this'. */
tree
do_friend (ctype, declarator, decl, parmdecls, flags, quals)
do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
tree ctype, declarator, decl, parmdecls;
enum overload_flags flags;
tree quals;
int funcdef_flag;
{
/* Every decl that gets here is a friend of something. */
DECL_FRIEND_P (decl) = 1;
......@@ -2424,7 +2432,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
/* This will set up DECL_ARGUMENTS for us. */
grokclassfn (ctype, cname, decl, flags, quals);
if (TYPE_SIZE (ctype) != 0)
check_classfn (ctype, cname, decl);
check_classfn (ctype, decl);
if (TREE_TYPE (decl) != error_mark_node)
{
......@@ -2492,7 +2500,8 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
= build_decl_overload (declarator, TYPE_ARG_TYPES (TREE_TYPE (decl)),
TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE);
DECL_ARGUMENTS (decl) = parmdecls;
DECL_CLASS_CONTEXT (decl) = current_class_type;
if (funcdef_flag)
DECL_CLASS_CONTEXT (decl) = current_class_type;
/* We can call pushdecl here, because the TREE_CHAIN of this
FUNCTION_DECL is not needed for other purposes. */
......@@ -2639,6 +2648,11 @@ build_new (placement, decl, init, use_global_new)
{
if (this_nelts == NULL_TREE)
error ("new of array type fails to specify size");
else if (current_template_parms)
{
nelts = this_nelts;
absdcl = TREE_OPERAND (absdcl, 0);
}
else
{
this_nelts = save_expr (convert (sizetype, this_nelts));
......@@ -2704,6 +2718,21 @@ build_new (placement, decl, init, use_global_new)
decl = TYPE_NAME (type);
}
if (current_template_parms)
{
tree t;
if (has_array)
t = min_tree_cons (min_tree_cons (NULL_TREE, type, NULL_TREE),
build_min_nt (ARRAY_REF, NULL_TREE, nelts),
NULL_TREE);
else
t = type;
rval = build_min_nt (NEW_EXPR, placement, t, init);
NEW_EXPR_USE_GLOBAL (rval) = use_global_new;
return rval;
}
/* ``A reference cannot be created by the new operator. A reference
is not an object (8.2.2, 8.4.3), so a pointer to it could not be
returned by new.'' ARM 5.3.3 */
......@@ -2740,6 +2769,13 @@ build_new (placement, decl, init, use_global_new)
nelts = build_binary_op (MULT_EXPR, nelts, this_nelts, 1);
true_type = TREE_TYPE (true_type);
}
if (TYPE_SIZE (complete_type (true_type)) == 0)
{
incomplete_type_error (0, true_type);
return error_mark_node;
}
if (has_array)
size = fold (build_binary_op (MULT_EXPR, size_in_bytes (true_type),
nelts, 1));
......@@ -2752,12 +2788,6 @@ build_new (placement, decl, init, use_global_new)
return error_mark_node;
}
if (TYPE_SIZE (true_type) == 0)
{
incomplete_type_error (0, true_type);
return error_mark_node;
}
if (TYPE_LANG_SPECIFIC (true_type)
&& CLASSTYPE_ABSTRACT_VIRTUALS (true_type))
{
......@@ -3473,7 +3503,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
if (TREE_CODE (type) == POINTER_TYPE)
{
type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
if (TYPE_SIZE (type) == 0)
if (TYPE_SIZE (complete_type (type)) == 0)
{
incomplete_type_error (0, type);
return error_mark_node;
......@@ -3505,7 +3535,6 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
return error_mark_node;
}
return build_vec_delete (addr, array_type_nelts (type),
c_sizeof_nowarn (TREE_TYPE (type)),
auto_delete, integer_two_node,
use_global_delete);
}
......@@ -3718,12 +3747,6 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
|| (TREE_VIA_VIRTUAL (base_binfo) == 0
&& ! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))))
{
tree virtual_size;
/* This is probably wrong. It should be the size of the virtual
object being deleted. */
virtual_size = c_sizeof_nowarn (type);
cond = build (COND_EXPR, void_type_node,
build (BIT_AND_EXPR, integer_type_node, auto_delete, integer_one_node),
build_builtin_call (void_type_node, BID,
......@@ -3834,9 +3857,9 @@ build_vbase_delete (type, decl)
confirm the size, and trap if the numbers differ; not clear that it'd
be worth bothering.) */
tree
build_vec_delete (base, maxindex, elt_size, auto_delete_vec, auto_delete,
build_vec_delete (base, maxindex, auto_delete_vec, auto_delete,
use_global_delete)
tree base, maxindex, elt_size;
tree base, maxindex;
tree auto_delete_vec, auto_delete;
int use_global_delete;
{
......
......@@ -346,10 +346,7 @@ build_overload_nested_name (decl)
OB_PUTCP (label);
}
else /* TYPE_DECL */
{
tree name = DECL_NAME (decl);
build_overload_identifier (name);
}
build_overload_identifier (decl);
}
/* Encoding for an INTEGER_CST value. */
......@@ -357,6 +354,27 @@ static void
build_overload_int (value)
tree value;
{
if (TREE_CODE (value) == TEMPLATE_CONST_PARM)
{
OB_PUTC ('Y');
if (TEMPLATE_CONST_IDX (value) > 9)
OB_PUTC ('_');
icat (TEMPLATE_CONST_IDX (value));
if (TEMPLATE_CONST_IDX (value) > 9)
OB_PUTC ('_');
return;
}
else if (uses_template_parms (value))
/* We don't ever want this output, but it's inconvenient not to
be able to build the string. This should cause assembler
errors we'll notice. */
{
static int n;
sprintf (digit_buffer, " *%d", n++);
OB_PUTCP (digit_buffer);
return;
}
my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243);
if (TYPE_PRECISION (value) == 2 * HOST_BITS_PER_WIDE_INT)
{
......@@ -544,11 +562,14 @@ static void
build_overload_identifier (name)
tree name;
{
if (IDENTIFIER_TEMPLATE (name))
if (TREE_CODE (name) == TYPE_DECL
&& IS_AGGR_TYPE (TREE_TYPE (name))
&& CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name))
&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name))))
{
tree template, parmlist, arglist, tname;
int i, nparms;
template = IDENTIFIER_TEMPLATE (name);
template = CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name));
arglist = TREE_VALUE (template);
template = TREE_PURPOSE (template);
tname = DECL_NAME (template);
......@@ -580,6 +601,8 @@ build_overload_identifier (name)
}
else
{
if (TREE_CODE (name) == TYPE_DECL)
name = DECL_NAME (name);
if (numeric_output_need_bar)
{
OB_PUTC ('_');
......@@ -873,8 +896,8 @@ build_overload_name (parmtypes, begin, end)
numeric_output_need_bar = 0;
build_overload_nested_name (TYPE_MAIN_DECL (parmtype));
}
else
build_overload_identifier (name);
else
build_overload_identifier (TYPE_MAIN_DECL (parmtype));
break;
}
......@@ -884,8 +907,15 @@ build_overload_name (parmtypes, begin, end)
break;
case TEMPLATE_TYPE_PARM:
case TEMPLATE_CONST_PARM:
case UNINSTANTIATED_P_TYPE:
OB_PUTC ('X');
if (TEMPLATE_TYPE_IDX (parmtype) > 9)
OB_PUTC ('_');
icat (TEMPLATE_TYPE_IDX (parmtype));
if (TEMPLATE_TYPE_IDX (parmtype) > 9)
OB_PUTC ('_');
break;
case TYPENAME_TYPE:
/* We don't ever want this output, but it's inconvenient not to
be able to build the string. This should cause assembler
errors we'll notice. */
......@@ -1468,7 +1498,6 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
NAME is $1 from the bison rule. It is an IDENTIFIER_NODE.
VALUE is $$ from the bison rule. It is the value returned by lookup_name ($1)
yychar is the pending input character (suitably encoded :-).
As a last ditch, try to look up the name as a label and return that
address.
......@@ -1478,11 +1507,10 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
compiler faster). */
tree
hack_identifier (value, name, yychar)
hack_identifier (value, name)
tree value, name;
int yychar;
{
tree type;
tree type, context;
if (TREE_CODE (value) == ERROR_MARK)
{
......@@ -1562,6 +1590,20 @@ hack_identifier (value, name, yychar)
else
mark_used (value);
if (pedantic
&& (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL))
{
tree context = decl_function_context (value);
if (context != NULL_TREE && context != current_function_decl
&& ! TREE_STATIC (value))
{
cp_pedwarn ("use of %s from containing function",
(TREE_CODE (value) == VAR_DECL
? "`auto' variable" : "parameter"));
cp_pedwarn_at (" `%#D' declared here", value);
}
}
if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && DECL_NONLOCAL (value))
{
if (DECL_LANG_SPECIFIC (value)
......@@ -1605,7 +1647,7 @@ hack_identifier (value, name, yychar)
return value;
}
if (TREE_CODE (type) == REFERENCE_TYPE)
if (TREE_CODE (type) == REFERENCE_TYPE && ! current_template_parms)
{
my_friendly_assert (TREE_CODE (value) == VAR_DECL
|| TREE_CODE (value) == PARM_DECL
......@@ -2217,9 +2259,6 @@ do_build_assign_ref (fndecl)
pop_momentary ();
}
void push_cp_function_context ();
void pop_cp_function_context ();
void
synthesize_method (fndecl)
tree fndecl;
......
......@@ -72,13 +72,6 @@ print_lang_type (file, node, indent)
return;
}
if (TREE_CODE (node) == UNINSTANTIATED_P_TYPE)
{
print_node (file, "template", UPT_TEMPLATE (node), indent + 4);
print_node (file, "parameters", UPT_PARMS (node), indent + 4);
return;
}
if (! (TREE_CODE (node) == RECORD_TYPE
|| TREE_CODE (node) == UNION_TYPE))
return;
......
......@@ -49,6 +49,7 @@ extern struct obstack permanent_obstack;
#define IDENTIFIER_REPO_USED(NODE) (TREE_LANG_FLAG_3 (NODE))
#define IDENTIFIER_REPO_CHOSEN(NODE) (TREE_LANG_FLAG_4 (NODE))
#if 0
/* Record the flags used to compile this translation unit. */
void
......@@ -82,8 +83,9 @@ void
repo_class_defined (t)
tree t;
{}
#endif
tree
static tree
repo_get_id (t)
tree t;
{
......@@ -120,7 +122,7 @@ repo_template_used (t)
else if (TREE_CODE_CLASS (TREE_CODE (t)) == 'd')
{
if (IDENTIFIER_REPO_CHOSEN (id))
mark_function_instantiated (t, 0);
mark_decl_instantiated (t, 0);
}
else
my_friendly_abort (1);
......@@ -132,9 +134,10 @@ repo_template_used (t)
}
}
#if 0
/* Note that the vtable for a class has been used, and offer to emit it. */
void
static void
repo_vtable_used (t)
tree t;
{
......@@ -172,6 +175,7 @@ repo_tinfo_used (ti)
tree ti;
{
}
#endif
void
repo_template_instantiated (t, extern_p)
......@@ -246,7 +250,7 @@ static void
open_repo_file (filename)
char *filename;
{
register char *p, *q;
register char *p;
char *s = get_base_filename (filename);
if (s == NULL)
......
......@@ -37,7 +37,7 @@ extern tree combine_strings PROTO((tree));
/* Given the expression EXP of type `class *', return the head
of the object pointed to by EXP. */
tree
static tree
build_headof (exp)
tree exp;
{
......@@ -156,7 +156,7 @@ get_typeid (type)
/* Get a bad_cast node for the program to throw...
See libstdc++::exception{,.cc} for __bad_cast_object */
tree
static tree
get_bad_cast_node ()
{
static tree t;
......@@ -179,7 +179,6 @@ build_dynamic_cast (type, expr)
enum tree_code tc = TREE_CODE (type);
tree exprtype = TREE_TYPE (expr);
enum tree_code ec = TREE_CODE (exprtype);
tree retval;
if (type == error_mark_node || expr == error_mark_node)
return error_mark_node;
......@@ -268,7 +267,7 @@ build_dynamic_cast (type, expr)
else
{
tree retval;
tree result, td1, td2, elems, tmp1, expr1;
tree result, td1, td2, elems, expr1;
/* If we got here, we can't convert statically. Therefore,
dynamic_cast<D&>(b) (b an object) cannot succeed. */
......@@ -462,7 +461,7 @@ static tree
build_user_desc (tdecl)
tree tdecl;
{
tree elems, name_string, t;
tree elems, name_string;
tree tname = DECL_NAME (tdecl);
name_string = combine_strings (build_string
......@@ -481,13 +480,15 @@ build_class_desc (tdecl, type)
tree name_string;
int i = CLASSTYPE_N_BASECLASSES (type);
int n_base = i;
int base_cnt = 0;
tree binfos = TYPE_BINFO_BASETYPES (type);
#if 0
/* See code below that used these. */
tree vb = CLASSTYPE_VBASECLASSES (type);
int n_base = i;
#endif
tree base, elems, access, offset, isvir;
tree base_list, off_list, acc_list, isvir_list;
tree t;
static tree acc_pub = NULL_TREE;
static tree acc_pro = NULL_TREE;
static tree acc_pri = NULL_TREE;
......@@ -516,7 +517,6 @@ build_class_desc (tdecl, type)
tree t = BINFO_TYPE (binfo);
char *name;
tree field;
int off;
name = (char *) alloca (TYPE_NAME_LENGTH (t)+sizeof (VBASE_NAME)+1);
sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (t));
......@@ -659,9 +659,8 @@ build_func_desc (tdecl)
/* Build an initializer for a __ptmf_type_info node. */
static tree
build_ptmf_desc (tdecl, type)
build_ptmf_desc (tdecl)
tree tdecl;
tree type;
{
tree elems, name_string;
tree tname = DECL_NAME (tdecl);
......@@ -711,7 +710,7 @@ add_uninstantiated_desc (type)
objects, we do that here. Return the type to link against if such a
link exists, otherwise just return TYPE. */
tree
static tree
get_def_to_follow (type)
tree type;
{
......@@ -735,10 +734,8 @@ build_t_desc (type, definition)
tree type;
int definition;
{
tree tdecl;
tree tname, name_string;
tree elems;
tree t, tt, taggr;
tree tdecl, tname;
tree t, taggr;
if (__ptmd_desc_type_node == NULL_TREE)
{
......@@ -841,13 +838,9 @@ build_t_desc (type, definition)
else if (IS_AGGR_TYPE (type))
{
if (TYPE_PTRMEMFUNC_P (type))
{
t = build_ptmf_desc (tdecl, type);
}
t = build_ptmf_desc (tdecl);
else
{
t = build_class_desc (tdecl, type);
}
t = build_class_desc (tdecl, type);
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
t = build_func_desc (tdecl);
......
......@@ -534,7 +534,7 @@ build_signature_table_constructor (sig_ty, rhs)
{
error ("class `%s' does not contain a method conforming to `%s'",
TYPE_NAME_STRING (rhstype),
fndecl_as_string (NULL, sig_method, 1));
fndecl_as_string (sig_method, 1));
undo_casts (sig_ty);
return error_mark_node;
}
......@@ -1000,7 +1000,7 @@ build_signature_method_call (basetype, instance, function, parms)
&& (!deflt_call || deflt_call == error_mark_node)))
{
compiler_error ("cannot build call of signature member function `%s'",
fndecl_as_string (NULL, function, 1));
fndecl_as_string (function, 1));
return error_mark_node;
}
......
......@@ -295,8 +295,8 @@ yylex()
if (lastiddecl != trrr)
{
lastiddecl = trrr;
if (got_scope || got_object)
tmp_token.yylval.ttype = DECL_NESTED_TYPENAME (trrr);
if (got_scope)
tmp_token.yylval.ttype = trrr;
}
break;
case IDENTIFIER:
......@@ -307,7 +307,7 @@ yylex()
break;
case NSNAME:
lastiddecl = trrr;
if (got_scope || got_object)
if (got_scope)
tmp_token.yylval.ttype = trrr;
break;
default:
......@@ -352,6 +352,7 @@ yylex()
consume_token();
}
got_object = NULL_TREE;
yylval = tmp_token.yylval;
yychar = tmp_token.yychar;
end_of_file = tmp_token.end_of_file;
......
......@@ -26,6 +26,11 @@ Boston, MA 02111-1307, USA. */
#include "cp-tree.h"
#include "flags.h"
#include "rtl.h"
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#define CEIL(x,y) (((x) + (y) - 1) / (y))
......@@ -202,10 +207,9 @@ lvalue_or_else (ref, string)
and return it so that it can be processed by language-independent
and language-specific expression expanders. */
tree
build_cplus_new (type, init, with_cleanup_p)
build_cplus_new (type, init)
tree type;
tree init;
int with_cleanup_p;
{
tree slot;
tree rval;
......@@ -234,7 +238,7 @@ break_out_cleanups (exp)
if (TREE_CODE (tmp) == CALL_EXPR
&& TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (tmp)))
return build_cplus_new (TREE_TYPE (tmp), tmp, 1);
return build_cplus_new (TREE_TYPE (tmp), tmp);
while (TREE_CODE (tmp) == NOP_EXPR
|| TREE_CODE (tmp) == CONVERT_EXPR
......@@ -245,7 +249,7 @@ break_out_cleanups (exp)
{
TREE_OPERAND (tmp, 0)
= build_cplus_new (TREE_TYPE (TREE_OPERAND (tmp, 0)),
TREE_OPERAND (tmp, 0), 1);
TREE_OPERAND (tmp, 0));
break;
}
else
......@@ -412,7 +416,14 @@ build_cplus_array_type (elt_type, index_type)
saveable_obstack = &permanent_obstack;
}
t = build_array_type (elt_type, index_type);
if (current_template_parms)
{
t = make_node (ARRAY_TYPE);
TREE_TYPE (t) = elt_type;
TYPE_DOMAIN (t) = index_type;
}
else
t = build_array_type (elt_type, index_type);
/* Push these needs up so that initialization takes place
more easily. */
......@@ -568,7 +579,6 @@ layout_vbasetypes (rec, max)
register unsigned const_size = 0;
register tree var_size = 0;
int nonvirtual_const_size;
tree nonvirtual_var_size;
CLASSTYPE_VBASECLASSES (rec) = vbase_types;
......@@ -578,7 +588,6 @@ layout_vbasetypes (rec, max)
var_size = TYPE_SIZE (rec);
nonvirtual_const_size = const_size;
nonvirtual_var_size = var_size;
while (vbase_types)
{
......@@ -1403,10 +1412,7 @@ build_exception_variant (type, raises)
tree type;
tree raises;
{
int i;
tree v = TYPE_MAIN_VARIANT (type);
tree t, t2, cname;
tree *a = (tree *)alloca ((list_length (raises)+1) * sizeof (tree));
int constp = TYPE_READONLY (type);
int volatilep = TYPE_VOLATILE (type);
......@@ -1435,6 +1441,7 @@ build_exception_variant (type, raises)
raises = copy_list (raises);
pop_obstacks ();
}
TYPE_RAISES_EXCEPTIONS (v) = raises;
return v;
}
......@@ -1449,7 +1456,6 @@ mapcar (t, func)
tree t;
tree (*func)();
{
enum tree_code code;
tree tmp;
if (t == NULL_TREE)
......@@ -1458,7 +1464,7 @@ mapcar (t, func)
if (tmp = func (t), tmp != NULL_TREE)
return tmp;
switch (code = TREE_CODE (t))
switch (TREE_CODE (t))
{
case ERROR_MARK:
return error_mark_node;
......@@ -1552,6 +1558,8 @@ mapcar (t, func)
case POSTDECREMENT_EXPR:
case POSTINCREMENT_EXPR:
case CALL_EXPR:
case ARRAY_REF:
case SCOPE_REF:
t = copy_node (t);
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
......@@ -1646,15 +1654,24 @@ copy_to_permanent (t)
return t;
}
#ifdef GATHER_STATISTICS
extern int depth_reached;
#endif
void
print_lang_statistics ()
{
extern struct obstack maybepermanent_obstack;
extern struct obstack maybepermanent_obstack, decl_obstack;
print_obstack_statistics ("class_obstack", &class_obstack);
print_obstack_statistics ("decl_obstack", &decl_obstack);
print_obstack_statistics ("permanent_obstack", &permanent_obstack);
print_obstack_statistics ("maybepermanent_obstack", &maybepermanent_obstack);
print_search_statistics ();
print_class_statistics ();
#ifdef GATHER_STATISTICS
fprintf (stderr, "maximum template instantiation depth reached: %d\n",
depth_reached);
#endif
}
/* This is used by the `assert' macro. It is provided in libgcc.a,
......@@ -1720,7 +1737,7 @@ bot_manip (t)
return t;
else if (TREE_CODE (t) == TARGET_EXPR)
return build_cplus_new (TREE_TYPE (t),
break_out_target_exprs (TREE_OPERAND (t, 1)), 0);
break_out_target_exprs (TREE_OPERAND (t, 1)));
return NULL_TREE;
}
......@@ -1819,3 +1836,151 @@ cp_expand_decl_cleanup (decl, cleanup)
{
return expand_decl_cleanup (decl, unsave_expr (cleanup));
}
/* Obstack used for allocating nodes in template function and variable
definitions. */
extern struct obstack *expression_obstack;
/* Similar to `build_nt', except we build
on the permanent_obstack, regardless. */
tree
build_min_nt VPROTO((enum tree_code code, ...))
{
#ifndef __STDC__
enum tree_code code;
#endif
register struct obstack *ambient_obstack = expression_obstack;
va_list p;
register tree t;
register int length;
register int i;
VA_START (p, code);
#ifndef __STDC__
code = va_arg (p, enum tree_code);
#endif
expression_obstack = &permanent_obstack;
t = make_node (code);
length = tree_code_length[(int) code];
TREE_COMPLEXITY (t) = lineno;
for (i = 0; i < length; i++)
{
tree x = va_arg (p, tree);
TREE_OPERAND (t, i) = copy_to_permanent (x);
}
va_end (p);
expression_obstack = ambient_obstack;
return t;
}
/* Similar to `build', except we build
on the permanent_obstack, regardless. */
tree
build_min VPROTO((enum tree_code code, tree tt, ...))
{
#ifndef __STDC__
enum tree_code code;
tree tt;
#endif
register struct obstack *ambient_obstack = expression_obstack;
va_list p;
register tree t;
register int length;
register int i;
VA_START (p, tt);
#ifndef __STDC__
code = va_arg (p, enum tree_code);
tt = va_arg (p, tree);
#endif
expression_obstack = &permanent_obstack;
t = make_node (code);
length = tree_code_length[(int) code];
TREE_TYPE (t) = tt;
TREE_COMPLEXITY (t) = lineno;
for (i = 0; i < length; i++)
{
tree x = va_arg (p, tree);
TREE_OPERAND (t, i) = copy_to_permanent (x);
}
va_end (p);
expression_obstack = ambient_obstack;
return t;
}
/* Same as `tree_cons' but make a permanent object. */
tree
min_tree_cons (purpose, value, chain)
tree purpose, value, chain;
{
register tree node;
register struct obstack *ambient_obstack = current_obstack;
current_obstack = &permanent_obstack;
node = tree_cons (purpose, value, chain);
current_obstack = ambient_obstack;
return node;
}
tree
get_type_decl (t)
tree t;
{
if (TREE_CODE (t) == IDENTIFIER_NODE)
return identifier_typedecl_value (t);
if (TREE_CODE (t) == TYPE_DECL)
return t;
if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
return TYPE_STUB_DECL (t);
my_friendly_abort (42);
}
int
can_free (obstack, t)
struct obstack *obstack;
tree t;
{
int size;
if (TREE_CODE (t) == TREE_VEC)
size = (TREE_VEC_LENGTH (t)-1) * sizeof (tree) + sizeof (struct tree_vec);
else
my_friendly_abort (42);
#define ROUND(x) ((x + obstack_alignment_mask (obstack)) \
& ~ obstack_alignment_mask (obstack))
if ((char *)t + ROUND (size) == obstack_next_free (obstack))
return 1;
#undef ROUND
return 0;
}
/* Return first vector element whose BINFO_TYPE is ELEM.
Return 0 if ELEM is not in VEC. */
tree
vec_binfo_member (elem, vec)
tree elem, vec;
{
int i;
for (i = 0; i < TREE_VEC_LENGTH (vec); ++i)
if (elem == BINFO_TYPE (TREE_VEC_ELT (vec, i)))
return TREE_VEC_ELT (vec, i);
return NULL_TREE;
}
......@@ -468,8 +468,8 @@ initializer_constant_valid_p (value, endtype)
return 0;
case PLUS_EXPR:
if (TREE_CODE (endtype) == INTEGER_TYPE
&& TYPE_PRECISION (endtype) < POINTER_SIZE)
if ((TREE_CODE (endtype) == INTEGER_TYPE)
&& (TYPE_PRECISION (endtype) < POINTER_SIZE))
return 0;
{
tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
......@@ -485,8 +485,8 @@ initializer_constant_valid_p (value, endtype)
}
case MINUS_EXPR:
if (TREE_CODE (endtype) == INTEGER_TYPE
&& TYPE_PRECISION (endtype) < POINTER_SIZE)
if ((TREE_CODE (endtype) == INTEGER_TYPE)
&& (TYPE_PRECISION (endtype) < POINTER_SIZE))
return 0;
{
tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
......@@ -1287,6 +1287,9 @@ build_x_arrow (datum)
if (type == error_mark_node)
return error_mark_node;
if (current_template_parms)
return build_min_nt (ARROW_EXPR, rval);
if (TREE_CODE (rval) == OFFSET_REF)
{
rval = resolve_offset_ref (datum);
......@@ -1299,7 +1302,7 @@ build_x_arrow (datum)
type = TREE_TYPE (rval);
}
if (IS_AGGR_TYPE (type) && TYPE_OVERLOADS_ARROW (type))
if (IS_AGGR_TYPE (type) && TYPE_OVERLOADS_ARROW (complete_type (type)))
{
while ((rval = build_opfncall (COMPONENT_REF, LOOKUP_NORMAL, rval, NULL_TREE, NULL_TREE)))
{
......@@ -1359,6 +1362,9 @@ build_m_component_ref (datum, component)
tree rettype;
tree binfo;
if (current_template_parms)
return build_min_nt (DOTSTAR_EXPR, datum, component);
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (component)))
{
type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (component)));
......@@ -1445,6 +1451,9 @@ build_functional_cast (exp, parms)
else
type = exp;
if (current_template_parms)
return build_min (CAST_EXPR, type, parms);
if (IS_SIGNATURE (type))
{
error ("signature type not allowed in cast or constructor expression");
......@@ -1480,7 +1489,7 @@ build_functional_cast (exp, parms)
name = DECL_NESTED_TYPENAME (name);
}
if (TYPE_SIZE (type) == NULL_TREE)
if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
{
cp_error ("type `%T' is not yet defined", type);
return error_mark_node;
......@@ -1495,7 +1504,7 @@ build_functional_cast (exp, parms)
if (expr_as_ctor == error_mark_node)
return error_mark_node;
return build_cplus_new (type, expr_as_ctor, 1);
return build_cplus_new (type, expr_as_ctor);
}
/* Return the character string for the name that encodes the
......
......@@ -183,7 +183,7 @@ GNU_xref_end (ect)
if (xf == NULL) return;
while (cur_scope != NULL)
GNU_xref_end_scope(cur_scope->gid,0,0,0,0);
GNU_xref_end_scope(cur_scope->gid,0,0,0);
doing_xref = 0;
......@@ -275,10 +275,10 @@ GNU_xref_start_scope (id)
TRNS is ??? */
void
GNU_xref_end_scope (id,inid,prm,keep,trns)
GNU_xref_end_scope (id,inid,prm,keep)
HOST_WIDE_INT id;
HOST_WIDE_INT inid;
int prm,keep,trns;
int prm,keep;
{
XREF_FILE xf;
XREF_SCOPE xs,lxs,oxs;
......@@ -400,7 +400,7 @@ GNU_xref_decl (fndecl,decl)
}
else if (TREE_CODE (decl) == TEMPLATE_DECL)
{
if (DECL_TEMPLATE_IS_CLASS (decl))
if (TREE_CODE (DECL_RESULT (decl)) == TYPE_DECL)
cls = "CLASSTEMP";
else if (TREE_CODE (DECL_RESULT (decl)) == FUNCTION_DECL)
cls = "FUNCTEMP";
......@@ -599,7 +599,9 @@ GNU_xref_member(cls, fld)
char *prot;
int confg, pure;
char *d;
#ifdef XREF_SHORT_MEMBER_NAMES
int i;
#endif
char buf[1024], bufa[1024];
if (!doing_xref) return;
......@@ -622,7 +624,9 @@ GNU_xref_member(cls, fld)
d = IDENTIFIER_POINTER(cls);
sprintf(buf, "%d%s", strlen(d), d);
#ifdef XREF_SHORT_MEMBER_NAMES
i = strlen(buf);
#endif
strcpy(bufa, declname(fld));
#ifdef XREF_SHORT_MEMBER_NAMES
......
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