Emit debug info for bitfields.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@64815 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Devang Patel 2009-02-17 21:23:59 +00:00
parent f163a95705
commit 36375ee7a5
4 changed files with 49 additions and 7 deletions

View File

@ -118,9 +118,9 @@ namespace llvm {
/// code generator accepts maximum one main compile unit per module. If a
/// module does not contain any main compile unit then the code generator
/// will emit multiple compile units in the output object file.
bool isMain() const { return getUnsignedField(6); }
bool isOptimized() const { return getUnsignedField(7); }
std::string getFlags() const { return getStringField(8); }
bool isMain() const { return getUnsignedField(6); }
bool isOptimized() const { return getUnsignedField(7); }
std::string getFlags() const { return getStringField(8); }
/// Verify - Verify that a compile unit is well formed.
bool Verify() const;
@ -217,6 +217,9 @@ namespace llvm {
explicit DIDerivedType(GlobalVariable *GV);
DIType getTypeDerivedFrom() const { return getFieldAs<DIType>(9); }
/// getOriginalTypeSize - If this type is derived from a base type then
/// return base type size.
uint64_t getOriginalTypeSize() const;
/// dump - print derived type.
void dump() const;
};

View File

@ -169,8 +169,8 @@ bool DIVariable::isVariable(unsigned Tag) {
}
}
DIVariable::DIVariable(GlobalVariable *GV) : DIDescriptor(GV) {
if (GV && !isVariable(getTag()))
DIVariable::DIVariable(GlobalVariable *gv) : DIDescriptor(gv) {
if (gv && !isVariable(getTag()))
GV = 0;
}
@ -273,7 +273,16 @@ bool DIVariable::Verify() const {
return true;
}
/// getOriginalTypeSize - If this type is derived from a base type then
/// return base type size.
uint64_t DIDerivedType::getOriginalTypeSize() const {
if (getTag() != dwarf::DW_TAG_member)
return getSizeInBits();
DIType BT = getTypeDerivedFrom();
if (BT.getTag() != dwarf::DW_TAG_base_type)
return getSizeInBits();
return BT.getSizeInBits();
}
//===----------------------------------------------------------------------===//
// DIFactory: Basic Helpers

View File

@ -1873,7 +1873,24 @@ private:
AddSourceLine(MemberDie, &DT);
// FIXME _ Handle bitfields
uint64_t Size = DT.getSizeInBits();
uint64_t FieldSize = DT.getOriginalTypeSize();
if (Size != FieldSize) {
// Handle bitfield.
AddUInt(MemberDie, DW_AT_byte_size, 0, DT.getOriginalTypeSize() >> 3);
AddUInt(MemberDie, DW_AT_bit_size, 0, DT.getSizeInBits());
uint64_t Offset = DT.getOffsetInBits();
uint64_t FieldOffset = Offset;
uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
uint64_t HiMark = (Offset + FieldSize) & AlignMask;
FieldOffset = (HiMark - FieldSize);
Offset -= FieldOffset;
// Maybe we need to work from the other end.
if (TD->isLittleEndian()) Offset = FieldSize - (Offset + Size);
AddUInt(MemberDie, DW_AT_bit_offset, 0, Offset);
}
DIEBlock *Block = new DIEBlock();
AddUInt(Block, 0, DW_FORM_data1, DW_OP_plus_uconst);
AddUInt(Block, 0, DW_FORM_udata, DT.getOffsetInBits() >> 3);

View File

@ -0,0 +1,13 @@
// Check bitfields.
// RUN: %llvmgcc -S -O0 -g %s -o - | llvm-as | \
// RUN: llc --disable-fp-elim -o 2009-02-17-BitField-dbg.s -f
// RUN: %compile_c 2009-02-17-BitField-dbg.s -o 2009-02-17-BitField-dbg.o
// RUN: echo {ptype mystruct} > %t2
// RUN: gdb -q -batch -n -x %t2 2009-02-17-BitField-dbg.o | \
// RUN: tee 2009-02-17-BitField-dbg.out | grep "int a : 4"
struct {
int a:4;
int b:2;
} mystruct;