History

bitfields: Implement MS compatible layout

Bit-fields are layed out differently in visual C, this implements a compatible mode. Checked against Visual C/C++ 2016. Unfortunately the GCC implementation of MS layout (behind -mms-bitfields) actually is different, and hence not compatible with MS in all cases :-/

Michael Matz committed 10 years ago

Commit bd69bce1 parent 78c70961 file · +30 −7Browse files

Unified · Split

tccgen.c+30−7
@@ -3266,7 +3266,7 @@ static void struct_add_offset (Sym *s, int offset) · 3265 unmodified lines
32663266
32673267 static void struct_layout(CType *type, AttributeDef *ad)
32683268 {
3269− int align, maxalign, offset, c, bit_pos;
3269+ int align, maxalign, offset, c, bit_pos, bt, prevbt;
32703270 Sym *f;
32713271 if (ad->a.aligned)
32723272 maxalign = ad->a.aligned;
@@ -3275,6 +3275,7 @@ static void struct_layout(CType *type, AttributeDef *ad) · 2 unmodified lines
32753275 offset = 0;
32763276 c = 0;
32773277 bit_pos = 0;
3278+ prevbt = VT_STRUCT; /* make it never match */
32783279 for (f = type->ref->next; f; f = f->next) {
32793280 int extra_bytes = 0;
32803281 int typealign, bit_size;
@@ -3312,7 +3313,7 @@ static void struct_layout(CType *type, AttributeDef *ad) · 31 unmodified lines
33123313 }
33133314 /*if (extra_bytes) c += extra_bytes;
33143315 else*/ if (bit_size < 0) {
3315− int addbytes = (bit_pos + 7) >> 3;
3316+ int addbytes = pcc ? (bit_pos + 7) >> 3 : 0;
33163317 if (type->ref->type.t == TOK_STRUCT) {
33173318 c = (c + addbytes + align - 1) & -align;
33183319 offset = c;
@@ -3328,6 +3329,7 @@ static void struct_layout(CType *type, AttributeDef *ad) · 9 unmodified lines
33283329 if (align > maxalign)
33293330 maxalign = align;
33303331 bit_pos = 0;
3332+ prevbt = VT_STRUCT;
33313333 } else {
33323334 /* A bit-field. Layout is more complicated. There are two
33333335 options TCC implements: PCC compatible and MS compatible
@@ -3347,9 +3349,9 @@ static void struct_layout(CType *type, AttributeDef *ad) · 13 unmodified lines
33473349 its container (depending on base type) or it's a zero-width
33483350 bit-field. Packed non-zero-width bit-fields always are
33493351 placed adjacent. */
3350− if (typealign != 1 &&
3351− (bit_pos + bit_size > size * 8 ||
3352− bit_size == 0)) {
3352+ if ((typealign != 1 &&
3353+ bit_pos + bit_size > size * 8) ||
3354+ bit_size == 0) {
33533355 c = (c + ((bit_pos + 7) >> 3) + typealign - 1) & -typealign;
33543356 offset = c;
33553357 bit_pos = 0;
@@ -3364,12 +3366,31 @@ static void struct_layout(CType *type, AttributeDef *ad) · 8 unmodified lines
33643366 maxalign = typealign;
33653367 }
33663368 } else {
3367− tcc_error("ms bit-field layout not implemented");
3369+ bt = f->type.t & VT_BTYPE;
3370+ if (
3371+ ((
3372+ bit_pos + bit_size > size * 8) ||
3373+ (bit_size == 0 && prevbt == bt) ||
3374+ (bit_size > 0 && bt != prevbt))) {
3375+ c = (c + typealign - 1) & -typealign;
3376+ offset = c;
3377+ bit_pos = 0;
3378+ /* In MS bitfield mode a bit-field run always uses
3379+ at least as many bits as the underlying type. */
3380+ c += size;
3381+ }
3382+ if (bit_size > 0 || prevbt == bt) {
3383+ if (align > maxalign)
3384+ maxalign = align;
3385+ if (typealign > maxalign)
3386+ maxalign = typealign;
3387+ }
3388+ prevbt = bt;
33683389 }
33693390 f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
33703391 | (bit_pos << VT_STRUCT_SHIFT);
33713392 bit_pos += bit_size;
3372− if (bit_pos >= size * 8) {
3393+ if (pcc && bit_pos >= size * 8) {
33733394 c += size;
33743395 bit_pos -= size * 8;
33753396 }
@@ -3573,6 +3594,8 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) · 197 unmodified lines
35733594 if (v && bit_size == 0)
35743595 tcc_error("zero width for bit-field '%s'",
35753596 get_tok_str(v, NULL));
3597+ if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
3598+ parse_attribute(&ad1);
35763599 }
35773600 size = type_size(&type1, &align);
35783601 /* Only remember non-default alignment. */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t