Commit be99da77 by Mike Stump

78th Cygnus<->FSF merge

From-SVN: r11039
parent 3a265431
Wed Jan 17 10:18:01 1996 Mike Stump <mrs@cygnus.com>
* decl2.c (warn_pointer_arith): Default to on.
Tue Jan 16 12:45:38 1996 Jason Merrill <jason@yorick.cygnus.com>
* lex.c (is_rid): New function.
* decl.c (grokdeclarator): Diagnose reserved words used as
declarator-ids.
Tue Jan 16 11:39:40 1996 Jason Merrill <jason@yorick.cygnus.com>
* tree.c (get_decl_list): Don't lose cv-quals.
* decl.c (grokdeclarator): Fix SCOPE_REF handling and diagnose
typespecs used as declarator-ids.
Tue Jan 16 11:09:42 1996 Mike Stump <mrs@cygnus.com>
* decl.c (poplevel): When poping a level, don't give a warning for
any subblocks that already exist.
Tue Jan 16 00:25:33 1996 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (build_object_ref): Finish what I started.
* parse.y (qualified_type_name): Don't check TYPE_BUILT_IN.
* decl2.c (constructor_name_full): Handle TEMPLATE_TYPE_PARMs.
* decl.c (grokdeclarator): Also accept TEMPLATE_TYPE_PARM as a
scope.
Mon Jan 15 16:19:32 1996 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (xref_tag): Handle passing a type in directly.
* parse.y (qualified_type_name): Pull out the type.
(nested_type): Ditto.
Take types directly instead of as identifiers.
* call.c (build_scoped_method_call): Take types directly instead of
as identifiers.
* decl.c (xref_basetypes): Ditto.
* init.c (expand_member_init): Ditto.
(build_member_call): Ditto.
(build_offset_ref): Ditto.
* typeck2.c (build_scoped_ref): Ditto, remove bogus code.
* method.c (do_build_assign_ref): Ditto.
* decl.c (grokdeclarator): Handle a type appearing as the
declarator-id for constructors.
* method.c (do_build_copy_constructor): current_base_init_list now
uses the types directly, not their names.
* init.c (sort_base_init): Ditto.
(expand_member_init): Ditto.
* init.c (is_aggr_type): New function, like is_aggr_typedef.
* class.c (pushclass): If !modify and
CLASSTYPE_LOCAL_TYPEDECLS (type)), do set up IDENTIFIER_TYPE_VALUE
for inherited types.
Mon Jan 15 08:45:01 1996 Jeffrey A Law (law@cygnus.com)
* tree.c (layout_basetypes): Call build_lang_field_decl instead
of build_lang_decl if first arg is a FIELD_DECL.
(tree_copy_lang_decl_for_deferred_output): Reverse test for when
to copy DECL_MAIN_VARIANT and DECL_CHAIN.
Thu Jan 11 14:55:07 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
* decl.c (cp_finish_decl): Only clear TREE_USED if DECL_NAME is
non-empty.
* except.c (expand_start_catch_block): Set TREE_USED to avoid
warnings about the catch handler.
Mon Jan 8 17:35:12 1996 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (build_modify_expr): Use a COMPOUND_EXPR instead of
expand_target_expr.
Thu Jan 4 12:30:32 1996 Brendan Kehoe <brendan@lisa.cygnus.com>
Fix access control to use trees rather than integers.
* class.c (access_{default, public, protected, private,
default_virtual, public_virtual, private_virtual}_node): Add
definitions.
(init_class_processing): Do creation of those nodes.
* cp-tree.h (access_type): Delete enum decl.
(access_{default, public, protected, private, default_virtual,
public_virtual, private_virtual}_node): Add decls.
(compute_access): Change return type.
* search.c (compute_access): Have tree return type, instead of enum.
(lookup_field): Declare THIS_V and NEW_V to be tree nodes.
* lex.c (real_yylex): Use yylval.ttype for giving the value of the
access_* node for each of RID_{PUBLIC, PRIVATE, PROTECTED}.
* parse.y (VISSPEC): Make ttype rather than itype.
(base_class_access_list): Likewise.
* *.[cy]: Change all refs of `access_public' to `access_public_node',
etc.
* call.c (build_method_call): Make ACCESS be a tree.
* class.c (alter_access, finish_struct_1, filter_struct): Likewise.
* cvt.c (convert_to_aggr): Likewise.
* init.c (build_offset_ref, resolve_offset_ref, build_delete):
Likewise.
* method.c (hack_identifier): Likewise.
* typeck.c (build_component_ref_1, build_component_ref): ): Likewise.
Thu Jan 4 11:02:20 1996 Mike Stump <mrs@cygnus.com>
* typeck.c (pointer_int_sum, pointer_diff): Make code agree with C
frontend, and make it more consistent with respect to
warn_pointer_arith.
Tue Jan 2 00:13:38 1996 Rusty Russell <rusty@adelaide.maptek.com.au>
* decl.c (pushdecl): Check for duplicate parameter names.
Wed Jan 3 09:25:48 1996 Mike Stump <mrs@cygnus.com>
* decl.c (expand_static_init): Call assemble_external for atexit.
Wed Jan 3 07:55:19 1996 Mike Stump <mrs@cygnus.com>
* except.c (do_unwind): Remove some generated dead code.
(eh_outer_context): New routine, factor out some common code from
expand_builtin_throw and end_eh_unwinder. Add code to do return
address masking for the PA.
(expand_builtin_throw): Use eh_outer_context instead of open coding
it here.
(end_eh_unwinder): Ditto.
Tue Jan 2 17:00:56 1996 Mike Stump <mrs@cygnus.com>
* except.c (expand_throw): Call assemble_external for __empty, if we
use it.
Thu Dec 28 11:13:15 1995 Mike Stump <mrs@cygnus.com>
* except.c (expand_builtin_throw): Use RETURN_ADDR_OFFSET instead of
......@@ -3977,7 +4111,7 @@ Fri Dec 9 18:17:37 1994 Doug Evans <dje@cygnus.com>
(PARSE_H): Depend on $(PARSE_C), for parallel makes.
(PARSE_C): Undo last patch.
Fri Dec 2 10:44:36 1994 Mike Stump (mrs@wombat.gnu.ai.mit.edu)
Fri Dec 2 10:44:36 1994 Mike Stump <mrs@cygnus.com>
* Makefile.in (BISONFLAGS): Add --yacc so that output winds up in
y.tab.c.
......
......@@ -1461,8 +1461,8 @@ resolve_scope_to_name (outer_type, inner_stuff)
/* Build a method call of the form `EXP->SCOPES::NAME (PARMS)'.
This is how virtual function calls are avoided. */
tree
build_scoped_method_call (exp, scopes, name, parms)
tree exp, scopes, name, parms;
build_scoped_method_call (exp, basetype, name, parms)
tree exp, basetype, name, parms;
{
/* Because this syntactic form does not allow
a pointer to a base class to be `stolen',
......@@ -1470,23 +1470,20 @@ build_scoped_method_call (exp, scopes, name, parms)
that happens here.
@@ But we do have to check access privileges later. */
tree basename = resolve_scope_to_name (NULL_TREE, scopes);
tree basetype, binfo, decl;
tree binfo, decl;
tree type = TREE_TYPE (exp);
if (type == error_mark_node
|| basename == NULL_TREE)
|| basetype == error_mark_node)
return error_mark_node;
basetype = IDENTIFIER_TYPE_VALUE (basename);
if (TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type);
/* Destructors can be "called" for simple types; see 5.2.4 and 12.4 Note
that explicit ~int is caught in the parser; this deals with typedefs
and template parms. */
if (TREE_CODE (name) == BIT_NOT_EXPR && ! is_aggr_typedef (basename, 0))
if (TREE_CODE (name) == BIT_NOT_EXPR && ! IS_AGGR_TYPE (basetype))
{
if (type != basetype)
cp_error ("type of `%E' does not match destructor type `%T' (type was `%T')",
......@@ -1498,7 +1495,7 @@ build_scoped_method_call (exp, scopes, name, parms)
return convert (void_type_node, exp);
}
if (! is_aggr_typedef (basename, 1))
if (! is_aggr_type (basetype, 1))
return error_mark_node;
if (! IS_AGGR_TYPE (type))
......@@ -1516,7 +1513,7 @@ build_scoped_method_call (exp, scopes, name, parms)
decl = build_indirect_ref (convert_pointer_to (binfo,
build_unary_op (ADDR_EXPR, exp, 0)), NULL_PTR);
else
decl = build_scoped_ref (exp, scopes);
decl = build_scoped_ref (exp, basetype);
/* Call to a destructor. */
if (TREE_CODE (name) == BIT_NOT_EXPR)
......@@ -1613,7 +1610,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
register tree baselink, result, method_name, parmtypes, parm;
tree last;
int pass;
enum access_type access = access_public;
tree access = access_public_node;
/* Range of cases for vtable optimization. */
enum vtable_needs { not_needed, maybe_needed, unneeded, needed };
......@@ -2422,7 +2419,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
if (flags & LOOKUP_PROTECT)
access = compute_access (basetype_path, function);
if (access == access_private)
if (access == access_private_node)
{
if (flags & LOOKUP_COMPLAIN)
{
......@@ -2433,7 +2430,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
}
return error_mark_node;
}
else if (access == access_protected)
else if (access == access_protected_node)
{
if (flags & LOOKUP_COMPLAIN)
{
......
......@@ -98,6 +98,15 @@ char *dont_allow_type_definitions;
via this node. */
static tree base_layout_decl;
/* Constants used for access control. */
tree access_default_node; /* 0 */
tree access_public_node; /* 1 */
tree access_protected_node; /* 2 */
tree access_private_node; /* 3 */
tree access_default_virtual_node; /* 4 */
tree access_public_virtual_node; /* 5 */
tree access_private_virtual_node; /* 6 */
/* Variables shared between class.c and call.c. */
int n_vtables = 0;
......@@ -1108,10 +1117,10 @@ static int
alter_access (t, fdecl, access)
tree t;
tree fdecl;
enum access_type access;
tree access;
{
tree elem = purpose_member (t, DECL_ACCESS (fdecl));
if (elem && TREE_VALUE (elem) != (tree)access)
if (elem && TREE_VALUE (elem) != access)
{
if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL)
{
......@@ -1123,25 +1132,24 @@ alter_access (t, fdecl, access)
}
else if (TREE_PRIVATE (fdecl))
{
if (access != access_private)
if (access != access_private_node)
cp_error_at ("cannot make private `%D' non-private", fdecl);
goto alter;
}
else if (TREE_PROTECTED (fdecl))
{
if (access != access_protected)
if (access != access_protected_node)
cp_error_at ("cannot make protected `%D' non-protected", fdecl);
goto alter;
}
/* ARM 11.3: an access declaration may not be used to restrict access
to a member that is accessible in the base class. */
else if (access != access_public)
else if (access != access_public_node)
cp_error_at ("cannot reduce access of public member `%D'", fdecl);
else if (elem == NULL_TREE)
{
alter:
DECL_ACCESS (fdecl) = tree_cons (t, (tree)access,
DECL_ACCESS (fdecl));
DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
return 1;
}
return 0;
......@@ -2957,16 +2965,16 @@ finish_struct_1 (t, warn_anon)
if (DECL_NAME (x) && TREE_CODE (DECL_NAME (x)) == SCOPE_REF)
{
tree fdecl = TREE_OPERAND (DECL_NAME (x), 1);
enum access_type access
= TREE_PRIVATE (x) ? access_private :
TREE_PROTECTED (x) ? access_protected : access_public;
tree access
= TREE_PRIVATE (x) ? access_private_node :
TREE_PROTECTED (x) ? access_protected_node : access_public_node;
if (last_x)
TREE_CHAIN (last_x) = TREE_CHAIN (x);
else
fields = TREE_CHAIN (x);
access_decls = tree_cons ((tree) access, fdecl, access_decls);
access_decls = tree_cons (access, fdecl, access_decls);
continue;
}
......@@ -3411,7 +3419,7 @@ finish_struct_1 (t, warn_anon)
tree fdecl = TREE_VALUE (access_decls);
tree flist = NULL_TREE;
tree name;
enum access_type access = (enum access_type)TREE_PURPOSE(access_decls);
tree access = TREE_PURPOSE(access_decls);
int i = TREE_VEC_ELT (method_vec, 0) ? 0 : 1;
tree tmp;
......@@ -4053,7 +4061,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
tree *tail = &TYPE_METHODS (t);
tree name = TYPE_NAME (t);
tree x, last_x = NULL_TREE;
enum access_type access;
tree access;
if (TREE_CODE (name) == TYPE_DECL)
{
......@@ -4083,21 +4091,21 @@ finish_struct (t, list_of_fieldlists, warn_anon)
if (CLASSTYPE_DECLARED_CLASS (t) == 0)
{
if (list_of_fieldlists
&& TREE_PURPOSE (list_of_fieldlists) == (tree)access_default)
TREE_PURPOSE (list_of_fieldlists) = (tree)access_public;
&& TREE_PURPOSE (list_of_fieldlists) == access_default_node)
TREE_PURPOSE (list_of_fieldlists) = access_public_node;
}
else if (list_of_fieldlists
&& TREE_PURPOSE (list_of_fieldlists) == (tree)access_default)
TREE_PURPOSE (list_of_fieldlists) = (tree)access_private;
&& TREE_PURPOSE (list_of_fieldlists) == access_default_node)
TREE_PURPOSE (list_of_fieldlists) = access_private_node;
while (list_of_fieldlists)
{
access = (enum access_type)TREE_PURPOSE (list_of_fieldlists);
access = TREE_PURPOSE (list_of_fieldlists);
for (x = TREE_VALUE (list_of_fieldlists); x; x = TREE_CHAIN (x))
{
TREE_PRIVATE (x) = access == access_private;
TREE_PROTECTED (x) = access == access_protected;
TREE_PRIVATE (x) = access == access_private_node;
TREE_PROTECTED (x) = access == access_protected_node;
/* Check for inconsistent use of this name in the class body.
Enums, types and static vars have already been checked. */
......@@ -4306,6 +4314,14 @@ init_class_processing ()
current_lang_base = (tree *)xmalloc(current_lang_stacksize * sizeof (tree));
current_lang_stack = current_lang_base;
access_default_node = build_int_2 (0, 0);
access_public_node = build_int_2 (1, 0);
access_protected_node = build_int_2 (2, 0);
access_private_node = build_int_2 (3, 0);
access_default_virtual_node = build_int_2 (4, 0);
access_public_virtual_node = build_int_2 (5, 0);
access_private_virtual_node = build_int_2 (6, 0);
/* Keep these values lying around. */
the_null_vtable_entry = build_vtable_entry (integer_zero_node, integer_zero_node);
base_layout_decl = build_lang_field_decl (FIELD_DECL, NULL_TREE, error_mark_node);
......@@ -4400,7 +4416,7 @@ pushclass (type, modify)
else if (type != previous_class_type || current_class_depth > 1)
{
build_mi_matrix (type);
push_class_decls (type);
push_class_decls (type, !modify);
free_mi_matrix ();
if (current_class_depth == 1)
previous_class_type = type;
......@@ -4437,6 +4453,12 @@ pushclass (type, modify)
current_function_decl = this_fndecl;
}
else if (CLASSTYPE_LOCAL_TYPEDECLS (type))
{
build_mi_matrix (type);
push_class_decls (type, !modify);
free_mi_matrix ();
}
if (flag_cadillac)
cadillac_push_class (type);
......
......@@ -1727,15 +1727,14 @@ extern int current_function_parms_stored;
can have. These are sensible combinations of {public,private,protected}
cross {virtual,non-virtual}. */
enum access_type {
access_default,
access_public,
access_protected,
access_private,
access_default_virtual,
access_public_virtual,
access_private_virtual
};
/* in class.c. */
extern tree access_default_node; /* 0 */
extern tree access_public_node; /* 1 */
extern tree access_protected_node; /* 2 */
extern tree access_private_node; /* 3 */
extern tree access_default_virtual_node; /* 4 */
extern tree access_public_virtual_node; /* 5 */
extern tree access_private_virtual_node; /* 6 */
/* in lex.c */
extern tree current_unit_name, current_unit_language;
......@@ -2311,7 +2310,7 @@ extern void push_memoized_context PROTO((tree, int));
extern void pop_memoized_context PROTO((int));
extern tree get_binfo PROTO((tree, tree, int));
extern int get_base_distance PROTO((tree, tree, int, tree *));
extern enum access_type compute_access PROTO((tree, tree));
extern tree compute_access PROTO((tree, tree));
extern tree lookup_field PROTO((tree, tree, int, int));
extern tree lookup_nested_field PROTO((tree, int));
extern tree lookup_fnfields PROTO((tree, tree, int));
......@@ -2333,7 +2332,7 @@ extern void build_mi_virtuals PROTO((int, int));
extern void add_mi_virtuals PROTO((int, tree));
extern void report_ambiguous_mi_virtuals PROTO((int, tree));
extern void note_debug_info_needed PROTO((tree));
extern void push_class_decls PROTO((tree));
extern void push_class_decls PROTO((tree, int));
extern void pop_class_decls PROTO((tree));
extern void unuse_fields PROTO((tree));
extern void unmark_finished_struct PROTO((tree));
......
......@@ -896,8 +896,7 @@ 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;
enum access_type access;
tree method_name, access;
int can_be_private, can_be_protected;
if (! TYPE_HAS_CONSTRUCTOR (basetype))
......@@ -907,7 +906,7 @@ convert_to_aggr (type, expr, msgp, protect)
return error_mark_node;
}
access = access_public;
access = access_public_node;
can_be_private = 0;
can_be_protected = IDENTIFIER_CLASS_VALUE (name) || name == current_class_name;
......@@ -987,20 +986,20 @@ convert_to_aggr (type, expr, msgp, protect)
if (protect)
{
if (TREE_PRIVATE (fndecl))
access = access_private;
access = access_private_node;
else if (TREE_PROTECTED (fndecl))
access = access_protected;
access = access_protected_node;
else
access = access_public;
access = access_public_node;
}
else
access = access_public;
access = access_public_node;
if (access == access_private
if (access == access_private_node
? (basetype == current_class_type
|| is_friend (basetype, cp->function)
|| purpose_member (basetype, DECL_ACCESS (fndecl)))
: access == access_protected
: access == access_protected_node
? (can_be_protected
|| purpose_member (basetype, DECL_ACCESS (fndecl)))
: 1)
......@@ -1011,7 +1010,7 @@ convert_to_aggr (type, expr, msgp, protect)
}
else
{
if (access == access_private)
if (access == access_private_node)
saw_private = 1;
else
saw_protected = 1;
......@@ -1061,7 +1060,7 @@ convert_to_aggr (type, expr, msgp, protect)
/* NOTREACHED */
found:
if (access == access_private)
if (access == access_private_node)
if (! can_be_private)
{
if (msgp)
......@@ -1070,7 +1069,7 @@ convert_to_aggr (type, expr, msgp, protect)
: "conversion to type `%s' is from private base class";
return error_mark_node;
}
if (access == access_protected)
if (access == access_protected_node)
if (! can_be_protected)
{
if (msgp)
......
......@@ -176,7 +176,7 @@ int warn_traditional;
/* Nonzero means warn about sizeof(function) or addition/subtraction
of function pointers. */
int warn_pointer_arith;
int warn_pointer_arith = 1;
/* Nonzero means warn for non-prototype function decls
or non-prototyped defs without previous prototype. */
......@@ -2026,7 +2026,9 @@ constructor_name_full (thing)
{
if (TREE_CODE (thing) == UNINSTANTIATED_P_TYPE)
return DECL_NAME (UPT_TEMPLATE (thing));
if (IS_AGGR_TYPE_CODE (TREE_CODE (thing)))
else if (TREE_CODE (thing) == TEMPLATE_TYPE_PARM)
thing = TYPE_NAME (thing);
else if (IS_AGGR_TYPE_CODE (TREE_CODE (thing)))
{
if (TYPE_WAS_ANONYMOUS (thing) && TYPE_HAS_CONSTRUCTOR (thing))
thing = DECL_NAME (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (thing), 0));
......
......@@ -155,7 +155,7 @@ exception_section ()
if (flag_pic)
data_section ();
else
#if defined(TARGET_POWERPC) /* are we on a __rs6000? */
#if defined (TARGET_POWERPC) /* are we on a __rs6000? */
data_section ();
#else
readonly_data_section ();
......@@ -1012,6 +1012,10 @@ expand_start_catch_block (declspecs, declarator)
return;
}
/* Make sure we mark the catch param as used, otherwise we'll get
a warning about an unused ((anonymous)). */
TREE_USED (decl) = 1;
/* Figure out the type that the initializer is. */
init_type = TREE_TYPE (decl);
if (TREE_CODE (init_type) != REFERENCE_TYPE
......@@ -1167,7 +1171,8 @@ static void
do_unwind (inner_throw_label)
rtx inner_throw_label;
{
#if defined(SPARC_STACK_ALIGN) /* was sparc */
#if defined (SPARC_STACK_ALIGN) /* was sparc */
/* This doesn't work for the flat model sparc, I bet. */
tree fcall;
tree params;
rtx return_val_rtx;
......@@ -1186,7 +1191,7 @@ do_unwind (inner_throw_label)
easy_expand_asm ("restore");
emit_barrier ();
#endif
#if defined(ARM_FRAME_RTX) /* was __arm */
#if defined (ARM_FRAME_RTX) /* was __arm */
if (flag_omit_frame_pointer)
sorry ("this implementation of exception handling requires a frame pointer");
......@@ -1195,7 +1200,7 @@ do_unwind (inner_throw_label)
emit_move_insn (hard_frame_pointer_rtx,
gen_rtx (MEM, Pmode, plus_constant (hard_frame_pointer_rtx, -12)));
#endif
#if defined(TARGET_88000) /* was m88k */
#if defined (TARGET_88000) /* was m88k */
rtx temp_frame = frame_pointer_rtx;
temp_frame = memory_address (Pmode, temp_frame);
......@@ -1218,17 +1223,18 @@ do_unwind (inner_throw_label)
(HOST_WIDE_INT)m88k_debugger_offset (arg_pointer_rtx, 0))));
#endif
#endif
#if !defined(TARGET_88000) && !defined(ARM_FRAME_RTX) && !defined(SPARC_STACK_ALIGN)
#if ! defined (TARGET_88000) && ! defined (ARM_FRAME_RTX) && ! defined (SPARC_STACK_ALIGN)
tree fcall;
tree params;
rtx return_val_rtx;
#if 0
/* I would like to do this here, but the move below doesn't seem to work. */
/* call to __builtin_return_address () */
params = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
fcall = build_function_call (BuiltinReturnAddress, params);
return_val_rtx = expand_expr (fcall, NULL_RTX, Pmode, 0);
#if 0
/* I would like to do this here, but doesn't seem to work. */
emit_move_insn (return_val_rtx, inner_throw_label);
/* So, for now, just pass throw label to stack unwinder. */
#endif
......@@ -1242,6 +1248,48 @@ 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
eh_outer_context (addr)
rtx addr;
{
#if defined (ARM_FRAME_RTX) /* was __arm */
/* On the ARM, '__builtin_return_address', must have 4
subtracted from it. */
emit_insn (gen_add2_insn (addr, GEN_INT (-4)));
/* If we are generating code for an ARM2/ARM3 machine or for an ARM6
in 26 bit mode, the condition codes must be masked out of the
return value, or else they will confuse BuiltinReturnAddress.
This does not apply to ARM6 and later processors when running in
32 bit mode. */
if (!TARGET_6)
emit_insn (gen_rtx (SET, Pmode,
addr,
gen_rtx (AND, Pmode,
addr, GEN_INT (0x03fffffc))));
#else
#if ! defined (SPARC_STACK_ALIGN) /* was sparc */
#if defined (TARGET_SNAKE)
/* On HPPA, the low order two bits hold the priviledge level, so we
must get rid of them. */
emit_insn (gen_rtx (SET, Pmode,
addr,
gen_rtx (AND, Pmode,
addr, GEN_INT (0xfffffffc))));
#endif
/* On the SPARC, __builtin_return_address is already -8 or -12, no
need to subtract any more from it. */
addr = plus_constant (addr, -1);
#endif
#endif
return addr;
}
/* is called from expand_exception_blocks () to generate the code in a function
to "throw" if anything in the function needs to perform a throw.
......@@ -1320,8 +1368,9 @@ expand_builtin_throw ()
emit_label (gotta_rethrow_it);
/* call to __builtin_return_address () */
#if defined(ARM_FRAME_RTX) /* was __arm */
/* This replaces a 'call' to __builtin_return_address */
#if defined (ARM_FRAME_RTX) /* was __arm */
/* This should be moved into arm.h:RETURN_ADDR_RTX */
/* This replaces a 'call' to __builtin_return_address */
return_val_rtx = gen_reg_rtx (Pmode);
emit_move_insn (return_val_rtx, gen_rtx (MEM, Pmode, plus_constant (hard_frame_pointer_rtx, -4)));
#else
......@@ -1336,28 +1385,10 @@ expand_builtin_throw ()
emit_jump_insn (gen_beq (gotta_call_terminate));
#if defined(ARM_FRAME_RTX) /* was __arm */
/* On the ARM, '__builtin_return_address', must have 4
subtracted from it. */
emit_insn (gen_add2_insn (return_val_rtx, GEN_INT (-4)));
return_val_rtx = eh_outer_context (return_val_rtx);
/* If we are generating code for an ARM2/ARM3 machine or for an ARM6 in 26 bit
mode, the condition codes must be masked out of the return value, or else
they will confuse BuiltinReturnAddress. This does not apply to ARM6 and
later processors when running in 32 bit mode. */
if (!TARGET_6)
emit_insn (gen_rtx (SET, Pmode, return_val_rtx, gen_rtx (AND, Pmode, return_val_rtx, GEN_INT (0x03fffffc))));
#else
#if !defined(SPARC_STACK_ALIGN) /* was sparc */
/* On the SPARC, __builtin_return_address is already -8, no need to
subtract any more from it. */
return_val_rtx = plus_constant (return_val_rtx, -1);
#endif
#endif
/* yes it did */
t = build_modify_expr (saved_pc, NOP_EXPR, make_tree (ptr_type_node, return_val_rtx));
expand_expr (t, const0_rtx, VOIDmode, 0);
/* Yes it did. */
emit_move_insn (DECL_RTL (saved_pc), return_val_rtx);
do_unwind (gen_rtx (LABEL_REF, Pmode, top_of_loop));
emit_jump (top_of_loop);
......@@ -1700,6 +1731,9 @@ expand_throw (exp)
}
}
if (cleanup == empty_fndecl)
assemble_external (empty_fndecl);
e = build_modify_expr (saved_throw_type, NOP_EXPR, throw_type);
expand_expr (e, const0_rtx, VOIDmode, 0);
......@@ -1823,11 +1857,9 @@ end_eh_unwinder (end)
ret_val = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
0, hard_frame_pointer_rtx);
return_val_rtx = copy_to_reg (ret_val);
#ifdef RETURN_ADDR_OFFSET
return_val_rtx = plus_constant (return_val_rtx, RETURN_ADDR_OFFSET-1);
#else
return_val_rtx = plus_constant (return_val_rtx, -1);
#endif
return_val_rtx = eh_outer_context (return_val_rtx);
emit_move_insn (DECL_RTL (saved_pc), return_val_rtx);
#ifdef JUMP_TO_THROW
......
......@@ -1217,24 +1217,25 @@ The below points out some things that work in g++'s exception handling.
All completely constructed temps and local variables are cleaned up in
all unwinded scopes. Completely constructed parts of partially
constructed objects are cleaned up. This includes partially built
arrays. Exception specifications are now handled.
arrays. Exception specifications are now handled. Thrown objects are
now cleaned up all the time.
The below points out some flaws in g++'s exception handling, as it now
stands.
Only exact type matching or reference matching of throw types works when
-fno-rtti is used. Only works on a SPARC (like Suns), i386, arm and
rs6000 machines. Partial support is in for all other machines, but a
stack unwinder called __unwind_function has to be written, and added to
libgcc2 for them. See below for details on __unwind_function. Don't
expect exception handling to work right if you optimize, in fact the
compiler will probably core dump. RTL_EXPRs for EH cond variables for
&& and || exprs should probably be wrapped in UNSAVE_EXPRs, and
RTL_EXPRs tweaked so that they can be unsaved, and the UNSAVE_EXPR code
should be in the backend, or alternatively, UNSAVE_EXPR should be ripped
out and exactly one finalization allowed to be expanded by the backend.
I talked with kenner about this, and we have to allow multiple
expansions.
-fno-rtti is used. Only works on a SPARC (like Suns), i386, arm,
rs6000, Alpha and mips machines. Partial support is in for all other
machines, but a stack unwinder called __unwind_function has to be
written, and added to libgcc2 for them. See below for details on
__unwind_function. Don't expect exception handling to work right if you
optimize, in fact the compiler will probably core dump. RTL_EXPRs for
EH cond variables for && and || exprs should probably be wrapped in
UNSAVE_EXPRs, and RTL_EXPRs tweaked so that they can be unsaved, and the
UNSAVE_EXPR code should be in the backend, or alternatively, UNSAVE_EXPR
should be ripped out and exactly one finalization allowed to be expanded
by the backend. I talked with kenner about this, and we have to allow
multiple expansions.
We only do pointer conversions on exception matching a la 15.3 p2 case
3: `A handler with type T, const T, T&, or const T& is a match for a
......@@ -1266,12 +1267,13 @@ build_exception_variant should sort the incoming list, so that it
implements set compares, not exact list equality. Type smashing should
smash exception specifications using set union.
Thrown objects are usually allocated on the heap, in the usual way, but
they are never deleted. They should be deleted by the catch clauses.
If one runs out of heap space, throwing an object will probably never
work. This could be relaxed some by passing an __in_chrg parameter to
track who has control over the exception object. Thrown objects are not
allocated on the heap when they are pointer to object types.
Thrown objects are usually allocated on the heap, in the usual way. If
one runs out of heap space, throwing an object will probably never work.
This could be relaxed some by passing an __in_chrg parameter to track
who has control over the exception object. Thrown objects are not
allocated on the heap when they are pointer to object types. We should
extend it so that all small (<4*sizeof(void*)) objects are stored
directly, instead of allocated on the heap.
When the backend returns a value, it can create new exception regions
that need protecting. The new region should rethrow the object in
......
......@@ -3018,9 +3018,8 @@ do_identifier (token)
if (IDENTIFIER_CLASS_VALUE (token) == id)
{
/* Check access. */
enum access_type access
= compute_access (TYPE_BINFO (current_class_type), id);
if (access == access_private)
tree access = compute_access (TYPE_BINFO (current_class_type), id);
if (access == access_private_node)
cp_error ("enum `%D' is private", id);
/* protected is OK, since it's an enum of `this'. */
}
......@@ -3279,13 +3278,13 @@ real_yylex ()
switch (ptr->rid)
{
case RID_PUBLIC:
yylval.itype = access_public;
yylval.ttype = access_public_node;
break;
case RID_PRIVATE:
yylval.itype = access_private;
yylval.ttype = access_private_node;
break;
case RID_PROTECTED:
yylval.itype = access_protected;
yylval.ttype = access_protected_node;
break;
default:
my_friendly_abort (63);
......@@ -4394,6 +4393,13 @@ done:
return value;
}
int
is_rid (t)
tree t;
{
return !!is_reserved_word (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t));
}
typedef enum
{
d_kind, t_kind, s_kind, r_kind, e_kind, c_kind,
......
......@@ -1582,8 +1582,7 @@ hack_identifier (value, name, yychar)
if (DECL_LANG_SPECIFIC (value)
&& DECL_CLASS_CONTEXT (value) != current_class_type)
{
tree path;
enum access_type access;
tree path, access;
register tree context
= (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value))
? DECL_CLASS_CONTEXT (value)
......@@ -1593,7 +1592,7 @@ hack_identifier (value, name, yychar)
if (path)
{
access = compute_access (path, value);
if (access != access_public)
if (access != access_public_node)
{
if (TREE_CODE (value) == VAR_DECL)
error ("static member `%s' is %s",
......@@ -2101,7 +2100,7 @@ do_build_copy_constructor (fndecl)
(build_reference_type (basetype), parm,
CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
p = convert_from_reference (p);
current_base_init_list = tree_cons (TYPE_NESTED_NAME (basetype),
current_base_init_list = tree_cons (basetype,
p, current_base_init_list);
}
......@@ -2116,7 +2115,7 @@ do_build_copy_constructor (fndecl)
(build_reference_type (basetype), parm,
CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
p = convert_from_reference (p);
current_base_init_list = tree_cons (TYPE_NESTED_NAME (basetype),
current_base_init_list = tree_cons (basetype,
p, current_base_init_list);
}
for (; fields; fields = TREE_CHAIN (fields))
......@@ -2192,8 +2191,7 @@ do_build_assign_ref (fndecl)
(build_reference_type (basetype), parm,
CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
p = convert_from_reference (p);
p = build_member_call (TYPE_NESTED_NAME (basetype),
ansi_opname [MODIFY_EXPR],
p = build_member_call (basetype, ansi_opname [MODIFY_EXPR],
build_tree_list (NULL_TREE, p));
expand_expr_stmt (p);
}
......
......@@ -140,7 +140,7 @@ empty_parms ()
/* the reserved words... C++ extensions */
%token <ttype> AGGR
%token <itype> VISSPEC
%token <ttype> VISSPEC
%token DELETE NEW OVERLOAD THIS OPERATOR CXX_TRUE CXX_FALSE
%token NAMESPACE TYPENAME_KEYWORD USING
%token LEFT_RIGHT TEMPLATE
......@@ -236,7 +236,7 @@ empty_parms ()
%type <ttype> named_complex_class_head_sans_basetype
%type <ttype> unnamed_class_head
%type <ttype> class_head base_class_list
%type <itype> base_class_access_list
%type <ttype> base_class_access_list
%type <ttype> base_class maybe_base_class_list base_class.1
%type <ttype> exception_specification_opt ansi_raise_identifier ansi_raise_identifiers
%type <ttype> operator_name
......@@ -779,13 +779,13 @@ member_init: '(' nonnull_exprlist ')'
expand_member_init (C_C_D, NULL_TREE, void_type_node);
}
| notype_identifier '(' nonnull_exprlist ')'
{ expand_member_init (C_C_D, $<ttype>$, $3); }
{ expand_member_init (C_C_D, $1, $3); }
| notype_identifier LEFT_RIGHT
{ expand_member_init (C_C_D, $<ttype>$, void_type_node); }
{ expand_member_init (C_C_D, $1, void_type_node); }
| complete_type_name '(' nonnull_exprlist ')'
{ expand_member_init (C_C_D, $<ttype>$, $3); }
{ expand_member_init (C_C_D, $1, $3); }
| complete_type_name LEFT_RIGHT
{ expand_member_init (C_C_D, $<ttype>$, void_type_node); }
{ expand_member_init (C_C_D, $1, void_type_node); }
/* GNU extension */
| notype_qualified_id '(' nonnull_exprlist ')'
{
......@@ -1589,7 +1589,7 @@ primary:
| object overqualified_id '(' nonnull_exprlist ')'
{
got_object = NULL_TREE;
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
if (IS_SIGNATURE (OP0 ($2)))
{
warning ("signature name in scope resolution ignored");
$$ = build_method_call ($$, OP1 ($2), $4, NULL_TREE,
......@@ -1601,7 +1601,7 @@ primary:
| object overqualified_id LEFT_RIGHT
{
got_object = NULL_TREE;
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
if (IS_SIGNATURE (OP0 ($2)))
{
warning ("signature name in scope resolution ignored");
$$ = build_method_call ($$, OP1 ($2), NULL_TREE, NULL_TREE,
......@@ -2349,9 +2349,8 @@ base_class_list:
base_class:
base_class.1
{
tree type;
type = IDENTIFIER_TYPE_VALUE ($$);
if (! is_aggr_typedef ($$, 1))
tree type = $1;
if (! is_aggr_type (type, 1))
$$ = NULL_TREE;
else if (current_aggr == signature_type_node
&& (! type) && (! IS_SIGNATURE (type)))
......@@ -2363,7 +2362,7 @@ base_class:
{
sorry ("signature inheritance, base type `%s' ignored",
IDENTIFIER_POINTER ($$));
$$ = build_tree_list ((tree)access_public, $$);
$$ = build_tree_list (access_public_node, $$);
}
else if (type && IS_SIGNATURE (type))
{
......@@ -2371,15 +2370,14 @@ base_class:
$$ = NULL_TREE;
}
else
$$ = build_tree_list ((tree)access_default, $$);
$$ = build_tree_list (access_default_node, $$);
}
| base_class_access_list see_typename base_class.1
{
tree type;
type = IDENTIFIER_TYPE_VALUE ($3);
tree type = $3;
if (current_aggr == signature_type_node)
error ("access and source specifiers not allowed in signature");
if (! is_aggr_typedef ($3, 1))
if (! IS_AGGR_TYPE (type))
$$ = NULL_TREE;
else if (current_aggr == signature_type_node
&& (! type) && (! IS_SIGNATURE (type)))
......@@ -2391,7 +2389,7 @@ base_class:
{
sorry ("signature inheritance, base type `%s' ignored",
IDENTIFIER_POINTER ($$));
$$ = build_tree_list ((tree)access_public, $3);
$$ = build_tree_list (access_public_node, $3);
}
else if (type && IS_SIGNATURE (type))
{
......@@ -2399,7 +2397,7 @@ base_class:
$$ = NULL_TREE;
}
else
$$ = build_tree_list ((tree) $$, $3);
$$ = build_tree_list ($$, $3);
}
;
......@@ -2412,8 +2410,7 @@ base_class.1:
if (IS_AGGR_TYPE (TREE_TYPE ($3)))
{
sorry ("`sigof' as base signature specifier");
/* need to return some dummy signature identifier */
$$ = $3;
$$ = TREE_TYPE ($3);
}
else
{
......@@ -2434,8 +2431,7 @@ base_class.1:
if (IS_AGGR_TYPE (groktypename ($3)))
{
sorry ("`sigof' as base signature specifier");
/* need to return some dummy signature identifier */
$$ = $3;
$$ = groktypename ($3);
}
else
{
......@@ -2456,40 +2452,40 @@ base_class_access_list:
| SCSPEC see_typename
{ if ($<ttype>$ != ridpointers[(int)RID_VIRTUAL])
sorry ("non-virtual access");
$$ = access_default_virtual; }
$$ = access_default_virtual_node; }
| base_class_access_list VISSPEC see_typename
{ int err = 0;
if ($2 == access_protected)
if ($2 == access_protected_node)
{
warning ("`protected' access not implemented");
$2 = access_public;
$2 = access_public_node;
err++;
}
else if ($2 == access_public)
else if ($2 == access_public_node)
{
if ($1 == access_private)
if ($1 == access_private_node)
{
mixed:
error ("base class cannot be public and private");
}
else if ($1 == access_default_virtual)
$$ = access_public_virtual;
else if ($1 == access_default_virtual_node)
$$ = access_public_virtual_node;
}
else /* $2 == access_private */
else /* $2 == access_private_node */
{
if ($1 == access_public)
if ($1 == access_public_node)
goto mixed;
else if ($1 == access_default_virtual)
$$ = access_private_virtual;
else if ($1 == access_default_virtual_node)
$$ = access_private_virtual_node;
}
}
| base_class_access_list SCSPEC see_typename
{ if ($2 != ridpointers[(int)RID_VIRTUAL])
sorry ("non-virtual access");
if ($$ == access_public)
$$ = access_public_virtual;
else if ($$ == access_private)
$$ = access_private_virtual; }
if ($$ == access_public_node)
$$ = access_public_virtual_node;
else if ($$ == access_private_node)
$$ = access_private_virtual_node; }
;
left_curly: '{'
......@@ -2564,18 +2560,18 @@ opt.component_decl_list:
| component_decl_list
{
if (current_aggr == signature_type_node)
$$ = build_tree_list ((tree) access_public, $$);
$$ = build_tree_list (access_public_node, $$);
else
$$ = build_tree_list ((tree) access_default, $$);
$$ = build_tree_list (access_default_node, $$);
}
| opt.component_decl_list VISSPEC ':' component_decl_list
{
tree visspec = (tree) $2;
tree visspec = $2;
if (current_aggr == signature_type_node)
{
error ("access specifier not allowed in signature");
visspec = (tree) access_public;
visspec = access_public_node;
}
$$ = chainon ($$, build_tree_list (visspec, $4));
}
......@@ -2861,23 +2857,20 @@ after_type_declarator:
qualified_type_name:
type_name %prec EMPTY
{
$$ = TREE_TYPE ($1);
/* Remember that this name has been used in the class
definition, as per [class.scope0] */
if (current_class_type
&& TYPE_BEING_DEFINED (current_class_type)
&& ! IDENTIFIER_CLASS_VALUE ($$))
{
tree t = lookup_name ($$, -2);
if (t)
pushdecl_class_level (t);
}
&& ! IDENTIFIER_CLASS_VALUE ($1))
pushdecl_class_level (lookup_name ($1, -2));
}
| nested_type
;
nested_type:
nested_name_specifier type_name %prec EMPTY
{ $$ = $2; }
{ $$ = TREE_TYPE ($2); }
;
direct_after_type_declarator:
......@@ -2941,9 +2934,9 @@ complex_direct_notype_declarator:
| direct_notype_declarator '[' ']'
{ $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
| notype_qualified_id
{ if (TREE_TYPE (OP0 ($$)) != current_class_type)
{ if (OP0 ($$) != current_class_type)
{
push_nested_class (TREE_TYPE (OP0 ($$)), 3);
push_nested_class (OP0 ($$), 3);
TREE_COMPLEXITY ($$) = current_class_depth;
}
}
......@@ -2991,11 +2984,11 @@ nested_name_specifier:
inline here?!? (jason) */
nested_name_specifier_1:
TYPENAME SCOPE
{ got_scope = TREE_TYPE ($$); }
{ got_scope = $$ = TREE_TYPE ($1); }
| NSNAME SCOPE
{ got_scope = $$; }
{ got_scope = $$ = $1; }
| template_type SCOPE
{ got_scope = TREE_TYPE ($$); }
{ got_scope = $$ = TREE_TYPE ($1); }
/* These break 'const i;'
| IDENTIFIER SCOPE
{
......
......@@ -127,13 +127,6 @@ process_template_parm (list, next)
decl = build_decl (TYPE_DECL, TREE_VALUE (parm), t);
TYPE_MAIN_DECL (t) = decl;
parm = decl;
if (defval)
{
if (IDENTIFIER_HAS_TYPE_VALUE (defval))
defval = IDENTIFIER_TYPE_VALUE (defval);
else
defval = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (defval));
}
}
SET_DECL_ARTIFICIAL (decl);
pushdecl (decl);
......
......@@ -794,23 +794,23 @@ current_scope ()
This will be static when lookup_fnfield comes into this file.
access_public means that the field can be accessed by the current lexical
access_public_node means that the field can be accessed by the current lexical
scope.
access_protected means that the field cannot be accessed by the current
access_protected_node means that the field cannot be accessed by the current
lexical scope because it is protected.
access_private means that the field cannot be accessed by the current
access_private_node means that the field cannot be accessed by the current
lexical scope because it is private. */
#if 0
#define PUBLIC_RETURN return (DECL_PUBLIC (field) = 1), access_public
#define PROTECTED_RETURN return (DECL_PROTECTED (field) = 1), access_protected
#define PRIVATE_RETURN return (DECL_PRIVATE (field) = 1), access_private
#define PUBLIC_RETURN return (DECL_PUBLIC (field) = 1), access_public_node
#define PROTECTED_RETURN return (DECL_PROTECTED (field) = 1), access_protected_node
#define PRIVATE_RETURN return (DECL_PRIVATE (field) = 1), access_private_node
#else
#define PUBLIC_RETURN return access_public
#define PROTECTED_RETURN return access_protected
#define PRIVATE_RETURN return access_private
#define PUBLIC_RETURN return access_public_node
#define PROTECTED_RETURN return access_protected_node
#define PRIVATE_RETURN return access_private_node
#endif
#if 0
......@@ -818,11 +818,11 @@ current_scope ()
static tree previous_scope = NULL_TREE;
#endif
enum access_type
tree
compute_access (basetype_path, field)
tree basetype_path, field;
{
enum access_type access;
tree access;
tree types;
tree context;
int protected_ok, via_protected;
......@@ -836,11 +836,11 @@ compute_access (basetype_path, field)
|| (TREE_CODE (field) != FUNCTION_DECL && TREE_STATIC (field)));
if (! flag_access_control)
return access_public;
return access_public_node;
/* The field lives in the current class. */
if (BINFO_TYPE (basetype_path) == current_class_type)
return access_public;
return access_public_node;
#if 0
/* Disabled until pushing function scope clears these out. If ever. */
......@@ -848,17 +848,17 @@ compute_access (basetype_path, field)
if (current_scope () == previous_scope)
{
if (DECL_PUBLIC (field))
return access_public;
return access_public_node;
if (DECL_PROTECTED (field))
return access_protected;
return access_protected_node;
if (DECL_PRIVATE (field))
return access_private;
return access_private_node;
}
#endif
/* We don't currently support access control on nested types. */
if (TREE_CODE (field) == TYPE_DECL)
return access_public;
return access_public_node;
previous_scope = current_scope ();
......@@ -912,7 +912,7 @@ compute_access (basetype_path, field)
basetype_path = reverse_path (basetype_path);
types = basetype_path;
via_protected = 0;
access = access_default;
access = access_default_node;
protected_ok = static_mem && current_class_type
&& ACCESSIBLY_DERIVED_FROM_P (BINFO_TYPE (types), current_class_type);
......@@ -934,7 +934,7 @@ compute_access (basetype_path, field)
member = purpose_member (type, DECL_ACCESS (field));
if (member)
{
access = (enum access_type) TREE_VALUE (member);
access = TREE_VALUE (member);
break;
}
......@@ -948,7 +948,7 @@ compute_access (basetype_path, field)
via_protected = 1;
else if (! TREE_VIA_PUBLIC (types) && ! private_ok)
{
access = access_private;
access = access_private_node;
break;
}
}
......@@ -959,30 +959,30 @@ compute_access (basetype_path, field)
/* No special visibilities apply. Use normal rules. */
if (access == access_default)
if (access == access_default_node)
{
if (is_friend (context, previous_scope))
access = access_public;
access = access_public_node;
else if (TREE_PRIVATE (field))
access = access_private;
access = access_private_node;
else if (TREE_PROTECTED (field))
access = access_protected;
access = access_protected_node;
else
access = access_public;
access = access_public_node;
}
if (access == access_public && via_protected)
access = access_protected;
if (access == access_public_node && via_protected)
access = access_protected_node;
if (access == access_protected && protected_ok)
access = access_public;
if (access == access_protected_node && protected_ok)
access = access_public_node;
#if 0
if (access == access_public)
if (access == access_public_node)
DECL_PUBLIC (field) = 1;
else if (access == access_protected)
else if (access == access_protected_node)
DECL_PROTECTED (field) = 1;
else if (access == access_private)
else if (access == access_private_node)
DECL_PRIVATE (field) = 1;
else my_friendly_abort (96);
#endif
......@@ -1072,9 +1072,9 @@ lookup_field (xbasetype, name, protect, want_type)
int head = 0, tail = 0;
tree rval, rval_binfo = NULL_TREE, rval_binfo_h;
tree type, basetype_chain, basetype_path;
enum access_type this_v = access_default;
tree this_v = access_default_node;
tree entry, binfo, binfo_h;
enum access_type own_access = access_default;
tree own_access = access_default_node;
int vbase_name_p = VBASE_NAME_P (name);
/* rval_binfo is the binfo associated with the found member, note,
......@@ -1179,16 +1179,16 @@ lookup_field (xbasetype, name, protect, want_type)
this_v = compute_access (basetype_path, rval);
if (TREE_CODE (rval) == CONST_DECL)
{
if (this_v == access_private)
if (this_v == access_private_node)
errstr = "enum `%D' is a private value of class `%T'";
else if (this_v == access_protected)
else if (this_v == access_protected_node)
errstr = "enum `%D' is a protected value of class `%T'";
}
else
{
if (this_v == access_private)
if (this_v == access_private_node)
errstr = "member `%D' is a private member of class `%T'";
else if (this_v == access_protected)
else if (this_v == access_protected_node)
errstr = "member `%D' is a protected member of class `%T'";
}
}
......@@ -1370,14 +1370,14 @@ lookup_field (xbasetype, name, protect, want_type)
/* If is possible for one of the derived types on the path to
have defined special access for this field. Look for such
declarations and report an error if a conflict is found. */
enum access_type new_v;
tree new_v;
if (this_v != access_default)
if (this_v != access_default_node)
new_v = compute_access (TREE_VALUE (TREE_CHAIN (*tp)), rval);
if (this_v != access_default && new_v != this_v)
if (this_v != access_default_node && new_v != this_v)
{
errstr = "conflicting access to member `%D'";
this_v = access_default;
this_v = access_default_node;
}
own_access = new_v;
CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));
......@@ -1397,15 +1397,15 @@ lookup_field (xbasetype, name, protect, want_type)
if (errstr == 0)
{
if (own_access == access_private)
if (own_access == access_private_node)
errstr = "member `%D' declared private";
else if (own_access == access_protected)
else if (own_access == access_protected_node)
errstr = "member `%D' declared protected";
else if (this_v == access_private)
else if (this_v == access_private_node)
errstr = TREE_PRIVATE (rval)
? "member `%D' is private"
: "member `%D' is from private base class";
else if (this_v == access_protected)
else if (this_v == access_protected_node)
errstr = TREE_PROTECTED (rval)
? "member `%D' is protected"
: "member `%D' is from protected base class";
......@@ -3334,10 +3334,14 @@ dfs_compress_decls (binfo)
lattice. Where ambiguities result, we mark them
with `error_mark_node' so that if they are encountered
without explicit qualification, we can emit an error
message. */
message.
ONLY_TYPES is set when defining TYPE so that inherited types are visible
in the derived class. */
void
push_class_decls (type)
push_class_decls (type, only_types)
tree type;
int only_types;
{
tree id;
struct obstack *ambient_obstack = current_obstack;
......@@ -3392,7 +3396,12 @@ push_class_decls (type)
/* Install the original class value in order to make
pushdecl_class_level work correctly. */
IDENTIFIER_CLASS_VALUE (id) = TREE_VALUE (closed_envelopes);
if (TREE_CODE (new) == TREE_LIST)
if (only_types)
{
if (TREE_CODE (new) == TYPE_DECL)
set_identifier_type_value (id, TREE_TYPE (new));
}
else if (TREE_CODE (new) == TREE_LIST)
push_class_level_binding (id, new);
else
pushdecl_class_level (new);
......
......@@ -530,7 +530,7 @@ build_signature_table_constructor (sig_ty, rhs)
if (rhs_method == NULL_TREE
|| (compute_access (basetypes, rhs_method)
!= access_public))
!= access_public_node))
{
error ("class `%s' does not contain a method conforming to `%s'",
TYPE_NAME_STRING (rhstype),
......
......@@ -820,8 +820,8 @@ layout_basetypes (rec, binfos)
goto got_it;
}
sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (basetype));
decl = build_lang_decl (FIELD_DECL, get_identifier (name),
build_pointer_type (basetype));
decl = build_lang_field_decl (FIELD_DECL, get_identifier (name),
build_pointer_type (basetype));
/* If you change any of the below, take a look at all the
other VFIELD_BASEs and VTABLE_BASEs in the code, and change
them too. */
......@@ -1137,7 +1137,8 @@ get_decl_list (value)
if (TREE_CODE (value) == IDENTIFIER_NODE)
list = get_identifier_list (value);
else if (TREE_CODE (value) == RECORD_TYPE
&& TYPE_LANG_SPECIFIC (value))
&& TYPE_LANG_SPECIFIC (value)
&& value == TYPE_MAIN_VARIANT (value))
list = CLASSTYPE_AS_LIST (value);
if (list != NULL_TREE)
......
......@@ -1532,15 +1532,14 @@ build_object_ref (datum, basetype, field)
basetype, field, dtype);
return error_mark_node;
}
else if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (basetype)))
else if (IS_SIGNATURE (basetype))
{
warning ("signature name in scope resolution ignored");
return build_component_ref (datum, field, NULL_TREE, 1);
}
else if (is_aggr_typedef (basetype, 1))
else if (is_aggr_type (basetype, 1))
{
tree real_basetype = IDENTIFIER_TYPE_VALUE (basetype);
tree binfo = binfo_or_else (real_basetype, TREE_TYPE (datum));
tree binfo = binfo_or_else (basetype, TREE_TYPE (datum));
if (binfo)
return build_component_ref (build_scoped_ref (datum, basetype),
field, binfo, 1);
......@@ -1590,15 +1589,14 @@ build_component_ref_1 (datum, field, protect)
if (datum == C_C_D)
{
enum access_type access
= compute_access (TYPE_BINFO (current_class_type), field);
tree access = compute_access (TYPE_BINFO (current_class_type), field);
if (access == access_private)
if (access == access_private_node)
{
cp_error ("field `%D' is private", field);
return error_mark_node;
}
else if (access == access_protected)
else if (access == access_protected_node)
{
cp_error ("field `%D' is protected", field);
return error_mark_node;
......@@ -1748,14 +1746,13 @@ build_component_ref (datum, component, basetype_path, protect)
if (TREE_CHAIN (fndecls) == NULL_TREE
&& DECL_CHAIN (TREE_VALUE (fndecls)) == NULL_TREE)
{
enum access_type access;
tree fndecl;
tree access, fndecl;
/* Unique, so use this one now. */
basetype = TREE_PURPOSE (fndecls);
fndecl = TREE_VALUE (fndecls);
access = compute_access (TREE_PURPOSE (fndecls), fndecl);
if (access == access_public)
if (access == access_public_node)
{
if (DECL_VINDEX (fndecl)
&& ! resolves_to_fixed_type_p (datum, 0))
......@@ -1769,7 +1766,7 @@ build_component_ref (datum, component, basetype_path, protect)
mark_used (fndecl);
return fndecl;
}
if (access == access_protected)
if (access == access_protected_node)
cp_error ("member function `%D' is protected", fndecl);
else
cp_error ("member function `%D' is private", fndecl);
......@@ -3727,7 +3724,7 @@ pointer_int_sum (resultcode, ptrop, intop)
}
else if (TREE_CODE (TREE_TYPE (result_type)) == OFFSET_TYPE)
{
if (pedantic)
if (pedantic || warn_pointer_arith)
pedwarn ("ANSI C++ forbids using pointer to a member in arithmetic");
size_exp = integer_one_node;
}
......@@ -3793,7 +3790,7 @@ pointer_diff (op0, op1)
tree restype = ptrdiff_type_node;
tree target_type = TREE_TYPE (TREE_TYPE (op0));
if (pedantic)
if (pedantic || warn_pointer_arith)
{
if (TREE_CODE (target_type) == VOID_TYPE)
pedwarn ("ANSI C++ forbids using pointer of type `void *' in subtraction");
......@@ -6169,9 +6166,10 @@ build_modify_expr (lhs, modifycode, rhs)
/* Can't initialize directly from a TARGET_EXPR, since that would
cause the lhs to be constructed twice, and possibly result in
accidental self-initialization. So we force the TARGET_EXPR to be
expanded. expand_expr should really do this by itself. */
expanded without a target. */
if (TREE_CODE (newrhs) == TARGET_EXPR)
newrhs = expand_target_expr (newrhs);
newrhs = build (COMPOUND_EXPR, TREE_TYPE (newrhs), newrhs,
TREE_VALUE (newrhs));
}
if (TREE_CODE (newrhs) == ERROR_MARK)
......
......@@ -1199,7 +1199,7 @@ process_init_constructor (type, init, elts)
/* Given a structure or union value DATUM, construct and return
the structure or union component which results from narrowing
that value by the types specified in TYPES. For example, given the
that value by the type specified in BASETYPE. For example, given the
hierarchy
class L { int ii; };
......@@ -1213,23 +1213,16 @@ process_init_constructor (type, init, elts)
then the expression
x::C::A::L::ii refers to the ii member of the L part of
x.A::ii refers to the ii member of the L part of
of A part of the C object named by X. In this case,
DATUM would be x, and TYPES would be a SCOPE_REF consisting of
SCOPE_REF
SCOPE_REF
C A
L
The last entry in the SCOPE_REF is always an IDENTIFIER_NODE.
DATUM would be x, and BASETYPE would be A.
*/
tree
build_scoped_ref (datum, types)
build_scoped_ref (datum, basetype)
tree datum;
tree types;
tree basetype;
{
tree ref;
tree type = TREE_TYPE (datum);
......@@ -1242,62 +1235,17 @@ build_scoped_ref (datum, types)
type = TYPE_MAIN_VARIANT (type);
if (TREE_CODE (types) == SCOPE_REF)
{
/* We have some work to do. */
struct type_chain
{ tree type; struct type_chain *next; }
*chain = NULL, *head = NULL, scratch;
ref = build_unary_op (ADDR_EXPR, datum, 0);
while (TREE_CODE (types) == SCOPE_REF)
{
tree t = TREE_OPERAND (types, 1);
if (is_aggr_typedef (t, 1))
{
head = (struct type_chain *)alloca (sizeof (struct type_chain));
head->type = IDENTIFIER_TYPE_VALUE (t);
head->next = chain;
chain = head;
types = TREE_OPERAND (types, 0);
}
else return error_mark_node;
}
if (! is_aggr_typedef (types, 1))
return error_mark_node;
head = &scratch;
head->type = IDENTIFIER_TYPE_VALUE (types);
head->next = chain;
chain = head;
while (chain)
{
tree binfo = chain->type;
type = TREE_TYPE (TREE_TYPE (ref));
if (binfo != TYPE_BINFO (type))
{
binfo = get_binfo (binfo, type, 1);
if (binfo == error_mark_node)
return error_mark_node;
if (binfo == 0)
return error_not_base_type (chain->type, type);
ref = convert_pointer_to (binfo, ref);
}
chain = chain->next;
}
return build_indirect_ref (ref, "(compiler error in build_scoped_ref)");
}
/* This is an easy conversion. */
if (is_aggr_typedef (types, 1))
if (is_aggr_type (basetype, 1))
{
tree binfo = TYPE_BINFO (IDENTIFIER_TYPE_VALUE (types));
tree binfo = TYPE_BINFO (basetype);
if (binfo != TYPE_BINFO (type))
{
binfo = get_binfo (binfo, type, 1);
if (binfo == error_mark_node)
return error_mark_node;
if (binfo == 0)
return error_not_base_type (IDENTIFIER_TYPE_VALUE (types), type);
return error_not_base_type (basetype, type);
}
switch (TREE_CODE (datum))
......
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