From e0cea8d93a0760335c5c5fa8269bb3633196c227 Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Sat, 2 Jun 2001 11:14:06 +0000 Subject: [PATCH] tree.h (struct record_layout_info_s): New field unpadded_align. * tree.h (struct record_layout_info_s): New field unpadded_align. (set_lang_adjust_rli): New declaration. * stor-layout.c (layout_decl): If DECL is packed, but at alignment it would have if not packed, do not downgrade DECL_ALIGN. (lang_adjust_rli, set_lang_adjust_rli): New. (start_record_layout): Initialize new field unpadded_align. (debug_rli): Display it. (place_union_field, place_field): Set it. (layout_type, case RECORD_TYPE): Call via lang_adjust_rli if set. From-SVN: r42796 --- gcc/ChangeLog | 10 ++++++++++ gcc/stor-layout.c | 38 ++++++++++++++++++++++++++++++-------- gcc/tree.h | 5 +++++ 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 77305ee612f..fad7c99c1d3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ Sat Jun 2 06:53:50 2001 Richard Kenner + * tree.h (struct record_layout_info_s): New field unpadded_align. + (set_lang_adjust_rli): New declaration. + * stor-layout.c (layout_decl): If DECL is packed, but at alignment + it would have if not packed, do not downgrade DECL_ALIGN. + (lang_adjust_rli, set_lang_adjust_rli): New. + (start_record_layout): Initialize new field unpadded_align. + (debug_rli): Display it. + (place_union_field, place_field): Set it. + (layout_type, case RECORD_TYPE): Call via lang_adjust_rli if set. + * print-tree.c (print_node): Don't print "regdecl" when bit doesn't mean that; use proper names instead. Print DECL_NO_STATIC_CHAIN. diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index a278eb11e54..52e23cb4c87 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -381,7 +381,7 @@ layout_decl (decl, known_align) DECL_BIT_FIELD_TYPE (decl) = DECL_BIT_FIELD (decl) ? type : 0; if (maximum_field_alignment != 0) DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment); - else if (DECL_PACKED (decl)) + else if (DECL_PACKED (decl) && known_align % DECL_ALIGN (decl) != 0) { DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT); DECL_USER_ALIGN (decl) = 0; @@ -444,6 +444,18 @@ layout_decl (decl, known_align) } } +/* Hook for a front-end function that can modify the record layout as needed + immediately before it is finalized. */ + +void (*lang_adjust_rli) PARAMS ((record_layout_info)) = 0; + +void +set_lang_adjust_rli (f) + void (*f) PARAMS ((record_layout_info)); +{ + lang_adjust_rli = f; +} + /* Begin laying out type T, which may be a RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE. Return a pointer to a struct record_layout_info which is to be passed to all other layout functions for this record. It is the @@ -464,7 +476,7 @@ start_record_layout (t) declaration, for example) use it -- otherwise, start with a one-byte alignment. */ rli->record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (t)); - rli->unpacked_align = rli->record_align; + rli->unpacked_align = rli->unpadded_align = rli->record_align; rli->offset_align = MAX (rli->record_align, BIGGEST_ALIGNMENT); #ifdef STRUCTURE_SIZE_BOUNDARY @@ -571,8 +583,9 @@ debug_rli (rli) print_node_brief (stderr, "\noffset", rli->offset, 0); print_node_brief (stderr, " bitpos", rli->bitpos, 0); - fprintf (stderr, "\nrec_align = %u, unpack_align = %u, off_align = %u\n", - rli->record_align, rli->unpacked_align, rli->offset_align); + fprintf (stderr, "\naligns: rec = %u, unpack = %u, unpad = %u, off = %u\n", + rli->record_align, rli->unpacked_align, rli->unpadded_align, + rli->offset_align); if (rli->packed_maybe_necessary) fprintf (stderr, "packed may be necessary\n"); @@ -639,13 +652,18 @@ place_union_field (rli, field) /* Union must be at least as aligned as any field requires. */ rli->record_align = MAX (rli->record_align, desired_align); + rli->unpadded_align = MAX (rli->unpadded_align, desired_align); #ifdef PCC_BITFIELD_TYPE_MATTERS /* On the m88000, a bit field of declare type `int' forces the entire union to have `int' alignment. */ if (PCC_BITFIELD_TYPE_MATTERS && DECL_BIT_FIELD_TYPE (field)) - rli->record_align = MAX (rli->record_align, - TYPE_ALIGN (TREE_TYPE (field))); + { + rli->record_align = MAX (rli->record_align, + TYPE_ALIGN (TREE_TYPE (field))); + rli->unpadded_align = MAX (rli->unpadded_align, + TYPE_ALIGN (TREE_TYPE (field))); + } #endif /* We assume the union's size will be a multiple of a byte so we don't @@ -773,9 +791,9 @@ place_field (rli, field) type_align = MIN (type_align, BITS_PER_UNIT); rli->record_align = MAX (rli->record_align, type_align); + rli->unpadded_align = MAX (rli->unpadded_align, DECL_ALIGN (field)); if (warn_packed) - rli->unpacked_align = MAX (rli->unpacked_align, - TYPE_ALIGN (type)); + rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type)); } } else @@ -783,6 +801,7 @@ place_field (rli, field) { rli->record_align = MAX (rli->record_align, desired_align); rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type)); + rli->unpadded_align = MAX (rli->unpadded_align, DECL_ALIGN (field)); } if (warn_packed && DECL_PACKED (field)) @@ -1498,6 +1517,9 @@ layout_type (type) if (TREE_CODE (type) == QUAL_UNION_TYPE) TYPE_FIELDS (type) = nreverse (TYPE_FIELDS (type)); + if (lang_adjust_rli) + (*lang_adjust_rli) (rli); + /* Finish laying out the record. */ finish_record_layout (rli); } diff --git a/gcc/tree.h b/gcc/tree.h index 6821b06b452..af784ad4263 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2118,12 +2118,17 @@ typedef struct record_layout_info_s unsigned int record_align; /* The alignment of the record so far, not including padding, in bits. */ unsigned int unpacked_align; + /* The alignment of the record so far, allowing for the record to be + padded only at the end, in bits. */ + unsigned int unpadded_align; /* The static variables (i.e., class variables, as opposed to instance variables) encountered in T. */ tree pending_statics; int packed_maybe_necessary; } *record_layout_info; +extern void set_lang_adjust_rli PARAMS ((void (*) PARAMS + ((record_layout_info)))); extern record_layout_info start_record_layout PARAMS ((tree)); extern tree bit_from_pos PARAMS ((tree, tree)); extern tree byte_from_pos PARAMS ((tree, tree));