diff options
author | David Majnemer <david.majnemer@gmail.com> | 2016-06-30 03:00:20 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2016-06-30 03:00:20 +0000 |
commit | 9319cbc045658d504f61dcd9ea78cf3df637de3d (patch) | |
tree | 13bdc18ee0d25d1874035d9c359f5590a2a28b3c /llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | |
parent | 0da2d147668532ce9266b03a29c078359d267f61 (diff) | |
download | bcm5719-llvm-9319cbc045658d504f61dcd9ea78cf3df637de3d.tar.gz bcm5719-llvm-9319cbc045658d504f61dcd9ea78cf3df637de3d.zip |
[CodeView] Implement support for bitfields in LLVM
CodeView need to know the offset of the storage allocation for a
bitfield. Encode this via the "extraData" field in DIDerivedType and
introduced a new flag, DIFlagBitField, to indicate whether or not a
member is a bitfield.
This fixes PR28162.
Differential Revision: http://reviews.llvm.org/D21782
llvm-svn: 274200
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index e01ee0984ed..a6bcf9e848d 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -20,6 +20,7 @@ #include "llvm/DebugInfo/CodeView/TypeDumper.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/IR/Constants.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSymbol.h" @@ -1500,23 +1501,32 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) { for (ClassInfo::MemberInfo &MemberInfo : Info.Members) { const DIDerivedType *Member = MemberInfo.MemberTypeNode; TypeIndex MemberBaseType = getTypeIndex(Member->getBaseType()); + StringRef MemberName = Member->getName(); + MemberAccess Access = + translateAccessFlags(Ty->getTag(), Member->getFlags()); if (Member->isStaticMember()) { - Fields.writeStaticDataMember(StaticDataMemberRecord( - translateAccessFlags(Ty->getTag(), Member->getFlags()), - MemberBaseType, Member->getName())); + Fields.writeStaticDataMember( + StaticDataMemberRecord(Access, MemberBaseType, MemberName)); MemberCount++; continue; } - uint64_t OffsetInBytes = MemberInfo.BaseOffset; - - // FIXME: Handle bitfield type memeber. - OffsetInBytes += Member->getOffsetInBits() / 8; - - Fields.writeDataMember( - DataMemberRecord(translateAccessFlags(Ty->getTag(), Member->getFlags()), - MemberBaseType, OffsetInBytes, Member->getName())); + // Data member. + uint64_t MemberOffsetInBits = Member->getOffsetInBits(); + if (Member->isBitField()) { + uint64_t StartBitOffset = MemberOffsetInBits; + if (const auto *CI = + dyn_cast_or_null<ConstantInt>(Member->getStorageOffsetInBits())) { + MemberOffsetInBits = CI->getZExtValue(); + } + StartBitOffset -= MemberOffsetInBits; + MemberBaseType = TypeTable.writeBitField(BitFieldRecord( + MemberBaseType, Member->getSizeInBits(), StartBitOffset)); + } + uint64_t MemberOffsetInBytes = MemberOffsetInBits / 8; + Fields.writeDataMember(DataMemberRecord(Access, MemberBaseType, + MemberOffsetInBytes, MemberName)); MemberCount++; } |