diff options
Diffstat (limited to 'gcc/stor-layout.c')
-rw-r--r-- | gcc/stor-layout.c | 81 |
1 files changed, 77 insertions, 4 deletions
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 95e7988c678..43904839213 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -80,6 +80,15 @@ int immediate_size_expand; /* Show that REFERENCE_TYPES are internal and should be Pmode. Called only by front end. */ +/* APPLE LOCAL begin Macintosh alignment 2002-5-24 ff */ +/* Keep track of whether we are laying out the first declared member + of a C++ class. We need this flag to handle the case of classes + with v-tables where the test to see if the offset in the record + is zero is not sufficient to determine if we are dealing with the + first declared member. */ +int darwin_align_is_first_member_of_class = 0; +/* APPLE LOCAL end Macintosh alignment 2002-5-24 ff */ + void internal_reference_types (void) { @@ -459,6 +468,12 @@ layout_decl (tree decl, unsigned int known_align) || DECL_SIZE_UNIT (decl) == 0 || TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST)) DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT); +/* APPLE LOCAL begin Macintosh alignment 2002-2-12 ff */ +#ifdef PEG_ALIGN_FOR_MAC68K + else if (TARGET_ALIGN_MAC68K) + DECL_ALIGN (decl) = PEG_ALIGN_FOR_MAC68K (DECL_ALIGN (decl)); +#endif +/* APPLE LOCAL end Macintosh alignment 2002-2-12 ff */ /* Should this be controlled by DECL_USER_ALIGN, too? */ if (maximum_field_alignment != 0) @@ -473,7 +488,10 @@ layout_decl (tree decl, unsigned int known_align) = MIN (DECL_ALIGN (decl), (unsigned) BIGGEST_FIELD_ALIGNMENT); #endif #ifdef ADJUST_FIELD_ALIGN - DECL_ALIGN (decl) = ADJUST_FIELD_ALIGN (decl, DECL_ALIGN (decl)); + /* APPLE LOCAL begin Macintosh alignment 2002-5-24 ff */ + DECL_ALIGN (decl) = ADJUST_FIELD_ALIGN (decl, DECL_ALIGN (decl), + known_align == 0); + /* APPLE LOCAL end Macintosh alignment 2002-5-24 ff */ #endif } } @@ -690,6 +708,19 @@ update_alignment_for_field (record_layout_info rli, tree field, && DECL_BIT_FIELD_TYPE (field) && ! integer_zerop (TYPE_SIZE (type))); +#ifdef ADJUST_FIELD_ALIGN + if (! user_align) + /* APPLE LOCAL begin Macintosh alignment 2002-5-24 ff */ + /* The third argument to ADJUST_FIELD_ALIGN indicates whether + we are dealing with the first field of the structure. */ + desired_align = + ADJUST_FIELD_ALIGN (field, desired_align, + (darwin_align_is_first_member_of_class + || (integer_zerop (rli->offset) + && integer_zerop (rli->bitpos)))); + /* APPLE LOCAL end Macintosh alignment 2002-5-24 ff */ +#endif + /* Record must have at least as much alignment as any field. Otherwise, the alignment of the field within the record is meaningless. */ @@ -726,13 +757,24 @@ update_alignment_for_field (record_layout_info rli, tree field, #ifdef ADJUST_FIELD_ALIGN if (! TYPE_USER_ALIGN (type)) - type_align = ADJUST_FIELD_ALIGN (field, type_align); + /* APPLE LOCAL begin Macintosh alignment */ + type_align = ADJUST_FIELD_ALIGN (field, type_align, + (darwin_align_is_first_member_of_class + || (integer_zerop (rli->offset) + && integer_zerop (rli->bitpos)))); + /* APPLE LOCAL end Macintosh alignment */ #endif if (maximum_field_alignment != 0) type_align = MIN (type_align, maximum_field_alignment); else if (DECL_PACKED (field)) type_align = MIN (type_align, BITS_PER_UNIT); +/* APPLE LOCAL begin Macintosh alignment 2002-2-12 ff */ +#ifdef PEG_ALIGN_FOR_MAC68K + else if (TARGET_ALIGN_MAC68K) + type_align = PEG_ALIGN_FOR_MAC68K (type_align); +#endif +/* APPLE LOCAL end Macintosh alignment 2002-2-12 ff */ /* The alignment of the record is increased to the maximum of the current alignment, the alignment indicated on the @@ -919,6 +961,11 @@ place_field (record_layout_info rli, tree field) && DECL_BIT_FIELD (field) && ! DECL_PACKED (field) && maximum_field_alignment == 0 +/* APPLE LOCAL begin Macintosh alignment 2002-2-12 ff */ +#ifdef PEG_ALIGN_FOR_MAC68K + && ! TARGET_ALIGN_MAC68K +#endif +/* APPLE LOCAL end Macintosh alignment 2002-2-12 ff */ && ! integer_zerop (DECL_SIZE (field)) && host_integerp (DECL_SIZE (field), 1) && host_integerp (rli->offset, 1) @@ -932,7 +979,12 @@ place_field (record_layout_info rli, tree field) #ifdef ADJUST_FIELD_ALIGN if (! TYPE_USER_ALIGN (type)) - type_align = ADJUST_FIELD_ALIGN (field, type_align); + /* APPLE LOCAL begin Macintosh alignment */ + type_align = ADJUST_FIELD_ALIGN (field, type_align, + (darwin_align_is_first_member_of_class + || (integer_zerop (rli->offset) + && integer_zerop (rli->bitpos)))); + /* APPLE LOCAL end Macintosh alignment */ #endif /* A bit field may not span more units of alignment of its type @@ -964,7 +1016,12 @@ place_field (record_layout_info rli, tree field) #ifdef ADJUST_FIELD_ALIGN if (! TYPE_USER_ALIGN (type)) - type_align = ADJUST_FIELD_ALIGN (field, type_align); + /* APPLE LOCAL begin Macintosh alignment */ + type_align = ADJUST_FIELD_ALIGN (field, type_align, + (darwin_align_is_first_member_of_class + || (integer_zerop (rli->offset) + && integer_zerop (rli->bitpos)))); + /* APPLE LOCAL end Macintosh alignment */ #endif if (maximum_field_alignment != 0) @@ -973,6 +1030,12 @@ place_field (record_layout_info rli, tree field) statement, so this code is unreachable currently. */ else if (DECL_PACKED (field)) type_align = MIN (type_align, BITS_PER_UNIT); +/* APPLE LOCAL begin Macintosh alignment 2002-2-12 ff */ +#ifdef PEG_ALIGN_FOR_MAC68K + else if (TARGET_ALIGN_MAC68K) + type_align = PEG_ALIGN_FOR_MAC68K (type_align); +#endif +/* APPLE LOCAL end Macintosh alignment 2002-2-12 ff */ /* A bit field may not span the unit of alignment of its type. Advance to next boundary if necessary. */ @@ -1327,6 +1390,16 @@ compute_record_mode (tree type) RECORD_TYPE. This does not apply to unions. */ if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode) TYPE_MODE (type) = mode; + /* APPLE LOCAL 8-byte-struct hack */ +#if defined RS6000_VARARGS_AREA + /* Make 8-byte structs BLKmode instead of DImode, which fixes both + struct-return methods and attempts to use floats in kernel code. + This should probably become a generic macro similar to + MEMBER_TYPE_FORCES_BLK above. */ + else if (mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1) == DImode + && flag_pic) + ; +#endif else TYPE_MODE (type) = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1); |