46 Cygnus<->FSF merge
From-SVN: r7943
This commit is contained in:
parent
07d0cbddd4
commit
0059501924
208
gcc/cp/ChangeLog
208
gcc/cp/ChangeLog
@ -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
|
||||
|
@ -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);
|
||||
|
114
gcc/cp/class.c
114
gcc/cp/class.c
@ -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)
|
||||
|
@ -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));
|
||||
|
@ -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)
|
||||
|
139
gcc/cp/decl.c
139
gcc/cp/decl.c
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
28
gcc/cp/lex.c
28
gcc/cp/lex.c
@ -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. */
|
||||
|
11
gcc/cp/lex.h
11
gcc/cp/lex.h
@ -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. */
|
||||
|
@ -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 ();
|
||||
|
@ -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
|
||||
|
28
gcc/cp/pt.c
28
gcc/cp/pt.c
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user