+Fri Jul 1 09:35:51 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * parse.y (init): ANSI C++ does not forbid { }.
+
+Thu Jun 30 00:35:22 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * decl2.c (lang_decode_option): Set warn_nonvdtor along with -Wall.
+ warn_nonvdtor defaults to off.
+
+ * class.c (instantiate_type): Use comptypes rather than relying on
+ types to satisfy ==.
+
+ * decl.c (start_function): Set DECL_DEFER_OUTPUT on all inlines that
+ might be static.
+
+ * tree.c (build_cplus_new): Never build WITH_CLEANUP_EXPRs.
+
+ * decl.c (grok_reference_init): Deal with ADDR_EXPRs of TARGET_EXPRs.
+
+ * cvt.c (cp_convert): Pass 0 to with_cleanup_p arg of
+ build_cplus_new.
+
+Wed Jun 29 22:31:09 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * decl2.c (finish_file): Maybe consider static inlines multiple
+ times, in case they reference each other.
+
Tue Jun 28 11:58:38 1994 Gerald Baumgartner (gb@cs.purdue.edu)
* class.c (finish_struct): Don't `cons_up_default_function's
if ((IS_SIGNATURE (basetype)
&& (instance_ptr = build_optr_ref (instance)))
|| (lvalue_p (instance)
- && (instance_ptr = build_unary_op (ADDR_EXPR, instance, 0)))
+ && (instance_ptr = build_unary_op (ADDR_EXPR, instance, 0)))
|| (instance_ptr = unary_complex_lvalue (ADDR_EXPR, instance)))
{
if (instance_ptr == error_mark_node)
{
elem = TREE_VALUE (baselink);
while (elem)
- if (TREE_TYPE (elem) != lhstype)
- elem = TREE_CHAIN (elem);
- else
+ if (comptypes (lhstype, TREE_TYPE (elem), 1))
return elem;
+ else
+ elem = TREE_CHAIN (elem);
}
/* No exact match found, look for a compatible method. */
cp_error ("in conversion to type `%T'", type);
return error_mark_node;
}
- rval = build_cplus_new (type, init, 1);
+ /* We can't pass 1 to the with_cleanup_p arg here, because that
+ screws up passing classes by value. */
+ rval = build_cplus_new (type, init, 0);
return rval;
}
}
goto fail;
else if (tmp != NULL_TREE)
{
+ tree subtype = TREE_TYPE (type);
init = tmp;
- if (TREE_CODE (init) == WITH_CLEANUP_EXPR)
+ /* Associate the cleanup with the reference so that we
+ don't get burned by "aggressive" cleanup policy. */
+ if (TYPE_NEEDS_DESTRUCTOR (subtype))
{
- /* Associate the cleanup with the reference so that we
- don't get burned by "aggressive" cleanup policy. */
- *cleanupp = TREE_OPERAND (init, 2);
- TREE_OPERAND (init, 2) = error_mark_node;
+ if (TREE_CODE (init) == WITH_CLEANUP_EXPR)
+ {
+ *cleanupp = TREE_OPERAND (init, 2);
+ TREE_OPERAND (init, 2) = error_mark_node;
+ }
+ else
+ {
+ if (TREE_CODE (tmp) == ADDR_EXPR)
+ tmp = TREE_OPERAND (tmp, 0);
+ if (TREE_CODE (tmp) == TARGET_EXPR)
+ {
+ *cleanupp = build_delete
+ (TYPE_POINTER_TO (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;
+ }
+ }
}
if (TREE_SIDE_EFFECTS (init))
defining how to inline. So set DECL_EXTERNAL in that case. */
DECL_EXTERNAL (decl1) = current_extern_inline;
- DECL_DEFER_OUTPUT (decl1)
- = (DECL_INLINE (decl1) && (DECL_IMPLICIT_INSTANTIATION (decl1)
- || DECL_FUNCTION_MEMBER_P (decl1)));
+ DECL_DEFER_OUTPUT (decl1) = DECL_INLINE (decl1);
}
if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1))
/* Non-zero means warn when declaring a class that has a non virtual
destructor, when it really ought to have a virtual one. */
-int warn_nonvdtor = 1;
+int warn_nonvdtor;
/* Non-zero means warn when a function is declared extern and later inline. */
int warn_extern_inline;
warn_format = setting;
warn_missing_braces = setting;
warn_extern_inline = setting;
+ warn_nonvdtor = setting;
/* We save the value of warn_uninitialized, since if they put
-Wuninitialized on the command line, we need to generate a
warning about not using it without also specifying -O. */
emit_thunk (vars);
}
- /* Now write out inline functions which had their addresses taken
- and which were not declared virtual and which were not declared
- `extern inline'. */
- while (saved_inlines)
- {
- tree decl = TREE_VALUE (saved_inlines);
- saved_inlines = TREE_CHAIN (saved_inlines);
- /* Redefinition of a member function can cause DECL_SAVED_INSNS to be
- 0; don't crash. */
- if (TREE_ASM_WRITTEN (decl) || DECL_SAVED_INSNS (decl) == 0)
- continue;
- if (DECL_FUNCTION_MEMBER_P (decl) && !TREE_PUBLIC (decl))
- {
- tree ctype = DECL_CLASS_CONTEXT (decl);
- if (CLASSTYPE_INTERFACE_KNOWN (ctype))
- {
- TREE_PUBLIC (decl) = 1;
- DECL_EXTERNAL (decl)
- = (CLASSTYPE_INTERFACE_ONLY (ctype)
- || (DECL_INLINE (decl) && ! flag_implement_inlines));
- }
- }
- if (TREE_PUBLIC (decl)
- || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
- || flag_keep_inline_functions)
- {
- if (DECL_EXTERNAL (decl)
- || (DECL_IMPLICIT_INSTANTIATION (decl)
- && ! flag_implicit_templates))
- assemble_external (decl);
- else
- {
- temporary_allocation ();
- output_inline_function (decl);
- permanent_allocation (1);
- }
- }
- }
+ {
+ int reconsider = 0; /* More may be referenced; check again */
+ tree delayed = NULL_TREE; /* These might be referenced later */
+
+ /* Now write out inline functions which had their addresses taken and
+ which were not declared virtual and which were not declared `extern
+ inline'. */
+ while (saved_inlines)
+ {
+ tree decl = TREE_VALUE (saved_inlines);
+ saved_inlines = TREE_CHAIN (saved_inlines);
+ /* Redefinition of a member function can cause DECL_SAVED_INSNS to be
+ 0; don't crash. */
+ if (TREE_ASM_WRITTEN (decl) || DECL_SAVED_INSNS (decl) == 0)
+ continue;
+ if (DECL_FUNCTION_MEMBER_P (decl) && !TREE_PUBLIC (decl))
+ {
+ tree ctype = DECL_CLASS_CONTEXT (decl);
+ if (CLASSTYPE_INTERFACE_KNOWN (ctype))
+ {
+ TREE_PUBLIC (decl) = 1;
+ DECL_EXTERNAL (decl)
+ = (CLASSTYPE_INTERFACE_ONLY (ctype)
+ || (DECL_INLINE (decl) && ! flag_implement_inlines));
+ }
+ }
+ if (TREE_PUBLIC (decl)
+ || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
+ || flag_keep_inline_functions)
+ {
+ if (DECL_EXTERNAL (decl)
+ || (DECL_IMPLICIT_INSTANTIATION (decl)
+ && ! flag_implicit_templates))
+ assemble_external (decl);
+ else
+ {
+ reconsider = 1;
+ temporary_allocation ();
+ output_inline_function (decl);
+ permanent_allocation (1);
+ }
+ }
+ else if (TREE_USED (decl)
+ || TREE_USED (DECL_ASSEMBLER_NAME (decl)))
+ delayed = tree_cons (NULL_TREE, decl, delayed);
+ }
+
+ if (reconsider && delayed)
+ {
+ while (reconsider)
+ {
+ tree place;
+ reconsider = 0;
+ for (place = delayed; place; place = TREE_CHAIN (place))
+ {
+ tree decl = TREE_VALUE (place);
+ if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
+ && ! TREE_ASM_WRITTEN (decl))
+ {
+ if (DECL_EXTERNAL (decl)
+ || (DECL_IMPLICIT_INSTANTIATION (decl)
+ && ! flag_implicit_templates))
+ assemble_external (decl);
+ else
+ {
+ reconsider = 1;
+ temporary_allocation ();
+ output_inline_function (decl);
+ permanent_allocation (1);
+ }
+ }
+ }
+ }
+ }
+ }
if (write_virtuals == 2)
{
expr_no_commas %prec '='
| '{' '}'
{ $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);
- TREE_HAS_CONSTRUCTOR ($$) = 1;
- if (pedantic)
- pedwarn ("ANSI C++ forbids empty initializer braces"); }
+ TREE_HAS_CONSTRUCTOR ($$) = 1; }
| '{' initlist '}'
{ $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2));
TREE_HAS_CONSTRUCTOR ($$) = 1; }
TREE_SIDE_EFFECTS (rval) = 1;
TREE_ADDRESSABLE (rval) = 1;
+#if 0
if (with_cleanup_p && TYPE_NEEDS_DESTRUCTOR (type))
{
TREE_OPERAND (rval, 2) = error_mark_node;
TREE_SIDE_EFFECTS (rval) = 1;
TREE_ADDRESSABLE (rval) = 1;
}
+#endif
return rval;
}
TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
TREE_TYPE (t) = rettype;
- /* The actual arglist for this function includes a "hidden" argument
- which is "this". Put it into the list of argument types. */
-
TYPE_ARG_TYPES (t) = argtypes;
/* If we already have such a type, use the old one and free this one.