-/* When target does not have ctors and dtors, we call all constructor
- and destructor by special initialization/destruction function
- recognized by collect2.
-
- When we are going to build this function, collect all constructors and
- destructors and turn them into normal functions. */
-
-static void
-record_cdtor_fn (tree fndecl)
-{
- struct cgraph_node *node;
- if (targetm.have_ctors_dtors
- || (!DECL_STATIC_CONSTRUCTOR (fndecl)
- && !DECL_STATIC_DESTRUCTOR (fndecl)))
- return;
-
- if (DECL_STATIC_CONSTRUCTOR (fndecl))
- {
- VEC_safe_push (tree, gc, static_ctors, fndecl);
- DECL_STATIC_CONSTRUCTOR (fndecl) = 0;
- }
- if (DECL_STATIC_DESTRUCTOR (fndecl))
- {
- VEC_safe_push (tree, gc, static_dtors, fndecl);
- DECL_STATIC_DESTRUCTOR (fndecl) = 0;
- }
- node = cgraph_node (fndecl);
- node->local.disregard_inline_limits = 1;
- cgraph_mark_reachable_node (node);
-}
-
-/* Define global constructors/destructor functions for the CDTORS, of
- which they are LEN. The CDTORS are sorted by initialization
- priority. If CTOR_P is true, these are constructors; otherwise,
- they are destructors. */
-
-static void
-build_cdtor (bool ctor_p, tree *cdtors, size_t len)
-{
- size_t i;
-
- i = 0;
- while (i < len)
- {
- tree body;
- tree fn;
- priority_type priority;
-
- priority = 0;
- body = NULL_TREE;
- /* Find the next batch of constructors/destructors with the same
- initialization priority. */
- do
- {
- priority_type p;
- fn = cdtors[i];
- p = ctor_p ? DECL_INIT_PRIORITY (fn) : DECL_FINI_PRIORITY (fn);
- if (!body)
- priority = p;
- else if (p != priority)
- break;
- append_to_statement_list (build_function_call_expr (UNKNOWN_LOCATION,
- fn, 0),
- &body);
- ++i;
- }
- while (i < len);
- gcc_assert (body != NULL_TREE);
- /* Generate a function to call all the function of like
- priority. */
- cgraph_build_static_cdtor (ctor_p ? 'I' : 'D', body, priority);
- }
-}
-
-/* Comparison function for qsort. P1 and P2 are actually of type
- "tree *" and point to static constructors. DECL_INIT_PRIORITY is
- used to determine the sort order. */
-
-static int
-compare_ctor (const void *p1, const void *p2)
-{
- tree f1;
- tree f2;
- int priority1;
- int priority2;
-
- f1 = *(const tree *)p1;
- f2 = *(const tree *)p2;
- priority1 = DECL_INIT_PRIORITY (f1);
- priority2 = DECL_INIT_PRIORITY (f2);
-
- if (priority1 < priority2)
- return -1;
- else if (priority1 > priority2)
- return 1;
- else
- /* Ensure a stable sort. */
- return (const tree *)p1 - (const tree *)p2;
-}
-
-/* Comparison function for qsort. P1 and P2 are actually of type
- "tree *" and point to static destructors. DECL_FINI_PRIORITY is
- used to determine the sort order. */
-
-static int
-compare_dtor (const void *p1, const void *p2)
-{
- tree f1;
- tree f2;
- int priority1;
- int priority2;
-
- f1 = *(const tree *)p1;
- f2 = *(const tree *)p2;
- priority1 = DECL_FINI_PRIORITY (f1);
- priority2 = DECL_FINI_PRIORITY (f2);
-
- if (priority1 < priority2)
- return -1;
- else if (priority1 > priority2)
- return 1;
- else
- /* Ensure a stable sort. */
- return (const tree *)p1 - (const tree *)p2;
-}
-
-/* Generate functions to call static constructors and destructors
- for targets that do not support .ctors/.dtors sections. These
- functions have magic names which are detected by collect2. */
-
-static void
-cgraph_build_cdtor_fns (void)
-{
- if (!VEC_empty (tree, static_ctors))
- {
- gcc_assert (!targetm.have_ctors_dtors);
- qsort (VEC_address (tree, static_ctors),
- VEC_length (tree, static_ctors),
- sizeof (tree),
- compare_ctor);
- build_cdtor (/*ctor_p=*/true,
- VEC_address (tree, static_ctors),
- VEC_length (tree, static_ctors));
- VEC_truncate (tree, static_ctors, 0);
- }
-
- if (!VEC_empty (tree, static_dtors))
- {
- gcc_assert (!targetm.have_ctors_dtors);
- qsort (VEC_address (tree, static_dtors),
- VEC_length (tree, static_dtors),
- sizeof (tree),
- compare_dtor);
- build_cdtor (/*ctor_p=*/false,
- VEC_address (tree, static_dtors),
- VEC_length (tree, static_dtors));
- VEC_truncate (tree, static_dtors, 0);
- }
-}
-