41st Cygnus<->FSF merge
From-SVN: r7553
This commit is contained in:
parent
f6ba0600ff
commit
a32034654e
@ -1,3 +1,91 @@
|
||||
Thu Jun 23 00:22:28 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* decl.c (grokdeclarator): Set explicit_int for decls that just
|
||||
specify, say, 'long'.
|
||||
|
||||
* init.c (do_friend): Do overload C functions (or call pushdecl,
|
||||
anyaway).
|
||||
|
||||
Wed Jun 22 13:40:49 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* cvt.c (build_up_reference): Don't call readonly_error.
|
||||
(convert_to_reference): Propagate const and volatile from expr to
|
||||
its type.
|
||||
|
||||
* tree.c (lvalue_p): Random CALL_EXPRs are not lvalues.
|
||||
|
||||
* cvt.c (build_up_reference): Break out WITH_CLEANUP_EXPR when
|
||||
creating a temporary.
|
||||
(convert_to_reference): Lose excessive and incorrect trickiness.
|
||||
(cp_convert): Call build_cplus_new with with_cleanup_p set.
|
||||
|
||||
* typeck2.c (build_functional_cast): Ditto.
|
||||
|
||||
Tue Jun 21 17:38:38 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* decl.c (grokdeclarator): signed, unsigned, long and short all
|
||||
imply 'int'.
|
||||
|
||||
* decl.c (grokdeclarator): Allow "this is a type" syntax.
|
||||
(grok_reference_init): Simplify and fix.
|
||||
|
||||
Sun Jun 19 17:08:48 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* decl.c (grokdeclarator): pedwarn about a typedef that specifies no
|
||||
type.
|
||||
|
||||
Sat Jun 18 04:16:50 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* decl.c (start_function): Move TREE_PUBLIC and DECL_EXTERNAL
|
||||
tinkering to after call to pushdecl.
|
||||
|
||||
Fri Jun 17 14:48:28 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* call.c (build_method_call): Handle destructors for non-aggregate
|
||||
types properly.
|
||||
|
||||
Thu Jun 16 16:48:05 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* call.c (build_method_call): Make sure that the name given for the
|
||||
destructor matches the constructor_name of the instance.
|
||||
|
||||
* pt.c (do_function_instantiation): A non-extern instantiation
|
||||
overrides a later extern one.
|
||||
(do_type_instantiation): Ditto.
|
||||
|
||||
Wed Jun 15 19:34:54 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* init.c (expand_aggr_init): Use TYPE_MAIN_VARIANT to get the
|
||||
unqualified array type.
|
||||
|
||||
* cp-tree.h (EMPTY_CONSTRUCTOR_P): Tests whether NODE is a
|
||||
CONSTRUCTOR with no elements.
|
||||
|
||||
* decl.c (various): Lose empty_init_node.
|
||||
(finish_decl): Use EMPTY_CONSTRUCTOR_P, do the empty CONSTRUCTOR
|
||||
thing depending on the value of DECL_COMMON instead of
|
||||
flag_conserve_space, do the empty CONSTRUCTOR thing for types that
|
||||
don't have constructors, don't treat a real empty CONSTRUCTOR
|
||||
specially.
|
||||
|
||||
* typeck2.c (process_init_constructor): Don't treat empty_init_node
|
||||
specially.
|
||||
|
||||
Wed Jun 15 19:05:25 1994 Mike Stump (mrs@cygnus.com)
|
||||
|
||||
* class.c (override_one_vtable): Don't forget to merge in an old
|
||||
overrider when we wanted to reuse a vtable, but couldn't.
|
||||
|
||||
Wed Jun 15 15:03:16 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* decl.c (start_decl): Put statics in common again.
|
||||
|
||||
* decl.c (grokdeclarator): Return NULL_TREE for an error rather than
|
||||
setting the type to error_mark_node.
|
||||
|
||||
* typeck.c (build_modify_expr): Build up a COMPOUND_EXPR for enum
|
||||
bitfield assignments.
|
||||
|
||||
Tue Jun 14 12:23:38 1994 Jason Merrill (jason@deneb.cygnus.com)
|
||||
|
||||
* decl.c (grok_op_properties): Const objects can be passed by value.
|
||||
|
@ -1603,14 +1603,22 @@ build_method_call (instance, name, parms, basetype_path, flags)
|
||||
name = TREE_OPERAND (name, 0);
|
||||
if (parms)
|
||||
error ("destructors take no parameters");
|
||||
basetype = get_type_value (name);
|
||||
if (basetype == NULL_TREE)
|
||||
basetype = TREE_TYPE (instance);
|
||||
if (IS_AGGR_TYPE (basetype))
|
||||
{
|
||||
cp_error ("call to destructor for non-type `%D'", name);
|
||||
return void_zero_node;
|
||||
if (name == constructor_name (basetype))
|
||||
goto huzzah;
|
||||
}
|
||||
if (basetype != TREE_TYPE(instance))
|
||||
basetype = TREE_TYPE(instance);
|
||||
else
|
||||
{
|
||||
if (basetype == get_type_value (name))
|
||||
goto huzzah;
|
||||
}
|
||||
cp_error ("destructor name `~%D' does not match type `%T' of expression",
|
||||
name, basetype);
|
||||
return void_zero_node;
|
||||
|
||||
huzzah:
|
||||
if (! TYPE_HAS_DESTRUCTOR (basetype))
|
||||
return void_zero_node;
|
||||
instance = default_conversion (instance);
|
||||
|
@ -2400,6 +2400,10 @@ override_one_vtable (binfo, old, t)
|
||||
}
|
||||
TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals);
|
||||
}
|
||||
else if (choose == NEITHER)
|
||||
{
|
||||
TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1167,6 +1167,9 @@ struct lang_decl
|
||||
has been duly initialized in its constructor. */
|
||||
#define TREE_HAS_CONSTRUCTOR(NODE) (TREE_LANG_FLAG_4(NODE))
|
||||
|
||||
#define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR \
|
||||
&& CONSTRUCTOR_ELTS (NODE) == NULL_TREE)
|
||||
|
||||
/* Indicates that a NON_LVALUE_EXPR came from a C++ reference.
|
||||
Used to generate more helpful error message in case somebody
|
||||
tries to take its address. */
|
||||
|
76
gcc/cp/cvt.c
76
gcc/cp/cvt.c
@ -337,7 +337,20 @@ build_up_reference (type, arg, flags, checkconst)
|
||||
TREE_READONLY (arg) = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE)
|
||||
{
|
||||
rval = copy_node (arg);
|
||||
TREE_TYPE (rval) = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
|
||||
}
|
||||
else
|
||||
rval = arg;
|
||||
|
||||
rval = convert (build_pointer_type (TREE_TYPE (type)), rval);
|
||||
TREE_TYPE (rval) = type;
|
||||
#else
|
||||
rval = build1 (CONVERT_EXPR, type, arg);
|
||||
#endif
|
||||
TREE_REFERENCE_EXPR (rval) = 1;
|
||||
|
||||
/* propagate the const flag on something like:
|
||||
@ -372,7 +385,7 @@ build_up_reference (type, arg, flags, checkconst)
|
||||
}
|
||||
literal_flag = TREE_CONSTANT (arg);
|
||||
|
||||
goto done_but_maybe_warn;
|
||||
goto done;
|
||||
|
||||
/* Get this out of a register if we happened to be in one by accident.
|
||||
Also, build up references to non-lvalues it we must. */
|
||||
@ -409,7 +422,7 @@ build_up_reference (type, arg, flags, checkconst)
|
||||
TREE_TYPE (rval) = type;
|
||||
literal_flag = staticp (TREE_OPERAND (targ, 0));
|
||||
|
||||
goto done_but_maybe_warn;
|
||||
goto done;
|
||||
|
||||
/* Anything not already handled and not a true memory reference
|
||||
needs to have a reference built up. Do so silently for
|
||||
@ -537,7 +550,12 @@ build_up_reference (type, arg, flags, checkconst)
|
||||
if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype))
|
||||
{
|
||||
temp = build_cplus_new (argtype, targ, 1);
|
||||
rval = build1 (ADDR_EXPR, type, temp);
|
||||
if (TREE_CODE (temp) == WITH_CLEANUP_EXPR)
|
||||
rval = build (WITH_CLEANUP_EXPR, type,
|
||||
build1 (ADDR_EXPR, type, TREE_OPERAND (temp, 0)),
|
||||
0, TREE_OPERAND (temp, 2));
|
||||
else
|
||||
rval = build1 (ADDR_EXPR, type, temp);
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
@ -572,10 +590,6 @@ build_up_reference (type, arg, flags, checkconst)
|
||||
else
|
||||
rval = build1 (ADDR_EXPR, type, arg);
|
||||
|
||||
done_but_maybe_warn:
|
||||
if (checkconst && TREE_READONLY (arg) && ! TYPE_READONLY (target_type))
|
||||
readonly_error (arg, "conversion to reference", 1);
|
||||
|
||||
done:
|
||||
if (TYPE_USES_COMPLEX_INHERITANCE (argtype))
|
||||
{
|
||||
@ -636,7 +650,11 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
|
||||
if (form == REFERENCE_TYPE)
|
||||
ttr = TREE_TYPE (TREE_TYPE (expr));
|
||||
else
|
||||
ttr = TREE_TYPE (expr);
|
||||
{
|
||||
int r = TREE_READONLY (expr);
|
||||
int v = TREE_THIS_VOLATILE (expr);
|
||||
ttr = c_build_type_variant (TREE_TYPE (expr), r, v);
|
||||
}
|
||||
|
||||
if (! lvalue_p (expr) &&
|
||||
(decl == NULL_TREE || ! TYPE_READONLY (ttl)))
|
||||
@ -653,46 +671,20 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
|
||||
{
|
||||
if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
|
||||
cp_pedwarn ("conversion from `%T' to `%T' discards const",
|
||||
TREE_TYPE (expr), reftype);
|
||||
ttr, reftype);
|
||||
else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
|
||||
cp_pedwarn ("conversion from `%T' to `%T' discards volatile",
|
||||
TREE_TYPE (expr), reftype);
|
||||
ttr, reftype);
|
||||
}
|
||||
}
|
||||
|
||||
/* If EXPR is of aggregate type, and is really a CALL_EXPR,
|
||||
then we don't need to convert it to reference type if
|
||||
it is only being used to initialize DECL which is also
|
||||
of the same aggregate type. */
|
||||
if (decl != NULL_TREE && decl != error_mark_node
|
||||
&& IS_AGGR_TYPE (type)
|
||||
&& TREE_CODE (expr) == CALL_EXPR
|
||||
&& TYPE_MAIN_VARIANT (type) == intype)
|
||||
{
|
||||
tree e1 = build (INIT_EXPR, void_type_node, decl, expr);
|
||||
tree e2;
|
||||
|
||||
TREE_SIDE_EFFECTS (e1) = 1;
|
||||
if (form == REFERENCE_TYPE)
|
||||
e2 = build1 (NOP_EXPR, reftype, decl);
|
||||
else
|
||||
{
|
||||
e2 = build_unary_op (ADDR_EXPR, decl, 0);
|
||||
TREE_TYPE (e2) = reftype;
|
||||
TREE_REFERENCE_EXPR (e2) = 1;
|
||||
}
|
||||
return build_compound_expr
|
||||
(tree_cons (NULL_TREE, e1, build_tree_list (NULL_TREE, e2)));
|
||||
}
|
||||
|
||||
else if (form == REFERENCE_TYPE)
|
||||
if (form == REFERENCE_TYPE)
|
||||
{
|
||||
rval = build1 (NOP_EXPR,
|
||||
build_pointer_type (TREE_TYPE (TREE_TYPE (expr))),
|
||||
expr);
|
||||
rval = copy_node (expr);
|
||||
TREE_TYPE (rval) = build_pointer_type (TREE_TYPE (TREE_TYPE (expr)));
|
||||
rval = cp_convert (build_pointer_type (TREE_TYPE (reftype)), rval,
|
||||
convtype, flags);
|
||||
rval = build1 (NOP_EXPR, reftype, rval);
|
||||
TREE_TYPE (rval) = reftype;
|
||||
return rval;
|
||||
}
|
||||
|
||||
@ -1364,7 +1356,7 @@ cp_convert (type, expr, convtype, flags)
|
||||
return error_mark_node;
|
||||
}
|
||||
/* call to constructor successful. */
|
||||
rval = build_cplus_new (type, rval, 0);
|
||||
rval = build_cplus_new (type, rval, 1);
|
||||
return rval;
|
||||
}
|
||||
}
|
||||
@ -1415,7 +1407,7 @@ cp_convert (type, expr, convtype, flags)
|
||||
cp_error ("in conversion to type `%T'", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
rval = build_cplus_new (type, init, 0);
|
||||
rval = build_cplus_new (type, init, 1);
|
||||
return rval;
|
||||
}
|
||||
}
|
||||
|
289
gcc/cp/decl.c
289
gcc/cp/decl.c
@ -244,15 +244,6 @@ tree maybe_gc_cleanup;
|
||||
/* Array type `vtable_entry_type[]' */
|
||||
tree vtbl_type_node;
|
||||
|
||||
/* Static decls which do not have static initializers have no
|
||||
initializers as far as GNU C is concerned. EMPTY_INIT_NODE
|
||||
is a static initializer which makes varasm code place the decl
|
||||
in data rather than in bss space. Such gymnastics are necessary
|
||||
to avoid the problem that the linker will not include a library
|
||||
file if all the library appears to contribute are bss variables. */
|
||||
|
||||
tree empty_init_node;
|
||||
|
||||
/* In a destructor, the point at which all derived class destroying
|
||||
has been done, just before any base class destroying will be done. */
|
||||
|
||||
@ -4376,7 +4367,6 @@ init_decl_processing ()
|
||||
TREE_TYPE (integer_two_node) = integer_type_node;
|
||||
integer_three_node = build_int_2 (3, 0);
|
||||
TREE_TYPE (integer_three_node) = integer_type_node;
|
||||
empty_init_node = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);
|
||||
|
||||
bool_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
|
||||
TREE_SET_CODE (bool_type_node, BOOLEAN_TYPE);
|
||||
@ -5385,8 +5375,14 @@ start_decl (declarator, declspecs, initialized, raises)
|
||||
else
|
||||
tem = pushdecl (decl);
|
||||
|
||||
/* Tell the back-end to use or not use .common as appropriate. */
|
||||
DECL_COMMON (tem) = flag_conserve_space;
|
||||
/* Tell the back-end to use or not use .common as appropriate. If we say
|
||||
-fconserve-space, we want this to save space, at the expense of wrong
|
||||
semantics. If we say -fno-conserve-space, we want this to produce
|
||||
errors about redefs; to do this we force variables into the data
|
||||
segment. Common storage is okay for non-public uninitialized data;
|
||||
the linker can't match it with storage from other files, and we may
|
||||
save some disk space. */
|
||||
DECL_COMMON (tem) = flag_conserve_space || ! TREE_PUBLIC (tem);
|
||||
|
||||
#if 0
|
||||
/* We don't do this yet for GNU C++. */
|
||||
@ -5556,10 +5552,7 @@ grok_reference_init (decl, type, init, cleanupp)
|
||||
tree decl, type, init;
|
||||
tree *cleanupp;
|
||||
{
|
||||
char *errstr = NULL;
|
||||
int is_reference;
|
||||
tree tmp;
|
||||
tree this_ptr_type, actual_init = NULL_TREE;
|
||||
|
||||
if (init == NULL_TREE)
|
||||
{
|
||||
@ -5585,56 +5578,22 @@ grok_reference_init (decl, type, init, cleanupp)
|
||||
|
||||
if (TREE_CODE (init) == TREE_LIST)
|
||||
init = build_compound_expr (init);
|
||||
is_reference = TREE_CODE (TREE_TYPE (init)) == REFERENCE_TYPE;
|
||||
tmp = is_reference ? convert_from_reference (init) : init;
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE)
|
||||
{
|
||||
/* Note: default conversion is only called in very
|
||||
special cases. */
|
||||
/* Note: default conversion is only called in very special cases. */
|
||||
init = default_conversion (init);
|
||||
}
|
||||
|
||||
/* Can we just enreference this lvalue? */
|
||||
if ((is_reference || lvalue_p (init)
|
||||
|| (actual_init = unary_complex_lvalue (ADDR_EXPR, init)))
|
||||
&& comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (type)),
|
||||
TYPE_MAIN_VARIANT (TREE_TYPE (tmp)), 0))
|
||||
{
|
||||
/* This section implements ANSI C++ June 5 1992 WP 8.4.3.5. */
|
||||
tmp = convert_to_reference
|
||||
(type, init, CONV_IMPLICIT, LOOKUP_SPECULATIVELY|LOOKUP_NORMAL, decl);
|
||||
|
||||
/* A reference to a volatile T cannot be initialized with
|
||||
a const T, and vice-versa. */
|
||||
if (TYPE_VOLATILE (TREE_TYPE (type)) && TREE_READONLY (init))
|
||||
errstr = "cannot initialize a reference to a volatile `%T' with a const `%T'";
|
||||
else if (TYPE_READONLY (TREE_TYPE (type)) && TREE_THIS_VOLATILE (init))
|
||||
errstr = "cannot initialize a reference to a const `%T' with a volatile `%T'";
|
||||
/* A reference to a plain T can be initialized only with a plain T. */
|
||||
else if (!TYPE_VOLATILE (TREE_TYPE (type))
|
||||
&& !TYPE_READONLY (TREE_TYPE (type)))
|
||||
{
|
||||
if (TREE_READONLY (init))
|
||||
errstr = "cannot initialize a reference to `%T' with a const `%T'";
|
||||
else if (TREE_THIS_VOLATILE (init))
|
||||
errstr = "cannot initialize a reference to `%T' with a volatile `%T'";
|
||||
}
|
||||
if (errstr)
|
||||
{
|
||||
cp_error (errstr, TREE_TYPE (type), TREE_TYPE (tmp));
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
/* OK, can we generate a reference then? */
|
||||
else if ((actual_init = convert_to_reference
|
||||
(type, init, CONV_IMPLICIT,
|
||||
LOOKUP_SPECULATIVELY|LOOKUP_NORMAL, decl)))
|
||||
if (tmp == error_mark_node)
|
||||
goto fail;
|
||||
else if (tmp != NULL_TREE)
|
||||
{
|
||||
if (actual_init == error_mark_node)
|
||||
goto fail;
|
||||
|
||||
init = actual_init;
|
||||
is_reference = 1;
|
||||
init = tmp;
|
||||
|
||||
if (TREE_CODE (init) == WITH_CLEANUP_EXPR)
|
||||
{
|
||||
@ -5643,6 +5602,11 @@ grok_reference_init (decl, type, init, cleanupp)
|
||||
*cleanupp = TREE_OPERAND (init, 2);
|
||||
TREE_OPERAND (init, 2) = error_mark_node;
|
||||
}
|
||||
|
||||
if (TREE_SIDE_EFFECTS (init))
|
||||
DECL_INITIAL (decl) = save_expr (init);
|
||||
else
|
||||
DECL_INITIAL (decl) = init;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -5650,55 +5614,6 @@ grok_reference_init (decl, type, init, cleanupp)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* In the case of initialization, it is permissible
|
||||
to assign one reference to another. */
|
||||
this_ptr_type = build_pointer_type (TREE_TYPE (type));
|
||||
|
||||
if (is_reference)
|
||||
{
|
||||
if (TREE_SIDE_EFFECTS (init))
|
||||
DECL_INITIAL (decl) = save_expr (init);
|
||||
else
|
||||
DECL_INITIAL (decl) = init;
|
||||
}
|
||||
else if (lvalue_p (init))
|
||||
{
|
||||
tmp = build_unary_op (ADDR_EXPR, init, 0);
|
||||
if (TREE_CODE (tmp) == ADDR_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (tmp, 0)) == WITH_CLEANUP_EXPR)
|
||||
{
|
||||
if (*cleanupp) my_friendly_abort (1);
|
||||
*cleanupp = TREE_OPERAND (TREE_OPERAND (tmp, 0), 2);
|
||||
TREE_OPERAND (TREE_OPERAND (tmp, 0), 2) = error_mark_node;
|
||||
}
|
||||
if (IS_AGGR_TYPE (TREE_TYPE (this_ptr_type)))
|
||||
DECL_INITIAL (decl) = convert_pointer_to (TREE_TYPE (this_ptr_type),
|
||||
tmp);
|
||||
else
|
||||
DECL_INITIAL (decl) = convert (this_ptr_type, tmp);
|
||||
|
||||
DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl));
|
||||
if (DECL_INITIAL (decl) == current_class_decl)
|
||||
DECL_INITIAL (decl) = copy_node (current_class_decl);
|
||||
TREE_TYPE (DECL_INITIAL (decl)) = type;
|
||||
}
|
||||
/* If actual_init is set here, it is set from the first check above. */
|
||||
else if (actual_init)
|
||||
{
|
||||
/* The initializer for this decl goes into its
|
||||
DECL_REFERENCE_SLOT. Make sure that we can handle
|
||||
multiple evaluations without ill effect. */
|
||||
if (TREE_CODE (actual_init) == ADDR_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (actual_init, 0)) == TARGET_EXPR)
|
||||
actual_init = save_expr (actual_init);
|
||||
DECL_INITIAL (decl) = convert_pointer_to (TREE_TYPE (this_ptr_type),
|
||||
actual_init);
|
||||
DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl));
|
||||
TREE_TYPE (DECL_INITIAL (decl)) = type;
|
||||
}
|
||||
else
|
||||
my_friendly_abort (1);
|
||||
|
||||
/* ?? Can this be optimized in some cases to
|
||||
hand back the DECL_INITIAL slot?? */
|
||||
if (TYPE_SIZE (TREE_TYPE (type)))
|
||||
@ -5892,8 +5807,7 @@ finish_decl (decl, init, asmspec_tree, need_pop)
|
||||
{
|
||||
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
init = digest_init (type, init, (tree *) 0);
|
||||
else if (TREE_CODE (init) == CONSTRUCTOR
|
||||
&& CONSTRUCTOR_ELTS (init) != NULL_TREE)
|
||||
else if (TREE_CODE (init) == CONSTRUCTOR)
|
||||
{
|
||||
if (TYPE_NEEDS_CONSTRUCTING (type))
|
||||
{
|
||||
@ -5951,16 +5865,11 @@ finish_decl (decl, init, asmspec_tree, need_pop)
|
||||
if (current_binding_level == global_binding_level)
|
||||
{
|
||||
tree value;
|
||||
if (flag_conserve_space)
|
||||
/* If we say -fconserve-space, we want this to save
|
||||
space, at the expense of wrong semantics. */
|
||||
if (DECL_COMMON (decl))
|
||||
/* Should this be a NULL_TREE? */
|
||||
value = error_mark_node;
|
||||
else
|
||||
/* If we say -fno-conserve-space, we want this to
|
||||
produce errors about redefs, to do this we make it
|
||||
go in the data space */
|
||||
value = digest_init (type, empty_init_node, (tree *) 0);
|
||||
value = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
|
||||
DECL_INITIAL (decl) = value;
|
||||
}
|
||||
else
|
||||
@ -5972,10 +5881,17 @@ finish_decl (decl, init, asmspec_tree, need_pop)
|
||||
if (TREE_CODE (init) != TREE_VEC)
|
||||
init = store_init_value (decl, init);
|
||||
|
||||
/* Don't let anyone try to initialize this variable
|
||||
until we are ready to do so. */
|
||||
if (init)
|
||||
/* Don't let anyone try to initialize this variable
|
||||
until we are ready to do so. */
|
||||
DECL_INITIAL (decl) = error_mark_node;
|
||||
{
|
||||
tree value;
|
||||
if (DECL_COMMON (decl))
|
||||
value = error_mark_node;
|
||||
else
|
||||
value = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
|
||||
DECL_INITIAL (decl) = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (DECL_EXTERNAL (decl))
|
||||
@ -6002,27 +5918,19 @@ finish_decl (decl, init, asmspec_tree, need_pop)
|
||||
cp_error ("uninitialized const `%D'", decl);
|
||||
|
||||
/* Initialize variables in need of static initialization with
|
||||
`empty_init_node' to keep assemble_variable from putting them in
|
||||
the wrong program space. Common storage is okay for non-public
|
||||
uninitialized data; the linker can't match it with storage from
|
||||
other files, and we may save some disk space. Consts have to go
|
||||
into data, though, since the backend would put them in text
|
||||
otherwise. */
|
||||
an empty CONSTRUCTOR to keep assemble_variable from putting them in
|
||||
the wrong program space. */
|
||||
if (flag_pic == 0
|
||||
&& TREE_STATIC (decl)
|
||||
&& (TREE_PUBLIC (decl) || was_readonly)
|
||||
&& TREE_PUBLIC (decl)
|
||||
&& ! DECL_EXTERNAL (decl)
|
||||
&& TREE_CODE (decl) == VAR_DECL
|
||||
&& TYPE_NEEDS_CONSTRUCTING (type)
|
||||
&& (DECL_INITIAL (decl) == NULL_TREE
|
||||
|| DECL_INITIAL (decl) == error_mark_node)
|
||||
/* If we say -fconserve-space, we want this to save space,
|
||||
at the expense of wrong semantics. */
|
||||
&& ! flag_conserve_space)
|
||||
{
|
||||
tree value = digest_init (type, empty_init_node, (tree *) 0);
|
||||
DECL_INITIAL (decl) = value;
|
||||
}
|
||||
&& ! DECL_COMMON (decl))
|
||||
DECL_INITIAL (decl) = build (CONSTRUCTOR, type, NULL_TREE,
|
||||
NULL_TREE);
|
||||
}
|
||||
else if (TREE_CODE (decl) == VAR_DECL
|
||||
&& TREE_CODE (type) != REFERENCE_TYPE
|
||||
@ -6182,7 +6090,7 @@ finish_decl (decl, init, asmspec_tree, need_pop)
|
||||
&& TREE_READONLY (decl)
|
||||
&& DECL_INITIAL (decl) != NULL_TREE
|
||||
&& DECL_INITIAL (decl) != error_mark_node
|
||||
&& DECL_INITIAL (decl) != empty_init_node)
|
||||
&& ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)))
|
||||
{
|
||||
DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl));
|
||||
|
||||
@ -6889,9 +6797,8 @@ grokvardecl (type, declarator, specbits, initialized)
|
||||
if (initialized && DECL_INITIAL (decl)
|
||||
/* Complain about multiply-initialized
|
||||
member variables, but don't be faked
|
||||
out if initializer is faked up from `empty_init_node'. */
|
||||
&& (TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR
|
||||
|| CONSTRUCTOR_ELTS (DECL_INITIAL (decl)) != NULL_TREE))
|
||||
out if initializer is empty. */
|
||||
&& ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)))
|
||||
error_with_aggr_type (DECL_CONTEXT (decl),
|
||||
"multiple initializations of static member `%s::%s'",
|
||||
IDENTIFIER_POINTER (DECL_NAME (decl)));
|
||||
@ -7358,44 +7265,19 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
||||
|
||||
if (TREE_CODE (id) == IDENTIFIER_NODE)
|
||||
{
|
||||
if (id == ridpointers[(int) RID_INT])
|
||||
if (id == ridpointers[(int) RID_INT]
|
||||
|| id == ridpointers[(int) RID_CHAR]
|
||||
|| id == ridpointers[(int) RID_BOOL]
|
||||
|| id == ridpointers[(int) RID_WCHAR])
|
||||
{
|
||||
if (type)
|
||||
error ("extraneous `int' ignored");
|
||||
else
|
||||
{
|
||||
explicit_int = 1;
|
||||
type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id));
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
if (id == ridpointers[(int) RID_CHAR])
|
||||
{
|
||||
if (type)
|
||||
error ("extraneous `char' ignored");
|
||||
else
|
||||
{
|
||||
explicit_char = 1;
|
||||
type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id));
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
if (id == ridpointers[(int) RID_BOOL])
|
||||
{
|
||||
if (type)
|
||||
error ("extraneous `bool' ignored");
|
||||
else
|
||||
{
|
||||
type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id));
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
if (id == ridpointers[(int) RID_WCHAR])
|
||||
{
|
||||
if (type)
|
||||
error ("extraneous `__wchar_t' ignored");
|
||||
error ("extraneous `%T' ignored", id);
|
||||
else
|
||||
{
|
||||
if (id == ridpointers[(int) RID_INT])
|
||||
explicit_int = 1;
|
||||
else if (id == ridpointers[(int) RID_CHAR])
|
||||
explicit_char = 1;
|
||||
type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id));
|
||||
}
|
||||
goto found;
|
||||
@ -7459,6 +7341,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
||||
which case the type defaults to `unknown type' and is
|
||||
instantiated when assigning to a signature pointer or ref. */
|
||||
|
||||
if (type == NULL_TREE
|
||||
&& (RIDBIT_SETP (RID_SIGNED, specbits)
|
||||
|| RIDBIT_SETP (RID_UNSIGNED, specbits)
|
||||
|| RIDBIT_SETP (RID_LONG, specbits)
|
||||
|| RIDBIT_SETP (RID_SHORT, specbits)))
|
||||
{
|
||||
/* These imply 'int'. */
|
||||
type = integer_type_node;
|
||||
explicit_int = 1;
|
||||
}
|
||||
|
||||
if (type == NULL_TREE)
|
||||
{
|
||||
explicit_int = -1;
|
||||
@ -7478,22 +7371,21 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
||||
opaque_typedef = 1;
|
||||
type = copy_node (opaque_type_node);
|
||||
}
|
||||
/* access declaration */
|
||||
else if (decl_context == FIELD && declarator
|
||||
&& TREE_CODE (declarator) == SCOPE_REF)
|
||||
type = void_type_node;
|
||||
else
|
||||
{
|
||||
if (funcdef_flag)
|
||||
{
|
||||
if (warn_return_type
|
||||
&& return_type == return_normal
|
||||
&& ! (RIDBIT_SETP (RID_SIGNED, specbits)
|
||||
|| RIDBIT_SETP (RID_UNSIGNED, specbits)
|
||||
|| RIDBIT_SETP (RID_LONG, specbits)
|
||||
|| RIDBIT_SETP (RID_SHORT, specbits)))
|
||||
&& return_type == return_normal)
|
||||
/* Save warning until we know what is really going on. */
|
||||
warn_about_return_type = 1;
|
||||
}
|
||||
else if (decl_context == FIELD && declarator
|
||||
&& TREE_CODE (declarator) == SCOPE_REF)
|
||||
/* OK -- access declaration */;
|
||||
else if (RIDBIT_SETP (RID_TYPEDEF, specbits))
|
||||
pedwarn ("ANSI C++ forbids typedef which does not specify a type");
|
||||
else if (declspecs == NULL_TREE &&
|
||||
(innermost_code != CALL_EXPR || pedantic))
|
||||
cp_pedwarn ("ANSI C++ forbids declaration `%D' with no type or storage class",
|
||||
@ -7522,6 +7414,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
||||
|
||||
type = ctor_return_type;
|
||||
}
|
||||
/* Catch typedefs that only specify a type, like 'typedef int;'. */
|
||||
else if (RIDBIT_SETP (RID_TYPEDEF, specbits) && declarator == NULL_TREE)
|
||||
{
|
||||
/* Template "this is a type" syntax; just ignore for now. */
|
||||
if (processing_template_defn)
|
||||
return void_type_node;
|
||||
}
|
||||
|
||||
ctype = NULL_TREE;
|
||||
|
||||
@ -8481,16 +8380,16 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
||||
TREE_TYPE (type), TYPE_ARG_TYPES (type));
|
||||
else
|
||||
{
|
||||
error ("cannot declare member function `%s::%s' within this class",
|
||||
TYPE_NAME_STRING (ctype), name);
|
||||
cp_error ("cannot declare member function `%T::%D' within `%T'",
|
||||
ctype, name, current_class_type);
|
||||
return void_type_node;
|
||||
}
|
||||
}
|
||||
else if (TYPE_MAIN_VARIANT (ctype) == current_class_type)
|
||||
{
|
||||
if (extra_warnings)
|
||||
warning ("extra qualification `%s' on member `%s' ignored",
|
||||
TYPE_NAME_STRING (ctype), name);
|
||||
cp_warning ("redundant qualification `%T' on member `%D' ignored",
|
||||
ctype, name);
|
||||
type = build_offset_type (ctype, type);
|
||||
}
|
||||
else if (TYPE_SIZE (ctype) != NULL_TREE
|
||||
@ -8659,7 +8558,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
||||
if (TREE_CODE (type) == OFFSET_TYPE || TREE_CODE (type) == METHOD_TYPE)
|
||||
{
|
||||
cp_error_at ("typedef name may not be class-qualified", decl);
|
||||
TREE_TYPE (decl) = error_mark_node;
|
||||
return NULL_TREE;
|
||||
}
|
||||
else if (quals)
|
||||
{
|
||||
@ -10773,6 +10672,19 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
|
||||
(This does not mean `static' in the C sense!) */
|
||||
TREE_STATIC (decl1) = 1;
|
||||
|
||||
/* Record the decl so that the function name is defined.
|
||||
If we already have a decl for this name, and it is a FUNCTION_DECL,
|
||||
use the old decl. */
|
||||
|
||||
if (pre_parsed_p == 0)
|
||||
{
|
||||
current_function_decl = decl1 = pushdecl (decl1);
|
||||
DECL_MAIN_VARIANT (decl1) = decl1;
|
||||
fntype = TREE_TYPE (decl1);
|
||||
}
|
||||
else
|
||||
current_function_decl = decl1;
|
||||
|
||||
/* 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. */
|
||||
@ -10800,19 +10712,6 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Record the decl so that the function name is defined.
|
||||
If we already have a decl for this name, and it is a FUNCTION_DECL,
|
||||
use the old decl. */
|
||||
|
||||
if (pre_parsed_p == 0)
|
||||
{
|
||||
current_function_decl = decl1 = pushdecl (decl1);
|
||||
DECL_MAIN_VARIANT (decl1) = decl1;
|
||||
fntype = TREE_TYPE (decl1);
|
||||
}
|
||||
else
|
||||
current_function_decl = decl1;
|
||||
|
||||
if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1))
|
||||
{
|
||||
if (TREE_CODE (fntype) == METHOD_TYPE)
|
||||
|
@ -215,7 +215,7 @@ int warn_extern_inline;
|
||||
#endif
|
||||
int dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
|
||||
|
||||
/* Nonzero for -no-strict-prototype switch: do not consider empty
|
||||
/* Nonzero for -fno-strict-prototype switch: do not consider empty
|
||||
argument prototype to mean function takes no arguments. */
|
||||
|
||||
int strict_prototype = 1;
|
||||
|
@ -1117,13 +1117,7 @@ expand_aggr_init (exp, init, alias_this)
|
||||
int was_const_elts = TYPE_READONLY (TREE_TYPE (type));
|
||||
tree itype = init ? TREE_TYPE (init) : NULL_TREE;
|
||||
if (was_const_elts)
|
||||
{
|
||||
tree atype = build_cplus_array_type (TYPE_MAIN_VARIANT (TREE_TYPE (type)),
|
||||
TYPE_DOMAIN (type));
|
||||
if (init && (TREE_TYPE (exp) == TREE_TYPE (init)))
|
||||
TREE_TYPE (init) = atype;
|
||||
TREE_TYPE (exp) = atype;
|
||||
}
|
||||
TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
|
||||
if (init && TREE_TYPE (init) == NULL_TREE)
|
||||
{
|
||||
/* Handle bad initializers like:
|
||||
@ -2613,40 +2607,9 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
|
||||
enum overload_flags flags;
|
||||
tree quals;
|
||||
{
|
||||
/* first, lets find out if what we are making a friend needs overloading */
|
||||
tree previous_decl;
|
||||
int was_c_linkage = 0;
|
||||
|
||||
/* Every decl that gets here is a friend of something. */
|
||||
DECL_FRIEND_P (decl) = 1;
|
||||
|
||||
/* If we find something in scope, let see if it has extern "C" linkage. */
|
||||
/* This code is pretty general and should be ripped out and reused
|
||||
as a separate function. */
|
||||
if (DECL_NAME (decl))
|
||||
{
|
||||
previous_decl = lookup_name (DECL_NAME (decl), 0);
|
||||
if (previous_decl && TREE_CODE (previous_decl) == TREE_LIST)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (TREE_TYPE (TREE_VALUE (previous_decl)) == TREE_TYPE (decl))
|
||||
{
|
||||
previous_decl = TREE_VALUE (previous_decl);
|
||||
break;
|
||||
}
|
||||
previous_decl = TREE_CHAIN (previous_decl);
|
||||
}
|
||||
while (previous_decl);
|
||||
}
|
||||
|
||||
/* It had extern "C" linkage, so don't overload this. */
|
||||
if (previous_decl && TREE_CODE (previous_decl) == FUNCTION_DECL
|
||||
&& TREE_TYPE (decl) == TREE_TYPE (previous_decl)
|
||||
&& DECL_LANGUAGE (previous_decl) == lang_c)
|
||||
was_c_linkage = 1;
|
||||
}
|
||||
|
||||
if (ctype)
|
||||
{
|
||||
tree cname = TYPE_NAME (ctype);
|
||||
@ -2711,7 +2674,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
|
||||
decl = void_type_node;
|
||||
}
|
||||
}
|
||||
/* never overload C functions */
|
||||
else if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& ((IDENTIFIER_LENGTH (declarator) == 4
|
||||
&& IDENTIFIER_POINTER (declarator)[0] == 'm'
|
||||
@ -2720,8 +2682,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
|
||||
&& IDENTIFIER_POINTER (declarator)[0] == '_'
|
||||
&& IDENTIFIER_POINTER (declarator)[1] == '_'
|
||||
&& strncmp (IDENTIFIER_POINTER (declarator)+2,
|
||||
"builtin_", 8) == 0)
|
||||
|| was_c_linkage))
|
||||
"builtin_", 8) == 0)))
|
||||
{
|
||||
/* raw "main", and builtin functions never gets overloaded,
|
||||
but they can become friends. */
|
||||
|
@ -2377,6 +2377,9 @@ do_function_instantiation (declspecs, declarator, storage)
|
||||
if (flag_external_templates)
|
||||
return;
|
||||
|
||||
if (DECL_EXPLICIT_INSTANTIATION (result) && ! DECL_EXTERNAL (result))
|
||||
return;
|
||||
|
||||
SET_DECL_EXPLICIT_INSTANTIATION (result);
|
||||
TREE_PUBLIC (result) = 1;
|
||||
|
||||
@ -2399,6 +2402,9 @@ do_type_instantiation (name, storage)
|
||||
if (flag_external_templates)
|
||||
return;
|
||||
|
||||
if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && ! CLASSTYPE_INTERFACE_ONLY (t))
|
||||
return;
|
||||
|
||||
if (TYPE_SIZE (t) == NULL_TREE)
|
||||
{
|
||||
cp_error ("explicit instantiation of `%#T' before definition of template",
|
||||
|
@ -74,12 +74,6 @@ lvalue_p (ref)
|
||||
case WITH_CLEANUP_EXPR:
|
||||
return 1;
|
||||
|
||||
case CALL_EXPR:
|
||||
/* unary_complex_lvalue knows how to deal with this case. */
|
||||
if (TREE_ADDRESSABLE (TREE_TYPE (ref)))
|
||||
return 1;
|
||||
break;
|
||||
|
||||
/* A currently unresolved scope ref. */
|
||||
case SCOPE_REF:
|
||||
my_friendly_abort (103);
|
||||
|
@ -5336,6 +5336,7 @@ build_modify_expr (lhs, modifycode, rhs)
|
||||
tree newrhs = rhs;
|
||||
tree lhstype = TREE_TYPE (lhs);
|
||||
tree olhstype = lhstype;
|
||||
tree olhs = lhs;
|
||||
|
||||
/* Types that aren't fully specified cannot be used in assignments. */
|
||||
lhs = require_complete_type (lhs);
|
||||
@ -5933,7 +5934,11 @@ build_modify_expr (lhs, modifycode, rhs)
|
||||
for enum bit fields. */
|
||||
if (TREE_CODE (TREE_TYPE (result)) == INTEGER_TYPE
|
||||
&& TREE_CODE (olhstype) == ENUMERAL_TYPE)
|
||||
return convert_force (olhstype, result);
|
||||
{
|
||||
result = build (COMPOUND_EXPR, olhstype, result, olhs);
|
||||
TREE_NO_UNUSED_WARNING (result) = 1;
|
||||
return result;
|
||||
}
|
||||
return convert_for_assignment (olhstype, result, "assignment",
|
||||
NULL_TREE, 0);
|
||||
}
|
||||
|
@ -844,7 +844,6 @@ static tree
|
||||
process_init_constructor (type, init, elts)
|
||||
tree type, init, *elts;
|
||||
{
|
||||
extern tree empty_init_node;
|
||||
register tree tail;
|
||||
/* List of the elements of the result constructor,
|
||||
in reverse order. */
|
||||
@ -917,7 +916,7 @@ process_init_constructor (type, init, elts)
|
||||
members = tree_cons (NULL_TREE, next1, members);
|
||||
}
|
||||
}
|
||||
if (TREE_CODE (type) == RECORD_TYPE && init != empty_init_node)
|
||||
if (TREE_CODE (type) == RECORD_TYPE)
|
||||
{
|
||||
register tree field;
|
||||
|
||||
@ -1010,7 +1009,7 @@ process_init_constructor (type, init, elts)
|
||||
}
|
||||
}
|
||||
|
||||
if (TREE_CODE (type) == UNION_TYPE && init != empty_init_node)
|
||||
if (TREE_CODE (type) == UNION_TYPE)
|
||||
{
|
||||
register tree field = TYPE_FIELDS (type);
|
||||
register tree next1;
|
||||
@ -1438,7 +1437,7 @@ build_functional_cast (exp, parms)
|
||||
return error_mark_node;
|
||||
|
||||
if (current_function_decl)
|
||||
return build_cplus_new (type, expr_as_ctor, 0);
|
||||
return build_cplus_new (type, expr_as_ctor, 1);
|
||||
|
||||
{
|
||||
register tree parm = TREE_OPERAND (expr_as_ctor, 1);
|
||||
|
Loading…
Reference in New Issue
Block a user