static void mf_xform_decls (tree fnbody, tree fnparams) { struct mf_xform_decls_data d; d.param_decls = fnparams; walk_tree_without_duplicates (&fnbody, mx_xfn_xform_decls, &d); }
static enum in_charge_use compute_use_thunks (tree fn) { tree last_arg, fn_parm; if (DECL_HAS_VTT_PARM_P (fn)) return NO_THUNKS; if (flag_apple_kext) return NO_THUNKS; if (flag_clone_structors) return NO_THUNKS; /* Functions that are too small will just get inlined back in anyway. Let the inliner do something useful instead. */ if (flag_inline_functions && estimate_num_insns (DECL_SAVED_TREE (fn)) < MAX_INLINE_INSNS_AUTO) return NO_THUNKS; /* If function accepts variable arguments, give up. */ last_arg = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fn))); if ( ! VOID_TYPE_P (TREE_VALUE (last_arg))) return NO_THUNKS; /* If constructor expects vector (AltiVec) arguments, give up. */ for (fn_parm = DECL_ARGUMENTS (fn); fn_parm; fn_parm = TREE_CHAIN (fn_parm)) if (TREE_CODE (fn_parm) == VECTOR_TYPE) return NO_THUNKS; if (DECL_HAS_IN_CHARGE_PARM_P (fn)) { int parmno; struct thunk_tree_walk_data data; for (parmno = 0, fn_parm = DECL_ARGUMENTS (fn); fn_parm; ++parmno, fn_parm = TREE_CHAIN (fn_parm)) if (parmno == 1) { data.in_charge_parm = fn_parm; break; } /* If every use of the in-charge parameter ANDs it with 1, then the functions that have in-charge set to 1 and 3 are equivalent, likewise 0 and 2. Check for this (common in practice). Likewise, if every use tests for equality with 0, then values 1, 2 and 3 are equivalent. */ gcc_assert (data.in_charge_parm != NULL_TREE); data.in_charge_use = ALL_THUNKS; walk_tree_without_duplicates (&DECL_SAVED_TREE (fn), examine_tree_for_in_charge_use, &data); return data.in_charge_use; } return ALL_THUNKS; }
void pre_genericize(tree fndecl, void *dummy) { (void)dummy; // get the function body tree body_chain = DECL_SAVED_TREE(fndecl); if(errorcount == 0 && sorrycount == 0) { walk_tree_without_duplicates(&body_chain, visit_fun, NULL); } }
void c_genericize (tree fndecl) { FILE *dump_orig; dump_flags_t local_dump_flags; struct cgraph_node *cgn; if (flag_sanitize & SANITIZE_BOUNDS) { hash_set<tree> pset; walk_tree (&DECL_SAVED_TREE (fndecl), ubsan_walk_array_refs_r, &pset, &pset); } if (warn_duplicated_branches) walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl), do_warn_duplicated_branches_r, NULL); /* Dump the C-specific tree IR. */ dump_orig = get_dump_info (TDI_original, &local_dump_flags); if (dump_orig) { fprintf (dump_orig, "\n;; Function %s", lang_hooks.decl_printable_name (fndecl, 2)); fprintf (dump_orig, " (%s)\n", (!DECL_ASSEMBLER_NAME_SET_P (fndecl) ? "null" : IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)))); fprintf (dump_orig, ";; enabled by -%s\n", dump_flag_name (TDI_original)); fprintf (dump_orig, "\n"); if (local_dump_flags & TDF_RAW) dump_node (DECL_SAVED_TREE (fndecl), TDF_SLIM | local_dump_flags, dump_orig); else print_c_tree (dump_orig, DECL_SAVED_TREE (fndecl)); fprintf (dump_orig, "\n"); } /* Dump all nested functions now. */ cgn = cgraph_node::get_create (fndecl); for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested) c_genericize (cgn->decl); }
tree visit_fun(tree *decl, int *subtrees, void *dummy) { (void)subtrees; (void)dummy; enum tree_code code = TREE_CODE(*decl); tree var = NULL_TREE; if(code == BIND_EXPR) { for(var = BIND_EXPR_VARS(*decl); var; var = TREE_CHAIN(var)) { if(TREE_CODE(var) == VAR_DECL) { if(auto_var_in_fn_p(var, current_function_decl) && !DECL_ARTIFICIAL(var)) { if(!DECL_INITIAL(var)) { tree init_var = walk_tree_without_duplicates(decl, walk_init, var); if(init_var == NULL_TREE) { // don't check classes initialization (too complicated) if(!(TREE_CODE(TREE_TYPE(var)) == RECORD_TYPE && CLASSTYPE_DECLARED_CLASS(TREE_TYPE(var)))) { WARNING_DECL(*decl, "uninititialized auto var %qD", var); } } } } } } } return NULL_TREE; }