aboutsummaryrefslogtreecommitdiff
path: root/gcc/dwarf2out.c
diff options
context:
space:
mode:
authorDJ Delorie <dj@redhat.com>2000-12-21 13:20:39 -0500
committerDJ Delorie <dj@gcc.gnu.org>2000-12-21 13:20:39 -0500
commit5f446d2172c1ca3e776b91a40127de9efa2f62d9 (patch)
treea1dbf48a966f8cd302df3cefa573d9905b403e4c /gcc/dwarf2out.c
parent477f6664a4b1316583e5a71f0edd30faefeeaab5 (diff)
downloadgcc-5f446d2172c1ca3e776b91a40127de9efa2f62d9.zip
gcc-5f446d2172c1ca3e776b91a40127de9efa2f62d9.tar.gz
gcc-5f446d2172c1ca3e776b91a40127de9efa2f62d9.tar.bz2
dwarf2out.c (simple_decl_align_in_bits): new
* dwarf2out.c (simple_decl_align_in_bits): new (field_byte_offset): Try both the type align and the decl align, use whichever works, preferring the type align. From-SVN: r38418
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r--gcc/dwarf2out.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 6d23ae4..39d76b2 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3460,6 +3460,7 @@ static dw_loc_descr_ref loc_descriptor_from_tree PARAMS ((tree, int));
static HOST_WIDE_INT ceiling PARAMS ((HOST_WIDE_INT, unsigned int));
static tree field_type PARAMS ((tree));
static unsigned int simple_type_align_in_bits PARAMS ((tree));
+static unsigned int simple_decl_align_in_bits PARAMS ((tree));
static unsigned HOST_WIDE_INT simple_type_size_in_bits PARAMS ((tree));
static HOST_WIDE_INT field_byte_offset PARAMS ((tree));
static void add_AT_location_description PARAMS ((dw_die_ref,
@@ -8050,10 +8051,9 @@ field_type (decl)
return type;
}
-/* Given a pointer to a tree node, assumed to be some kind of a ..._TYPE
- node, return the alignment in bits for the type, or else return
- BITS_PER_WORD if the node actually turns out to be an
- ERROR_MARK node. */
+/* Given a pointer to a tree node, return the alignment in bits for
+ it, or else return BITS_PER_WORD if the node actually turns out to
+ be an ERROR_MARK node. */
static inline unsigned
simple_type_align_in_bits (type)
@@ -8062,6 +8062,13 @@ simple_type_align_in_bits (type)
return (TREE_CODE (type) != ERROR_MARK) ? TYPE_ALIGN (type) : BITS_PER_WORD;
}
+static inline unsigned
+simple_decl_align_in_bits (decl)
+ register tree decl;
+{
+ return (TREE_CODE (decl) != ERROR_MARK) ? DECL_ALIGN (decl) : BITS_PER_WORD;
+}
+
/* Given a pointer to a tree node, assumed to be some kind of a ..._TYPE
node, return the size in bits for the type if it is a constant, or else
return the alignment for the type if the type's size is not constant, or
@@ -8096,10 +8103,9 @@ static HOST_WIDE_INT
field_byte_offset (decl)
register tree decl;
{
- unsigned int type_align_in_bytes;
unsigned int type_align_in_bits;
+ unsigned int decl_align_in_bits;
unsigned HOST_WIDE_INT type_size_in_bits;
- HOST_WIDE_INT object_offset_in_align_units;
HOST_WIDE_INT object_offset_in_bits;
HOST_WIDE_INT object_offset_in_bytes;
tree type;
@@ -8138,7 +8144,7 @@ field_byte_offset (decl)
type_size_in_bits = simple_type_size_in_bits (type);
type_align_in_bits = simple_type_align_in_bits (type);
- type_align_in_bytes = type_align_in_bits / BITS_PER_UNIT;
+ decl_align_in_bits = simple_decl_align_in_bits (decl);
/* Note that the GCC front-end doesn't make any attempt to keep track of
the starting bit offset (relative to the start of the containing
@@ -8185,14 +8191,25 @@ field_byte_offset (decl)
/* This is the tricky part. Use some fancy footwork to deduce where the
lowest addressed bit of the containing object must be. */
- object_offset_in_bits
- = ceiling (deepest_bitpos, type_align_in_bits) - type_size_in_bits;
+ object_offset_in_bits = deepest_bitpos - type_size_in_bits;
+
+ /* Round up to type_align by default. This works best for bitfields. */
+ object_offset_in_bits += type_align_in_bits - 1;
+ object_offset_in_bits /= type_align_in_bits;
+ object_offset_in_bits *= type_align_in_bits;
- /* Compute the offset of the containing object in "alignment units". */
- object_offset_in_align_units = object_offset_in_bits / type_align_in_bits;
+ if (object_offset_in_bits > bitpos_int)
+ {
+ /* Sigh, the decl must be packed. */
+ object_offset_in_bits = deepest_bitpos - type_size_in_bits;
+
+ /* Round up to decl_align instead. */
+ object_offset_in_bits += decl_align_in_bits - 1;
+ object_offset_in_bits /= decl_align_in_bits;
+ object_offset_in_bits *= decl_align_in_bits;
+ }
- /* Compute the offset of the containing object in bytes. */
- object_offset_in_bytes = object_offset_in_align_units * type_align_in_bytes;
+ object_offset_in_bytes = object_offset_in_bits / BITS_PER_UNIT;
return object_offset_in_bytes;
}