forked from OSchip/llvm-project
With ms_struct attribut, Zero-length bitfields following
non-bitfield members are ignore. // rdar://8823265 wip llvm-svn: 130257
This commit is contained in:
parent
79ea878bf9
commit
bcb23a180b
|
@ -564,6 +564,8 @@ protected:
|
|||
unsigned IsUnion : 1;
|
||||
|
||||
unsigned IsMac68kAlign : 1;
|
||||
|
||||
unsigned IsMsStruct : 1;
|
||||
|
||||
/// UnfilledBitsInLastByte - If the last field laid out was a bitfield,
|
||||
/// this contains the number of bits in the last byte that can be used for
|
||||
|
@ -612,7 +614,8 @@ protected:
|
|||
*EmptySubobjects)
|
||||
: Context(Context), EmptySubobjects(EmptySubobjects), Size(0),
|
||||
Alignment(CharUnits::One()), UnpackedAlignment(Alignment),
|
||||
Packed(false), IsUnion(false), IsMac68kAlign(false),
|
||||
Packed(false), IsUnion(false),
|
||||
IsMac68kAlign(false), IsMsStruct(false),
|
||||
UnfilledBitsInLastByte(0), MaxFieldAlignment(CharUnits::Zero()),
|
||||
DataSize(0), NonVirtualSize(CharUnits::Zero()),
|
||||
NonVirtualAlignment(CharUnits::One()), PrimaryBase(0),
|
||||
|
@ -1148,6 +1151,8 @@ void RecordLayoutBuilder::InitializeLayout(const Decl *D) {
|
|||
IsUnion = RD->isUnion();
|
||||
|
||||
Packed = D->hasAttr<PackedAttr>();
|
||||
|
||||
IsMsStruct = D->hasAttr<MsStructAttr>();
|
||||
|
||||
// mac68k alignment supersedes maximum field alignment and attribute aligned,
|
||||
// and forces all structures to have 2-byte alignment. The IBM docs on it
|
||||
|
@ -1249,9 +1254,21 @@ void RecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) {
|
|||
void RecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
|
||||
// Layout each field, for now, just sequentially, respecting alignment. In
|
||||
// the future, this will need to be tweakable by targets.
|
||||
const FieldDecl *LastFD = 0;
|
||||
for (RecordDecl::field_iterator Field = D->field_begin(),
|
||||
FieldEnd = D->field_end(); Field != FieldEnd; ++Field)
|
||||
FieldEnd = D->field_end(); Field != FieldEnd; ++Field) {
|
||||
if (IsMsStruct) {
|
||||
// Zero-length bitfields following non-bitfield members are
|
||||
// ignored:
|
||||
const FieldDecl *FD = (*Field);
|
||||
if (FD->isBitField() && LastFD && !LastFD->isBitField() &&
|
||||
FD->getBitWidth()->EvaluateAsInt(Context).getZExtValue() == 0) {
|
||||
continue;
|
||||
}
|
||||
LastFD = FD;
|
||||
}
|
||||
LayoutField(*Field);
|
||||
}
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,
|
||||
|
|
|
@ -77,6 +77,9 @@ public:
|
|||
|
||||
/// Packed - Whether the resulting LLVM struct will be packed or not.
|
||||
bool Packed;
|
||||
|
||||
/// IsMsStruct - Whether ms_struct is in effect or not
|
||||
bool IsMsStruct;
|
||||
|
||||
private:
|
||||
CodeGenTypes &Types;
|
||||
|
@ -184,7 +187,8 @@ public:
|
|||
CGRecordLayoutBuilder(CodeGenTypes &Types)
|
||||
: BaseSubobjectType(0),
|
||||
IsZeroInitializable(true), IsZeroInitializableAsBase(true),
|
||||
Packed(false), Types(Types), BitsAvailableInLastField(0) { }
|
||||
Packed(false), IsMsStruct(false),
|
||||
Types(Types), BitsAvailableInLastField(0) { }
|
||||
|
||||
/// Layout - Will layout a RecordDecl.
|
||||
void Layout(const RecordDecl *D);
|
||||
|
@ -195,6 +199,8 @@ public:
|
|||
void CGRecordLayoutBuilder::Layout(const RecordDecl *D) {
|
||||
Alignment = Types.getContext().getASTRecordLayout(D).getAlignment();
|
||||
Packed = D->hasAttr<PackedAttr>();
|
||||
|
||||
IsMsStruct = D->hasAttr<MsStructAttr>();
|
||||
|
||||
if (D->isUnion()) {
|
||||
LayoutUnion(D);
|
||||
|
@ -739,9 +745,24 @@ bool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
|
|||
LayoutNonVirtualBases(RD, Layout);
|
||||
|
||||
unsigned FieldNo = 0;
|
||||
|
||||
const FieldDecl *LastFD = 0;
|
||||
|
||||
for (RecordDecl::field_iterator Field = D->field_begin(),
|
||||
FieldEnd = D->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
|
||||
if (IsMsStruct) {
|
||||
// Zero-length bitfields following non-bitfield members are
|
||||
// ignored:
|
||||
const FieldDecl *FD = (*Field);
|
||||
// FIXME. Refactor into common code as it is used in several places.
|
||||
if (FD->isBitField() && LastFD && !LastFD->isBitField() &&
|
||||
FD->getBitWidth()->
|
||||
EvaluateAsInt(Types.getContext()).getZExtValue() == 0) {
|
||||
--FieldNo;
|
||||
continue;
|
||||
}
|
||||
LastFD = FD;
|
||||
}
|
||||
|
||||
if (!LayoutField(*Field, Layout.getFieldOffset(FieldNo))) {
|
||||
assert(!Packed &&
|
||||
"Could not layout fields even with a packed LLVM struct!");
|
||||
|
@ -960,6 +981,8 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) {
|
|||
|
||||
const ASTRecordLayout &AST_RL = getContext().getASTRecordLayout(D);
|
||||
RecordDecl::field_iterator it = D->field_begin();
|
||||
const FieldDecl *LastFD = 0;
|
||||
bool IsMsStruct = D->hasAttr<MsStructAttr>();
|
||||
for (unsigned i = 0, e = AST_RL.getFieldCount(); i != e; ++i, ++it) {
|
||||
const FieldDecl *FD = *it;
|
||||
|
||||
|
@ -969,13 +992,28 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) {
|
|||
unsigned FieldNo = RL->getLLVMFieldNo(FD);
|
||||
assert(AST_RL.getFieldOffset(i) == SL->getElementOffsetInBits(FieldNo) &&
|
||||
"Invalid field offset!");
|
||||
LastFD = FD;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IsMsStruct) {
|
||||
// Zero-length bitfields following non-bitfield members are
|
||||
// ignored:
|
||||
if (FD->isBitField() && LastFD && !LastFD->isBitField() &&
|
||||
FD->getBitWidth()->
|
||||
EvaluateAsInt(getContext()).getZExtValue() == 0) {
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
LastFD = FD;
|
||||
}
|
||||
|
||||
// Ignore unnamed bit-fields.
|
||||
if (!FD->getDeclName())
|
||||
if (!FD->getDeclName()) {
|
||||
LastFD = FD;
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
const CGBitFieldInfo &Info = RL->getBitFieldInfo(FD);
|
||||
for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) {
|
||||
const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i);
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-apple-darwin9 %s
|
||||
// rdar://8823265
|
||||
|
||||
#define ATTR __attribute__((__ms_struct__))
|
||||
|
||||
struct
|
||||
{
|
||||
char foo;
|
||||
long : 0;
|
||||
char bar;
|
||||
} ATTR t1;
|
||||
|
||||
struct
|
||||
{
|
||||
char foo;
|
||||
long : 0;
|
||||
char : 0;
|
||||
int : 0;
|
||||
char bar;
|
||||
} ATTR t2;
|
||||
|
||||
struct
|
||||
{
|
||||
char foo;
|
||||
long : 0;
|
||||
char : 0;
|
||||
int : 0;
|
||||
char bar;
|
||||
long : 0;
|
||||
char : 0;
|
||||
} ATTR t3;
|
||||
|
||||
struct
|
||||
{
|
||||
long : 0;
|
||||
char bar;
|
||||
} ATTR t4;
|
||||
|
||||
struct
|
||||
{
|
||||
long : 0;
|
||||
long : 0;
|
||||
char : 0;
|
||||
char bar;
|
||||
} ATTR t5;
|
||||
|
||||
struct
|
||||
{
|
||||
long : 0;
|
||||
long : 0;
|
||||
char : 0;
|
||||
char bar;
|
||||
} ATTR t6;
|
||||
|
||||
struct
|
||||
{
|
||||
char foo;
|
||||
long : 0;
|
||||
int : 0;
|
||||
char bar;
|
||||
char bar1;
|
||||
long : 0;
|
||||
char bar2;
|
||||
char bar3;
|
||||
char : 0;
|
||||
char bar4;
|
||||
char bar5;
|
||||
char : 0;
|
||||
char bar6;
|
||||
char bar7;
|
||||
} ATTR t7;
|
||||
|
||||
struct
|
||||
{
|
||||
long : 0;
|
||||
long : 0;
|
||||
char : 0;
|
||||
} ATTR t8;
|
||||
|
||||
struct
|
||||
{
|
||||
char foo;
|
||||
long : 0;
|
||||
int : 0;
|
||||
char bar;
|
||||
char bar1;
|
||||
long : 0;
|
||||
char bar2;
|
||||
char bar3;
|
||||
char : 0;
|
||||
char bar4;
|
||||
char bar5;
|
||||
char : 0;
|
||||
char bar6;
|
||||
char bar7;
|
||||
int i1;
|
||||
char : 0;
|
||||
long : 0;
|
||||
char :4;
|
||||
char bar8;
|
||||
char : 0;
|
||||
char bar9;
|
||||
char bar10;
|
||||
int i2;
|
||||
char : 0;
|
||||
long : 0;
|
||||
char :4;
|
||||
} ATTR t9;
|
||||
|
||||
static int arr1[(sizeof(t1) == 2) -1];
|
||||
static int arr2[(sizeof(t2) == 2) -1];
|
||||
static int arr3[(sizeof(t3) == 2) -1];
|
||||
static int arr4[(sizeof(t4) == 1) -1];
|
||||
static int arr5[(sizeof(t5) == 1) -1];
|
||||
static int arr6[(sizeof(t6) == 1) -1];
|
||||
static int arr7[(sizeof(t7) == 9) -1];
|
||||
static int arr8[(sizeof(t8) == 0) -1];
|
||||
static int arr9[(sizeof(t9) == 28) -1];
|
||||
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue