mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
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.
This commit is contained in:
parent
8632e4fc7b
commit
c0a1b4fa46
2 changed files with 30 additions and 4 deletions
|
|
@ -73,6 +73,9 @@ pub fn print(
|
||||||
const target = mod.getTarget();
|
const target = mod.getTarget();
|
||||||
var val = tv.val;
|
var val = tv.val;
|
||||||
var ty = tv.ty;
|
var ty = tv.ty;
|
||||||
|
if (val.isVariable(mod))
|
||||||
|
return writer.writeAll("(variable)");
|
||||||
|
|
||||||
while (true) switch (val.tag()) {
|
while (true) switch (val.tag()) {
|
||||||
.u1_type => return writer.writeAll("u1"),
|
.u1_type => return writer.writeAll("u1"),
|
||||||
.u8_type => return writer.writeAll("u8"),
|
.u8_type => return writer.writeAll("u8"),
|
||||||
|
|
@ -155,9 +158,12 @@ pub fn print(
|
||||||
}
|
}
|
||||||
try print(.{
|
try print(.{
|
||||||
.ty = ty.structFieldType(i),
|
.ty = ty.structFieldType(i),
|
||||||
.val = ty.structFieldValueComptime(i) orelse b: {
|
.val = switch (ty.containerLayout()) {
|
||||||
const vals = val.castTag(.aggregate).?.data;
|
.Packed => val.castTag(.aggregate).?.data[i],
|
||||||
break :b vals[i];
|
else => ty.structFieldValueComptime(i) orelse b: {
|
||||||
|
const vals = val.castTag(.aggregate).?.data;
|
||||||
|
break :b vals[i];
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}, writer, level - 1, mod);
|
}, writer, level - 1, mod);
|
||||||
}
|
}
|
||||||
|
|
@ -241,7 +247,7 @@ pub fn print(
|
||||||
mod.declPtr(val.castTag(.function).?.data.owner_decl).name,
|
mod.declPtr(val.castTag(.function).?.data.owner_decl).name,
|
||||||
}),
|
}),
|
||||||
.extern_fn => return writer.writeAll("(extern function)"),
|
.extern_fn => return writer.writeAll("(extern function)"),
|
||||||
.variable => return writer.writeAll("(variable)"),
|
.variable => unreachable,
|
||||||
.decl_ref_mut => {
|
.decl_ref_mut => {
|
||||||
const decl_index = val.castTag(.decl_ref_mut).?.data.decl_index;
|
const decl_index = val.castTag(.decl_ref_mut).?.data.decl_index;
|
||||||
const decl = mod.declPtr(decl_index);
|
const decl = mod.declPtr(decl_index);
|
||||||
|
|
|
||||||
|
|
@ -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.
|
// Asserts that the provided start/end are in-bounds.
|
||||||
pub fn sliceArray(
|
pub fn sliceArray(
|
||||||
val: Value,
|
val: Value,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue