Skip to content

Commit df03fcf

Browse files
Vexuandrewrk
authored andcommitted
implement @bitSizeOf
1 parent f609ce4 commit df03fcf

File tree

6 files changed

+43
-5
lines changed

6 files changed

+43
-5
lines changed

doc/langref.html.in

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6815,6 +6815,19 @@ async fn func(y: *i32) void {
68156815
</p>
68166816
{#header_close#}
68176817

6818+
{#header_open|@bitSizeOf#}
6819+
<pre>{#syntax#}@bitSizeOf(comptime T: type) comptime_int{#endsyntax#}</pre>
6820+
<p>
6821+
This function returns the number of bits it takes to store {#syntax#}T{#endsyntax#} in memory.
6822+
The result is a target-specific compile time constant.
6823+
</p>
6824+
<p>
6825+
This function measures the size at runtime. For types that are disallowed at runtime, such as
6826+
{#syntax#}comptime_int{#endsyntax#} and {#syntax#}type{#endsyntax#}, the result is {#syntax#}0{#endsyntax#}.
6827+
</p>
6828+
{#see_also|@sizeOf|@typeInfo#}
6829+
{#header_close#}
6830+
68186831
{#header_open|@breakpoint#}
68196832
<pre>{#syntax#}@breakpoint(){#endsyntax#}</pre>
68206833
<p>
@@ -8044,7 +8057,7 @@ test "@setRuntimeSafety" {
80448057
This function measures the size at runtime. For types that are disallowed at runtime, such as
80458058
{#syntax#}comptime_int{#endsyntax#} and {#syntax#}type{#endsyntax#}, the result is {#syntax#}0{#endsyntax#}.
80468059
</p>
8047-
{#see_also|@typeInfo#}
8060+
{#see_also|@bitSizeOf|@typeInfo#}
80488061
{#header_close#}
80498062

80508063
{#header_open|@sliceToBytes#}

src/all_types.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,8 @@ struct LazyValueSizeOf {
358358

359359
IrAnalyze *ira;
360360
IrInstruction *target_type;
361+
362+
bool bit_size;
361363
};
362364

363365
struct LazyValueSliceType {
@@ -1754,6 +1756,7 @@ enum BuiltinFnId {
17541756
BuiltinFnIdFrameSize,
17551757
BuiltinFnIdAs,
17561758
BuiltinFnIdCall,
1759+
BuiltinFnIdBitSizeof,
17571760
};
17581761

17591762
struct BuiltinFnEntry {
@@ -3146,6 +3149,7 @@ struct IrInstructionAsmGen {
31463149
struct IrInstructionSizeOf {
31473150
IrInstruction base;
31483151

3152+
bool bit_size;
31493153
IrInstruction *type_value;
31503154
};
31513155

src/codegen.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8299,6 +8299,7 @@ static void define_builtin_fns(CodeGen *g) {
82998299
create_builtin_fn(g, BuiltinFnIdFrameSize, "frameSize", 1);
83008300
create_builtin_fn(g, BuiltinFnIdAs, "as", 2);
83018301
create_builtin_fn(g, BuiltinFnIdCall, "call", 3);
8302+
create_builtin_fn(g, BuiltinFnIdBitSizeof, "bitSizeOf", 1);
83028303
}
83038304

83048305
static const char *bool_to_str(bool b) {

src/ir.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,9 +2392,10 @@ static IrInstruction *ir_build_asm_gen(IrAnalyze *ira, Scope *scope, AstNode *so
23922392
return &instruction->base;
23932393
}
23942394

2395-
static IrInstruction *ir_build_size_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) {
2395+
static IrInstruction *ir_build_size_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value, bool bit_size) {
23962396
IrInstructionSizeOf *instruction = ir_build_instruction<IrInstructionSizeOf>(irb, scope, source_node);
23972397
instruction->type_value = type_value;
2398+
instruction->bit_size = bit_size;
23982399

23992400
ir_ref_instruction(type_value, irb->current_basic_block);
24002401

@@ -5249,13 +5250,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
52495250
return ir_lval_wrap(irb, scope, set_float_mode, lval, result_loc);
52505251
}
52515252
case BuiltinFnIdSizeof:
5253+
case BuiltinFnIdBitSizeof:
52525254
{
52535255
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
52545256
IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
52555257
if (arg0_value == irb->codegen->invalid_instruction)
52565258
return arg0_value;
52575259

5258-
IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value);
5260+
IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value, builtin_fn->id == BuiltinFnIdBitSizeof);
52595261
return ir_lval_wrap(irb, scope, size_of, lval, result_loc);
52605262
}
52615263
case BuiltinFnIdImport:
@@ -21065,6 +21067,7 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, IrInstructi
2106521067
lazy_size_of->ira = ira; ira_ref(ira);
2106621068
result->value->data.x_lazy = &lazy_size_of->base;
2106721069
lazy_size_of->base.id = LazyValueIdSizeOf;
21070+
lazy_size_of->bit_size = instruction->bit_size;
2106821071

2106921072
lazy_size_of->target_type = instruction->type_value->child;
2107021073
if (ir_resolve_type_lazy(ira, lazy_size_of->target_type) == nullptr)
@@ -29415,7 +29418,10 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
2941529418

2941629419
val->special = ConstValSpecialStatic;
2941729420
assert(val->type->id == ZigTypeIdComptimeInt || val->type->id == ZigTypeIdInt);
29418-
bigint_init_unsigned(&val->data.x_bigint, abi_size);
29421+
if (lazy_size_of->bit_size)
29422+
bigint_init_unsigned(&val->data.x_bigint, size_in_bits);
29423+
else
29424+
bigint_init_unsigned(&val->data.x_bigint, abi_size);
2941929425

2942029426
// We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
2942129427
return ErrorNone;

src/ir_print.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1039,7 +1039,10 @@ static void ir_print_asm_gen(IrPrint *irp, IrInstructionAsmGen *instruction) {
10391039
}
10401040

10411041
static void ir_print_size_of(IrPrint *irp, IrInstructionSizeOf *instruction) {
1042-
fprintf(irp->f, "@sizeOf(");
1042+
if (instruction->bit_size)
1043+
fprintf(irp->f, "@bitSizeOf(");
1044+
else
1045+
fprintf(irp->f, "@sizeOf(");
10431046
ir_print_other_instruction(irp, instruction->type_value);
10441047
fprintf(irp->f, ")");
10451048
}

test/stage1/behavior/sizeof_and_typeof.zig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,14 @@ fn fn1(alpha: bool) void {
124124
test "lazy @sizeOf result is checked for definedness" {
125125
const f = fn1;
126126
}
127+
128+
test "@bitSizeOf" {
129+
expect(@bitSizeOf(u2) == 2);
130+
expect(@bitSizeOf(u8) == @sizeOf(u8) * 8);
131+
expect(@bitSizeOf(struct {
132+
a: u2
133+
}) == 8);
134+
expect(@bitSizeOf(packed struct {
135+
a: u2
136+
}) == 2);
137+
}

0 commit comments

Comments
 (0)