mirror of
https://github.com/dlang/dmd.git
synced 2025-05-01 07:30:14 +03:00
ImportC: implement bitfields for StructLiteralExpression
This commit is contained in:
parent
1f4133bc62
commit
61103da39c
3 changed files with 85 additions and 5 deletions
|
@ -1319,11 +1319,31 @@ extern (C++) class VarDeclaration : Declaration
|
||||||
|
|
||||||
final bool isOverlappedWith(VarDeclaration v)
|
final bool isOverlappedWith(VarDeclaration v)
|
||||||
{
|
{
|
||||||
const vsz = v.type.size();
|
auto vsz = v.type.size();
|
||||||
const tsz = type.size();
|
auto tsz = type.size();
|
||||||
assert(vsz != SIZE_INVALID && tsz != SIZE_INVALID);
|
assert(vsz != SIZE_INVALID && tsz != SIZE_INVALID);
|
||||||
return offset < v.offset + vsz &&
|
|
||||||
v.offset < offset + tsz;
|
auto off = offset * 8;
|
||||||
|
auto voff = v.offset * 8;
|
||||||
|
|
||||||
|
if (auto bf = isBitFieldDeclaration())
|
||||||
|
{
|
||||||
|
off += bf.bitOffset;
|
||||||
|
tsz = bf.fieldWidth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tsz *= 8;
|
||||||
|
|
||||||
|
if (auto bf = v.isBitFieldDeclaration())
|
||||||
|
{
|
||||||
|
voff += bf.bitOffset;
|
||||||
|
vsz = bf.fieldWidth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vsz *= 8;
|
||||||
|
|
||||||
|
return off < voff + vsz &&
|
||||||
|
voff < off + tsz;
|
||||||
}
|
}
|
||||||
|
|
||||||
override final bool hasPointers()
|
override final bool hasPointers()
|
||||||
|
|
|
@ -6227,6 +6227,7 @@ elem *toElemStructLit(StructLiteralExp sle, IRState *irs, TOK op, Symbol *sym, b
|
||||||
|
|
||||||
// CTFE may fill the hidden pointer by NullExp.
|
// CTFE may fill the hidden pointer by NullExp.
|
||||||
{
|
{
|
||||||
|
VarDeclaration vbf;
|
||||||
foreach (i, el; *sle.elements)
|
foreach (i, el; *sle.elements)
|
||||||
{
|
{
|
||||||
if (!el)
|
if (!el)
|
||||||
|
@ -6270,6 +6271,27 @@ elem *toElemStructLit(StructLiteralExp sle, IRState *irs, TOK op, Symbol *sym, b
|
||||||
e1 = el_una(OPind, ty, e1);
|
e1 = el_una(OPind, ty, e1);
|
||||||
if (tybasic(ty) == TYstruct)
|
if (tybasic(ty) == TYstruct)
|
||||||
e1.ET = Type_toCtype(v.type);
|
e1.ET = Type_toCtype(v.type);
|
||||||
|
if (auto bf = v.isBitFieldDeclaration())
|
||||||
|
{
|
||||||
|
if (!vbf || vbf.offset + vbf.type.size() <= v.offset)
|
||||||
|
{
|
||||||
|
/* Initialize entire location the bitfield is in
|
||||||
|
* ep = (ep & ((1 << bf.fieldWidth) - 1)) << bf.bitOffset
|
||||||
|
*/
|
||||||
|
tym_t e1ty = e1.Ety;
|
||||||
|
auto ex = el_bin(OPand, e1ty, ep, el_long(e1ty, (1L << bf.fieldWidth) - 1));
|
||||||
|
ep = el_bin(OPshl, e1ty, ex, el_long(e1ty, bf.bitOffset));
|
||||||
|
vbf = v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Insert special bitfield operator
|
||||||
|
auto mos = el_long(TYuint, bf.fieldWidth * 256 + bf.bitOffset);
|
||||||
|
e1 = el_bin(OPbit, e1.Ety, e1, mos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vbf = null;
|
||||||
e1 = elAssign(e1, ep, v.type, e1.ET);
|
e1 = elAssign(e1, ep, v.type, e1.ET);
|
||||||
}
|
}
|
||||||
e = el_combine(e, e1);
|
e = el_combine(e, e1);
|
||||||
|
|
|
@ -8,7 +8,7 @@ struct S
|
||||||
|
|
||||||
_Static_assert(sizeof(struct S) == 4, "in");
|
_Static_assert(sizeof(struct S) == 4, "in");
|
||||||
|
|
||||||
int main()
|
void test1()
|
||||||
{
|
{
|
||||||
struct S s;
|
struct S s;
|
||||||
s.a = 3;
|
s.a = 3;
|
||||||
|
@ -24,6 +24,44 @@ int main()
|
||||||
printf("error %d\n", s.b);
|
printf("error %d\n", s.b);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************/
|
||||||
|
|
||||||
|
struct S2
|
||||||
|
{
|
||||||
|
unsigned a:2, b:4;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S2 foo()
|
||||||
|
{
|
||||||
|
struct S2 s = { 7, 8 }; // test struct literal expressions
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test2()
|
||||||
|
{
|
||||||
|
struct S2 s = foo();
|
||||||
|
|
||||||
|
if (s.a != 3)
|
||||||
|
{
|
||||||
|
printf("error %d\n", s.a);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.b != 8)
|
||||||
|
{
|
||||||
|
printf("error %d\n", s.b);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************/
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test1();
|
||||||
|
test2();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue