mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 04:56:07 +00:00
Fix bug in computation of ivar offsets for (adjacent) bitfields.
- The confusing IRgen bitfield interface is partly to blame here; fixing the functional error for now, cleanups to the interface to follow. llvm-svn: 69503
This commit is contained in:
parent
ecbcb3ab0b
commit
9a7a78b0ae
@ -1879,17 +1879,20 @@ llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
|
||||
uint64_t CGObjCCommonMac::GetIvarBaseOffset(const llvm::StructLayout *Layout,
|
||||
const FieldDecl *Field) {
|
||||
if (!Field->isBitField())
|
||||
return Layout->getElementOffset(
|
||||
CGM.getTypes().getLLVMFieldNo(Field));
|
||||
return Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field));
|
||||
|
||||
// FIXME. Must be a better way of getting a bitfield base offset.
|
||||
uint64_t offset = CGM.getTypes().getLLVMFieldNo(Field);
|
||||
const llvm::Type *Ty = CGM.getTypes().ConvertTypeForMemRecursive(Field->getType());
|
||||
uint64_t size = CGM.getTypes().getTargetData().getTypePaddedSizeInBits(Ty);
|
||||
offset = (offset*size)/8;
|
||||
return offset;
|
||||
CodeGenTypes::BitFieldInfo BFI = CGM.getTypes().getBitFieldInfo(Field);
|
||||
// FIXME: The "field no" for bitfields is something completely
|
||||
// different; it is the offset in multiples of the base type size!
|
||||
uint64_t Offset = CGM.getTypes().getLLVMFieldNo(Field);
|
||||
const llvm::Type *Ty =
|
||||
CGM.getTypes().ConvertTypeForMemRecursive(Field->getType());
|
||||
Offset *= CGM.getTypes().getTargetData().getTypePaddedSizeInBits(Ty);
|
||||
return (Offset + BFI.Begin) / 8;
|
||||
}
|
||||
|
||||
/// GetFieldBaseOffset - return's field byt offset.
|
||||
/// GetFieldBaseOffset - return the field's byte offset.
|
||||
uint64_t CGObjCCommonMac::GetFieldBaseOffset(const ObjCInterfaceDecl *OI,
|
||||
const llvm::StructLayout *Layout,
|
||||
const FieldDecl *Field) {
|
||||
@ -4580,8 +4583,8 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
|
||||
for (RecordDecl::field_iterator e = RD->field_end(CGM.getContext());
|
||||
i != e; ++i) {
|
||||
FieldDecl *Field = *i;
|
||||
uint64_t offset = GetIvarBaseOffset(Layout, Field);
|
||||
Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), OIvars[iv++], offset);
|
||||
Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), OIvars[iv++],
|
||||
GetIvarBaseOffset(Layout, Field));
|
||||
if (Field->getIdentifier())
|
||||
Ivar[1] = GetMethodVarName(Field->getIdentifier());
|
||||
else
|
||||
|
23
clang/test/CodeGenObjC/bitfield-ivar-offsets.m
Normal file
23
clang/test/CodeGenObjC/bitfield-ivar-offsets.m
Normal file
@ -0,0 +1,23 @@
|
||||
// RUN: clang-cc -triple x86_64-apple-darwin10 -emit-llvm -o %t %s &&
|
||||
// RUN: grep -F '@"OBJC_IVAR_$_I0._b0" = global i64 0, section "__DATA, __objc_const", align 8' %t &&
|
||||
// RUN: grep -F '@"OBJC_IVAR_$_I0._b1" = global i64 0, section "__DATA, __objc_const", align 8' %t &&
|
||||
// RUN: grep -F '@"OBJC_IVAR_$_I0._b2" = global i64 1, section "__DATA, __objc_const", align 8' %t &&
|
||||
// RUN: grep -F '@"OBJC_IVAR_$_I0._x" = global i64 2, section "__DATA, __objc_const", align 8' %t &&
|
||||
// RUN: grep -F '@"OBJC_IVAR_$_I0._b3" = global i64 4, section "__DATA, __objc_const", align 8' %t &&
|
||||
// RUN: grep -F '@"OBJC_IVAR_$_I0._y" = global i64 6, section "__DATA, __objc_const", align 8' %t &&
|
||||
// RUN: grep -F '@"OBJC_IVAR_$_I0._b4" = global i64 7, section "__DATA, __objc_const", align 8' %t &&
|
||||
// RUN: true
|
||||
|
||||
@interface I0 {
|
||||
unsigned _b0:4;
|
||||
unsigned _b1:5;
|
||||
unsigned _b2:5;
|
||||
char _x;
|
||||
unsigned _b3:9;
|
||||
char _y;
|
||||
char _b4:3;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation I0
|
||||
@end
|
Loading…
x
Reference in New Issue
Block a user