-/* Register a function tree, so that its optimization and conversion
- to RTL is only done at the end of the compilation. */
-
-int
-defer_fn (tree fn)
-{
- VARRAY_PUSH_TREE (deferred_fns, fn);
-
- return 1;
-}
-
-/* Expand deferred functions for C and ObjC. */
-
-static void
-expand_deferred_fns (void)
-{
- unsigned int i;
- bool reconsider;
-
- do
- {
- reconsider = false;
- for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_fns); i++)
- {
- tree decl = VARRAY_TREE (deferred_fns, i);
-
- if (TREE_ASM_WRITTEN (decl))
- continue;
-
- /* "extern inline" says the symbol exists externally,
- which means we should *never* expand it locally
- unless we're actually inlining it. */
- /* ??? Why did we queue these in the first place? */
- if (DECL_DECLARED_INLINE_P (decl) && DECL_EXTERNAL (decl))
- continue;
-
- /* With flag_keep_inline_functions, we're emitting everything,
- so we never need to reconsider. */
- if (flag_keep_inline_functions)
- ;
- /* Must emit all public functions. C doesn't have COMDAT
- functions, so we don't need to check that, like C++. */
- else if (TREE_PUBLIC (decl))
- reconsider = true;
- /* Must emit if the symbol is referenced. */
- else if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
- reconsider = true;
- else
- continue;
-
- c_expand_deferred_function (decl);
- }
- }
- while (reconsider);
-
- deferred_fns = 0;
-}
-
-static tree
-start_cdtor (int method_type)
-{
- tree fnname = get_file_function_name (method_type);
- tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
- tree body;
-
- start_function (void_list_node_1,
- build_nt (CALL_EXPR, fnname,
- tree_cons (NULL_TREE, NULL_TREE, void_list_node_1),
- NULL_TREE),
- NULL_TREE);
- store_parm_decls ();
-
- current_function_cannot_inline
- = "static constructors and destructors cannot be inlined";
-
- body = c_begin_compound_stmt ();
-
- pushlevel (0);
- clear_last_expr ();
- add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
-
- return body;
-}
-
-static void
-finish_cdtor (tree body)
-{
- tree scope;
- tree block;
-
- scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
- block = poplevel (0, 0, 0);
- SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
- SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
-
- RECHAIN_STMTS (body, COMPOUND_BODY (body));
-
- finish_function (0, 0);
-}
-
-/* Called at end of parsing, but before end-of-file processing. */
-
-void
-c_objc_common_finish_file (void)
-{
- if (pch_file)
- c_common_write_pch ();
-
- /* If multiple translation units were built, copy information between
- them based on linkage rules. */
- merge_translation_unit_decls ();
-
- if (flag_unit_at_a_time)
- {
- cgraph_finalize_compilation_unit ();
- cgraph_optimize ();
- }
- else
- expand_deferred_fns ();
-
- if (static_ctors)
- {
- tree body = start_cdtor ('I');
-
- for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
- c_expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
- NULL_TREE));
-
- finish_cdtor (body);
- }
-
- if (static_dtors)
- {
- tree body = start_cdtor ('D');
-
- for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
- c_expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
- NULL_TREE));
-
- finish_cdtor (body);
- }
-
- {
- int flags;
- FILE *stream = dump_begin (TDI_all, &flags);
-
- if (stream)
- {
- dump_node (getdecls (), flags & ~TDF_SLIM, stream);
- dump_end (TDI_all, stream);
- }
- }
-}
-