| author | |
| committer | |
| log | c0a1b4fa46dfd00d0cc4d1b6954bc07ae762e31e |
| tree | 0a1c5d0951abca83fc9610d6c99093b63563c23a |
| parent | 8632e4fc7b6cad33b951f71298ee6ac478e133cb |
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.2 files changed, 30 insertions(+), 4 deletions(-)
src/TypedValue.zig+10-4| ... | ... | @@ -73,6 +73,9 @@ pub fn print( |
| 73 | 73 | const target = mod.getTarget(); |
| 74 | 74 | var val = tv.val; |
| 75 | 75 | var ty = tv.ty; |
| 76 | if (val.isVariable(mod)) | |
| 77 | return writer.writeAll("(variable)"); | |
| 78 | ||
| 76 | 79 | while (true) switch (val.tag()) { |
| 77 | 80 | .u1_type => return writer.writeAll("u1"), |
| 78 | 81 | .u8_type => return writer.writeAll("u8"), |
| ... | ... | @@ -155,9 +158,12 @@ pub fn print( |
| 155 | 158 | } |
| 156 | 159 | try print(.{ |
| 157 | 160 | .ty = ty.structFieldType(i), |
| 158 | .val = ty.structFieldValueComptime(i) orelse b: { | |
| 159 | const vals = val.castTag(.aggregate).?.data; | |
| 160 | break :b vals[i]; | |
| 161 | .val = switch (ty.containerLayout()) { | |
| 162 | .Packed => val.castTag(.aggregate).?.data[i], | |
| 163 | else => ty.structFieldValueComptime(i) orelse b: { | |
| 164 | const vals = val.castTag(.aggregate).?.data; | |
| 165 | break :b vals[i]; | |
| 166 | }, | |
| 161 | 167 | }, |
| 162 | 168 | }, writer, level - 1, mod); |
| 163 | 169 | } |
| ... | ... | @@ -241,7 +247,7 @@ pub fn print( |
| 241 | 247 | mod.declPtr(val.castTag(.function).?.data.owner_decl).name, |
| 242 | 248 | }), |
| 243 | 249 | .extern_fn => return writer.writeAll("(extern function)"), |
| 244 | .variable => return writer.writeAll("(variable)"), | |
| 250 | .variable => unreachable, | |
| 245 | 251 | .decl_ref_mut => { |
| 246 | 252 | const decl_index = val.castTag(.decl_ref_mut).?.data.decl_index; |
| 247 | 253 | const decl = mod.declPtr(decl_index); |
src/value.zig+20| ... | ... | @@ -2664,6 +2664,26 @@ pub const Value = extern union { |
| 2664 | 2664 | } |
| 2665 | 2665 | } |
| 2666 | 2666 | |
| 2667 | /// Returns true if a Value is backed by a variable | |
| 2668 | pub fn isVariable( | |
| 2669 | val: Value, | |
| 2670 | mod: *Module, | |
| 2671 | ) bool { | |
| 2672 | return switch (val.tag()) { | |
| 2673 | .slice => val.castTag(.slice).?.data.ptr.isVariable(mod), | |
| 2674 | .comptime_field_ptr => val.castTag(.comptime_field_ptr).?.data.field_val.isVariable(mod), | |
| 2675 | .elem_ptr => val.castTag(.elem_ptr).?.data.array_ptr.isVariable(mod), | |
| 2676 | .field_ptr => val.castTag(.field_ptr).?.data.container_ptr.isVariable(mod), | |
| 2677 | .eu_payload_ptr => val.castTag(.eu_payload_ptr).?.data.container_ptr.isVariable(mod), | |
| 2678 | .opt_payload_ptr => val.castTag(.opt_payload_ptr).?.data.container_ptr.isVariable(mod), | |
| 2679 | .decl_ref => mod.declPtr(val.castTag(.decl_ref).?.data).val.isVariable(mod), | |
| 2680 | .decl_ref_mut => mod.declPtr(val.castTag(.decl_ref_mut).?.data.decl_index).val.isVariable(mod), | |
| 2681 | ||
| 2682 | .variable => true, | |
| 2683 | else => false, | |
| 2684 | }; | |
| 2685 | } | |
| 2686 | ||
| 2667 | 2687 | // Asserts that the provided start/end are in-bounds. |
| 2668 | 2688 | pub fn sliceArray( |
| 2669 | 2689 | val: Value, |