tree body = begin_compound_stmt (BCS_FN_BODY);
- bool has_import_inits = default_init && module_has_import_inits ();
- if (is_module_init && (has_import_inits || has_body))
+ if (is_module_init && has_body)
{
// If the function is going to be empty, don't emit idempotency.
// 'static bool __in_chrg = false;
finish_expr_stmt (assign);
}
- if (has_import_inits)
- module_add_import_initializers ();
-
return body;
}
maybe_warn_sized_delete ();
+ // Place the init fns in the right order. We need to do this now,
+ // so that any module init will go at the start.
+ if (static_init_fini_fns[true])
+ for (auto iter : *static_init_fini_fns[true])
+ iter.second = nreverse (iter.second);
+
/* Then, do the Objective-C stuff. This is where all the
Objective-C module stuff gets generated (symtab,
class/protocol/selector lists etc). This must be done after C++
if (c_dialect_objc ())
objc_write_global_declarations ();
- /* We give C linkage to static constructors and destructors. */
- push_lang_context (lang_name_c);
+ if (module_determine_import_inits ())
+ {
+ input_location = locus_at_end_of_parsing;
+ tree body = start_partial_init_fini_fn (true, DEFAULT_INIT_PRIORITY,
+ ssdf_count++);
+ module_add_import_initializers ();
+ input_location = locus_at_end_of_parsing;
+ finish_partial_init_fini_fn (body);
+ }
if ((c_dialect_objc () && objc_static_init_needed_p ())
- || module_global_init_needed () || module_has_import_inits ())
+ || module_global_init_needed ())
{
// Make sure there's a default priority entry.
if (!static_init_fini_fns[true])
}
/* Generate initialization and destruction functions for all
- priorities for which they are required. */
+ priorities for which they are required. They have C-language
+ linkage. */
+ push_lang_context (lang_name_c);
for (unsigned initp = 2; initp--;)
if (static_init_fini_fns[initp])
{
for (auto iter : *static_init_fini_fns[initp])
- {
- tree fns = iter.second;
- // The list of functions was constructed in reverse
- // order, which we only want for dtors.
- if (initp)
- fns = nreverse (fns);
- generate_ctor_or_dtor_function (initp, iter.first, fns,
- locus_at_end_of_parsing);
- }
+ generate_ctor_or_dtor_function (initp, iter.first, iter.second,
+ locus_at_end_of_parsing);
static_init_fini_fns[initp] = nullptr;
}
-
+ pop_lang_context ();
+
fini_modules ();
/* Generate any missing aliases. */
maybe_apply_pending_pragma_weaks ();
- /* We're done with static constructors, so we can go back to "C++"
- linkage now. */
- pop_lang_context ();
-
if (flag_vtable_verify)
{
vtv_recover_class_info ();
/* What the current TU is. */
unsigned module_kind;
-/* Number of global init calls needed. */
-unsigned num_init_calls_needed = 0;
-
/* Global trees. */
static const std::pair<tree *, unsigned> global_tree_arys[] =
{
return module_has_cmi_p () && !header_module_p ();
}
-/* Return true IFF we have import global inits to call. */
+/* Calculate which, if any, import initializers need calling. */
bool
-module_has_import_inits ()
+module_determine_import_inits ()
{
- return bool (num_init_calls_needed);
+ if (!modules || header_module_p ())
+ return false;
+
+ /* Determine call_init_p. We need the same bitmap allocation
+ scheme as for the imports member. */
+ function_depth++; /* Disable GC. */
+ bitmap indirect_imports (BITMAP_GGC_ALLOC ());
+
+ bool any = false;
+
+ /* Because indirect imports are before their direct import, and
+ we're scanning the array backwards, we only need one pass! */
+ for (unsigned ix = modules->length (); --ix;)
+ {
+ module_state *import = (*modules)[ix];
+
+ if (!import->is_header ()
+ && !bitmap_bit_p (indirect_imports, ix))
+ {
+ /* Everything this imports is therefore indirectly
+ imported. */
+ bitmap_ior_into (indirect_imports, import->imports);
+ /* We don't have to worry about the self-import bit,
+ because of the single pass. */
+
+ import->call_init_p = true;
+ any = true;
+ }
+ }
+ function_depth--;
+
+ return any;
}
/* Emit calls to each direct import's global initializer. Including
void
module_add_import_initializers ()
{
- unsigned calls = 0;
- if (modules)
- {
- tree fntype = build_function_type (void_type_node, void_list_node);
- releasing_vec args; // There are no args
+ if (!modules || header_module_p ())
+ return;
- for (unsigned ix = modules->length (); --ix;)
+ tree fntype = build_function_type (void_type_node, void_list_node);
+ releasing_vec args; // There are no args
+
+ for (unsigned ix = modules->length (); --ix;)
+ {
+ module_state *import = (*modules)[ix];
+ if (import->call_init_p)
{
- module_state *import = (*modules)[ix];
- if (import->call_init_p)
- {
- tree name = mangle_module_global_init (ix);
- tree fndecl = build_lang_decl (FUNCTION_DECL, name, fntype);
+ tree name = mangle_module_global_init (ix);
+ tree fndecl = build_lang_decl (FUNCTION_DECL, name, fntype);
- DECL_CONTEXT (fndecl) = FROB_CONTEXT (global_namespace);
- SET_DECL_ASSEMBLER_NAME (fndecl, name);
- TREE_PUBLIC (fndecl) = true;
- determine_visibility (fndecl);
+ DECL_CONTEXT (fndecl) = FROB_CONTEXT (global_namespace);
+ SET_DECL_ASSEMBLER_NAME (fndecl, name);
+ TREE_PUBLIC (fndecl) = true;
+ determine_visibility (fndecl);
- tree call = cp_build_function_call_vec (fndecl, &args,
- tf_warning_or_error);
- finish_expr_stmt (call);
-
- calls++;
- }
+ tree call = cp_build_function_call_vec (fndecl, &args,
+ tf_warning_or_error);
+ finish_expr_stmt (call);
}
}
-
- gcc_checking_assert (calls == num_init_calls_needed);
}
/* NAME & LEN are a preprocessed header name, possibly including the
(available_clusters + !available_clusters));
dump.pop (n);
}
-
- if (modules && !header_module_p ())
- {
- /* Determine call_init_p. We need the same bitmap allocation
- scheme as for the imports member. */
- function_depth++; /* Disable GC. */
- bitmap indirect_imports (BITMAP_GGC_ALLOC ());
-
- /* Because indirect imports are before their direct import, and
- we're scanning the array backwards, we only need one pass! */
- for (unsigned ix = modules->length (); --ix;)
- {
- module_state *import = (*modules)[ix];
-
- if (!import->is_header ()
- && !bitmap_bit_p (indirect_imports, ix))
- {
- /* Everything this imports is therefore indirectly
- imported. */
- bitmap_ior_into (indirect_imports, import->imports);
- /* We don't have to worry about the self-import bit,
- because of the single pass. */
-
- import->call_init_p = true;
- num_init_calls_needed++;
- }
- }
- function_depth--;
- }
}
void