diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index ebb264eb61..e43da6ff4c 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -1041,7 +1041,13 @@ llvm::DIType *CGDebugInfo::createBitFieldType(const FieldDecl *BitFieldDecl, assert(SizeInBits > 0 && "found named 0-width bitfield"); uint64_t StorageOffsetInBits = CGM.getContext().toBits(BitFieldInfo.StorageOffset); - uint64_t OffsetInBits = StorageOffsetInBits + BitFieldInfo.Offset; + uint64_t Offset = BitFieldInfo.Offset; + // The bit offsets for big endian machines are reversed for big + // endian target, compensate for that as the DIDerivedType requires + // un-reversed offsets. + if (CGM.getDataLayout().isBigEndian()) + Offset = BitFieldInfo.StorageSize - BitFieldInfo.Size - Offset; + uint64_t OffsetInBits = StorageOffsetInBits + Offset; llvm::DINode::DIFlags Flags = getAccessFlag(BitFieldDecl->getAccess(), RD); return DBuilder.createBitFieldMemberType( RecordTy, Name, File, Line, SizeInBits, OffsetInBits, StorageOffsetInBits, diff --git a/test/CodeGen/mips-debug-info-bitfield.c b/test/CodeGen/mips-debug-info-bitfield.c new file mode 100644 index 0000000000..a0e2ed9cde --- /dev/null +++ b/test/CodeGen/mips-debug-info-bitfield.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -x c -debug-info-kind=limited -triple mips-none-linux-gnu -emit-llvm -o - %s | FileCheck %s + +struct fields +{ + unsigned a : 4; + unsigned b : 4; +} flags; + +// CHECK: !DIDerivedType(tag: DW_TAG_member, +// CHECK-SAME: {{.*}}name: "a" +// CHECK-NOT: {{.*}}offset: +// CHECK-SAME: {{.*}}flags: DIFlagBitField + +// CHECK: !DIDerivedType(tag: DW_TAG_member, +// CHECK-SAME: {{.*}}name: "b" +// CHECK-SAME: {{.*}}offset: 4 +// CHECK-SAME: {{.*}}flags: DIFlagBitField