mirror of
https://github.com/ziglang/zig.git
synced 2025-02-05 20:30:37 +00:00
implement @bitSizeOf
This commit is contained in:
parent
f609ce4f65
commit
df03fcf5f0
@ -6815,6 +6815,19 @@ async fn func(y: *i32) void {
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@bitSizeOf#}
|
||||
<pre>{#syntax#}@bitSizeOf(comptime T: type) comptime_int{#endsyntax#}</pre>
|
||||
<p>
|
||||
This function returns the number of bits it takes to store {#syntax#}T{#endsyntax#} in memory.
|
||||
The result is a target-specific compile time constant.
|
||||
</p>
|
||||
<p>
|
||||
This function measures the size at runtime. For types that are disallowed at runtime, such as
|
||||
{#syntax#}comptime_int{#endsyntax#} and {#syntax#}type{#endsyntax#}, the result is {#syntax#}0{#endsyntax#}.
|
||||
</p>
|
||||
{#see_also|@sizeOf|@typeInfo#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@breakpoint#}
|
||||
<pre>{#syntax#}@breakpoint(){#endsyntax#}</pre>
|
||||
<p>
|
||||
@ -8044,7 +8057,7 @@ test "@setRuntimeSafety" {
|
||||
This function measures the size at runtime. For types that are disallowed at runtime, such as
|
||||
{#syntax#}comptime_int{#endsyntax#} and {#syntax#}type{#endsyntax#}, the result is {#syntax#}0{#endsyntax#}.
|
||||
</p>
|
||||
{#see_also|@typeInfo#}
|
||||
{#see_also|@bitSizeOf|@typeInfo#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@sliceToBytes#}
|
||||
|
@ -358,6 +358,8 @@ struct LazyValueSizeOf {
|
||||
|
||||
IrAnalyze *ira;
|
||||
IrInstruction *target_type;
|
||||
|
||||
bool bit_size;
|
||||
};
|
||||
|
||||
struct LazyValueSliceType {
|
||||
@ -1754,6 +1756,7 @@ enum BuiltinFnId {
|
||||
BuiltinFnIdFrameSize,
|
||||
BuiltinFnIdAs,
|
||||
BuiltinFnIdCall,
|
||||
BuiltinFnIdBitSizeof,
|
||||
};
|
||||
|
||||
struct BuiltinFnEntry {
|
||||
@ -3146,6 +3149,7 @@ struct IrInstructionAsmGen {
|
||||
struct IrInstructionSizeOf {
|
||||
IrInstruction base;
|
||||
|
||||
bool bit_size;
|
||||
IrInstruction *type_value;
|
||||
};
|
||||
|
||||
|
@ -8299,6 +8299,7 @@ static void define_builtin_fns(CodeGen *g) {
|
||||
create_builtin_fn(g, BuiltinFnIdFrameSize, "frameSize", 1);
|
||||
create_builtin_fn(g, BuiltinFnIdAs, "as", 2);
|
||||
create_builtin_fn(g, BuiltinFnIdCall, "call", 3);
|
||||
create_builtin_fn(g, BuiltinFnIdBitSizeof, "bitSizeOf", 1);
|
||||
}
|
||||
|
||||
static const char *bool_to_str(bool b) {
|
||||
|
12
src/ir.cpp
12
src/ir.cpp
@ -2392,9 +2392,10 @@ static IrInstruction *ir_build_asm_gen(IrAnalyze *ira, Scope *scope, AstNode *so
|
||||
return &instruction->base;
|
||||
}
|
||||
|
||||
static IrInstruction *ir_build_size_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) {
|
||||
static IrInstruction *ir_build_size_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value, bool bit_size) {
|
||||
IrInstructionSizeOf *instruction = ir_build_instruction<IrInstructionSizeOf>(irb, scope, source_node);
|
||||
instruction->type_value = type_value;
|
||||
instruction->bit_size = bit_size;
|
||||
|
||||
ir_ref_instruction(type_value, irb->current_basic_block);
|
||||
|
||||
@ -5249,13 +5250,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
|
||||
return ir_lval_wrap(irb, scope, set_float_mode, lval, result_loc);
|
||||
}
|
||||
case BuiltinFnIdSizeof:
|
||||
case BuiltinFnIdBitSizeof:
|
||||
{
|
||||
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
|
||||
IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
|
||||
if (arg0_value == irb->codegen->invalid_instruction)
|
||||
return arg0_value;
|
||||
|
||||
IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value);
|
||||
IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value, builtin_fn->id == BuiltinFnIdBitSizeof);
|
||||
return ir_lval_wrap(irb, scope, size_of, lval, result_loc);
|
||||
}
|
||||
case BuiltinFnIdImport:
|
||||
@ -21065,6 +21067,7 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, IrInstructi
|
||||
lazy_size_of->ira = ira; ira_ref(ira);
|
||||
result->value->data.x_lazy = &lazy_size_of->base;
|
||||
lazy_size_of->base.id = LazyValueIdSizeOf;
|
||||
lazy_size_of->bit_size = instruction->bit_size;
|
||||
|
||||
lazy_size_of->target_type = instruction->type_value->child;
|
||||
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) {
|
||||
|
||||
val->special = ConstValSpecialStatic;
|
||||
assert(val->type->id == ZigTypeIdComptimeInt || val->type->id == ZigTypeIdInt);
|
||||
bigint_init_unsigned(&val->data.x_bigint, abi_size);
|
||||
if (lazy_size_of->bit_size)
|
||||
bigint_init_unsigned(&val->data.x_bigint, size_in_bits);
|
||||
else
|
||||
bigint_init_unsigned(&val->data.x_bigint, abi_size);
|
||||
|
||||
// We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
|
||||
return ErrorNone;
|
||||
|
@ -1039,7 +1039,10 @@ static void ir_print_asm_gen(IrPrint *irp, IrInstructionAsmGen *instruction) {
|
||||
}
|
||||
|
||||
static void ir_print_size_of(IrPrint *irp, IrInstructionSizeOf *instruction) {
|
||||
fprintf(irp->f, "@sizeOf(");
|
||||
if (instruction->bit_size)
|
||||
fprintf(irp->f, "@bitSizeOf(");
|
||||
else
|
||||
fprintf(irp->f, "@sizeOf(");
|
||||
ir_print_other_instruction(irp, instruction->type_value);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
@ -124,3 +124,14 @@ fn fn1(alpha: bool) void {
|
||||
test "lazy @sizeOf result is checked for definedness" {
|
||||
const f = fn1;
|
||||
}
|
||||
|
||||
test "@bitSizeOf" {
|
||||
expect(@bitSizeOf(u2) == 2);
|
||||
expect(@bitSizeOf(u8) == @sizeOf(u8) * 8);
|
||||
expect(@bitSizeOf(struct {
|
||||
a: u2
|
||||
}) == 8);
|
||||
expect(@bitSizeOf(packed struct {
|
||||
a: u2
|
||||
}) == 2);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user