+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
(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.
/* 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',
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')",
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))
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)
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 };
if (flags & LOOKUP_PROTECT)
access = compute_access (basetype_path, function);
- if (access == access_private)
+ if (access == access_private_node)
{
if (flags & LOOKUP_COMPLAIN)
{
}
return error_mark_node;
}
- else if (access == access_protected)
+ else if (access == access_protected_node)
{
if (flags & LOOKUP_COMPLAIN)
{
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;
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)
{
}
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;
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;
}
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;
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)
{
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. */
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);
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;
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);
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;
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));
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));
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))
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;
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)
}
else
{
- if (access == access_private)
+ if (access == access_private_node)
saw_private = 1;
else
saw_protected = 1;
/* NOTREACHED */
found:
- if (access == access_private)
+ if (access == access_private_node)
if (! can_be_private)
{
if (msgp)
: "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)
{
if (decls || tags || subblocks)
{
- if (BLOCK_VARS (block) || BLOCK_TYPE_TAGS (block) || BLOCK_SUBBLOCKS (block))
+ if (BLOCK_VARS (block) || BLOCK_TYPE_TAGS (block))
{
warning ("internal compiler error: debugging info corrupted");
}
BLOCK_VARS (block) = decls;
BLOCK_TYPE_TAGS (block) = tags;
- /* Recover from too many blocks by chaining them together. */
- BLOCK_SUBBLOCKS (block) = chainon (BLOCK_SUBBLOCKS (block), subblocks);
+
+ /* We can have previous subblocks and new subblocks when
+ doing fixup_gotos with complex cleanups. We chain the new
+ subblocks onto the end of any pre-existing subblocks. */
+ BLOCK_SUBBLOCKS (block) = chainon (BLOCK_SUBBLOCKS (block),
+ subblocks);
}
- /* If we created the block earlier on, and we are just diddling it now, then
- it already should have a proper BLOCK_END_NOTE value associated with it. */
+ /* If we created the block earlier on, and we are just
+ diddling it now, then it already should have a proper
+ BLOCK_END_NOTE value associated with it. */
}
else
{
{
if (DECL_CONTEXT (t) == NULL_TREE)
fatal ("parse errors have confused me too much");
+
+ /* Check for duplicate params. */
+ if (duplicate_decls (x, t))
+ return t;
}
else if (((TREE_CODE (x) == FUNCTION_DECL && DECL_LANGUAGE (x) == lang_c)
|| (TREE_CODE (x) == TEMPLATE_DECL
was initialized was ever used. Don't do this if it has a
destructor, so we don't complain about the 'resource
allocation is initialization' idiom. */
- if (TYPE_NEEDS_CONSTRUCTING (type) && cleanup == NULL_TREE)
+ if (TYPE_NEEDS_CONSTRUCTING (type)
+ && cleanup == NULL_TREE
+ && DECL_NAME (decl))
TREE_USED (decl) = 0;
/* Store the cleanup, if there was one. */
build_function_type (void_type_node,
pfvlist),
NOT_BUILT_IN, NULL_PTR);
+ assemble_external (atexit_fndecl);
Atexit = default_conversion (atexit_fndecl);
pop_lang_context ();
pop_obstacks ();
/* Look inside a declarator for the name being declared
and get it as a string, for an error message. */
{
- tree last = NULL_TREE;
- register tree decl = declarator;
+ tree *next = &declarator;
+ register tree decl;
name = NULL;
- while (decl)
- switch (TREE_CODE (decl))
- {
- case COND_EXPR:
- ctype = NULL_TREE;
- decl = TREE_OPERAND (decl, 0);
- break;
-
- case BIT_NOT_EXPR: /* for C++ destructors! */
+ while (next && *next)
+ {
+ decl = *next;
+ switch (TREE_CODE (decl))
{
- tree name = TREE_OPERAND (decl, 0);
- tree rename = NULL_TREE;
-
- my_friendly_assert (flags == NO_SPECIAL, 152);
- flags = DTOR_FLAG;
- return_type = return_dtor;
- my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 153);
- if (ctype == NULL_TREE)
- {
- if (current_class_type == NULL_TREE)
- {
- error ("destructors must be member functions");
- flags = NO_SPECIAL;
- }
- else
- {
- tree t = constructor_name (current_class_name);
- if (t != name)
- rename = t;
- }
- }
- else
- {
- tree t = constructor_name (ctype);
- if (t != name)
- rename = t;
- }
-
- if (rename)
- {
- error ("destructor `%s' must match class name `%s'",
- IDENTIFIER_POINTER (name),
- IDENTIFIER_POINTER (rename));
- TREE_OPERAND (decl, 0) = rename;
- }
- decl = name;
- }
- break;
-
- case ADDR_EXPR: /* C++ reference declaration */
- /* fall through */
- case ARRAY_REF:
- case INDIRECT_REF:
- ctype = NULL_TREE;
- innermost_code = TREE_CODE (decl);
- last = decl;
- decl = TREE_OPERAND (decl, 0);
- break;
+ case COND_EXPR:
+ ctype = NULL_TREE;
+ next = &TREE_OPERAND (decl, 0);
+ break;
- case CALL_EXPR:
- if (parmlist_is_exprlist (TREE_OPERAND (decl, 1)))
+ case BIT_NOT_EXPR: /* for C++ destructors! */
{
- /* This is actually a variable declaration using constructor
- syntax. We need to call start_decl and cp_finish_decl so we
- can get the variable initialized... */
-
- if (last)
- /* We need to insinuate ourselves into the declarator in place
- of the CALL_EXPR. */
- TREE_OPERAND (last, 0) = TREE_OPERAND (decl, 0);
+ tree name = TREE_OPERAND (decl, 0);
+ tree rename = NULL_TREE;
+
+ my_friendly_assert (flags == NO_SPECIAL, 152);
+ flags = DTOR_FLAG;
+ return_type = return_dtor;
+ my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 153);
+ if (ctype == NULL_TREE)
+ {
+ if (current_class_type == NULL_TREE)
+ {
+ error ("destructors must be member functions");
+ flags = NO_SPECIAL;
+ }
+ else
+ {
+ tree t = constructor_name (current_class_name);
+ if (t != name)
+ rename = t;
+ }
+ }
else
- declarator = TREE_OPERAND (decl, 0);
-
- init = TREE_OPERAND (decl, 1);
-
- decl = start_decl (declarator, declspecs, 1, NULL_TREE);
- finish_decl (decl, init, NULL_TREE);
- return 0;
- }
- innermost_code = TREE_CODE (decl);
- if (decl_context == FIELD && ctype == NULL_TREE)
- ctype = current_class_type;
- if (ctype
- && TREE_OPERAND (decl, 0) == constructor_name_full (ctype))
- TREE_OPERAND (decl, 0) = constructor_name (ctype);
- decl = TREE_OPERAND (decl, 0);
- if (ctype != NULL_TREE
- && decl != NULL_TREE && flags != DTOR_FLAG
- && decl == constructor_name (ctype))
- {
- return_type = return_ctor;
- ctor_return_type = ctype;
- }
- ctype = NULL_TREE;
- break;
-
- case IDENTIFIER_NODE:
- dname = decl;
- decl = NULL_TREE;
+ {
+ tree t = constructor_name (ctype);
+ if (t != name)
+ rename = t;
+ }
- if (! IDENTIFIER_OPNAME_P (dname)
- /* Linux headers use '__op'. Arrgh. */
- || IDENTIFIER_TYPENAME_P (dname) && ! TREE_TYPE (dname))
- name = IDENTIFIER_POINTER (dname);
- else
- {
- if (IDENTIFIER_TYPENAME_P (dname))
+ if (rename)
{
- my_friendly_assert (flags == NO_SPECIAL, 154);
- flags = TYPENAME_FLAG;
- ctor_return_type = TREE_TYPE (dname);
- return_type = return_conversion;
+ error ("destructor `%s' must match class name `%s'",
+ IDENTIFIER_POINTER (name),
+ IDENTIFIER_POINTER (rename));
+ TREE_OPERAND (decl, 0) = rename;
}
- name = operator_name_string (dname);
+ next = &name;
}
- break;
+ break;
- case RECORD_TYPE:
- case UNION_TYPE:
- case ENUMERAL_TYPE:
- /* Parse error puts this typespec where
- a declarator should go. */
- error ("declarator name missing");
- dname = TYPE_NAME (decl);
- if (dname && TREE_CODE (dname) == TYPE_DECL)
- dname = DECL_NAME (dname);
- name = dname ? IDENTIFIER_POINTER (dname) : "<nameless>";
- declspecs = temp_tree_cons (NULL_TREE, decl, declspecs);
- decl = NULL_TREE;
- break;
+ case ADDR_EXPR: /* C++ reference declaration */
+ /* fall through */
+ case ARRAY_REF:
+ case INDIRECT_REF:
+ ctype = NULL_TREE;
+ innermost_code = TREE_CODE (decl);
+ next = &TREE_OPERAND (decl, 0);
+ break;
- /* C++ extension */
- case SCOPE_REF:
- {
- /* Perform error checking, and convert class names to types.
- We may call grokdeclarator multiple times for the same
- tree structure, so only do the conversion once. In this
- case, we have exactly what we want for `ctype'. */
- tree cname = TREE_OPERAND (decl, 0);
- if (cname == NULL_TREE)
- ctype = NULL_TREE;
- /* Can't use IS_AGGR_TYPE because CNAME might not be a type. */
- else if (IS_AGGR_TYPE_CODE (TREE_CODE (cname))
- || TREE_CODE (cname) == UNINSTANTIATED_P_TYPE)
- ctype = cname;
- else if (! is_aggr_typedef (cname, 1))
+ case CALL_EXPR:
+ if (parmlist_is_exprlist (TREE_OPERAND (decl, 1)))
{
- TREE_OPERAND (decl, 0) = NULL_TREE;
+ /* This is actually a variable declaration using constructor
+ syntax. We need to call start_decl and cp_finish_decl so we
+ can get the variable initialized... */
+
+ *next = TREE_OPERAND (decl, 0);
+ init = TREE_OPERAND (decl, 1);
+
+ decl = start_decl (declarator, declspecs, 1, NULL_TREE);
+ finish_decl (decl, init, NULL_TREE);
+ return 0;
}
- /* Must test TREE_OPERAND (decl, 1), in case user gives
- us `typedef (class::memfunc)(int); memfunc *memfuncptr;' */
- else if (TREE_OPERAND (decl, 1)
- && TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)
+ innermost_code = TREE_CODE (decl);
+ if (decl_context == FIELD && ctype == NULL_TREE)
+ ctype = current_class_type;
+ if (ctype && TREE_OPERAND (decl, 0) == ctype)
+ TREE_OPERAND (decl, 0) = constructor_name (ctype);
+ next = &TREE_OPERAND (decl, 0);
+ decl = *next;
+ if (ctype != NULL_TREE
+ && decl != NULL_TREE && flags != DTOR_FLAG
+ && decl == constructor_name (ctype))
{
- TREE_OPERAND (decl, 0) = IDENTIFIER_TYPE_VALUE (cname);
+ return_type = return_ctor;
+ ctor_return_type = ctype;
}
- else if (ctype == NULL_TREE)
+ ctype = NULL_TREE;
+ break;
+
+ case IDENTIFIER_NODE:
+ dname = decl;
+ next = 0;
+
+ if (is_rid (dname))
{
- ctype = IDENTIFIER_TYPE_VALUE (cname);
- TREE_OPERAND (decl, 0) = ctype;
+ cp_error ("declarator-id missing; using reserved word `%D'",
+ dname);
+ name = IDENTIFIER_POINTER (dname);
}
- else if (TREE_COMPLEXITY (decl) == current_class_depth)
- TREE_OPERAND (decl, 0) = ctype;
+ if (! IDENTIFIER_OPNAME_P (dname)
+ /* Linux headers use '__op'. Arrgh. */
+ || IDENTIFIER_TYPENAME_P (dname) && ! TREE_TYPE (dname))
+ name = IDENTIFIER_POINTER (dname);
else
{
- if (! UNIQUELY_DERIVED_FROM_P (IDENTIFIER_TYPE_VALUE (cname),
- ctype))
+ if (IDENTIFIER_TYPENAME_P (dname))
{
- cp_error ("type `%T' is not derived from type `%T'",
- IDENTIFIER_TYPE_VALUE (cname), ctype);
- TREE_OPERAND (decl, 0) = NULL_TREE;
- }
- else
- {
- ctype = IDENTIFIER_TYPE_VALUE (cname);
- TREE_OPERAND (decl, 0) = ctype;
+ my_friendly_assert (flags == NO_SPECIAL, 154);
+ flags = TYPENAME_FLAG;
+ ctor_return_type = TREE_TYPE (dname);
+ return_type = return_conversion;
}
+ name = operator_name_string (dname);
}
+ break;
- if (ctype
- && TREE_OPERAND (decl, 1) == constructor_name_full (ctype))
- TREE_OPERAND (decl, 1) = constructor_name (ctype);
- decl = TREE_OPERAND (decl, 1);
- if (ctype)
+ /* C++ extension */
+ case SCOPE_REF:
+ {
+ /* Perform error checking, and decide on a ctype. */
+ tree cname = TREE_OPERAND (decl, 0);
+ if (cname == NULL_TREE)
+ ctype = NULL_TREE;
+ else if (! is_aggr_type (cname, 1))
+ TREE_OPERAND (decl, 0) = NULL_TREE;
+ /* Must test TREE_OPERAND (decl, 1), in case user gives
+ us `typedef (class::memfunc)(int); memfunc *memfuncptr;' */
+ else if (TREE_OPERAND (decl, 1)
+ && TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)
+ ctype = cname;
+ else if (ctype == NULL_TREE)
+ ctype = cname;
+ else if (TREE_COMPLEXITY (decl) == current_class_depth)
+ TREE_OPERAND (decl, 0) = ctype;
+ else
+ {
+ if (! UNIQUELY_DERIVED_FROM_P (cname, ctype))
+ {
+ cp_error ("type `%T' is not derived from type `%T'",
+ cname, ctype);
+ TREE_OPERAND (decl, 0) = NULL_TREE;
+ }
+ else
+ ctype = cname;
+ }
+
+ if (ctype
+ && TREE_OPERAND (decl, 1) == constructor_name_full (ctype))
+ TREE_OPERAND (decl, 1) = constructor_name (ctype);
+ next = &TREE_OPERAND (decl, 1);
+ decl = *next;
+ if (ctype)
+ {
+ if (TREE_CODE (decl) == IDENTIFIER_NODE
+ && constructor_name (ctype) == decl)
+ {
+ return_type = return_ctor;
+ ctor_return_type = ctype;
+ }
+ else if (TREE_CODE (decl) == BIT_NOT_EXPR
+ && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE
+ && (constructor_name (ctype) == TREE_OPERAND (decl, 0)
+ || constructor_name_full (ctype) == TREE_OPERAND (decl, 0)))
+ {
+ return_type = return_dtor;
+ ctor_return_type = ctype;
+ flags = DTOR_FLAG;
+ TREE_OPERAND (decl, 0) = constructor_name (ctype);
+ next = &TREE_OPERAND (decl, 0);
+ }
+ }
+ }
+ break;
+
+ case ERROR_MARK:
+ next = 0;
+ break;
+
+ default:
+ if (TREE_CODE_CLASS (TREE_CODE (decl)) == 't')
{
- if (TREE_CODE (decl) == IDENTIFIER_NODE
- && constructor_name (ctype) == decl)
- {
- return_type = return_ctor;
- ctor_return_type = ctype;
- }
- else if (TREE_CODE (decl) == BIT_NOT_EXPR
- && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE
- && (constructor_name (ctype) == TREE_OPERAND (decl, 0)
- || constructor_name_full (ctype) == TREE_OPERAND (decl, 0)))
- {
- return_type = return_dtor;
- ctor_return_type = ctype;
- flags = DTOR_FLAG;
- decl = TREE_OPERAND (decl, 0) = constructor_name (ctype);
- }
+ /* Parse error puts this typespec where
+ a declarator should go. */
+ error ("typename specified as declarator-id");
+ if (current_class_type)
+ cp_error (" perhaps you want `%T' for a constructor",
+ current_class_name);
+ dname = TYPE_IDENTIFIER (decl);
+ name = dname ? IDENTIFIER_POINTER (dname) : "<nameless>";
+ declspecs = temp_tree_cons (NULL_TREE, integer_type_node,
+ declspecs);
+ *next = dname;
+ next = 0;
+ break;
}
+ cp_compiler_error ("`%D' as declarator", decl);
+ return 0; /* We used to do a 155 abort here. */
}
- break;
-
- case ERROR_MARK:
- decl = NULL_TREE;
- break;
-
- default:
- return 0; /* We used to do a 155 abort here. */
- }
+ }
if (name == NULL)
name = "type name";
}
/* If a cross reference is requested, look up the type
already defined for this tag and return it. */
- t = IDENTIFIER_TYPE_VALUE (name);
+ if (TREE_CODE_CLASS (TREE_CODE (name)) == 't')
+ {
+ t = name;
+ name = TYPE_NESTED_NAME (t);
+ }
+ else
+ t = IDENTIFIER_TYPE_VALUE (name);
if (t && TREE_CODE (t) != code)
t = NULL_TREE;
{
/* The base of a derived struct is public by default. */
int via_public
- = (TREE_PURPOSE (binfo) == (tree)access_public
- || TREE_PURPOSE (binfo) == (tree)access_public_virtual
+ = (TREE_PURPOSE (binfo) == access_public_node
+ || TREE_PURPOSE (binfo) == access_public_virtual_node
|| (tag_code != class_type
- && (TREE_PURPOSE (binfo) == (tree)access_default
- || TREE_PURPOSE (binfo) == (tree)access_default_virtual)));
- int via_protected = TREE_PURPOSE (binfo) == (tree)access_protected;
+ && (TREE_PURPOSE (binfo) == access_default_node
+ || TREE_PURPOSE (binfo) == access_default_virtual_node)));
+ int via_protected = TREE_PURPOSE (binfo) == access_protected_node;
int via_virtual
- = (TREE_PURPOSE (binfo) == (tree)access_private_virtual
- || TREE_PURPOSE (binfo) == (tree)access_public_virtual
- || TREE_PURPOSE (binfo) == (tree)access_default_virtual);
- tree basetype = TREE_TYPE (TREE_VALUE (binfo));
+ = (TREE_PURPOSE (binfo) == access_private_virtual_node
+ || TREE_PURPOSE (binfo) == access_public_virtual_node
+ || TREE_PURPOSE (binfo) == access_default_virtual_node);
+ tree basetype = TREE_VALUE (binfo);
tree base_binfo;
GNU_xref_hier (IDENTIFIER_POINTER (name),
/* 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. */
{
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));
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 ();
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
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;
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");
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);
(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
}
+/* 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.
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
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);
}
}
+ 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);
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
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
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
last = tree_cons (NULL_TREE, NULL_TREE, current_base_init_list);
for (x = TREE_CHAIN (last); x; x = TREE_CHAIN (x))
{
- tree basename = TREE_PURPOSE (x);
+ tree basetype = TREE_PURPOSE (x);
tree binfo;
- if (basename == NULL_TREE)
+ if (basetype == NULL_TREE)
{
/* Initializer for single base class. Must not
use multiple inheritance or this is ambiguous. */
}
binfo = TREE_VEC_ELT (binfos, 0);
}
- else if (is_aggr_typedef (basename, 1))
+ else if (is_aggr_type (basetype, 1))
{
- binfo = binfo_or_else (IDENTIFIER_TYPE_VALUE (basename), t);
+ binfo = binfo_or_else (basetype, t);
if (binfo == NULL_TREE)
continue;
if (i < 0)
{
cp_error ("`%T' is not an immediate base class of `%T'",
- IDENTIFIER_TYPE_VALUE (basename),
- current_class_type);
+ basetype, current_class_type);
continue;
}
}
type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
+ if (TREE_CODE_CLASS (TREE_CODE (name)) == 't')
+ {
+ basetype = name;
+ name = TYPE_IDENTIFIER (name);
+ }
+
if (name == NULL_TREE && IS_AGGR_TYPE (type))
switch (CLASSTYPE_N_BASECLASSES (type))
{
if (init == void_type_node)
init = NULL_TREE;
- if (name == NULL_TREE || IDENTIFIER_HAS_TYPE_VALUE (name))
+ if (name == NULL_TREE || basetype)
{
tree base_init;
}
else
{
- basetype = IDENTIFIER_TYPE_VALUE (name);
if (basetype != type
&& ! binfo_member (basetype, TYPE_BINFO (type))
&& ! binfo_member (basetype, CLASSTYPE_VBASECLASSES (type)))
if (IDENTIFIER_CLASS_VALUE (name))
goto try_member;
if (TYPE_USES_VIRTUAL_BASECLASSES (type))
- error ("type `%s' is not an immediate or virtual basetype for `%s'",
- IDENTIFIER_POINTER (name),
- TYPE_NAME_STRING (type));
+ cp_error ("type `%T' is not an immediate or virtual basetype for `%T'",
+ basetype, type);
else
- error ("type `%s' is not an immediate basetype for `%s'",
- IDENTIFIER_POINTER (name),
- TYPE_NAME_STRING (type));
+ cp_error ("type `%T' is not an immediate basetype for `%T'",
+ basetype, type);
return;
}
}
- if (purpose_member (name, current_base_init_list))
+ if (purpose_member (basetype, current_base_init_list))
{
- error ("base class `%s' already initialized",
- IDENTIFIER_POINTER (name));
+ cp_error ("base class `%T' already initialized", basetype);
return;
}
if (warn_reorder && current_member_init_list)
{
- warning ("base initializer for `%s'", IDENTIFIER_POINTER (name));
+ cp_warning ("base initializer for `%T'", basetype);
warning (" will be re-ordered to precede member initializations");
}
- base_init = build_tree_list (name, init);
- TREE_TYPE (base_init) = basetype;
+ base_init = build_tree_list (basetype, init);
current_base_init_list = chainon (current_base_init_list, base_init);
}
else
if (purpose_member (name, current_member_init_list))
{
- error ("field `%s' already initialized", IDENTIFIER_POINTER (name));
+ cp_error ("field `%D' already initialized", field);
return;
}
member_init = build_tree_list (name, init);
- TREE_TYPE (member_init) = TREE_TYPE (field);
current_member_init_list = chainon (current_member_init_list, member_init);
}
return;
return 1;
}
+/* Report an error if TYPE is not a user-defined, aggregate type. If
+ OR_ELSE is nonzero, give an error message. */
+int
+is_aggr_type (type, or_else)
+ tree type;
+ int or_else;
+{
+ if (type == error_mark_node)
+ return 0;
+
+ if (! IS_AGGR_TYPE (type)
+ && TREE_CODE (type) != TEMPLATE_TYPE_PARM)
+ {
+ if (or_else)
+ cp_error ("`%T' is not an aggregate type", type);
+ return 0;
+ }
+ return 1;
+}
+
/* Like is_aggr_typedef, but returns typedef if successful. */
tree
get_aggr_from_typedef (name, or_else)
/* This code could just as well go in `class.c', but is placed here for
modularity. */
-/* For an expression of the form CNAME :: NAME (PARMLIST), build
+/* For an expression of the form TYPE :: NAME (PARMLIST), build
the appropriate function call. */
tree
-build_member_call (cname, name, parmlist)
- tree cname, name, parmlist;
+build_member_call (type, name, parmlist)
+ tree type, name, parmlist;
{
- tree type, t;
+ tree t;
tree method_name = name;
int dtor = 0;
int dont_use_this = 0;
dtor = 1;
}
- if (TREE_CODE (cname) == SCOPE_REF)
- cname = resolve_scope_to_name (NULL_TREE, cname);
-
/* This shouldn't be here, and build_member_call shouldn't appear in
parse.y! (mrs) */
- if (cname && get_aggr_from_typedef (cname, 0) == 0
- && TREE_CODE (cname) == IDENTIFIER_NODE)
+ if (type && TREE_CODE (type) == IDENTIFIER_NODE
+ && get_aggr_from_typedef (type, 0) == 0)
{
- tree ns = lookup_name (cname, 0);
+ tree ns = lookup_name (type, 0);
if (ns && TREE_CODE (ns) == NAMESPACE_DECL)
{
- return build_x_function_call (build_offset_ref (cname, name), parmlist, current_class_decl);
+ return build_x_function_call (build_offset_ref (type, name), parmlist, current_class_decl);
}
}
- if (cname == NULL_TREE || ! (type = get_aggr_from_typedef (cname, 1)))
+ if (type == NULL_TREE || ! is_aggr_type (type, 1))
return error_mark_node;
/* An operator we did not like. */
/* Build a reference to a member of an aggregate. This is not a
C++ `&', but really something which can have its address taken,
- and then act as a pointer to member, for example CNAME :: FIELD
- can have its address taken by saying & CNAME :: FIELD.
+ and then act as a pointer to member, for example TYPE :: FIELD
+ can have its address taken by saying & TYPE :: FIELD.
@@ Prints out lousy diagnostics for operator <typename>
@@ fields.
@@ This function should be rewritten and placed in search.c. */
tree
-build_offset_ref (cname, name)
- tree cname, name;
+build_offset_ref (type, name)
+ tree type, name;
{
- tree decl, type, fnfields, fields, t = error_mark_node;
+ tree decl, fnfields, fields, t = error_mark_node;
tree basetypes = NULL_TREE;
int dtor = 0;
- if (TREE_CODE (cname) == SCOPE_REF)
- cname = resolve_scope_to_name (NULL_TREE, cname);
-
/* Handle namespace names fully here. */
- if (TREE_CODE (cname) == IDENTIFIER_NODE
- && get_aggr_from_typedef (cname, 0) == 0)
+ if (TREE_CODE (type) == IDENTIFIER_NODE
+ && get_aggr_from_typedef (type, 0) == 0)
{
- tree ns = lookup_name (cname, 0);
+ tree ns = lookup_name (type, 0);
tree val;
if (ns && TREE_CODE (ns) == NAMESPACE_DECL)
{
}
}
- if (cname == NULL_TREE || ! is_aggr_typedef (cname, 1))
+ if (type == NULL_TREE || ! is_aggr_type (type, 1))
return error_mark_node;
- type = IDENTIFIER_TYPE_VALUE (cname);
-
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
dtor = 1;
name = TREE_OPERAND (name, 0);
}
+ if (name == constructor_name_full (type))
+ name = constructor_name (type);
+
if (TYPE_SIZE (type) == 0)
{
t = IDENTIFIER_CLASS_VALUE (name);
return error_mark_node;
}
-#if 0
- if (TREE_CODE (name) == TYPE_EXPR)
- /* Pass a TYPE_DECL to build_component_type_expr. */
- return build_component_type_expr (TYPE_NAME (TREE_TYPE (cname)),
- name, NULL_TREE, 1);
-#endif
-
if (current_class_type == 0
|| get_base_distance (type, current_class_type, 0, &basetypes) == -1)
{
basetypes = TYPE_BINFO (type);
- decl = build1 (NOP_EXPR,
- IDENTIFIER_TYPE_VALUE (cname),
- error_mark_node);
+ decl = build1 (NOP_EXPR, type, error_mark_node);
}
else if (current_class_decl == 0)
- decl = build1 (NOP_EXPR, IDENTIFIER_TYPE_VALUE (cname),
- error_mark_node);
+ decl = build1 (NOP_EXPR, type, error_mark_node);
else
decl = C_C_D;
if (DECL_CHAIN (t) == NULL_TREE || dtor)
{
- enum access_type access;
+ tree access;
/* unique functions are handled easily. */
unique:
access = compute_access (basetypes, t);
- if (access == access_protected)
+ if (access == access_protected_node)
{
cp_error_at ("member function `%#D' is protected", t);
error ("in this context");
return error_mark_node;
}
- if (access == access_private)
+ if (access == access_private_node)
{
cp_error_at ("member function `%#D' is private", t);
error ("in this context");
}
/* overloaded functions may need more work. */
- if (cname == name)
+ if (name == constructor_name (type))
{
if (TYPE_HAS_DESTRUCTOR (type)
&& DECL_CHAIN (DECL_CHAIN (t)) == NULL_TREE)
}
/* static class functions too. */
- if (TREE_CODE (t) == FUNCTION_DECL && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
+ if (TREE_CODE (t) == FUNCTION_DECL
+ && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
my_friendly_abort (53);
- /* In member functions, the form `cname::name' is no longer
- equivalent to `this->cname::name'. */
+ /* In member functions, the form `type::name' is no longer
+ equivalent to `this->type::name', at least not until
+ resolve_offset_ref. */
return build (OFFSET_REF, build_offset_type (type, TREE_TYPE (t)), decl, t);
}
|| (TREE_CODE (base) == NOP_EXPR
&& TREE_OPERAND (base, 0) == error_mark_node)))
{
- tree basetype_path;
- enum access_type access;
+ tree basetype_path, access;
if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
basetype = TYPE_OFFSET_BASETYPE (type);
}
addr = convert_pointer_to (basetype, base);
access = compute_access (basetype_path, member);
- if (access == access_public)
+ if (access == access_public_node)
return build (COMPONENT_REF, TREE_TYPE (member),
build_indirect_ref (addr, NULL_PTR), member);
- if (access == access_protected)
+ if (access == access_protected_node)
{
cp_error_at ("member `%D' is protected", member);
error ("in this context");
return error_mark_node;
}
- if (access == access_private)
+ if (access == access_private_node)
{
cp_error_at ("member `%D' is private", member);
error ("in this context");
if (flags & LOOKUP_PROTECT)
{
- enum access_type access = compute_access (basetypes, dtor);
+ tree access = compute_access (basetypes, dtor);
- if (access == access_private)
+ if (access == access_private_node)
{
if (flags & LOOKUP_COMPLAIN)
cp_error ("destructor for type `%T' is private in this scope", type);
return error_mark_node;
}
- else if (access == access_protected)
+ else if (access == access_protected_node)
{
if (flags & LOOKUP_COMPLAIN)
cp_error ("destructor for type `%T' is protected in this scope", type);
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'. */
}
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);
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,
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)
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",
(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);
}
(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))
(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);
}
/* 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
%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
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 ')'
{
| 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,
| 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,
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)))
{
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))
{
$$ = 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)))
{
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))
{
$$ = NULL_TREE;
}
else
- $$ = build_tree_list ((tree) $$, $3);
+ $$ = build_tree_list ($$, $3);
}
;
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
{
if (IS_AGGR_TYPE (groktypename ($3)))
{
sorry ("`sigof' as base signature specifier");
- /* need to return some dummy signature identifier */
- $$ = $3;
+ $$ = groktypename ($3);
}
else
{
| 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: '{'
| 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));
}
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:
| 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;
}
}
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
{
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);
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
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;
|| (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. */
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 ();
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);
member = purpose_member (type, DECL_ACCESS (field));
if (member)
{
- access = (enum access_type) TREE_VALUE (member);
+ access = TREE_VALUE (member);
break;
}
via_protected = 1;
else if (! TREE_VIA_PUBLIC (types) && ! private_ok)
{
- access = access_private;
+ access = access_private_node;
break;
}
}
/* 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
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,
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'";
}
}
/* 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)));
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";
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;
/* 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);
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),
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. */
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)
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);
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;
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))
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);
}
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;
}
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");
/* 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)
\f
/* 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; };
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);
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))