(set_init_index): Add pedantic warning.
(set_init_label): Likewise. (digest_init): Add `static' to definition. (start_init): Fill in p->next. Handle gaps in record initializers. (constructor_bit_index): New variable. (constructor_stack): New field bit_index. (really_start_incremental_init, push_init_level): Save and init it. (pop_init_level): Restore it. (output_init_element): Update constructor_bit_index. Use it to output gaps. (pop_init_level): Speed up by using constructor_bit_index. (process_init_element): Accept STRING_CST for subarray. From-SVN: r4997
This commit is contained in:
parent
a785e67e7b
commit
b62acd6076
148
gcc/c-typeck.c
148
gcc/c-typeck.c
|
@ -4831,7 +4831,7 @@ static tree free_tree_list = NULL_TREE;
|
|||
If OFWHAT is null, the component name is stored on the spelling stack.
|
||||
(That is true for all nested calls to digest_init.) */
|
||||
|
||||
tree
|
||||
static tree
|
||||
digest_init (type, init, tail, require_constant, constructor_constant)
|
||||
tree type, init, *tail;
|
||||
int require_constant, constructor_constant;
|
||||
|
@ -5081,6 +5081,11 @@ static tree constructor_unfilled_fields;
|
|||
This is a special INTEGER_CST node that we modify in place. */
|
||||
static tree constructor_unfilled_index;
|
||||
|
||||
/* In a RECORD_TYPE, the byte index of the next consecutive field.
|
||||
This is so we can generate gaps between fields, when appropriate.
|
||||
This is a special INTEGER_CST node that we modify in place. */
|
||||
static tree constructor_bit_index;
|
||||
|
||||
/* If we are saving up the elements rather than allocating them,
|
||||
this is the list of elements so far (in reverse order,
|
||||
most recent first). */
|
||||
|
@ -5131,6 +5136,10 @@ static int constructor_top_level;
|
|||
/* When we finish reading a constructor expression
|
||||
(constructor_decl is 0), the CONSTRUCTOR goes here. */
|
||||
static tree constructor_result;
|
||||
|
||||
/* This stack has a level for each implicit or explicit level of
|
||||
structuring in the initializer, including the outermost one. It
|
||||
saves the values of most of the variables above. */
|
||||
|
||||
struct constructor_stack
|
||||
{
|
||||
|
@ -5142,6 +5151,7 @@ struct constructor_stack
|
|||
tree max_index;
|
||||
tree unfilled_index;
|
||||
tree unfilled_fields;
|
||||
tree bit_index;
|
||||
tree elements;
|
||||
int offset;
|
||||
tree pending_elts;
|
||||
|
@ -5205,7 +5215,7 @@ start_init (decl, asmspec_tree, top_level)
|
|||
p->spelling_size = spelling_size;
|
||||
p->deferred = constructor_subconstants_deferred;
|
||||
p->top_level = constructor_top_level;
|
||||
p->next = 0;
|
||||
p->next = initializer_stack;
|
||||
initializer_stack = p;
|
||||
|
||||
constructor_decl = decl;
|
||||
|
@ -5302,6 +5312,7 @@ really_start_incremental_init (type)
|
|||
p->max_index = constructor_max_index;
|
||||
p->unfilled_index = constructor_unfilled_index;
|
||||
p->unfilled_fields = constructor_unfilled_fields;
|
||||
p->bit_index = constructor_bit_index;
|
||||
p->elements = 0;
|
||||
p->constant = constructor_constant;
|
||||
p->simple = constructor_simple;
|
||||
|
@ -5326,6 +5337,7 @@ really_start_incremental_init (type)
|
|||
{
|
||||
constructor_fields = TYPE_FIELDS (constructor_type);
|
||||
constructor_unfilled_fields = constructor_fields;
|
||||
constructor_bit_index = copy_node (integer_zero_node);
|
||||
}
|
||||
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
|
||||
{
|
||||
|
@ -5381,6 +5393,7 @@ push_init_level (implicit)
|
|||
p->max_index = constructor_max_index;
|
||||
p->unfilled_index = constructor_unfilled_index;
|
||||
p->unfilled_fields = constructor_unfilled_fields;
|
||||
p->bit_index = constructor_bit_index;
|
||||
p->elements = constructor_elements;
|
||||
p->constant = constructor_constant;
|
||||
p->simple = constructor_simple;
|
||||
|
@ -5419,6 +5432,7 @@ push_init_level (implicit)
|
|||
{
|
||||
constructor_fields = TYPE_FIELDS (constructor_type);
|
||||
constructor_unfilled_fields = constructor_fields;
|
||||
constructor_bit_index = copy_node (integer_zero_node);
|
||||
}
|
||||
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
|
||||
{
|
||||
|
@ -5488,6 +5502,15 @@ pop_init_level (implicit)
|
|||
/* Now output all pending elements. */
|
||||
output_pending_init_elements (1);
|
||||
|
||||
#if 0 /* c-parse.in warns about {}. */
|
||||
/* In ANSI, each brace level must have at least one element. */
|
||||
if (! implicit && pedantic
|
||||
&& (TREE_CODE (constructor_type) == ARRAY_TYPE
|
||||
? integer_zerop (constructor_unfilled_index)
|
||||
: constructor_unfilled_fields == TYPE_FIELDS (constructor_type)))
|
||||
pedwarn_init ("empty braces in initializer%s", " for `%s'", NULL);
|
||||
#endif
|
||||
|
||||
/* Pad out the end of the structure. */
|
||||
|
||||
if (! constructor_incremental)
|
||||
|
@ -5515,17 +5538,9 @@ pop_init_level (implicit)
|
|||
if (TREE_CODE (constructor_type) == RECORD_TYPE
|
||||
|| TREE_CODE (constructor_type) == UNION_TYPE)
|
||||
{
|
||||
tree tail;
|
||||
/* Find the last field written out. */
|
||||
for (tail = TYPE_FIELDS (constructor_type); tail;
|
||||
tail = TREE_CHAIN (tail))
|
||||
if (TREE_CHAIN (tail) == constructor_unfilled_fields)
|
||||
break;
|
||||
/* Find the offset of the end of that field. */
|
||||
filled = size_binop (CEIL_DIV_EXPR,
|
||||
size_binop (PLUS_EXPR,
|
||||
DECL_FIELD_BITPOS (tail),
|
||||
DECL_SIZE (tail)),
|
||||
constructor_bit_index,
|
||||
size_int (BITS_PER_UNIT));
|
||||
}
|
||||
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
|
||||
|
@ -5581,6 +5596,7 @@ pop_init_level (implicit)
|
|||
constructor_max_index = p->max_index;
|
||||
constructor_unfilled_index = p->unfilled_index;
|
||||
constructor_unfilled_fields = p->unfilled_fields;
|
||||
constructor_bit_index = p->bit_index;
|
||||
constructor_elements = p->elements;
|
||||
constructor_constant = p->constant;
|
||||
constructor_simple = p->simple;
|
||||
|
@ -5622,7 +5638,11 @@ set_init_index (first, last)
|
|||
if (last != 0 && tree_int_cst_lt (last, first))
|
||||
error_init ("empty index range in initializer%s", " for `%s'", NULL);
|
||||
else
|
||||
constructor_range_end = last;
|
||||
{
|
||||
if (pedantic)
|
||||
pedwarn ("ANSI C forbids specifying element to initialize");
|
||||
constructor_range_end = last;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5651,7 +5671,11 @@ set_init_label (fieldname)
|
|||
error ("field `%s' already initialized",
|
||||
IDENTIFIER_POINTER (fieldname));
|
||||
else
|
||||
constructor_fields = tail;
|
||||
{
|
||||
constructor_fields = tail;
|
||||
if (pedantic)
|
||||
pedwarn ("ANSI C forbids specifying structure member to initialize");
|
||||
}
|
||||
}
|
||||
|
||||
/* "Output" the next constructor element.
|
||||
|
@ -5759,7 +5783,37 @@ output_init_element (value, type, field, pending)
|
|||
require_constant_elements),
|
||||
constructor_elements);
|
||||
else
|
||||
output_constant (value, int_size_in_bytes (type));
|
||||
{
|
||||
/* Structure elements may require alignment.
|
||||
Do this, if necessary. */
|
||||
if (TREE_CODE (constructor_type) == RECORD_TYPE)
|
||||
{
|
||||
/* Advance to offset of this element. */
|
||||
if (! tree_int_cst_equal (constructor_bit_index,
|
||||
DECL_FIELD_BITPOS (constructor_fields)))
|
||||
{
|
||||
int next = (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field))
|
||||
/ BITS_PER_UNIT);
|
||||
int here = (TREE_INT_CST_LOW (constructor_bit_index)
|
||||
/ BITS_PER_UNIT);
|
||||
|
||||
assemble_zeros (next - here);
|
||||
}
|
||||
}
|
||||
output_constant (value, int_size_in_bytes (type));
|
||||
|
||||
/* For a record, keep track of end position of last field. */
|
||||
if (TREE_CODE (constructor_type) == RECORD_TYPE)
|
||||
{
|
||||
tree temp = size_binop (PLUS_EXPR,
|
||||
DECL_FIELD_BITPOS (constructor_fields),
|
||||
DECL_SIZE (constructor_fields));
|
||||
TREE_INT_CST_LOW (constructor_bit_index)
|
||||
= TREE_INT_CST_LOW (temp);
|
||||
TREE_INT_CST_HIGH (constructor_bit_index)
|
||||
= TREE_INT_CST_HIGH (temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Advance the variable that indicates sequential elements output. */
|
||||
|
@ -5924,6 +5978,9 @@ void
|
|||
process_init_element (value)
|
||||
tree value;
|
||||
{
|
||||
tree orig_value = value;
|
||||
int string_flag = value != 0 && TREE_CODE (value) == STRING_CST;
|
||||
|
||||
if (value != 0)
|
||||
value = default_conversion (value);
|
||||
|
||||
|
@ -5968,9 +6025,18 @@ process_init_element (value)
|
|||
fieldtype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_fields));
|
||||
fieldcode = TREE_CODE (fieldtype);
|
||||
|
||||
if (value != 0 && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype
|
||||
&& (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
|
||||
|| fieldcode == UNION_TYPE))
|
||||
/* Accept a string constant to initialize a subarray. */
|
||||
if (value != 0
|
||||
&& fieldcode == ARRAY_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE
|
||||
&& string_flag)
|
||||
value = orig_value;
|
||||
/* Otherwise, if we have come to a subaggregate,
|
||||
and we don't have an element of its type, push into it. */
|
||||
else if (value != 0
|
||||
&& TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype
|
||||
&& (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
|
||||
|| fieldcode == UNION_TYPE))
|
||||
{
|
||||
push_init_level (1);
|
||||
continue;
|
||||
|
@ -5983,10 +6049,20 @@ process_init_element (value)
|
|||
RESTORE_SPELLING_DEPTH (constructor_depth);
|
||||
}
|
||||
else
|
||||
/* If we are doing the bookkeeping for an element that was
|
||||
directly output as a constructor,
|
||||
we must update constructor_unfilled_fields. */
|
||||
constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
|
||||
/* Do the bookkeeping for an element that was
|
||||
directly output as a constructor. */
|
||||
{
|
||||
/* For a record, keep track of end position of last field. */
|
||||
tree temp = size_binop (PLUS_EXPR,
|
||||
DECL_FIELD_BITPOS (constructor_fields),
|
||||
DECL_SIZE (constructor_fields));
|
||||
TREE_INT_CST_LOW (constructor_bit_index)
|
||||
= TREE_INT_CST_LOW (temp);
|
||||
TREE_INT_CST_HIGH (constructor_bit_index)
|
||||
= TREE_INT_CST_HIGH (temp);
|
||||
|
||||
constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
|
||||
}
|
||||
|
||||
constructor_fields = TREE_CHAIN (constructor_fields);
|
||||
break;
|
||||
|
@ -6006,9 +6082,18 @@ process_init_element (value)
|
|||
fieldtype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_fields));
|
||||
fieldcode = TREE_CODE (fieldtype);
|
||||
|
||||
if (value != 0 && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype
|
||||
&& (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
|
||||
|| fieldcode == UNION_TYPE))
|
||||
/* Accept a string constant to initialize a subarray. */
|
||||
if (value != 0
|
||||
&& fieldcode == ARRAY_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE
|
||||
&& string_flag)
|
||||
value = orig_value;
|
||||
/* Otherwise, if we have come to a subaggregate,
|
||||
and we don't have an element of its type, push into it. */
|
||||
else if (value != 0
|
||||
&& TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype
|
||||
&& (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
|
||||
|| fieldcode == UNION_TYPE))
|
||||
{
|
||||
push_init_level (1);
|
||||
continue;
|
||||
|
@ -6034,9 +6119,18 @@ process_init_element (value)
|
|||
tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
|
||||
enum tree_code eltcode = TREE_CODE (elttype);
|
||||
|
||||
if (value != 0 && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != elttype
|
||||
&& (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE
|
||||
|| eltcode == UNION_TYPE))
|
||||
/* Accept a string constant to initialize a subarray. */
|
||||
if (value != 0
|
||||
&& eltcode == ARRAY_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (elttype)) == INTEGER_TYPE
|
||||
&& string_flag)
|
||||
value = orig_value;
|
||||
/* Otherwise, if we have come to a subaggregate,
|
||||
and we don't have an element of its type, push into it. */
|
||||
else if (value != 0
|
||||
&& TYPE_MAIN_VARIANT (TREE_TYPE (value)) != elttype
|
||||
&& (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE
|
||||
|| eltcode == UNION_TYPE))
|
||||
{
|
||||
push_init_level (1);
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue