46 Cygnus<->FSF merge

From-SVN: r7943
This commit is contained in:
Mike Stump 1994-08-18 20:50:43 +00:00
parent 07d0cbddd4
commit 0059501924
18 changed files with 663 additions and 251 deletions

View File

@ -1,3 +1,211 @@
Thu Aug 18 12:48:09 1994 Mike Stump (mrs@cygnus.com)
* class.c (finish_struct): Move setting of CLASSTYPE_INTERFACE and
CLASSTYPE_VTABLE_NEEDS_WRITING up to left_curly time.
* decl.c (xref_tag): Move setting of CLASSTYPE_INTERFACE and
CLASSTYPE_VTABLE_NEEDS_WRITING down to left_curly time.
* parse.y (left_curly): New final resting place for setting
CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING.
Thu Aug 11 11:32:42 1994 H.J. Lu (hjl@nynexst.com)
* g++.c (main): Only decrement "added" and set "library" to
NULL when "library" != NULL.
Sat Aug 13 00:14:52 1994 Jason Merrill (jason@deneb.cygnus.com)
* decl.c (grokdeclarator): Don't set TREE_PUBLIC on a function decl
just because its class has a known interface.
(decls_match): Deal with new format of template parms.
* lex.c (cons_up_default_function): Don't play with TREE_PUBLIC and
DECL_EXTERNAL here.
Fri Aug 12 01:55:15 1994 Jason Merrill (jason@deneb.cygnus.com)
* decl.c (pushtag): SET_DECL_ARTIFICIAL on gratuitous typedefs.
(xref_defn_tag): Ditto.
(pushdecl): Only allow artificial typedefs to be shadowed.
* init.c (emit_base_init): Pass the right binfos to
expand_aggr_init_1.
* class.c (delete_duplicate_fields_1): Make it work right.
(finish_struct): Catch function/field name conflict.
* decl2.c (check_classfn): Pass the function to cp_error, not just
the name.
* init.c (sort_member_init): Warn when order of member initializers
does not match order of member declarations.
(emit_base_init): Call expand_aggr_init_1 with LOOKUP_PROTECT.
* error.c (dump_expr): Handle lists of functions.
* decl.c (start_function): #pragma interface only affects functions
that would otherwise be static.
(finish_decl): Don't warn about an unused variable if it has both
constructor and destructor, since the 'resource allocation is
initialization' idiom is relatively common.
* typeck.c (comp_target_types): Don't handle TEMPLATE_TYPE_PARMs.
(comp_target_parms): Ditto.
(compparms): Never consider default parms.
(common_base_type): Don't choose a virtual baseclass if there is a
more derived class in common.
(build_conditional_expr): If pedantic, pedwarn about conversion to
common base in conditional expr.
* class.c (instantiate_type): Handle template instantiation better.
* typeck.c (convert_arguments): Don't try to get tricky and convert
to int directly when PROMOTE_PROTOTYPES is set, as it breaks
user-defined conversions.
* lex.c (check_for_missing_semicolon): Also give error at end of
file.
* call.c (build_method_call): Don't promote arrays to pointers here.
* typeck.c (convert_arguments): Don't require the actual parameter
to be of a complete type if the formal parameter is a reference.
Thu Aug 11 15:21:40 1994 Jason Merrill (jason@deneb.cygnus.com)
* decl.c (grokdeclarator): Soften 'static' on member function error
to pedwarn.
* init.c (build_new): Don't automatically save rval.
(build_offset_ref): Do field lookup with proper basetype_path.
Thu Aug 11 12:46:54 1994 Brendan Kehoe (brendan@lisa.cygnus.com)
* errfn.c (cp_silent): Declare to mark when we should avoid
emitting warnings and errors.
(cp_error): Check it.
(cp_warning): Likewise.
(cp_pedwarn): Likewise.
(cp_compiler_error): Likewise.
(cp_error_at): Likewise.
(cp_warning_at): Likewise.
(cp_pedwarn_at): Likewise.
* call.c (compute_conversion_costs): Set CP_SILENT when we start
out, and make sure we turn it off before we leave.
Thu Aug 11 00:02:54 1994 Jason Merrill (jason@deneb.cygnus.com)
* decl2.c (grok_array_decl): Try computing *(A+B) if neither
argument is obviously an array.
Wed Aug 10 15:32:04 1994 Jason Merrill (jason@deneb.cygnus.com)
* typeck.c (c_expand_start_case): Do cleanups here.
* parse.y (xcond): Do bool conversion here, too.
(simple_stmt, SWITCH case): Don't do cleanups here.
* decl.c (duplicate_decls): Don't treat builtins that have been
explicitly declared specially.
Tue Aug 9 01:16:09 1994 Jason Merrill (jason@deneb.cygnus.com)
* tree.c (make_deep_copy): Support copying pointer, reference,
function, array, offset and method types.
* decl.c (init_decl_processing): Mark exit and abort as
BUILT_IN_NONANSI so that duplicate_decls is kinder about
redeclaration.
(duplicate_decls): Don't give two errors for redeclaring a C
function with the same parms but a different return type.
* parse.y (paren_cond_or_null): Do cleanup and bool conversion here.
(condition): Instead of here.
(simple_stmt, SWITCH case): Also do cleanup here.
* decl2.c (finish_anon_union): Only break out FIELD_DECLs.
* call.c (build_method_call): Don't throw away the side effects of
the object in a call to a non-existent constructor.
* parse.y (primary): Ditto.
* method.c (build_decl_overload): Oop.
* decl2.c (lang_decode_option): Deal with flag_no_nonansi_builtin,
warn about uselessness of specifying -fansi-overloading.
* method.c (build_decl_overload): Treat any non-member new with one
parameter as __builtin_new.
* decl.c (init_decl_processing): Setup built-in meanings of exit,
_exit and abort.
Mon Aug 8 15:03:30 1994 Jason Merrill (jason@deneb.cygnus.com)
* error.c (dump_readonly_or_volatile): Put a space between const and
volatile if both apply.
* init.c (perform_member_init): Clean up after this initialization.
(emit_base_init): Clean up after each base init, not after all have
been done.
(expand_aggr_vbase_init_1): Clean up after this init.
Sun Aug 7 14:55:05 1994 Jason Merrill (jason@deneb.cygnus.com)
* call.c (build_method_call): Deal with destroying references.
* parse.y (condition): Do bool_truthvalue_conversion here.
(paren_expr_or_null): And here.
(simple_if): Not here.
(simple_stmt): Or here.
Sat Aug 6 22:29:45 1994 Jason Merrill (jason@deneb.cygnus.com)
* parse.y (paren_expr_or_null): Wrap the expression in a
CLEANUP_POINT_EXPR.
(condition): Ditto.
Sat Aug 6 19:46:37 1994 Rohan Lenard (rjl@easams.com.au)
* call.c (build_scoped_method_call): Fix error message when
destructor call refers to a nonexistent type.
Sat Apr 16 22:43:30 1993 Gerald Baumgartner (gb@cs.purdue.edu)
* lex.h (rid): Deleted RID_RAISES, it's never used.
Moved RID_PUBLIC, RID_PRIVATE, RID_PROTECTED, RID_EXCEPTION,
RID_TEMPLATE and RID_SIGNATURE to the end of the enumeration,
they don't need to be touched in `grokdeclarator.'
(RID_LAST_MODIFIER): Defined macro to be RID_MUTABLE.
* decl.c (grokdeclarator): Use RID_LAST_MODIFIER instead of
RID_MAX as loop limit for finding declaration specifiers.
Sat Apr 3 21:59:07 1993 Gerald Baumgartner (gb@cs.purdue.edu)
* lex.c (debug_yytranslate): Moved to parse.y since it needs to
access `yytname,' which is static in parse.c.
Fri Apr 2 23:36:57 1993 Gerald Baumgarnter (gb@cs.purdue.edu)
* cp-tree.h (GNU_xref_ref): Fixed typo in extern declaration, it
was `GNU_xref_def' instead of `GNU_xref_ref.'
Fri Aug 5 14:20:16 1994 Jason Merrill (jason@deneb.cygnus.com)
* pt.c (do_function_instantiation): Don't set TREE_PUBLIC and
DECL_EXTERNAL on 'extern' instantiations; wait until EOF to do that.
(do_type_instantiation): Ditto.
* decl2.c (import_export_inline): Decides at EOF what an inline's
linkage should be.
(finish_file): Call it.
* decl.c (start_function): Don't rely on the settings of TREE_PUBLIC
and DECL_EXTERNAL from do_*_instantiation. Only set
DECL_DEFER_OUTPUT on inlines whose linkage might actually change.
(finish_function): Use DECL_DEFER_OUTPUT to decide which inlines to
mark for later consideration, rather than DECL_FUNCTION_MEMBER_P.
Fri Aug 5 01:12:20 1994 Mike Stump (mrs@cygnus.com)
* class.c (get_class_offset_1, get_class_offset): New routine to

View File

@ -700,11 +700,17 @@ compute_conversion_costs (function, tta_in, cp, arglen)
int strike_index = 0, win;
struct harshness_code lose;
extern int cp_silent;
#ifdef GATHER_STATISTICS
n_compute_conversion_costs++;
#endif
#ifndef DEBUG_MATCHING
/* We don't emit any warnings or errors while trying out each candidate. */
cp_silent = 1;
#endif
cp->function = function;
cp->arg = tta ? TREE_VALUE (tta) : NULL_TREE;
cp->u.bad_arg = 0; /* optimistic! */
@ -812,6 +818,7 @@ compute_conversion_costs (function, tta_in, cp, arglen)
{
cp->h.code = EVIL_CODE;
cp->u.bad_arg = -1;
cp_silent = 0;
return;
}
else
@ -833,6 +840,7 @@ compute_conversion_costs (function, tta_in, cp, arglen)
{
cp->h.code = EVIL_CODE;
cp->u.bad_arg = -2;
cp_silent = 0;
return;
}
/* Store index of first default. */
@ -855,6 +863,7 @@ compute_conversion_costs (function, tta_in, cp, arglen)
if (dont_convert_types)
{
cp->h.code = EVIL_CODE;
cp_silent = 0;
return;
}
@ -1002,6 +1011,7 @@ compute_conversion_costs (function, tta_in, cp, arglen)
cp->h.code |= ELLIPSIS_CODE;
if (user_strikes)
cp->h.code |= USER_CODE;
cp_silent = 0;
#ifdef DEBUG_MATCHING
cp_error ("final eval %s", print_harshness (&cp->h));
#endif
@ -1428,7 +1438,9 @@ build_scoped_method_call (exp, scopes, name, parms)
if (type != basetype)
cp_error ("type of `%E' does not match destructor type `%T' (type was `%T')",
exp, basetype, type);
name = IDENTIFIER_TYPE_VALUE (TREE_OPERAND (name, 0));
name = TREE_OPERAND (name, 0);
if (IDENTIFIER_HAS_TYPE_VALUE (name))
name = IDENTIFIER_TYPE_VALUE (name);
if (basetype != name)
cp_error ("qualified type `%T' does not match destructor type `%T'",
basetype, name);
@ -1604,17 +1616,19 @@ build_method_call (instance, name, parms, basetype_path, flags)
if (parms)
error ("destructors take no parameters");
basetype = TREE_TYPE (instance);
if (TREE_CODE (basetype) == REFERENCE_TYPE)
basetype = TREE_TYPE (basetype);
if (! ((IS_AGGR_TYPE (basetype)
&& name == constructor_name (basetype))
|| basetype == get_type_value (name)))
{
cp_error ("destructor name `~%D' does not match type `%T' of expression",
name, basetype);
return void_zero_node;
return convert (void_type_node, instance);
}
if (! TYPE_HAS_DESTRUCTOR (basetype))
return void_zero_node;
return convert (void_type_node, instance);
instance = default_conversion (instance);
instance_ptr = build_unary_op (ADDR_EXPR, instance, 0);
return build_delete (build_pointer_type (basetype),
@ -1891,6 +1905,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
{
TREE_VALUE (parm) = build_unary_op (ADDR_EXPR, TREE_VALUE (parm), 0);
}
#if 0
/* This breaks reference-to-array parameters. */
if (TREE_CODE (t) == ARRAY_TYPE)
{
/* Perform the conversion from ARRAY_TYPE to POINTER_TYPE in place.
@ -1898,6 +1914,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
TREE_VALUE (parm) = default_conversion (TREE_VALUE (parm));
t = TREE_TYPE (TREE_VALUE (parm));
}
#endif
if (t == error_mark_node)
return error_mark_node;
last = build_tree_list (NULL_TREE, t);

View File

@ -992,20 +992,18 @@ add_method (type, fields, method)
not duplicates, they are just anonymous fields. This happens
when we have unnamed bitfields, for example. */
static tree
delete_duplicate_fields_1 (field, field_ptr, fields)
tree field, *field_ptr, fields;
delete_duplicate_fields_1 (field, fields)
tree field, fields;
{
tree x;
tree prev = field_ptr ? *field_ptr : 0;
tree prev = 0;
if (DECL_NAME (field) == 0)
{
if (TREE_CODE (TREE_TYPE (field)) != UNION_TYPE)
return fields;
for (x = TYPE_FIELDS (TREE_TYPE (field)); x; x = TREE_CHAIN (x))
fields = delete_duplicate_fields_1 (x, field_ptr, fields);
if (prev)
TREE_CHAIN (prev) = fields;
fields = delete_duplicate_fields_1 (x, fields);
return fields;
}
else
@ -1017,7 +1015,7 @@ delete_duplicate_fields_1 (field, field_ptr, fields)
if (TREE_CODE (TREE_TYPE (x)) != UNION_TYPE)
continue;
TYPE_FIELDS (TREE_TYPE (x))
= delete_duplicate_fields_1 (field, (tree *)0, TYPE_FIELDS (TREE_TYPE (x)));
= delete_duplicate_fields_1 (field, TYPE_FIELDS (TREE_TYPE (x)));
if (TYPE_FIELDS (TREE_TYPE (x)) == 0)
{
if (prev == 0)
@ -1039,7 +1037,7 @@ delete_duplicate_fields_1 (field, field_ptr, fields)
x);
else if (TREE_CODE (field) == TYPE_DECL
&& TREE_CODE (x) == TYPE_DECL)
cp_error_at ("duplicate class scope type `%D'", x);
cp_error_at ("duplicate nested type `%D'", x);
else if (TREE_CODE (field) == TYPE_DECL
|| TREE_CODE (x) == TYPE_DECL)
cp_error_at ("duplicate field `%D' (as type and non-type)",
@ -1063,7 +1061,7 @@ delete_duplicate_fields (fields)
{
tree x;
for (x = fields; x && TREE_CHAIN (x); x = TREE_CHAIN (x))
TREE_CHAIN (x) = delete_duplicate_fields_1 (x, &x, TREE_CHAIN (x));
TREE_CHAIN (x) = delete_duplicate_fields_1 (x, TREE_CHAIN (x));
}
/* Change the access of FDECL to ACCESS in T.
@ -1937,8 +1935,8 @@ finish_struct_methods (t, fn_fields, nonprivate_method)
&& CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
&& DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE
&& warn_ctor_dtor_privacy)
warning ("class `%s' only defines a private destructor and has no friends",
TYPE_NAME_STRING (t));
cp_warning ("`%#T' only defines a private destructor and has no friends",
t);
break;
}
}
@ -2774,17 +2772,12 @@ finish_struct (t, list_of_fieldlists, warn_anon)
TYPE_SIZE (t) = NULL_TREE;
CLASSTYPE_GOT_SEMICOLON (t) = 0;
/* A signature type will contain the fields of the signature table.
Therefore, it's not only an interface. */
if (IS_SIGNATURE (t))
/* This is in general too late to do this. I moved the main case up to
left_curly, what else needs to move? */
if (! IS_SIGNATURE (t))
{
CLASSTYPE_INTERFACE_ONLY (t) = 0;
SET_CLASSTYPE_INTERFACE_KNOWN (t);
}
else
{
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
my_friendly_assert (CLASSTYPE_INTERFACE_ONLY (t) == interface_only, 999);
my_friendly_assert (CLASSTYPE_INTERFACE_KNOWN (t) == ! interface_unknown, 999);
}
if (flag_dossier)
@ -2848,14 +2841,13 @@ finish_struct (t, list_of_fieldlists, warn_anon)
needs_virtual_dtor = 0;
}
/* Both of these should be done before now. */
if (write_virtuals == 3 && CLASSTYPE_INTERFACE_KNOWN (t)
&& ! IS_SIGNATURE (t))
{
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! interface_only;
my_friendly_assert (CLASSTYPE_INTERFACE_ONLY (t) == interface_only, 999);
my_friendly_assert (CLASSTYPE_VTABLE_NEEDS_WRITING (t) == ! interface_only, 999);
}
else if (IS_SIGNATURE (t))
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = 0;
/* The three of these are approximations which may later be
modified. Needed at this point to make add_virtual_function
@ -3520,6 +3512,31 @@ finish_struct (t, list_of_fieldlists, warn_anon)
/* Delete all duplicate fields from the fields */
delete_duplicate_fields (fields);
/* Catch function/field name conflict, removing the field (since it's
easier). */
{
int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
tree last = NULL_TREE;
for (x = fields; x; x = TREE_CHAIN (x))
{
tree name = DECL_NAME (x);
int i;
for (i = 0; i < n_methods; ++i)
if (DECL_NAME (TREE_VEC_ELT (method_vec, i)) == name)
{
cp_error_at ("data member `%#D' conflicts with", x);
cp_error_at ("function member `%#D'",
TREE_VEC_ELT (method_vec, i));
if (last)
TREE_CHAIN (last) = TREE_CHAIN (x);
else
fields = TREE_CHAIN (x);
break;
}
last = x;
}
}
/* Now we have the final fieldlist for the data fields. Record it,
then lay out the structure or union (including the fields). */
@ -4701,11 +4718,42 @@ instantiate_type (lhstype, rhs, complain)
{
elem = get_first_fn (rhs);
while (elem)
if (TREE_TYPE (elem) != lhstype)
if (! comptypes (lhstype, TREE_TYPE (elem), 1))
elem = DECL_CHAIN (elem);
else
return elem;
/* No exact match found, look for a compatible function. */
/* No exact match found, look for a compatible template. */
{
tree save_elem = 0;
for (elem = get_first_fn (rhs); elem; elem = DECL_CHAIN (elem))
if (TREE_CODE (elem) == TEMPLATE_DECL)
{
int n = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (elem));
tree *t = (tree *) alloca (sizeof (tree) * n);
int i, d;
i = type_unification (DECL_TEMPLATE_PARMS (elem), t,
TYPE_ARG_TYPES (TREE_TYPE (elem)),
TYPE_ARG_TYPES (lhstype), &d, 0);
if (i == 0)
{
if (save_elem)
{
cp_error ("ambiguous template instantiation converting to `%#T'", lhstype);
return error_mark_node;
}
save_elem = instantiate_template (elem, t);
/* Check the return type. */
if (! comptypes (TREE_TYPE (lhstype),
TREE_TYPE (TREE_TYPE (save_elem)), 1))
save_elem = 0;
}
}
if (save_elem)
return save_elem;
}
/* No match found, look for a compatible function. */
elem = get_first_fn (rhs);
while (elem && ! comp_target_types (lhstype, TREE_TYPE (elem), 1))
elem = DECL_CHAIN (elem);
@ -4727,18 +4775,6 @@ instantiate_type (lhstype, rhs, complain)
}
return error_mark_node;
}
if (TREE_CODE (save_elem) == TEMPLATE_DECL)
{
int ntparms = TREE_VEC_LENGTH
(DECL_TEMPLATE_PARMS (save_elem));
tree *targs = (tree *) alloca (sizeof (tree) * ntparms);
int i, dummy;
i = type_unification
(DECL_TEMPLATE_PARMS (save_elem), targs,
TYPE_ARG_TYPES (TREE_TYPE (save_elem)),
TYPE_ARG_TYPES (lhstype), &dummy, 0);
save_elem = instantiate_template (save_elem, targs);
}
return save_elem;
}
if (complain)

View File

@ -2359,7 +2359,7 @@ extern void GNU_xref_end PROTO((int));
extern void GNU_xref_file PROTO((char *));
extern void GNU_xref_start_scope PROTO((HOST_WIDE_INT));
extern void GNU_xref_end_scope PROTO((HOST_WIDE_INT, HOST_WIDE_INT, int, int, int));
extern void GNU_xref_def PROTO((tree, char *));
extern void GNU_xref_ref PROTO((tree, char *));
extern void GNU_xref_decl PROTO((tree, tree));
extern void GNU_xref_call PROTO((tree, char *));
extern void GNU_xref_function PROTO((tree, tree));

View File

@ -1233,11 +1233,9 @@ cp_convert (type, expr, convtype, flags)
{
tree rval;
rval = build_type_conversion (CONVERT_EXPR, type, e, 1);
if (rval) return rval;
if (code == BOOLEAN_TYPE)
cp_error ("`%#T' used where a `bool' was expected", intype);
else
cp_error ("`%#T' used where an `int' was expected", intype);
if (rval)
return rval;
cp_error ("`%#T' used where a `%T' was expected", intype, type);
return error_mark_node;
}
if (code == BOOLEAN_TYPE)

View File

@ -401,6 +401,11 @@ extern int flag_short_double;
extern int flag_no_builtin;
/* Nonzero means don't recognize the non-ANSI builtin functions.
-ansi sets this. */
extern int flag_no_nonansi_builtin;
/* Nonzero means disable GNU extensions. */
extern int flag_ansi;
@ -1743,6 +1748,7 @@ pushtag (name, type, globalize)
#else
d = build_decl (TYPE_DECL, name, type);
#endif
SET_DECL_ARTIFICIAL (d);
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
{
@ -1778,6 +1784,7 @@ pushtag (name, type, globalize)
/* Make nested declarations go into class-level scope. */
newdecl = 1;
d = build_decl (TYPE_DECL, name, type);
SET_DECL_ARTIFICIAL (d);
#ifdef DWARF_DEBUGGING_INFO
if (write_symbols == DWARF_DEBUG)
{
@ -1981,11 +1988,11 @@ decls_match (newdecl, olddecl)
for (i = 0; i < len; i++)
{
tree newarg = TREE_VEC_ELT (newargs, i);
tree oldarg = TREE_VEC_ELT (oldargs, i);
tree newarg = TREE_VALUE (TREE_VEC_ELT (newargs, i));
tree oldarg = TREE_VALUE (TREE_VEC_ELT (oldargs, i));
if (TREE_CODE (newarg) != TREE_CODE (oldarg))
return 0;
else if (TREE_CODE (newarg) == IDENTIFIER_NODE)
else if (TREE_CODE (newarg) == TYPE_DECL)
/* continue */;
else if (! comptypes (TREE_TYPE (newarg), TREE_TYPE (oldarg), 1))
return 0;
@ -2104,6 +2111,7 @@ duplicate_decls (newdecl, olddecl)
after implicit decl. */
;
else if (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_ARTIFICIAL (olddecl)
&& (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl)))
{
/* If you declare a built-in or predefined function name as static,
@ -2188,9 +2196,8 @@ duplicate_decls (newdecl, olddecl)
newdecl);
cp_error_at ("previous declaration `%#D' here", olddecl);
}
if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
TYPE_ARG_TYPES (TREE_TYPE (olddecl)), 2))
else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
TYPE_ARG_TYPES (TREE_TYPE (olddecl)), 2))
{
cp_error ("new declaration `%#D'", newdecl);
cp_error_at ("ambiguates old declaration `%#D'", olddecl);
@ -2678,7 +2685,8 @@ pushdecl (x)
/* don't do anything just yet */;
else if (TREE_CODE (t) != TREE_CODE (x))
{
if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (x) == TYPE_DECL)
if ((TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t))
|| (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)))
{
/* We do nothing special here, because C++ does such nasty
things with TYPE_DECLs. Instead, just let the TYPE_DECL
@ -4540,14 +4548,31 @@ init_decl_processing ()
sizetype,
endlink)),
BUILT_IN_ALLOCA, "alloca");
#if 0
builtin_function ("alloca",
build_function_type (ptr_type_node,
tree_cons (NULL_TREE,
sizetype,
endlink)),
BUILT_IN_ALLOCA, NULL_PTR);
/* Define alloca, ffs as builtins.
Declare _exit just to mark it as volatile. */
if (! flag_no_builtin && !flag_no_nonansi_builtin)
{
#if 0 /* Why is this disabled? (jason 8/9/94) */
temp = builtin_function ("alloca",
build_function_type (ptr_type_node,
tree_cons (NULL_TREE,
sizetype,
endlink)),
BUILT_IN_ALLOCA, NULL_PTR);
/* Suppress error if redefined as a non-function. */
DECL_BUILT_IN_NONANSI (temp) = 1;
#endif
temp = builtin_function ("ffs", int_ftype_int, BUILT_IN_FFS, NULL_PTR);
/* Suppress error if redefined as a non-function. */
DECL_BUILT_IN_NONANSI (temp) = 1;
temp = builtin_function ("_exit", build_function_type (void_type_node,
int_endlink),
NOT_BUILT_IN, NULL_PTR);
TREE_THIS_VOLATILE (temp) = 1;
TREE_SIDE_EFFECTS (temp) = 1;
/* Suppress error if redefined as a non-function. */
DECL_BUILT_IN_NONANSI (temp) = 1;
}
builtin_function ("__builtin_abs", int_ftype_int,
BUILT_IN_ABS, NULL_PTR);
@ -4647,6 +4672,23 @@ init_decl_processing ()
builtin_function ("strlen", sizet_ftype_string, BUILT_IN_STRLEN, NULL_PTR);
builtin_function ("sin", double_ftype_double, BUILT_IN_SIN, NULL_PTR);
builtin_function ("cos", double_ftype_double, BUILT_IN_COS, NULL_PTR);
/* Declare these functions volatile
to avoid spurious "control drops through" warnings. */
temp = builtin_function ("abort",
build_function_type (void_type_node, endlink),
NOT_BUILT_IN, NULL_PTR);
TREE_THIS_VOLATILE (temp) = 1;
TREE_SIDE_EFFECTS (temp) = 1;
/* Well, these are actually ANSI, but we can't set DECL_BUILT_IN on
them... */
DECL_BUILT_IN_NONANSI (temp) = 1;
temp = builtin_function ("exit", build_function_type (void_type_node,
int_endlink),
NOT_BUILT_IN, NULL_PTR);
TREE_THIS_VOLATILE (temp) = 1;
TREE_SIDE_EFFECTS (temp) = 1;
DECL_BUILT_IN_NONANSI (temp) = 1;
}
#if 0
@ -6315,9 +6357,11 @@ finish_decl (decl, init, asmspec_tree, need_pop)
expand_aggr_init (decl, init, 0);
}
/* Set this to 0 so we can tell whether an aggregate
which was initialized was ever used. */
if (TYPE_NEEDS_CONSTRUCTING (type))
/* Set this to 0 so we can tell whether an aggregate which
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)
TREE_USED (decl) = 0;
/* Store the cleanup, if there was one. */
@ -7283,7 +7327,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
goto found;
}
for (i = (int) RID_FIRST_MODIFIER; i < (int) RID_MAX; i++)
for (i = (int) RID_FIRST_MODIFIER; i < (int) RID_LAST_MODIFIER; i++)
{
if (ridpointers[i] == id)
{
@ -8965,14 +9009,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep),
TREE_TYPE (type), TYPE_ARG_TYPES (type));
/* Record presence of `static'. In C++, `inline' is like `static'.
Methods of classes should be public, unless we're dropping them
into some other file, so we don't clear TREE_PUBLIC for them. */
/* Record presence of `static'. In C++, `inline' is like `static'. */
publicp
= ((ctype
&& CLASSTYPE_INTERFACE_KNOWN (ctype))
|| !(RIDBIT_SETP (RID_STATIC, specbits)
|| RIDBIT_SETP (RID_INLINE, specbits)));
= !(RIDBIT_SETP (RID_STATIC, specbits)
|| RIDBIT_SETP (RID_INLINE, specbits));
decl = grokfndecl (ctype, type, original_name,
virtualp, flags, quals,
@ -8993,7 +9033,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
declaring main to be static. */
if (TREE_CODE (type) == METHOD_TYPE)
{
cp_error_at ("cannot declare member function `%D' to have static linkage", decl);
cp_pedwarn ("cannot declare member function `%D' to have static linkage", decl);
illegal_static = 1;
}
else if (! ctype
@ -9795,6 +9835,7 @@ xref_defn_tag (code_type_node, name, binfo)
if (! ANON_AGGRNAME_P (name))
{
register tree type_decl = build_decl (TYPE_DECL, ncp, rv);
SET_DECL_ARTIFICIAL (type_decl);
#ifdef DWARF_DEBUGGING_INFO
/* Mark the TYPE_DECL node created just above as a gratuitous one
so that dwarfout.c will know not to generate a TAG_typedef DIE
@ -9943,9 +9984,7 @@ xref_tag (code_type_node, name, binfo, globalize)
}
else
{
extern tree pending_vtables;
struct binding_level *old_b = class_binding_level;
int needs_writing;
ref = make_lang_type (code);
@ -9955,36 +9994,10 @@ xref_tag (code_type_node, name, binfo, globalize)
{
SET_SIGNATURE (ref);
CLASSTYPE_INTERFACE_ONLY (ref) = 0;
CLASSTYPE_INTERFACE_UNKNOWN (ref) = 0;
SET_CLASSTYPE_INTERFACE_UNKNOWN (ref);
CLASSTYPE_VTABLE_NEEDS_WRITING (ref) = 0;
}
/* Record how to set the access of this class's
virtual functions. If write_virtuals == 2 or 3, then
inline virtuals are ``extern inline''. */
switch (write_virtuals)
{
case 0:
case 1:
needs_writing = 1;
break;
case 2:
needs_writing = !! value_member (name, pending_vtables);
break;
case 3:
needs_writing = ! CLASSTYPE_INTERFACE_ONLY (ref)
&& CLASSTYPE_INTERFACE_KNOWN (ref);
break;
default:
needs_writing = 0;
}
/* Signatures don't have a vtable. As long as we don't have default
implementations, they behave as if `write_virtuals' were 3. */
if (tag_code == signature_type)
CLASSTYPE_VTABLE_NEEDS_WRITING (ref) = 0;
else
CLASSTYPE_VTABLE_NEEDS_WRITING (ref) = needs_writing;
#ifdef NONNESTED_CLASSES
/* Class types don't nest the way enums do. */
class_binding_level = (struct binding_level *)0;
@ -10682,15 +10695,14 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
/* If this function belongs to an interface, it is public.
If it belongs to someone else's interface, it is also external.
It doesn't matter whether it's inline or not. */
if (interface_unknown == 0)
if (interface_unknown == 0
&& ! TREE_PUBLIC (decl1))
{
TREE_PUBLIC (decl1) = 1;
DECL_EXTERNAL (decl1)
= (interface_only
|| (DECL_INLINE (decl1) && ! flag_implement_inlines));
}
else if (DECL_EXPLICIT_INSTANTIATION (decl1))
/* PUBLIC and EXTERNAL set by do_*_instantiation */;
else
{
/* This is a definition, not a reference.
@ -10699,7 +10711,10 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
defining how to inline. So set DECL_EXTERNAL in that case. */
DECL_EXTERNAL (decl1) = current_extern_inline;
DECL_DEFER_OUTPUT (decl1) = DECL_INLINE (decl1);
DECL_DEFER_OUTPUT (decl1)
= DECL_INLINE (decl1) && ! TREE_PUBLIC (decl1)
&& (DECL_FUNCTION_MEMBER_P (decl1)
|| DECL_TEMPLATE_INSTANTIATION (decl1));
}
if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1))
@ -11567,8 +11582,8 @@ finish_function (lineno, call_poplevel)
rest_of_compilation (fndecl);
}
if (DECL_INLINE (fndecl)
&& !TREE_ASM_WRITTEN (fndecl) && DECL_FUNCTION_MEMBER_P (fndecl))
if (DECL_INLINE (fndecl) && !TREE_ASM_WRITTEN (fndecl)
&& DECL_DEFER_OUTPUT (fndecl))
{
mark_inline_for_output (fndecl);
}

View File

@ -84,6 +84,11 @@ int flag_no_asm;
int flag_no_builtin;
/* Nonzero means don't recognize the non-ANSI builtin functions.
-ansi sets this. */
int flag_no_nonansi_builtin;
/* Nonzero means do some things the same way PCC does. */
int flag_traditional;
@ -361,6 +366,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
{"conserve-space", &flag_conserve_space, 1},
{"vtable-thunks", &flag_vtable_thunks, 1},
{"short-temps", &flag_short_temps, 1},
{"nonansi-builtins", &flag_no_nonansi_builtin, 0}
};
/* Decode the string P as a language-specific option.
@ -447,6 +453,10 @@ lang_decode_option (p)
flag_alt_external_templates = 0;
found = 1;
}
else if (!strcmp (p, "ansi-overloading"))
{
warning ("-fansi-overloading is no longer meaningful");
}
else for (j = 0;
!found && j < sizeof (lang_f_options) / sizeof (lang_f_options[0]);
j++)
@ -544,7 +554,8 @@ lang_decode_option (p)
else return 0;
}
else if (!strcmp (p, "-ansi"))
flag_no_asm = 1, dollars_in_ident = 0, flag_ansi = 1;
flag_no_asm = 1, dollars_in_ident = 0, flag_no_nonansi_builtin = 1,
flag_ansi = 1;
#ifdef SPEW_DEBUG
/* Undocumented, only ever used when you're invoking cc1plus by hand, since
it's probably safe to assume no sane person would ever want to use this
@ -983,7 +994,7 @@ grok_array_decl (array_expr, index_exp)
if (TYPE_LANG_SPECIFIC (type)
&& TYPE_OVERLOADS_ARRAY_REF (type))
return build_opfncall (ARRAY_REF, LOOKUP_NORMAL,
array_expr, index_exp, NULL_TREE);
array_expr, index_exp, NULL_TREE);
/* Otherwise, create an ARRAY_REF for a pointer or array type. */
if (TREE_CODE (type) == POINTER_TYPE
@ -1000,17 +1011,14 @@ grok_array_decl (array_expr, index_exp)
|| TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type);
if (TYPE_LANG_SPECIFIC (type)
&& TYPE_OVERLOADS_ARRAY_REF (type))
error ("array expression backwards");
else if (TREE_CODE (type) == POINTER_TYPE
|| TREE_CODE (type) == ARRAY_TYPE)
if (TREE_CODE (type) == POINTER_TYPE
|| TREE_CODE (type) == ARRAY_TYPE)
return build_array_ref (index_exp, array_expr);
else
error("`[]' applied to non-pointer type");
/* We gave an error, so give an error. Huh? */
return error_mark_node;
/* The expression E1[E2] is identical (by definition) to *((E1)+(E2)). */
return build_indirect_ref (build_binary_op (PLUS_EXPR, array_expr,
index_exp, 1),
"array indexing");
}
/* Given the cast expression EXP, checking out its validity. Either return
@ -1128,13 +1136,13 @@ check_classfn (ctype, cname, function)
}
if (methods != end)
cp_error ("argument list for `%D' does not match any in class `%T'",
fn_name, ctype);
cp_error ("argument list for `%#D' does not match any in class `%T'",
function, ctype);
else
{
methods = 0;
cp_error ("no `%D' member function declared in class `%T'",
fn_name, ctype);
cp_error ("no `%#D' member function declared in class `%T'",
function, ctype);
}
/* If we did not find the method in the class, add it to
@ -2067,9 +2075,13 @@ finish_anon_union (anon_union_decl)
return;
}
while (field)
for (; field; field = TREE_CHAIN (field))
{
tree decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field));
tree decl;
if (TREE_CODE (field) != FIELD_DECL)
continue;
decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field));
/* tell `pushdecl' that this is not tentative. */
DECL_INITIAL (decl) = error_mark_node;
TREE_PUBLIC (decl) = public_p;
@ -2096,7 +2108,6 @@ finish_anon_union (anon_union_decl)
TREE_PURPOSE of the following TREE_LIST. */
elems = tree_cons (NULL_TREE, decl, elems);
TREE_TYPE (elems) = type;
field = TREE_CHAIN (field);
}
if (static_p)
{
@ -2530,6 +2541,37 @@ walk_sigtables (typedecl_fn, vardecl_fn)
}
}
/* Determines the proper settings of TREE_PUBLIC and DECL_EXTERNAL for an
inline function at end-of-file. */
void
import_export_inline (decl)
tree decl;
{
if (TREE_PUBLIC (decl))
return;
/* If an explicit instantiation doesn't have TREE_PUBLIC set, it was with
'extern'. */
if (DECL_EXPLICIT_INSTANTIATION (decl)
|| (DECL_IMPLICIT_INSTANTIATION (decl) && ! flag_implicit_templates))
{
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = 1;
}
else if (DECL_FUNCTION_MEMBER_P (decl))
{
tree ctype = DECL_CLASS_CONTEXT (decl);
if (CLASSTYPE_INTERFACE_KNOWN (ctype))
{
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl)
= (CLASSTYPE_INTERFACE_ONLY (ctype)
|| (DECL_INLINE (decl) && ! flag_implement_inlines));
}
}
}
extern int parse_time, varconst_time;
#define TIMEVAR(VAR, BODY) \
@ -2835,24 +2877,12 @@ finish_file ()
0; don't crash. */
if (TREE_ASM_WRITTEN (decl) || DECL_SAVED_INSNS (decl) == 0)
continue;
if (DECL_FUNCTION_MEMBER_P (decl) && !TREE_PUBLIC (decl))
{
tree ctype = DECL_CLASS_CONTEXT (decl);
if (CLASSTYPE_INTERFACE_KNOWN (ctype))
{
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl)
= (CLASSTYPE_INTERFACE_ONLY (ctype)
|| (DECL_INLINE (decl) && ! flag_implement_inlines));
}
}
import_export_inline (decl);
if (TREE_PUBLIC (decl)
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
|| flag_keep_inline_functions)
{
if (DECL_EXTERNAL (decl)
|| (DECL_IMPLICIT_INSTANTIATION (decl)
&& ! flag_implicit_templates))
if (DECL_EXTERNAL (decl))
assemble_external (decl);
else
{
@ -2879,9 +2909,7 @@ finish_file ()
if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
&& ! TREE_ASM_WRITTEN (decl))
{
if (DECL_EXTERNAL (decl)
|| (DECL_IMPLICIT_INSTANTIATION (decl)
&& ! flag_implicit_templates))
if (DECL_EXTERNAL (decl))
assemble_external (decl);
else
{

View File

@ -30,6 +30,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
typedef char* cp_printer PROTO((HOST_WIDE_INT, int));
extern cp_printer * cp_printers[256];
/* Whether or not we should try to be quiet for errors and warnings; this is
used to avoid being too talkative about problems with tentative choices
when we're computing the conversion costs for a method call. */
int cp_silent = 0;
typedef void errorfn (); /* deliberately vague */
extern char* cp_file_of PROTO((tree));
@ -150,7 +155,8 @@ cp_error (format, arglist)
arglist_dcl
{
extern errorfn error;
cp_thing (error, 0, format, arglist);
if (! cp_silent)
cp_thing (error, 0, format, arglist);
}
void
@ -159,7 +165,8 @@ cp_warning (format, arglist)
arglist_dcl
{
extern errorfn warning;
cp_thing (warning, 0, format, arglist);
if (! cp_silent)
cp_thing (warning, 0, format, arglist);
}
void
@ -168,7 +175,8 @@ cp_pedwarn (format, arglist)
arglist_dcl
{
extern errorfn pedwarn;
cp_thing (pedwarn, 0, format, arglist);
if (! cp_silent)
cp_thing (pedwarn, 0, format, arglist);
}
void
@ -177,7 +185,8 @@ cp_compiler_error (format, arglist)
arglist_dcl
{
extern errorfn compiler_error;
cp_thing (compiler_error, 0, format, arglist);
if (! cp_silent)
cp_thing (compiler_error, 0, format, arglist);
}
void
@ -195,7 +204,8 @@ cp_error_at (format, arglist)
arglist_dcl
{
extern errorfn error_with_file_and_line;
cp_thing (error_with_file_and_line, 1, format, arglist);
if (! cp_silent)
cp_thing (error_with_file_and_line, 1, format, arglist);
}
void
@ -204,7 +214,8 @@ cp_warning_at (format, arglist)
arglist_dcl
{
extern errorfn warning_with_file_and_line;
cp_thing (warning_with_file_and_line, 1, format, arglist);
if (! cp_silent)
cp_thing (warning_with_file_and_line, 1, format, arglist);
}
void
@ -213,5 +224,6 @@ cp_pedwarn_at (format, arglist)
arglist_dcl
{
extern errorfn pedwarn_with_file_and_line;
cp_thing (pedwarn_with_file_and_line, 1, format, arglist);
if (! cp_silent)
cp_thing (pedwarn_with_file_and_line, 1, format, arglist);
}

View File

@ -104,6 +104,8 @@ dump_readonly_or_volatile (t, p)
if (p == before) OB_PUTC (' ');
if (TYPE_READONLY (t))
OB_PUTS ("const");
if (TYPE_READONLY (t) && TYPE_VOLATILE (t))
OB_PUTC (' ');
if (TYPE_VOLATILE (t))
OB_PUTS ("volatile");
if (p == after) OB_PUTC (' ');
@ -1228,6 +1230,14 @@ dump_expr (t, nop)
break;
}
case TREE_LIST:
if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL)
{
OB_PUTID (DECL_NAME (TREE_VALUE (t)));
break;
}
/* else fall through */
/* This list is incomplete, but should suffice for now.
It is very important that `sorry' does not call
`report_error_function'. That could cause an infinite loop. */

View File

@ -217,6 +217,7 @@ perform_member_init (member, name, init, explicit)
expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
}
}
expand_cleanups_to (NULL_TREE);
if (flag_handle_exceptions && TYPE_NEEDS_DESTRUCTOR (type))
cp_warning ("caution, member `%D' may not be destroyed in the presense of an exception during construction", member);
}
@ -230,11 +231,14 @@ sort_member_init (t)
tree init_list = NULL_TREE;
tree fields_to_unmark = NULL_TREE;
int found;
int last_pos = 0;
tree last_field;
for (member = TYPE_FIELDS (t); member ; member = TREE_CHAIN (member))
{
int pos;
found = 0;
for (x = current_member_init_list ; x ; x = TREE_CHAIN (x))
for (x = current_member_init_list, pos = 0; x; x = TREE_CHAIN (x), ++pos)
{
/* If we cleared this out, then pay no attention to it. */
if (TREE_PURPOSE (x) == NULL_TREE)
@ -264,6 +268,17 @@ sort_member_init (t)
field);
continue;
}
else
{
if (pos < last_pos && extra_warnings)
{
cp_warning_at ("member initializers for `%#D'", last_field);
cp_warning_at (" and `%#D'", field);
warning (" will be re-ordered to match declaration order");
}
last_pos = pos;
last_field = field;
}
init_list = chainon (init_list,
build_tree_list (name, TREE_VALUE (x)));
@ -500,9 +515,10 @@ emit_base_init (t, immediately)
continue;
member = convert_pointer_to (binfo, current_class_decl);
expand_aggr_init_1 (t_binfo, 0,
expand_aggr_init_1 (binfo, 0,
build_indirect_ref (member, NULL_PTR), init,
BINFO_OFFSET_ZEROP (binfo), LOOKUP_COMPLAIN);
BINFO_OFFSET_ZEROP (binfo), LOOKUP_NORMAL);
expand_cleanups_to (NULL_TREE);
}
if (pass == 0)
@ -568,9 +584,10 @@ emit_base_init (t, immediately)
current_class_decl, BINFO_OFFSET (base_binfo));
ref = build_indirect_ref (base, NULL_PTR);
expand_aggr_init_1 (t_binfo, 0, ref, NULL_TREE,
expand_aggr_init_1 (base_binfo, 0, ref, NULL_TREE,
BINFO_OFFSET_ZEROP (base_binfo),
LOOKUP_COMPLAIN);
LOOKUP_NORMAL);
expand_cleanups_to (NULL_TREE);
}
}
CLEAR_BINFO_BASEINIT_MARKED (base_binfo);
@ -655,11 +672,6 @@ emit_base_init (t, immediately)
current_member_init_list = NULL_TREE;
/* It is possible for the initializers to need cleanups.
Expand those cleanups now that all the initialization
has been done. */
expand_cleanups_to (NULL_TREE);
if (! immediately)
{
extern rtx base_init_insns;
@ -734,6 +746,7 @@ expand_aggr_vbase_init_1 (binfo, exp, addr, init_list)
/* Call constructors, but don't set up vtables. */
expand_aggr_init_1 (binfo, exp, ref, init, 0,
LOOKUP_COMPLAIN|LOOKUP_SPECULATIVELY);
expand_cleanups_to (NULL_TREE);
CLEAR_BINFO_VBASE_INIT_MARKED (binfo);
}
@ -1966,12 +1979,6 @@ build_offset_ref (cname, name)
name, NULL_TREE, 1);
#endif
fnfields = lookup_fnfields (TYPE_BINFO (type), name, 1);
fields = lookup_field (type, name, 0, 0);
if (fields == error_mark_node || fnfields == error_mark_node)
return error_mark_node;
if (current_class_type == 0
|| get_base_distance (type, current_class_type, 0, &basetypes) == -1)
{
@ -1986,6 +1993,12 @@ build_offset_ref (cname, name)
else
decl = C_C_D;
fnfields = lookup_fnfields (basetypes, name, 1);
fields = lookup_field (basetypes, name, 0, 0);
if (fields == error_mark_node || fnfields == error_mark_node)
return error_mark_node;
/* A lot of this logic is now handled in lookup_field and
lookup_fnfield. */
if (fnfields)
@ -2018,7 +2031,6 @@ build_offset_ref (cname, name)
{
extern int flag_save_memoized_contexts;
/* This does not handle access checking yet. */
if (DECL_CHAIN (t) == NULL_TREE || dtor)
{
enum access_type access;
@ -3261,7 +3273,7 @@ build_new (placement, decl, init, use_global_new)
build_tree_list (NULL_TREE, rval))));
}
return save_expr (rval);
return rval;
}
/* `expand_vec_init' performs initialization of a vector of aggregate

View File

@ -960,15 +960,6 @@ set_yydebug (value)
#endif
}
#ifdef SPEW_DEBUG
const char *
debug_yytranslate (value)
int value;
{
return yytname[YYTRANSLATE (value)];
}
#endif
/* Functions and data structures for #pragma interface.
@ -1786,13 +1777,6 @@ cons_up_default_function (type, name, fields, kind)
warn_if_unknown_interface ();
t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2));
store_pending_inline (fn, t);
if (interface_unknown)
TREE_PUBLIC (fn) = 0;
else
{
TREE_PUBLIC (fn) = 1;
DECL_EXTERNAL (fn) = interface_only;
}
}
finish_method (fn);
@ -2182,17 +2166,17 @@ check_for_missing_semicolon (type)
if (yychar < 0)
yychar = yylex ();
if (yychar > 255
&& yychar != SCSPEC
&& yychar != IDENTIFIER
&& yychar != TYPENAME)
if ((yychar > 255
&& yychar != SCSPEC
&& yychar != IDENTIFIER
&& yychar != TYPENAME)
|| end_of_file)
{
if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))
error ("semicolon missing after %s declaration",
TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct");
else
error ("semicolon missing after declaration of `%s'",
TYPE_NAME_STRING (type));
cp_error ("semicolon missing after declaration of `%T'", type);
shadow_tag (build_tree_list (0, type));
}
/* Could probably also hack cases where class { ... } f (); appears. */

View File

@ -58,14 +58,16 @@ enum rid
RID_VOLATILE,
RID_FRIEND,
RID_VIRTUAL,
RID_SIGNED,
RID_AUTO,
RID_MUTABLE,
/* This is where grokdeclarator ends its search when setting the specbits. */
RID_PUBLIC,
RID_PRIVATE,
RID_PROTECTED,
RID_SIGNED,
RID_EXCEPTION,
RID_RAISES,
RID_AUTO,
RID_MUTABLE,
RID_TEMPLATE,
RID_SIGNATURE,
/* Before adding enough to get up to 64, the RIDBIT_* macros
@ -76,6 +78,7 @@ enum rid
#define NORID RID_UNUSED
#define RID_FIRST_MODIFIER RID_EXTERN
#define RID_LAST_MODIFIER RID_MUTABLE
/* The type that can represent all values of RIDBIT. */
/* We assume that we can stick in at least 32 bits into this. */

View File

@ -852,18 +852,17 @@ build_decl_overload (dname, parms, for_method)
/* 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) DELETE_EXPR])
return get_identifier ("__builtin_delete");
else if (dname == ansi_opname[(int) VEC_DELETE_EXPR])
return get_identifier ("__builtin_vec_delete");
else if (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 ();

View File

@ -895,7 +895,8 @@ paren_expr_or_null:
cond_stmt_keyword);
$$ = integer_zero_node; }
| '(' expr ')'
{ $$ = $2; }
{ $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node,
bool_truthvalue_conversion ($2)); }
;
paren_cond_or_null:
@ -904,13 +905,16 @@ paren_cond_or_null:
cond_stmt_keyword);
$$ = integer_zero_node; }
| '(' condition ')'
{ $$ = $2; }
{ $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node,
bool_truthvalue_conversion ($2)); }
;
xcond:
/* empty */
{ $$ = NULL_TREE; }
| condition
{ $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node,
bool_truthvalue_conversion ($$)); }
| error
{ $$ = NULL_TREE; }
;
@ -1548,7 +1552,7 @@ primary:
if (TREE_CODE (TREE_TYPE ($1))
!= TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($3))))
cp_error ("`%E' is not of type `%T'", $1, $3);
$$ = void_zero_node;
$$ = convert (void_type_node, $1);
}
| object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT
{
@ -1557,7 +1561,7 @@ primary:
if (TREE_CODE (TREE_TYPE ($1))
!= TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($2))))
cp_error ("`%E' is not of type `%T'", $1, $2);
$$ = void_zero_node;
$$ = convert (void_type_node, $1);
}
;
@ -2398,25 +2402,59 @@ base_class_access_list:
;
left_curly: '{'
{ tree t;
{ tree t = $<ttype>0;
push_obstacks_nochange ();
end_temporary_allocation ();
if (! IS_AGGR_TYPE ($<ttype>0))
if (! IS_AGGR_TYPE (t))
{
$<ttype>0 = make_lang_type (RECORD_TYPE);
TYPE_NAME ($<ttype>0) = get_identifier ("erroneous type");
t = $<ttype>0 = make_lang_type (RECORD_TYPE);
TYPE_NAME (t) = get_identifier ("erroneous type");
}
if (TYPE_SIZE ($<ttype>0))
duplicate_tag_error ($<ttype>0);
if (TYPE_SIZE ($<ttype>0) || TYPE_BEING_DEFINED ($<ttype>0))
if (TYPE_SIZE (t))
duplicate_tag_error (t);
if (TYPE_SIZE (t) || TYPE_BEING_DEFINED (t))
{
t = make_lang_type (TREE_CODE ($<ttype>0));
t = make_lang_type (TREE_CODE (t));
pushtag (TYPE_IDENTIFIER ($<ttype>0), t, 0);
$<ttype>0 = t;
}
pushclass ($<ttype>0, 0);
TYPE_BEING_DEFINED ($<ttype>0) = 1;
pushclass (t, 0);
TYPE_BEING_DEFINED (t) = 1;
/* Reset the interface data, at the earliest possible
moment, as it might have been set via a class foo;
before. */
/* Don't change signatures. */
if (! IS_SIGNATURE (t))
{
extern tree pending_vtables;
int needs_writing;
tree name = TYPE_IDENTIFIER (t);
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
/* Record how to set the access of this class's
virtual functions. If write_virtuals == 2 or 3, then
inline virtuals are ``extern inline''. */
switch (write_virtuals)
{
case 0:
case 1:
needs_writing = 1;
break;
case 2:
needs_writing = !! value_member (name, pending_vtables);
break;
case 3:
needs_writing = ! CLASSTYPE_INTERFACE_ONLY (t)
&& CLASSTYPE_INTERFACE_KNOWN (t);
break;
default:
needs_writing = 0;
}
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = needs_writing;
}
#if 0
t = TYPE_IDENTIFIER ($<ttype>0);
if (t && IDENTIFIER_TEMPLATE (t))
@ -3053,7 +3091,7 @@ simple_if:
{ cond_stmt_keyword = "if"; }
.pushlevel paren_cond_or_null
{ emit_line_note (input_filename, lineno);
expand_start_cond (bool_truthvalue_conversion ($4), 0); }
expand_start_cond ($4, 0); }
implicitly_scoped_stmt
;
@ -3108,7 +3146,7 @@ simple_stmt:
expand_start_loop (1);
cond_stmt_keyword = "while"; }
.pushlevel paren_cond_or_null
{ expand_exit_loop_if_false (0, bool_truthvalue_conversion ($4)); }
{ expand_exit_loop_if_false (0, $4); }
already_scoped_stmt
{ expand_end_bindings (getdecls (), kept_level_p (), 1);
poplevel (kept_level_p (), 1, 0);
@ -3124,7 +3162,7 @@ simple_stmt:
cond_stmt_keyword = "do"; }
paren_expr_or_null ';'
{ emit_line_note (input_filename, lineno);
expand_exit_loop_if_false (0, bool_truthvalue_conversion ($6));
expand_exit_loop_if_false (0, $6);
expand_end_loop ();
clear_momentary ();
finish_stmt (); }
@ -3135,7 +3173,7 @@ simple_stmt:
expand_start_loop_continue_elsewhere (1); }
.pushlevel xcond ';'
{ emit_line_note (input_filename, lineno);
if ($4) expand_exit_loop_if_false (0, bool_truthvalue_conversion ($4)); }
if ($4) expand_exit_loop_if_false (0, $4); }
xexpr ')'
/* Don't let the tree nodes for $7 be discarded
by clear_momentary during the parsing of the next stmt. */
@ -3156,7 +3194,7 @@ simple_stmt:
expand_start_loop_continue_elsewhere (1); }
.pushlevel xcond ';'
{ emit_line_note (input_filename, lineno);
if ($4) expand_exit_loop_if_false (0, bool_truthvalue_conversion ($4)); }
if ($4) expand_exit_loop_if_false (0, $4); }
xexpr ')'
/* Don't let the tree nodes for $7 be discarded
by clear_momentary during the parsing of the next stmt. */
@ -3175,7 +3213,7 @@ simple_stmt:
}
| SWITCH .pushlevel '(' condition ')'
{ emit_line_note (input_filename, lineno);
c_expand_start_case ($4);
c_expand_start_case ($4);
/* Don't let the tree nodes for $4 be discarded by
clear_momentary during the parsing of the next stmt. */
push_momentary (); }
@ -3761,3 +3799,13 @@ operator_name:
;
%%
#ifdef SPEW_DEBUG
const char *
debug_yytranslate (value)
int value;
{
return yytname[YYTRANSLATE (value)];
}
#endif

View File

@ -2408,16 +2408,19 @@ do_function_instantiation (declspecs, declarator, storage)
if (flag_external_templates)
return;
if (DECL_EXPLICIT_INSTANTIATION (result) && ! DECL_EXTERNAL (result))
if (DECL_EXPLICIT_INSTANTIATION (result) && TREE_PUBLIC (result))
return;
SET_DECL_EXPLICIT_INSTANTIATION (result);
TREE_PUBLIC (result) = 1;
if (storage == NULL_TREE)
DECL_EXTERNAL (result) = DECL_INLINE (result) && ! flag_implement_inlines;
{
TREE_PUBLIC (result) = 1;
DECL_EXTERNAL (result) = (DECL_INLINE (result)
&& ! flag_implement_inlines);
}
else if (storage == ridpointers[(int) RID_EXTERN])
DECL_EXTERNAL (result) = 1;
;
else
cp_error ("storage class `%D' applied to template instantiation",
storage);
@ -2454,7 +2457,7 @@ do_type_instantiation (name, storage)
}
/* We've already instantiated this. */
if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && ! CLASSTYPE_INTERFACE_ONLY (t))
if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && CLASSTYPE_INTERFACE_KNOWN (t))
{
if (! extern_p)
cp_pedwarn ("multiple explicit instantiation of `%#T'", t);
@ -2462,11 +2465,11 @@ do_type_instantiation (name, storage)
}
SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t);
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! extern_p;
SET_CLASSTYPE_INTERFACE_KNOWN (t);
CLASSTYPE_INTERFACE_ONLY (t) = extern_p;
if (! extern_p)
{
SET_CLASSTYPE_INTERFACE_KNOWN (t);
CLASSTYPE_INTERFACE_ONLY (t) = 0;
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = 1;
CLASSTYPE_DEBUG_REQUESTED (t) = 1;
TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0;
rest_of_type_compilation (t, 1);
@ -2478,9 +2481,12 @@ do_type_instantiation (name, storage)
for (; tmp; tmp = TREE_CHAIN (tmp))
{
SET_DECL_EXPLICIT_INSTANTIATION (tmp);
TREE_PUBLIC (tmp) = 1;
DECL_EXTERNAL (tmp)
= (extern_p || (DECL_INLINE (tmp) && ! flag_implement_inlines));
if (! extern_p)
{
TREE_PUBLIC (tmp) = 1;
DECL_EXTERNAL (tmp) = (DECL_INLINE (tmp)
&& ! flag_implement_inlines);
}
}
#if 0

View File

@ -1626,6 +1626,31 @@ make_deep_copy (t)
TREE_OPERAND (t, 0) = make_deep_copy (TREE_OPERAND (t, 0));
return t;
case POINTER_TYPE:
return build_pointer_type (make_deep_copy (TREE_TYPE (t)));
case REFERENCE_TYPE:
return build_reference_type (make_deep_copy (TREE_TYPE (t)));
case FUNCTION_TYPE:
return build_function_type (make_deep_copy (TREE_TYPE (t)),
make_deep_copy (TYPE_ARG_TYPES (t)));
case ARRAY_TYPE:
return build_array_type (make_deep_copy (TREE_TYPE (t)),
make_deep_copy (TYPE_DOMAIN (t)));
case OFFSET_TYPE:
return build_offset_type (make_deep_copy (TYPE_OFFSET_BASETYPE (t)),
make_deep_copy (TREE_TYPE (t)));
case METHOD_TYPE:
return build_method_type
(make_deep_copy (TYPE_METHOD_BASETYPE (t)),
build_function_type
(make_deep_copy (TREE_TYPE (t)),
make_deep_copy (TREE_CHAIN (TYPE_ARG_TYPES (t)))));
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (t))
return build_ptrmemfunc_type
(make_deep_copy (TYPE_PTRMEMFUNC_FN_TYPE (t)));
/* else fall through */
/* This list is incomplete, but should suffice for now.
It is very important that `sorry' does not call
`report_error_function'. That could cause an infinite loop. */

View File

@ -734,8 +734,6 @@ comp_target_types (ttl, ttr, nptrs)
ttr = TYPE_MAIN_VARIANT (ttr);
if (ttl == ttr)
return 1;
if (TREE_CODE (ttr) == TEMPLATE_TYPE_PARM)
return 1;
if (TREE_CODE (ttr) != TREE_CODE (ttl))
return 0;
@ -813,12 +811,14 @@ common_base_type (tt1, tt2)
if (UNIQUELY_DERIVED_FROM_P (tt2, tt1))
return tt2;
#if 0
/* If they share a virtual baseclass, that's good enough. */
for (tmp = CLASSTYPE_VBASECLASSES (tt1); tmp; tmp = TREE_CHAIN (tmp))
{
if (binfo_member (BINFO_TYPE (tmp), CLASSTYPE_VBASECLASSES (tt2)))
return BINFO_TYPE (tmp);
}
#endif
/* Otherwise, try to find a unique baseclass of TT1
that is shared by TT2, and follow that down. */
@ -904,6 +904,8 @@ compparms (parms1, parms2, strict)
return t2 == void_list_node && TREE_PURPOSE (t1);
return TREE_PURPOSE (t1) || TREE_PURPOSE (t2);
}
#if 0
/* Default parms are not part of the type of a function. */
if (strict != 3 && TREE_PURPOSE (t1) && TREE_PURPOSE (t2))
{
int cmp = simple_cst_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2));
@ -912,6 +914,7 @@ compparms (parms1, parms2, strict)
if (cmp == 0)
return 0;
}
#endif
t1 = TREE_CHAIN (t1);
t2 = TREE_CHAIN (t2);
@ -959,8 +962,6 @@ comp_target_parms (parms1, parms2, strict)
p2 = TREE_VALUE (t2);
if (p1 == p2)
continue;
if (TREE_CODE (p2) == TEMPLATE_TYPE_PARM)
continue;
if ((TREE_CODE (p1) == POINTER_TYPE && TREE_CODE (p2) == POINTER_TYPE)
|| (TREE_CODE (p1) == REFERENCE_TYPE && TREE_CODE (p2) == REFERENCE_TYPE))
@ -970,9 +971,6 @@ comp_target_parms (parms1, parms2, strict)
== TYPE_MAIN_VARIANT (TREE_TYPE (p2))))
continue;
if (TREE_CODE (TREE_TYPE (p2)) == TEMPLATE_TYPE_PARM)
continue;
/* The following is wrong for contravariance,
but many programs depend on it. */
if (TREE_TYPE (p1) == void_type_node)
@ -2530,13 +2528,15 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
&& (type == 0 || TREE_CODE (type) != REFERENCE_TYPE))
val = TREE_OPERAND (val, 0);
if ((type == 0 || TREE_CODE (type) != REFERENCE_TYPE)
&& (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE
if (type == 0 || TREE_CODE (type) != REFERENCE_TYPE)
{
if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (val)) == METHOD_TYPE))
val = default_conversion (val);
|| TREE_CODE (TREE_TYPE (val)) == METHOD_TYPE)
val = default_conversion (val);
val = require_complete_type (val);
val = require_complete_type (val);
}
if (val == error_mark_node)
continue;
@ -2555,7 +2555,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
}
else
{
#ifdef PROMOTE_PROTOTYPES
#if 0 && defined (PROMOTE_PROTOTYPES)
/* This breaks user-defined conversions. */
/* Rather than truncating and then reextending,
convert directly to int, if that's the type we will want. */
if (! flag_traditional
@ -4682,11 +4683,20 @@ build_conditional_expr (ifexp, op1, op2)
{
if (result_type == error_mark_node)
{
message_2_types (error, "common base type of types `%s' and `%s' is ambiguous",
TREE_TYPE (type1), TREE_TYPE (type2));
cp_error ("common base type of types `%T' and `%T' is ambiguous",
TREE_TYPE (type1), TREE_TYPE (type2));
result_type = ptr_type_node;
}
else result_type = TYPE_POINTER_TO (result_type);
else
{
if (pedantic
&& result_type != TREE_TYPE (type1)
&& result_type != TREE_TYPE (type2))
cp_pedwarn ("`%T' and `%T' converted to `%T *' in conditional expression",
type1, type2, result_type);
result_type = TYPE_POINTER_TO (result_type);
}
}
else
{
@ -7210,7 +7220,8 @@ c_expand_start_case (exp)
exp = index;
}
expand_start_case (1, exp, type, "switch statement");
expand_start_case (1, build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp),
type, "switch statement");
return exp;
}

View File

@ -631,7 +631,7 @@ digest_init (type, init, tail)
tree type, init, *tail;
{
enum tree_code code = TREE_CODE (type);
tree element = 0;
tree element = NULL_TREE;
tree old_tail_contents;
/* Nonzero if INIT is a braced grouping, which comes in as a CONSTRUCTOR
tree node which has no TREE_TYPE. */