Skip to content

Commit c1a4486

Browse files
committed
add __traits getBitfieldOffset and getBitfieldWidth
1 parent f713bd3 commit c1a4486

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

compiler/src/dmd/id.d

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,8 @@ immutable Msgtable[] msgtable =
484484
{ "hasMember" },
485485
{ "identifier" },
486486
{ "fullyQualifiedName" },
487+
{ "getBitfieldOffset" },
488+
{ "getBitfieldWidth" },
487489
{ "getProtection" },
488490
{ "getVisibility" },
489491
{ "parent" },

compiler/src/dmd/traits.d

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,41 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
776776
return se.expressionSemantic(sc);
777777

778778
}
779+
if (e.ident == Id.getBitfieldOffset || e.ident == Id.getBitfieldWidth)
780+
{
781+
if (dim != 1)
782+
return dimError(1);
783+
784+
auto o = (*e.args)[0];
785+
auto s = getDsymbolWithoutExpCtx(o);
786+
if (!s)
787+
{
788+
error(e.loc, "bitfield symbol expected not `%s`", o.toChars());
789+
return ErrorExp.get();
790+
}
791+
792+
auto vd = s.toAlias.isVarDeclaration();
793+
if (!vd || !(vd.storage_class & STC.field))
794+
{
795+
error(e.loc, "bitfield symbol expected not %s `%s`", s.kind, s.toPrettyChars);
796+
return ErrorExp.get();
797+
}
798+
799+
uint fieldWidth;
800+
uint bitOffset;
801+
if (auto bf = vd.isBitFieldDeclaration())
802+
{
803+
fieldWidth = bf.fieldWidth;
804+
bitOffset = bf.bitOffset;
805+
}
806+
else // just a regular field
807+
{
808+
fieldWidth = cast(uint)size(vd.type) * 8;
809+
bitOffset = 0;
810+
}
811+
uint value = e.ident == Id.getBitfieldOffset ? bitOffset : fieldWidth;
812+
return new IntegerExp(e.loc, value, Type.tuns32);
813+
}
779814
if (e.ident == Id.getProtection || e.ident == Id.getVisibility)
780815
{
781816
if (dim != 1)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* REQUIRED_ARGS: -preview=bitfields
2+
* TEST_OUTPUT:
3+
---
4+
fail_compilation/biterrors5.d(23): Error: bitfield symbol expected not struct `biterrors5.S`
5+
fail_compilation/biterrors5.d(24): Error: bitfield symbol expected not variable `biterrors5.test0.i`
6+
---
7+
*/
8+
9+
struct S
10+
{
11+
int a,b;
12+
int :2, c:3;
13+
}
14+
15+
static assert(__traits(getBitfieldOffset, S.b) == 0);
16+
static assert(__traits(getBitfieldWidth, S.b) == 32);
17+
static assert(__traits(getBitfieldOffset, S.c) == 2);
18+
static assert(__traits(getBitfieldWidth, S.c) == 3);
19+
20+
void test0()
21+
{
22+
int i;
23+
i = __traits(getBitfieldOffset, S);
24+
i = __traits(getBitfieldOffset, i);
25+
}

0 commit comments

Comments
 (0)