mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 21:21:48 +03:00
add __traits getBitfieldOffset and getBitfieldWidth (#17043)
This commit is contained in:
parent
e17cc3a28f
commit
b70e66033c
5 changed files with 82 additions and 0 deletions
16
changelog/dmd.getBitfieldInfo.dd
Normal file
16
changelog/dmd.getBitfieldInfo.dd
Normal file
|
@ -0,0 +1,16 @@
|
|||
Add __traits getBitfieldOffset and getBitfieldWidth
|
||||
|
||||
This completes the introspection capabilities of builtin bitfields. For example:
|
||||
|
||||
---
|
||||
struct S
|
||||
{
|
||||
int a,b;
|
||||
int :2, c:3;
|
||||
}
|
||||
|
||||
static assert(__traits(getBitfieldOffset, S.b) == 0);
|
||||
static assert(__traits(getBitfieldOffset, S.c) == 2);
|
||||
static assert(__traits(getBitfieldWidth, S.b) == 32);
|
||||
static assert(__traits(getBitfieldWidth, S.c) == 3);
|
||||
---
|
|
@ -8924,6 +8924,8 @@ struct Id final
|
|||
static Identifier* hasMember;
|
||||
static Identifier* identifier;
|
||||
static Identifier* fullyQualifiedName;
|
||||
static Identifier* getBitfieldOffset;
|
||||
static Identifier* getBitfieldWidth;
|
||||
static Identifier* getProtection;
|
||||
static Identifier* getVisibility;
|
||||
static Identifier* parent;
|
||||
|
|
|
@ -484,6 +484,8 @@ immutable Msgtable[] msgtable =
|
|||
{ "hasMember" },
|
||||
{ "identifier" },
|
||||
{ "fullyQualifiedName" },
|
||||
{ "getBitfieldOffset" },
|
||||
{ "getBitfieldWidth" },
|
||||
{ "getProtection" },
|
||||
{ "getVisibility" },
|
||||
{ "parent" },
|
||||
|
|
|
@ -776,6 +776,43 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
|
|||
return se.expressionSemantic(sc);
|
||||
|
||||
}
|
||||
if (e.ident == Id.getBitfieldOffset || e.ident == Id.getBitfieldWidth)
|
||||
{
|
||||
if (dim != 1)
|
||||
return dimError(1);
|
||||
|
||||
auto o = (*e.args)[0];
|
||||
auto s = getDsymbolWithoutExpCtx(o);
|
||||
if (!s)
|
||||
{
|
||||
error(e.loc, "bitfield symbol expected not `%s`", o.toChars());
|
||||
return ErrorExp.get();
|
||||
}
|
||||
|
||||
auto vd = s.toAlias.isVarDeclaration();
|
||||
if (!vd || !(vd.storage_class & STC.field))
|
||||
{
|
||||
error(e.loc, "bitfield symbol expected not %s `%s`", s.kind, s.toPrettyChars);
|
||||
return ErrorExp.get();
|
||||
}
|
||||
|
||||
uint fieldWidth;
|
||||
uint bitOffset;
|
||||
if (auto bf = vd.isBitFieldDeclaration())
|
||||
{
|
||||
fieldWidth = bf.fieldWidth;
|
||||
bitOffset = bf.bitOffset;
|
||||
}
|
||||
else // just a regular field
|
||||
{
|
||||
const sz = size(vd.type);
|
||||
assert(sz < uint.max / 8); // overflow check
|
||||
fieldWidth = cast(uint)sz * 8;
|
||||
bitOffset = 0;
|
||||
}
|
||||
uint value = e.ident == Id.getBitfieldOffset ? bitOffset : fieldWidth;
|
||||
return new IntegerExp(e.loc, value, Type.tuns32);
|
||||
}
|
||||
if (e.ident == Id.getProtection || e.ident == Id.getVisibility)
|
||||
{
|
||||
if (dim != 1)
|
||||
|
|
25
compiler/test/fail_compilation/biterrors5.d
Normal file
25
compiler/test/fail_compilation/biterrors5.d
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* REQUIRED_ARGS: -preview=bitfields
|
||||
* TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/biterrors5.d(23): Error: bitfield symbol expected not struct `biterrors5.S`
|
||||
fail_compilation/biterrors5.d(24): Error: bitfield symbol expected not variable `biterrors5.test0.i`
|
||||
---
|
||||
*/
|
||||
|
||||
struct S
|
||||
{
|
||||
int a,b;
|
||||
int :2, c:3;
|
||||
}
|
||||
|
||||
static assert(__traits(getBitfieldOffset, S.b) == 0);
|
||||
static assert(__traits(getBitfieldWidth, S.b) == 32);
|
||||
static assert(__traits(getBitfieldOffset, S.c) == 2);
|
||||
static assert(__traits(getBitfieldWidth, S.c) == 3);
|
||||
|
||||
void test0()
|
||||
{
|
||||
int i;
|
||||
i = __traits(getBitfieldOffset, S);
|
||||
i = __traits(getBitfieldOffset, i);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue