}
static tree
-remap_type (tree type, inline_data *id)
+remap_type_1 (tree type, inline_data *id)
{
- splay_tree_node node;
tree new, t;
- if (type == NULL)
- return type;
-
- /* See if we have remapped this type. */
- node = splay_tree_lookup (id->decl_map, (splay_tree_key) type);
- if (node)
- return (tree) node->value;
-
- /* The type only needs remapping if it's variably modified. */
- if (! variably_modified_type_p (type, id->callee))
- {
- insert_decl_map (id, type, type);
- return type;
- }
-
/* We do need a copy. build and register it now. If this is a pointer or
reference type, remap the designated type and make a new pointer or
reference type. */
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
- walk_tree (&TYPE_FIELDS (new), copy_body_r, id, NULL);
+ {
+ tree f, nf = NULL;
+
+ for (f = TYPE_FIELDS (new); f ; f = TREE_CHAIN (f))
+ {
+ t = remap_decl (f, id);
+ DECL_CONTEXT (t) = new;
+ TREE_CHAIN (t) = nf;
+ nf = t;
+ }
+ TYPE_FIELDS (new) = nreverse (nf);
+ }
break;
case OFFSET_TYPE:
}
static tree
+remap_type (tree type, inline_data *id)
+{
+ splay_tree_node node;
+
+ if (type == NULL)
+ return type;
+
+ /* See if we have remapped this type. */
+ node = splay_tree_lookup (id->decl_map, (splay_tree_key) type);
+ if (node)
+ return (tree) node->value;
+
+ /* The type only needs remapping if it's variably modified. */
+ if (! variably_modified_type_p (type, id->callee))
+ {
+ insert_decl_map (id, type, type);
+ return type;
+ }
+
+ return remap_type_1 (type, id);
+}
+
+static tree
remap_decls (tree decls, inline_data *id)
{
tree old_var;
/* If the callee cannot possibly modify MODIFY_DEST, then we can
reuse it as the result of the call directly. Don't do this if
it would promote MODIFY_DEST to addressable. */
- else if (!TREE_STATIC (modify_dest)
- && !TREE_ADDRESSABLE (modify_dest)
- && !TREE_ADDRESSABLE (result))
- use_it = true;
+ else if (TREE_ADDRESSABLE (result))
+ use_it = false;
+ else
+ {
+ tree base_m = get_base_address (modify_dest);
+
+ /* If the base isn't a decl, then it's a pointer, and we don't
+ know where that's going to go. */
+ if (!DECL_P (base_m))
+ use_it = false;
+ else if (is_global_var (base_m))
+ use_it = false;
+ else if (!TREE_ADDRESSABLE (base_m))
+ use_it = true;
+ }
if (use_it)
{
DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl);
/* The new variable/label has no RTL, yet. */
- if (!TREE_STATIC (copy) && !DECL_EXTERNAL (copy))
+ if (CODE_CONTAINS_STRUCT (TREE_CODE (copy), TS_DECL_WRTL)
+ && !TREE_STATIC (copy) && !DECL_EXTERNAL (copy))
SET_DECL_RTL (copy, NULL_RTX);
/* These args would always appear unused, if not for this. */
{
return (!id->saving_p && !id->cloning_p && !id->versioning_p);
}
+
+/* Duplicate a type, fields and all. */
+
+tree
+build_duplicate_type (tree type)
+{
+ inline_data id;
+
+ memset (&id, 0, sizeof (id));
+ id.callee = current_function_decl;
+ id.caller = current_function_decl;
+ id.callee_cfun = cfun;
+ id.decl_map = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
+
+ type = remap_type_1 (type, &id);
+
+ splay_tree_delete (id.decl_map);
+
+ return type;
+}