Commit b62acd60 by Richard Stallman

(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
parent a785e67e
...@@ -4831,7 +4831,7 @@ static tree free_tree_list = NULL_TREE; ...@@ -4831,7 +4831,7 @@ static tree free_tree_list = NULL_TREE;
If OFWHAT is null, the component name is stored on the spelling stack. If OFWHAT is null, the component name is stored on the spelling stack.
(That is true for all nested calls to digest_init.) */ (That is true for all nested calls to digest_init.) */
tree static tree
digest_init (type, init, tail, require_constant, constructor_constant) digest_init (type, init, tail, require_constant, constructor_constant)
tree type, init, *tail; tree type, init, *tail;
int require_constant, constructor_constant; int require_constant, constructor_constant;
...@@ -5081,6 +5081,11 @@ static tree constructor_unfilled_fields; ...@@ -5081,6 +5081,11 @@ static tree constructor_unfilled_fields;
This is a special INTEGER_CST node that we modify in place. */ This is a special INTEGER_CST node that we modify in place. */
static tree constructor_unfilled_index; 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, /* If we are saving up the elements rather than allocating them,
this is the list of elements so far (in reverse order, this is the list of elements so far (in reverse order,
most recent first). */ most recent first). */
...@@ -5131,6 +5136,10 @@ static int constructor_top_level; ...@@ -5131,6 +5136,10 @@ static int constructor_top_level;
/* When we finish reading a constructor expression /* When we finish reading a constructor expression
(constructor_decl is 0), the CONSTRUCTOR goes here. */ (constructor_decl is 0), the CONSTRUCTOR goes here. */
static tree constructor_result; 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 struct constructor_stack
{ {
...@@ -5142,6 +5151,7 @@ struct constructor_stack ...@@ -5142,6 +5151,7 @@ struct constructor_stack
tree max_index; tree max_index;
tree unfilled_index; tree unfilled_index;
tree unfilled_fields; tree unfilled_fields;
tree bit_index;
tree elements; tree elements;
int offset; int offset;
tree pending_elts; tree pending_elts;
...@@ -5205,7 +5215,7 @@ start_init (decl, asmspec_tree, top_level) ...@@ -5205,7 +5215,7 @@ start_init (decl, asmspec_tree, top_level)
p->spelling_size = spelling_size; p->spelling_size = spelling_size;
p->deferred = constructor_subconstants_deferred; p->deferred = constructor_subconstants_deferred;
p->top_level = constructor_top_level; p->top_level = constructor_top_level;
p->next = 0; p->next = initializer_stack;
initializer_stack = p; initializer_stack = p;
constructor_decl = decl; constructor_decl = decl;
...@@ -5302,6 +5312,7 @@ really_start_incremental_init (type) ...@@ -5302,6 +5312,7 @@ really_start_incremental_init (type)
p->max_index = constructor_max_index; p->max_index = constructor_max_index;
p->unfilled_index = constructor_unfilled_index; p->unfilled_index = constructor_unfilled_index;
p->unfilled_fields = constructor_unfilled_fields; p->unfilled_fields = constructor_unfilled_fields;
p->bit_index = constructor_bit_index;
p->elements = 0; p->elements = 0;
p->constant = constructor_constant; p->constant = constructor_constant;
p->simple = constructor_simple; p->simple = constructor_simple;
...@@ -5326,6 +5337,7 @@ really_start_incremental_init (type) ...@@ -5326,6 +5337,7 @@ really_start_incremental_init (type)
{ {
constructor_fields = TYPE_FIELDS (constructor_type); constructor_fields = TYPE_FIELDS (constructor_type);
constructor_unfilled_fields = constructor_fields; constructor_unfilled_fields = constructor_fields;
constructor_bit_index = copy_node (integer_zero_node);
} }
else if (TREE_CODE (constructor_type) == ARRAY_TYPE) else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{ {
...@@ -5381,6 +5393,7 @@ push_init_level (implicit) ...@@ -5381,6 +5393,7 @@ push_init_level (implicit)
p->max_index = constructor_max_index; p->max_index = constructor_max_index;
p->unfilled_index = constructor_unfilled_index; p->unfilled_index = constructor_unfilled_index;
p->unfilled_fields = constructor_unfilled_fields; p->unfilled_fields = constructor_unfilled_fields;
p->bit_index = constructor_bit_index;
p->elements = constructor_elements; p->elements = constructor_elements;
p->constant = constructor_constant; p->constant = constructor_constant;
p->simple = constructor_simple; p->simple = constructor_simple;
...@@ -5419,6 +5432,7 @@ push_init_level (implicit) ...@@ -5419,6 +5432,7 @@ push_init_level (implicit)
{ {
constructor_fields = TYPE_FIELDS (constructor_type); constructor_fields = TYPE_FIELDS (constructor_type);
constructor_unfilled_fields = constructor_fields; constructor_unfilled_fields = constructor_fields;
constructor_bit_index = copy_node (integer_zero_node);
} }
else if (TREE_CODE (constructor_type) == ARRAY_TYPE) else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{ {
...@@ -5488,6 +5502,15 @@ pop_init_level (implicit) ...@@ -5488,6 +5502,15 @@ pop_init_level (implicit)
/* Now output all pending elements. */ /* Now output all pending elements. */
output_pending_init_elements (1); 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. */ /* Pad out the end of the structure. */
if (! constructor_incremental) if (! constructor_incremental)
...@@ -5515,17 +5538,9 @@ pop_init_level (implicit) ...@@ -5515,17 +5538,9 @@ pop_init_level (implicit)
if (TREE_CODE (constructor_type) == RECORD_TYPE if (TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == UNION_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. */ /* Find the offset of the end of that field. */
filled = size_binop (CEIL_DIV_EXPR, filled = size_binop (CEIL_DIV_EXPR,
size_binop (PLUS_EXPR, constructor_bit_index,
DECL_FIELD_BITPOS (tail),
DECL_SIZE (tail)),
size_int (BITS_PER_UNIT)); size_int (BITS_PER_UNIT));
} }
else if (TREE_CODE (constructor_type) == ARRAY_TYPE) else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
...@@ -5581,6 +5596,7 @@ pop_init_level (implicit) ...@@ -5581,6 +5596,7 @@ pop_init_level (implicit)
constructor_max_index = p->max_index; constructor_max_index = p->max_index;
constructor_unfilled_index = p->unfilled_index; constructor_unfilled_index = p->unfilled_index;
constructor_unfilled_fields = p->unfilled_fields; constructor_unfilled_fields = p->unfilled_fields;
constructor_bit_index = p->bit_index;
constructor_elements = p->elements; constructor_elements = p->elements;
constructor_constant = p->constant; constructor_constant = p->constant;
constructor_simple = p->simple; constructor_simple = p->simple;
...@@ -5622,7 +5638,11 @@ set_init_index (first, last) ...@@ -5622,7 +5638,11 @@ set_init_index (first, last)
if (last != 0 && tree_int_cst_lt (last, first)) if (last != 0 && tree_int_cst_lt (last, first))
error_init ("empty index range in initializer%s", " for `%s'", NULL); error_init ("empty index range in initializer%s", " for `%s'", NULL);
else 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) ...@@ -5651,7 +5671,11 @@ set_init_label (fieldname)
error ("field `%s' already initialized", error ("field `%s' already initialized",
IDENTIFIER_POINTER (fieldname)); IDENTIFIER_POINTER (fieldname));
else else
constructor_fields = tail; {
constructor_fields = tail;
if (pedantic)
pedwarn ("ANSI C forbids specifying structure member to initialize");
}
} }
/* "Output" the next constructor element. /* "Output" the next constructor element.
...@@ -5759,7 +5783,37 @@ output_init_element (value, type, field, pending) ...@@ -5759,7 +5783,37 @@ output_init_element (value, type, field, pending)
require_constant_elements), require_constant_elements),
constructor_elements); constructor_elements);
else 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. */ /* Advance the variable that indicates sequential elements output. */
...@@ -5924,6 +5978,9 @@ void ...@@ -5924,6 +5978,9 @@ void
process_init_element (value) process_init_element (value)
tree value; tree value;
{ {
tree orig_value = value;
int string_flag = value != 0 && TREE_CODE (value) == STRING_CST;
if (value != 0) if (value != 0)
value = default_conversion (value); value = default_conversion (value);
...@@ -5968,9 +6025,18 @@ process_init_element (value) ...@@ -5968,9 +6025,18 @@ process_init_element (value)
fieldtype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_fields)); fieldtype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_fields));
fieldcode = TREE_CODE (fieldtype); fieldcode = TREE_CODE (fieldtype);
if (value != 0 && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype /* Accept a string constant to initialize a subarray. */
&& (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE if (value != 0
|| fieldcode == UNION_TYPE)) && 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); push_init_level (1);
continue; continue;
...@@ -5983,10 +6049,20 @@ process_init_element (value) ...@@ -5983,10 +6049,20 @@ process_init_element (value)
RESTORE_SPELLING_DEPTH (constructor_depth); RESTORE_SPELLING_DEPTH (constructor_depth);
} }
else else
/* If we are doing the bookkeeping for an element that was /* Do the bookkeeping for an element that was
directly output as a constructor, directly output as a constructor. */
we must update constructor_unfilled_fields. */ {
constructor_unfilled_fields = TREE_CHAIN (constructor_fields); /* 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); constructor_fields = TREE_CHAIN (constructor_fields);
break; break;
...@@ -6006,9 +6082,18 @@ process_init_element (value) ...@@ -6006,9 +6082,18 @@ process_init_element (value)
fieldtype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_fields)); fieldtype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_fields));
fieldcode = TREE_CODE (fieldtype); fieldcode = TREE_CODE (fieldtype);
if (value != 0 && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype /* Accept a string constant to initialize a subarray. */
&& (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE if (value != 0
|| fieldcode == UNION_TYPE)) && 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); push_init_level (1);
continue; continue;
...@@ -6034,9 +6119,18 @@ process_init_element (value) ...@@ -6034,9 +6119,18 @@ process_init_element (value)
tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type)); tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
enum tree_code eltcode = TREE_CODE (elttype); enum tree_code eltcode = TREE_CODE (elttype);
if (value != 0 && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != elttype /* Accept a string constant to initialize a subarray. */
&& (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE if (value != 0
|| eltcode == UNION_TYPE)) && 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); push_init_level (1);
continue; continue;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment