aboutsummaryrefslogtreecommitdiff
path: root/gcc/varasm.c
diff options
context:
space:
mode:
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>2000-08-30 02:00:55 +0000
committerRichard Kenner <kenner@gcc.gnu.org>2000-08-29 22:00:55 -0400
commit85f3d674d453d980199d404c188b217dcc6ee9c1 (patch)
tree93a77b8da110b5aa2e972ff4785ebafed42b4547 /gcc/varasm.c
parent5b67ad6f4566834f8c0ffb253769727307bf0a11 (diff)
downloadgcc-85f3d674d453d980199d404c188b217dcc6ee9c1.zip
gcc-85f3d674d453d980199d404c188b217dcc6ee9c1.tar.gz
gcc-85f3d674d453d980199d404c188b217dcc6ee9c1.tar.bz2
expr.c (store_constructor): Allow variable bounds of array type.
* expr.c (store_constructor): Allow variable bounds of array type. (expand_expr): Don't blow up if type is ERROR_MARK. * varasm.c (output_constructor): Don't access lower bound of array type unless need it if index is supplied (so it can be a variable if no index is supplied). Use tree_low_cst; use HOST_WIDE_INT for sizes; change BITPOS to POS. Other minor cleanups. From-SVN: r36060
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r--gcc/varasm.c89
1 files changed, 41 insertions, 48 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 5193dd6..478daf8 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -4361,11 +4361,12 @@ output_constructor (exp, size)
tree exp;
int size;
{
+ tree type = TREE_TYPE (exp);
register tree link, field = 0;
- HOST_WIDE_INT min_index = 0;
+ tree min_index = 0;
/* Number of bytes output or skipped so far.
In other words, current position within the constructor. */
- int total_bytes = 0;
+ HOST_WIDE_INT total_bytes = 0;
/* Non-zero means BYTE contains part of a byte, to be output. */
int byte_buffer_in_use = 0;
register int byte = 0;
@@ -4373,13 +4374,12 @@ output_constructor (exp, size)
if (HOST_BITS_PER_WIDE_INT < BITS_PER_UNIT)
abort ();
- if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
- field = TYPE_FIELDS (TREE_TYPE (exp));
+ if (TREE_CODE (type) == RECORD_TYPE)
+ field = TYPE_FIELDS (type);
- if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
- && TYPE_DOMAIN (TREE_TYPE (exp)) != 0)
- min_index
- = TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (exp))));
+ 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.
@@ -4398,17 +4398,14 @@ output_constructor (exp, size)
tree val = TREE_VALUE (link);
tree index = 0;
- /* the element in a union constructor specifies the proper field. */
+ /* 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)
+ && TREE_PURPOSE (link) != 0)
+ field = TREE_PURPOSE (link);
- if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
- || TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE)
- {
- /* if available, use the type given by link */
- if (TREE_PURPOSE (link) != 0)
- field = TREE_PURPOSE (link);
- }
-
- if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
+ else if (TREE_CODE (type) == ARRAY_TYPE)
index = TREE_PURPOSE (link);
/* Eliminate the marker that makes a cast not be an lvalue. */
@@ -4418,10 +4415,11 @@ output_constructor (exp, size)
if (index && TREE_CODE (index) == RANGE_EXPR)
{
register int fieldsize
- = int_size_in_bytes (TREE_TYPE (TREE_TYPE (exp)));
- HOST_WIDE_INT lo_index = TREE_INT_CST_LOW (TREE_OPERAND (index, 0));
- HOST_WIDE_INT hi_index = TREE_INT_CST_LOW (TREE_OPERAND (index, 1));
+ = 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;
+
for (index = lo_index; index <= hi_index; index++)
{
/* Output the element's initial value. */
@@ -4441,12 +4439,11 @@ output_constructor (exp, size)
register int fieldsize;
/* Since this structure is static,
we know the positions are constant. */
- HOST_WIDE_INT bitpos = field ? int_byte_position (field) : 0;
+ HOST_WIDE_INT pos = field ? int_byte_position (field) : 0;
if (index != 0)
- bitpos
- = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (val)), 1)
- * (tree_low_cst (index, 0) - min_index));
+ 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)
@@ -4459,31 +4456,24 @@ output_constructor (exp, size)
/* 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) && bitpos != total_bytes)
+ if ((field != 0 || index != 0) && pos != total_bytes)
{
- assemble_zeros (bitpos - total_bytes);
- total_bytes = bitpos;
+ assemble_zeros (pos - total_bytes);
+ total_bytes = pos;
}
- else if (field != 0 && DECL_PACKED (field))
- {
- /* Some assemblers automaticallly align a datum according to
- its size if no align directive is specified. The datum,
- however, may be declared with 'packed' attribute, so we
- have to disable such a feature. */
- ASM_OUTPUT_ALIGN (asm_out_file, 0);
- }
+ else if (field != 0 && DECL_PACKED (field))
+ /* Some assemblers automaticallly align a datum according to its
+ size if no align directive is specified. The datum, however,
+ may be declared with 'packed' attribute, so we have to disable
+ such a feature. */
+ ASM_OUTPUT_ALIGN (asm_out_file, 0);
/* Determine size this element should occupy. */
if (field)
- {
- if (TREE_CODE (DECL_SIZE_UNIT (field)) != INTEGER_CST)
- abort ();
-
- fieldsize = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
- }
+ fieldsize = tree_low_cst (DECL_SIZE_UNIT (field), 1);
else
- fieldsize = int_size_in_bytes (TREE_TYPE (TREE_TYPE (exp)));
+ fieldsize = int_size_in_bytes (TREE_TYPE (type));
/* Output the element's initial value. */
if (val == 0)
@@ -4544,8 +4534,8 @@ output_constructor (exp, size)
int this_time;
int shift;
HOST_WIDE_INT value;
- int next_byte = next_offset / BITS_PER_UNIT;
- int next_bit = next_offset % BITS_PER_UNIT;
+ 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. */
@@ -4566,6 +4556,7 @@ output_constructor (exp, size)
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
@@ -4579,9 +4570,7 @@ output_constructor (exp, size)
/* Now get the bits from the appropriate constant word. */
if (shift < HOST_BITS_PER_WIDE_INT)
- {
- value = TREE_INT_CST_LOW (val);
- }
+ value = TREE_INT_CST_LOW (val);
else if (shift < 2 * HOST_BITS_PER_WIDE_INT)
{
value = TREE_INT_CST_HIGH (val);
@@ -4589,6 +4578,7 @@ output_constructor (exp, size)
}
else
abort ();
+
/* Get the result. This works only when:
1 <= this_time <= HOST_BITS_PER_WIDE_INT. */
byte |= (((value >> shift)
@@ -4628,16 +4618,19 @@ output_constructor (exp, size)
& (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))
<< next_bit);
}
+
next_offset += this_time;
byte_buffer_in_use = 1;
}
}
}
+
if (byte_buffer_in_use)
{
ASM_OUTPUT_BYTE (asm_out_file, byte);
total_bytes++;
}
+
if (total_bytes < size)
assemble_zeros (size - total_bytes);
}