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 (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); } }
/* Emit any file-wide instrumentation. */ void mudflap_finish_file (void) { tree ctor_statements = NULL_TREE; /* No need to continue when there were errors. */ if (errorcount != 0 || sorrycount != 0) return; /* Insert a call to __mf_init. */ { tree call2_stmt = build_function_call_expr (mf_init_fndecl, NULL_TREE); append_to_statement_list (call2_stmt, &ctor_statements); } /* If appropriate, call __mf_set_options to pass along read-ignore mode. */ if (flag_mudflap_ignore_reads) { tree arg = tree_cons (NULL_TREE, mf_build_string ("-ignore-reads"), NULL_TREE); tree call_stmt = build_function_call_expr (mf_set_options_fndecl, arg); append_to_statement_list (call_stmt, &ctor_statements); } /* Process all enqueued object decls. */ if (deferred_static_decls) { size_t i; tree obj; for (i = 0; VEC_iterate (tree, deferred_static_decls, i, obj); i++) { gcc_assert (DECL_P (obj)); if (mf_marked_p (obj)) continue; /* Omit registration for static unaddressed objects. NB: Perform registration for non-static objects regardless of TREE_USED or TREE_ADDRESSABLE, because they may be used from other compilation units. */ if (! TREE_PUBLIC (obj) && ! TREE_ADDRESSABLE (obj)) continue; if (! COMPLETE_TYPE_P (TREE_TYPE (obj))) { warning (0, "mudflap cannot track unknown size extern %qs", IDENTIFIER_POINTER (DECL_NAME (obj))); continue; } mudflap_register_call (obj, size_in_bytes (TREE_TYPE (obj)), mf_varname_tree (obj)); } VEC_truncate (tree, deferred_static_decls, 0); } /* Append all the enqueued registration calls. */ if (enqueued_call_stmt_chain) { append_to_statement_list (enqueued_call_stmt_chain, &ctor_statements); enqueued_call_stmt_chain = NULL_TREE; } cgraph_build_static_cdtor ('I', ctor_statements, MAX_RESERVED_INIT_PRIORITY-1); }