aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2005-09-26 08:42:57 +0000
committerRichard Guenther <rguenther@suse.de>2005-09-26 08:42:57 +0000
commite0d7a19f592ccd7091f41b129f48017bb1f7327c (patch)
tree648f10df42593f49ba0272c32c14700dbb481473
parent0396274759975ddd5b5aaa88b473712a944f655a (diff)
2005-09-26 Richard Guenther <rguenther@suse.de>
PR middle-end/15855 * decl2.c (do_static_destruction): Remove. (finish_static_initialization_or_destruction): Likewise. (DECL_EFFECTIVE_INIT_PRIORITY): New macro. (NEEDS_GUARD_P): Likewise. (do_static_initialization): Rename to do_static_initialization_or_destruction. Process all initializers/destructors and handle common conditionalizing. (start_static_initialization_or_destruction): Rename to one_static_initialization_or_destruction. Handle only decl-specific conditionalizing. (cp_finish_file): Call do_static_initialization_or_destruction. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@104642 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog15
-rw-r--r--gcc/cp/decl2.c210
2 files changed, 123 insertions, 102 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b77388c2fd5..44109ef82f5 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,18 @@
+2005-09-26 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/15855
+ * decl2.c (do_static_destruction): Remove.
+ (finish_static_initialization_or_destruction): Likewise.
+ (DECL_EFFECTIVE_INIT_PRIORITY): New macro.
+ (NEEDS_GUARD_P): Likewise.
+ (do_static_initialization): Rename to
+ do_static_initialization_or_destruction. Process all
+ initializers/destructors and handle common conditionalizing.
+ (start_static_initialization_or_destruction): Rename to
+ one_static_initialization_or_destruction. Handle only
+ decl-specific conditionalizing.
+ (cp_finish_file): Call do_static_initialization_or_destruction.
+
2005-09-22 Jakub Jelinek <jakub@redhat.com>
PR c++/21983
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index c2a90fc5bc5..1e812838435 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -73,10 +73,8 @@ static void finish_objects (int, int, tree);
static tree start_static_storage_duration_function (unsigned);
static void finish_static_storage_duration_function (tree);
static priority_info get_priority_info (int);
-static void do_static_initialization (tree, tree);
-static void do_static_destruction (tree);
-static tree start_static_initialization_or_destruction (tree, int);
-static void finish_static_initialization_or_destruction (tree);
+static void do_static_initialization_or_destruction (tree, bool);
+static void one_static_initialization_or_destruction (tree, tree, bool);
static void generate_ctor_or_dtor_function (bool, int, location_t *);
static int generate_ctor_and_dtor_functions_for_priority (splay_tree_node,
void *);
@@ -2316,33 +2314,34 @@ get_priority_info (int priority)
return pi;
}
+/* The effective initialization priority of a DECL. */
+
+#define DECL_EFFECTIVE_INIT_PRIORITY(decl) \
+ ((!DECL_HAS_INIT_PRIORITY_P (decl) || DECL_INIT_PRIORITY (decl) == 0) \
+ ? DEFAULT_INIT_PRIORITY : DECL_INIT_PRIORITY (decl))
+
+/* Wether a DECL needs a guard to protect it against multiple
+ initialization. */
+
+#define NEEDS_GUARD_P(decl) (TREE_PUBLIC (decl) && (DECL_COMMON (decl) \
+ || DECL_ONE_ONLY (decl) \
+ || DECL_WEAK (decl)))
+
/* Set up to handle the initialization or destruction of DECL. If
INITP is nonzero, we are initializing the variable. Otherwise, we
are destroying it. */
-static tree
-start_static_initialization_or_destruction (tree decl, int initp)
+static void
+one_static_initialization_or_destruction (tree decl, tree init, bool initp)
{
tree guard_if_stmt = NULL_TREE;
- int priority = 0;
- tree cond;
tree guard;
- tree init_cond;
- priority_info pi;
-
- /* Figure out the priority for this declaration. */
- if (DECL_HAS_INIT_PRIORITY_P (decl))
- priority = DECL_INIT_PRIORITY (decl);
- if (!priority)
- priority = DEFAULT_INIT_PRIORITY;
- /* Remember that we had an initialization or finalization at this
- priority. */
- pi = get_priority_info (priority);
- if (initp)
- pi->initializations_p = 1;
- else
- pi->destructions_p = 1;
+ /* If we are supposed to destruct and there's a trivial destructor,
+ nothing has to be done. */
+ if (!initp
+ && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
+ return;
/* Trick the compiler into thinking we are at the file and line
where DECL was declared so that error-messages make sense, and so
@@ -2368,27 +2367,13 @@ start_static_initialization_or_destruction (tree decl, int initp)
DECL_STATIC_FUNCTION_P (current_function_decl) = 1;
}
- /* Conditionalize this initialization on being in the right priority
- and being initializing/finalizing appropriately. */
- guard_if_stmt = begin_if_stmt ();
- cond = cp_build_binary_op (EQ_EXPR,
- priority_decl,
- build_int_cst (NULL_TREE, priority));
- init_cond = initp ? integer_one_node : integer_zero_node;
- init_cond = cp_build_binary_op (EQ_EXPR,
- initialize_p_decl,
- init_cond);
- cond = cp_build_binary_op (TRUTH_ANDIF_EXPR, cond, init_cond);
-
/* Assume we don't need a guard. */
guard = NULL_TREE;
/* We need a guard if this is an object with external linkage that
might be initialized in more than one place. (For example, a
static data member of a template, when the data member requires
construction.) */
- if (TREE_PUBLIC (decl) && (DECL_COMMON (decl)
- || DECL_ONE_ONLY (decl)
- || DECL_WEAK (decl)))
+ if (NEEDS_GUARD_P (decl))
{
tree guard_cond;
@@ -2425,28 +2410,36 @@ start_static_initialization_or_destruction (tree decl, int initp)
/*noconvert=*/1),
integer_zero_node);
- cond = cp_build_binary_op (TRUTH_ANDIF_EXPR, cond, guard_cond);
+ guard_if_stmt = begin_if_stmt ();
+ finish_if_stmt_cond (guard_cond, guard_if_stmt);
}
- finish_if_stmt_cond (cond, guard_if_stmt);
/* If we're using __cxa_atexit, we have not already set the GUARD,
so we must do so now. */
if (guard && initp && flag_use_cxa_atexit)
finish_expr_stmt (set_guard (guard));
- return guard_if_stmt;
-}
+ /* Perform the initialization or destruction. */
+ if (initp)
+ {
+ if (init)
+ finish_expr_stmt (init);
-/* We've just finished generating code to do an initialization or
- finalization. GUARD_IF_STMT is the if-statement we used to guard
- the initialization. */
+ /* If we're using __cxa_atexit, register a function that calls the
+ destructor for the object. */
+ if (flag_use_cxa_atexit)
+ finish_expr_stmt (register_dtor_fn (decl));
+ }
+ else
+ finish_expr_stmt (build_cleanup (decl));
-static void
-finish_static_initialization_or_destruction (tree guard_if_stmt)
-{
- finish_then_clause (guard_if_stmt);
- finish_if_stmt (guard_if_stmt);
+ /* Finish the guard if-stmt, if necessary. */
+ if (guard)
+ {
+ finish_then_clause (guard_if_stmt);
+ finish_if_stmt (guard_if_stmt);
+ }
/* Now that we're done with DECL we don't need to pretend to be a
member of its class any longer. */
@@ -2454,55 +2447,72 @@ finish_static_initialization_or_destruction (tree guard_if_stmt)
DECL_STATIC_FUNCTION_P (current_function_decl) = 0;
}
-/* Generate code to do the initialization of DECL, a VAR_DECL with
- static storage duration. The initialization is INIT. */
+/* Generate code to do the initialization or destruction of the decls in VARS,
+ a TREE_LIST of VAR_DECL with static storage duration.
+ Whether initialization or destruction is performed is specified by INITP. */
static void
-do_static_initialization (tree decl, tree init)
+do_static_initialization_or_destruction (tree vars, bool initp)
{
- tree guard_if_stmt;
-
- /* Set up for the initialization. */
- guard_if_stmt
- = start_static_initialization_or_destruction (decl,
- /*initp=*/1);
-
- /* Perform the initialization. */
- if (init)
- finish_expr_stmt (init);
-
- /* If we're using __cxa_atexit, register a function that calls the
- destructor for the object. */
- if (flag_use_cxa_atexit)
- finish_expr_stmt (register_dtor_fn (decl));
+ tree node, init_if_stmt, cond;
- /* Finish up. */
- finish_static_initialization_or_destruction (guard_if_stmt);
-}
-
-/* Generate code to do the static destruction of DECL. If DECL may be
- initialized more than once in different object files, GUARD is the
- guard variable to check. PRIORITY is the priority for the
- destruction. */
-
-static void
-do_static_destruction (tree decl)
-{
- tree guard_if_stmt;
-
- /* If we're using __cxa_atexit, then destructors are registered
- immediately after objects are initialized. */
- gcc_assert (!flag_use_cxa_atexit);
-
- /* If we don't need a destructor, there's nothing to do. */
- if (TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
- return;
+ /* Build the outer if-stmt to check for initialization or destruction. */
+ init_if_stmt = begin_if_stmt ();
+ cond = initp ? integer_one_node : integer_zero_node;
+ cond = cp_build_binary_op (EQ_EXPR,
+ initialize_p_decl,
+ cond);
+ finish_if_stmt_cond (cond, init_if_stmt);
+
+ node = vars;
+ do {
+ tree decl = TREE_VALUE (node);
+ tree priority_if_stmt;
+ int priority;
+ priority_info pi;
+
+ /* If we don't need a destructor, there's nothing to do. Avoid
+ creating a possibly empty if-stmt. */
+ if (!initp && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
+ {
+ node = TREE_CHAIN (node);
+ continue;
+ }
- /* Actually do the destruction. */
- guard_if_stmt = start_static_initialization_or_destruction (decl,
- /*initp=*/0);
- finish_expr_stmt (build_cleanup (decl));
- finish_static_initialization_or_destruction (guard_if_stmt);
+ /* Remember that we had an initialization or finalization at this
+ priority. */
+ priority = DECL_EFFECTIVE_INIT_PRIORITY (decl);
+ pi = get_priority_info (priority);
+ if (initp)
+ pi->initializations_p = 1;
+ else
+ pi->destructions_p = 1;
+
+ /* Conditionalize this initialization on being in the right priority
+ and being initializing/finalizing appropriately. */
+ priority_if_stmt = begin_if_stmt ();
+ cond = cp_build_binary_op (EQ_EXPR,
+ priority_decl,
+ build_int_cst (NULL_TREE, priority));
+ finish_if_stmt_cond (cond, priority_if_stmt);
+
+ /* Process initializers with same priority. */
+ for (; node
+ && DECL_EFFECTIVE_INIT_PRIORITY (TREE_VALUE (node)) == priority;
+ node = TREE_CHAIN (node))
+ /* Do one initialization or destruction. */
+ one_static_initialization_or_destruction (TREE_VALUE (node),
+ TREE_PURPOSE (node), initp);
+
+ /* Finish up the priority if-stmt body. */
+ finish_then_clause (priority_if_stmt);
+ finish_if_stmt (priority_if_stmt);
+
+ } while (node);
+
+ /* Finish up the init/destruct if-stmt body. */
+ finish_then_clause (init_if_stmt);
+ finish_if_stmt (init_if_stmt);
}
/* VARS is a list of variables with static storage duration which may
@@ -2900,8 +2910,6 @@ cp_finish_file (void)
if (vars)
{
- tree v;
-
/* We need to start a new initialization function each time
through the loop. That's because we need to know which
vtables have been referenced, and TREE_SYMBOL_REFERENCED
@@ -2920,9 +2928,8 @@ cp_finish_file (void)
write_out_vars (vars);
/* First generate code to do all the initializations. */
- for (v = vars; v; v = TREE_CHAIN (v))
- do_static_initialization (TREE_VALUE (v),
- TREE_PURPOSE (v));
+ if (vars)
+ do_static_initialization_or_destruction (vars, /*initp=*/true);
/* Then, generate code to do all the destructions. Do these
in reverse order so that the most recently constructed
@@ -2930,11 +2937,10 @@ cp_finish_file (void)
__cxa_atexit, then we don't need to do this; functions
were registered at initialization time to destroy the
local statics. */
- if (!flag_use_cxa_atexit)
+ if (!flag_use_cxa_atexit && vars)
{
vars = nreverse (vars);
- for (v = vars; v; v = TREE_CHAIN (v))
- do_static_destruction (TREE_VALUE (v));
+ do_static_initialization_or_destruction (vars, /*initp=*/false);
}
else
vars = NULL_TREE;