diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-03-16 17:33:24 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-03-16 17:33:24 -0700 |
| commit | 1ed569e0b23c4432cd00604dcae89a17edc852a9 (patch) | |
| tree | 090e0b3817a0caa4f3e7b99ec1d4d965f2bc7438 /src/value.zig | |
| parent | 778ca2ae6bf025edb6babeec08c957be1fbb37a5 (diff) | |
| parent | b4d58e93ea4d0bbfe674f80d301279d302fe8fc8 (diff) | |
| download | zig-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.zig | 67 |
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)), |
