[PATCH] support static nested constructors in bitfields (1/2)
Olivier Hainque
hainque@adacore.com
Mon Apr 27 10:36:00 GMT 2009
Hello,
This is a resubmission of a patch first suggested at
http://gcc.gnu.org/ml/gcc-patches/2008-07/msg01802.html
The patch still applies. Just re-tested on x86_64-suse-linux, no new
regression. I'll be posting the followup part with tests etc shortly.
Thanks in advance,
Olivier
2009-04-27 Olivier Hainque <hainque@adacore.com>
* varasm.c (oc_local_state): New structure, output_constructor
local state to support communication with helpers.
(output_constructor_array_range): New output_constructor helper,
extracted code for an array range element.
(output_constructor_regular_field): New output_constructor helper,
extracted code for an element that is not a bitfield.
(output_constructor_bitfield): New output_constructor helper,
extracted code for a bitfield element.
(output_constructor): Rework to use helpers.
-------------- next part --------------
*** gcc/varasm.c.ori Tue Jun 10 17:59:09 2008
--- gcc/varasm.c Tue Jun 10 18:00:49 2008
*************** array_size_for_constructor (tree val)
*** 4550,4555 ****
--- 4550,4837 ----
return tree_low_cst (i, 1);
}
+ /* Datastructures and helpers for output_constructor. */
+
+ /* Local output_constructor state to support interaction with helpers. */
+
+ typedef struct {
+
+ /* Received arguments. */
+ tree exp; /* constructor expression. */
+ unsigned HOST_WIDE_INT size; /* # bytes to output - pad if necessary. */
+ unsigned int align; /* known initial alignment. */
+
+ /* Constructor expression data. */
+ tree type; /* expression type. */
+ tree field; /* current field decl in a record. */
+ tree min_index; /* lower bound if specified for an array. */
+
+ /* Output processing state per se. */
+ HOST_WIDE_INT total_bytes; /* # bytes output so far / current position. */
+ int byte_buffer_in_use; /* whether byte ... */
+ int byte; /* ... contains part of a bitfield byte yet to
+ be output. */
+
+ /* Current element. */
+ tree val; /* current element value. */
+ tree index; /* current element index. */
+
+ } oc_local_state;
+
+ static void output_constructor_array_range (oc_local_state *);
+ static void output_constructor_regular_field (oc_local_state *);
+ static void output_constructor_bitfield (oc_local_state *);
+
+ /* Helper for output_constructor. Output a RANGE_EXPR element. */
+
+ static void
+ output_constructor_array_range (oc_local_state *local)
+ {
+ unsigned HOST_WIDE_INT fieldsize
+ = int_size_in_bytes (TREE_TYPE (local->type));
+
+ HOST_WIDE_INT lo_index
+ = tree_low_cst (TREE_OPERAND (local->index, 0), 0);
+ HOST_WIDE_INT hi_index
+ = tree_low_cst (TREE_OPERAND (local->index, 1), 0);
+ HOST_WIDE_INT index;
+
+ unsigned int align2
+ = min_align (local->align, fieldsize * BITS_PER_UNIT);
+
+ for (index = lo_index; index <= hi_index; index++)
+ {
+ /* Output the element's initial value. */
+ if (local->val == 0)
+ assemble_zeros (fieldsize);
+ else
+ output_constant (local->val, fieldsize, align2);
+
+ /* Count its size. */
+ local->total_bytes += fieldsize;
+ }
+ }
+
+ /* Helper for output_constructor. Output a field element that is not
+ bitfield. */
+
+ static void
+ output_constructor_regular_field (oc_local_state *local)
+ {
+ /* Field size and position. Since this structure is static, we know the
+ positions are constant. */
+ unsigned HOST_WIDE_INT fieldsize;
+ HOST_WIDE_INT pos = local->field ? int_byte_position (local->field) : 0;
+
+ unsigned int align2;
+
+ if (local->index != 0)
+ pos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (local->val)), 1)
+ * ((tree_low_cst (local->index, 0)
+ - tree_low_cst (local->min_index, 0))));
+
+ /* Output any buffered-up bit-fields preceding this element. */
+ if (local->byte_buffer_in_use)
+ {
+ assemble_integer (GEN_INT (local->byte), 1, BITS_PER_UNIT, 1);
+ local->total_bytes++;
+ local->byte_buffer_in_use = 0;
+ }
+
+ /* Advance to offset of this element.
+ Note no alignment needed in an array, since that is guaranteed
+ if each element has the proper size. */
+ if ((local->field != 0 || local->index != 0) && pos != local->total_bytes)
+ {
+ gcc_assert (pos >= local->total_bytes);
+ assemble_zeros (pos - local->total_bytes);
+ local->total_bytes = pos;
+ }
+
+ /* Find the alignment of this element. */
+ align2 = min_align (local->align, BITS_PER_UNIT * pos);
+
+ /* Determine size this element should occupy. */
+ if (local->field)
+ {
+ fieldsize = 0;
+
+ /* If this is an array with an unspecified upper bound,
+ the initializer determines the size. */
+ /* ??? This ought to only checked if DECL_SIZE_UNIT is NULL,
+ but we cannot do this until the deprecated support for
+ initializing zero-length array members is removed. */
+ if (TREE_CODE (TREE_TYPE (local->field)) == ARRAY_TYPE
+ && TYPE_DOMAIN (TREE_TYPE (local->field))
+ && ! TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (local->field))))
+ {
+ fieldsize = array_size_for_constructor (local->val);
+ /* Given a non-empty initialization, this field had
+ better be last. */
+ gcc_assert (!fieldsize || !TREE_CHAIN (local->field));
+ }
+ else if (DECL_SIZE_UNIT (local->field))
+ {
+ /* ??? This can't be right. If the decl size overflows
+ a host integer we will silently emit no data. */
+ if (host_integerp (DECL_SIZE_UNIT (local->field), 1))
+ fieldsize = tree_low_cst (DECL_SIZE_UNIT (local->field), 1);
+ }
+ }
+ else
+ fieldsize = int_size_in_bytes (TREE_TYPE (local->type));
+
+ /* Output the element's initial value. */
+ if (local->val == 0)
+ assemble_zeros (fieldsize);
+ else
+ output_constant (local->val, fieldsize, align2);
+
+ /* Count its size. */
+ local->total_bytes += fieldsize;
+ }
+
+ /* Helper for output_constructor. Output a bitfield element. */
+
+ static void
+ output_constructor_bitfield (oc_local_state *local)
+ {
+ /* Offset in bits from the beginning of the structure to the next bit of
+ this element to be processed. */
+ HOST_WIDE_INT next_offset = int_bit_position (local->field);
+
+ /* Offset of the first bit past the end of this element. */
+ HOST_WIDE_INT end_offset
+ = (next_offset + tree_low_cst (DECL_SIZE (local->field), 1));
+
+ if (local->val != 0 && TREE_CODE (local->val) != INTEGER_CST)
+ error ("invalid initial value for member %qs",
+ IDENTIFIER_POINTER (DECL_NAME (local->field)));
+
+ if (local->val == 0)
+ local->val = integer_zero_node;
+
+ /* If this field does not start in this (or, next) byte,
+ skip some bytes. */
+ if (next_offset / BITS_PER_UNIT != local->total_bytes)
+ {
+ /* Output remnant of any bit field in previous bytes. */
+ if (local->byte_buffer_in_use)
+ {
+ assemble_integer (GEN_INT (local->byte), 1, BITS_PER_UNIT, 1);
+ local->total_bytes++;
+ local->byte_buffer_in_use = 0;
+ }
+
+ /* If still not at proper byte, advance to there. */
+ if (next_offset / BITS_PER_UNIT != local->total_bytes)
+ {
+ gcc_assert (next_offset / BITS_PER_UNIT >= local->total_bytes);
+ assemble_zeros (next_offset / BITS_PER_UNIT - local->total_bytes);
+ local->total_bytes = next_offset / BITS_PER_UNIT;
+ }
+ }
+
+ if (! local->byte_buffer_in_use)
+ local->byte = 0;
+
+ /* We must split the element into pieces that fall within
+ separate bytes, and combine each byte with previous or
+ following bit-fields. */
+
+ while (next_offset < end_offset)
+ {
+ int this_time;
+ int shift;
+ HOST_WIDE_INT value;
+ HOST_WIDE_INT next_byte = next_offset / BITS_PER_UNIT;
+ HOST_WIDE_INT next_bit = next_offset % BITS_PER_UNIT;
+
+ /* Advance from byte to byte
+ within this element when necessary. */
+ while (next_byte != local->total_bytes)
+ {
+ assemble_integer (GEN_INT (local->byte), 1, BITS_PER_UNIT, 1);
+ local->total_bytes++;
+ local->byte = 0;
+ }
+
+ /* Number of bits we can process at once
+ (all part of the same byte). */
+ this_time = MIN (end_offset - next_offset,
+ BITS_PER_UNIT - next_bit);
+ if (BYTES_BIG_ENDIAN)
+ {
+ /* On big-endian machine, take the most significant bits
+ first (of the bits that are significant)
+ and put them into bytes from the most significant end. */
+ shift = end_offset - next_offset - this_time;
+
+ /* Don't try to take a bunch of bits that cross
+ the word boundary in the INTEGER_CST. We can
+ only select bits from the LOW or HIGH part
+ not from both. */
+ if (shift < HOST_BITS_PER_WIDE_INT
+ && shift + this_time > HOST_BITS_PER_WIDE_INT)
+ {
+ this_time = shift + this_time - HOST_BITS_PER_WIDE_INT;
+ shift = HOST_BITS_PER_WIDE_INT;
+ }
+
+ /* Now get the bits from the appropriate constant word. */
+ if (shift < HOST_BITS_PER_WIDE_INT)
+ value = TREE_INT_CST_LOW (local->val);
+ else
+ {
+ gcc_assert (shift < 2 * HOST_BITS_PER_WIDE_INT);
+ value = TREE_INT_CST_HIGH (local->val);
+ shift -= HOST_BITS_PER_WIDE_INT;
+ }
+
+ /* Get the result. This works only when:
+ 1 <= this_time <= HOST_BITS_PER_WIDE_INT. */
+ local->byte |= (((value >> shift)
+ & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))
+ << (BITS_PER_UNIT - this_time - next_bit));
+ }
+ else
+ {
+ /* On little-endian machines,
+ take first the least significant bits of the value
+ and pack them starting at the least significant
+ bits of the bytes. */
+ shift = next_offset - int_bit_position (local->field);
+
+ /* Don't try to take a bunch of bits that cross
+ the word boundary in the INTEGER_CST. We can
+ only select bits from the LOW or HIGH part
+ not from both. */
+ if (shift < HOST_BITS_PER_WIDE_INT
+ && shift + this_time > HOST_BITS_PER_WIDE_INT)
+ this_time = (HOST_BITS_PER_WIDE_INT - shift);
+
+ /* Now get the bits from the appropriate constant word. */
+ if (shift < HOST_BITS_PER_WIDE_INT)
+ value = TREE_INT_CST_LOW (local->val);
+ else
+ {
+ gcc_assert (shift < 2 * HOST_BITS_PER_WIDE_INT);
+ value = TREE_INT_CST_HIGH (local->val);
+ shift -= HOST_BITS_PER_WIDE_INT;
+ }
+
+ /* Get the result. This works only when:
+ 1 <= this_time <= HOST_BITS_PER_WIDE_INT. */
+ local->byte |= (((value >> shift)
+ & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))
+ << next_bit);
+ }
+
+ next_offset += this_time;
+ local->byte_buffer_in_use = 1;
+ }
+ }
+
/* Subroutine of output_constant, used for CONSTRUCTORs (aggregate constants).
Generate at least SIZE bytes, padding if necessary. */
*************** static void
*** 4557,4865 ****
output_constructor (tree exp, unsigned HOST_WIDE_INT size,
unsigned int align)
{
- tree type = TREE_TYPE (exp);
- tree field = 0;
- tree min_index = 0;
- /* Number of bytes output or skipped so far.
- In other words, current position within the constructor. */
- HOST_WIDE_INT total_bytes = 0;
- /* Nonzero means BYTE contains part of a byte, to be output. */
- int byte_buffer_in_use = 0;
- int byte = 0;
unsigned HOST_WIDE_INT cnt;
constructor_elt *ce;
! gcc_assert (HOST_BITS_PER_WIDE_INT >= BITS_PER_UNIT);
! if (TREE_CODE (type) == RECORD_TYPE)
! field = TYPE_FIELDS (type);
! if (TREE_CODE (type) == ARRAY_TYPE
! && TYPE_DOMAIN (type) != 0)
! min_index = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
!
! /* As LINK goes through the elements of the constant,
! FIELD goes through the structure fields, if the constant is a structure.
! if the constant is a union, then we override this,
! by getting the field from the TREE_LIST element.
But the constant could also be an array. Then FIELD is zero.
There is always a maximum of one element in the chain LINK for unions
(even if the initializer in a source program incorrectly contains
more one). */
for (cnt = 0;
VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (exp), cnt, ce);
! cnt++, field = field ? TREE_CHAIN (field) : 0)
{
! tree val = ce->value;
! tree index = 0;
/* The element in a union constructor specifies the proper field
or index. */
! if ((TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
! || TREE_CODE (type) == QUAL_UNION_TYPE)
&& ce->index != 0)
! field = ce->index;
! else if (TREE_CODE (type) == ARRAY_TYPE)
! index = ce->index;
#ifdef ASM_COMMENT_START
! if (field && flag_verbose_asm)
fprintf (asm_out_file, "%s %s:\n",
ASM_COMMENT_START,
! DECL_NAME (field)
! ? IDENTIFIER_POINTER (DECL_NAME (field))
: "<anonymous>");
#endif
/* Eliminate the marker that makes a cast not be an lvalue. */
! if (val != 0)
! STRIP_NOPS (val);
! if (index && TREE_CODE (index) == RANGE_EXPR)
! {
! unsigned HOST_WIDE_INT fieldsize
! = int_size_in_bytes (TREE_TYPE (type));
! HOST_WIDE_INT lo_index = tree_low_cst (TREE_OPERAND (index, 0), 0);
! HOST_WIDE_INT hi_index = tree_low_cst (TREE_OPERAND (index, 1), 0);
! HOST_WIDE_INT index;
! unsigned int align2 = min_align (align, fieldsize * BITS_PER_UNIT);
!
! for (index = lo_index; index <= hi_index; index++)
! {
! /* Output the element's initial value. */
! if (val == 0)
! assemble_zeros (fieldsize);
! else
! output_constant (val, fieldsize, align2);
!
! /* Count its size. */
! total_bytes += fieldsize;
! }
! }
! else if (field == 0 || !DECL_BIT_FIELD (field))
! {
! /* An element that is not a bit-field. */
!
! unsigned HOST_WIDE_INT fieldsize;
! /* Since this structure is static,
! we know the positions are constant. */
! HOST_WIDE_INT pos = field ? int_byte_position (field) : 0;
! unsigned int align2;
!
! if (index != 0)
! pos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (val)), 1)
! * (tree_low_cst (index, 0) - tree_low_cst (min_index, 0)));
!
! /* Output any buffered-up bit-fields preceding this element. */
! if (byte_buffer_in_use)
! {
! assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
! total_bytes++;
! byte_buffer_in_use = 0;
! }
!
! /* Advance to offset of this element.
! Note no alignment needed in an array, since that is guaranteed
! if each element has the proper size. */
! if ((field != 0 || index != 0) && pos != total_bytes)
! {
! gcc_assert (pos >= total_bytes);
! assemble_zeros (pos - total_bytes);
! total_bytes = pos;
! }
!
! /* Find the alignment of this element. */
! align2 = min_align (align, BITS_PER_UNIT * pos);
! /* Determine size this element should occupy. */
! if (field)
! {
! fieldsize = 0;
!
! /* If this is an array with an unspecified upper bound,
! the initializer determines the size. */
! /* ??? This ought to only checked if DECL_SIZE_UNIT is NULL,
! but we cannot do this until the deprecated support for
! initializing zero-length array members is removed. */
! if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
! && TYPE_DOMAIN (TREE_TYPE (field))
! && ! TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (field))))
! {
! fieldsize = array_size_for_constructor (val);
! /* Given a non-empty initialization, this field had
! better be last. */
! gcc_assert (!fieldsize || !TREE_CHAIN (field));
! }
! else if (DECL_SIZE_UNIT (field))
! {
! /* ??? This can't be right. If the decl size overflows
! a host integer we will silently emit no data. */
! if (host_integerp (DECL_SIZE_UNIT (field), 1))
! fieldsize = tree_low_cst (DECL_SIZE_UNIT (field), 1);
! }
! }
! else
! fieldsize = int_size_in_bytes (TREE_TYPE (type));
! /* Output the element's initial value. */
! if (val == 0)
! assemble_zeros (fieldsize);
! else
! output_constant (val, fieldsize, align2);
! /* Count its size. */
! total_bytes += fieldsize;
! }
! else if (val != 0 && TREE_CODE (val) != INTEGER_CST)
! error ("invalid initial value for member %qs",
! IDENTIFIER_POINTER (DECL_NAME (field)));
else
! {
! /* Element that is a bit-field. */
!
! HOST_WIDE_INT next_offset = int_bit_position (field);
! HOST_WIDE_INT end_offset
! = (next_offset + tree_low_cst (DECL_SIZE (field), 1));
!
! if (val == 0)
! val = integer_zero_node;
!
! /* If this field does not start in this (or, next) byte,
! skip some bytes. */
! if (next_offset / BITS_PER_UNIT != total_bytes)
! {
! /* Output remnant of any bit field in previous bytes. */
! if (byte_buffer_in_use)
! {
! assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
! total_bytes++;
! byte_buffer_in_use = 0;
! }
!
! /* If still not at proper byte, advance to there. */
! if (next_offset / BITS_PER_UNIT != total_bytes)
! {
! gcc_assert (next_offset / BITS_PER_UNIT >= total_bytes);
! assemble_zeros (next_offset / BITS_PER_UNIT - total_bytes);
! total_bytes = next_offset / BITS_PER_UNIT;
! }
! }
!
! if (! byte_buffer_in_use)
! byte = 0;
!
! /* We must split the element into pieces that fall within
! separate bytes, and combine each byte with previous or
! following bit-fields. */
!
! /* next_offset is the offset n fbits from the beginning of
! the structure to the next bit of this element to be processed.
! end_offset is the offset of the first bit past the end of
! this element. */
! while (next_offset < end_offset)
! {
! int this_time;
! int shift;
! HOST_WIDE_INT value;
! HOST_WIDE_INT next_byte = next_offset / BITS_PER_UNIT;
! HOST_WIDE_INT next_bit = next_offset % BITS_PER_UNIT;
!
! /* Advance from byte to byte
! within this element when necessary. */
! while (next_byte != total_bytes)
! {
! assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
! total_bytes++;
! byte = 0;
! }
!
! /* Number of bits we can process at once
! (all part of the same byte). */
! this_time = MIN (end_offset - next_offset,
! BITS_PER_UNIT - next_bit);
! if (BYTES_BIG_ENDIAN)
! {
! /* On big-endian machine, take the most significant bits
! first (of the bits that are significant)
! and put them into bytes from the most significant end. */
! shift = end_offset - next_offset - this_time;
!
! /* Don't try to take a bunch of bits that cross
! the word boundary in the INTEGER_CST. We can
! only select bits from the LOW or HIGH part
! not from both. */
! if (shift < HOST_BITS_PER_WIDE_INT
! && shift + this_time > HOST_BITS_PER_WIDE_INT)
! {
! this_time = shift + this_time - HOST_BITS_PER_WIDE_INT;
! shift = HOST_BITS_PER_WIDE_INT;
! }
!
! /* Now get the bits from the appropriate constant word. */
! if (shift < HOST_BITS_PER_WIDE_INT)
! value = TREE_INT_CST_LOW (val);
! else
! {
! gcc_assert (shift < 2 * HOST_BITS_PER_WIDE_INT);
! value = TREE_INT_CST_HIGH (val);
! shift -= HOST_BITS_PER_WIDE_INT;
! }
!
! /* Get the result. This works only when:
! 1 <= this_time <= HOST_BITS_PER_WIDE_INT. */
! byte |= (((value >> shift)
! & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))
! << (BITS_PER_UNIT - this_time - next_bit));
! }
! else
! {
! /* On little-endian machines,
! take first the least significant bits of the value
! and pack them starting at the least significant
! bits of the bytes. */
! shift = next_offset - int_bit_position (field);
!
! /* Don't try to take a bunch of bits that cross
! the word boundary in the INTEGER_CST. We can
! only select bits from the LOW or HIGH part
! not from both. */
! if (shift < HOST_BITS_PER_WIDE_INT
! && shift + this_time > HOST_BITS_PER_WIDE_INT)
! this_time = (HOST_BITS_PER_WIDE_INT - shift);
!
! /* Now get the bits from the appropriate constant word. */
! if (shift < HOST_BITS_PER_WIDE_INT)
! value = TREE_INT_CST_LOW (val);
! else
! {
! gcc_assert (shift < 2 * HOST_BITS_PER_WIDE_INT);
! value = TREE_INT_CST_HIGH (val);
! shift -= HOST_BITS_PER_WIDE_INT;
! }
!
! /* Get the result. This works only when:
! 1 <= this_time <= HOST_BITS_PER_WIDE_INT. */
! byte |= (((value >> shift)
! & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))
! << next_bit);
! }
!
! next_offset += this_time;
! byte_buffer_in_use = 1;
! }
! }
}
! if (byte_buffer_in_use)
{
! assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
! total_bytes++;
}
! if ((unsigned HOST_WIDE_INT)total_bytes < size)
! assemble_zeros (size - total_bytes);
}
/* This TREE_LIST contains any weak symbol declarations waiting
--- 4839,4934 ----
output_constructor (tree exp, unsigned HOST_WIDE_INT size,
unsigned int align)
{
unsigned HOST_WIDE_INT cnt;
constructor_elt *ce;
! oc_local_state local;
! /* Setup our local state to communicate with helpers. */
! local.exp = exp;
! local.size = size;
! local.align = align;
!
! local.total_bytes = 0;
! local.byte_buffer_in_use = 0;
! local.byte = 0;
!
! local.type = TREE_TYPE (exp);
!
! local.min_index = 0;
! if (TREE_CODE (local.type) == ARRAY_TYPE
! && TYPE_DOMAIN (local.type) != 0)
! local.min_index = TYPE_MIN_VALUE (TYPE_DOMAIN (local.type));
!
! gcc_assert (HOST_BITS_PER_WIDE_INT >= BITS_PER_UNIT);
! /* As CE goes through the elements of the constant, FIELD goes through the
! structure fields if the constant is a structure. If the constant is a
! union, we override this by getting the field from the TREE_LIST element.
But the constant could also be an array. Then FIELD is zero.
There is always a maximum of one element in the chain LINK for unions
(even if the initializer in a source program incorrectly contains
more one). */
+
+ local.field = 0;
+ if (TREE_CODE (local.type) == RECORD_TYPE)
+ local.field = TYPE_FIELDS (local.type);
+
for (cnt = 0;
VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (exp), cnt, ce);
! cnt++, local.field = local.field ? TREE_CHAIN (local.field) : 0)
{
! local.val = ce->value;
! local.index = 0;
/* The element in a union constructor specifies the proper field
or index. */
! if ((TREE_CODE (local.type) == RECORD_TYPE
! || TREE_CODE (local.type) == UNION_TYPE
! || TREE_CODE (local.type) == QUAL_UNION_TYPE)
&& ce->index != 0)
! local.field = ce->index;
! else if (TREE_CODE (local.type) == ARRAY_TYPE)
! local.index = ce->index;
#ifdef ASM_COMMENT_START
! if (local.field && flag_verbose_asm)
fprintf (asm_out_file, "%s %s:\n",
ASM_COMMENT_START,
! DECL_NAME (local.field)
! ? IDENTIFIER_POINTER (DECL_NAME (local.field))
: "<anonymous>");
#endif
/* Eliminate the marker that makes a cast not be an lvalue. */
! if (local.val != 0)
! STRIP_NOPS (local.val);
! /* Output the current element, using the appropriate helper ... */
! /* For an array slice. */
! if (local.index && TREE_CODE (local.index) == RANGE_EXPR)
! output_constructor_array_range (&local);
! /* For a field that is not a bitfield. */
! else if (local.field == 0 || !DECL_BIT_FIELD (local.field))
! output_constructor_regular_field (&local);
! /* For a bitfield. */
else
! output_constructor_bitfield (&local);
}
! if (local.byte_buffer_in_use)
{
! assemble_integer (GEN_INT (local.byte), 1, BITS_PER_UNIT, 1);
! local.total_bytes++;
}
! if ((unsigned HOST_WIDE_INT)local.total_bytes < size)
! assemble_zeros (size - local.total_bytes);
}
/* This TREE_LIST contains any weak symbol declarations waiting
More information about the Gcc-patches
mailing list