diff options
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r-- | gcc/tree-inline.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 510b53e..4b937ca 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -5817,3 +5817,55 @@ build_duplicate_type (tree type) return type; } + +/* Unshare the entire DECL_SAVED_TREE of FN and return the remapped + parameters and RESULT_DECL in PARMS and RESULT. Used by C++ constexpr + evaluation. */ + +tree +copy_fn (tree fn, tree& parms, tree& result) +{ + copy_body_data id; + tree param; + hash_map<tree, tree> decl_map; + + tree *p = &parms; + *p = NULL_TREE; + + memset (&id, 0, sizeof (id)); + id.src_fn = fn; + id.dst_fn = current_function_decl; + id.src_cfun = DECL_STRUCT_FUNCTION (fn); + id.decl_map = &decl_map; + + id.copy_decl = copy_decl_no_change; + id.transform_call_graph_edges = CB_CGE_DUPLICATE; + id.transform_new_cfg = false; + id.transform_return_to_modify = false; + id.transform_parameter = true; + id.transform_lang_insert_block = NULL; + + /* Make sure not to unshare trees behind the front-end's back + since front-end specific mechanisms may rely on sharing. */ + id.regimplify = false; + id.do_not_unshare = true; + + /* We're not inside any EH region. */ + id.eh_lp_nr = 0; + + /* Remap the parameters and result and return them to the caller. */ + for (param = DECL_ARGUMENTS (fn); + param; + param = DECL_CHAIN (param)) + { + *p = remap_decl (param, &id); + p = &DECL_CHAIN (*p); + } + + if (DECL_RESULT (fn)) + result = remap_decl (DECL_RESULT (fn), &id); + else + result = NULL_TREE; + + return copy_tree_body (&id); +} |