aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2021-10-21 16:54:34 +0200
committerRobin Voetter <robin@voetter.nl>2021-10-21 17:29:42 +0200
commitfc034ca94f0682a06795616992f176f19ec9a83d (patch)
tree162caa58d75510d751b0da4807a8dbee0473a352 /src/Sema.zig
parent09c7d5aebc4f7fe96a89f93c0cf99cc03977ea5f (diff)
downloadzig-fc034ca94f0682a06795616992f176f19ec9a83d.tar.gz
zig-fc034ca94f0682a06795616992f176f19ec9a83d.zip
stage2: comptime elemVal and elemPtr for Many/C pointers
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig82
1 files changed, 57 insertions, 25 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 5a77f81aa0..b01e4539b0 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -351,6 +351,24 @@ pub const Block = struct {
});
}
+ pub fn addPtrElemPtr(
+ block: *Block,
+ array_ptr: Air.Inst.Ref,
+ elem_index: Air.Inst.Ref,
+ elem_ptr_ty: Type,
+ ) !Air.Inst.Ref {
+ return block.addInst(.{
+ .tag = .ptr_elem_ptr,
+ .data = .{ .ty_pl = .{
+ .ty = try block.sema.addType(elem_ptr_ty),
+ .payload = try block.sema.addExtra(Air.Bin{
+ .lhs = array_ptr,
+ .rhs = elem_index,
+ }),
+ } },
+ });
+ }
+
pub fn addInst(block: *Block, inst: Air.Inst) error{OutOfMemory}!Air.Inst.Ref {
return Air.indexToRef(try block.addInstAsIndex(inst));
}
@@ -11500,10 +11518,10 @@ fn elemPtr(
switch (array_ty.zigTypeTag()) {
.Pointer => {
// In all below cases, we have to deref the ptr operand to get the actual array pointer.
- const array = try sema.analyzeLoad(block, src, array_ptr, array_ptr_src);
+ const array = try sema.analyzeLoad(block, array_ptr_src, array_ptr, array_ptr_src);
+ const result_ty = try array_ty.elemPtrType(sema.arena);
switch (array_ty.ptrSize()) {
.Slice => {
- const result_ty = try array_ty.elemPtrType(sema.arena);
const maybe_slice_val = try sema.resolveDefinedValue(block, array_ptr_src, array);
const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
const runtime_src = if (maybe_slice_val) |slice_val| rs: {
@@ -11516,14 +11534,28 @@ fn elemPtr(
try sema.requireRuntimeBlock(block, runtime_src);
return block.addSliceElemPtr(array, elem_index, result_ty);
},
- .Many, .C => return sema.fail(block, src, "TODO implement Sema for elemPtr for many/c pointer", .{}),
+ .Many, .C => {
+ const maybe_ptr_val = try sema.resolveDefinedValue(block, array_ptr_src, array);
+ const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
+
+ const runtime_src = rs: {
+ 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);
+ return sema.addConstant(result_ty, elem_ptr);
+ };
+
+ try sema.requireRuntimeBlock(block, runtime_src);
+ return block.addPtrElemPtr(array, elem_index, result_ty);
+ },
.One => {
assert(array_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable
- return sema.elemPtrArray(block, src, array, elem_index, elem_index_src);
+ return sema.elemPtrArray(block, array_ptr_src, array, elem_index, elem_index_src);
},
}
},
- .Array => return sema.elemPtrArray(block, src, array_ptr, elem_index, elem_index_src),
+ .Array => return sema.elemPtrArray(block, array_ptr_src, array_ptr, elem_index, elem_index_src),
.Vector => return sema.fail(block, src, "TODO implement Sema for elemPtr for vector", .{}),
else => unreachable,
}
@@ -11560,21 +11592,30 @@ fn elemVal(
return block.addBinOp(.slice_elem_val, array, elem_index);
},
.Many, .C => {
- if (try sema.resolveDefinedValue(block, src, array)) |ptr_val| {
- _ = ptr_val;
- return sema.fail(block, src, "TODO implement Sema for elemVal for comptime known pointer", .{});
- }
- try sema.requireRuntimeBlock(block, src);
+ const maybe_ptr_val = try sema.resolveDefinedValue(block, array_src, array);
+ const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
+
+ const runtime_src = rs: {
+ const ptr_val = maybe_ptr_val orelse break :rs array_src;
+ const index_val = maybe_index_val orelse break :rs elem_index_src;
+ const index = @intCast(usize, index_val.toUnsignedInt());
+ const maybe_array_val = try ptr_val.pointerDeref(sema.arena);
+ const array_val = maybe_array_val orelse break :rs array_src;
+ const elem_val = try array_val.elemValue(sema.arena, index);
+ return sema.addConstant(array_ty.elemType2(), elem_val);
+ };
+
+ try sema.requireRuntimeBlock(block, runtime_src);
return block.addBinOp(.ptr_elem_val, array, elem_index);
},
.One => {
assert(array_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable
- const elem_ptr = try sema.elemPtr(block, src, array, elem_index, elem_index_src);
- return sema.analyzeLoad(block, src, elem_ptr, elem_index_src);
+ const elem_ptr = try sema.elemPtr(block, array_src, array, elem_index, elem_index_src);
+ return sema.analyzeLoad(block, array_src, elem_ptr, elem_index_src);
},
},
.Array => {
- if (try sema.resolveMaybeUndefVal(block, src, array)) |array_val| {
+ if (try sema.resolveMaybeUndefVal(block, array_src, array)) |array_val| {
const elem_ty = array_ty.childType();
if (array_val.isUndef()) return sema.addConstUndef(elem_ty);
const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
@@ -11584,10 +11625,10 @@ fn elemVal(
return sema.addConstant(elem_ty, elem_val);
}
}
- try sema.requireRuntimeBlock(block, src);
+ try sema.requireRuntimeBlock(block, array_src);
return block.addBinOp(.array_elem_val, array, elem_index);
},
- .Vector => return sema.fail(block, src, "TODO implement Sema for elemVal for vector", .{}),
+ .Vector => return sema.fail(block, array_src, "TODO implement Sema for elemVal for vector", .{}),
else => unreachable,
}
}
@@ -11615,16 +11656,7 @@ fn elemPtrArray(
}
// TODO safety check for array bounds
try sema.requireRuntimeBlock(block, src);
- return block.addInst(.{
- .tag = .ptr_elem_ptr,
- .data = .{ .ty_pl = .{
- .ty = try sema.addType(result_ty),
- .payload = try sema.addExtra(Air.Bin{
- .lhs = array_ptr,
- .rhs = elem_index,
- }),
- } },
- });
+ return block.addPtrElemPtr(array_ptr, elem_index, result_ty);
}
fn coerce(