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
`echo $(srcdir)/parse.c | sed 's,^\./,,'`
$(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); grep '^#define[ ]*YYEMPTY' parse.c >>parse.h
......
......@@ -2673,10 +2673,7 @@ build_scoped_method_call (exp, scopes, name, parms)
{
/* Explicit call to destructor. */
name = TREE_OPERAND (name, 0);
if (TREE_TYPE (decl) !=
(IDENTIFIER_CLASS_VALUE (name)
? IDENTIFIER_CLASS_TYPE_VALUE (name)
: IDENTIFIER_TYPE_VALUE (name)))
if (name != constructor_name (TREE_TYPE (decl)))
{
cp_error
("qualified type `%T' does not match destructor type `%T'",
......@@ -2808,6 +2805,10 @@ build_method_call (instance, name, parms, basetype_path, flags)
/* If it doesn't work, two argument delete must work */
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)
{
......
......@@ -2494,7 +2494,9 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
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 */
cp_error_at ("`%D' overloaded", fn_fields);
......@@ -4149,8 +4151,10 @@ finish_struct (t, list_of_fieldlists, warn_anon)
else if (flag_dossier && ! CLASSTYPE_DOSSIER (t))
build_t_desc (t, 1);
#if 0
if (TYPE_NAME (t) && TYPE_IDENTIFIER (t))
undo_template_name_overload (TYPE_IDENTIFIER (t), 1);
#endif
if (current_class_type)
popclass (0);
else
......@@ -4426,10 +4430,7 @@ pushclass (type, modify)
current_function_decl = NULL_TREE;
if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE)
{
declare_uninstantiated_type_level ();
overload_template_name (current_class_name, 0);
}
declare_uninstantiated_type_level ();
else if (type != previous_class_type || current_class_depth > 1)
{
build_mi_matrix (type);
......@@ -4457,6 +4458,9 @@ pushclass (type, modify)
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))
{
TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 1;
......@@ -4513,9 +4517,9 @@ popclass (modify)
TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
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 ();
......@@ -4583,7 +4587,12 @@ push_nested_class (type, modify)
tree type;
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)
push_nested_class (context, 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
saying whether the store should be deallocated as well. */
DEFTREECODE (DELETE_EXPR, "dl_expr", "e", 2)
DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", "e", 2)
/* Value is reference to particular overloaded class method.
Operand 0 is the class name (an IDENTIFIER_NODE);
......@@ -52,6 +53,7 @@ DEFTREECODE (TYPE_EXPR, "type_expr", "e", 1)
operand 1 is argument list to initialization function,
and operand 2 is the slot which was allocated for this expression. */
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
that were caught. Only the DECL_NAME (and TREE_CHAIN)
......
......@@ -68,10 +68,6 @@ struct lang_id2
#define IDENTIFIER_TYPE_VALUE(NODE) (TREE_TYPE (NODE))
#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_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) \
(((struct lang_identifier *)(NODE))->x \
......@@ -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 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) \
(TREE_CODE (TYPE1) == TREE_CODE (TYPE2) \
&& IS_AGGR_TYPE (TYPE1)&IS_AGGR_TYPE (TYPE2))
......@@ -395,14 +391,13 @@ struct lang_type
unsigned vtable_needs_writing : 1;
unsigned has_assign_ref : 1;
unsigned gets_new : 1;
unsigned gets_placed_new : 1;
unsigned gets_delete : 1;
unsigned gets_new : 2;
unsigned gets_delete : 2;
unsigned has_call_overloaded : 1;
unsigned has_array_ref_overloaded : 1;
unsigned has_arrow_overloaded : 1;
unsigned local_typedecls : 1;
unsigned local_typedecls : 1;
unsigned interface_only : 1;
unsigned interface_unknown : 1;
unsigned needs_virtual_reinit : 1;
......@@ -410,16 +405,16 @@ struct lang_type
unsigned declared_class : 1;
unsigned being_defined : 1;
unsigned redefined : 1;
unsigned no_globalize : 1;
unsigned no_globalize : 1;
unsigned marked : 1;
unsigned marked2 : 1;
unsigned marked3 : 1;
unsigned marked4 : 1;
unsigned marked5 : 1;
unsigned marked6 : 1;
unsigned use_template : 2;
unsigned use_template : 2;
unsigned debug_requested : 1;
unsigned has_method_call_overloaded : 1;
unsigned private_attr : 1;
......@@ -427,8 +422,8 @@ struct lang_type
unsigned ptrmemfunc_flag : 1;
unsigned is_signature : 1;
unsigned is_signature_pointer : 1;
unsigned is_signature_reference : 1;
unsigned is_signature_reference : 1;
unsigned has_default_implementation : 1;
unsigned grokking_typedef : 1;
unsigned has_opaque_typedecls : 1;
......@@ -436,15 +431,16 @@ struct lang_type
unsigned was_anonymous : 1;
unsigned has_real_assignment : 1;
unsigned has_real_assign_ref : 1;
unsigned has_const_init_ref : 1;
unsigned has_complex_init_ref : 1;
unsigned has_complex_assign_ref : 1;
unsigned vec_delete_takes_size : 1;
/* The MIPS compiler gets it wrong if this struct also
does not fill out to a multiple of 4 bytes. Add a
member `dummy' with new bits if you go over the edge. */
unsigned dummy : 22;
unsigned dummy : 20;
unsigned n_vancestors : 16;
} type_flags;
......@@ -519,9 +515,17 @@ struct lang_type
/* Nonzero for _CLASSTYPE means that operator new and delete are defined,
respectively. */
#define TREE_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 TREE_GETS_DELETE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_delete)
#define TYPE_GETS_NEW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_new)
#define TYPE_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. */
#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));
extern tree build_x_delete PROTO((tree, tree, int, tree));
extern tree build_delete PROTO((tree, tree, tree, int, int));
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 */
......@@ -2081,6 +2085,7 @@ extern int do_pending_expansions PROTO((void));
extern void do_pending_templates PROTO((void));
struct tinst_level *tinst_for_decl PROTO((void));
extern void do_function_instantiation PROTO((tree, tree));
extern tree create_nested_upt PROTO((tree, tree));
/* in search.c */
extern tree make_memoized_table_entry PROTO((tree, tree, int));
......@@ -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_nested_field PROTO((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 int tree_needs_constructor_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));
extern tree common_base_types PROTO((tree, tree));
extern int compparms 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 signed_type PROTO((tree));
extern tree signed_or_unsigned_type PROTO((int, tree));
......
......@@ -720,8 +720,16 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
{
/* When casting an lvalue to a reference type, just convert into
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 */
/* 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);
if (rval != error_mark_node)
rval = convert_force (build_pointer_type (TREE_TYPE (reftype)), rval);
......@@ -744,6 +752,7 @@ convert_to_reference (decl, reftype, expr, fndecl, parmnum,
/* Definitely need to go through a constructor here. */
if (TYPE_HAS_CONSTRUCTOR (type)
&& ! CLASSTYPE_ABSTRACT_VIRTUALS (type)
&& (rval = build_method_call
(NULL_TREE, constructor_name_full (type),
build_tree_list (NULL_TREE, expr), TYPE_BINFO (type),
......
......@@ -1071,6 +1071,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
return error_mark_node;
}
#if 0
/* If the type has no destructor, then we should build a regular
delete, instead of a vector delete. Otherwise, we would end
up passing a bogus offset into __builtin_delete, which is
......@@ -1082,15 +1083,15 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
doing_vec = 0;
use_global_delete = 1;
}
#endif
if (doing_vec)
return build_vec_delete (t, maxindex, elt_size, NULL_TREE,
integer_one_node, integer_two_node);
return build_vec_delete (t, maxindex, elt_size, integer_one_node,
integer_two_node, use_global_delete);
else
return build_delete (type, t, integer_three_node,
LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE,
use_global_delete
|| TYPE_HAS_DESTRUCTOR (TREE_TYPE (type)));
use_global_delete);
}
/* Sanity check: report error if this function FUNCTION is not
......@@ -1456,6 +1457,7 @@ grokbitfield (declarator, declspecs, width)
return value;
}
#if 0
/* Like GROKFIELD, except that the declarator has been
buried in DECLSPECS. Find the declarator, and
return something that looks like it came from
......@@ -1634,6 +1636,7 @@ groktypefield (declspecs, parmlist)
DECL_IN_AGGR_P (decl) = 1;
return decl;
}
#endif
tree
grokoptypename (declspecs, declarator)
......@@ -2278,7 +2281,7 @@ coerce_delete_type (type)
else if (e3 |= e2)
{
if (arg_types == NULL_TREE)
arg_types = void_list_node;
arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
else
arg_types = tree_cons (NULL_TREE, ptr_type_node, TREE_CHAIN (arg_types));
}
......@@ -2853,7 +2856,11 @@ reparse_decl_as_expr1 (decl)
case BIT_NOT_EXPR:
return build_x_unary_op (BIT_NOT_EXPR,
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:
my_friendly_abort (5);
return NULL_TREE;
......@@ -2901,6 +2908,9 @@ finish_decl_parsing (decl)
push_nested_class (TREE_OPERAND (decl, 0), 3);
TREE_COMPLEXITY (decl) = current_class_depth;
return decl;
case ARRAY_REF:
TREE_OPERAND (decl, 0) = finish_decl_parsing (TREE_OPERAND (decl, 0));
return decl;
default:
my_friendly_abort (5);
return NULL_TREE;
......
......@@ -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
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 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
@code{sizeof}. Section 8.1 of the pre-San Diego working paper specifies
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
@code{expr_or_declarator}/@code{complex_direct_notype_declarator}, for
various token strings. This situation occurs in code looking like
3) Between @code{functional_cast} and
@code{complex_direct_notype_declarator}, for various token strings.
This situation occurs in code looking like
@example
int (*a);
......@@ -1078,11 +1079,23 @@ int (*a);
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} to @samp{int}. Section 6.8 specifies that the former
interpretation is correct. This ambiguity results in 12 reduce/reduce
conflicts. Ack.
4) Between @code{after_type_declarator} and @code{parm}, for the token
@code{TYPENAME}. This occurs in (as one example) code like
interpretation is correct. This ambiguity results in 7 reduce/reduce
conflicts. Another aspect of this ambiguity is code like 'int (x[2]);',
which is resolved at the '[' and accounts for 6 reduce/reduce conflicts
between @samp{direct_notype_declarator} and
@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
typedef int foo, bar;
......@@ -1093,11 +1106,12 @@ class A @{
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
@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
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
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.
......
......@@ -542,6 +542,10 @@ init_lex ()
IDENTIFIER_OPNAME_P (ansi_opname[(int) NEW_EXPR]) = 1;
ansi_opname[(int) DELETE_EXPR] = get_identifier ("__dl");
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");
IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1;
......@@ -681,6 +685,8 @@ init_lex ()
opname_tab[(int) MODIFY_EXPR] = "=";
opname_tab[(int) NEW_EXPR] = "new";
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) CALL_EXPR] = "()";
opname_tab[(int) PLUS_EXPR] = "+";
......@@ -841,10 +847,7 @@ yyprint (file, yychar, yylval)
case IDENTIFIER_DEFN:
case TYPENAME_DEFN:
case PTYPENAME_DEFN:
case TYPENAME_COLON:
case TYPENAME_ELLIPSIS:
case SCOPED_TYPENAME:
case SCOPED_NAME:
case SCSPEC:
case PRE_PARSED_CLASS_DECL:
t = yylval.ttype;
......@@ -2324,14 +2327,15 @@ check_newline ()
register int c;
register int token;
lineno++;
/* Read first nonwhite char on the line. */
/* Read first nonwhite char on the line. Do this before incrementing the
line number, in case we're at the end of saved text. */
do
c = getch ();
while (c == ' ' || c == '\t');
lineno++;
if (c != '#')
{
/* If not #, return it so caller will use it. */
......@@ -3080,12 +3084,13 @@ readescape (ignore_ptr)
return c;
}
/* Value is 1 if we should try to make the next identifier look like 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 -1 if we must not see a type name. */
/* Value is 1 (or 2) if we should try to make the next identifier look like
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. */
int looking_for_typename = 0;
#if 0
/* NO LONGER USED: Value is -1 if we must not see a type name. */
void
dont_see_typename ()
{
......@@ -3096,6 +3101,7 @@ dont_see_typename ()
lastiddecl = 0;
}
}
#endif
#ifdef __GNUC__
extern __inline int identifier_type ();
......@@ -3119,7 +3125,7 @@ see_typename ()
looking_for_typename = 0;
if (yychar == IDENTIFIER)
{
lastiddecl = lookup_name (yylval.ttype, -1);
lastiddecl = lookup_name (yylval.ttype, -2);
if (lastiddecl == 0)
{
if (flag_labels_ok)
......@@ -3540,7 +3546,6 @@ real_yylex ()
}
if (value == NEW && ! global_bindings_p ())
{
looking_for_typename = 1;
value = NEW;
goto done;
}
......
......@@ -114,6 +114,9 @@ extern char *token_buffer; /* Pointer to token buffer. */
/* Back-door communication channel to the lexer. */
extern int looking_for_typename;
/* Tell the lexer where to look for names. */
extern tree got_scope;
/* Pending language change.
Positive is push count, negative is pop count. */
extern int pending_lang_change;
......
......@@ -840,27 +840,22 @@ build_decl_overload (dname, parms, for_method)
{
char *name = IDENTIFIER_POINTER (dname);
if (dname == ansi_opname[(int) NEW_EXPR]
&& parms != NULL_TREE
&& TREE_CODE (parms) == TREE_LIST
&& TREE_VALUE (parms) == sizetype
&& TREE_CHAIN (parms) == void_list_node)
return get_identifier ("__builtin_new");
else if (dname == ansi_opname[(int) DELETE_EXPR]
&& parms != NULL_TREE
&& TREE_CODE (parms) == TREE_LIST
&& TREE_VALUE (parms) == ptr_type_node
&& TREE_CHAIN (parms) == void_list_node)
return get_identifier ("__builtin_delete");
else if (dname == ansi_opname[(int) DELETE_EXPR]
&& parms != NULL_TREE
&& TREE_CODE (parms) == TREE_LIST
&& 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");
/* member operators new and delete look like methods at this point. */
if (! for_method && parms != NULL_TREE && TREE_CODE (parms) == TREE_LIST)
{
if (TREE_VALUE (parms) == sizetype
&& TREE_CHAIN (parms) == void_list_node)
{
if (dname == ansi_opname[(int) NEW_EXPR])
return get_identifier ("__builtin_new");
else if (dname == ansi_opname[(int) VEC_NEW_EXPR])
return get_identifier ("__builtin_vec_new");
}
else if (dname == ansi_opname[(int) DELETE_EXPR])
return get_identifier ("__builtin_delete");
else if (dname == ansi_opname[(int) VEC_DELETE_EXPR])
return get_identifier ("__builtin_vec_delete");
}
OB_INIT ();
if (for_method != 2)
......@@ -1112,19 +1107,19 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
try_second = 0;
break;
case VEC_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)
return build_overload_call (fnname, tree_cons (NULL_TREE, xarg2, arg3),
flags & LOOKUP_COMPLAIN,
return build_overload_call (fnname, args, flags & LOOKUP_COMPLAIN,
(struct candidate *)0);
rval = build_method_call
(build_indirect_ref (build1 (NOP_EXPR, xarg1, error_mark_node),
"new"),
fnname, tree_cons (NULL_TREE, xarg2, arg3),
NULL_TREE, flags);
fnname, args, NULL_TREE, flags);
if (rval == error_mark_node)
/* User might declare fancy operator new, but invoke it
like standard one. */
......@@ -1136,13 +1131,13 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
}
break;
case VEC_DELETE_EXPR:
case DELETE_EXPR:
{
fnname = ansi_opname[(int) DELETE_EXPR];
fnname = ansi_opname[(int) code];
if (flags & LOOKUP_GLOBAL)
return build_overload_call (fnname,
tree_cons (NULL_TREE, xarg1,
build_tree_list (NULL_TREE, xarg2)),
build_tree_list (NULL_TREE, xarg1),
flags & LOOKUP_COMPLAIN,
(struct candidate *)0);
......@@ -1151,7 +1146,7 @@ build_opfncall (code, flags, xarg1, xarg2, arg3)
error_mark_node),
NULL_PTR),
fnname, tree_cons (NULL_TREE, xarg1,
build_tree_list (NULL_TREE, xarg2)),
build_tree_list (NULL_TREE, xarg2)),
NULL_TREE, flags);
/* This happens when the user mis-declares `operator delete'.
Should now be impossible. */
......
......@@ -1690,6 +1690,7 @@ instantiate_template (tmpl, targ_ptr)
return fndecl;
}
/* classlevel should now never be true. jason 4/12/94 */
void
undo_template_name_overload (id, classlevel)
tree id;
......@@ -1711,6 +1712,7 @@ undo_template_name_overload (id, classlevel)
#endif
}
/* classlevel should now never be true. jason 4/12/94 */
void
overload_template_name (id, classlevel)
tree id;
......@@ -1731,12 +1733,9 @@ overload_template_name (id, classlevel)
#if 1 /* XXX */
/* This was a botch... names of templates do not get their own private
scopes. Rather, the names of generated template instances should
just get pushed into whatever scope we happen to be in at the moment.
This will typically (but not always) be the global scope. (Maybe
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.) */
scopes. Rather, they should go into the binding level already created
by push_template_decls. Except that there isn't one of those for
specializations. */
if (!classlevel)
{
pushlevel (1);
......@@ -1765,20 +1764,13 @@ overload_template_name (id, classlevel)
if (classlevel)
pushdecl_class_level (decl);
else
#if 0 /* not yet, should get fixed properly later */
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
be done in a proper way later on. */
DECL_CONTEXT (decl) = t;
#endif
}
/* NAME is the IDENTIFIER value of a PRE_PARSED_CLASS_DECL. */
......@@ -2028,6 +2020,22 @@ unify (tparms, targs, ntparms, parm, arg, nsubsts)
return 0;
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);
return 1;
}
......@@ -2306,3 +2314,18 @@ do_function_instantiation (declspecs, declarator)
if (!result)
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)
else
fputs (" X(X&)", file);
}
if (TREE_GETS_NEW (node))
fputs (" gets-new", file);
if (TREE_GETS_DELETE (node))
fputs (" gets-delete", file);
if (TYPE_GETS_NEW (node) & 1)
fputs (" new", file);
if (TYPE_GETS_NEW (node) & 2)
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))
fputs (" has=", file);
if (TYPE_HAS_ASSIGN_REF (node))
......
......@@ -1079,16 +1079,16 @@ lookup_field (xbasetype, name, protect, want_type)
if (TREE_CODE (rval) == CONST_DECL)
{
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)
errstr = "enum `%s' is a protected value of class `%s'";
errstr = "enum `%D' is a protected value of class `%T'";
}
else
{
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)
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)
else
{
/* This is ambiguous. */
errstr = "request for member `%s' is ambiguous";
errstr = "request for member `%D' is ambiguous";
protect = 2;
break;
}
......@@ -1250,7 +1250,7 @@ lookup_field (xbasetype, name, protect, want_type)
new_v = compute_access (TREE_VALUE (TREE_CHAIN (*tp)), rval);
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;
}
own_access = new_v;
......@@ -1272,17 +1272,17 @@ lookup_field (xbasetype, name, protect, want_type)
if (errstr == 0)
{
if (own_access == access_private)
errstr = "member `%s' declared private";
errstr = "member `%D' declared private";
else if (own_access == access_protected)
errstr = "member `%s' declared protected";
errstr = "member `%D' declared protected";
else if (this_v == access_private)
errstr = TREE_PRIVATE (rval)
? "member `%s' is private"
: "member `%s' is from private base class";
? "member `%D' is private"
: "member `%D' is from private base class";
else if (this_v == access_protected)
errstr = TREE_PROTECTED (rval)
? "member `%s' is protected"
: "member `%s' is from protected base class";
? "member `%D' is protected"
: "member `%D' is from protected base class";
}
if (entry)
......@@ -1302,17 +1302,7 @@ lookup_field (xbasetype, name, protect, want_type)
if (errstr && protect)
{
char *p = IDENTIFIER_POINTER (name), *q = NULL;
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);
cp_error (errstr, name, type);
rval = error_mark_node;
}
return rval;
......@@ -3031,15 +3021,15 @@ push_class_decls (type)
search_stack = push_search_level (search_stack, &search_obstack);
id = TYPE_IDENTIFIER (type);
#if 0
if (IDENTIFIER_TEMPLATE (id) != 0)
{
#if 0
tree tmpl = IDENTIFIER_TEMPLATE (id);
push_template_decls (DECL_ARGUMENTS (TREE_PURPOSE (tmpl)),
TREE_VALUE (tmpl), 1);
#endif
overload_template_name (id, 1);
}
#endif
/* Push class fields into CLASS_VALUE scope, and mark. */
dfs_walk (TYPE_BINFO (type), dfs_pushdecls, unmarkedp);
......@@ -3227,3 +3217,27 @@ reinit_search_statistics ()
n_outer_fields_searched = 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