+/* A subroutine of gimplify_init_ctor_eval. Create a loop for
+ a RANGE_EXPR in a CONSTRUCTOR for an array.
+
+ var = lower;
+ loop_entry:
+ object[var] = value;
+ if (var == upper)
+ goto loop_exit;
+ var = var + 1;
+ goto loop_entry;
+ loop_exit:
+
+ We increment var _after_ the loop exit check because we might otherwise
+ fail if upper == TYPE_MAX_VALUE (type for upper).
+
+ Note that we never have to deal with SAVE_EXPRs here, because this has
+ already been taken care of for us, in gimplify_init_ctor_preeval(). */
+
+static void gimplify_init_ctor_eval (tree, tree, tree *, bool);
+
+static void
+gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
+ tree value, tree array_elt_type,
+ tree *pre_p, bool cleared)
+{
+ tree loop_entry_label, loop_exit_label;
+ tree var, var_type, cref;
+
+ loop_entry_label = create_artificial_label ();
+ loop_exit_label = create_artificial_label ();
+
+ /* Create and initialize the index variable. */
+ var_type = TREE_TYPE (upper);
+ var = create_tmp_var (var_type, NULL);
+ append_to_statement_list (build2 (MODIFY_EXPR, var_type, var, lower), pre_p);
+
+ /* Add the loop entry label. */
+ append_to_statement_list (build1 (LABEL_EXPR,
+ void_type_node,
+ loop_entry_label),
+ pre_p);
+
+ /* Build the reference. */
+ cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
+ var, NULL_TREE, NULL_TREE);
+
+ /* If we are a constructor, just call gimplify_init_ctor_eval to do
+ the store. Otherwise just assign value to the reference. */
+
+ if (TREE_CODE (value) == CONSTRUCTOR)
+ /* NB we might have to call ourself recursively through
+ gimplify_init_ctor_eval if the value is a constructor. */
+ gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
+ pre_p, cleared);
+ else
+ append_to_statement_list (build2 (MODIFY_EXPR, TREE_TYPE (cref),
+ cref, value),
+ pre_p);
+
+ /* We exit the loop when the index var is equal to the upper bound. */
+ gimplify_and_add (build3 (COND_EXPR, void_type_node,
+ build2 (EQ_EXPR, boolean_type_node,
+ var, upper),
+ build1 (GOTO_EXPR,
+ void_type_node,
+ loop_exit_label),
+ NULL_TREE),
+ pre_p);
+
+ /* Otherwise, increment the index var... */
+ append_to_statement_list (build2 (MODIFY_EXPR, var_type, var,
+ build2 (PLUS_EXPR, var_type, var,
+ fold_convert (var_type,
+ integer_one_node))),
+ pre_p);
+
+ /* ...and jump back to the loop entry. */
+ append_to_statement_list (build1 (GOTO_EXPR,
+ void_type_node,
+ loop_entry_label),
+ pre_p);
+
+ /* Add the loop exit label. */
+ append_to_statement_list (build1 (LABEL_EXPR,
+ void_type_node,
+ loop_exit_label),
+ pre_p);
+}
+