From e5447574c8f58b766659ab93198916b85e52ef96 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Thu, 28 Apr 2016 15:37:52 +0000 Subject: Debug Info: Restore the pre-r240853 behavior for DWARF2 bitfields. The DWARF2 specification of DW_AT_bit_offset is ambiguous for little-endian machines, but by restoring to the old behavior we match what debuggers expect and what other popular compilers generate. llvm-svn: 267896 --- llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 34 +++++++++---------------------- 1 file changed, 10 insertions(+), 24 deletions(-) (limited to 'llvm/lib/CodeGen') diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 08800f415a4..51f25ec0fe6 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1407,30 +1407,16 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) { 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); + uint64_t HiMark = (Offset + FieldSize) & AlignMask; + uint64_t FieldOffset = (HiMark - FieldSize); + Offset -= FieldOffset; + + // Maybe we need to work from the other end. + if (Asm->getDataLayout().isLittleEndian()) + Offset = FieldSize - (Offset + Size); + + addUInt(MemberDie, dwarf::DW_AT_bit_offset, None, Offset); + OffsetInBytes = FieldOffset >> 3; } } else // This is not a bitfield. -- cgit v1.2.3