zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit c0a1b4fa46dfd00d0cc4d1b6954bc07ae762e31e (tree)
parent 8632e4fc7b6cad33b951f71298ee6ac478e133cb
Author: Cody Tapscott <topolarity@tapscott.me>
Date:   Sat, 30 Jul 2022 06:34:49 -0700

stage2: Fix AIR printing

Packed structs never have comptime fields, and a slice might actually be
backed by a variable, which we need to catch before iterating its
elements.

Diffstat:
Msrc/TypedValue.zig | 14++++++++++----
Msrc/value.zig | 20++++++++++++++++++++
2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/src/TypedValue.zig b/src/TypedValue.zig @@ -73,6 +73,9 @@ pub fn print( const target = mod.getTarget(); var val = tv.val; var ty = tv.ty; + if (val.isVariable(mod)) + return writer.writeAll("(variable)"); + while (true) switch (val.tag()) { .u1_type => return writer.writeAll("u1"), .u8_type => return writer.writeAll("u8"), @@ -155,9 +158,12 @@ pub fn print( } try print(.{ .ty = ty.structFieldType(i), - .val = ty.structFieldValueComptime(i) orelse b: { - const vals = val.castTag(.aggregate).?.data; - break :b vals[i]; + .val = switch (ty.containerLayout()) { + .Packed => val.castTag(.aggregate).?.data[i], + else => ty.structFieldValueComptime(i) orelse b: { + const vals = val.castTag(.aggregate).?.data; + break :b vals[i]; + }, }, }, writer, level - 1, mod); } @@ -241,7 +247,7 @@ pub fn print( mod.declPtr(val.castTag(.function).?.data.owner_decl).name, }), .extern_fn => return writer.writeAll("(extern function)"), - .variable => return writer.writeAll("(variable)"), + .variable => unreachable, .decl_ref_mut => { const decl_index = val.castTag(.decl_ref_mut).?.data.decl_index; const decl = mod.declPtr(decl_index); diff --git a/src/value.zig b/src/value.zig @@ -2664,6 +2664,26 @@ pub const Value = extern union { } } + /// Returns true if a Value is backed by a variable + pub fn isVariable( + val: Value, + mod: *Module, + ) bool { + return switch (val.tag()) { + .slice => val.castTag(.slice).?.data.ptr.isVariable(mod), + .comptime_field_ptr => val.castTag(.comptime_field_ptr).?.data.field_val.isVariable(mod), + .elem_ptr => val.castTag(.elem_ptr).?.data.array_ptr.isVariable(mod), + .field_ptr => val.castTag(.field_ptr).?.data.container_ptr.isVariable(mod), + .eu_payload_ptr => val.castTag(.eu_payload_ptr).?.data.container_ptr.isVariable(mod), + .opt_payload_ptr => val.castTag(.opt_payload_ptr).?.data.container_ptr.isVariable(mod), + .decl_ref => mod.declPtr(val.castTag(.decl_ref).?.data).val.isVariable(mod), + .decl_ref_mut => mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val.isVariable(mod), + + .variable => true, + else => false, + }; + } + // Asserts that the provided start/end are in-bounds. pub fn sliceArray( val: Value,