mirror of
https://github.com/dlang/dmd.git
synced 2025-04-29 22:50:27 +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)
|
||||
{
|
||||
const vsz = v.type.size();
|
||||
const tsz = type.size();
|
||||
auto vsz = v.type.size();
|
||||
auto tsz = type.size();
|
||||
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()
|
||||
|
|
|
@ -6227,6 +6227,7 @@ elem *toElemStructLit(StructLiteralExp sle, IRState *irs, TOK op, Symbol *sym, b
|
|||
|
||||
// CTFE may fill the hidden pointer by NullExp.
|
||||
{
|
||||
VarDeclaration vbf;
|
||||
foreach (i, el; *sle.elements)
|
||||
{
|
||||
if (!el)
|
||||
|
@ -6270,6 +6271,27 @@ elem *toElemStructLit(StructLiteralExp sle, IRState *irs, TOK op, Symbol *sym, b
|
|||
e1 = el_una(OPind, ty, e1);
|
||||
if (tybasic(ty) == TYstruct)
|
||||
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);
|
||||
}
|
||||
e = el_combine(e, e1);
|
||||
|
|
|
@ -8,7 +8,7 @@ struct S
|
|||
|
||||
_Static_assert(sizeof(struct S) == 4, "in");
|
||||
|
||||
int main()
|
||||
void test1()
|
||||
{
|
||||
struct S s;
|
||||
s.a = 3;
|
||||
|
@ -24,6 +24,44 @@ int main()
|
|||
printf("error %d\n", s.b);
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue