aboutsummaryrefslogtreecommitdiff
path: root/src/value.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-03-16 17:33:24 -0700
committerAndrew Kelley <andrew@ziglang.org>2023-03-16 17:33:24 -0700
commit1ed569e0b23c4432cd00604dcae89a17edc852a9 (patch)
tree090e0b3817a0caa4f3e7b99ec1d4d965f2bc7438 /src/value.zig
parent778ca2ae6bf025edb6babeec08c957be1fbb37a5 (diff)
parentb4d58e93ea4d0bbfe674f80d301279d302fe8fc8 (diff)
downloadzig-1ed569e0b23c4432cd00604dcae89a17edc852a9.tar.gz
zig-1ed569e0b23c4432cd00604dcae89a17edc852a9.zip
Merge remote-tracking branch 'origin/master' into llvm16
Diffstat (limited to 'src/value.zig')
-rw-r--r--src/value.zig67
1 files changed, 60 insertions, 7 deletions
diff --git a/src/value.zig b/src/value.zig
index 4a5683df36..e5283d1270 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -1365,6 +1365,17 @@ pub const Value = extern union {
if (val.isDeclRef()) return error.ReinterpretDeclRef;
return val.writeToMemory(Type.usize, mod, buffer);
},
+ .Optional => {
+ assert(ty.isPtrLikeOptional());
+ var buf: Type.Payload.ElemType = undefined;
+ const child = ty.optionalChild(&buf);
+ const opt_val = val.optionalValue();
+ if (opt_val) |some| {
+ return some.writeToMemory(child, mod, buffer);
+ } else {
+ return writeToMemory(Value.zero, Type.usize, mod, buffer);
+ }
+ },
else => @panic("TODO implement writeToMemory for more types"),
}
}
@@ -1471,6 +1482,17 @@ pub const Value = extern union {
if (val.isDeclRef()) return error.ReinterpretDeclRef;
return val.writeToPackedMemory(Type.usize, mod, buffer, bit_offset);
},
+ .Optional => {
+ assert(ty.isPtrLikeOptional());
+ var buf: Type.Payload.ElemType = undefined;
+ const child = ty.optionalChild(&buf);
+ const opt_val = val.optionalValue();
+ if (opt_val) |some| {
+ return some.writeToPackedMemory(child, mod, buffer, bit_offset);
+ } else {
+ return writeToPackedMemory(Value.zero, Type.usize, mod, buffer, bit_offset);
+ }
+ },
else => @panic("TODO implement writeToPackedMemory for more types"),
}
}
@@ -1579,6 +1601,12 @@ pub const Value = extern union {
assert(!ty.isSlice()); // No well defined layout.
return readFromMemory(Type.usize, mod, buffer, arena);
},
+ .Optional => {
+ assert(ty.isPtrLikeOptional());
+ var buf: Type.Payload.ElemType = undefined;
+ const child = ty.optionalChild(&buf);
+ return readFromMemory(child, mod, buffer, arena);
+ },
else => @panic("TODO implement readFromMemory for more types"),
}
}
@@ -1670,6 +1698,12 @@ pub const Value = extern union {
assert(!ty.isSlice()); // No well defined layout.
return readFromPackedMemory(Type.usize, mod, buffer, bit_offset, arena);
},
+ .Optional => {
+ assert(ty.isPtrLikeOptional());
+ var buf: Type.Payload.ElemType = undefined;
+ const child = ty.optionalChild(&buf);
+ return readFromPackedMemory(child, mod, buffer, bit_offset, arena);
+ },
else => @panic("TODO implement readFromPackedMemory for more types"),
}
}
@@ -3144,13 +3178,32 @@ pub const Value = extern union {
/// TODO: check for cases such as array that is not marked undef but all the element
/// values are marked undef, or struct that is not marked undef but all fields are marked
/// undef, etc.
- pub fn anyUndef(self: Value) bool {
- if (self.castTag(.aggregate)) |aggregate| {
- for (aggregate.data) |val| {
- if (val.anyUndef()) return true;
- }
+ pub fn anyUndef(self: Value, mod: *Module) bool {
+ switch (self.tag()) {
+ .slice => {
+ const payload = self.castTag(.slice).?;
+ const len = payload.data.len.toUnsignedInt(mod.getTarget());
+
+ var elem_value_buf: ElemValueBuffer = undefined;
+ var i: usize = 0;
+ while (i < len) : (i += 1) {
+ const elem_val = payload.data.ptr.elemValueBuffer(mod, i, &elem_value_buf);
+ if (elem_val.anyUndef(mod)) return true;
+ }
+ },
+
+ .aggregate => {
+ const payload = self.castTag(.aggregate).?;
+ for (payload.data) |val| {
+ if (val.anyUndef(mod)) return true;
+ }
+ },
+
+ .undef => return true,
+ else => {},
}
- return self.isUndef();
+
+ return false;
}
/// Asserts the value is not undefined and not unreachable.
@@ -3319,7 +3372,7 @@ pub const Value = extern union {
}
}
- fn floatToValue(float: f128, arena: Allocator, dest_ty: Type, target: Target) !Value {
+ pub fn floatToValue(float: f128, arena: Allocator, dest_ty: Type, target: Target) !Value {
switch (dest_ty.floatBits(target)) {
16 => return Value.Tag.float_16.create(arena, @floatCast(f16, float)),
32 => return Value.Tag.float_32.create(arena, @floatCast(f32, float)),