Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 33 additions & 45 deletions compiler/src/dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -7186,12 +7186,19 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
error(bfd.loc, "bit field width %d is larger than type", bfd.fieldWidth);

const style = target.c.bitFieldStyle;
if (style != TargetC.BitFieldStyle.MS && style != TargetC.BitFieldStyle.Gcc_Clang)
assert(0, "unsupported bit-field style");

const isMicrosoftStyle = style == TargetC.BitFieldStyle.MS;
const contributesToAggregateAlignment = target.c.contributesToAggregateAlignment(bfd);

void startNewField()
{
if (log) printf("startNewField()\n");
uint alignsize;
if (style == TargetC.BitFieldStyle.Gcc_Clang)
if (isMicrosoftStyle)
alignsize = memsize; // not memalignsize
else
{
if (bfd.fieldWidth > 32)
alignsize = memalignsize;
Expand All @@ -7202,15 +7209,13 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
else
alignsize = 1;
}
else
alignsize = memsize; // not memalignsize

uint dummy;
bfd.offset = placeField(
fieldState.offset,
memsize, alignsize, bfd.alignment,
ad.structsize,
(anon && style == TargetC.BitFieldStyle.Gcc_Clang) ? dummy : ad.alignsize,
contributesToAggregateAlignment ? ad.alignsize : dummy,
isunion);

fieldState.inFlight = true;
Expand All @@ -7219,53 +7224,38 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
fieldState.fieldSize = memsize;
}

if (style == TargetC.BitFieldStyle.Gcc_Clang)
if (ad.alignsize == 0)
ad.alignsize = 1;
if (!isMicrosoftStyle && contributesToAggregateAlignment && ad.alignsize < memalignsize)
ad.alignsize = memalignsize;

if (bfd.fieldWidth == 0)
{
if (bfd.fieldWidth == 0)
if (!isMicrosoftStyle && !isunion)
{
if (!isunion)
{
// Use type of zero width field to align to next field
fieldState.offset = (fieldState.offset + memalignsize - 1) & ~(memalignsize - 1);
ad.structsize = fieldState.offset;
}

fieldState.inFlight = false;
return;
// Use type of zero width field to align to next field
fieldState.offset = (fieldState.offset + memalignsize - 1) & ~(memalignsize - 1);
ad.structsize = fieldState.offset;
}

if (ad.alignsize == 0)
ad.alignsize = 1;
if (!anon &&
ad.alignsize < memalignsize)
ad.alignsize = memalignsize;
}
else if (style == TargetC.BitFieldStyle.MS)
{
if (ad.alignsize == 0)
ad.alignsize = 1;
if (bfd.fieldWidth == 0)
else if (isMicrosoftStyle && fieldState.inFlight && !isunion)
{
if (fieldState.inFlight && !isunion)
{
// documentation says align to next int
//const alsz = cast(uint)Type.tint32.size();
const alsz = memsize; // but it really does this
fieldState.offset = (fieldState.offset + alsz - 1) & ~(alsz - 1);
ad.structsize = fieldState.offset;
}

fieldState.inFlight = false;
return;
// documentation says align to next int
//const alsz = cast(uint)Type.tint32.size();
const alsz = memsize; // but it really does this
fieldState.offset = (fieldState.offset + alsz - 1) & ~(alsz - 1);
ad.structsize = fieldState.offset;
}

fieldState.inFlight = false;
return;
}

if (!fieldState.inFlight)
{
//printf("not in flight\n");
startNewField();
}
else if (style == TargetC.BitFieldStyle.Gcc_Clang)
else if (!isMicrosoftStyle)
{
// If the bit-field spans more units of alignment than its type,
// start a new field at the next alignment boundary.
Expand All @@ -7288,7 +7278,7 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
}
}
}
else if (style == TargetC.BitFieldStyle.MS)
else
{
if (memsize != fieldState.fieldSize ||
fieldState.bitOffset + bfd.fieldWidth > fieldState.fieldSize * 8)
Expand All @@ -7297,14 +7287,14 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
startNewField();
}
}
else
assert(0);

bfd.offset = fieldState.fieldOffset;
bfd.bitOffset = fieldState.bitOffset;

const pastField = bfd.bitOffset + bfd.fieldWidth;
if (style == TargetC.BitFieldStyle.Gcc_Clang)
if (isMicrosoftStyle)
fieldState.fieldSize = memsize;
else
{
auto size = (pastField + 7) / 8;
fieldState.fieldSize = size;
Expand All @@ -7318,8 +7308,6 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
else
ad.structsize = bfd.offset + size;
}
else
fieldState.fieldSize = memsize;
//printf("at end: ad.structsize = %d\n", cast(int)ad.structsize);
//print(fieldState);

Expand Down
1 change: 1 addition & 0 deletions compiler/src/dmd/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -5950,6 +5950,7 @@ struct TargetC final
uint8_t wchar_tsize;
Runtime runtime;
BitFieldStyle bitFieldStyle;
bool contributesToAggregateAlignment(BitFieldDeclaration* bfd);
TargetC() :
crtDestructorsSupported(true),
boolsize(),
Expand Down
20 changes: 20 additions & 0 deletions compiler/src/dmd/target.d
Original file line number Diff line number Diff line change
Expand Up @@ -1360,6 +1360,8 @@ extern (C++) struct Target
*/
struct TargetC
{
import dmd.declaration : BitFieldDeclaration;

enum Runtime : ubyte
{
Unspecified,
Expand Down Expand Up @@ -1449,6 +1451,24 @@ struct TargetC
crtDestructorsSupported = false;
}
}

/**
* Indicates whether the specified bit-field contributes to the alignment
* of the containing aggregate.
* E.g., (not all) ARM ABIs do NOT ignore anonymous (incl. 0-length)
* bit-fields.
*/
extern (C++) bool contributesToAggregateAlignment(BitFieldDeclaration bfd)
{
if (bitFieldStyle == BitFieldStyle.MS)
return true;
if (bitFieldStyle == BitFieldStyle.Gcc_Clang)
{
// sufficient for DMD's currently supported architectures
return !bfd.isAnonymous();
}
assert(0);
}
}

////////////////////////////////////////////////////////////////////////////////
Expand Down
3 changes: 3 additions & 0 deletions compiler/src/dmd/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "globals.h"
#include "tokens.h"

class BitFieldDeclaration;
class ClassDeclaration;
class Dsymbol;
class Expression;
Expand Down Expand Up @@ -77,6 +78,8 @@ struct TargetC
uint8_t wchar_tsize; // size of a C 'wchar_t' type
Runtime runtime;
BitFieldStyle bitFieldStyle; // different C compilers do it differently

bool contributesToAggregateAlignment(BitFieldDeclaration *bfd);
};

struct TargetCPP
Expand Down