41st Cygnus<->FSF merge

From-SVN: r7553
This commit is contained in:
Mike Stump 1994-06-24 00:54:38 +00:00
parent f6ba0600ff
commit a32034654e
12 changed files with 255 additions and 296 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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
{

View File

@ -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. */

View File

@ -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;
}
}

View File

@ -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)

View File

@ -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;

View File

@ -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. */

View File

@ -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",

View File

@ -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);

View File

@ -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);
}

View File

@ -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);