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:
Cody Tapscott 2022-07-30 06:34:49 -07:00 committed by Andrew Kelley
parent 8632e4fc7b
commit c0a1b4fa46
2 changed files with 30 additions and 4 deletions

View file

@ -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,10 +158,13 @@ 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()) {
.Packed => val.castTag(.aggregate).?.data[i],
else => ty.structFieldValueComptime(i) orelse b: {
const vals = val.castTag(.aggregate).?.data; const vals = val.castTag(.aggregate).?.data;
break :b vals[i]; break :b vals[i];
}, },
},
}, writer, level - 1, mod); }, writer, level - 1, mod);
} }
if (ty.structFieldCount() > max_aggregate_items) { if (ty.structFieldCount() > max_aggregate_items) {
@ -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);

View file

@ -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,