+ /* We assume the union's size will be a multiple of a byte so we don't
+ bother with BITPOS. */
+ if (TREE_CODE (rli->t) == UNION_TYPE)
+ rli->offset = size_binop (MAX_EXPR, rli->offset, DECL_SIZE_UNIT (field));
+ else if (TREE_CODE (rli->t) == QUAL_UNION_TYPE)
+ rli->offset = fold (build (COND_EXPR, sizetype,
+ DECL_QUALIFIER (field),
+ DECL_SIZE_UNIT (field), rli->offset));
+}
+
+/* RLI contains information about the layout of a RECORD_TYPE. FIELD
+ is a FIELD_DECL to be added after those fields already present in
+ T. (FIELD is not actually added to the TYPE_FIELDS list here;
+ callers that desire that behavior must manually perform that step.) */
+
+void
+place_field (rli, field)
+ record_layout_info rli;
+ tree field;
+{
+ /* The alignment required for FIELD. */
+ unsigned int desired_align;
+ /* The alignment FIELD would have if we just dropped it into the
+ record as it presently stands. */
+ unsigned int known_align;
+ unsigned int actual_align;
+ /* The type of this field. */
+ tree type = TREE_TYPE (field);
+
+ /* If FIELD is static, then treat it like a separate variable, not
+ really like a structure field. If it is a FUNCTION_DECL, it's a
+ method. In both cases, all we do is lay out the decl, and we do
+ it *after* the record is laid out. */
+ if (TREE_CODE (field) == VAR_DECL)
+ {
+ rli->pending_statics = tree_cons (NULL_TREE, field,
+ rli->pending_statics);
+ return;
+ }
+
+ /* Enumerators and enum types which are local to this class need not
+ be laid out. Likewise for initialized constant fields. */
+ else if (TREE_CODE (field) != FIELD_DECL)
+ return;
+
+ /* Unions are laid out very differently than records, so split
+ that code off to another function. */
+ else if (TREE_CODE (rli->t) != RECORD_TYPE)
+ {
+ place_union_field (rli, field);
+ return;
+ }
+
+ /* Work out the known alignment so far. Note that A & (-A) is the
+ value of the least-significant bit in A that is one. */
+ if (! integer_zerop (rli->bitpos))
+ known_align = (tree_low_cst (rli->bitpos, 1)
+ & - tree_low_cst (rli->bitpos, 1));
+ else if (integer_zerop (rli->offset))
+ known_align = BIGGEST_ALIGNMENT;
+ else if (host_integerp (rli->offset, 1))
+ known_align = (BITS_PER_UNIT
+ * (tree_low_cst (rli->offset, 1)
+ & - tree_low_cst (rli->offset, 1)));
+ else
+ known_align = rli->offset_align;
+
+ /* Lay out the field so we know what alignment it needs. For a
+ packed field, use the alignment as specified, disregarding what
+ the type would want. */
+ desired_align = DECL_ALIGN (field);
+ layout_decl (field, known_align);
+ if (! DECL_PACKED (field))
+ desired_align = DECL_ALIGN (field);
+
+ /* Some targets (i.e. VMS) limit struct field alignment
+ to a lower boundary than alignment of variables. */
+#ifdef BIGGEST_FIELD_ALIGNMENT
+ desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT);
+#endif
+#ifdef ADJUST_FIELD_ALIGN
+ desired_align = ADJUST_FIELD_ALIGN (field, desired_align);
+#endif
+
+ /* Record must have at least as much alignment as any field.
+ Otherwise, the alignment of the field within the record is
+ meaningless. */
+#ifdef PCC_BITFIELD_TYPE_MATTERS
+ if (PCC_BITFIELD_TYPE_MATTERS && type != error_mark_node
+ && DECL_BIT_FIELD_TYPE (field)
+ && ! integer_zerop (TYPE_SIZE (type)))
+ {
+ /* For these machines, a zero-length field does not
+ affect the alignment of the structure as a whole.
+ It does, however, affect the alignment of the next field
+ within the structure. */
+ if (! integer_zerop (DECL_SIZE (field)))
+ rli->record_align = MAX (rli->record_align, desired_align);
+ else if (! DECL_PACKED (field))
+ desired_align = TYPE_ALIGN (type);
+
+ /* A named bit field of declared type `int'
+ forces the entire structure to have `int' alignment. */
+ if (DECL_NAME (field) != 0)