parent
2670328aa5
commit
e349ee739e
127
gcc/cp/ChangeLog
127
gcc/cp/ChangeLog
|
@ -3,6 +3,131 @@ Sat May 11 04:33:50 1996 Doug Evans <dje@canuck.cygnus.com>
|
|||
* decl2.c (finish_vtable_vardecl): Surround DECL_ONE_ONLY with ifdef.
|
||||
(finish_file): Likewise.
|
||||
|
||||
Wed May 29 17:04:33 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* cvt.c (build_up_reference): Redo how and when temporaries are
|
||||
created.
|
||||
* decl.c (grok_reference_init): Don't try and be smart about
|
||||
running cleanups.
|
||||
|
||||
Wed May 29 16:02:08 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* cvt.c (build_up_reference): Add NULL_TREE to all calls to build
|
||||
(TARGET_EXPR...), now that it has 4 arguments.
|
||||
* tree.c (build_cplus_new): Ditto.
|
||||
|
||||
Thu May 23 16:40:30 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* error.c (dump_expr, case CAST_EXPR): Handle T() properly.
|
||||
|
||||
* pt.c (instantiate_decl): Don't call push/pop_cp_function_context.
|
||||
* decl.c (struct saved_scope): Remove named_labels,
|
||||
{base,member}_init_list.
|
||||
(maybe_push_to_top_level): Don't set them. Call
|
||||
push_cp_function_context if appropriate.
|
||||
(pop_from_top_level): Likewise.
|
||||
|
||||
* method.c (do_build_assign_ref): Remove obsolete check of
|
||||
TYPE_HAS_ASSIGN_REF (basetype).
|
||||
|
||||
* decl.c (grokfndecl): Diagnose user definition of
|
||||
implicitly-declared methods.
|
||||
|
||||
Thu May 23 12:13:08 1996 Bob Manson <manson@charmed.cygnus.com>
|
||||
|
||||
* method.c (do_build_copy_constructor): Add code to give
|
||||
meaningful error messages instead of crashing.
|
||||
(do_build_assign_ref): Don't synthesize assignment operators for
|
||||
classes containing reference or const members.
|
||||
|
||||
* class.c (struct base_info): Remove cant_synth_copy_ctor
|
||||
and cant_synth_asn_ref.
|
||||
(finish_base_struct): Remove the code that tries to conditionalize
|
||||
synthesis of copy constructors & assignment operators based on
|
||||
access permissions. Instead, let it fail when it tries to
|
||||
synthesize the copy constructor. This will give meaningful error
|
||||
messages instead of silently generating code to perform a bitcopy.
|
||||
|
||||
Wed May 22 11:45:19 1996 Bob Manson <manson@charmed.cygnus.com>
|
||||
|
||||
* lex.c (real_yylex): Remove old-n-crufty #if 0 code for
|
||||
determining types for constant values.
|
||||
|
||||
* decl.c (struct named_label_list): Use instead of stuffing
|
||||
random items into a TREE_LIST node.
|
||||
(named_label_uses): Use the new struct.
|
||||
(poplevel): Ditto.
|
||||
(lookup_label): Ditto.
|
||||
(define_label): Add an error message to tell the user the line
|
||||
where the goto is located in addition to the destination of the
|
||||
goto.
|
||||
(init_decl_processing): Use NULL instead of NULL_TREE to initialize
|
||||
named_label_uses.
|
||||
(finish_function): Ditto.
|
||||
|
||||
(start_decl): Complain about defining a static data member
|
||||
in a different type from which it was declared.
|
||||
|
||||
Wed May 22 09:33:23 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* cvt.c (build_expr_type_conversion): Adjust.
|
||||
|
||||
Tue May 21 11:21:56 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* call.c (build_method_call): Always convert 'this' to the
|
||||
appropriate type.
|
||||
|
||||
* search.c (add_conversions): Put the conversion function in
|
||||
TREE_VALUE, the type in TREE_PURPOSE.
|
||||
* cvt.c (build_type_conversion): Adjust.
|
||||
* call.c (user_harshness): Adjust.
|
||||
|
||||
* method.c (emit_thunk): Call temporary_allocation and
|
||||
permanent_allocation around the ASM_OUTPUT_MI_THUNK case, too.
|
||||
|
||||
* tree.c (build_cplus_array_type): Handle tweaking of
|
||||
TYPE_MAIN_VARIANT here.
|
||||
* typeck.c (common_type): Not here.
|
||||
|
||||
* typeck.c (complete_type): Only try to complete an array type if
|
||||
it has a domain.
|
||||
|
||||
Mon May 20 14:55:59 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* decl.c (grokvardecl): Call complete_type.
|
||||
(grokdeclarator): Call complete_type for PARM_DECLs.
|
||||
|
||||
Fri May 17 16:41:17 1996 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* pt.c (instantiate_class_template): Re-set
|
||||
CLASSTYPE_GOT_SEMICOLON after calling finish_struct_1.
|
||||
|
||||
Fri May 17 14:56:55 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* cp-tree.h (cp_expand_decl_cleanup): Remove, the backend is now
|
||||
smart enough to do it right.
|
||||
* tree.c (cp_expand_decl_cleanup): Ditto.
|
||||
* decl.c (cp_finish_decl): Use expand_decl_cleanup instead of
|
||||
cp_expand_decl_cleanup.
|
||||
(store_parm_decls): Ditto.
|
||||
(hack_incomplete_structures): Ditto.
|
||||
* except.c (push_eh_cleanup): Ditto.
|
||||
|
||||
Fri May 17 13:13:51 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* expr.c (expand_expr, cond UNSAVE_EXPR): Move from the C++
|
||||
frontend to the backend where it belongs.
|
||||
* tree.c (unsave_expr): Ditto.
|
||||
(unsave_expr_now): Ditto.
|
||||
* tree.def (UNSAVE_EXPR): Ditto.
|
||||
* cp-tree.h (unsave_expr): Ditto.
|
||||
(unsave_expr_now): Ditto.
|
||||
|
||||
Fri May 17 11:02:41 1996 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* init.c (emit_base_init): Make sure the partial EH cleanups live
|
||||
on the function_obstack.
|
||||
|
||||
Thu May 16 15:29:33 1996 Bob Manson <manson@charmed.cygnus.com>
|
||||
|
||||
* expr.c (do_case): Don't try to dereference null TREE_TYPEs
|
||||
|
@ -2369,7 +2494,7 @@ Mon Nov 13 15:45:34 1995 Mike Stump <mrs@cygnus.com>
|
|||
indirect binding.
|
||||
* decl.c (cp_finish_decl): Ensure that we reuse stack slots as fast
|
||||
as they are unused.
|
||||
(expand_static_init): Diotto.
|
||||
(expand_static_init): Ditto.
|
||||
(cplus_expand_expr_stmt): Ditto.
|
||||
* decl2.c (finish_file): Ditto.
|
||||
* init.c (perform_member_init): Ditto.
|
||||
|
|
|
@ -641,10 +641,10 @@ user_harshness (type, parmtype)
|
|||
{
|
||||
struct harshness_code tmp;
|
||||
|
||||
if (winner && TREE_PURPOSE (winner) == TREE_PURPOSE (conv))
|
||||
if (winner && TREE_VALUE (winner) == TREE_VALUE (conv))
|
||||
continue;
|
||||
|
||||
if (tmp = convert_harshness (type, TREE_VALUE (conv), NULL_TREE),
|
||||
if (tmp = convert_harshness (type, TREE_PURPOSE (conv), NULL_TREE),
|
||||
(tmp.code < USER_CODE) && (tmp.distance >= 0))
|
||||
{
|
||||
if (winner)
|
||||
|
@ -2531,8 +2531,8 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
|||
{
|
||||
int sub_flags = DECL_CONSTRUCTOR_P (function) ? flags : LOOKUP_NORMAL;
|
||||
basetype = TREE_TYPE (instance);
|
||||
if (TYPE_METHOD_BASETYPE (TREE_TYPE (function)) != TYPE_MAIN_VARIANT (basetype)
|
||||
&& TYPE_USES_COMPLEX_INHERITANCE (basetype))
|
||||
if (TYPE_METHOD_BASETYPE (TREE_TYPE (function))
|
||||
!= TYPE_MAIN_VARIANT (basetype))
|
||||
{
|
||||
basetype = DECL_CLASS_CONTEXT (function);
|
||||
instance_ptr = convert_pointer_to (basetype, instance_ptr);
|
||||
|
|
|
@ -1408,8 +1408,6 @@ struct base_info
|
|||
tree rtti;
|
||||
char cant_have_default_ctor;
|
||||
char cant_have_const_ctor;
|
||||
char cant_synth_copy_ctor;
|
||||
char cant_synth_asn_ref;
|
||||
char no_const_asn_ref;
|
||||
char base_has_virtual;
|
||||
};
|
||||
|
@ -1465,13 +1463,8 @@ finish_base_struct (t, b, t_binfo)
|
|||
TREE_VEC_ELT (binfos, j) = TREE_VEC_ELT (binfos, j+1);
|
||||
}
|
||||
|
||||
if (TYPE_HAS_INIT_REF (basetype)
|
||||
&& !TYPE_HAS_CONST_INIT_REF (basetype))
|
||||
if (! TYPE_HAS_CONST_INIT_REF (basetype))
|
||||
b->cant_have_const_ctor = 1;
|
||||
if (! TYPE_HAS_INIT_REF (basetype)
|
||||
|| (TYPE_HAS_NONPUBLIC_CTOR (basetype) == 2
|
||||
&& ! is_friend_type (t, basetype)))
|
||||
b->cant_synth_copy_ctor = 1;
|
||||
|
||||
if (TYPE_HAS_CONSTRUCTOR (basetype)
|
||||
&& ! TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype))
|
||||
|
@ -1488,11 +1481,6 @@ finish_base_struct (t, b, t_binfo)
|
|||
if (TYPE_HAS_ASSIGN_REF (basetype)
|
||||
&& !TYPE_HAS_CONST_ASSIGN_REF (basetype))
|
||||
b->no_const_asn_ref = 1;
|
||||
if (! TYPE_HAS_ASSIGN_REF (basetype)
|
||||
|| TYPE_HAS_ABSTRACT_ASSIGN_REF (basetype)
|
||||
|| (TYPE_HAS_NONPUBLIC_ASSIGN_REF (basetype) == 2
|
||||
&& ! is_friend_type (t, basetype)))
|
||||
b->cant_synth_asn_ref = 1;
|
||||
|
||||
b->n_ancestors += CLASSTYPE_N_SUPERCLASSES (basetype);
|
||||
TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype);
|
||||
|
@ -1645,8 +1633,6 @@ finish_base_struct (t, b, t_binfo)
|
|||
{
|
||||
cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
|
||||
basetype, t);
|
||||
b->cant_synth_asn_ref = 1;
|
||||
b->cant_synth_copy_ctor = 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
|
@ -1660,8 +1646,6 @@ finish_base_struct (t, b, t_binfo)
|
|||
if (extra_warnings)
|
||||
cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
|
||||
basetype, t);
|
||||
b->cant_synth_asn_ref = 1;
|
||||
b->cant_synth_copy_ctor = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3016,8 +3000,6 @@ finish_struct_1 (t, attributes, warn_anon)
|
|||
tree vfields;
|
||||
int cant_have_default_ctor;
|
||||
int cant_have_const_ctor;
|
||||
int cant_synth_copy_ctor;
|
||||
int cant_synth_asn_ref;
|
||||
int no_const_asn_ref;
|
||||
|
||||
/* The index of the first base class which has virtual
|
||||
|
@ -3108,8 +3090,6 @@ finish_struct_1 (t, attributes, warn_anon)
|
|||
CLASSTYPE_RTTI (t) = base_info.rtti;
|
||||
cant_have_default_ctor = base_info.cant_have_default_ctor;
|
||||
cant_have_const_ctor = base_info.cant_have_const_ctor;
|
||||
cant_synth_copy_ctor = base_info.cant_synth_copy_ctor;
|
||||
cant_synth_asn_ref = base_info.cant_synth_asn_ref;
|
||||
no_const_asn_ref = base_info.no_const_asn_ref;
|
||||
base_has_virtual = base_info.base_has_virtual;
|
||||
n_baseclasses = TREE_VEC_LENGTH (BINFO_BASETYPES (t_binfo));
|
||||
|
@ -3126,8 +3106,6 @@ finish_struct_1 (t, attributes, warn_anon)
|
|||
last_x = NULL_TREE;
|
||||
cant_have_default_ctor = 0;
|
||||
cant_have_const_ctor = 0;
|
||||
cant_synth_copy_ctor = 0;
|
||||
cant_synth_asn_ref = 0;
|
||||
no_const_asn_ref = 0;
|
||||
base_has_virtual = 0;
|
||||
}
|
||||
|
@ -3273,7 +3251,7 @@ finish_struct_1 (t, attributes, warn_anon)
|
|||
|
||||
#if 0
|
||||
if (DECL_NAME (x) == constructor_name (t))
|
||||
cant_have_default_ctor = cant_synth_copy_ctor = 1;
|
||||
cant_have_default_ctor = 1;
|
||||
#endif
|
||||
|
||||
if (TREE_TYPE (x) == error_mark_node)
|
||||
|
@ -3313,8 +3291,8 @@ finish_struct_1 (t, attributes, warn_anon)
|
|||
aggregate, initialization by a brace-enclosed list) is the
|
||||
only way to initialize nonstatic const and reference
|
||||
members. */
|
||||
cant_synth_asn_ref = 1;
|
||||
cant_have_default_ctor = 1;
|
||||
TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
|
||||
|
||||
if (! TYPE_HAS_CONSTRUCTOR (t) && extra_warnings)
|
||||
{
|
||||
|
@ -3336,8 +3314,8 @@ finish_struct_1 (t, attributes, warn_anon)
|
|||
aggregate, initialization by a brace-enclosed list) is the
|
||||
only way to initialize nonstatic const and reference
|
||||
members. */
|
||||
cant_synth_asn_ref = 1;
|
||||
cant_have_default_ctor = 1;
|
||||
TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
|
||||
|
||||
if (! TYPE_HAS_CONSTRUCTOR (t) && !IS_SIGNATURE (t)
|
||||
&& extra_warnings)
|
||||
|
@ -3508,18 +3486,10 @@ finish_struct_1 (t, attributes, warn_anon)
|
|||
TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (type);
|
||||
}
|
||||
|
||||
if (! TYPE_HAS_INIT_REF (type)
|
||||
|| (TYPE_HAS_NONPUBLIC_CTOR (type)
|
||||
&& ! is_friend (t, type)))
|
||||
cant_synth_copy_ctor = 1;
|
||||
else if (!TYPE_HAS_CONST_INIT_REF (type))
|
||||
if (!TYPE_HAS_CONST_INIT_REF (type))
|
||||
cant_have_const_ctor = 1;
|
||||
|
||||
if (! TYPE_HAS_ASSIGN_REF (type)
|
||||
|| (TYPE_HAS_NONPUBLIC_ASSIGN_REF (type)
|
||||
&& ! is_friend (t, type)))
|
||||
cant_synth_asn_ref = 1;
|
||||
else if (!TYPE_HAS_CONST_ASSIGN_REF (type))
|
||||
if (!TYPE_HAS_CONST_ASSIGN_REF (type))
|
||||
no_const_asn_ref = 1;
|
||||
|
||||
if (TYPE_HAS_CONSTRUCTOR (type)
|
||||
|
@ -3614,8 +3584,7 @@ finish_struct_1 (t, attributes, warn_anon)
|
|||
}
|
||||
|
||||
/* Create default copy constructor, if needed. */
|
||||
if (! TYPE_HAS_INIT_REF (t) && ! cant_synth_copy_ctor
|
||||
&& ! IS_SIGNATURE (t))
|
||||
if (! TYPE_HAS_INIT_REF (t) && ! IS_SIGNATURE (t))
|
||||
{
|
||||
/* ARM 12.18: You get either X(X&) or X(const X&), but
|
||||
not both. --Chip */
|
||||
|
@ -3630,8 +3599,7 @@ finish_struct_1 (t, attributes, warn_anon)
|
|||
TYPE_HAS_COMPLEX_ASSIGN_REF (t)
|
||||
|= TYPE_HAS_ASSIGN_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t);
|
||||
|
||||
if (! TYPE_HAS_ASSIGN_REF (t) && ! cant_synth_asn_ref
|
||||
&& ! IS_SIGNATURE (t))
|
||||
if (! TYPE_HAS_ASSIGN_REF (t) && ! IS_SIGNATURE (t))
|
||||
{
|
||||
tree default_fn = cons_up_default_function (t, name,
|
||||
5 + no_const_asn_ref);
|
||||
|
|
|
@ -2403,7 +2403,6 @@ extern void print_lang_statistics PROTO((void));
|
|||
extern tree array_type_nelts_total PROTO((tree));
|
||||
extern tree array_type_nelts_top PROTO((tree));
|
||||
extern tree break_out_target_exprs PROTO((tree));
|
||||
extern int cp_expand_decl_cleanup PROTO((tree, tree));
|
||||
extern tree get_type_decl PROTO((tree));
|
||||
extern tree vec_binfo_member PROTO((tree, tree));
|
||||
extern tree hack_decl_function_context PROTO((tree));
|
||||
|
|
519
gcc/cp/cvt.c
519
gcc/cp/cvt.c
|
@ -596,13 +596,24 @@ build_up_reference (type, arg, flags, checkconst)
|
|||
|
||||
if (TREE_ADDRESSABLE (targ) == 0)
|
||||
{
|
||||
tree temp;
|
||||
if (! (flags&INDIRECT_BIND)
|
||||
&& toplevel_bindings_p ())
|
||||
{
|
||||
tree temp = get_temp_name (argtype, 0);
|
||||
/* Give this new temp some rtl and initialize it. */
|
||||
DECL_INITIAL (temp) = targ;
|
||||
TREE_STATIC (temp) = 1;
|
||||
cp_finish_decl (temp, targ, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
|
||||
/* Do this after declaring it static. */
|
||||
rval = build_unary_op (ADDR_EXPR, temp, 0);
|
||||
TREE_TYPE (rval) = type;
|
||||
literal_flag = TREE_CONSTANT (rval);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype))
|
||||
{
|
||||
temp = build_cplus_new (argtype, targ);
|
||||
rval = build1 (ADDR_EXPR, type, temp);
|
||||
goto done;
|
||||
arg = build_cplus_new (argtype, targ);
|
||||
}
|
||||
else if (flags&INDIRECT_BIND)
|
||||
{
|
||||
|
@ -611,41 +622,41 @@ build_up_reference (type, arg, flags, checkconst)
|
|||
use INDIRECT_BIND. */
|
||||
tree slot = build (VAR_DECL, argtype);
|
||||
layout_decl (slot, 0);
|
||||
rval = build (TARGET_EXPR, argtype, slot, arg, NULL_TREE);
|
||||
rval = build1 (ADDR_EXPR, type, rval);
|
||||
goto done;
|
||||
arg = build (TARGET_EXPR, argtype, slot, arg, NULL_TREE, NULL_TREE);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = get_temp_name (argtype, 0);
|
||||
if (toplevel_bindings_p ())
|
||||
{
|
||||
/* Give this new temp some rtl and initialize it. */
|
||||
DECL_INITIAL (temp) = targ;
|
||||
TREE_STATIC (temp) = 1;
|
||||
cp_finish_decl (temp, targ, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
|
||||
/* Do this after declaring it static. */
|
||||
rval = build_unary_op (ADDR_EXPR, temp, 0);
|
||||
TREE_TYPE (rval) = type;
|
||||
literal_flag = TREE_CONSTANT (rval);
|
||||
goto done;
|
||||
}
|
||||
tree temp = get_temp_name (argtype, 0);
|
||||
rval = build_unary_op (ADDR_EXPR, temp, 0);
|
||||
if (binfo && !BINFO_OFFSET_ZEROP (binfo))
|
||||
rval = convert_pointer_to (target_type, rval);
|
||||
else
|
||||
{
|
||||
rval = build_unary_op (ADDR_EXPR, temp, 0);
|
||||
if (binfo && !BINFO_OFFSET_ZEROP (binfo))
|
||||
rval = convert_pointer_to (target_type, rval);
|
||||
else
|
||||
TREE_TYPE (rval) = type;
|
||||
TREE_TYPE (rval) = type;
|
||||
|
||||
temp = build (MODIFY_EXPR, argtype, temp, arg);
|
||||
TREE_SIDE_EFFECTS (temp) = 1;
|
||||
return build (COMPOUND_EXPR, type, temp, rval);
|
||||
temp = build (MODIFY_EXPR, argtype, temp, arg);
|
||||
TREE_SIDE_EFFECTS (temp) = 1;
|
||||
return build (COMPOUND_EXPR, type, temp, rval);
|
||||
}
|
||||
}
|
||||
|
||||
if (! (flags&INDIRECT_BIND))
|
||||
{
|
||||
if (TREE_CODE (arg) == TARGET_EXPR)
|
||||
{
|
||||
tree decl = TREE_OPERAND (arg, 0);
|
||||
tree cleanup;
|
||||
|
||||
if (! toplevel_bindings_p ())
|
||||
{
|
||||
expand_decl (decl);
|
||||
cleanup = maybe_build_cleanup (decl);
|
||||
if (cleanup)
|
||||
expand_decl_cleanup (decl, cleanup);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
rval = build1 (ADDR_EXPR, type, arg);
|
||||
|
||||
rval = build1 (ADDR_EXPR, type, arg);
|
||||
|
||||
done:
|
||||
if (TYPE_USES_COMPLEX_INHERITANCE (argtype)
|
||||
|
@ -1498,10 +1509,10 @@ build_type_conversion (code, xtype, expr, for_sure)
|
|||
/* Nope; try looking for others. */
|
||||
for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv))
|
||||
{
|
||||
if (winner && TREE_PURPOSE (winner) == TREE_PURPOSE (conv))
|
||||
if (winner && TREE_VALUE (winner) == TREE_VALUE (conv))
|
||||
continue;
|
||||
|
||||
if (can_convert (xtype, TREE_VALUE (conv)))
|
||||
if (can_convert (xtype, TREE_PURPOSE (conv)))
|
||||
{
|
||||
if (winner)
|
||||
{
|
||||
|
@ -1510,7 +1521,7 @@ build_type_conversion (code, xtype, expr, for_sure)
|
|||
cp_error ("ambiguous conversion from `%T' to `%T'", basetype,
|
||||
xtype);
|
||||
cp_error (" candidate conversions include `%T' and `%T'",
|
||||
TREE_VALUE (winner), TREE_VALUE (conv));
|
||||
TREE_PURPOSE (winner), TREE_PURPOSE (conv));
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
@ -1521,7 +1532,7 @@ build_type_conversion (code, xtype, expr, for_sure)
|
|||
|
||||
if (winner)
|
||||
return build_type_conversion_1 (xtype, basetype, expr,
|
||||
TREE_PURPOSE (winner), for_sure);
|
||||
DECL_NAME (TREE_VALUE (winner)), for_sure);
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
@ -1580,10 +1591,10 @@ build_expr_type_conversion (desires, expr, complain)
|
|||
int win = 0;
|
||||
tree candidate;
|
||||
|
||||
if (winner && TREE_PURPOSE (winner) == TREE_PURPOSE (conv))
|
||||
if (winner && TREE_VALUE (winner) == TREE_VALUE (conv))
|
||||
continue;
|
||||
|
||||
candidate = TREE_VALUE (conv);
|
||||
candidate = TREE_PURPOSE (conv);
|
||||
if (TREE_CODE (candidate) == REFERENCE_TYPE)
|
||||
candidate = TREE_TYPE (candidate);
|
||||
|
||||
|
@ -1609,7 +1620,7 @@ build_expr_type_conversion (desires, expr, complain)
|
|||
cp_error ("ambiguous default type conversion from `%T'",
|
||||
basetype);
|
||||
cp_error (" candidate conversions include `%T' and `%T'",
|
||||
TREE_VALUE (winner), TREE_VALUE (conv));
|
||||
TREE_PURPOSE (winner), TREE_PURPOSE (conv));
|
||||
}
|
||||
return error_mark_node;
|
||||
}
|
||||
|
@ -1620,11 +1631,11 @@ build_expr_type_conversion (desires, expr, complain)
|
|||
|
||||
if (winner)
|
||||
{
|
||||
tree type = TREE_VALUE (winner);
|
||||
tree type = TREE_PURPOSE (winner);
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
type = TREE_TYPE (type);
|
||||
return build_type_conversion_1 (type, basetype, expr,
|
||||
TREE_PURPOSE (winner), 1);
|
||||
DECL_NAME (TREE_VALUE (winner)), 1);
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
|
@ -1819,6 +1830,41 @@ null_ptr_cst (t)
|
|||
return (INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t));
|
||||
}
|
||||
|
||||
tree
|
||||
build_conv (code, type, from)
|
||||
enum tree_code code;
|
||||
tree type, from;
|
||||
{
|
||||
tree t = build1 (code, type, from);
|
||||
int rank = ICS_STD_RANK (from);
|
||||
switch (code)
|
||||
{
|
||||
case PROMO_CONV:
|
||||
if (rank < PROMO_RANK)
|
||||
rank = PROMO_RANK;
|
||||
break;
|
||||
|
||||
case PTR_CONV:
|
||||
case PMEM_CONV:
|
||||
case BASE_CONV:
|
||||
case STD_CONV:
|
||||
if (rank < STD_RANK)
|
||||
rank = STD_RANK;
|
||||
break;
|
||||
|
||||
case PBOOL_CONV:
|
||||
if (rank < PBOOL_RANK)
|
||||
rank = PBOOL_RANK;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ICS_STD_RANK (t) = rank;
|
||||
ICS_USER_FLAG (t) = ICS_USER_FLAG (from);
|
||||
return t;
|
||||
}
|
||||
|
||||
tree
|
||||
standard_conversion (to, from, expr)
|
||||
tree to, from, expr;
|
||||
|
@ -1830,25 +1876,27 @@ standard_conversion (to, from, expr)
|
|||
if (from == to)
|
||||
return from;
|
||||
|
||||
conv = from;
|
||||
conv = build1 (EXACT_CONV, from, expr);
|
||||
if (TREE_CODE (expr) == USER_CONV)
|
||||
ICS_USER_FLAG (conv) = 1;
|
||||
|
||||
if (fcode == FUNCTION_TYPE)
|
||||
{
|
||||
from = build_pointer_type (from);
|
||||
fcode = TREE_CODE (from);
|
||||
conv = build1 (LVALUE_CONV, from, conv);
|
||||
conv = build_conv (LVALUE_CONV, from, conv);
|
||||
}
|
||||
else if (fcode == ARRAY_TYPE)
|
||||
{
|
||||
from = build_pointer_type (TREE_TYPE (from));
|
||||
fcode = TREE_CODE (from);
|
||||
conv = build1 (LVALUE_CONV, from, conv);
|
||||
conv = build_conv (LVALUE_CONV, from, conv);
|
||||
}
|
||||
|
||||
if ((tcode == POINTER_TYPE || TYPE_PTRMEMFUNC_P (to))
|
||||
&& expr && null_ptr_cst (expr))
|
||||
{
|
||||
conv = build1 (CONV_CONV, to, conv);
|
||||
conv = build_conv (STD_CONV, to, conv);
|
||||
}
|
||||
else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE)
|
||||
{
|
||||
|
@ -1864,7 +1912,7 @@ standard_conversion (to, from, expr)
|
|||
from = cp_build_type_variant (void_type_node,
|
||||
TYPE_READONLY (TREE_TYPE (from)),
|
||||
TYPE_VOLATILE (TREE_TYPE (from)));
|
||||
conv = build1 (CONV_CONV, from, conv);
|
||||
conv = build_conv (PTR_CONV, from, conv);
|
||||
}
|
||||
else if (ufcode == OFFSET_TYPE && utcode == OFFSET_TYPE)
|
||||
{
|
||||
|
@ -1877,7 +1925,7 @@ standard_conversion (to, from, expr)
|
|||
1)))
|
||||
{
|
||||
from = build_offset_type (tbase, TREE_TYPE (TREE_TYPE (from)));
|
||||
conv = build1 (CONV_CONV, from, conv);
|
||||
conv = build_conv (PMEM_CONV, from, conv);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
@ -1890,7 +1938,7 @@ standard_conversion (to, from, expr)
|
|||
from = cp_build_type_variant (TREE_TYPE (to),
|
||||
TYPE_READONLY (TREE_TYPE (from)),
|
||||
TYPE_VOLATILE (TREE_TYPE (from)));
|
||||
conv = build1 (CONV_CONV, from, conv);
|
||||
conv = build_conv (PTR_CONV, from, conv);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
@ -1901,7 +1949,7 @@ standard_conversion (to, from, expr)
|
|||
if (! comptypes (from, to, 1) && comp_ptr_ttypes (to, from))
|
||||
{
|
||||
from = to;
|
||||
conv = build1 (QUAL_CONV, from, conv);
|
||||
conv = build_conv (QUAL_CONV, from, conv);
|
||||
}
|
||||
}
|
||||
else if (TYPE_PTRMEMFUNC_P (to) && TYPE_PTRMEMFUNC_P (from))
|
||||
|
@ -1923,29 +1971,32 @@ standard_conversion (to, from, expr)
|
|||
TYPE_VOLATILE (fbase));
|
||||
from = build_cplus_method_type (from, TREE_TYPE (fromfn),
|
||||
TREE_CHAIN (TYPE_ARG_TYPES (fromfn)));
|
||||
conv = build1 (CONV_CONV, from, conv);
|
||||
conv = build_conv (PMEM_CONV, from, conv);
|
||||
}
|
||||
else if (tcode == BOOLEAN_TYPE)
|
||||
{
|
||||
if (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE
|
||||
|| fcode == POINTER_TYPE)
|
||||
return build1 (CONV_CONV, to, conv);
|
||||
else
|
||||
if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE
|
||||
|| fcode == POINTER_TYPE || TYPE_PTRMEMFUNC_P (from)))
|
||||
return 0;
|
||||
|
||||
if (fcode == POINTER_TYPE || TYPE_PTRMEMFUNC_P (from))
|
||||
conv = build_conv (PBOOL_CONV, to, conv);
|
||||
else
|
||||
conv = build_conv (STD_CONV, to, conv);
|
||||
}
|
||||
else if (INTEGRAL_CODE_P (tcode) || tcode == REAL_TYPE)
|
||||
{
|
||||
if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE))
|
||||
return 0;
|
||||
else if (to == type_promotes_to (from))
|
||||
conv = build1 (PROMO_CONV, to, conv);
|
||||
conv = build_conv (PROMO_CONV, to, conv);
|
||||
else
|
||||
conv = build1 (CONV_CONV, to, conv);
|
||||
conv = build_conv (STD_CONV, to, conv);
|
||||
}
|
||||
else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
|
||||
&& DERIVED_FROM_P (to, from))
|
||||
{
|
||||
conv = build1 (CONV_CONV, to, conv);
|
||||
conv = build_conv (BASE_CONV, to, conv);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
@ -1958,16 +2009,366 @@ implicit_conversion (to, from, expr, flags)
|
|||
tree to, from, expr;
|
||||
int flags;
|
||||
{
|
||||
tree conv = standard_conversion (to, from, expr);
|
||||
tree t, conv = standard_conversion (to, from, expr);
|
||||
struct z_candidate *cand;
|
||||
|
||||
if (conv || (flags & LOOKUP_NO_CONVERSION))
|
||||
return conv;
|
||||
|
||||
flags |= LOOKUP_NO_CONVERSION;
|
||||
|
||||
/* try constructors */;
|
||||
/* try conversion ops */;
|
||||
cand = build_user_type_conversion_1 (to, expr, flags);
|
||||
if (! cand)
|
||||
return NULL_TREE;
|
||||
|
||||
conv = cand->second_conv;
|
||||
|
||||
for (t = conv; TREE_CODE (TREE_OPERAND (t, 0)) != EXACT_MATCH; )
|
||||
t = TREE_OPERAND (t, 0));
|
||||
|
||||
TREE_OPERAND (t, 0) = build (USER_CONV
|
||||
|
||||
return conv;
|
||||
}
|
||||
|
||||
struct z_candidate *
|
||||
add_method_candidate (candidates, method, instance, parms, flags)
|
||||
struct z_candidate *candidates;
|
||||
tree method, instance, parms;
|
||||
int flags;
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
struct z_candidate *
|
||||
build_user_type_conversion_1 (totype, expr, flags)
|
||||
tree totype, expr;
|
||||
int flags;
|
||||
{
|
||||
struct z_candidate *candidates, *cand;
|
||||
tree fromtype = TREE_TYPE (expr);
|
||||
tree ctors = NULL_TREE, convs = NULL_TREE, t;
|
||||
|
||||
if (IS_AGGR_TYPE (totype))
|
||||
ctors = lookup_fnfields (TYPE_BINFO (totype), ctor_identifier, 0);
|
||||
if (IS_AGGR_TYPE (fromtype))
|
||||
convs = lookup_conversions (fromtype);
|
||||
|
||||
if (ctors)
|
||||
ctors = TREE_VALUE (ctors);
|
||||
for (; ctors; ctors = DECL_CHAIN (ctors))
|
||||
{
|
||||
candidates = add_ctor_candidate (candidates, ctors, expr, flags);
|
||||
}
|
||||
|
||||
for (; convs; convs = TREE_CHAIN (convs))
|
||||
{
|
||||
tree fn = TREE_VALUE (convs);
|
||||
tree ics = standard_conversion (totype, TREE_TYPE (TREE_TYPE (fn)), 0);
|
||||
if (ics)
|
||||
{
|
||||
candidates = add_method_candidate
|
||||
(candidates, fn, expr, NULL_TREE, flags);
|
||||
candidates->second_ics = ics;
|
||||
}
|
||||
}
|
||||
|
||||
if (! any_viable (candidates))
|
||||
{
|
||||
if (flags & LOOKUP_COMPLAIN)
|
||||
cp_error ("no viable candidates");
|
||||
return 0;
|
||||
}
|
||||
|
||||
candidates = splice_viable (candidates);
|
||||
cand = tourney (candidates, totype);
|
||||
|
||||
if (cand == 0)
|
||||
{
|
||||
if (flags & LOOKUP_COMPLAIN)
|
||||
cp_error ("ambiguous user-defined type conversion");
|
||||
}
|
||||
|
||||
return cand;
|
||||
}
|
||||
|
||||
/* Compare two implicit conversion sequences according to the rules set out in
|
||||
[over.ics.rank]. Return values:
|
||||
|
||||
1: ics1 is better than ics2
|
||||
-1: ics2 is better than ics1
|
||||
0: ics1 and ics2 are indistinguishable */
|
||||
|
||||
int
|
||||
compare_ics (ics1, ics2)
|
||||
tree ics1, ics2;
|
||||
{
|
||||
tree main1, main2;
|
||||
|
||||
if (ICS_RANK (ics1) > ICS_RANK (ics2))
|
||||
return 1;
|
||||
else if (ICS_RANK (ics1) < ICS_RANK (ics2))
|
||||
return -1;
|
||||
|
||||
/* User-defined conversion sequence U1 is a better conversion sequence
|
||||
than another user-defined conversion sequence U2 if they contain the
|
||||
same user-defined conversion operator or constructor and if the sec-
|
||||
ond standard conversion sequence of U1 is better than the second
|
||||
standard conversion sequence of U2. */
|
||||
|
||||
if (ICS_RANK (ics1) == USER_RANK)
|
||||
{
|
||||
tree t1, t2;
|
||||
|
||||
for (t1 = ics1; TREE_CODE (t1) != USER_CONV; t1 = TREE_OPERAND (t1, 0))
|
||||
;
|
||||
for (t2 = ics2; TREE_CODE (t2) != USER_CONV; t2 = TREE_OPERAND (t2, 0))
|
||||
;
|
||||
|
||||
if (USER_CONV_FN (t1) != USER_CONV_FN (t2))
|
||||
return 0;
|
||||
else if (ICS_STD_RANK (ics1) > ICS_STD_RANK (ics2))
|
||||
return 1;
|
||||
else if (ICS_STD_RANK (ics1) < ICS_STD_RANK (ics2))
|
||||
return -1;
|
||||
|
||||
/* else fall through */
|
||||
}
|
||||
|
||||
#if 0 /* Handled by ranking */
|
||||
/* A conversion that is not a conversion of a pointer, or pointer to
|
||||
member, to bool is better than another conversion that is such a
|
||||
conversion. */
|
||||
{
|
||||
int bool1 = TREE_CODE (ics1) == BOOL_CONV;
|
||||
int bool2 = TREE_CODE (ics2) == BOOL_CONV;
|
||||
|
||||
if (bool1)
|
||||
{
|
||||
tree it = TREE_TYPE (TREE_OPERAND (ics1, 0));
|
||||
if (TREE_CODE (it) != POINTER_TYPE
|
||||
&& ! TYPE_PTRMEMFUNC_TYPE (it))
|
||||
bool1 = 0;
|
||||
}
|
||||
if (bool2)
|
||||
{
|
||||
tree it = TREE_TYPE (TREE_OPERAND (ics2, 0));
|
||||
if (TREE_CODE (it) != POINTER_TYPE
|
||||
&& ! TYPE_PTRMEMFUNC_TYPE (it))
|
||||
bool2 = 0;
|
||||
}
|
||||
if (bool1 && ! bool2)
|
||||
return 1;
|
||||
if (bool2 && ! bool1)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (TREE_CODE (ics1) == QUAL_CONV)
|
||||
main1 = TREE_OPERAND (ics1, 0);
|
||||
else
|
||||
main1 = ics1;
|
||||
|
||||
if (TREE_CODE (ics2) == QUAL_CONV)
|
||||
main2 = TREE_OPERAND (ics2, 0);
|
||||
else
|
||||
main2 = ics2;
|
||||
|
||||
if (TREE_CODE (main1) != TREE_CODE (main2))
|
||||
return 0;
|
||||
|
||||
if (TREE_CODE (main1) == PTR_CONV || TREE_CODE (main1) == PMEM_CONV
|
||||
|| TREE_CODE (main1) == REF_BIND)
|
||||
{
|
||||
tree to1 = TREE_TYPE (main1);
|
||||
tree from1 = TREE_TYPE (TREE_OPERAND (main1, 0));
|
||||
tree to2 = TREE_TYPE (main2);
|
||||
tree from2 = TREE_TYPE (TREE_OPERAND (main2, 0));
|
||||
int distf, distt;
|
||||
|
||||
/* Standard conversion sequence S1 is a better conversion sequence than
|
||||
standard conversion sequence S2 if...
|
||||
|
||||
S1 and S2 differ only in their qualification conversion and they
|
||||
yield types identical except for cv-qualifiers and S2 adds all the
|
||||
qualifiers that S1 adds (and in the same places) and S2 adds yet
|
||||
more cv-qualifiers than S1, or the similar case with reference
|
||||
binding15). */
|
||||
if (from1 == from2 && to1 == to2)
|
||||
{
|
||||
to1 = TREE_TYPE (TREE_TYPE (ics1));
|
||||
to2 = TREE_TYPE (TREE_TYPE (ics2));
|
||||
if (TYPE_READONLY (to1) >= TYPE_READONLY (to2)
|
||||
&& TYPE_VOLATILE (to1) > TYPE_VOLATILE (to2))
|
||||
return 1;
|
||||
else if (TYPE_READONLY (to1) > TYPE_READONLY (to2)
|
||||
&& TYPE_VOLATILE (to1) == TYPE_VOLATILE (to2))
|
||||
return 1;
|
||||
else if (TYPE_READONLY (to1) <= TYPE_READONLY (to2)
|
||||
&& TYPE_VOLATILE (to1) < TYPE_VOLATILE (to2))
|
||||
return -1;
|
||||
else if (TYPE_READONLY (to1) < TYPE_READONLY (to2)
|
||||
&& TYPE_VOLATILE (to1) == TYPE_VOLATILE (to2))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (TYPE_PTRMEMFUNC_P (to1))
|
||||
{
|
||||
to1 = TYPE_METHOD_BASETYPE (TYPE_PTRMEMFUNC_FN_TYPE (to1));
|
||||
from1 = TYPE_METHOD_BASETYPE (TYPE_PTRMEMFUNC_FN_TYPE (from1));
|
||||
}
|
||||
else
|
||||
{
|
||||
to1 = TREE_TYPE (to1);
|
||||
from1 = TREE_TYPE (from1);
|
||||
|
||||
if (TREE_CODE (to1) == OFFSET_TYPE)
|
||||
{
|
||||
to1 = TYPE_OFFSET_BASETYPE (to1);
|
||||
from1 = TYPE_OFFSET_BASETYPE (from1);
|
||||
}
|
||||
}
|
||||
|
||||
if (TYPE_PTRMEMFUNC_P (to2))
|
||||
{
|
||||
to2 = TYPE_METHOD_BASETYPE (TYPE_PTRMEMFUNC_FN_TYPE (to2));
|
||||
from2 = TYPE_METHOD_BASETYPE (TYPE_PTRMEMFUNC_FN_TYPE (from2));
|
||||
}
|
||||
else
|
||||
{
|
||||
to2 = TREE_TYPE (to2);
|
||||
from2 = TREE_TYPE (from2);
|
||||
|
||||
if (TREE_CODE (to2) == OFFSET_TYPE)
|
||||
{
|
||||
to2 = TYPE_OFFSET_BASETYPE (to2);
|
||||
from2 = TYPE_OFFSET_BASETYPE (from2);
|
||||
}
|
||||
}
|
||||
|
||||
if (! (IS_AGGR_TYPE (from1) && IS_AGGR_TYPE (from2)))
|
||||
return 0;
|
||||
|
||||
distf = get_base_distance (from1, from2, 0, 0);
|
||||
if (distf == -1)
|
||||
distf = -get_base_distance (from2, from1, 0, 0);
|
||||
if (distf == -1)
|
||||
return 0;
|
||||
|
||||
/* If class B is derived directly or indirectly from class A, conver-
|
||||
sion of B* to A* is better than conversion of B* to void*, and
|
||||
conversion of A* to void* is better than conversion of B* to void*. */
|
||||
|
||||
if (TREE_CODE (to1) == VOID_TYPE && TREE_CODE (to2) == VOID_TYPE)
|
||||
{
|
||||
if (distf > 0)
|
||||
return 1;
|
||||
else if (distf < 0)
|
||||
return -1;
|
||||
}
|
||||
else if (TREE_CODE (to2) == VOID_TYPE && IS_AGGR_TYPE (to1)
|
||||
&& get_base_distance (to1, from1, 0, 0) != -1)
|
||||
return 1;
|
||||
else if (TREE_CODE (to1) == VOID_TYPE && IS_AGGR_TYPE (to2)
|
||||
&& get_base_distance (to2, from2, 0, 0) != -1)
|
||||
return -1;
|
||||
|
||||
if (! (IS_AGGR_TYPE (to1) && IS_AGGR_TYPE (to2)))
|
||||
return 0;
|
||||
|
||||
/* If class B is derived directly or indirectly from class A and class
|
||||
C is derived directly or indirectly from B */
|
||||
|
||||
distt = get_base_distance (to1, to2, 0, 0);
|
||||
if (distt == -1)
|
||||
distt = -get_base_distance (to2, to1, 0, 0);
|
||||
if (distt == -1)
|
||||
return 0;
|
||||
|
||||
/* --conversion of C* to B* is better than conversion of C* to A*, */
|
||||
if (distf == 0)
|
||||
{
|
||||
if (distt > 0)
|
||||
return -1;
|
||||
else if (distt < 0)
|
||||
return 1;
|
||||
}
|
||||
/* --conversion of B* to A* is better than conversion of C* to A*, */
|
||||
else if (distt == 0)
|
||||
{
|
||||
if (distf > 0)
|
||||
return 1;
|
||||
else if (distf < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int joust (cand1, cand2)
|
||||
struct z_candidate *cand1, *cand2;
|
||||
{
|
||||
int winner = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < TREE_VEC_LENGTH (cand1->convs); ++i)
|
||||
{
|
||||
int comp = compare_ics (TREE_VEC_ELT (cand1->convs, i),
|
||||
TREE_VEC_ELT (cand2->convs, i));
|
||||
|
||||
if (comp != 0)
|
||||
{
|
||||
if (winner && comp != winner)
|
||||
return 0;
|
||||
winner = comp;
|
||||
}
|
||||
}
|
||||
|
||||
if (winner == 0 && cand1->second_ics)
|
||||
winner = compare_ics (cand1->second_ics, cand2->second_ics);
|
||||
|
||||
return winner;
|
||||
}
|
||||
|
||||
struct z_candidate *
|
||||
tourney (candidates)
|
||||
struct z_candidate *candidates;
|
||||
{
|
||||
struct z_candidate *champ = candidates, *challenger;
|
||||
int fate;
|
||||
|
||||
/* This algorithm has a worst case of O(2n) (winner is last) , and a best
|
||||
case of O(n/2) (no winner); much better than a sorting algorithm. */
|
||||
|
||||
for (challenger = champ->next; challenger; )
|
||||
{
|
||||
fate = joust (champ, challenger);
|
||||
if (fate == 1)
|
||||
challenger = challenger->next;
|
||||
else
|
||||
{
|
||||
if (fate == 0)
|
||||
{
|
||||
champ = challenger->next;
|
||||
if (champ == 0)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
champ = challenger;
|
||||
|
||||
challenger = champ->next;
|
||||
}
|
||||
}
|
||||
|
||||
for (challenger = candidates; challenger != champ;
|
||||
challenger = challenger->next)
|
||||
{
|
||||
fate = joust (champ, challenger);
|
||||
if (fate != 1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return champ;
|
||||
}
|
||||
#endif
|
||||
|
|
151
gcc/cp/decl.c
151
gcc/cp/decl.c
|
@ -300,6 +300,16 @@ tree pfn_identifier, index_identifier, delta_identifier, delta2_identifier;
|
|||
tree pfn_or_delta2_identifier, tag_identifier;
|
||||
tree vt_off_identifier;
|
||||
|
||||
struct named_label_list
|
||||
{
|
||||
struct binding_level *binding_level;
|
||||
tree names_in_scope;
|
||||
tree label_decl;
|
||||
char *filename_o_goto;
|
||||
int lineno_o_goto;
|
||||
struct named_label_list *next;
|
||||
};
|
||||
|
||||
/* A list (chain of TREE_LIST nodes) of named label uses.
|
||||
The TREE_PURPOSE field is the list of variables defined
|
||||
the the label's scope defined at the point of use.
|
||||
|
@ -307,11 +317,17 @@ tree vt_off_identifier;
|
|||
The TREE_TYPE field holds `current_binding_level' at the
|
||||
point of the label's use.
|
||||
|
||||
BWAHAHAAHAHahhahahahaah. No, no, no, said the little chicken.
|
||||
|
||||
Look at the pretty struct named_label_list. See the pretty struct
|
||||
with the pretty named fields that describe what they do. See the
|
||||
pretty lack of gratuitous casts. Notice the code got a lot cleaner.
|
||||
|
||||
Used only for jumps to as-yet undefined labels, since
|
||||
jumps to defined labels can have their validity checked
|
||||
by stmt.c. */
|
||||
|
||||
static tree named_label_uses;
|
||||
static struct named_label_list *named_label_uses = NULL;
|
||||
|
||||
/* A list of objects which have constructors or destructors
|
||||
which reside in the global scope. The decl is stored in
|
||||
|
@ -1199,12 +1215,12 @@ poplevel (keep, reverse, functionbody)
|
|||
level_chain = current_binding_level->level_chain;
|
||||
if (level_chain)
|
||||
{
|
||||
tree labels;
|
||||
for (labels = named_label_uses; labels; labels = TREE_CHAIN (labels))
|
||||
if (TREE_TYPE (labels) == (tree)current_binding_level)
|
||||
struct named_label_list *labels;
|
||||
for (labels = named_label_uses; labels; labels = labels->next)
|
||||
if (labels->binding_level == current_binding_level)
|
||||
{
|
||||
TREE_TYPE (labels) = (tree)level_chain;
|
||||
TREE_PURPOSE (labels) = level_chain->names;
|
||||
labels->binding_level = level_chain;
|
||||
labels->names_in_scope = level_chain->names;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1739,11 +1755,9 @@ struct saved_scope {
|
|||
tree old_bindings;
|
||||
struct saved_scope *prev;
|
||||
tree class_name, class_type, function_decl;
|
||||
tree base_init_list, member_init_list;
|
||||
struct binding_level *class_bindings;
|
||||
tree *lang_base, *lang_stack, lang_name;
|
||||
int lang_stacksize;
|
||||
tree named_labels;
|
||||
int minimal_parse_mode;
|
||||
tree last_function_parms;
|
||||
tree template_parms;
|
||||
|
@ -1803,6 +1817,9 @@ maybe_push_to_top_level (pseudo)
|
|||
struct binding_level *b = inner_binding_level;
|
||||
tree old_bindings = NULL_TREE;
|
||||
|
||||
if (current_function_decl)
|
||||
push_cp_function_context (NULL_TREE);
|
||||
|
||||
if (previous_class_type)
|
||||
old_bindings = store_bindings (previous_class_values, old_bindings);
|
||||
|
||||
|
@ -1832,19 +1849,17 @@ maybe_push_to_top_level (pseudo)
|
|||
s->class_name = current_class_name;
|
||||
s->class_type = current_class_type;
|
||||
s->function_decl = current_function_decl;
|
||||
s->base_init_list = current_base_init_list;
|
||||
s->member_init_list = current_member_init_list;
|
||||
s->class_bindings = class_binding_level;
|
||||
s->lang_stack = current_lang_stack;
|
||||
s->lang_base = current_lang_base;
|
||||
s->lang_stacksize = current_lang_stacksize;
|
||||
s->lang_name = current_lang_name;
|
||||
s->named_labels = named_labels;
|
||||
s->minimal_parse_mode = minimal_parse_mode;
|
||||
s->last_function_parms = last_function_parms;
|
||||
s->template_parms = current_template_parms;
|
||||
s->previous_class_type = previous_class_type;
|
||||
s->previous_class_values = previous_class_values;
|
||||
|
||||
current_class_name = current_class_type = NULL_TREE;
|
||||
current_function_decl = NULL_TREE;
|
||||
class_binding_level = (struct binding_level *)0;
|
||||
|
@ -1902,8 +1917,6 @@ pop_from_top_level ()
|
|||
}
|
||||
current_class_name = s->class_name;
|
||||
current_class_type = s->class_type;
|
||||
current_base_init_list = s->base_init_list;
|
||||
current_member_init_list = s->member_init_list;
|
||||
current_function_decl = s->function_decl;
|
||||
class_binding_level = s->class_bindings;
|
||||
free (current_lang_base);
|
||||
|
@ -1915,7 +1928,6 @@ pop_from_top_level ()
|
|||
strict_prototype = strict_prototypes_lang_cplusplus;
|
||||
else if (current_lang_name == lang_name_c)
|
||||
strict_prototype = strict_prototypes_lang_c;
|
||||
named_labels = s->named_labels;
|
||||
minimal_parse_mode = s->minimal_parse_mode;
|
||||
last_function_parms = s->last_function_parms;
|
||||
current_template_parms = s->template_parms;
|
||||
|
@ -1923,6 +1935,9 @@ pop_from_top_level ()
|
|||
previous_class_values = s->previous_class_values;
|
||||
|
||||
free (s);
|
||||
|
||||
if (current_function_decl)
|
||||
pop_cp_function_context (NULL_TREE);
|
||||
}
|
||||
|
||||
/* Push a definition of struct, union or enum tag "name".
|
||||
|
@ -3717,13 +3732,20 @@ lookup_label (id)
|
|||
|
||||
if ((decl == NULL_TREE
|
||||
|| DECL_SOURCE_LINE (decl) == 0)
|
||||
&& (named_label_uses == NULL_TREE
|
||||
|| TREE_PURPOSE (named_label_uses) != current_binding_level->names
|
||||
|| TREE_VALUE (named_label_uses) != decl))
|
||||
&& (named_label_uses == NULL
|
||||
|| named_label_uses->names_in_scope != current_binding_level->names
|
||||
|| named_label_uses->label_decl != decl))
|
||||
{
|
||||
named_label_uses
|
||||
= tree_cons (current_binding_level->names, decl, named_label_uses);
|
||||
TREE_TYPE (named_label_uses) = (tree)current_binding_level;
|
||||
struct named_label_list *new_ent;
|
||||
new_ent
|
||||
= (struct named_label_list*)oballoc (sizeof (struct named_label_list));
|
||||
new_ent->label_decl = decl;
|
||||
new_ent->names_in_scope = current_binding_level->names;
|
||||
new_ent->binding_level = current_binding_level;
|
||||
new_ent->lineno_o_goto = lineno;
|
||||
new_ent->filename_o_goto = input_filename;
|
||||
new_ent->next = named_label_uses;
|
||||
named_label_uses = new_ent;
|
||||
}
|
||||
|
||||
/* Use a label already defined or ref'd with this name. */
|
||||
|
@ -3754,7 +3776,7 @@ lookup_label (id)
|
|||
SET_IDENTIFIER_LABEL_VALUE (id, decl);
|
||||
|
||||
named_labels = tree_cons (NULL_TREE, decl, named_labels);
|
||||
TREE_VALUE (named_label_uses) = decl;
|
||||
named_label_uses->label_decl = decl;
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
@ -3830,7 +3852,7 @@ define_label (filename, line, name)
|
|||
}
|
||||
else
|
||||
{
|
||||
tree uses, prev;
|
||||
struct named_label_list *uses, *prev;
|
||||
int identified = 0;
|
||||
|
||||
/* Mark label as having been defined. */
|
||||
|
@ -3839,17 +3861,17 @@ define_label (filename, line, name)
|
|||
DECL_SOURCE_FILE (decl) = filename;
|
||||
DECL_SOURCE_LINE (decl) = line;
|
||||
|
||||
for (prev = NULL_TREE, uses = named_label_uses;
|
||||
uses;
|
||||
prev = uses, uses = TREE_CHAIN (uses))
|
||||
if (TREE_VALUE (uses) == decl)
|
||||
prev = NULL;
|
||||
uses = named_label_uses;
|
||||
while (uses != NULL)
|
||||
if (uses->label_decl == decl)
|
||||
{
|
||||
struct binding_level *b = current_binding_level;
|
||||
while (b)
|
||||
{
|
||||
tree new_decls = b->names;
|
||||
tree old_decls = ((tree)b == TREE_TYPE (uses)
|
||||
? TREE_PURPOSE (uses) : NULL_TREE);
|
||||
tree old_decls = (b == uses->binding_level)
|
||||
? uses->names_in_scope : NULL_TREE;
|
||||
while (new_decls != old_decls)
|
||||
{
|
||||
if (TREE_CODE (new_decls) == VAR_DECL
|
||||
|
@ -3862,23 +3884,35 @@ define_label (filename, line, name)
|
|||
&& DECL_INITIAL (new_decls) != error_mark_node)
|
||||
|| TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls))))
|
||||
{
|
||||
if (! identified)
|
||||
cp_error ("jump to label `%D'", decl);
|
||||
identified = 1;
|
||||
if (! identified)
|
||||
{
|
||||
cp_error ("jump to label `%D'", decl);
|
||||
error_with_file_and_line (uses->filename_o_goto,
|
||||
uses->lineno_o_goto,
|
||||
" from here");
|
||||
identified = 1;
|
||||
}
|
||||
cp_error_at (" crosses initialization of `%#D'",
|
||||
new_decls);
|
||||
}
|
||||
new_decls = TREE_CHAIN (new_decls);
|
||||
}
|
||||
if ((tree)b == TREE_TYPE (uses))
|
||||
if (b == uses->binding_level)
|
||||
break;
|
||||
b = b->level_chain;
|
||||
}
|
||||
|
||||
if (prev)
|
||||
TREE_CHAIN (prev) = TREE_CHAIN (uses);
|
||||
if (prev != NULL)
|
||||
prev->next = uses->next;
|
||||
else
|
||||
named_label_uses = TREE_CHAIN (uses);
|
||||
named_label_uses = uses->next;
|
||||
|
||||
uses = uses->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = uses;
|
||||
uses = uses->next;
|
||||
}
|
||||
current_function_return_value = NULL_TREE;
|
||||
return decl;
|
||||
|
@ -4665,7 +4699,7 @@ init_decl_processing ()
|
|||
|
||||
current_function_decl = NULL_TREE;
|
||||
named_labels = NULL_TREE;
|
||||
named_label_uses = NULL_TREE;
|
||||
named_label_uses = NULL;
|
||||
current_binding_level = NULL_BINDING_LEVEL;
|
||||
free_binding_level = NULL_BINDING_LEVEL;
|
||||
|
||||
|
@ -5797,8 +5831,13 @@ start_decl (declarator, declspecs, initialized, raises)
|
|||
tree field = lookup_field (context, DECL_NAME (decl), 0, 0);
|
||||
if (field == NULL_TREE || TREE_CODE (field) != VAR_DECL)
|
||||
cp_error ("`%#D' is not a static member of `%#T'", decl, context);
|
||||
else if (duplicate_decls (decl, field))
|
||||
decl = field;
|
||||
else
|
||||
{
|
||||
if (DECL_CONTEXT (field) != context)
|
||||
cp_pedwarn ("ANSI C++ does not permit `%T::%D' to be defined as `%T::%D'", DECL_CONTEXT (field), DECL_NAME (decl), context, DECL_NAME (decl));
|
||||
if (duplicate_decls (decl, field))
|
||||
decl = field;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -6034,25 +6073,7 @@ grok_reference_init (decl, type, init, cleanupp)
|
|||
goto fail;
|
||||
else if (tmp != NULL_TREE)
|
||||
{
|
||||
tree subtype = TREE_TYPE (type);
|
||||
init = tmp;
|
||||
|
||||
/* Associate the cleanup with the reference so that we
|
||||
don't get burned by "aggressive" cleanup policy. */
|
||||
if (TYPE_NEEDS_DESTRUCTOR (subtype))
|
||||
{
|
||||
if (TREE_CODE (tmp) == ADDR_EXPR)
|
||||
tmp = TREE_OPERAND (tmp, 0);
|
||||
if (TREE_CODE (tmp) == TARGET_EXPR)
|
||||
{
|
||||
*cleanupp = build_delete
|
||||
(build_pointer_type (subtype),
|
||||
build_unary_op (ADDR_EXPR, TREE_OPERAND (tmp, 0), 0),
|
||||
integer_two_node, LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0);
|
||||
TREE_OPERAND (tmp, 2) = error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
DECL_INITIAL (decl) = save_expr (init);
|
||||
}
|
||||
else
|
||||
|
@ -6620,7 +6641,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
|
|||
{
|
||||
/* XXX: Why don't we use decl here? */
|
||||
/* Ans: Because it was already expanded? */
|
||||
if (! cp_expand_decl_cleanup (NULL_TREE, cleanup))
|
||||
if (! expand_decl_cleanup (NULL_TREE, cleanup))
|
||||
cp_error ("parser lost in parsing declaration of `%D'",
|
||||
decl);
|
||||
/* Cleanup used up here. */
|
||||
|
@ -6710,7 +6731,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
|
|||
/* Store the cleanup, if there was one. */
|
||||
if (cleanup)
|
||||
{
|
||||
if (! cp_expand_decl_cleanup (decl, cleanup))
|
||||
if (! expand_decl_cleanup (decl, cleanup))
|
||||
cp_error ("parser lost in parsing declaration of `%D'",
|
||||
decl);
|
||||
}
|
||||
|
@ -7113,6 +7134,8 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
|
|||
if (check)
|
||||
{
|
||||
tmp = check_classfn (ctype, decl);
|
||||
if (tmp && DECL_ARTIFICIAL (tmp))
|
||||
cp_error ("definition of implicitly-declared `%D'", tmp);
|
||||
if (tmp && duplicate_decls (decl, tmp))
|
||||
return tmp;
|
||||
}
|
||||
|
@ -7159,6 +7182,8 @@ grokfndecl (ctype, type, declarator, virtualp, flags, quals,
|
|||
revert_static_member_fn (&decl, NULL, NULL);
|
||||
last_function_parms = TREE_CHAIN (last_function_parms);
|
||||
}
|
||||
if (tmp && DECL_ARTIFICIAL (tmp))
|
||||
cp_error ("definition of implicitly-declared `%D'", tmp);
|
||||
if (tmp && duplicate_decls (decl, tmp))
|
||||
return tmp;
|
||||
}
|
||||
|
@ -7224,7 +7249,7 @@ grokvardecl (type, declarator, specbits, initialized, constp)
|
|||
DECL_ASSEMBLER_NAME (decl) = build_static_name (basetype, declarator);
|
||||
}
|
||||
else
|
||||
decl = build_decl (VAR_DECL, declarator, type);
|
||||
decl = build_decl (VAR_DECL, declarator, complete_type (type));
|
||||
|
||||
DECL_ASSEMBLER_NAME (decl) = current_namespace_id (DECL_ASSEMBLER_NAME (decl));
|
||||
|
||||
|
@ -9118,7 +9143,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises, attrli
|
|||
return NULL_TREE;
|
||||
}
|
||||
|
||||
decl = build_decl (PARM_DECL, declarator, type);
|
||||
decl = build_decl (PARM_DECL, declarator, complete_type (type));
|
||||
|
||||
bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE,
|
||||
inlinep, friendp, raises != NULL_TREE);
|
||||
|
@ -11279,7 +11304,7 @@ store_parm_decls ()
|
|||
&& (cleanup = maybe_build_cleanup (parm), cleanup))
|
||||
{
|
||||
expand_decl (parm);
|
||||
if (! cp_expand_decl_cleanup (parm, cleanup))
|
||||
if (! expand_decl_cleanup (parm, cleanup))
|
||||
cp_error ("parser lost in parsing declaration of `%D'",
|
||||
parm);
|
||||
parms_have_cleanups = 1;
|
||||
|
@ -11973,7 +11998,7 @@ finish_function (lineno, call_poplevel, nested)
|
|||
current_function_decl = NULL_TREE;
|
||||
}
|
||||
|
||||
named_label_uses = NULL_TREE;
|
||||
named_label_uses = NULL;
|
||||
current_class_ptr = NULL_TREE;
|
||||
current_class_ref = NULL_TREE;
|
||||
}
|
||||
|
@ -12200,7 +12225,7 @@ hack_incomplete_structures (type)
|
|||
expand_decl (decl);
|
||||
cleanup = maybe_build_cleanup (decl);
|
||||
expand_decl_init (decl);
|
||||
if (! cp_expand_decl_cleanup (decl, cleanup))
|
||||
if (! expand_decl_cleanup (decl, cleanup))
|
||||
cp_error ("parser lost in parsing declaration of `%D'",
|
||||
decl);
|
||||
}
|
||||
|
|
|
@ -1285,7 +1285,8 @@ dump_expr (t, nop)
|
|||
break;
|
||||
|
||||
case CAST_EXPR:
|
||||
if (TREE_CHAIN (TREE_OPERAND (t, 0)))
|
||||
if (TREE_OPERAND (t, 0) == NULL_TREE
|
||||
|| TREE_CHAIN (TREE_OPERAND (t, 0)))
|
||||
{
|
||||
dump_type (TREE_TYPE (t), 0);
|
||||
OB_PUTC ('(');
|
||||
|
|
|
@ -962,7 +962,7 @@ push_eh_cleanup ()
|
|||
cleanup = build (COMPOUND_EXPR, void_type_node, cleanup,
|
||||
build_modify_expr (saved_in_catch, NOP_EXPR,
|
||||
build_modify_expr (saved_throw_type, NOP_EXPR, integer_zero_node)));
|
||||
cp_expand_decl_cleanup (NULL_TREE, cleanup);
|
||||
expand_decl_cleanup (NULL_TREE, cleanup);
|
||||
|
||||
resume_momentary (yes);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
@chapter Internal Architecture of the Compiler
|
||||
|
||||
This is meant to describe the C++ front-end for gcc in detail.
|
||||
Questions and comments to mrs@@cygnus.com.
|
||||
Questions and comments to Mike Stump @code{<mrs@@cygnus.com>}.
|
||||
|
||||
@menu
|
||||
* Limitations of g++::
|
||||
|
@ -310,9 +310,7 @@ vtables. See also vtable and vfield.
|
|||
|
||||
This section describes some of the macros used on trees. The list
|
||||
should be alphabetical. Eventually all macros should be documented
|
||||
here. There are some postscript drawings that can be used to better
|
||||
understand from of the more complex data structures, contact Mike Stump
|
||||
(@code{mrs@@cygnus.com}) for information about them.
|
||||
here.
|
||||
|
||||
@table @code
|
||||
@item BINFO_BASETYPES
|
||||
|
|
|
@ -615,9 +615,14 @@ emit_base_init (t, immediately)
|
|||
if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)))
|
||||
{
|
||||
start_protect ();
|
||||
|
||||
/* All cleanups must be on the function_obstack. */
|
||||
push_obstacks_nochange ();
|
||||
resume_temporary_allocation ();
|
||||
protect_list = tree_cons (NULL_TREE,
|
||||
build_partial_cleanup_for (base_binfo),
|
||||
protect_list);
|
||||
pop_obstacks ();
|
||||
}
|
||||
|
||||
rbase_init_list = TREE_CHAIN (rbase_init_list);
|
||||
|
|
101
gcc/cp/lex.c
101
gcc/cp/lex.c
|
@ -2750,24 +2750,6 @@ identifier_typedecl_value (node)
|
|||
return NULL_TREE;
|
||||
}
|
||||
|
||||
struct try_type
|
||||
{
|
||||
tree *node_var;
|
||||
char unsigned_flag;
|
||||
char long_flag;
|
||||
char long_long_flag;
|
||||
};
|
||||
|
||||
struct try_type type_sequence[] =
|
||||
{
|
||||
{ &integer_type_node, 0, 0, 0},
|
||||
{ &unsigned_type_node, 1, 0, 0},
|
||||
{ &long_integer_type_node, 0, 1, 0},
|
||||
{ &long_unsigned_type_node, 1, 1, 0},
|
||||
{ &long_long_integer_type_node, 0, 1, 1},
|
||||
{ &long_long_unsigned_type_node, 1, 1, 1}
|
||||
};
|
||||
|
||||
int
|
||||
real_yylex ()
|
||||
{
|
||||
|
@ -3528,83 +3510,10 @@ real_yylex ()
|
|||
yylval.ttype = build_int_2 (low, high);
|
||||
TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
|
||||
|
||||
#if 0
|
||||
/* Find the first allowable type that the value fits in. */
|
||||
type = 0;
|
||||
for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
|
||||
i++)
|
||||
if (!(spec_long && !type_sequence[i].long_flag)
|
||||
&& !(spec_long_long && !type_sequence[i].long_long_flag)
|
||||
&& !(spec_unsigned && !type_sequence[i].unsigned_flag)
|
||||
/* A hex or octal constant traditionally is unsigned. */
|
||||
&& !(base != 10 && flag_traditional
|
||||
&& !type_sequence[i].unsigned_flag)
|
||||
/* A decimal constant can't be unsigned int
|
||||
unless explicitly specified. */
|
||||
&& !(base == 10 && !spec_unsigned
|
||||
&& *type_sequence[i].node_var == unsigned_type_node))
|
||||
if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
|
||||
{
|
||||
type = *type_sequence[i].node_var;
|
||||
break;
|
||||
}
|
||||
if (flag_traditional && type == long_unsigned_type_node
|
||||
&& !spec_unsigned)
|
||||
type = long_integer_type_node;
|
||||
|
||||
if (type == 0)
|
||||
{
|
||||
type = long_long_integer_type_node;
|
||||
warning ("integer constant out of range");
|
||||
}
|
||||
|
||||
/* Warn about some cases where the type of a given constant
|
||||
changes from traditional C to ANSI C. */
|
||||
if (warn_traditional)
|
||||
{
|
||||
tree other_type = 0;
|
||||
|
||||
/* This computation is the same as the previous one
|
||||
except that flag_traditional is used backwards. */
|
||||
for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
|
||||
i++)
|
||||
if (!(spec_long && !type_sequence[i].long_flag)
|
||||
&& !(spec_long_long && !type_sequence[i].long_long_flag)
|
||||
&& !(spec_unsigned && !type_sequence[i].unsigned_flag)
|
||||
/* A hex or octal constant traditionally is unsigned. */
|
||||
&& !(base != 10 && !flag_traditional
|
||||
&& !type_sequence[i].unsigned_flag)
|
||||
/* A decimal constant can't be unsigned int
|
||||
unless explicitly specified. */
|
||||
&& !(base == 10 && !spec_unsigned
|
||||
&& *type_sequence[i].node_var == unsigned_type_node))
|
||||
if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
|
||||
{
|
||||
other_type = *type_sequence[i].node_var;
|
||||
break;
|
||||
}
|
||||
if (!flag_traditional && type == long_unsigned_type_node
|
||||
&& !spec_unsigned)
|
||||
type = long_integer_type_node;
|
||||
|
||||
if (other_type != 0 && other_type != type)
|
||||
{
|
||||
if (flag_traditional)
|
||||
warning ("type of integer constant would be different without -traditional");
|
||||
else
|
||||
warning ("type of integer constant would be different with -traditional");
|
||||
}
|
||||
}
|
||||
|
||||
#else /* 1 */
|
||||
if (!spec_long && !spec_unsigned
|
||||
&& !(flag_traditional && base != 10)
|
||||
&& int_fits_type_p (yylval.ttype, integer_type_node))
|
||||
{
|
||||
#if 0
|
||||
if (warn_traditional && base != 10)
|
||||
warning ("small nondecimal constant becomes signed in ANSI C++");
|
||||
#endif
|
||||
type = integer_type_node;
|
||||
}
|
||||
else if (!spec_long && (base != 10 || spec_unsigned)
|
||||
|
@ -3622,10 +3531,6 @@ real_yylex ()
|
|||
&& int_fits_type_p (yylval.ttype,
|
||||
long_unsigned_type_node))
|
||||
{
|
||||
#if 0
|
||||
if (warn_traditional && !spec_unsigned)
|
||||
warning ("large integer constant becomes unsigned in ANSI C++");
|
||||
#endif
|
||||
if (flag_traditional && !spec_unsigned)
|
||||
type = long_integer_type_node;
|
||||
else
|
||||
|
@ -3642,11 +3547,6 @@ real_yylex ()
|
|||
else if (int_fits_type_p (yylval.ttype,
|
||||
long_long_unsigned_type_node))
|
||||
{
|
||||
#if 0
|
||||
if (warn_traditional && !spec_unsigned)
|
||||
warning ("large nondecimal constant is unsigned in ANSI C++");
|
||||
#endif
|
||||
|
||||
if (flag_traditional && !spec_unsigned)
|
||||
type = long_long_integer_type_node;
|
||||
else
|
||||
|
@ -3661,7 +3561,6 @@ real_yylex ()
|
|||
if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
|
||||
warning ("decimal integer constant is so large that it is unsigned");
|
||||
}
|
||||
#endif
|
||||
|
||||
TREE_TYPE (yylval.ttype) = type;
|
||||
*p = 0;
|
||||
|
|
|
@ -1751,9 +1751,11 @@ emit_thunk (thunk_fndecl)
|
|||
abort ();
|
||||
current_function_decl = thunk_fndecl;
|
||||
#ifdef ASM_OUTPUT_MI_THUNK
|
||||
temporary_allocation ();
|
||||
assemble_start_function (thunk_fndecl, fnname);
|
||||
ASM_OUTPUT_MI_THUNK (asm_out_file, thunk_fndecl, delta, function);
|
||||
assemble_end_function (thunk_fndecl, fnname);
|
||||
permanent_allocation (1);
|
||||
#else
|
||||
save_ofp = flag_omit_frame_pointer;
|
||||
flag_omit_frame_pointer = 1;
|
||||
|
@ -1995,8 +1997,12 @@ do_build_copy_constructor (fndecl)
|
|||
(build_reference_type (basetype), parm,
|
||||
CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
|
||||
p = convert_from_reference (p);
|
||||
current_base_init_list = tree_cons (basetype,
|
||||
p, current_base_init_list);
|
||||
|
||||
if (p == error_mark_node)
|
||||
cp_error ("in default copy constructor");
|
||||
else
|
||||
current_base_init_list = tree_cons (basetype,
|
||||
p, current_base_init_list);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_bases; ++i)
|
||||
|
@ -2009,9 +2015,15 @@ do_build_copy_constructor (fndecl)
|
|||
p = convert_to_reference
|
||||
(build_reference_type (basetype), parm,
|
||||
CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
|
||||
p = convert_from_reference (p);
|
||||
current_base_init_list = tree_cons (basetype,
|
||||
p, current_base_init_list);
|
||||
|
||||
if (p == error_mark_node)
|
||||
cp_error ("in default copy constructor");
|
||||
else
|
||||
{
|
||||
p = convert_from_reference (p);
|
||||
current_base_init_list = tree_cons (basetype,
|
||||
p, current_base_init_list);
|
||||
}
|
||||
}
|
||||
for (; fields; fields = TREE_CHAIN (fields))
|
||||
{
|
||||
|
@ -2080,16 +2092,13 @@ do_build_assign_ref (fndecl)
|
|||
for (i = 0; i < n_bases; ++i)
|
||||
{
|
||||
tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
|
||||
if (TYPE_HAS_ASSIGN_REF (basetype))
|
||||
{
|
||||
tree p = convert_to_reference
|
||||
(build_reference_type (basetype), parm,
|
||||
CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
|
||||
p = convert_from_reference (p);
|
||||
p = build_member_call (basetype, ansi_opname [MODIFY_EXPR],
|
||||
build_tree_list (NULL_TREE, p));
|
||||
expand_expr_stmt (p);
|
||||
}
|
||||
tree p = convert_to_reference
|
||||
(build_reference_type (basetype), parm,
|
||||
CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
|
||||
p = convert_from_reference (p);
|
||||
p = build_member_call (basetype, ansi_opname [MODIFY_EXPR],
|
||||
build_tree_list (NULL_TREE, p));
|
||||
expand_expr_stmt (p);
|
||||
}
|
||||
for (; fields; fields = TREE_CHAIN (fields))
|
||||
{
|
||||
|
@ -2098,6 +2107,24 @@ do_build_assign_ref (fndecl)
|
|||
|
||||
if (TREE_CODE (field) != FIELD_DECL)
|
||||
continue;
|
||||
|
||||
if (TREE_READONLY (field))
|
||||
{
|
||||
if (DECL_NAME (field))
|
||||
cp_error ("non-static const member `%#D', can't use default assignment operator", field);
|
||||
else
|
||||
cp_error ("non-static const member in type `%T', can't use default assignment operator", current_class_type);
|
||||
continue;
|
||||
}
|
||||
else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
|
||||
{
|
||||
if (DECL_NAME (field))
|
||||
cp_error ("non-static reference member `%#D', can't use default assignment operator", field);
|
||||
else
|
||||
cp_error ("non-static reference member in type `%T', can't use default assignment operator", current_class_type);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (DECL_NAME (field))
|
||||
{
|
||||
if (VFIELD_NAME_P (DECL_NAME (field)))
|
||||
|
|
|
@ -1187,6 +1187,7 @@ instantiate_class_template (type)
|
|||
|
||||
/* XXX handle attributes */
|
||||
type = finish_struct_1 (type, NULL_TREE, 0);
|
||||
CLASSTYPE_GOT_SEMICOLON (type) = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2968,8 +2969,6 @@ instantiate_decl (d)
|
|||
if (! push_tinst_level (d))
|
||||
return d;
|
||||
|
||||
if (TREE_CODE (d) == FUNCTION_DECL && nested)
|
||||
push_cp_function_context (NULL_TREE);
|
||||
push_to_top_level ();
|
||||
|
||||
/* Trick tsubst into giving us a new decl in case the template changed. */
|
||||
|
@ -3044,8 +3043,6 @@ instantiate_decl (d)
|
|||
}
|
||||
|
||||
pop_from_top_level ();
|
||||
if (TREE_CODE (d) == FUNCTION_DECL && nested)
|
||||
pop_cp_function_context (NULL_TREE);
|
||||
pop_tinst_level ();
|
||||
|
||||
return d;
|
||||
|
|
|
@ -3508,7 +3508,7 @@ add_conversions (binfo)
|
|||
tree tmp = TREE_VEC_ELT (method_vec, i);
|
||||
if (! IDENTIFIER_TYPENAME_P (DECL_NAME (tmp)))
|
||||
break;
|
||||
conversions = tree_cons (DECL_NAME (tmp), TREE_TYPE (TREE_TYPE (tmp)),
|
||||
conversions = tree_cons (TREE_TYPE (TREE_TYPE (tmp)), tmp,
|
||||
conversions);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -220,7 +220,7 @@ build_cplus_new (type, init)
|
|||
TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), slot);
|
||||
TREE_SIDE_EFFECTS (rval) = 1;
|
||||
TREE_ADDRESSABLE (rval) = 1;
|
||||
rval = build (TARGET_EXPR, type, slot, rval, NULL_TREE);
|
||||
rval = build (TARGET_EXPR, type, slot, rval, NULL_TREE, NULL_TREE);
|
||||
TREE_SIDE_EFFECTS (rval) = 1;
|
||||
TREE_ADDRESSABLE (rval) = 1;
|
||||
|
||||
|
@ -399,7 +399,7 @@ build_cplus_method_type (basetype, rettype, argtypes)
|
|||
}
|
||||
|
||||
tree
|
||||
build_cplus_array_type (elt_type, index_type)
|
||||
build_cplus_array_type_1 (elt_type, index_type)
|
||||
tree elt_type;
|
||||
tree index_type;
|
||||
{
|
||||
|
@ -433,6 +433,24 @@ build_cplus_array_type (elt_type, index_type)
|
|||
saveable_obstack = ambient_saveable_obstack;
|
||||
return t;
|
||||
}
|
||||
|
||||
tree
|
||||
build_cplus_array_type (elt_type, index_type)
|
||||
tree elt_type;
|
||||
tree index_type;
|
||||
{
|
||||
tree t;
|
||||
int constp = TYPE_READONLY (elt_type);
|
||||
int volatilep = TYPE_VOLATILE (elt_type);
|
||||
elt_type = TYPE_MAIN_VARIANT (elt_type);
|
||||
|
||||
t = build_cplus_array_type_1 (elt_type, index_type);
|
||||
|
||||
if (constp || volatilep)
|
||||
t = cp_build_type_variant (t, constp, volatilep);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Make a variant type in the proper way for C/C++, propagating qualifiers
|
||||
down to the element type of an array. */
|
||||
|
@ -451,9 +469,9 @@ cp_build_type_variant (type, constp, volatilep)
|
|||
|
||||
push_obstacks (TYPE_OBSTACK (real_main_variant),
|
||||
TYPE_OBSTACK (real_main_variant));
|
||||
type = build_cplus_array_type (cp_build_type_variant (TREE_TYPE (type),
|
||||
constp, volatilep),
|
||||
TYPE_DOMAIN (type));
|
||||
type = build_cplus_array_type_1 (cp_build_type_variant
|
||||
(TREE_TYPE (type), constp, volatilep),
|
||||
TYPE_DOMAIN (type));
|
||||
|
||||
/* TYPE must be on same obstack as REAL_MAIN_VARIANT. If not,
|
||||
make a copy. (TYPE might have come from the hash table and
|
||||
|
@ -467,6 +485,7 @@ cp_build_type_variant (type, constp, volatilep)
|
|||
|
||||
TYPE_MAIN_VARIANT (type) = real_main_variant;
|
||||
pop_obstacks ();
|
||||
return type;
|
||||
}
|
||||
return build_type_variant (type, constp, volatilep);
|
||||
}
|
||||
|
@ -1753,16 +1772,6 @@ break_out_target_exprs (t)
|
|||
return mapcar (t, bot_manip);
|
||||
}
|
||||
|
||||
/* Since cleanup may have SAVE_EXPRs in it, we protect it with an
|
||||
UNSAVE_EXPR as the backend cannot yet handle SAVE_EXPRs in cleanups
|
||||
by itself. */
|
||||
int
|
||||
cp_expand_decl_cleanup (decl, cleanup)
|
||||
tree decl, cleanup;
|
||||
{
|
||||
return expand_decl_cleanup (decl, unsave_expr (cleanup));
|
||||
}
|
||||
|
||||
/* Obstack used for allocating nodes in template function and variable
|
||||
definitions. */
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ complete_type (type)
|
|||
{
|
||||
if (TYPE_SIZE (type) != NULL_TREE)
|
||||
;
|
||||
else if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
|
||||
{
|
||||
tree t = complete_type (TREE_TYPE (type));
|
||||
if (TYPE_SIZE (t) != NULL_TREE)
|
||||
|
@ -437,10 +437,6 @@ common_type (t1, t2)
|
|||
|
||||
case ARRAY_TYPE:
|
||||
{
|
||||
int constp
|
||||
= TYPE_READONLY (t1) || TYPE_READONLY (t2);
|
||||
int volatilep
|
||||
= TYPE_VOLATILE (t1) || TYPE_VOLATILE (t2);
|
||||
tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
|
||||
/* Save space: see if the result is identical to one of the args. */
|
||||
if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
|
||||
|
@ -448,9 +444,8 @@ common_type (t1, t2)
|
|||
if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2))
|
||||
return build_type_attribute_variant (t2, attributes);
|
||||
/* Merge the element types, and have a size if either arg has one. */
|
||||
t1 = build_cplus_array_type (TYPE_MAIN_VARIANT (elt), TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
|
||||
if (constp || volatilep)
|
||||
t1 = cp_build_type_variant (t1, constp, volatilep);
|
||||
t1 = build_cplus_array_type
|
||||
(elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
|
||||
return build_type_attribute_variant (t1, attributes);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue