summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp58
1 files changed, 30 insertions, 28 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 91c490f0e9d..08800f415a4 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1395,41 +1395,43 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {
// Handle bitfield, assume bytes are 8 bits.
addUInt(MemberDie, dwarf::DW_AT_byte_size, None, FieldSize/8);
addUInt(MemberDie, dwarf::DW_AT_bit_size, None, Size);
- //
- // The DWARF 2 DW_AT_bit_offset is counting the bits between the most
- // significant bit of the aligned storage unit containing the bit field to
- // the most significan bit of the bit field.
- //
- // FIXME: DWARF 4 states that DW_AT_data_bit_offset (which
- // counts from the beginning, regardless of endianness) should
- // be used instead.
- //
- //
- // Struct Align Align Align
- // v v v v
- // +-----------+-----*-----+-----*-----+--
- // | ... |b1|b2|b3|b4|
- // +-----------+-----*-----+-----*-----+--
- // | | |<-- Size ->| |
- // |<---- Offset --->| |<--->|
- // | | | \_ DW_AT_bit_offset (little endian)
- // | |<--->|
- // |<--------->| \_ StartBitOffset = DW_AT_bit_offset (big endian)
- // \ = DW_AT_data_bit_offset (biendian)
- // \_ OffsetInBytes
+
uint64_t Offset = DT->getOffsetInBits();
uint64_t Align = DT->getAlignInBits() ? DT->getAlignInBits() : FieldSize;
uint64_t AlignMask = ~(Align - 1);
// The bits from the start of the storage unit to the start of the field.
uint64_t StartBitOffset = Offset - (Offset & AlignMask);
- // The endian-dependent DWARF 2 offset.
- uint64_t DwarfBitOffset = Asm->getDataLayout().isLittleEndian()
- ? OffsetToAlignment(Offset + Size, Align)
- : StartBitOffset;
-
// The byte offset of the field's aligned storage unit inside the struct.
OffsetInBytes = (Offset - StartBitOffset) / 8;
- addUInt(MemberDie, dwarf::DW_AT_bit_offset, None, DwarfBitOffset);
+
+ if (DD->getDwarfVersion() >= 4)
+ addUInt(MemberDie, dwarf::DW_AT_data_bit_offset, None, Offset);
+ else {
+ //
+ // The DWARF 2 DW_AT_bit_offset is counting the bits between the most
+ // significant bit of the aligned storage unit containing the bit field
+ // to
+ // the most significan bit of the bit field.
+ //
+ // Struct Align Align Align
+ // v v v v
+ // +-----------+-----*-----+-----*-----+--
+ // | ... |b1|b2|b3|b4|
+ // +-----------+-----*-----+-----*-----+--
+ // | | |<-- Size ->| |
+ // |<---- Offset --->| |<--->|
+ // | | | \_ DW_AT_bit_offset (little endian)
+ // | |<--->|
+ // |<--------->| \_ StartBitOffset = DW_AT_bit_offset (big endian)
+ // \ = DW_AT_data_bit_offset (biendian)
+ // \_ OffsetInBytes
+ // The endian-dependent DWARF 2 offset.
+ uint64_t DwarfBitOffset = Asm->getDataLayout().isLittleEndian()
+ ? OffsetToAlignment(Offset + Size, Align)
+ : StartBitOffset;
+
+ addUInt(MemberDie, dwarf::DW_AT_bit_offset, None, DwarfBitOffset);
+ }
} else
// This is not a bitfield.
OffsetInBytes = DT->getOffsetInBits() / 8;
OpenPOWER on IntegriCloud