Commit a28e3c7f by Mike Stump

32nd Cygnus<->FSF merge

From-SVN: r7047
parent 7062b881
...@@ -200,7 +200,7 @@ parse.o : $(srcdir)/parse.c $(CONFIG_H) $(CXX_TREE_H) ../flags.h lex.h ...@@ -200,7 +200,7 @@ parse.o : $(srcdir)/parse.c $(CONFIG_H) $(CXX_TREE_H) ../flags.h lex.h
`echo $(srcdir)/parse.c | sed 's,^\./,,'` `echo $(srcdir)/parse.c | sed 's,^\./,,'`
$(srcdir)/parse.c $(srcdir)/parse.h : $(srcdir)/parse.y $(srcdir)/parse.c $(srcdir)/parse.h : $(srcdir)/parse.y
@echo expect 24 reduce/reduce conflicts. @echo expect 33 reduce/reduce conflicts.
cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o parse.c parse.y cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o parse.c parse.y
cd $(srcdir); grep '^#define[ ]*YYEMPTY' parse.c >>parse.h cd $(srcdir); grep '^#define[ ]*YYEMPTY' parse.c >>parse.h
......
...@@ -2673,10 +2673,7 @@ build_scoped_method_call (exp, scopes, name, parms) ...@@ -2673,10 +2673,7 @@ build_scoped_method_call (exp, scopes, name, parms)
{ {
/* Explicit call to destructor. */ /* Explicit call to destructor. */
name = TREE_OPERAND (name, 0); name = TREE_OPERAND (name, 0);
if (TREE_TYPE (decl) != if (name != constructor_name (TREE_TYPE (decl)))
(IDENTIFIER_CLASS_VALUE (name)
? IDENTIFIER_CLASS_TYPE_VALUE (name)
: IDENTIFIER_TYPE_VALUE (name)))
{ {
cp_error cp_error
("qualified type `%T' does not match destructor type `%T'", ("qualified type `%T' does not match destructor type `%T'",
...@@ -2808,6 +2805,10 @@ build_method_call (instance, name, parms, basetype_path, flags) ...@@ -2808,6 +2805,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
/* If it doesn't work, two argument delete must work */ /* If it doesn't work, two argument delete must work */
TREE_CHAIN (parms) = save_last; TREE_CHAIN (parms) = save_last;
} }
/* We already know whether it's needed or not for vec delete. */
else if (name == ansi_opname[(int) VEC_DELETE_EXPR]
&& ! TYPE_VEC_DELETE_TAKES_SIZE (TREE_TYPE (instance)))
TREE_CHAIN (parms) = NULL_TREE;
if (TREE_CODE (name) == BIT_NOT_EXPR) if (TREE_CODE (name) == BIT_NOT_EXPR)
{ {
......
...@@ -2494,7 +2494,9 @@ finish_struct_methods (t, fn_fields, nonprivate_method) ...@@ -2494,7 +2494,9 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
for (x = *testp; x; x = DECL_CHAIN (x)) for (x = *testp; x; x = DECL_CHAIN (x))
{ {
if (DECL_NAME (fn_fields) == ansi_opname[(int) DELETE_EXPR]) if (DECL_NAME (fn_fields) == ansi_opname[(int) DELETE_EXPR]
|| DECL_NAME (fn_fields)
== ansi_opname[(int) VEC_DELETE_EXPR])
{ {
/* ANSI C++ June 5 1992 WP 12.5.5.1 */ /* ANSI C++ June 5 1992 WP 12.5.5.1 */
cp_error_at ("`%D' overloaded", fn_fields); cp_error_at ("`%D' overloaded", fn_fields);
...@@ -4149,8 +4151,10 @@ finish_struct (t, list_of_fieldlists, warn_anon) ...@@ -4149,8 +4151,10 @@ finish_struct (t, list_of_fieldlists, warn_anon)
else if (flag_dossier && ! CLASSTYPE_DOSSIER (t)) else if (flag_dossier && ! CLASSTYPE_DOSSIER (t))
build_t_desc (t, 1); build_t_desc (t, 1);
#if 0
if (TYPE_NAME (t) && TYPE_IDENTIFIER (t)) if (TYPE_NAME (t) && TYPE_IDENTIFIER (t))
undo_template_name_overload (TYPE_IDENTIFIER (t), 1); undo_template_name_overload (TYPE_IDENTIFIER (t), 1);
#endif
if (current_class_type) if (current_class_type)
popclass (0); popclass (0);
else else
...@@ -4426,10 +4430,7 @@ pushclass (type, modify) ...@@ -4426,10 +4430,7 @@ pushclass (type, modify)
current_function_decl = NULL_TREE; current_function_decl = NULL_TREE;
if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE) if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE)
{ declare_uninstantiated_type_level ();
declare_uninstantiated_type_level ();
overload_template_name (current_class_name, 0);
}
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);
...@@ -4457,6 +4458,9 @@ pushclass (type, modify) ...@@ -4457,6 +4458,9 @@ pushclass (type, modify)
unuse_fields (type); unuse_fields (type);
} }
if (IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (type)))
overload_template_name (current_class_name, 0);
for (tags = CLASSTYPE_TAGS (type); tags; tags = TREE_CHAIN (tags)) for (tags = CLASSTYPE_TAGS (type); tags; tags = TREE_CHAIN (tags))
{ {
TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 1; TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 1;
...@@ -4513,9 +4517,9 @@ popclass (modify) ...@@ -4513,9 +4517,9 @@ popclass (modify)
TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0; TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
tags = TREE_CHAIN (tags); tags = TREE_CHAIN (tags);
} }
if (IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (current_class_type)))
undo_template_name_overload (current_class_name, 0);
} }
if (TREE_CODE (current_class_type) == UNINSTANTIATED_P_TYPE)
undo_template_name_overload (current_class_name, 0);
poplevel_class (); poplevel_class ();
...@@ -4583,7 +4587,12 @@ push_nested_class (type, modify) ...@@ -4583,7 +4587,12 @@ push_nested_class (type, modify)
tree type; tree type;
int modify; int modify;
{ {
tree context = DECL_CONTEXT (TYPE_NAME (type)); tree context;
if (type == error_mark_node || ! IS_AGGR_TYPE (type))
return;
context = DECL_CONTEXT (TYPE_NAME (type));
if (context && TREE_CODE (context) == RECORD_TYPE) if (context && TREE_CODE (context) == RECORD_TYPE)
push_nested_class (context, 2); push_nested_class (context, 2);
......
...@@ -32,6 +32,7 @@ DEFTREECODE (CP_OFFSET_REF, "cp_offset_ref", "r", 2) ...@@ -32,6 +32,7 @@ DEFTREECODE (CP_OFFSET_REF, "cp_offset_ref", "r", 2)
Operand 1 is the value to pass to the destroying function Operand 1 is the value to pass to the destroying function
saying whether the store should be deallocated as well. */ saying whether the store should be deallocated as well. */
DEFTREECODE (DELETE_EXPR, "dl_expr", "e", 2) DEFTREECODE (DELETE_EXPR, "dl_expr", "e", 2)
DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", "e", 2)
/* Value is reference to particular overloaded class method. /* Value is reference to particular overloaded class method.
Operand 0 is the class name (an IDENTIFIER_NODE); Operand 0 is the class name (an IDENTIFIER_NODE);
...@@ -52,6 +53,7 @@ DEFTREECODE (TYPE_EXPR, "type_expr", "e", 1) ...@@ -52,6 +53,7 @@ DEFTREECODE (TYPE_EXPR, "type_expr", "e", 1)
operand 1 is argument list to initialization function, operand 1 is argument list to initialization function,
and operand 2 is the slot which was allocated for this expression. */ and operand 2 is the slot which was allocated for this expression. */
DEFTREECODE (NEW_EXPR, "nw_expr", "e", 3) DEFTREECODE (NEW_EXPR, "nw_expr", "e", 3)
DEFTREECODE (VEC_NEW_EXPR, "vec_nw_expr", "e", 3)
/* Distinguish variables that are only used to identify exceptions /* Distinguish variables that are only used to identify exceptions
that were caught. Only the DECL_NAME (and TREE_CHAIN) that were caught. Only the DECL_NAME (and TREE_CHAIN)
......
...@@ -68,10 +68,6 @@ struct lang_id2 ...@@ -68,10 +68,6 @@ struct lang_id2
#define IDENTIFIER_TYPE_VALUE(NODE) (TREE_TYPE (NODE)) #define IDENTIFIER_TYPE_VALUE(NODE) (TREE_TYPE (NODE))
#define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = TYPE) #define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = TYPE)
#define IDENTIFIER_HAS_TYPE_VALUE(NODE) (TREE_TYPE (NODE) ? 1 : 0) #define IDENTIFIER_HAS_TYPE_VALUE(NODE) (TREE_TYPE (NODE) ? 1 : 0)
#define IDENTIFIER_HAS_CLASS_TYPE_VALUE(NODE) \
(IDENTIFIER_CLASS_VALUE (NODE) && TREE_TYPE (IDENTIFIER_CLASS_VALUE (NODE)))
#define IDENTIFIER_CLASS_TYPE_VALUE(NODE) \
TREE_TYPE (IDENTIFIER_CLASS_VALUE (NODE))
#define LANG_ID_FIELD(NAME,NODE) \ #define LANG_ID_FIELD(NAME,NODE) \
(((struct lang_identifier *)(NODE))->x \ (((struct lang_identifier *)(NODE))->x \
...@@ -325,7 +321,7 @@ enum languages { lang_c, lang_cplusplus }; ...@@ -325,7 +321,7 @@ enum languages { lang_c, lang_cplusplus };
#define TYPE_ASSEMBLER_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE)))) #define TYPE_ASSEMBLER_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE))))
#define IS_AGGR_TYPE(t) (TYPE_LANG_FLAG_5 (t)) #define IS_AGGR_TYPE(t) (TYPE_LANG_FLAG_5 (t))
#define IS_AGGR_TYPE_CODE(t) (t == RECORD_TYPE || t == UNION_TYPE) #define IS_AGGR_TYPE_CODE(t) (t == RECORD_TYPE || t == UNION_TYPE || t == UNINSTANTIATED_P_TYPE)
#define IS_AGGR_TYPE_2(TYPE1,TYPE2) \ #define IS_AGGR_TYPE_2(TYPE1,TYPE2) \
(TREE_CODE (TYPE1) == TREE_CODE (TYPE2) \ (TREE_CODE (TYPE1) == TREE_CODE (TYPE2) \
&& IS_AGGR_TYPE (TYPE1)&IS_AGGR_TYPE (TYPE2)) && IS_AGGR_TYPE (TYPE1)&IS_AGGR_TYPE (TYPE2))
...@@ -395,14 +391,13 @@ struct lang_type ...@@ -395,14 +391,13 @@ struct lang_type
unsigned vtable_needs_writing : 1; unsigned vtable_needs_writing : 1;
unsigned has_assign_ref : 1; unsigned has_assign_ref : 1;
unsigned gets_new : 1; unsigned gets_new : 2;
unsigned gets_placed_new : 1; unsigned gets_delete : 2;
unsigned gets_delete : 1;
unsigned has_call_overloaded : 1; unsigned has_call_overloaded : 1;
unsigned has_array_ref_overloaded : 1; unsigned has_array_ref_overloaded : 1;
unsigned has_arrow_overloaded : 1; unsigned has_arrow_overloaded : 1;
unsigned local_typedecls : 1;
unsigned local_typedecls : 1;
unsigned interface_only : 1; unsigned interface_only : 1;
unsigned interface_unknown : 1; unsigned interface_unknown : 1;
unsigned needs_virtual_reinit : 1; unsigned needs_virtual_reinit : 1;
...@@ -410,16 +405,16 @@ struct lang_type ...@@ -410,16 +405,16 @@ struct lang_type
unsigned declared_class : 1; unsigned declared_class : 1;
unsigned being_defined : 1; unsigned being_defined : 1;
unsigned redefined : 1; unsigned redefined : 1;
unsigned no_globalize : 1;
unsigned no_globalize : 1;
unsigned marked : 1; unsigned marked : 1;
unsigned marked2 : 1; unsigned marked2 : 1;
unsigned marked3 : 1; unsigned marked3 : 1;
unsigned marked4 : 1; unsigned marked4 : 1;
unsigned marked5 : 1; unsigned marked5 : 1;
unsigned marked6 : 1; unsigned marked6 : 1;
unsigned use_template : 2;
unsigned use_template : 2;
unsigned debug_requested : 1; unsigned debug_requested : 1;
unsigned has_method_call_overloaded : 1; unsigned has_method_call_overloaded : 1;
unsigned private_attr : 1; unsigned private_attr : 1;
...@@ -427,8 +422,8 @@ struct lang_type ...@@ -427,8 +422,8 @@ struct lang_type
unsigned ptrmemfunc_flag : 1; unsigned ptrmemfunc_flag : 1;
unsigned is_signature : 1; unsigned is_signature : 1;
unsigned is_signature_pointer : 1; unsigned is_signature_pointer : 1;
unsigned is_signature_reference : 1;
unsigned is_signature_reference : 1;
unsigned has_default_implementation : 1; unsigned has_default_implementation : 1;
unsigned grokking_typedef : 1; unsigned grokking_typedef : 1;
unsigned has_opaque_typedecls : 1; unsigned has_opaque_typedecls : 1;
...@@ -436,15 +431,16 @@ struct lang_type ...@@ -436,15 +431,16 @@ struct lang_type
unsigned was_anonymous : 1; unsigned was_anonymous : 1;
unsigned has_real_assignment : 1; unsigned has_real_assignment : 1;
unsigned has_real_assign_ref : 1; unsigned has_real_assign_ref : 1;
unsigned has_const_init_ref : 1; unsigned has_const_init_ref : 1;
unsigned has_complex_init_ref : 1; unsigned has_complex_init_ref : 1;
unsigned has_complex_assign_ref : 1; unsigned has_complex_assign_ref : 1;
unsigned vec_delete_takes_size : 1;
/* The MIPS compiler gets it wrong if this struct also /* The MIPS compiler gets it wrong if this struct also
does not fill out to a multiple of 4 bytes. Add a does not fill out to a multiple of 4 bytes. Add a
member `dummy' with new bits if you go over the edge. */ member `dummy' with new bits if you go over the edge. */
unsigned dummy : 22; unsigned dummy : 20;
unsigned n_vancestors : 16; unsigned n_vancestors : 16;
} type_flags; } type_flags;
...@@ -519,9 +515,17 @@ struct lang_type ...@@ -519,9 +515,17 @@ struct lang_type
/* Nonzero for _CLASSTYPE means that operator new and delete are defined, /* Nonzero for _CLASSTYPE means that operator new and delete are defined,
respectively. */ respectively. */
#define TREE_GETS_NEW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_new) #define TYPE_GETS_NEW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_new)
#define TREE_GETS_PLACED_NEW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_placed_new) #define TYPE_GETS_DELETE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_delete)
#define TREE_GETS_DELETE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_delete) #define TYPE_GETS_REG_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 1)
/* Nonzero for _CLASSTYPE means that operator vec delete is defined and
takes the optional size_t argument. */
#define TYPE_VEC_DELETE_TAKES_SIZE(NODE) \
(TYPE_LANG_SPECIFIC(NODE)->type_flags.vec_delete_takes_size)
#define TYPE_VEC_NEW_USES_COOKIE(NODE) \
(TYPE_NEEDS_DESTRUCTOR (NODE) \
|| (TYPE_LANG_SPECIFIC (NODE) && TYPE_VEC_DELETE_TAKES_SIZE (NODE)))
/* Nonzero for TREE_LIST or _TYPE node means that this node is class-local. */ /* Nonzero for TREE_LIST or _TYPE node means that this node is class-local. */
#define TREE_NONLOCAL_FLAG(NODE) (TREE_LANG_FLAG_0 (NODE)) #define TREE_NONLOCAL_FLAG(NODE) (TREE_LANG_FLAG_0 (NODE))
...@@ -1972,7 +1976,7 @@ extern tree expand_vec_init PROTO((tree, tree, tree, tree, int)); ...@@ -1972,7 +1976,7 @@ extern tree expand_vec_init PROTO((tree, tree, tree, tree, int));
extern tree build_x_delete PROTO((tree, tree, int, tree)); extern tree build_x_delete PROTO((tree, tree, int, tree));
extern tree build_delete PROTO((tree, tree, tree, int, int)); extern tree build_delete PROTO((tree, tree, tree, int, int));
extern tree build_vbase_delete PROTO((tree, tree)); extern tree build_vbase_delete PROTO((tree, tree));
extern tree build_vec_delete PROTO((tree, tree, tree, tree, tree, tree)); extern tree build_vec_delete PROTO((tree, tree, tree, tree, tree, int));
/* in input.c */ /* in input.c */
...@@ -2081,6 +2085,7 @@ extern int do_pending_expansions PROTO((void)); ...@@ -2081,6 +2085,7 @@ extern int do_pending_expansions PROTO((void));
extern void do_pending_templates PROTO((void)); extern void do_pending_templates PROTO((void));
struct tinst_level *tinst_for_decl PROTO((void)); struct tinst_level *tinst_for_decl PROTO((void));
extern void do_function_instantiation PROTO((tree, tree)); extern void do_function_instantiation PROTO((tree, tree));
extern tree create_nested_upt PROTO((tree, tree));
/* in search.c */ /* in search.c */
extern tree make_memoized_table_entry PROTO((tree, tree, int)); extern tree make_memoized_table_entry PROTO((tree, tree, int));
...@@ -2092,6 +2097,7 @@ extern enum access_type compute_access PROTO((tree, tree)); ...@@ -2092,6 +2097,7 @@ extern enum access_type 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));
extern tree lookup_nested_tag PROTO((tree, tree));
extern HOST_WIDE_INT breadth_first_search PROTO((tree, int (*)(), int (*)())); extern HOST_WIDE_INT breadth_first_search PROTO((tree, int (*)(), int (*)()));
extern int tree_needs_constructor_p PROTO((tree, int)); extern int tree_needs_constructor_p PROTO((tree, int));
extern int tree_has_any_destructor_p PROTO((tree, int)); extern int tree_has_any_destructor_p PROTO((tree, int));
...@@ -2193,6 +2199,7 @@ extern int comp_target_types PROTO((tree, tree, int)); ...@@ -2193,6 +2199,7 @@ extern int comp_target_types PROTO((tree, tree, int));
extern tree common_base_types PROTO((tree, tree)); extern tree common_base_types PROTO((tree, tree));
extern int compparms PROTO((tree, tree, int)); extern int compparms PROTO((tree, tree, int));
extern int comp_target_types PROTO((tree, tree, int)); extern int comp_target_types PROTO((tree, tree, int));
extern int self_promoting_args_p PROTO((tree));
extern tree unsigned_type PROTO((tree)); extern tree unsigned_type PROTO((tree));
extern tree signed_type PROTO((tree)); extern tree signed_type PROTO((tree));
extern tree signed_or_unsigned_type PROTO((int, tree)); extern tree signed_or_unsigned_type PROTO((int, tree));
......
...@@ -720,8 +720,16 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum, ...@@ -720,8 +720,16 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
{ {
/* When casting an lvalue to a reference type, just convert into /* When casting an lvalue to a reference type, just convert into
a pointer to the new type and deference it. This is allowed a pointer to the new type and deference it. This is allowed
by San Diego WP section 5.2.8 paragraph 9, though perhaps it by San Diego WP section 5.2.9 paragraph 12, though perhaps it
should be done directly (jason). (int &)ri ---> *(int*)&ri */ should be done directly (jason). (int &)ri ---> *(int*)&ri */
/* B* bp; A& ar = (A&)bp; is legal, but it's probably not what they
meant. */
if (form == POINTER_TYPE
&& (comptypes (TREE_TYPE (intype), type, strict)))
cp_warning ("casting `%T' to `%T' does not dereference pointer",
intype, reftype);
rval = build_unary_op (ADDR_EXPR, expr, 0); rval = build_unary_op (ADDR_EXPR, expr, 0);
if (rval != error_mark_node) if (rval != error_mark_node)
rval = convert_force (build_pointer_type (TREE_TYPE (reftype)), rval); rval = convert_force (build_pointer_type (TREE_TYPE (reftype)), rval);
...@@ -744,6 +752,7 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum, ...@@ -744,6 +752,7 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
/* Definitely need to go through a constructor here. */ /* Definitely need to go through a constructor here. */
if (TYPE_HAS_CONSTRUCTOR (type) if (TYPE_HAS_CONSTRUCTOR (type)
&& ! CLASSTYPE_ABSTRACT_VIRTUALS (type)
&& (rval = build_method_call && (rval = build_method_call
(NULL_TREE, constructor_name_full (type), (NULL_TREE, constructor_name_full (type),
build_tree_list (NULL_TREE, expr), TYPE_BINFO (type), build_tree_list (NULL_TREE, expr), TYPE_BINFO (type),
......
...@@ -1071,6 +1071,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete) ...@@ -1071,6 +1071,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
return error_mark_node; return error_mark_node;
} }
#if 0
/* If the type has no destructor, then we should build a regular /* If the type has no destructor, then we should build a regular
delete, instead of a vector delete. Otherwise, we would end delete, instead of a vector delete. Otherwise, we would end
up passing a bogus offset into __builtin_delete, which is up passing a bogus offset into __builtin_delete, which is
...@@ -1082,15 +1083,15 @@ delete_sanity (exp, size, doing_vec, use_global_delete) ...@@ -1082,15 +1083,15 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
doing_vec = 0; doing_vec = 0;
use_global_delete = 1; use_global_delete = 1;
} }
#endif
if (doing_vec) if (doing_vec)
return build_vec_delete (t, maxindex, elt_size, NULL_TREE, return build_vec_delete (t, maxindex, elt_size, integer_one_node,
integer_one_node, integer_two_node); integer_two_node, use_global_delete);
else else
return build_delete (type, t, integer_three_node, return build_delete (type, t, integer_three_node,
LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE, LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE,
use_global_delete use_global_delete);
|| TYPE_HAS_DESTRUCTOR (TREE_TYPE (type)));
} }
/* Sanity check: report error if this function FUNCTION is not /* Sanity check: report error if this function FUNCTION is not
...@@ -1456,6 +1457,7 @@ grokbitfield (declarator, declspecs, width) ...@@ -1456,6 +1457,7 @@ grokbitfield (declarator, declspecs, width)
return value; return value;
} }
#if 0
/* Like GROKFIELD, except that the declarator has been /* Like GROKFIELD, except that the declarator has been
buried in DECLSPECS. Find the declarator, and buried in DECLSPECS. Find the declarator, and
return something that looks like it came from return something that looks like it came from
...@@ -1634,6 +1636,7 @@ groktypefield (declspecs, parmlist) ...@@ -1634,6 +1636,7 @@ groktypefield (declspecs, parmlist)
DECL_IN_AGGR_P (decl) = 1; DECL_IN_AGGR_P (decl) = 1;
return decl; return decl;
} }
#endif
tree tree
grokoptypename (declspecs, declarator) grokoptypename (declspecs, declarator)
...@@ -2278,7 +2281,7 @@ coerce_delete_type (type) ...@@ -2278,7 +2281,7 @@ coerce_delete_type (type)
else if (e3 |= e2) else if (e3 |= e2)
{ {
if (arg_types == NULL_TREE) if (arg_types == NULL_TREE)
arg_types = void_list_node; arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
else else
arg_types = tree_cons (NULL_TREE, ptr_type_node, TREE_CHAIN (arg_types)); arg_types = tree_cons (NULL_TREE, ptr_type_node, TREE_CHAIN (arg_types));
} }
...@@ -2853,7 +2856,11 @@ reparse_decl_as_expr1 (decl) ...@@ -2853,7 +2856,11 @@ reparse_decl_as_expr1 (decl)
case BIT_NOT_EXPR: case BIT_NOT_EXPR:
return build_x_unary_op (BIT_NOT_EXPR, return build_x_unary_op (BIT_NOT_EXPR,
reparse_decl_as_expr1 (TREE_OPERAND (decl, 0))); reparse_decl_as_expr1 (TREE_OPERAND (decl, 0)));
case SCOPE_REF:
return build_offset_ref (TREE_OPERAND (decl, 0), TREE_OPERAND (decl, 1));
case ARRAY_REF:
return grok_array_decl (reparse_decl_as_expr1 (TREE_OPERAND (decl, 0)),
TREE_OPERAND (decl, 1));
default: default:
my_friendly_abort (5); my_friendly_abort (5);
return NULL_TREE; return NULL_TREE;
...@@ -2901,6 +2908,9 @@ finish_decl_parsing (decl) ...@@ -2901,6 +2908,9 @@ finish_decl_parsing (decl)
push_nested_class (TREE_OPERAND (decl, 0), 3); push_nested_class (TREE_OPERAND (decl, 0), 3);
TREE_COMPLEXITY (decl) = current_class_depth; TREE_COMPLEXITY (decl) = current_class_depth;
return decl; return decl;
case ARRAY_REF:
TREE_OPERAND (decl, 0) = finish_decl_parsing (TREE_OPERAND (decl, 0));
return decl;
default: default:
my_friendly_abort (5); my_friendly_abort (5);
return NULL_TREE; return NULL_TREE;
......
...@@ -1059,17 +1059,18 @@ It is ambiguous whether @code{class T} should be parsed as the ...@@ -1059,17 +1059,18 @@ It is ambiguous whether @code{class T} should be parsed as the
declaration of a template type parameter named @code{T} or an unnamed declaration of a template type parameter named @code{T} or an unnamed
constant parameter of type @code{class T}. Section 14.6, paragraph 3 of constant parameter of type @code{class T}. Section 14.6, paragraph 3 of
the January '94 working paper states that the first interpretation is the January '94 working paper states that the first interpretation is
the correct one. This ambiguity results in four reduce/reduce conflicts. the correct one. This ambiguity results in two reduce/reduce conflicts.
2) Between @code{primary} and @code{typename} for code like @samp{int()} 2) Between @code{primary} and @code{type_id} for code like @samp{int()}
in places where both can be accepted, such as the argument to in places where both can be accepted, such as the argument to
@code{sizeof}. Section 8.1 of the pre-San Diego working paper specifies @code{sizeof}. Section 8.1 of the pre-San Diego working paper specifies
that these ambiguous constructs will be interpreted as @code{typename}s. that these ambiguous constructs will be interpreted as @code{typename}s.
This ambiguity results in six reduce/reduce conflicts. This ambiguity results in six reduce/reduce conflicts between
@samp{absdcl} and @samp{functional_cast}.
3) Between @code{primary}/@code{functional_cast} and 3) Between @code{functional_cast} and
@code{expr_or_declarator}/@code{complex_direct_notype_declarator}, for @code{complex_direct_notype_declarator}, for various token strings.
various token strings. This situation occurs in code looking like This situation occurs in code looking like
@example @example
int (*a); int (*a);
...@@ -1078,11 +1079,23 @@ int (*a); ...@@ -1078,11 +1079,23 @@ int (*a);
This code is ambiguous; it could be a declaration of the variable This code is ambiguous; it could be a declaration of the variable
@samp{a} as a pointer to @samp{int}, or it could be a functional cast of @samp{a} as a pointer to @samp{int}, or it could be a functional cast of
@samp{*a} to @samp{int}. Section 6.8 specifies that the former @samp{*a} to @samp{int}. Section 6.8 specifies that the former
interpretation is correct. This ambiguity results in 12 reduce/reduce interpretation is correct. This ambiguity results in 7 reduce/reduce
conflicts. Ack. conflicts. Another aspect of this ambiguity is code like 'int (x[2]);',
which is resolved at the '[' and accounts for 6 reduce/reduce conflicts
4) Between @code{after_type_declarator} and @code{parm}, for the token between @samp{direct_notype_declarator} and
@code{TYPENAME}. This occurs in (as one example) code like @samp{primary}/@samp{overqualified_id}. Finally, there are 4 r/r
conflicts between @samp{expr_or_declarator} and @samp{primary} over code
like 'int (a);', which could probably be resolved but would also
probably be more trouble than it's worth. In all, this situation
accounts for 17 conflicts. Ack!
The second case above is responsible for the failure to parse 'LinppFile
ppfile (String (argv[1]), &outs, argc, argv);' (from Rogue Wave
Math.h++) as an object declaration, and must be fixed so that it does
not resolve until later.
4) Indirectly between @code{after_type_declarator} and @code{parm}, for
type names. This occurs in (as one example) code like
@example @example
typedef int foo, bar; typedef int foo, bar;
...@@ -1093,11 +1106,12 @@ class A @{ ...@@ -1093,11 +1106,12 @@ class A @{
What is @code{bar} inside the class definition? We currently interpret What is @code{bar} inside the class definition? We currently interpret
it as a @code{parm}, as does Cfront, but IBM xlC interprets it as an it as a @code{parm}, as does Cfront, but IBM xlC interprets it as an
@code{after_type_declarator}. I suspect that xlC is correct, in light @code{after_type_declarator}. I believe that xlC is correct, in light
of 7.1p2, which says "The longest sequence of @i{decl-specifiers} that of 7.1p2, which says "The longest sequence of @i{decl-specifiers} that
could possibly be a type name is taken as the @i{decl-specifier-seq} of could possibly be a type name is taken as the @i{decl-specifier-seq} of
a @i{declaration}." However, it seems clear that this rule must be a @i{declaration}." However, it seems clear that this rule must be
violated in the case of constructors, so... violated in the case of constructors. This ambiguity accounts for 8
conflicts.
Unlike the others, this ambiguity is not recognized by the Working Paper. Unlike the others, this ambiguity is not recognized by the Working Paper.
......
...@@ -542,6 +542,10 @@ init_lex () ...@@ -542,6 +542,10 @@ init_lex ()
IDENTIFIER_OPNAME_P (ansi_opname[(int) NEW_EXPR]) = 1; IDENTIFIER_OPNAME_P (ansi_opname[(int) NEW_EXPR]) = 1;
ansi_opname[(int) DELETE_EXPR] = get_identifier ("__dl"); ansi_opname[(int) DELETE_EXPR] = get_identifier ("__dl");
IDENTIFIER_OPNAME_P (ansi_opname[(int) DELETE_EXPR]) = 1; IDENTIFIER_OPNAME_P (ansi_opname[(int) DELETE_EXPR]) = 1;
ansi_opname[(int) VEC_NEW_EXPR] = get_identifier ("__vn");
IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_NEW_EXPR]) = 1;
ansi_opname[(int) VEC_DELETE_EXPR] = get_identifier ("__vd");
IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_DELETE_EXPR]) = 1;
ansi_opname[(int) TYPE_EXPR] = get_identifier ("__op"); ansi_opname[(int) TYPE_EXPR] = get_identifier ("__op");
IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1; IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1;
...@@ -681,6 +685,8 @@ init_lex () ...@@ -681,6 +685,8 @@ init_lex ()
opname_tab[(int) MODIFY_EXPR] = "="; opname_tab[(int) MODIFY_EXPR] = "=";
opname_tab[(int) NEW_EXPR] = "new"; opname_tab[(int) NEW_EXPR] = "new";
opname_tab[(int) DELETE_EXPR] = "delete"; opname_tab[(int) DELETE_EXPR] = "delete";
opname_tab[(int) VEC_NEW_EXPR] = "new []";
opname_tab[(int) VEC_DELETE_EXPR] = "delete []";
opname_tab[(int) COND_EXPR] = "... ? ... : ..."; opname_tab[(int) COND_EXPR] = "... ? ... : ...";
opname_tab[(int) CALL_EXPR] = "()"; opname_tab[(int) CALL_EXPR] = "()";
opname_tab[(int) PLUS_EXPR] = "+"; opname_tab[(int) PLUS_EXPR] = "+";
...@@ -841,10 +847,7 @@ yyprint (file, yychar, yylval) ...@@ -841,10 +847,7 @@ yyprint (file, yychar, yylval)
case IDENTIFIER_DEFN: case IDENTIFIER_DEFN:
case TYPENAME_DEFN: case TYPENAME_DEFN:
case PTYPENAME_DEFN: case PTYPENAME_DEFN:
case TYPENAME_COLON:
case TYPENAME_ELLIPSIS: case TYPENAME_ELLIPSIS:
case SCOPED_TYPENAME:
case SCOPED_NAME:
case SCSPEC: case SCSPEC:
case PRE_PARSED_CLASS_DECL: case PRE_PARSED_CLASS_DECL:
t = yylval.ttype; t = yylval.ttype;
...@@ -2324,14 +2327,15 @@ check_newline () ...@@ -2324,14 +2327,15 @@ check_newline ()
register int c; register int c;
register int token; register int token;
lineno++; /* Read first nonwhite char on the line. Do this before incrementing the
line number, in case we're at the end of saved text. */
/* Read first nonwhite char on the line. */
do do
c = getch (); c = getch ();
while (c == ' ' || c == '\t'); while (c == ' ' || c == '\t');
lineno++;
if (c != '#') if (c != '#')
{ {
/* If not #, return it so caller will use it. */ /* If not #, return it so caller will use it. */
...@@ -3080,12 +3084,13 @@ readescape (ignore_ptr) ...@@ -3080,12 +3084,13 @@ readescape (ignore_ptr)
return c; return c;
} }
/* Value is 1 if we should try to make the next identifier look like a /* Value is 1 (or 2) if we should try to make the next identifier look like
typename (when it may be a local variable or a class variable). a typename (when it may be a local variable or a class variable).
Value is 0 if we treat this name in a default fashion. Value is 0 if we treat this name in a default fashion. */
Value is -1 if we must not see a type name. */
int looking_for_typename = 0; int looking_for_typename = 0;
#if 0
/* NO LONGER USED: Value is -1 if we must not see a type name. */
void void
dont_see_typename () dont_see_typename ()
{ {
...@@ -3096,6 +3101,7 @@ dont_see_typename () ...@@ -3096,6 +3101,7 @@ dont_see_typename ()
lastiddecl = 0; lastiddecl = 0;
} }
} }
#endif
#ifdef __GNUC__ #ifdef __GNUC__
extern __inline int identifier_type (); extern __inline int identifier_type ();
...@@ -3119,7 +3125,7 @@ see_typename () ...@@ -3119,7 +3125,7 @@ see_typename ()
looking_for_typename = 0; looking_for_typename = 0;
if (yychar == IDENTIFIER) if (yychar == IDENTIFIER)
{ {
lastiddecl = lookup_name (yylval.ttype, -1); lastiddecl = lookup_name (yylval.ttype, -2);
if (lastiddecl == 0) if (lastiddecl == 0)
{ {
if (flag_labels_ok) if (flag_labels_ok)
...@@ -3540,7 +3546,6 @@ real_yylex () ...@@ -3540,7 +3546,6 @@ real_yylex ()
} }
if (value == NEW && ! global_bindings_p ()) if (value == NEW && ! global_bindings_p ())
{ {
looking_for_typename = 1;
value = NEW; value = NEW;
goto done; goto done;
} }
......
...@@ -114,6 +114,9 @@ extern char *token_buffer; /* Pointer to token buffer. */ ...@@ -114,6 +114,9 @@ extern char *token_buffer; /* Pointer to token buffer. */
/* Back-door communication channel to the lexer. */ /* Back-door communication channel to the lexer. */
extern int looking_for_typename; extern int looking_for_typename;
/* Tell the lexer where to look for names. */
extern tree got_scope;
/* Pending language change. /* Pending language change.
Positive is push count, negative is pop count. */ Positive is push count, negative is pop count. */
extern int pending_lang_change; extern int pending_lang_change;
......
...@@ -840,27 +840,22 @@ build_decl_overload (dname, parms, for_method) ...@@ -840,27 +840,22 @@ build_decl_overload (dname, parms, for_method)
{ {
char *name = IDENTIFIER_POINTER (dname); char *name = IDENTIFIER_POINTER (dname);
if (dname == ansi_opname[(int) NEW_EXPR] /* member operators new and delete look like methods at this point. */
&& parms != NULL_TREE if (! for_method && parms != NULL_TREE && TREE_CODE (parms) == TREE_LIST)
&& TREE_CODE (parms) == TREE_LIST {
&& TREE_VALUE (parms) == sizetype if (TREE_VALUE (parms) == sizetype
&& TREE_CHAIN (parms) == void_list_node) && TREE_CHAIN (parms) == void_list_node)
return get_identifier ("__builtin_new"); {
else if (dname == ansi_opname[(int) DELETE_EXPR] if (dname == ansi_opname[(int) NEW_EXPR])
&& parms != NULL_TREE return get_identifier ("__builtin_new");
&& TREE_CODE (parms) == TREE_LIST else if (dname == ansi_opname[(int) VEC_NEW_EXPR])
&& TREE_VALUE (parms) == ptr_type_node return get_identifier ("__builtin_vec_new");
&& TREE_CHAIN (parms) == void_list_node) }
return get_identifier ("__builtin_delete"); else if (dname == ansi_opname[(int) DELETE_EXPR])
else if (dname == ansi_opname[(int) DELETE_EXPR] return get_identifier ("__builtin_delete");
&& parms != NULL_TREE else if (dname == ansi_opname[(int) VEC_DELETE_EXPR])
&& TREE_CODE (parms) == TREE_LIST return get_identifier ("__builtin_vec_delete");
&& TREE_VALUE (parms) == ptr_type_node }
&& TREE_CHAIN (parms) != NULL_TREE
&& TREE_CODE (TREE_CHAIN (parms)) == TREE_LIST
&& TREE_VALUE (TREE_CHAIN (parms)) == sizetype
&& TREE_CHAIN (TREE_CHAIN (parms)) == void_list_node)
return get_identifier ("__builtin_delete");
OB_INIT (); OB_INIT ();
if (for_method != 2) if (for_method != 2)
...@@ -1112,19 +1107,19 @@ build_opfncall (code, flags, xarg1, xarg2, arg3) ...@@ -1112,19 +1107,19 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
try_second = 0; try_second = 0;
break; break;
case VEC_NEW_EXPR:
case NEW_EXPR: case NEW_EXPR:
{ {
fnname = ansi_opname[(int) NEW_EXPR]; tree args = tree_cons (NULL_TREE, xarg2, arg3);
fnname = ansi_opname[(int) code];
if (flags & LOOKUP_GLOBAL) if (flags & LOOKUP_GLOBAL)
return build_overload_call (fnname, tree_cons (NULL_TREE, xarg2, arg3), return build_overload_call (fnname, args, flags & LOOKUP_COMPLAIN,
flags & LOOKUP_COMPLAIN,
(struct candidate *)0); (struct candidate *)0);
rval = build_method_call rval = build_method_call
(build_indirect_ref (build1 (NOP_EXPR, xarg1, error_mark_node), (build_indirect_ref (build1 (NOP_EXPR, xarg1, error_mark_node),
"new"), "new"),
fnname, tree_cons (NULL_TREE, xarg2, arg3), fnname, args, NULL_TREE, flags);
NULL_TREE, flags);
if (rval == error_mark_node) if (rval == error_mark_node)
/* User might declare fancy operator new, but invoke it /* User might declare fancy operator new, but invoke it
like standard one. */ like standard one. */
...@@ -1136,13 +1131,13 @@ build_opfncall (code, flags, xarg1, xarg2, arg3) ...@@ -1136,13 +1131,13 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
} }
break; break;
case VEC_DELETE_EXPR:
case DELETE_EXPR: case DELETE_EXPR:
{ {
fnname = ansi_opname[(int) DELETE_EXPR]; fnname = ansi_opname[(int) code];
if (flags & LOOKUP_GLOBAL) if (flags & LOOKUP_GLOBAL)
return build_overload_call (fnname, return build_overload_call (fnname,
tree_cons (NULL_TREE, xarg1, build_tree_list (NULL_TREE, xarg1),
build_tree_list (NULL_TREE, xarg2)),
flags & LOOKUP_COMPLAIN, flags & LOOKUP_COMPLAIN,
(struct candidate *)0); (struct candidate *)0);
...@@ -1151,7 +1146,7 @@ build_opfncall (code, flags, xarg1, xarg2, arg3) ...@@ -1151,7 +1146,7 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
error_mark_node), error_mark_node),
NULL_PTR), NULL_PTR),
fnname, tree_cons (NULL_TREE, xarg1, fnname, tree_cons (NULL_TREE, xarg1,
build_tree_list (NULL_TREE, xarg2)), build_tree_list (NULL_TREE, xarg2)),
NULL_TREE, flags); NULL_TREE, flags);
/* This happens when the user mis-declares `operator delete'. /* This happens when the user mis-declares `operator delete'.
Should now be impossible. */ Should now be impossible. */
......
...@@ -1690,6 +1690,7 @@ instantiate_template (tmpl, targ_ptr) ...@@ -1690,6 +1690,7 @@ instantiate_template (tmpl, targ_ptr)
return fndecl; return fndecl;
} }
/* classlevel should now never be true. jason 4/12/94 */
void void
undo_template_name_overload (id, classlevel) undo_template_name_overload (id, classlevel)
tree id; tree id;
...@@ -1711,6 +1712,7 @@ undo_template_name_overload (id, classlevel) ...@@ -1711,6 +1712,7 @@ undo_template_name_overload (id, classlevel)
#endif #endif
} }
/* classlevel should now never be true. jason 4/12/94 */
void void
overload_template_name (id, classlevel) overload_template_name (id, classlevel)
tree id; tree id;
...@@ -1731,12 +1733,9 @@ overload_template_name (id, classlevel) ...@@ -1731,12 +1733,9 @@ overload_template_name (id, classlevel)
#if 1 /* XXX */ #if 1 /* XXX */
/* This was a botch... names of templates do not get their own private /* This was a botch... names of templates do not get their own private
scopes. Rather, the names of generated template instances should scopes. Rather, they should go into the binding level already created
just get pushed into whatever scope we happen to be in at the moment. by push_template_decls. Except that there isn't one of those for
This will typically (but not always) be the global scope. (Maybe specializations. */
what we really want to do here is a `push_to_toplevel' and then stay
there while we are generating the instance; popping back out to the
current scope when we are done generating the instance.) */
if (!classlevel) if (!classlevel)
{ {
pushlevel (1); pushlevel (1);
...@@ -1765,20 +1764,13 @@ overload_template_name (id, classlevel) ...@@ -1765,20 +1764,13 @@ overload_template_name (id, classlevel)
if (classlevel) if (classlevel)
pushdecl_class_level (decl); pushdecl_class_level (decl);
else else
#if 0 /* not yet, should get fixed properly later */
pushdecl (decl); pushdecl (decl);
pushlevel (1);
#else
{
pushdecl (decl);
/* @@ Is this necessary now? */
IDENTIFIER_LOCAL_VALUE (template) = decl;
}
#endif
#if 0 /* This seems bogus to me; if it isn't, explain why. (jason) */
/* Fake this for now, just to make dwarfout.c happy. It will have to /* Fake this for now, just to make dwarfout.c happy. It will have to
be done in a proper way later on. */ be done in a proper way later on. */
DECL_CONTEXT (decl) = t; DECL_CONTEXT (decl) = t;
#endif
} }
/* NAME is the IDENTIFIER value of a PRE_PARSED_CLASS_DECL. */ /* NAME is the IDENTIFIER value of a PRE_PARSED_CLASS_DECL. */
...@@ -2028,6 +2020,22 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts) ...@@ -2028,6 +2020,22 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
return 0; return 0;
else if (targs[idx]) else if (targs[idx])
{ {
tree t = targs[idx];
if (TREE_CODE (t) == TREE_CODE (arg))
switch (TREE_CODE (arg))
{
case INTEGER_CST:
if (tree_int_cst_equal (t, arg))
return 0;
break;
case REAL_CST:
if (REAL_VALUES_EQUAL (TREE_REAL_CST (t), TREE_REAL_CST (arg)))
return 0;
break;
/* STRING_CST values are not valid template const parms. */
default:
;
}
my_friendly_abort (87); my_friendly_abort (87);
return 1; return 1;
} }
...@@ -2306,3 +2314,18 @@ do_function_instantiation (declspecs, declarator) ...@@ -2306,3 +2314,18 @@ do_function_instantiation (declspecs, declarator)
if (!result) if (!result)
cp_error ("no matching template for `%D' found", decl); cp_error ("no matching template for `%D' found", decl);
} }
tree
create_nested_upt (scope, name)
tree scope, name;
{
tree t = make_lang_type (UNINSTANTIATED_P_TYPE);
tree d = build_lang_decl (TYPE_DECL, name, t);
TYPE_NAME (t) = d;
TYPE_VALUES (t) = TYPE_VALUES (scope);
TYPE_CONTEXT (t) = scope;
pushdecl (d);
return d;
}
...@@ -108,10 +108,14 @@ print_lang_type (file, node, indent) ...@@ -108,10 +108,14 @@ print_lang_type (file, node, indent)
else else
fputs (" X(X&)", file); fputs (" X(X&)", file);
} }
if (TREE_GETS_NEW (node)) if (TYPE_GETS_NEW (node) & 1)
fputs (" gets-new", file); fputs (" new", file);
if (TREE_GETS_DELETE (node)) if (TYPE_GETS_NEW (node) & 2)
fputs (" gets-delete", file); fputs (" new[]", file);
if (TYPE_GETS_DELETE (node) & 1)
fputs (" delete", file);
if (TYPE_GETS_DELETE (node) & 2)
fputs (" delete[]", file);
if (TYPE_HAS_ASSIGNMENT (node)) if (TYPE_HAS_ASSIGNMENT (node))
fputs (" has=", file); fputs (" has=", file);
if (TYPE_HAS_ASSIGN_REF (node)) if (TYPE_HAS_ASSIGN_REF (node))
......
...@@ -1079,16 +1079,16 @@ lookup_field (xbasetype, name, protect, want_type) ...@@ -1079,16 +1079,16 @@ lookup_field (xbasetype, name, protect, want_type)
if (TREE_CODE (rval) == CONST_DECL) if (TREE_CODE (rval) == CONST_DECL)
{ {
if (this_v == access_private) if (this_v == access_private)
errstr = "enum `%s' is a private value of class `%s'"; errstr = "enum `%D' is a private value of class `%T'";
else if (this_v == access_protected) else if (this_v == access_protected)
errstr = "enum `%s' is a protected value of class `%s'"; errstr = "enum `%D' is a protected value of class `%T'";
} }
else else
{ {
if (this_v == access_private) if (this_v == access_private)
errstr = "member `%s' is a private member of class `%s'"; errstr = "member `%D' is a private member of class `%T'";
else if (this_v == access_protected) else if (this_v == access_protected)
errstr = "member `%s' is a protected member of class `%s'"; errstr = "member `%D' is a protected member of class `%T'";
} }
} }
...@@ -1214,7 +1214,7 @@ lookup_field (xbasetype, name, protect, want_type) ...@@ -1214,7 +1214,7 @@ lookup_field (xbasetype, name, protect, want_type)
else else
{ {
/* This is ambiguous. */ /* This is ambiguous. */
errstr = "request for member `%s' is ambiguous"; errstr = "request for member `%D' is ambiguous";
protect = 2; protect = 2;
break; break;
} }
...@@ -1250,7 +1250,7 @@ lookup_field (xbasetype, name, protect, want_type) ...@@ -1250,7 +1250,7 @@ lookup_field (xbasetype, name, protect, want_type)
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 && new_v != this_v)
{ {
errstr = "conflicting access to member `%s'"; errstr = "conflicting access to member `%D'";
this_v = access_default; this_v = access_default;
} }
own_access = new_v; own_access = new_v;
...@@ -1272,17 +1272,17 @@ lookup_field (xbasetype, name, protect, want_type) ...@@ -1272,17 +1272,17 @@ lookup_field (xbasetype, name, protect, want_type)
if (errstr == 0) if (errstr == 0)
{ {
if (own_access == access_private) if (own_access == access_private)
errstr = "member `%s' declared private"; errstr = "member `%D' declared private";
else if (own_access == access_protected) else if (own_access == access_protected)
errstr = "member `%s' declared protected"; errstr = "member `%D' declared protected";
else if (this_v == access_private) else if (this_v == access_private)
errstr = TREE_PRIVATE (rval) errstr = TREE_PRIVATE (rval)
? "member `%s' is private" ? "member `%D' is private"
: "member `%s' is from private base class"; : "member `%D' is from private base class";
else if (this_v == access_protected) else if (this_v == access_protected)
errstr = TREE_PROTECTED (rval) errstr = TREE_PROTECTED (rval)
? "member `%s' is protected" ? "member `%D' is protected"
: "member `%s' is from protected base class"; : "member `%D' is from protected base class";
} }
if (entry) if (entry)
...@@ -1302,17 +1302,7 @@ lookup_field (xbasetype, name, protect, want_type) ...@@ -1302,17 +1302,7 @@ lookup_field (xbasetype, name, protect, want_type)
if (errstr && protect) if (errstr && protect)
{ {
char *p = IDENTIFIER_POINTER (name), *q = NULL; cp_error (errstr, name, type);
if (IDENTIFIER_OPNAME_P (name))
{
q = operator_name_string (name);
p = (char *) xmalloc (9 + strlen (q) + 1);
sprintf (p, "operator %s", q);
}
error (errstr, p, TYPE_NAME_STRING (type));
if (q)
free (p);
rval = error_mark_node; rval = error_mark_node;
} }
return rval; return rval;
...@@ -3031,15 +3021,15 @@ push_class_decls (type) ...@@ -3031,15 +3021,15 @@ push_class_decls (type)
search_stack = push_search_level (search_stack, &search_obstack); search_stack = push_search_level (search_stack, &search_obstack);
id = TYPE_IDENTIFIER (type); id = TYPE_IDENTIFIER (type);
#if 0
if (IDENTIFIER_TEMPLATE (id) != 0) if (IDENTIFIER_TEMPLATE (id) != 0)
{ {
#if 0
tree tmpl = IDENTIFIER_TEMPLATE (id); tree tmpl = IDENTIFIER_TEMPLATE (id);
push_template_decls (DECL_ARGUMENTS (TREE_PURPOSE (tmpl)), push_template_decls (DECL_ARGUMENTS (TREE_PURPOSE (tmpl)),
TREE_VALUE (tmpl), 1); TREE_VALUE (tmpl), 1);
#endif
overload_template_name (id, 1); overload_template_name (id, 1);
} }
#endif
/* Push class fields into CLASS_VALUE scope, and mark. */ /* Push class fields into CLASS_VALUE scope, and mark. */
dfs_walk (TYPE_BINFO (type), dfs_pushdecls, unmarkedp); dfs_walk (TYPE_BINFO (type), dfs_pushdecls, unmarkedp);
...@@ -3227,3 +3217,27 @@ reinit_search_statistics () ...@@ -3227,3 +3217,27 @@ reinit_search_statistics ()
n_outer_fields_searched = 0; n_outer_fields_searched = 0;
n_contexts_saved = 0; n_contexts_saved = 0;
} }
tree
lookup_nested_tag (type, name)
tree type, name;
{
tree tags = CLASSTYPE_TAGS (type);
for (; tags; tags = TREE_CHAIN (tags))
{
/* The TREE_PURPOSE of an enum tag (which becomes a member of the
enclosing class) is set to the name for the enum type. So, if
name is `bar', and we strike `baz' for `enum bar { baz }', then
this test will be true. */
if (TREE_PURPOSE (tags) == name)
break;
}
if (tags)
return TYPE_NAME (TREE_VALUE (tags));
if (TYPE_CONTEXT (type))
return lookup_nested_tag (TYPE_CONTEXT (type), name);
return NULL_TREE;
}
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