+/* A subroutine of wrapup_global_declarations. We've come to the end of
+ the compilation unit. All deferred variables should be undeferred,
+ and all incomplete decls should be finalized. */
+
+void
+wrapup_global_declaration_1 (tree decl)
+{
+ /* We're not deferring this any longer. Assignment is conditional to
+ avoid needlessly dirtying PCH pages. */
+ if (CODE_CONTAINS_STRUCT (TREE_CODE (decl), TS_DECL_WITH_VIS)
+ && DECL_DEFER_OUTPUT (decl) != 0)
+ DECL_DEFER_OUTPUT (decl) = 0;
+
+ if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0)
+ lang_hooks.finish_incomplete_decl (decl);
+}
+
+/* A subroutine of wrapup_global_declarations. Decide whether or not DECL
+ needs to be output. Return true if it is output. */
+
+bool
+wrapup_global_declaration_2 (tree decl)
+{
+ if (TREE_ASM_WRITTEN (decl) || DECL_EXTERNAL (decl))
+ return false;
+
+ /* Don't write out static consts, unless we still need them.
+
+ We also keep static consts if not optimizing (for debugging),
+ unless the user specified -fno-keep-static-consts.
+ ??? They might be better written into the debug information.
+ This is possible when using DWARF.
+
+ A language processor that wants static constants to be always
+ written out (even if it is not used) is responsible for
+ calling rest_of_decl_compilation itself. E.g. the C front-end
+ calls rest_of_decl_compilation from finish_decl.
+ One motivation for this is that is conventional in some
+ environments to write things like:
+ static const char rcsid[] = "... version string ...";
+ intending to force the string to be in the executable.
+
+ A language processor that would prefer to have unneeded
+ static constants "optimized away" would just defer writing
+ them out until here. E.g. C++ does this, because static
+ constants are often defined in header files.
+
+ ??? A tempting alternative (for both C and C++) would be
+ to force a constant to be written if and only if it is
+ defined in a main file, as opposed to an include file. */
+
+ if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
+ {
+ struct varpool_node *node;
+ bool needed = true;
+ node = varpool_node (decl);
+
+ if (node->finalized)
+ needed = false;
+ else if (node->alias)
+ needed = false;
+ else if (!cgraph_global_info_ready
+ && (TREE_USED (decl)
+ || TREE_USED (DECL_ASSEMBLER_NAME (decl))))
+ /* needed */;
+ else if (node->needed)
+ /* needed */;
+ else if (DECL_COMDAT (decl))
+ needed = false;
+ else if (TREE_READONLY (decl) && !TREE_PUBLIC (decl)
+ && (optimize || !flag_keep_static_consts
+ || DECL_ARTIFICIAL (decl)))
+ needed = false;
+
+ if (needed)
+ {
+ rest_of_decl_compilation (decl, 1, 1);
+ return true;
+ }
+ }
+
+ return false;
+}
+