+/* A helper function for remap_vla_decls. See if *TP contains
+ some remapped variables. */
+
+static tree
+contains_remapped_vars (tree *tp, int *walk_subtrees, void *data)
+{
+ struct nesting_info *root = (struct nesting_info *) data;
+ tree t = *tp;
+ void **slot;
+
+ if (DECL_P (t))
+ {
+ *walk_subtrees = 0;
+ slot = pointer_map_contains (root->var_map, t);
+
+ if (slot)
+ return (tree) *slot;
+ }
+ return NULL;
+}
+
+/* Remap VLA decls in BLOCK and subblocks if remapped variables are
+ involved. */
+
+static void
+remap_vla_decls (tree block, struct nesting_info *root)
+{
+ tree var, subblock, val, type;
+ struct nesting_copy_body_data id;
+
+ for (subblock = BLOCK_SUBBLOCKS (block);
+ subblock;
+ subblock = BLOCK_CHAIN (subblock))
+ remap_vla_decls (subblock, root);
+
+ for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var))
+ {
+ if (TREE_CODE (var) == VAR_DECL
+ && variably_modified_type_p (TREE_TYPE (var), NULL)
+ && DECL_HAS_VALUE_EXPR_P (var))
+ {
+ type = TREE_TYPE (var);
+ val = DECL_VALUE_EXPR (var);
+ if (walk_tree (&type, contains_remapped_vars, root, NULL) != NULL
+ || walk_tree (&val, contains_remapped_vars, root, NULL) != NULL)
+ break;
+ }
+ }
+ if (var == NULL_TREE)
+ return;
+
+ memset (&id, 0, sizeof (id));
+ id.cb.copy_decl = nesting_copy_decl;
+ id.cb.decl_map = pointer_map_create ();
+ id.root = root;
+
+ for (; var; var = TREE_CHAIN (var))
+ if (TREE_CODE (var) == VAR_DECL
+ && variably_modified_type_p (TREE_TYPE (var), NULL)
+ && DECL_HAS_VALUE_EXPR_P (var))
+ {
+ struct nesting_info *i;
+ tree newt, t, context;
+
+ t = type = TREE_TYPE (var);
+ val = DECL_VALUE_EXPR (var);
+ if (walk_tree (&type, contains_remapped_vars, root, NULL) == NULL
+ && walk_tree (&val, contains_remapped_vars, root, NULL) == NULL)
+ continue;
+
+ context = decl_function_context (var);
+ for (i = root; i; i = i->outer)
+ if (i->context == context)
+ break;
+
+ if (i == NULL)
+ continue;
+
+ id.cb.src_fn = i->context;
+ id.cb.dst_fn = i->context;
+ id.cb.src_cfun = DECL_STRUCT_FUNCTION (root->context);
+
+ TREE_TYPE (var) = newt = remap_type (type, &id.cb);
+ while (POINTER_TYPE_P (newt) && !TYPE_NAME (newt))
+ {
+ newt = TREE_TYPE (newt);
+ t = TREE_TYPE (t);
+ }
+ if (TYPE_NAME (newt)
+ && TREE_CODE (TYPE_NAME (newt)) == TYPE_DECL
+ && DECL_ORIGINAL_TYPE (TYPE_NAME (newt))
+ && newt != t
+ && TYPE_NAME (newt) == TYPE_NAME (t))
+ TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb);
+
+ walk_tree (&val, copy_tree_body_r, &id.cb, NULL);
+ if (val != DECL_VALUE_EXPR (var))
+ SET_DECL_VALUE_EXPR (var, val);
+ }
+
+ pointer_map_destroy (id.cb.decl_map);
+}
+