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> Thu Dec 28 11:13:15 1995 Mike Stump <mrs@cygnus.com>
* except.c (expand_builtin_throw): Use RETURN_ADDR_OFFSET instead of * 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> ...@@ -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_H): Depend on $(PARSE_C), for parallel makes.
(PARSE_C): Undo last patch. (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 * Makefile.in (BISONFLAGS): Add --yacc so that output winds up in
y.tab.c. y.tab.c.
......
...@@ -1461,8 +1461,8 @@ resolve_scope_to_name (outer_type, inner_stuff) ...@@ -1461,8 +1461,8 @@ resolve_scope_to_name (outer_type, inner_stuff)
/* Build a method call of the form `EXP->SCOPES::NAME (PARMS)'. /* Build a method call of the form `EXP->SCOPES::NAME (PARMS)'.
This is how virtual function calls are avoided. */ This is how virtual function calls are avoided. */
tree tree
build_scoped_method_call (exp, scopes, name, parms) build_scoped_method_call (exp, basetype, name, parms)
tree exp, scopes, name, parms; tree exp, basetype, name, parms;
{ {
/* Because this syntactic form does not allow /* Because this syntactic form does not allow
a pointer to a base class to be `stolen', a pointer to a base class to be `stolen',
...@@ -1470,23 +1470,20 @@ build_scoped_method_call (exp, scopes, name, parms) ...@@ -1470,23 +1470,20 @@ build_scoped_method_call (exp, scopes, name, parms)
that happens here. that happens here.
@@ But we do have to check access privileges later. */ @@ But we do have to check access privileges later. */
tree basename = resolve_scope_to_name (NULL_TREE, scopes); tree binfo, decl;
tree basetype, binfo, decl;
tree type = TREE_TYPE (exp); tree type = TREE_TYPE (exp);
if (type == error_mark_node if (type == error_mark_node
|| basename == NULL_TREE) || basetype == error_mark_node)
return error_mark_node; return error_mark_node;
basetype = IDENTIFIER_TYPE_VALUE (basename);
if (TREE_CODE (type) == REFERENCE_TYPE) if (TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type); type = TREE_TYPE (type);
/* Destructors can be "called" for simple types; see 5.2.4 and 12.4 Note /* 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 that explicit ~int is caught in the parser; this deals with typedefs
and template parms. */ 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) if (type != basetype)
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')",
...@@ -1498,7 +1495,7 @@ build_scoped_method_call (exp, scopes, name, parms) ...@@ -1498,7 +1495,7 @@ build_scoped_method_call (exp, scopes, name, parms)
return convert (void_type_node, exp); return convert (void_type_node, exp);
} }
if (! is_aggr_typedef (basename, 1)) if (! is_aggr_type (basetype, 1))
return error_mark_node; return error_mark_node;
if (! IS_AGGR_TYPE (type)) if (! IS_AGGR_TYPE (type))
...@@ -1516,7 +1513,7 @@ build_scoped_method_call (exp, scopes, name, parms) ...@@ -1516,7 +1513,7 @@ build_scoped_method_call (exp, scopes, name, parms)
decl = build_indirect_ref (convert_pointer_to (binfo, decl = build_indirect_ref (convert_pointer_to (binfo,
build_unary_op (ADDR_EXPR, exp, 0)), NULL_PTR); build_unary_op (ADDR_EXPR, exp, 0)), NULL_PTR);
else else
decl = build_scoped_ref (exp, scopes); decl = build_scoped_ref (exp, basetype);
/* Call to a destructor. */ /* Call to a destructor. */
if (TREE_CODE (name) == BIT_NOT_EXPR) if (TREE_CODE (name) == BIT_NOT_EXPR)
...@@ -1613,7 +1610,7 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -1613,7 +1610,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
register tree baselink, result, method_name, parmtypes, parm; register tree baselink, result, method_name, parmtypes, parm;
tree last; tree last;
int pass; int pass;
enum access_type access = access_public; tree access = access_public_node;
/* Range of cases for vtable optimization. */ /* Range of cases for vtable optimization. */
enum vtable_needs { not_needed, maybe_needed, unneeded, needed }; enum vtable_needs { not_needed, maybe_needed, unneeded, needed };
...@@ -2422,7 +2419,7 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -2422,7 +2419,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
if (flags & LOOKUP_PROTECT) if (flags & LOOKUP_PROTECT)
access = compute_access (basetype_path, function); access = compute_access (basetype_path, function);
if (access == access_private) if (access == access_private_node)
{ {
if (flags & LOOKUP_COMPLAIN) if (flags & LOOKUP_COMPLAIN)
{ {
...@@ -2433,7 +2430,7 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -2433,7 +2430,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
} }
return error_mark_node; return error_mark_node;
} }
else if (access == access_protected) else if (access == access_protected_node)
{ {
if (flags & LOOKUP_COMPLAIN) if (flags & LOOKUP_COMPLAIN)
{ {
......
...@@ -98,6 +98,15 @@ char *dont_allow_type_definitions; ...@@ -98,6 +98,15 @@ char *dont_allow_type_definitions;
via this node. */ via this node. */
static tree base_layout_decl; 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. */ /* Variables shared between class.c and call.c. */
int n_vtables = 0; int n_vtables = 0;
...@@ -1108,10 +1117,10 @@ static int ...@@ -1108,10 +1117,10 @@ static int
alter_access (t, fdecl, access) alter_access (t, fdecl, access)
tree t; tree t;
tree fdecl; tree fdecl;
enum access_type access; tree access;
{ {
tree elem = purpose_member (t, DECL_ACCESS (fdecl)); 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) if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL)
{ {
...@@ -1123,25 +1132,24 @@ alter_access (t, fdecl, access) ...@@ -1123,25 +1132,24 @@ alter_access (t, fdecl, access)
} }
else if (TREE_PRIVATE (fdecl)) else if (TREE_PRIVATE (fdecl))
{ {
if (access != access_private) if (access != access_private_node)
cp_error_at ("cannot make private `%D' non-private", fdecl); cp_error_at ("cannot make private `%D' non-private", fdecl);
goto alter; goto alter;
} }
else if (TREE_PROTECTED (fdecl)) else if (TREE_PROTECTED (fdecl))
{ {
if (access != access_protected) if (access != access_protected_node)
cp_error_at ("cannot make protected `%D' non-protected", fdecl); cp_error_at ("cannot make protected `%D' non-protected", fdecl);
goto alter; goto alter;
} }
/* ARM 11.3: an access declaration may not be used to restrict access /* ARM 11.3: an access declaration may not be used to restrict access
to a member that is accessible in the base class. */ 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); cp_error_at ("cannot reduce access of public member `%D'", fdecl);
else if (elem == NULL_TREE) else if (elem == NULL_TREE)
{ {
alter: alter:
DECL_ACCESS (fdecl) = tree_cons (t, (tree)access, DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
DECL_ACCESS (fdecl));
return 1; return 1;
} }
return 0; return 0;
...@@ -2957,16 +2965,16 @@ finish_struct_1 (t, warn_anon) ...@@ -2957,16 +2965,16 @@ finish_struct_1 (t, warn_anon)
if (DECL_NAME (x) && TREE_CODE (DECL_NAME (x)) == SCOPE_REF) if (DECL_NAME (x) && TREE_CODE (DECL_NAME (x)) == SCOPE_REF)
{ {
tree fdecl = TREE_OPERAND (DECL_NAME (x), 1); tree fdecl = TREE_OPERAND (DECL_NAME (x), 1);
enum access_type access tree access
= TREE_PRIVATE (x) ? access_private : = TREE_PRIVATE (x) ? access_private_node :
TREE_PROTECTED (x) ? access_protected : access_public; TREE_PROTECTED (x) ? access_protected_node : access_public_node;
if (last_x) if (last_x)
TREE_CHAIN (last_x) = TREE_CHAIN (x); TREE_CHAIN (last_x) = TREE_CHAIN (x);
else else
fields = TREE_CHAIN (x); fields = TREE_CHAIN (x);
access_decls = tree_cons ((tree) access, fdecl, access_decls); access_decls = tree_cons (access, fdecl, access_decls);
continue; continue;
} }
...@@ -3411,7 +3419,7 @@ finish_struct_1 (t, warn_anon) ...@@ -3411,7 +3419,7 @@ finish_struct_1 (t, warn_anon)
tree fdecl = TREE_VALUE (access_decls); tree fdecl = TREE_VALUE (access_decls);
tree flist = NULL_TREE; tree flist = NULL_TREE;
tree name; 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; int i = TREE_VEC_ELT (method_vec, 0) ? 0 : 1;
tree tmp; tree tmp;
...@@ -4053,7 +4061,7 @@ finish_struct (t, list_of_fieldlists, warn_anon) ...@@ -4053,7 +4061,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
tree *tail = &TYPE_METHODS (t); tree *tail = &TYPE_METHODS (t);
tree name = TYPE_NAME (t); tree name = TYPE_NAME (t);
tree x, last_x = NULL_TREE; tree x, last_x = NULL_TREE;
enum access_type access; tree access;
if (TREE_CODE (name) == TYPE_DECL) if (TREE_CODE (name) == TYPE_DECL)
{ {
...@@ -4083,21 +4091,21 @@ finish_struct (t, list_of_fieldlists, warn_anon) ...@@ -4083,21 +4091,21 @@ finish_struct (t, list_of_fieldlists, warn_anon)
if (CLASSTYPE_DECLARED_CLASS (t) == 0) if (CLASSTYPE_DECLARED_CLASS (t) == 0)
{ {
if (list_of_fieldlists if (list_of_fieldlists
&& TREE_PURPOSE (list_of_fieldlists) == (tree)access_default) && TREE_PURPOSE (list_of_fieldlists) == access_default_node)
TREE_PURPOSE (list_of_fieldlists) = (tree)access_public; TREE_PURPOSE (list_of_fieldlists) = access_public_node;
} }
else if (list_of_fieldlists else if (list_of_fieldlists
&& TREE_PURPOSE (list_of_fieldlists) == (tree)access_default) && TREE_PURPOSE (list_of_fieldlists) == access_default_node)
TREE_PURPOSE (list_of_fieldlists) = (tree)access_private; TREE_PURPOSE (list_of_fieldlists) = access_private_node;
while (list_of_fieldlists) 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)) for (x = TREE_VALUE (list_of_fieldlists); x; x = TREE_CHAIN (x))
{ {
TREE_PRIVATE (x) = access == access_private; TREE_PRIVATE (x) = access == access_private_node;
TREE_PROTECTED (x) = access == access_protected; TREE_PROTECTED (x) = access == access_protected_node;
/* Check for inconsistent use of this name in the class body. /* Check for inconsistent use of this name in the class body.
Enums, types and static vars have already been checked. */ Enums, types and static vars have already been checked. */
...@@ -4306,6 +4314,14 @@ init_class_processing () ...@@ -4306,6 +4314,14 @@ init_class_processing ()
current_lang_base = (tree *)xmalloc(current_lang_stacksize * sizeof (tree)); current_lang_base = (tree *)xmalloc(current_lang_stacksize * sizeof (tree));
current_lang_stack = current_lang_base; 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. */ /* Keep these values lying around. */
the_null_vtable_entry = build_vtable_entry (integer_zero_node, integer_zero_node); 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); base_layout_decl = build_lang_field_decl (FIELD_DECL, NULL_TREE, error_mark_node);
...@@ -4400,7 +4416,7 @@ pushclass (type, modify) ...@@ -4400,7 +4416,7 @@ pushclass (type, modify)
else if (type != previous_class_type || current_class_depth > 1) else if (type != previous_class_type || current_class_depth > 1)
{ {
build_mi_matrix (type); build_mi_matrix (type);
push_class_decls (type); push_class_decls (type, !modify);
free_mi_matrix (); free_mi_matrix ();
if (current_class_depth == 1) if (current_class_depth == 1)
previous_class_type = type; previous_class_type = type;
...@@ -4437,6 +4453,12 @@ pushclass (type, modify) ...@@ -4437,6 +4453,12 @@ pushclass (type, modify)
current_function_decl = this_fndecl; 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) if (flag_cadillac)
cadillac_push_class (type); cadillac_push_class (type);
......
...@@ -1727,15 +1727,14 @@ extern int current_function_parms_stored; ...@@ -1727,15 +1727,14 @@ extern int current_function_parms_stored;
can have. These are sensible combinations of {public,private,protected} can have. These are sensible combinations of {public,private,protected}
cross {virtual,non-virtual}. */ cross {virtual,non-virtual}. */
enum access_type { /* in class.c. */
access_default, extern tree access_default_node; /* 0 */
access_public, extern tree access_public_node; /* 1 */
access_protected, extern tree access_protected_node; /* 2 */
access_private, extern tree access_private_node; /* 3 */
access_default_virtual, extern tree access_default_virtual_node; /* 4 */
access_public_virtual, extern tree access_public_virtual_node; /* 5 */
access_private_virtual extern tree access_private_virtual_node; /* 6 */
};
/* in lex.c */ /* in lex.c */
extern tree current_unit_name, current_unit_language; extern tree current_unit_name, current_unit_language;
...@@ -2311,7 +2310,7 @@ extern void push_memoized_context PROTO((tree, int)); ...@@ -2311,7 +2310,7 @@ extern void push_memoized_context PROTO((tree, int));
extern void pop_memoized_context PROTO((int)); extern void pop_memoized_context PROTO((int));
extern tree get_binfo PROTO((tree, tree, int)); extern tree get_binfo PROTO((tree, tree, int));
extern int get_base_distance PROTO((tree, tree, int, tree *)); 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_field PROTO((tree, tree, int, int));
extern tree lookup_nested_field PROTO((tree, int)); extern tree lookup_nested_field PROTO((tree, int));
extern tree lookup_fnfields PROTO((tree, tree, int)); extern tree lookup_fnfields PROTO((tree, tree, int));
...@@ -2333,7 +2332,7 @@ extern void build_mi_virtuals PROTO((int, int)); ...@@ -2333,7 +2332,7 @@ extern void build_mi_virtuals PROTO((int, int));
extern void add_mi_virtuals PROTO((int, tree)); extern void add_mi_virtuals PROTO((int, tree));
extern void report_ambiguous_mi_virtuals PROTO((int, tree)); extern void report_ambiguous_mi_virtuals PROTO((int, tree));
extern void note_debug_info_needed PROTO((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 pop_class_decls PROTO((tree));
extern void unuse_fields PROTO((tree)); extern void unuse_fields PROTO((tree));
extern void unmark_finished_struct PROTO((tree)); extern void unmark_finished_struct PROTO((tree));
......
...@@ -896,8 +896,7 @@ convert_to_aggr (type, expr, msgp, protect) ...@@ -896,8 +896,7 @@ 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; tree method_name, access;
enum access_type 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))
...@@ -907,7 +906,7 @@ convert_to_aggr (type, expr, msgp, protect) ...@@ -907,7 +906,7 @@ convert_to_aggr (type, expr, msgp, protect)
return error_mark_node; return error_mark_node;
} }
access = access_public; access = access_public_node;
can_be_private = 0; can_be_private = 0;
can_be_protected = IDENTIFIER_CLASS_VALUE (name) || name == current_class_name; can_be_protected = IDENTIFIER_CLASS_VALUE (name) || name == current_class_name;
...@@ -987,20 +986,20 @@ convert_to_aggr (type, expr, msgp, protect) ...@@ -987,20 +986,20 @@ convert_to_aggr (type, expr, msgp, protect)
if (protect) if (protect)
{ {
if (TREE_PRIVATE (fndecl)) if (TREE_PRIVATE (fndecl))
access = access_private; access = access_private_node;
else if (TREE_PROTECTED (fndecl)) else if (TREE_PROTECTED (fndecl))
access = access_protected; access = access_protected_node;
else else
access = access_public; access = access_public_node;
} }
else else
access = access_public; access = access_public_node;
if (access == access_private if (access == access_private_node
? (basetype == current_class_type ? (basetype == current_class_type
|| is_friend (basetype, cp->function) || is_friend (basetype, cp->function)
|| purpose_member (basetype, DECL_ACCESS (fndecl))) || purpose_member (basetype, DECL_ACCESS (fndecl)))
: access == access_protected : access == access_protected_node
? (can_be_protected ? (can_be_protected
|| purpose_member (basetype, DECL_ACCESS (fndecl))) || purpose_member (basetype, DECL_ACCESS (fndecl)))
: 1) : 1)
...@@ -1011,7 +1010,7 @@ convert_to_aggr (type, expr, msgp, protect) ...@@ -1011,7 +1010,7 @@ convert_to_aggr (type, expr, msgp, protect)
} }
else else
{ {
if (access == access_private) if (access == access_private_node)
saw_private = 1; saw_private = 1;
else else
saw_protected = 1; saw_protected = 1;
...@@ -1061,7 +1060,7 @@ convert_to_aggr (type, expr, msgp, protect) ...@@ -1061,7 +1060,7 @@ convert_to_aggr (type, expr, msgp, protect)
/* NOTREACHED */ /* NOTREACHED */
found: found:
if (access == access_private) if (access == access_private_node)
if (! can_be_private) if (! can_be_private)
{ {
if (msgp) if (msgp)
...@@ -1070,7 +1069,7 @@ convert_to_aggr (type, expr, msgp, protect) ...@@ -1070,7 +1069,7 @@ convert_to_aggr (type, expr, msgp, protect)
: "conversion to type `%s' is from private base class"; : "conversion to type `%s' is from private base class";
return error_mark_node; return error_mark_node;
} }
if (access == access_protected) if (access == access_protected_node)
if (! can_be_protected) if (! can_be_protected)
{ {
if (msgp) if (msgp)
......
...@@ -176,7 +176,7 @@ int warn_traditional; ...@@ -176,7 +176,7 @@ int warn_traditional;
/* Nonzero means warn about sizeof(function) or addition/subtraction /* Nonzero means warn about sizeof(function) or addition/subtraction
of function pointers. */ of function pointers. */
int warn_pointer_arith; int warn_pointer_arith = 1;
/* Nonzero means warn for non-prototype function decls /* Nonzero means warn for non-prototype function decls
or non-prototyped defs without previous prototype. */ or non-prototyped defs without previous prototype. */
...@@ -2026,7 +2026,9 @@ constructor_name_full (thing) ...@@ -2026,7 +2026,9 @@ constructor_name_full (thing)
{ {
if (TREE_CODE (thing) == UNINSTANTIATED_P_TYPE) if (TREE_CODE (thing) == UNINSTANTIATED_P_TYPE)
return DECL_NAME (UPT_TEMPLATE (thing)); 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)) if (TYPE_WAS_ANONYMOUS (thing) && TYPE_HAS_CONSTRUCTOR (thing))
thing = DECL_NAME (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (thing), 0)); thing = DECL_NAME (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (thing), 0));
......
...@@ -155,7 +155,7 @@ exception_section () ...@@ -155,7 +155,7 @@ exception_section ()
if (flag_pic) if (flag_pic)
data_section (); data_section ();
else else
#if defined(TARGET_POWERPC) /* are we on a __rs6000? */ #if defined (TARGET_POWERPC) /* are we on a __rs6000? */
data_section (); data_section ();
#else #else
readonly_data_section (); readonly_data_section ();
...@@ -1012,6 +1012,10 @@ expand_start_catch_block (declspecs, declarator) ...@@ -1012,6 +1012,10 @@ expand_start_catch_block (declspecs, declarator)
return; 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. */ /* Figure out the type that the initializer is. */
init_type = TREE_TYPE (decl); init_type = TREE_TYPE (decl);
if (TREE_CODE (init_type) != REFERENCE_TYPE if (TREE_CODE (init_type) != REFERENCE_TYPE
...@@ -1167,7 +1171,8 @@ static void ...@@ -1167,7 +1171,8 @@ static void
do_unwind (inner_throw_label) do_unwind (inner_throw_label)
rtx 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 fcall;
tree params; tree params;
rtx return_val_rtx; rtx return_val_rtx;
...@@ -1186,7 +1191,7 @@ do_unwind (inner_throw_label) ...@@ -1186,7 +1191,7 @@ do_unwind (inner_throw_label)
easy_expand_asm ("restore"); easy_expand_asm ("restore");
emit_barrier (); emit_barrier ();
#endif #endif
#if defined(ARM_FRAME_RTX) /* was __arm */ #if defined (ARM_FRAME_RTX) /* was __arm */
if (flag_omit_frame_pointer) if (flag_omit_frame_pointer)
sorry ("this implementation of exception handling requires a frame pointer"); sorry ("this implementation of exception handling requires a frame pointer");
...@@ -1195,7 +1200,7 @@ do_unwind (inner_throw_label) ...@@ -1195,7 +1200,7 @@ do_unwind (inner_throw_label)
emit_move_insn (hard_frame_pointer_rtx, emit_move_insn (hard_frame_pointer_rtx,
gen_rtx (MEM, Pmode, plus_constant (hard_frame_pointer_rtx, -12))); gen_rtx (MEM, Pmode, plus_constant (hard_frame_pointer_rtx, -12)));
#endif #endif
#if defined(TARGET_88000) /* was m88k */ #if defined (TARGET_88000) /* was m88k */
rtx temp_frame = frame_pointer_rtx; rtx temp_frame = frame_pointer_rtx;
temp_frame = memory_address (Pmode, temp_frame); temp_frame = memory_address (Pmode, temp_frame);
...@@ -1218,17 +1223,18 @@ do_unwind (inner_throw_label) ...@@ -1218,17 +1223,18 @@ do_unwind (inner_throw_label)
(HOST_WIDE_INT)m88k_debugger_offset (arg_pointer_rtx, 0)))); (HOST_WIDE_INT)m88k_debugger_offset (arg_pointer_rtx, 0))));
#endif #endif
#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 fcall;
tree params; tree params;
rtx return_val_rtx; 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 () */ /* call to __builtin_return_address () */
params = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE); params = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
fcall = build_function_call (BuiltinReturnAddress, params); fcall = build_function_call (BuiltinReturnAddress, params);
return_val_rtx = expand_expr (fcall, NULL_RTX, Pmode, 0); 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); emit_move_insn (return_val_rtx, inner_throw_label);
/* So, for now, just pass throw label to stack unwinder. */ /* So, for now, just pass throw label to stack unwinder. */
#endif #endif
...@@ -1242,6 +1248,48 @@ do_unwind (inner_throw_label) ...@@ -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 /* 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. to "throw" if anything in the function needs to perform a throw.
...@@ -1320,8 +1368,9 @@ expand_builtin_throw () ...@@ -1320,8 +1368,9 @@ expand_builtin_throw ()
emit_label (gotta_rethrow_it); emit_label (gotta_rethrow_it);
/* call to __builtin_return_address () */ /* call to __builtin_return_address () */
#if defined(ARM_FRAME_RTX) /* was __arm */ #if defined (ARM_FRAME_RTX) /* was __arm */
/* This replaces a 'call' to __builtin_return_address */ /* 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); return_val_rtx = gen_reg_rtx (Pmode);
emit_move_insn (return_val_rtx, gen_rtx (MEM, Pmode, plus_constant (hard_frame_pointer_rtx, -4))); emit_move_insn (return_val_rtx, gen_rtx (MEM, Pmode, plus_constant (hard_frame_pointer_rtx, -4)));
#else #else
...@@ -1336,28 +1385,10 @@ expand_builtin_throw () ...@@ -1336,28 +1385,10 @@ expand_builtin_throw ()
emit_jump_insn (gen_beq (gotta_call_terminate)); emit_jump_insn (gen_beq (gotta_call_terminate));
#if defined(ARM_FRAME_RTX) /* was __arm */ return_val_rtx = eh_outer_context (return_val_rtx);
/* On the ARM, '__builtin_return_address', must have 4
subtracted from it. */
emit_insn (gen_add2_insn (return_val_rtx, 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, 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 */ /* Yes it did. */
t = build_modify_expr (saved_pc, NOP_EXPR, make_tree (ptr_type_node, return_val_rtx)); emit_move_insn (DECL_RTL (saved_pc), return_val_rtx);
expand_expr (t, const0_rtx, VOIDmode, 0);
do_unwind (gen_rtx (LABEL_REF, Pmode, top_of_loop)); do_unwind (gen_rtx (LABEL_REF, Pmode, top_of_loop));
emit_jump (top_of_loop); emit_jump (top_of_loop);
...@@ -1700,6 +1731,9 @@ expand_throw (exp) ...@@ -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); e = build_modify_expr (saved_throw_type, NOP_EXPR, throw_type);
expand_expr (e, const0_rtx, VOIDmode, 0); expand_expr (e, const0_rtx, VOIDmode, 0);
...@@ -1823,11 +1857,9 @@ end_eh_unwinder (end) ...@@ -1823,11 +1857,9 @@ end_eh_unwinder (end)
ret_val = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS, ret_val = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
0, hard_frame_pointer_rtx); 0, hard_frame_pointer_rtx);
return_val_rtx = copy_to_reg (ret_val); return_val_rtx = copy_to_reg (ret_val);
#ifdef RETURN_ADDR_OFFSET
return_val_rtx = plus_constant (return_val_rtx, RETURN_ADDR_OFFSET-1); return_val_rtx = eh_outer_context (return_val_rtx);
#else
return_val_rtx = plus_constant (return_val_rtx, -1);
#endif
emit_move_insn (DECL_RTL (saved_pc), return_val_rtx); emit_move_insn (DECL_RTL (saved_pc), return_val_rtx);
#ifdef JUMP_TO_THROW #ifdef JUMP_TO_THROW
......
...@@ -1217,24 +1217,25 @@ The below points out some things that work in g++'s exception handling. ...@@ -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 completely constructed temps and local variables are cleaned up in
all unwinded scopes. Completely constructed parts of partially all unwinded scopes. Completely constructed parts of partially
constructed objects are cleaned up. This includes partially built 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 The below points out some flaws in g++'s exception handling, as it now
stands. stands.
Only exact type matching or reference matching of throw types works when 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 -fno-rtti is used. Only works on a SPARC (like Suns), i386, arm,
rs6000 machines. Partial support is in for all other machines, but a rs6000, Alpha and mips machines. Partial support is in for all other
stack unwinder called __unwind_function has to be written, and added to machines, but a stack unwinder called __unwind_function has to be
libgcc2 for them. See below for details on __unwind_function. Don't written, and added to libgcc2 for them. See below for details on
expect exception handling to work right if you optimize, in fact the __unwind_function. Don't expect exception handling to work right if you
compiler will probably core dump. RTL_EXPRs for EH cond variables for optimize, in fact the compiler will probably core dump. RTL_EXPRs for
&& and || exprs should probably be wrapped in UNSAVE_EXPRs, and EH cond variables for && and || exprs should probably be wrapped in
RTL_EXPRs tweaked so that they can be unsaved, and the UNSAVE_EXPR code UNSAVE_EXPRs, and RTL_EXPRs tweaked so that they can be unsaved, and the
should be in the backend, or alternatively, UNSAVE_EXPR should be ripped UNSAVE_EXPR code should be in the backend, or alternatively, UNSAVE_EXPR
out and exactly one finalization allowed to be expanded by the backend. should be ripped out and exactly one finalization allowed to be expanded
I talked with kenner about this, and we have to allow multiple by the backend. I talked with kenner about this, and we have to allow
expansions. multiple expansions.
We only do pointer conversions on exception matching a la 15.3 p2 case 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 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 ...@@ -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 implements set compares, not exact list equality. Type smashing should
smash exception specifications using set union. smash exception specifications using set union.
Thrown objects are usually allocated on the heap, in the usual way, but Thrown objects are usually allocated on the heap, in the usual way. If
they are never deleted. They should be deleted by the catch clauses. one runs out of heap space, throwing an object will probably never work.
If one runs out of heap space, throwing an object will probably never This could be relaxed some by passing an __in_chrg parameter to track
work. This could be relaxed some by passing an __in_chrg parameter to who has control over the exception object. Thrown objects are not
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
allocated on the heap when they are pointer to object types. 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 When the backend returns a value, it can create new exception regions
that need protecting. The new region should rethrow the object in that need protecting. The new region should rethrow the object in
......
...@@ -3018,9 +3018,8 @@ do_identifier (token) ...@@ -3018,9 +3018,8 @@ do_identifier (token)
if (IDENTIFIER_CLASS_VALUE (token) == id) if (IDENTIFIER_CLASS_VALUE (token) == id)
{ {
/* Check access. */ /* Check access. */
enum access_type access tree access = compute_access (TYPE_BINFO (current_class_type), id);
= compute_access (TYPE_BINFO (current_class_type), id); if (access == access_private_node)
if (access == access_private)
cp_error ("enum `%D' is private", id); cp_error ("enum `%D' is private", id);
/* protected is OK, since it's an enum of `this'. */ /* protected is OK, since it's an enum of `this'. */
} }
...@@ -3279,13 +3278,13 @@ real_yylex () ...@@ -3279,13 +3278,13 @@ real_yylex ()
switch (ptr->rid) switch (ptr->rid)
{ {
case RID_PUBLIC: case RID_PUBLIC:
yylval.itype = access_public; yylval.ttype = access_public_node;
break; break;
case RID_PRIVATE: case RID_PRIVATE:
yylval.itype = access_private; yylval.ttype = access_private_node;
break; break;
case RID_PROTECTED: case RID_PROTECTED:
yylval.itype = access_protected; yylval.ttype = access_protected_node;
break; break;
default: default:
my_friendly_abort (63); my_friendly_abort (63);
...@@ -4394,6 +4393,13 @@ done: ...@@ -4394,6 +4393,13 @@ done:
return value; return value;
} }
int
is_rid (t)
tree t;
{
return !!is_reserved_word (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t));
}
typedef enum typedef enum
{ {
d_kind, t_kind, s_kind, r_kind, e_kind, c_kind, d_kind, t_kind, s_kind, r_kind, e_kind, c_kind,
......
...@@ -1582,8 +1582,7 @@ hack_identifier (value, name, yychar) ...@@ -1582,8 +1582,7 @@ hack_identifier (value, name, yychar)
if (DECL_LANG_SPECIFIC (value) if (DECL_LANG_SPECIFIC (value)
&& DECL_CLASS_CONTEXT (value) != current_class_type) && DECL_CLASS_CONTEXT (value) != current_class_type)
{ {
tree path; tree path, access;
enum access_type access;
register tree context register tree context
= (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value)) = (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value))
? DECL_CLASS_CONTEXT (value) ? DECL_CLASS_CONTEXT (value)
...@@ -1593,7 +1592,7 @@ hack_identifier (value, name, yychar) ...@@ -1593,7 +1592,7 @@ hack_identifier (value, name, yychar)
if (path) if (path)
{ {
access = compute_access (path, value); access = compute_access (path, value);
if (access != access_public) if (access != access_public_node)
{ {
if (TREE_CODE (value) == VAR_DECL) if (TREE_CODE (value) == VAR_DECL)
error ("static member `%s' is %s", error ("static member `%s' is %s",
...@@ -2101,7 +2100,7 @@ do_build_copy_constructor (fndecl) ...@@ -2101,7 +2100,7 @@ do_build_copy_constructor (fndecl)
(build_reference_type (basetype), parm, (build_reference_type (basetype), parm,
CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE); CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
p = convert_from_reference (p); 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); p, current_base_init_list);
} }
...@@ -2116,7 +2115,7 @@ do_build_copy_constructor (fndecl) ...@@ -2116,7 +2115,7 @@ do_build_copy_constructor (fndecl)
(build_reference_type (basetype), parm, (build_reference_type (basetype), parm,
CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE); CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
p = convert_from_reference (p); 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); p, current_base_init_list);
} }
for (; fields; fields = TREE_CHAIN (fields)) for (; fields; fields = TREE_CHAIN (fields))
...@@ -2192,8 +2191,7 @@ do_build_assign_ref (fndecl) ...@@ -2192,8 +2191,7 @@ do_build_assign_ref (fndecl)
(build_reference_type (basetype), parm, (build_reference_type (basetype), parm,
CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE); CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
p = convert_from_reference (p); p = convert_from_reference (p);
p = build_member_call (TYPE_NESTED_NAME (basetype), p = build_member_call (basetype, ansi_opname [MODIFY_EXPR],
ansi_opname [MODIFY_EXPR],
build_tree_list (NULL_TREE, p)); build_tree_list (NULL_TREE, p));
expand_expr_stmt (p); expand_expr_stmt (p);
} }
......
...@@ -140,7 +140,7 @@ empty_parms () ...@@ -140,7 +140,7 @@ empty_parms ()
/* the reserved words... C++ extensions */ /* the reserved words... C++ extensions */
%token <ttype> AGGR %token <ttype> AGGR
%token <itype> VISSPEC %token <ttype> VISSPEC
%token DELETE NEW OVERLOAD THIS OPERATOR CXX_TRUE CXX_FALSE %token DELETE NEW OVERLOAD THIS OPERATOR CXX_TRUE CXX_FALSE
%token NAMESPACE TYPENAME_KEYWORD USING %token NAMESPACE TYPENAME_KEYWORD USING
%token LEFT_RIGHT TEMPLATE %token LEFT_RIGHT TEMPLATE
...@@ -236,7 +236,7 @@ empty_parms () ...@@ -236,7 +236,7 @@ empty_parms ()
%type <ttype> named_complex_class_head_sans_basetype %type <ttype> named_complex_class_head_sans_basetype
%type <ttype> unnamed_class_head %type <ttype> unnamed_class_head
%type <ttype> class_head base_class_list %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> base_class maybe_base_class_list base_class.1
%type <ttype> exception_specification_opt ansi_raise_identifier ansi_raise_identifiers %type <ttype> exception_specification_opt ansi_raise_identifier ansi_raise_identifiers
%type <ttype> operator_name %type <ttype> operator_name
...@@ -779,13 +779,13 @@ member_init: '(' nonnull_exprlist ')' ...@@ -779,13 +779,13 @@ member_init: '(' nonnull_exprlist ')'
expand_member_init (C_C_D, NULL_TREE, void_type_node); expand_member_init (C_C_D, NULL_TREE, void_type_node);
} }
| notype_identifier '(' nonnull_exprlist ')' | notype_identifier '(' nonnull_exprlist ')'
{ expand_member_init (C_C_D, $<ttype>$, $3); } { expand_member_init (C_C_D, $1, $3); }
| notype_identifier LEFT_RIGHT | 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 ')' | 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 | 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 */ /* GNU extension */
| notype_qualified_id '(' nonnull_exprlist ')' | notype_qualified_id '(' nonnull_exprlist ')'
{ {
...@@ -1589,7 +1589,7 @@ primary: ...@@ -1589,7 +1589,7 @@ primary:
| object overqualified_id '(' nonnull_exprlist ')' | object overqualified_id '(' nonnull_exprlist ')'
{ {
got_object = NULL_TREE; got_object = NULL_TREE;
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2)))) if (IS_SIGNATURE (OP0 ($2)))
{ {
warning ("signature name in scope resolution ignored"); warning ("signature name in scope resolution ignored");
$$ = build_method_call ($$, OP1 ($2), $4, NULL_TREE, $$ = build_method_call ($$, OP1 ($2), $4, NULL_TREE,
...@@ -1601,7 +1601,7 @@ primary: ...@@ -1601,7 +1601,7 @@ primary:
| object overqualified_id LEFT_RIGHT | object overqualified_id LEFT_RIGHT
{ {
got_object = NULL_TREE; got_object = NULL_TREE;
if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2)))) if (IS_SIGNATURE (OP0 ($2)))
{ {
warning ("signature name in scope resolution ignored"); warning ("signature name in scope resolution ignored");
$$ = build_method_call ($$, OP1 ($2), NULL_TREE, NULL_TREE, $$ = build_method_call ($$, OP1 ($2), NULL_TREE, NULL_TREE,
...@@ -2349,9 +2349,8 @@ base_class_list: ...@@ -2349,9 +2349,8 @@ base_class_list:
base_class: base_class:
base_class.1 base_class.1
{ {
tree type; tree type = $1;
type = IDENTIFIER_TYPE_VALUE ($$); if (! is_aggr_type (type, 1))
if (! is_aggr_typedef ($$, 1))
$$ = NULL_TREE; $$ = NULL_TREE;
else if (current_aggr == signature_type_node else if (current_aggr == signature_type_node
&& (! type) && (! IS_SIGNATURE (type))) && (! type) && (! IS_SIGNATURE (type)))
...@@ -2363,7 +2362,7 @@ base_class: ...@@ -2363,7 +2362,7 @@ base_class:
{ {
sorry ("signature inheritance, base type `%s' ignored", sorry ("signature inheritance, base type `%s' ignored",
IDENTIFIER_POINTER ($$)); IDENTIFIER_POINTER ($$));
$$ = build_tree_list ((tree)access_public, $$); $$ = build_tree_list (access_public_node, $$);
} }
else if (type && IS_SIGNATURE (type)) else if (type && IS_SIGNATURE (type))
{ {
...@@ -2371,15 +2370,14 @@ base_class: ...@@ -2371,15 +2370,14 @@ base_class:
$$ = NULL_TREE; $$ = NULL_TREE;
} }
else else
$$ = build_tree_list ((tree)access_default, $$); $$ = build_tree_list (access_default_node, $$);
} }
| base_class_access_list see_typename base_class.1 | base_class_access_list see_typename base_class.1
{ {
tree type; tree type = $3;
type = IDENTIFIER_TYPE_VALUE ($3);
if (current_aggr == signature_type_node) if (current_aggr == signature_type_node)
error ("access and source specifiers not allowed in signature"); error ("access and source specifiers not allowed in signature");
if (! is_aggr_typedef ($3, 1)) if (! IS_AGGR_TYPE (type))
$$ = NULL_TREE; $$ = NULL_TREE;
else if (current_aggr == signature_type_node else if (current_aggr == signature_type_node
&& (! type) && (! IS_SIGNATURE (type))) && (! type) && (! IS_SIGNATURE (type)))
...@@ -2391,7 +2389,7 @@ base_class: ...@@ -2391,7 +2389,7 @@ base_class:
{ {
sorry ("signature inheritance, base type `%s' ignored", sorry ("signature inheritance, base type `%s' ignored",
IDENTIFIER_POINTER ($$)); IDENTIFIER_POINTER ($$));
$$ = build_tree_list ((tree)access_public, $3); $$ = build_tree_list (access_public_node, $3);
} }
else if (type && IS_SIGNATURE (type)) else if (type && IS_SIGNATURE (type))
{ {
...@@ -2399,7 +2397,7 @@ base_class: ...@@ -2399,7 +2397,7 @@ base_class:
$$ = NULL_TREE; $$ = NULL_TREE;
} }
else else
$$ = build_tree_list ((tree) $$, $3); $$ = build_tree_list ($$, $3);
} }
; ;
...@@ -2412,8 +2410,7 @@ base_class.1: ...@@ -2412,8 +2410,7 @@ base_class.1:
if (IS_AGGR_TYPE (TREE_TYPE ($3))) if (IS_AGGR_TYPE (TREE_TYPE ($3)))
{ {
sorry ("`sigof' as base signature specifier"); sorry ("`sigof' as base signature specifier");
/* need to return some dummy signature identifier */ $$ = TREE_TYPE ($3);
$$ = $3;
} }
else else
{ {
...@@ -2434,8 +2431,7 @@ base_class.1: ...@@ -2434,8 +2431,7 @@ base_class.1:
if (IS_AGGR_TYPE (groktypename ($3))) if (IS_AGGR_TYPE (groktypename ($3)))
{ {
sorry ("`sigof' as base signature specifier"); sorry ("`sigof' as base signature specifier");
/* need to return some dummy signature identifier */ $$ = groktypename ($3);
$$ = $3;
} }
else else
{ {
...@@ -2456,40 +2452,40 @@ base_class_access_list: ...@@ -2456,40 +2452,40 @@ base_class_access_list:
| SCSPEC see_typename | SCSPEC see_typename
{ if ($<ttype>$ != ridpointers[(int)RID_VIRTUAL]) { if ($<ttype>$ != ridpointers[(int)RID_VIRTUAL])
sorry ("non-virtual access"); sorry ("non-virtual access");
$$ = access_default_virtual; } $$ = access_default_virtual_node; }
| base_class_access_list VISSPEC see_typename | base_class_access_list VISSPEC see_typename
{ int err = 0; { int err = 0;
if ($2 == access_protected) if ($2 == access_protected_node)
{ {
warning ("`protected' access not implemented"); warning ("`protected' access not implemented");
$2 = access_public; $2 = access_public_node;
err++; err++;
} }
else if ($2 == access_public) else if ($2 == access_public_node)
{ {
if ($1 == access_private) if ($1 == access_private_node)
{ {
mixed: mixed:
error ("base class cannot be public and private"); error ("base class cannot be public and private");
} }
else if ($1 == access_default_virtual) else if ($1 == access_default_virtual_node)
$$ = access_public_virtual; $$ = access_public_virtual_node;
} }
else /* $2 == access_private */ else /* $2 == access_private_node */
{ {
if ($1 == access_public) if ($1 == access_public_node)
goto mixed; goto mixed;
else if ($1 == access_default_virtual) else if ($1 == access_default_virtual_node)
$$ = access_private_virtual; $$ = access_private_virtual_node;
} }
} }
| base_class_access_list SCSPEC see_typename | base_class_access_list SCSPEC see_typename
{ if ($2 != ridpointers[(int)RID_VIRTUAL]) { if ($2 != ridpointers[(int)RID_VIRTUAL])
sorry ("non-virtual access"); sorry ("non-virtual access");
if ($$ == access_public) if ($$ == access_public_node)
$$ = access_public_virtual; $$ = access_public_virtual_node;
else if ($$ == access_private) else if ($$ == access_private_node)
$$ = access_private_virtual; } $$ = access_private_virtual_node; }
; ;
left_curly: '{' left_curly: '{'
...@@ -2564,18 +2560,18 @@ opt.component_decl_list: ...@@ -2564,18 +2560,18 @@ opt.component_decl_list:
| component_decl_list | component_decl_list
{ {
if (current_aggr == signature_type_node) if (current_aggr == signature_type_node)
$$ = build_tree_list ((tree) access_public, $$); $$ = build_tree_list (access_public_node, $$);
else else
$$ = build_tree_list ((tree) access_default, $$); $$ = build_tree_list (access_default_node, $$);
} }
| opt.component_decl_list VISSPEC ':' component_decl_list | opt.component_decl_list VISSPEC ':' component_decl_list
{ {
tree visspec = (tree) $2; tree visspec = $2;
if (current_aggr == signature_type_node) if (current_aggr == signature_type_node)
{ {
error ("access specifier not allowed in signature"); error ("access specifier not allowed in signature");
visspec = (tree) access_public; visspec = access_public_node;
} }
$$ = chainon ($$, build_tree_list (visspec, $4)); $$ = chainon ($$, build_tree_list (visspec, $4));
} }
...@@ -2861,23 +2857,20 @@ after_type_declarator: ...@@ -2861,23 +2857,20 @@ after_type_declarator:
qualified_type_name: qualified_type_name:
type_name %prec EMPTY type_name %prec EMPTY
{ {
$$ = TREE_TYPE ($1);
/* Remember that this name has been used in the class /* Remember that this name has been used in the class
definition, as per [class.scope0] */ definition, as per [class.scope0] */
if (current_class_type if (current_class_type
&& TYPE_BEING_DEFINED (current_class_type) && TYPE_BEING_DEFINED (current_class_type)
&& ! IDENTIFIER_CLASS_VALUE ($$)) && ! IDENTIFIER_CLASS_VALUE ($1))
{ pushdecl_class_level (lookup_name ($1, -2));
tree t = lookup_name ($$, -2);
if (t)
pushdecl_class_level (t);
}
} }
| nested_type | nested_type
; ;
nested_type: nested_type:
nested_name_specifier type_name %prec EMPTY nested_name_specifier type_name %prec EMPTY
{ $$ = $2; } { $$ = TREE_TYPE ($2); }
; ;
direct_after_type_declarator: direct_after_type_declarator:
...@@ -2941,9 +2934,9 @@ complex_direct_notype_declarator: ...@@ -2941,9 +2934,9 @@ complex_direct_notype_declarator:
| direct_notype_declarator '[' ']' | direct_notype_declarator '[' ']'
{ $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
| notype_qualified_id | 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; TREE_COMPLEXITY ($$) = current_class_depth;
} }
} }
...@@ -2991,11 +2984,11 @@ nested_name_specifier: ...@@ -2991,11 +2984,11 @@ nested_name_specifier:
inline here?!? (jason) */ inline here?!? (jason) */
nested_name_specifier_1: nested_name_specifier_1:
TYPENAME SCOPE TYPENAME SCOPE
{ got_scope = TREE_TYPE ($$); } { got_scope = $$ = TREE_TYPE ($1); }
| NSNAME SCOPE | NSNAME SCOPE
{ got_scope = $$; } { got_scope = $$ = $1; }
| template_type SCOPE | template_type SCOPE
{ got_scope = TREE_TYPE ($$); } { got_scope = $$ = TREE_TYPE ($1); }
/* These break 'const i;' /* These break 'const i;'
| IDENTIFIER SCOPE | IDENTIFIER SCOPE
{ {
......
...@@ -127,13 +127,6 @@ process_template_parm (list, next) ...@@ -127,13 +127,6 @@ process_template_parm (list, next)
decl = build_decl (TYPE_DECL, TREE_VALUE (parm), t); decl = build_decl (TYPE_DECL, TREE_VALUE (parm), t);
TYPE_MAIN_DECL (t) = decl; TYPE_MAIN_DECL (t) = decl;
parm = 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); SET_DECL_ARTIFICIAL (decl);
pushdecl (decl); pushdecl (decl);
......
...@@ -794,23 +794,23 @@ current_scope () ...@@ -794,23 +794,23 @@ current_scope ()
This will be static when lookup_fnfield comes into this file. 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. 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. 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. */ lexical scope because it is private. */
#if 0 #if 0
#define PUBLIC_RETURN return (DECL_PUBLIC (field) = 1), access_public #define PUBLIC_RETURN return (DECL_PUBLIC (field) = 1), access_public_node
#define PROTECTED_RETURN return (DECL_PROTECTED (field) = 1), access_protected #define PROTECTED_RETURN return (DECL_PROTECTED (field) = 1), access_protected_node
#define PRIVATE_RETURN return (DECL_PRIVATE (field) = 1), access_private #define PRIVATE_RETURN return (DECL_PRIVATE (field) = 1), access_private_node
#else #else
#define PUBLIC_RETURN return access_public #define PUBLIC_RETURN return access_public_node
#define PROTECTED_RETURN return access_protected #define PROTECTED_RETURN return access_protected_node
#define PRIVATE_RETURN return access_private #define PRIVATE_RETURN return access_private_node
#endif #endif
#if 0 #if 0
...@@ -818,11 +818,11 @@ current_scope () ...@@ -818,11 +818,11 @@ current_scope ()
static tree previous_scope = NULL_TREE; static tree previous_scope = NULL_TREE;
#endif #endif
enum access_type tree
compute_access (basetype_path, field) compute_access (basetype_path, field)
tree basetype_path, field; tree basetype_path, field;
{ {
enum access_type access; tree access;
tree types; tree types;
tree context; tree context;
int protected_ok, via_protected; int protected_ok, via_protected;
...@@ -836,11 +836,11 @@ compute_access (basetype_path, field) ...@@ -836,11 +836,11 @@ compute_access (basetype_path, field)
|| (TREE_CODE (field) != FUNCTION_DECL && TREE_STATIC (field))); || (TREE_CODE (field) != FUNCTION_DECL && TREE_STATIC (field)));
if (! flag_access_control) if (! flag_access_control)
return access_public; return access_public_node;
/* The field lives in the current class. */ /* The field lives in the current class. */
if (BINFO_TYPE (basetype_path) == current_class_type) if (BINFO_TYPE (basetype_path) == current_class_type)
return access_public; return access_public_node;
#if 0 #if 0
/* Disabled until pushing function scope clears these out. If ever. */ /* Disabled until pushing function scope clears these out. If ever. */
...@@ -848,17 +848,17 @@ compute_access (basetype_path, field) ...@@ -848,17 +848,17 @@ compute_access (basetype_path, field)
if (current_scope () == previous_scope) if (current_scope () == previous_scope)
{ {
if (DECL_PUBLIC (field)) if (DECL_PUBLIC (field))
return access_public; return access_public_node;
if (DECL_PROTECTED (field)) if (DECL_PROTECTED (field))
return access_protected; return access_protected_node;
if (DECL_PRIVATE (field)) if (DECL_PRIVATE (field))
return access_private; return access_private_node;
} }
#endif #endif
/* We don't currently support access control on nested types. */ /* We don't currently support access control on nested types. */
if (TREE_CODE (field) == TYPE_DECL) if (TREE_CODE (field) == TYPE_DECL)
return access_public; return access_public_node;
previous_scope = current_scope (); previous_scope = current_scope ();
...@@ -912,7 +912,7 @@ compute_access (basetype_path, field) ...@@ -912,7 +912,7 @@ compute_access (basetype_path, field)
basetype_path = reverse_path (basetype_path); basetype_path = reverse_path (basetype_path);
types = basetype_path; types = basetype_path;
via_protected = 0; via_protected = 0;
access = access_default; access = access_default_node;
protected_ok = static_mem && current_class_type protected_ok = static_mem && current_class_type
&& ACCESSIBLY_DERIVED_FROM_P (BINFO_TYPE (types), current_class_type); && ACCESSIBLY_DERIVED_FROM_P (BINFO_TYPE (types), current_class_type);
...@@ -934,7 +934,7 @@ compute_access (basetype_path, field) ...@@ -934,7 +934,7 @@ compute_access (basetype_path, field)
member = purpose_member (type, DECL_ACCESS (field)); member = purpose_member (type, DECL_ACCESS (field));
if (member) if (member)
{ {
access = (enum access_type) TREE_VALUE (member); access = TREE_VALUE (member);
break; break;
} }
...@@ -948,7 +948,7 @@ compute_access (basetype_path, field) ...@@ -948,7 +948,7 @@ compute_access (basetype_path, field)
via_protected = 1; via_protected = 1;
else if (! TREE_VIA_PUBLIC (types) && ! private_ok) else if (! TREE_VIA_PUBLIC (types) && ! private_ok)
{ {
access = access_private; access = access_private_node;
break; break;
} }
} }
...@@ -959,30 +959,30 @@ compute_access (basetype_path, field) ...@@ -959,30 +959,30 @@ compute_access (basetype_path, field)
/* No special visibilities apply. Use normal rules. */ /* No special visibilities apply. Use normal rules. */
if (access == access_default) if (access == access_default_node)
{ {
if (is_friend (context, previous_scope)) if (is_friend (context, previous_scope))
access = access_public; access = access_public_node;
else if (TREE_PRIVATE (field)) else if (TREE_PRIVATE (field))
access = access_private; access = access_private_node;
else if (TREE_PROTECTED (field)) else if (TREE_PROTECTED (field))
access = access_protected; access = access_protected_node;
else else
access = access_public; access = access_public_node;
} }
if (access == access_public && via_protected) if (access == access_public_node && via_protected)
access = access_protected; access = access_protected_node;
if (access == access_protected && protected_ok) if (access == access_protected_node && protected_ok)
access = access_public; access = access_public_node;
#if 0 #if 0
if (access == access_public) if (access == access_public_node)
DECL_PUBLIC (field) = 1; DECL_PUBLIC (field) = 1;
else if (access == access_protected) else if (access == access_protected_node)
DECL_PROTECTED (field) = 1; DECL_PROTECTED (field) = 1;
else if (access == access_private) else if (access == access_private_node)
DECL_PRIVATE (field) = 1; DECL_PRIVATE (field) = 1;
else my_friendly_abort (96); else my_friendly_abort (96);
#endif #endif
...@@ -1072,9 +1072,9 @@ lookup_field (xbasetype, name, protect, want_type) ...@@ -1072,9 +1072,9 @@ lookup_field (xbasetype, name, protect, want_type)
int head = 0, tail = 0; int head = 0, tail = 0;
tree rval, rval_binfo = NULL_TREE, rval_binfo_h; tree rval, rval_binfo = NULL_TREE, rval_binfo_h;
tree type, basetype_chain, basetype_path; tree type, basetype_chain, basetype_path;
enum access_type this_v = access_default; tree this_v = access_default_node;
tree entry, binfo, binfo_h; 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); int vbase_name_p = VBASE_NAME_P (name);
/* rval_binfo is the binfo associated with the found member, note, /* rval_binfo is the binfo associated with the found member, note,
...@@ -1179,16 +1179,16 @@ lookup_field (xbasetype, name, protect, want_type) ...@@ -1179,16 +1179,16 @@ lookup_field (xbasetype, name, protect, want_type)
this_v = compute_access (basetype_path, rval); this_v = compute_access (basetype_path, rval);
if (TREE_CODE (rval) == CONST_DECL) 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'"; 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'"; errstr = "enum `%D' is a protected value of class `%T'";
} }
else else
{ {
if (this_v == access_private) if (this_v == access_private_node)
errstr = "member `%D' is a private member of class `%T'"; 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'"; errstr = "member `%D' is a protected member of class `%T'";
} }
} }
...@@ -1370,14 +1370,14 @@ lookup_field (xbasetype, name, protect, want_type) ...@@ -1370,14 +1370,14 @@ lookup_field (xbasetype, name, protect, want_type)
/* If is possible for one of the derived types on the path to /* If is possible for one of the derived types on the path to
have defined special access for this field. Look for such have defined special access for this field. Look for such
declarations and report an error if a conflict is found. */ 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); 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'"; errstr = "conflicting access to member `%D'";
this_v = access_default; this_v = access_default_node;
} }
own_access = new_v; own_access = new_v;
CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp))); CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));
...@@ -1397,15 +1397,15 @@ lookup_field (xbasetype, name, protect, want_type) ...@@ -1397,15 +1397,15 @@ lookup_field (xbasetype, name, protect, want_type)
if (errstr == 0) if (errstr == 0)
{ {
if (own_access == access_private) if (own_access == access_private_node)
errstr = "member `%D' declared private"; errstr = "member `%D' declared private";
else if (own_access == access_protected) else if (own_access == access_protected_node)
errstr = "member `%D' declared protected"; errstr = "member `%D' declared protected";
else if (this_v == access_private) else if (this_v == access_private_node)
errstr = TREE_PRIVATE (rval) errstr = TREE_PRIVATE (rval)
? "member `%D' is private" ? "member `%D' is private"
: "member `%D' is from private base class"; : "member `%D' is from private base class";
else if (this_v == access_protected) else if (this_v == access_protected_node)
errstr = TREE_PROTECTED (rval) errstr = TREE_PROTECTED (rval)
? "member `%D' is protected" ? "member `%D' is protected"
: "member `%D' is from protected base class"; : "member `%D' is from protected base class";
...@@ -3334,10 +3334,14 @@ dfs_compress_decls (binfo) ...@@ -3334,10 +3334,14 @@ dfs_compress_decls (binfo)
lattice. Where ambiguities result, we mark them lattice. Where ambiguities result, we mark them
with `error_mark_node' so that if they are encountered with `error_mark_node' so that if they are encountered
without explicit qualification, we can emit an error 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 void
push_class_decls (type) push_class_decls (type, only_types)
tree type; tree type;
int only_types;
{ {
tree id; tree id;
struct obstack *ambient_obstack = current_obstack; struct obstack *ambient_obstack = current_obstack;
...@@ -3392,7 +3396,12 @@ push_class_decls (type) ...@@ -3392,7 +3396,12 @@ push_class_decls (type)
/* Install the original class value in order to make /* Install the original class value in order to make
pushdecl_class_level work correctly. */ pushdecl_class_level work correctly. */
IDENTIFIER_CLASS_VALUE (id) = TREE_VALUE (closed_envelopes); 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); push_class_level_binding (id, new);
else else
pushdecl_class_level (new); pushdecl_class_level (new);
......
...@@ -530,7 +530,7 @@ build_signature_table_constructor (sig_ty, rhs) ...@@ -530,7 +530,7 @@ build_signature_table_constructor (sig_ty, rhs)
if (rhs_method == NULL_TREE if (rhs_method == NULL_TREE
|| (compute_access (basetypes, rhs_method) || (compute_access (basetypes, rhs_method)
!= access_public)) != access_public_node))
{ {
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),
......
...@@ -820,7 +820,7 @@ layout_basetypes (rec, binfos) ...@@ -820,7 +820,7 @@ layout_basetypes (rec, binfos)
goto got_it; goto got_it;
} }
sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (basetype)); sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (basetype));
decl = build_lang_decl (FIELD_DECL, get_identifier (name), decl = build_lang_field_decl (FIELD_DECL, get_identifier (name),
build_pointer_type (basetype)); build_pointer_type (basetype));
/* If you change any of the below, take a look at all the /* If you change any of the below, take a look at all the
other VFIELD_BASEs and VTABLE_BASEs in the code, and change other VFIELD_BASEs and VTABLE_BASEs in the code, and change
...@@ -1137,7 +1137,8 @@ get_decl_list (value) ...@@ -1137,7 +1137,8 @@ get_decl_list (value)
if (TREE_CODE (value) == IDENTIFIER_NODE) if (TREE_CODE (value) == IDENTIFIER_NODE)
list = get_identifier_list (value); list = get_identifier_list (value);
else if (TREE_CODE (value) == RECORD_TYPE 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); list = CLASSTYPE_AS_LIST (value);
if (list != NULL_TREE) if (list != NULL_TREE)
......
...@@ -1532,15 +1532,14 @@ build_object_ref (datum, basetype, field) ...@@ -1532,15 +1532,14 @@ build_object_ref (datum, basetype, field)
basetype, field, dtype); basetype, field, dtype);
return error_mark_node; return error_mark_node;
} }
else if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (basetype))) else if (IS_SIGNATURE (basetype))
{ {
warning ("signature name in scope resolution ignored"); warning ("signature name in scope resolution ignored");
return build_component_ref (datum, field, NULL_TREE, 1); 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 (basetype, TREE_TYPE (datum));
tree binfo = binfo_or_else (real_basetype, TREE_TYPE (datum));
if (binfo) if (binfo)
return build_component_ref (build_scoped_ref (datum, basetype), return build_component_ref (build_scoped_ref (datum, basetype),
field, binfo, 1); field, binfo, 1);
...@@ -1590,15 +1589,14 @@ build_component_ref_1 (datum, field, protect) ...@@ -1590,15 +1589,14 @@ build_component_ref_1 (datum, field, protect)
if (datum == C_C_D) if (datum == C_C_D)
{ {
enum access_type access tree access = compute_access (TYPE_BINFO (current_class_type), field);
= compute_access (TYPE_BINFO (current_class_type), field);
if (access == access_private) if (access == access_private_node)
{ {
cp_error ("field `%D' is private", field); cp_error ("field `%D' is private", field);
return error_mark_node; return error_mark_node;
} }
else if (access == access_protected) else if (access == access_protected_node)
{ {
cp_error ("field `%D' is protected", field); cp_error ("field `%D' is protected", field);
return error_mark_node; return error_mark_node;
...@@ -1748,14 +1746,13 @@ build_component_ref (datum, component, basetype_path, protect) ...@@ -1748,14 +1746,13 @@ build_component_ref (datum, component, basetype_path, protect)
if (TREE_CHAIN (fndecls) == NULL_TREE if (TREE_CHAIN (fndecls) == NULL_TREE
&& DECL_CHAIN (TREE_VALUE (fndecls)) == NULL_TREE) && DECL_CHAIN (TREE_VALUE (fndecls)) == NULL_TREE)
{ {
enum access_type access; tree access, fndecl;
tree fndecl;
/* Unique, so use this one now. */ /* Unique, so use this one now. */
basetype = TREE_PURPOSE (fndecls); basetype = TREE_PURPOSE (fndecls);
fndecl = TREE_VALUE (fndecls); fndecl = TREE_VALUE (fndecls);
access = compute_access (TREE_PURPOSE (fndecls), fndecl); access = compute_access (TREE_PURPOSE (fndecls), fndecl);
if (access == access_public) if (access == access_public_node)
{ {
if (DECL_VINDEX (fndecl) if (DECL_VINDEX (fndecl)
&& ! resolves_to_fixed_type_p (datum, 0)) && ! resolves_to_fixed_type_p (datum, 0))
...@@ -1769,7 +1766,7 @@ build_component_ref (datum, component, basetype_path, protect) ...@@ -1769,7 +1766,7 @@ build_component_ref (datum, component, basetype_path, protect)
mark_used (fndecl); mark_used (fndecl);
return fndecl; return fndecl;
} }
if (access == access_protected) if (access == access_protected_node)
cp_error ("member function `%D' is protected", fndecl); cp_error ("member function `%D' is protected", fndecl);
else else
cp_error ("member function `%D' is private", fndecl); cp_error ("member function `%D' is private", fndecl);
...@@ -3727,7 +3724,7 @@ pointer_int_sum (resultcode, ptrop, intop) ...@@ -3727,7 +3724,7 @@ pointer_int_sum (resultcode, ptrop, intop)
} }
else if (TREE_CODE (TREE_TYPE (result_type)) == OFFSET_TYPE) 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"); pedwarn ("ANSI C++ forbids using pointer to a member in arithmetic");
size_exp = integer_one_node; size_exp = integer_one_node;
} }
...@@ -3793,7 +3790,7 @@ pointer_diff (op0, op1) ...@@ -3793,7 +3790,7 @@ pointer_diff (op0, op1)
tree restype = ptrdiff_type_node; tree restype = ptrdiff_type_node;
tree target_type = TREE_TYPE (TREE_TYPE (op0)); tree target_type = TREE_TYPE (TREE_TYPE (op0));
if (pedantic) if (pedantic || warn_pointer_arith)
{ {
if (TREE_CODE (target_type) == VOID_TYPE) if (TREE_CODE (target_type) == VOID_TYPE)
pedwarn ("ANSI C++ forbids using pointer of type `void *' in subtraction"); pedwarn ("ANSI C++ forbids using pointer of type `void *' in subtraction");
...@@ -6169,9 +6166,10 @@ build_modify_expr (lhs, modifycode, rhs) ...@@ -6169,9 +6166,10 @@ build_modify_expr (lhs, modifycode, rhs)
/* Can't initialize directly from a TARGET_EXPR, since that would /* Can't initialize directly from a TARGET_EXPR, since that would
cause the lhs to be constructed twice, and possibly result in cause the lhs to be constructed twice, and possibly result in
accidental self-initialization. So we force the TARGET_EXPR to be 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) 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) if (TREE_CODE (newrhs) == ERROR_MARK)
......
...@@ -1199,7 +1199,7 @@ process_init_constructor (type, init, elts) ...@@ -1199,7 +1199,7 @@ process_init_constructor (type, init, elts)
/* Given a structure or union value DATUM, construct and return /* Given a structure or union value DATUM, construct and return
the structure or union component which results from narrowing 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 hierarchy
class L { int ii; }; class L { int ii; };
...@@ -1213,23 +1213,16 @@ process_init_constructor (type, init, elts) ...@@ -1213,23 +1213,16 @@ process_init_constructor (type, init, elts)
then the expression 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, 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 DATUM would be x, and BASETYPE would be A.
SCOPE_REF
SCOPE_REF
C A
L
The last entry in the SCOPE_REF is always an IDENTIFIER_NODE.
*/ */
tree tree
build_scoped_ref (datum, types) build_scoped_ref (datum, basetype)
tree datum; tree datum;
tree types; tree basetype;
{ {
tree ref; tree ref;
tree type = TREE_TYPE (datum); tree type = TREE_TYPE (datum);
...@@ -1242,62 +1235,17 @@ build_scoped_ref (datum, types) ...@@ -1242,62 +1235,17 @@ build_scoped_ref (datum, types)
type = TYPE_MAIN_VARIANT (type); 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. */ /* 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)) if (binfo != TYPE_BINFO (type))
{ {
binfo = get_binfo (binfo, type, 1); binfo = get_binfo (binfo, type, 1);
if (binfo == error_mark_node) if (binfo == error_mark_node)
return error_mark_node; return error_mark_node;
if (binfo == 0) if (binfo == 0)
return error_not_base_type (IDENTIFIER_TYPE_VALUE (types), type); return error_not_base_type (basetype, type);
} }
switch (TREE_CODE (datum)) 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