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