authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-01-16 17:12:43+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-16 13:13:45-05:00
logdf03fcf5f07e0d5d16e5b837658265f6c468cbe4
treeba012a63f4ca49632a8f74a8941b913e8a63c3e3
parentf609ce4f6551d772dcb6480c573ccad7645056cb

implement `@bitSizeOf`


6 files changed, 43 insertions(+), 5 deletions(-)

doc/langref.html.in+14-1
......@@ -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+4
......@@ -358,6 +358,8 @@ struct LazyValueSizeOf {
358358
359359 IrAnalyze *ira;
360360 IrInstruction *target_type;
361
362 bool bit_size;
361363};
362364
363365struct LazyValueSliceType {
......@@ -1754,6 +1756,7 @@ enum BuiltinFnId {
17541756 BuiltinFnIdFrameSize,
17551757 BuiltinFnIdAs,
17561758 BuiltinFnIdCall,
1759 BuiltinFnIdBitSizeof,
17571760};
17581761
17591762struct BuiltinFnEntry {
......@@ -3146,6 +3149,7 @@ struct IrInstructionAsmGen {
31463149struct IrInstructionSizeOf {
31473150 IrInstruction base;
31483151
3152 bool bit_size;
31493153 IrInstruction *type_value;
31503154};
31513155
src/codegen.cpp+1
......@@ -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
83048305static const char *bool_to_str(bool b) {
src/ir.cpp+9-3
......@@ -2392,9 +2392,10 @@ static IrInstruction *ir_build_asm_gen(IrAnalyze *ira, Scope *scope, AstNode *so
23922392 return &instruction->base;
23932393}
23942394
2395static IrInstruction *ir_build_size_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) {
2395static 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+4-1
......@@ -1039,7 +1039,10 @@ static void ir_print_asm_gen(IrPrint *irp, IrInstructionAsmGen *instruction) {
10391039}
10401040
10411041static 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+11
......@@ -124,3 +124,14 @@ fn fn1(alpha: bool) void {
124124test "lazy @sizeOf result is checked for definedness" {
125125 const f = fn1;
126126}
127
128test "@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}