r274201 - [CodeView] Implement support for bitfields in Clang
David Majnemer via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 29 20:02:00 PDT 2016
Author: majnemer
Date: Wed Jun 29 22:01:59 2016
New Revision: 274201
URL: http://llvm.org/viewvc/llvm-project?rev=274201&view=rev
Log:
[CodeView] Implement support for bitfields in Clang
Emit the underlying storage offset in addition to the starting bit
position of the field.
This fixes PR28162.
Differential Revision: http://reviews.llvm.org/D21783
Added:
cfe/trunk/test/CodeGenCXX/debug-info-ms-bitfields.cpp
Modified:
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
cfe/trunk/lib/CodeGen/CGDebugInfo.h
cfe/trunk/test/CodeGen/debug-info-packed-struct.c
Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=274201&r1=274200&r2=274201&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Wed Jun 29 22:01:59 2016
@@ -13,6 +13,7 @@
#include "CGDebugInfo.h"
#include "CGBlocks.h"
+#include "CGRecordLayout.h"
#include "CGCXXABI.h"
#include "CGObjCRuntime.h"
#include "CodeGenFunction.h"
@@ -905,10 +906,38 @@ static unsigned getAccessFlag(AccessSpec
llvm_unreachable("unexpected access enumerator");
}
-llvm::DIType *CGDebugInfo::createFieldType(
- StringRef name, QualType type, uint64_t sizeInBitsOverride,
- SourceLocation loc, AccessSpecifier AS, uint64_t offsetInBits,
- llvm::DIFile *tunit, llvm::DIScope *scope, const RecordDecl *RD) {
+llvm::DIType *CGDebugInfo::createBitFieldType(const FieldDecl *BitFieldDecl,
+ llvm::DIScope *RecordTy,
+ const RecordDecl *RD) {
+ StringRef Name = BitFieldDecl->getName();
+ QualType Ty = BitFieldDecl->getType();
+ SourceLocation Loc = BitFieldDecl->getLocation();
+ llvm::DIFile *VUnit = getOrCreateFile(Loc);
+ llvm::DIType *DebugType = getOrCreateType(Ty, VUnit);
+
+ // Get the location for the field.
+ llvm::DIFile *File = getOrCreateFile(Loc);
+ unsigned Line = getLineNumber(Loc);
+
+ const CGBitFieldInfo &BitFieldInfo =
+ CGM.getTypes().getCGRecordLayout(RD).getBitFieldInfo(BitFieldDecl);
+ uint64_t SizeInBits = BitFieldInfo.Size;
+ assert(SizeInBits > 0 && "found named 0-width bitfield");
+ unsigned AlignInBits = CGM.getContext().getTypeAlign(Ty);
+ uint64_t StorageOffsetInBits =
+ CGM.getContext().toBits(BitFieldInfo.StorageOffset);
+ uint64_t OffsetInBits = StorageOffsetInBits + BitFieldInfo.Offset;
+ unsigned Flags = getAccessFlag(BitFieldDecl->getAccess(), RD);
+ return DBuilder.createBitFieldMemberType(
+ RecordTy, Name, File, Line, SizeInBits, AlignInBits, OffsetInBits,
+ StorageOffsetInBits, Flags, DebugType);
+}
+
+llvm::DIType *
+CGDebugInfo::createFieldType(StringRef name, QualType type, SourceLocation loc,
+ AccessSpecifier AS, uint64_t offsetInBits,
+ llvm::DIFile *tunit, llvm::DIScope *scope,
+ const RecordDecl *RD) {
llvm::DIType *debugType = getOrCreateType(type, tunit);
// Get the location for the field.
@@ -921,9 +950,6 @@ llvm::DIType *CGDebugInfo::createFieldTy
TypeInfo TI = CGM.getContext().getTypeInfo(type);
SizeInBits = TI.Width;
AlignInBits = TI.Align;
-
- if (sizeInBitsOverride)
- SizeInBits = sizeInBitsOverride;
}
unsigned flags = getAccessFlag(AS, RD);
@@ -945,19 +971,15 @@ void CGDebugInfo::CollectRecordLambdaFie
I != E; ++I, ++Field, ++fieldno) {
const LambdaCapture &C = *I;
if (C.capturesVariable()) {
+ SourceLocation Loc = C.getLocation();
+ assert(!Field->isBitField() && "lambdas don't have bitfield members!");
VarDecl *V = C.getCapturedVar();
- llvm::DIFile *VUnit = getOrCreateFile(C.getLocation());
StringRef VName = V->getName();
- uint64_t SizeInBitsOverride = 0;
- if (Field->isBitField()) {
- SizeInBitsOverride = Field->getBitWidthValue(CGM.getContext());
- assert(SizeInBitsOverride && "found named 0-width bitfield");
- }
- llvm::DIType *fieldType = createFieldType(
- VName, Field->getType(), SizeInBitsOverride, C.getLocation(),
- Field->getAccess(), layout.getFieldOffset(fieldno), VUnit, RecordTy,
- CXXDecl);
- elements.push_back(fieldType);
+ llvm::DIFile *VUnit = getOrCreateFile(Loc);
+ llvm::DIType *FieldType = createFieldType(
+ VName, Field->getType(), Loc, Field->getAccess(),
+ layout.getFieldOffset(fieldno), VUnit, RecordTy, CXXDecl);
+ elements.push_back(FieldType);
} else if (C.capturesThis()) {
// TODO: Need to handle 'this' in some way by probably renaming the
// this of the lambda class and having a field member of 'this' or
@@ -967,7 +989,7 @@ void CGDebugInfo::CollectRecordLambdaFie
llvm::DIFile *VUnit = getOrCreateFile(f->getLocation());
QualType type = f->getType();
llvm::DIType *fieldType = createFieldType(
- "this", type, 0, f->getLocation(), f->getAccess(),
+ "this", type, f->getLocation(), f->getAccess(),
layout.getFieldOffset(fieldno), VUnit, RecordTy, CXXDecl);
elements.push_back(fieldType);
@@ -1015,17 +1037,16 @@ void CGDebugInfo::CollectRecordNormalFie
if (name.empty() && !type->isRecordType())
return;
- uint64_t SizeInBitsOverride = 0;
+ llvm::DIType *FieldType;
if (field->isBitField()) {
- SizeInBitsOverride = field->getBitWidthValue(CGM.getContext());
- assert(SizeInBitsOverride && "found named 0-width bitfield");
+ FieldType = createBitFieldType(field, RecordTy, RD);
+ } else {
+ FieldType =
+ createFieldType(name, type, field->getLocation(), field->getAccess(),
+ OffsetInBits, tunit, RecordTy, RD);
}
- llvm::DIType *fieldType =
- createFieldType(name, type, SizeInBitsOverride, field->getLocation(),
- field->getAccess(), OffsetInBits, tunit, RecordTy, RD);
-
- elements.push_back(fieldType);
+ elements.push_back(FieldType);
}
void CGDebugInfo::CollectRecordFields(
@@ -3299,25 +3320,25 @@ void CGDebugInfo::EmitDeclareOfBlockLite
CGM.getDataLayout().getStructLayout(block.StructureType);
SmallVector<llvm::Metadata *, 16> fields;
- fields.push_back(createFieldType("__isa", C.VoidPtrTy, 0, loc, AS_public,
+ fields.push_back(createFieldType("__isa", C.VoidPtrTy, loc, AS_public,
blockLayout->getElementOffsetInBits(0),
tunit, tunit));
- fields.push_back(createFieldType("__flags", C.IntTy, 0, loc, AS_public,
+ fields.push_back(createFieldType("__flags", C.IntTy, loc, AS_public,
blockLayout->getElementOffsetInBits(1),
tunit, tunit));
- fields.push_back(createFieldType("__reserved", C.IntTy, 0, loc, AS_public,
+ fields.push_back(createFieldType("__reserved", C.IntTy, loc, AS_public,
blockLayout->getElementOffsetInBits(2),
tunit, tunit));
auto *FnTy = block.getBlockExpr()->getFunctionType();
auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar());
- fields.push_back(createFieldType("__FuncPtr", FnPtrType, 0, loc, AS_public,
+ fields.push_back(createFieldType("__FuncPtr", FnPtrType, loc, AS_public,
blockLayout->getElementOffsetInBits(3),
tunit, tunit));
fields.push_back(createFieldType(
"__descriptor", C.getPointerType(block.NeedsCopyDispose
? C.getBlockDescriptorExtendedType()
: C.getBlockDescriptorType()),
- 0, loc, AS_public, blockLayout->getElementOffsetInBits(4), tunit, tunit));
+ loc, AS_public, blockLayout->getElementOffsetInBits(4), tunit, tunit));
// We want to sort the captures by offset, not because DWARF
// requires this, but because we're paranoid about debuggers.
@@ -3368,7 +3389,7 @@ void CGDebugInfo::EmitDeclareOfBlockLite
else
llvm_unreachable("unexpected block declcontext");
- fields.push_back(createFieldType("this", type, 0, loc, AS_public,
+ fields.push_back(createFieldType("this", type, loc, AS_public,
offsetInBits, tunit, tunit));
continue;
}
@@ -3388,7 +3409,7 @@ void CGDebugInfo::EmitDeclareOfBlockLite
DBuilder.createMemberType(tunit, name, tunit, line, PtrInfo.Width,
PtrInfo.Align, offsetInBits, 0, fieldType);
} else {
- fieldType = createFieldType(name, variable->getType(), 0, loc, AS_public,
+ fieldType = createFieldType(name, variable->getType(), loc, AS_public,
offsetInBits, tunit, tunit);
}
fields.push_back(fieldType);
Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=274201&r1=274200&r2=274201&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Wed Jun 29 22:01:59 2016
@@ -232,11 +232,16 @@ class CGDebugInfo {
llvm::DIFile *F);
llvm::DIType *createFieldType(StringRef name, QualType type,
- uint64_t sizeInBitsOverride, SourceLocation loc,
- AccessSpecifier AS, uint64_t offsetInBits,
- llvm::DIFile *tunit, llvm::DIScope *scope,
+ SourceLocation loc, AccessSpecifier AS,
+ uint64_t offsetInBits, llvm::DIFile *tunit,
+ llvm::DIScope *scope,
const RecordDecl *RD = nullptr);
+ /// Create new bit field member.
+ llvm::DIType *createBitFieldType(const FieldDecl *BitFieldDecl,
+ llvm::DIScope *RecordTy,
+ const RecordDecl *RD);
+
/// Helpers for collecting fields of a record.
/// @{
void CollectRecordLambdaFields(const CXXRecordDecl *CXXDecl,
Modified: cfe/trunk/test/CodeGen/debug-info-packed-struct.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/debug-info-packed-struct.c?rev=274201&r1=274200&r2=274201&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/debug-info-packed-struct.c (original)
+++ cfe/trunk/test/CodeGen/debug-info-packed-struct.c Wed Jun 29 22:01:59 2016
@@ -21,7 +21,7 @@ struct layout0 {
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "l0_ofs8",
// CHECK-SAME: {{.*}}size: 64, align: 64, offset: 64)
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "l0_ofs16",
-// CHECK-SAME: {{.*}}size: 1, align: 32, offset: 128)
+// CHECK-SAME: {{.*}}size: 1, align: 32, offset: 128, flags: DIFlagBitField, extraData: i64 128)
// ---------------------------------------------------------------------
@@ -40,7 +40,7 @@ struct layout1 {
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "l1_ofs1",
// CHECK-SAME: {{.*}}size: 64, align: 8, offset: 8)
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "l1_ofs9",
-// CHECK-SAME: {{.*}}size: 1, align: 32, offset: 72)
+// CHECK-SAME: {{.*}}size: 1, align: 32, offset: 72, flags: DIFlagBitField, extraData: i64 72)
// ---------------------------------------------------------------------
@@ -61,7 +61,7 @@ struct layout2 {
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "l2_ofs1",
// CHECK-SAME: {{.*}}size: 64, align: 8, offset: 8)
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "l2_ofs9",
-// CHECK-SAME: {{.*}}size: 1, align: 32, offset: 72)
+// CHECK-SAME: {{.*}}size: 1, align: 32, offset: 72, flags: DIFlagBitField, extraData: i64 72)
@@ -83,7 +83,7 @@ struct layout3 {
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "l3_ofs4",
// CHECK-SAME: {{.*}}size: 64, align: 32, offset: 32)
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "l3_ofs12",
-// CHECK-SAME: {{.*}}size: 1, align: 32, offset: 96)
+// CHECK-SAME: {{.*}}size: 1, align: 32, offset: 96, flags: DIFlagBitField, extraData: i64 96)
struct layout0 l0;
struct layout1 l1;
Added: cfe/trunk/test/CodeGenCXX/debug-info-ms-bitfields.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-ms-bitfields.cpp?rev=274201&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/debug-info-ms-bitfields.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/debug-info-ms-bitfields.cpp Wed Jun 29 22:01:59 2016
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-pc-win32 -debug-info-kind=limited -gcodeview %s -emit-llvm -o - | FileCheck %s
+
+#pragma pack(1)
+struct S {
+ char : 8;
+ short : 8;
+ short x : 8;
+} s;
+
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x", {{.*}}, size: 8, align: 16, offset: 16, flags: DIFlagBitField, extraData: i64 8)
More information about the cfe-commits
mailing list