* cp-tree.h (register_dtor_fn): New function.
* decl.c (destroy_local_static): Rename to ...
(register_dtor_fn): ... this. Give it external linkage.
(expand_static_init): Use it.
* decl2.c (do_static_initialization): Likewise, if using
__cxa_atexit.
(do_static_destruction): Check that __cxa_atexit is not in use.
(finish_file): Don't call do_static_destruction if using
__cxa_atexit.
* typeck.c (convert_arguments): Restore two-message error
reporting.
From-SVN: r31570
+2000-01-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (register_dtor_fn): New function.
+ * decl.c (destroy_local_static): Rename to ...
+ (register_dtor_fn): ... this. Give it external linkage.
+ (expand_static_init): Use it.
+ * decl2.c (do_static_initialization): Likewise, if using
+ __cxa_atexit.
+ (do_static_destruction): Check that __cxa_atexit is not in use.
+ (finish_file): Don't call do_static_destruction if using
+ __cxa_atexit.
+
+ * typeck.c (convert_arguments): Restore two-message error
+ reporting.
+
2000-01-20 Nathan Sidwell <sidwell@codesourcery.com>
Remap dynamic cast hint values to be consistent across ABIs.
extern int local_variable_p PROTO((tree));
extern int nonstatic_local_decl_p PROTO((tree));
extern tree declare_global_var PROTO((tree, tree));
+extern void register_dtor_fn PROTO((tree));
/* in decl2.c */
extern void init_decl2 PROTO((void));
static void mark_stmt_tree PROTO((struct stmt_tree *));
static void save_function_data PROTO((tree));
static void check_function_type PROTO((tree));
-static void destroy_local_static PROTO((tree));
static void destroy_local_var PROTO((tree));
static void finish_constructor_body PROTO((void));
static void finish_destructor_body PROTO((void));
pop_from_top_level ();
}
-/* Generate code to handle the destruction of the function-scoped
- static variable DECL. */
+/* Generate code to handle the destruction of DECL, an object with
+ static storage duration. */
-static void
-destroy_local_static (decl)
+void
+register_dtor_fn (decl)
tree decl;
{
tree cleanup;
int saved_flag_access_control;
+ if (!TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl)))
+ return;
+
/* Call build_cleanup before we enter the anonymous function so that
any access checks will be done relative to the current scope,
rather than the scope of the anonymous function. */
/* Use atexit to register a function for destroying this static
variable. */
- if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl)))
- destroy_local_static (decl);
+ register_dtor_fn (decl);
finish_compound_stmt (/*has_no_scope=*/0, then_clause);
finish_then_clause (if_stmt);
}
finish_expr_stmt (expr);
+ /* If we're using __cxa_atexit, register a a function that calls the
+ destructor for the object. */
+ if (flag_use_cxa_atexit)
+ register_dtor_fn (decl);
+
/* Finsh up. */
finish_static_initialization_or_destruction (sentry_if_stmt);
}
{
tree sentry_if_stmt;
+ /* If we're using __cxa_atexit, then destructors are registered
+ immediately after objects are initialized. */
+ my_friendly_assert (!flag_use_cxa_atexit, 20000121);
+
/* If we don't need a destructor, there's nothing to do. */
if (!TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl)))
return;
-
+
/* Actually do the destruction. */
sentry_if_stmt = start_static_initialization_or_destruction (decl,
/*initp=*/0);
/* Then, generate code to do all the destructions. Do these
in reverse order so that the most recently constructed
- variable is the first destroyed. */
- vars = nreverse (vars);
- for (v = vars; v; v = TREE_CHAIN (v))
- do_static_destruction (TREE_VALUE (v));
+ variable is the first destroyed. If we're using
+ __cxa_atexit, then we don't need to do this; functions
+ we're registered at initialization time to destroy the
+ local statics. */
+ if (!flag_use_cxa_atexit)
+ {
+ vars = nreverse (vars);
+ for (v = vars; v; v = TREE_CHAIN (v))
+ do_static_destruction (TREE_VALUE (v));
+ }
+ else
+ vars = NULL_TREE;
/* Finish up the static storage duration function for this
round. */
if (type == void_type_node)
{
if (fndecl)
- cp_error_at ("too many arguments to %s `%+#D' at this point",
- called_thing, fndecl);
+ {
+ cp_error_at ("too many arguments to %s `%+#D'", called_thing,
+ fndecl);
+ error ("at this point in file");
+ }
else
error ("too many arguments to function");
/* In case anybody wants to know if this argument
else
{
if (fndecl)
- cp_error_at ("too few arguments to %s `%+#D' at this point",
- called_thing, fndecl);
+ {
+ cp_error_at ("too few arguments to %s `%+#D'",
+ called_thing, fndecl);
+ error ("at this point in file");
+ }
else
error ("too few arguments to function");
return error_mark_list;