mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
stage2: Add container_ty/elem_ty to elem_ptr, field_ptr, *_payload_ptr Values
This commit is contained in:
parent
a2a5d3c288
commit
bbd750ff05
45
src/Sema.zig
45
src/Sema.zig
@ -5568,7 +5568,10 @@ fn analyzeOptionalPayloadPtr(
|
||||
}
|
||||
return sema.addConstant(
|
||||
child_pointer,
|
||||
try Value.Tag.opt_payload_ptr.create(sema.arena, ptr_val),
|
||||
try Value.Tag.opt_payload_ptr.create(sema.arena, .{
|
||||
.container_ptr = ptr_val,
|
||||
.container_ty = optional_ptr_ty.childType(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
if (try sema.pointerDeref(block, src, ptr_val, optional_ptr_ty)) |val| {
|
||||
@ -5578,7 +5581,10 @@ fn analyzeOptionalPayloadPtr(
|
||||
// The same Value represents the pointer to the optional and the payload.
|
||||
return sema.addConstant(
|
||||
child_pointer,
|
||||
try Value.Tag.opt_payload_ptr.create(sema.arena, ptr_val),
|
||||
try Value.Tag.opt_payload_ptr.create(sema.arena, .{
|
||||
.container_ptr = ptr_val,
|
||||
.container_ty = optional_ptr_ty.childType(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -5733,7 +5739,10 @@ fn analyzeErrUnionPayloadPtr(
|
||||
}
|
||||
return sema.addConstant(
|
||||
operand_pointer_ty,
|
||||
try Value.Tag.eu_payload_ptr.create(sema.arena, ptr_val),
|
||||
try Value.Tag.eu_payload_ptr.create(sema.arena, .{
|
||||
.container_ptr = ptr_val,
|
||||
.container_ty = operand_ty.elemType(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
if (try sema.pointerDeref(block, src, ptr_val, operand_ty)) |val| {
|
||||
@ -5743,7 +5752,10 @@ fn analyzeErrUnionPayloadPtr(
|
||||
|
||||
return sema.addConstant(
|
||||
operand_pointer_ty,
|
||||
try Value.Tag.eu_payload_ptr.create(sema.arena, ptr_val),
|
||||
try Value.Tag.eu_payload_ptr.create(sema.arena, .{
|
||||
.container_ptr = ptr_val,
|
||||
.container_ty = operand_ty.elemType(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -6652,6 +6664,7 @@ fn zirSwitchCapture(
|
||||
field_ty_ptr,
|
||||
try Value.Tag.field_ptr.create(sema.arena, .{
|
||||
.container_ptr = op_ptr_val,
|
||||
.container_ty = operand_ty,
|
||||
.field_index = field_index,
|
||||
}),
|
||||
);
|
||||
@ -9638,7 +9651,7 @@ fn analyzePtrArithmetic(
|
||||
if (air_tag == .ptr_sub) {
|
||||
return sema.fail(block, op_src, "TODO implement Sema comptime pointer subtraction", .{});
|
||||
}
|
||||
const new_ptr_val = try ptr_val.elemPtr(sema.arena, offset_int);
|
||||
const new_ptr_val = try ptr_val.elemPtr(ptr_ty, sema.arena, offset_int);
|
||||
return sema.addConstant(new_ptr_ty, new_ptr_val);
|
||||
} else break :rs offset_src;
|
||||
} else break :rs ptr_src;
|
||||
@ -15903,6 +15916,7 @@ fn finishFieldCallBind(
|
||||
ptr_field_ty,
|
||||
try Value.Tag.field_ptr.create(arena, .{
|
||||
.container_ptr = struct_ptr_val,
|
||||
.container_ty = ptr_ty.childType(),
|
||||
.field_index = field_index,
|
||||
}),
|
||||
);
|
||||
@ -16065,6 +16079,7 @@ fn structFieldPtrByIndex(
|
||||
ptr_field_ty,
|
||||
try Value.Tag.field_ptr.create(sema.arena, .{
|
||||
.container_ptr = struct_ptr_val,
|
||||
.container_ty = struct_ptr_ty.childType(),
|
||||
.field_index = field_index,
|
||||
}),
|
||||
);
|
||||
@ -16241,6 +16256,7 @@ fn unionFieldPtr(
|
||||
ptr_field_ty,
|
||||
try Value.Tag.field_ptr.create(arena, .{
|
||||
.container_ptr = union_ptr_val,
|
||||
.container_ty = union_ty,
|
||||
.field_index = field_index,
|
||||
}),
|
||||
);
|
||||
@ -16333,7 +16349,7 @@ fn elemPtr(
|
||||
const runtime_src = if (maybe_slice_val) |slice_val| rs: {
|
||||
const index_val = maybe_index_val orelse break :rs elem_index_src;
|
||||
const index = @intCast(usize, index_val.toUnsignedInt());
|
||||
const elem_ptr = try slice_val.elemPtr(sema.arena, index);
|
||||
const elem_ptr = try slice_val.elemPtr(array_ty, sema.arena, index);
|
||||
return sema.addConstant(result_ty, elem_ptr);
|
||||
} else array_ptr_src;
|
||||
|
||||
@ -16348,7 +16364,7 @@ fn elemPtr(
|
||||
const ptr_val = maybe_ptr_val orelse break :rs array_ptr_src;
|
||||
const index_val = maybe_index_val orelse break :rs elem_index_src;
|
||||
const index = @intCast(usize, index_val.toUnsignedInt());
|
||||
const elem_ptr = try ptr_val.elemPtr(sema.arena, index);
|
||||
const elem_ptr = try ptr_val.elemPtr(array_ty, sema.arena, index);
|
||||
return sema.addConstant(result_ty, elem_ptr);
|
||||
};
|
||||
|
||||
@ -16473,6 +16489,7 @@ fn tupleFieldPtr(
|
||||
ptr_field_ty,
|
||||
try Value.Tag.field_ptr.create(sema.arena, .{
|
||||
.container_ptr = tuple_ptr_val,
|
||||
.container_ty = tuple_ty,
|
||||
.field_index = field_index,
|
||||
}),
|
||||
);
|
||||
@ -16563,7 +16580,7 @@ fn elemPtrArray(
|
||||
const index_u64 = index_val.toUnsignedInt();
|
||||
// @intCast here because it would have been impossible to construct a value that
|
||||
// required a larger index.
|
||||
const elem_ptr = try array_ptr_val.elemPtr(sema.arena, @intCast(usize, index_u64));
|
||||
const elem_ptr = try array_ptr_val.elemPtr(array_ptr_ty, sema.arena, @intCast(usize, index_u64));
|
||||
return sema.addConstant(result_ty, elem_ptr);
|
||||
}
|
||||
}
|
||||
@ -17757,8 +17774,8 @@ fn beginComptimePtrMutation(
|
||||
}
|
||||
},
|
||||
.eu_payload_ptr => {
|
||||
const eu_ptr_val = ptr_val.castTag(.eu_payload_ptr).?.data;
|
||||
var parent = try beginComptimePtrMutation(sema, block, src, eu_ptr_val);
|
||||
const eu_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
|
||||
var parent = try beginComptimePtrMutation(sema, block, src, eu_ptr.container_ptr);
|
||||
const payload_ty = parent.ty.errorUnionPayload();
|
||||
switch (parent.val.tag()) {
|
||||
else => {
|
||||
@ -17790,8 +17807,8 @@ fn beginComptimePtrMutation(
|
||||
}
|
||||
},
|
||||
.opt_payload_ptr => {
|
||||
const opt_ptr_val = ptr_val.castTag(.opt_payload_ptr).?.data;
|
||||
var parent = try beginComptimePtrMutation(sema, block, src, opt_ptr_val);
|
||||
const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
|
||||
var parent = try beginComptimePtrMutation(sema, block, src, opt_ptr.container_ptr);
|
||||
const payload_ty = try parent.ty.optionalChildAlloc(sema.arena);
|
||||
switch (parent.val.tag()) {
|
||||
.undef, .null_value => {
|
||||
@ -17965,7 +17982,7 @@ fn beginComptimePtrLoad(
|
||||
},
|
||||
.eu_payload_ptr => {
|
||||
const err_union_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
|
||||
const parent = try beginComptimePtrLoad(sema, block, src, err_union_ptr);
|
||||
const parent = try beginComptimePtrLoad(sema, block, src, err_union_ptr.container_ptr);
|
||||
return ComptimePtrLoadKit{
|
||||
.root_val = parent.root_val,
|
||||
.root_ty = parent.root_ty,
|
||||
@ -17977,7 +17994,7 @@ fn beginComptimePtrLoad(
|
||||
},
|
||||
.opt_payload_ptr => {
|
||||
const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
|
||||
const parent = try beginComptimePtrLoad(sema, block, src, opt_ptr);
|
||||
const parent = try beginComptimePtrLoad(sema, block, src, opt_ptr.container_ptr);
|
||||
return ComptimePtrLoadKit{
|
||||
.root_val = parent.root_val,
|
||||
.root_ty = parent.root_ty,
|
||||
|
||||
@ -2901,7 +2901,7 @@ pub const DeclGen = struct {
|
||||
},
|
||||
.opt_payload_ptr => {
|
||||
const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
|
||||
const parent = try dg.lowerParentPtr(opt_payload_ptr, base_ty);
|
||||
const parent = try dg.lowerParentPtr(opt_payload_ptr.container_ptr, base_ty);
|
||||
var buf: Type.Payload.ElemType = undefined;
|
||||
const payload_ty = parent.ty.optionalChild(&buf);
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime() or parent.ty.isPtrLikeOptional()) {
|
||||
@ -2925,7 +2925,7 @@ pub const DeclGen = struct {
|
||||
},
|
||||
.eu_payload_ptr => {
|
||||
const eu_payload_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
|
||||
const parent = try dg.lowerParentPtr(eu_payload_ptr, base_ty);
|
||||
const parent = try dg.lowerParentPtr(eu_payload_ptr.container_ptr, base_ty);
|
||||
const payload_ty = parent.ty.errorUnionPayload();
|
||||
if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
|
||||
// In this case, we represent pointer to error union the same as pointer
|
||||
|
||||
@ -268,12 +268,14 @@ pub const Value = extern union {
|
||||
|
||||
.repeated,
|
||||
.eu_payload,
|
||||
.eu_payload_ptr,
|
||||
.opt_payload,
|
||||
.opt_payload_ptr,
|
||||
.empty_array_sentinel,
|
||||
=> Payload.SubValue,
|
||||
|
||||
.eu_payload_ptr,
|
||||
.opt_payload_ptr,
|
||||
=> Payload.PayloadPtr,
|
||||
|
||||
.bytes,
|
||||
.enum_literal,
|
||||
=> Payload.Bytes,
|
||||
@ -479,6 +481,20 @@ pub const Value = extern union {
|
||||
.variable => return self.copyPayloadShallow(arena, Payload.Variable),
|
||||
.decl_ref => return self.copyPayloadShallow(arena, Payload.Decl),
|
||||
.decl_ref_mut => return self.copyPayloadShallow(arena, Payload.DeclRefMut),
|
||||
.eu_payload_ptr,
|
||||
.opt_payload_ptr,
|
||||
=> {
|
||||
const payload = self.cast(Payload.PayloadPtr).?;
|
||||
const new_payload = try arena.create(Payload.PayloadPtr);
|
||||
new_payload.* = .{
|
||||
.base = payload.base,
|
||||
.data = .{
|
||||
.container_ptr = try payload.data.container_ptr.copy(arena),
|
||||
.container_ty = try payload.data.container_ty.copy(arena),
|
||||
},
|
||||
};
|
||||
return Value{ .ptr_otherwise = &new_payload.base };
|
||||
},
|
||||
.elem_ptr => {
|
||||
const payload = self.castTag(.elem_ptr).?;
|
||||
const new_payload = try arena.create(Payload.ElemPtr);
|
||||
@ -486,6 +502,7 @@ pub const Value = extern union {
|
||||
.base = payload.base,
|
||||
.data = .{
|
||||
.array_ptr = try payload.data.array_ptr.copy(arena),
|
||||
.elem_ty = try payload.data.elem_ty.copy(arena),
|
||||
.index = payload.data.index,
|
||||
},
|
||||
};
|
||||
@ -498,6 +515,7 @@ pub const Value = extern union {
|
||||
.base = payload.base,
|
||||
.data = .{
|
||||
.container_ptr = try payload.data.container_ptr.copy(arena),
|
||||
.container_ty = try payload.data.container_ty.copy(arena),
|
||||
.field_index = payload.data.field_index,
|
||||
},
|
||||
};
|
||||
@ -506,9 +524,7 @@ pub const Value = extern union {
|
||||
.bytes => return self.copyPayloadShallow(arena, Payload.Bytes),
|
||||
.repeated,
|
||||
.eu_payload,
|
||||
.eu_payload_ptr,
|
||||
.opt_payload,
|
||||
.opt_payload_ptr,
|
||||
.empty_array_sentinel,
|
||||
=> {
|
||||
const payload = self.cast(Payload.SubValue).?;
|
||||
@ -740,11 +756,11 @@ pub const Value = extern union {
|
||||
.inferred_alloc_comptime => return out_stream.writeAll("(inferred comptime allocation value)"),
|
||||
.eu_payload_ptr => {
|
||||
try out_stream.writeAll("(eu_payload_ptr)");
|
||||
val = val.castTag(.eu_payload_ptr).?.data;
|
||||
val = val.castTag(.eu_payload_ptr).?.data.container_ptr;
|
||||
},
|
||||
.opt_payload_ptr => {
|
||||
try out_stream.writeAll("(opt_payload_ptr)");
|
||||
val = val.castTag(.opt_payload_ptr).?.data;
|
||||
val = val.castTag(.opt_payload_ptr).?.data.container_ptr;
|
||||
},
|
||||
.bound_fn => {
|
||||
const bound_func = val.castTag(.bound_fn).?.data;
|
||||
@ -2162,8 +2178,8 @@ pub const Value = extern union {
|
||||
.decl_ref_mut => true,
|
||||
.elem_ptr => isComptimeMutablePtr(val.castTag(.elem_ptr).?.data.array_ptr),
|
||||
.field_ptr => isComptimeMutablePtr(val.castTag(.field_ptr).?.data.container_ptr),
|
||||
.eu_payload_ptr => isComptimeMutablePtr(val.castTag(.eu_payload_ptr).?.data),
|
||||
.opt_payload_ptr => isComptimeMutablePtr(val.castTag(.opt_payload_ptr).?.data),
|
||||
.eu_payload_ptr => isComptimeMutablePtr(val.castTag(.eu_payload_ptr).?.data.container_ptr),
|
||||
.opt_payload_ptr => isComptimeMutablePtr(val.castTag(.opt_payload_ptr).?.data.container_ptr),
|
||||
|
||||
else => false,
|
||||
};
|
||||
@ -2174,9 +2190,9 @@ pub const Value = extern union {
|
||||
switch (val.tag()) {
|
||||
.repeated => return val.castTag(.repeated).?.data.canMutateComptimeVarState(),
|
||||
.eu_payload => return val.castTag(.eu_payload).?.data.canMutateComptimeVarState(),
|
||||
.eu_payload_ptr => return val.castTag(.eu_payload_ptr).?.data.canMutateComptimeVarState(),
|
||||
.eu_payload_ptr => return val.castTag(.eu_payload_ptr).?.data.container_ptr.canMutateComptimeVarState(),
|
||||
.opt_payload => return val.castTag(.opt_payload).?.data.canMutateComptimeVarState(),
|
||||
.opt_payload_ptr => return val.castTag(.opt_payload_ptr).?.data.canMutateComptimeVarState(),
|
||||
.opt_payload_ptr => return val.castTag(.opt_payload_ptr).?.data.container_ptr.canMutateComptimeVarState(),
|
||||
.aggregate => {
|
||||
const fields = val.castTag(.aggregate).?.data;
|
||||
for (fields) |field| {
|
||||
@ -2239,12 +2255,12 @@ pub const Value = extern union {
|
||||
.eu_payload_ptr => {
|
||||
const err_union_ptr = ptr_val.castTag(.eu_payload_ptr).?.data;
|
||||
std.hash.autoHash(hasher, Value.Tag.eu_payload_ptr);
|
||||
hashPtr(err_union_ptr, hasher);
|
||||
hashPtr(err_union_ptr.container_ptr, hasher);
|
||||
},
|
||||
.opt_payload_ptr => {
|
||||
const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data;
|
||||
std.hash.autoHash(hasher, Value.Tag.opt_payload_ptr);
|
||||
hashPtr(opt_ptr, hasher);
|
||||
hashPtr(opt_ptr.container_ptr, hasher);
|
||||
},
|
||||
|
||||
.zero,
|
||||
@ -2272,12 +2288,14 @@ pub const Value = extern union {
|
||||
|
||||
.repeated,
|
||||
.eu_payload,
|
||||
.eu_payload_ptr,
|
||||
.opt_payload,
|
||||
.opt_payload_ptr,
|
||||
.empty_array_sentinel,
|
||||
=> return markReferencedDeclsAlive(val.cast(Payload.SubValue).?.data),
|
||||
|
||||
.eu_payload_ptr,
|
||||
.opt_payload_ptr,
|
||||
=> return markReferencedDeclsAlive(val.cast(Payload.PayloadPtr).?.data.container_ptr),
|
||||
|
||||
.slice => {
|
||||
const slice = val.cast(Payload.Slice).?.data;
|
||||
markReferencedDeclsAlive(slice.ptr);
|
||||
@ -2422,36 +2440,28 @@ pub const Value = extern union {
|
||||
}
|
||||
|
||||
/// Returns a pointer to the element value at the index.
|
||||
pub fn elemPtr(val: Value, arena: Allocator, index: usize) Allocator.Error!Value {
|
||||
switch (val.tag()) {
|
||||
.elem_ptr => {
|
||||
const elem_ptr = val.castTag(.elem_ptr).?.data;
|
||||
pub fn elemPtr(val: Value, ty: Type, arena: Allocator, index: usize) Allocator.Error!Value {
|
||||
const elem_ty = ty.elemType2();
|
||||
const ptr_val = switch (val.tag()) {
|
||||
.slice => val.slicePtr(),
|
||||
else => val,
|
||||
};
|
||||
|
||||
if (ptr_val.tag() == .elem_ptr) {
|
||||
const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
|
||||
if (elem_ptr.elem_ty.eql(elem_ty)) {
|
||||
return Tag.elem_ptr.create(arena, .{
|
||||
.array_ptr = elem_ptr.array_ptr,
|
||||
.elem_ty = elem_ptr.elem_ty,
|
||||
.index = elem_ptr.index + index,
|
||||
});
|
||||
},
|
||||
.slice => {
|
||||
const ptr_val = val.castTag(.slice).?.data.ptr;
|
||||
switch (ptr_val.tag()) {
|
||||
.elem_ptr => {
|
||||
const elem_ptr = ptr_val.castTag(.elem_ptr).?.data;
|
||||
return Tag.elem_ptr.create(arena, .{
|
||||
.array_ptr = elem_ptr.array_ptr,
|
||||
.index = elem_ptr.index + index,
|
||||
});
|
||||
},
|
||||
else => return Tag.elem_ptr.create(arena, .{
|
||||
.array_ptr = ptr_val,
|
||||
.index = index,
|
||||
}),
|
||||
}
|
||||
},
|
||||
else => return Tag.elem_ptr.create(arena, .{
|
||||
.array_ptr = val,
|
||||
.index = index,
|
||||
}),
|
||||
}
|
||||
}
|
||||
return Tag.elem_ptr.create(arena, .{
|
||||
.array_ptr = ptr_val,
|
||||
.elem_ty = elem_ty,
|
||||
.index = index,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn isUndef(self: Value) bool {
|
||||
@ -4144,12 +4154,21 @@ pub const Value = extern union {
|
||||
};
|
||||
};
|
||||
|
||||
pub const PayloadPtr = struct {
|
||||
base: Payload,
|
||||
data: struct {
|
||||
container_ptr: Value,
|
||||
container_ty: Type,
|
||||
},
|
||||
};
|
||||
|
||||
pub const ElemPtr = struct {
|
||||
pub const base_tag = Tag.elem_ptr;
|
||||
|
||||
base: Payload = Payload{ .tag = base_tag },
|
||||
data: struct {
|
||||
array_ptr: Value,
|
||||
elem_ty: Type,
|
||||
index: usize,
|
||||
},
|
||||
};
|
||||
@ -4160,6 +4179,7 @@ pub const Value = extern union {
|
||||
base: Payload = Payload{ .tag = base_tag },
|
||||
data: struct {
|
||||
container_ptr: Value,
|
||||
container_ty: Type,
|
||||
field_index: usize,
|
||||
},
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user