constructor_elt *end;
};
-static tree reshape_init_r (tree, reshape_iter *, bool, tsubst_flags_t);
+static tree reshape_init_r (tree, reshape_iter *, tree, tsubst_flags_t);
/* FIELD is a FIELD_DECL or NULL. In the former case, the value
returned is the next FIELD_DECL (possibly FIELD itself) that can be
static tree
reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
- tsubst_flags_t complain)
+ tree first_initializer_p, tsubst_flags_t complain)
{
tree new_init;
bool sized_array_p = (max_index && TREE_CONSTANT (max_index));
unsigned HOST_WIDE_INT max_index_cst = 0;
unsigned HOST_WIDE_INT index;
- /* The initializer for an array is always a CONSTRUCTOR. */
- new_init = build_constructor (init_list_type_node, NULL);
+ /* The initializer for an array is always a CONSTRUCTOR. If this is the
+ outermost CONSTRUCTOR and the element type is non-aggregate, we don't need
+ to build a new one. */
+ bool reuse = first_initializer_p && !CP_AGGREGATE_TYPE_P (elt_type);
+ if (reuse)
+ new_init = first_initializer_p;
+ else
+ new_init = build_constructor (init_list_type_node, NULL);
if (sized_array_p)
{
constructor_elt *old_cur = d->cur;
check_array_designated_initializer (d->cur, index);
- elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false,
+ elt_init = reshape_init_r (elt_type, d,
+ /*first_initializer_p=*/NULL_TREE,
complain);
if (elt_init == error_mark_node)
return error_mark_node;
- CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init),
- size_int (index), elt_init);
+ tree idx = size_int (index);
+ if (reuse)
+ {
+ old_cur->index = idx;
+ old_cur->value = elt_init;
+ }
+ else
+ CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init),
+ idx, elt_init);
if (!TREE_CONSTANT (elt_init))
TREE_CONSTANT (new_init) = false;
Parameters are the same of reshape_init_r. */
static tree
-reshape_init_array (tree type, reshape_iter *d, tsubst_flags_t complain)
+reshape_init_array (tree type, reshape_iter *d, tree first_initializer_p,
+ tsubst_flags_t complain)
{
tree max_index = NULL_TREE;
if (TYPE_DOMAIN (type))
max_index = array_type_nelts (type);
- return reshape_init_array_1 (TREE_TYPE (type), max_index, d, complain);
+ return reshape_init_array_1 (TREE_TYPE (type), max_index, d,
+ first_initializer_p, complain);
}
/* Subroutine of reshape_init_r, processes the initializers for vectors.
if (VECTOR_TYPE_P (type))
max_index = size_int (TYPE_VECTOR_SUBPARTS (type) - 1);
- return reshape_init_array_1 (TREE_TYPE (type), max_index, d, complain);
+ return reshape_init_array_1 (TREE_TYPE (type), max_index, d,
+ NULL_TREE, complain);
}
/* Subroutine of reshape_init_r, processes the initializers for classes
break;
field_init = reshape_init_r (TREE_TYPE (field), d,
- /*first_initializer_p=*/false, complain);
+ /*first_initializer_p=*/NULL_TREE,
+ complain);
if (field_init == error_mark_node)
return error_mark_node;
/* Subroutine of reshape_init, which processes a single initializer (part of
a CONSTRUCTOR). TYPE is the type of the variable being initialized, D is the
iterator within the CONSTRUCTOR which points to the initializer to process.
- FIRST_INITIALIZER_P is true if this is the first initializer of the
- outermost CONSTRUCTOR node. */
+ If this is the first initializer of the outermost CONSTRUCTOR node,
+ FIRST_INITIALIZER_P is that CONSTRUCTOR; otherwise, it is NULL_TREE. */
static tree
-reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
+reshape_init_r (tree type, reshape_iter *d, tree first_initializer_p,
tsubst_flags_t complain)
{
tree init = d->cur->value;
if (CLASS_TYPE_P (type))
return reshape_init_class (type, d, first_initializer_p, complain);
else if (TREE_CODE (type) == ARRAY_TYPE)
- return reshape_init_array (type, d, complain);
+ return reshape_init_array (type, d, first_initializer_p, complain);
else if (VECTOR_TYPE_P (type))
return reshape_init_vector (type, d, complain);
else
d.cur = &(*v)[0];
d.end = d.cur + v->length ();
- new_init = reshape_init_r (type, &d, true, complain);
+ new_init = reshape_init_r (type, &d, init, complain);
if (new_init == error_mark_node)
return error_mark_node;