llvm-project/clang/test/CodeGen/mips-debug-info-bitfield.c

18 lines
472 B
C
Raw Normal View History

Correct debug info bit offset calculation for big-endian targets Summary: The change "[CodeView] Implement support for bit fields in Clang" (r274201, https://reviews.llvm.org/rL274201) broke the calculation of bit offsets for the debug info describing bitfields on big-endian targets. Prior to commit r274201 the debug info for bitfields got their offsets from the ASTRecordLayout in CGDebugInfo::CollectRecordFields(), the current field offset was then passed on to CGDebugInfo::CollectRecordNormalField() and used directly in the DIDerivedType. Since commit r274201, the bit offset ending up in the DIDerivedType no longer comes directly from the ASTRecordLayout. Instead CGDebugInfo::CollectRecordNormalField() calls the new method CGDebugInfo::createBitFieldType(), which in turn calls CodeGenTypes::getCGRecordLayout().getBitFieldInfo() to fetch a CGBitFieldInfo describing the field. The 'Offset' member of CGBitFieldInfo is then used to calculate the bit offset of the DIDerivedType. Unfortunately the previous and current method of calculating the bit offset are only equivalent for little endian targets, as CGRecordLowering::setBitFieldInfo() reverses the bit offsets for big endian targets as the last thing it does. A simple reproducer for this error is the following module: struct fields { unsigned a : 4; unsigned b : 4; } flags = {0x0f, 0x1}; Compiled for Mips, with commit r274200 both the DIDerivedType bit offsets on the IR-level and the DWARF information on the ELF-level will have the expected values: the offsets of 'a' and 'b' are 0 and 4 respectively. With r274201 the offsets are switched to 4 and 0. By noting that the static initialization of 'flags' in both cases is the same, we can eliminate a change in record layout as the cause of the change in the debug info. Also compiling this example with gcc, produces the same record layout and debug info as commit r274200. In order to restore the previous function we extend CGDebugInfo::createBitFieldType() to compensate for the reversal done in CGRecordLowering::setBitFieldInfo(). Patch by Frej Drejhammar! Reviewers: cfe-commits, majnemer, rnk, aaboud, echristo, aprantl Reviewed By: rnk, aprantl Subscribers: aprantl, arichardson, frej Differential Revision: https://reviews.llvm.org/D32745 llvm-svn: 305224
2017-06-13 03:57:56 +08:00
// 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