aboutsummaryrefslogtreecommitdiff
path: root/gcc/stor-layout.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/stor-layout.c')
-rw-r--r--gcc/stor-layout.c81
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);