diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-05-05 18:07:43 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-06-10 20:42:28 -0700 |
| commit | ce3cffbd5a00a6ae44ec3f2c6550de1c52c293c4 (patch) | |
| tree | d1e44eae010ba81b362e5342d0530ced3ab71cc7 /src | |
| parent | 0471638734257d479d21abcb490ed9459df42b9b (diff) | |
| download | zig-ce3cffbd5a00a6ae44ec3f2c6550de1c52c293c4.tar.gz zig-ce3cffbd5a00a6ae44ec3f2c6550de1c52c293c4.zip | |
fill out more InternPool Type methods
particularly, printing types
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 32 | ||||
| -rw-r--r-- | src/print_air.zig | 2 | ||||
| -rw-r--r-- | src/type.zig | 208 | ||||
| -rw-r--r-- | src/value.zig | 64 |
4 files changed, 206 insertions, 100 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 39f39b43d9..088d830280 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -31485,11 +31485,18 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) { .int_type => false, - .ptr_type => @panic("TODO"), - .array_type => @panic("TODO"), + .ptr_type => |ptr_type| { + const child_ty = ptr_type.elem_type.toType(); + if (child_ty.zigTypeTag(mod) == .Fn) { + return child_ty.fnInfo().is_generic; + } else { + return sema.resolveTypeRequiresComptime(child_ty); + } + }, + .array_type => |array_type| return sema.resolveTypeRequiresComptime(array_type.child.toType()), .vector_type => |vector_type| return sema.resolveTypeRequiresComptime(vector_type.child.toType()), - .opt_type => @panic("TODO"), - .error_union_type => @panic("TODO"), + .opt_type => |child| return sema.resolveTypeRequiresComptime(child.toType()), + .error_union_type => |error_union_type| return sema.resolveTypeRequiresComptime(error_union_type.payload_type.toType()), .simple_type => |t| switch (t) { .f16, .f32, @@ -33528,11 +33535,20 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { if (ty.ip_index != .none) { switch (mod.intern_pool.indexToKey(ty.ip_index)) { .int_type => return false, - .ptr_type => @panic("TODO"), - .array_type => @panic("TODO"), + .ptr_type => |ptr_type| { + const child_ty = ptr_type.elem_type.toType(); + if (child_ty.zigTypeTag(mod) == .Fn) { + return child_ty.fnInfo().is_generic; + } else { + return sema.typeRequiresComptime(child_ty); + } + }, + .array_type => |array_type| return sema.typeRequiresComptime(array_type.child.toType()), .vector_type => |vector_type| return sema.typeRequiresComptime(vector_type.child.toType()), - .opt_type => @panic("TODO"), - .error_union_type => @panic("TODO"), + .opt_type => |child| return sema.typeRequiresComptime(child.toType()), + .error_union_type => |error_union_type| { + return sema.typeRequiresComptime(error_union_type.payload_type.toType()); + }, .simple_type => |t| return switch (t) { .f16, .f32, diff --git a/src/print_air.zig b/src/print_air.zig index 4396a26f44..a1f277870e 100644 --- a/src/print_air.zig +++ b/src/print_air.zig @@ -95,7 +95,7 @@ const Writer = struct { for (w.air.instructions.items(.tag), 0..) |tag, i| { const inst = @intCast(Air.Inst.Index, i); switch (tag) { - .constant, .const_ty => { + .constant, .const_ty, .interned => { try w.writeInst(s, inst); try s.writeByte('\n'); }, diff --git a/src/type.zig b/src/type.zig index db8c116f70..cbc0b5bcea 100644 --- a/src/type.zig +++ b/src/type.zig @@ -1274,11 +1274,77 @@ pub const Type = struct { }; return writer.print("{c}{d}", .{ sign_char, int_type.bits }); }, - .ptr_type => @panic("TODO"), - .array_type => @panic("TODO"), - .vector_type => @panic("TODO"), - .opt_type => @panic("TODO"), - .error_union_type => @panic("TODO"), + .ptr_type => { + const info = ty.ptrInfo(mod); + + if (info.sentinel) |s| switch (info.size) { + .One, .C => unreachable, + .Many => try writer.print("[*:{}]", .{s.fmtValue(info.pointee_type, mod)}), + .Slice => try writer.print("[:{}]", .{s.fmtValue(info.pointee_type, mod)}), + } else switch (info.size) { + .One => try writer.writeAll("*"), + .Many => try writer.writeAll("[*]"), + .C => try writer.writeAll("[*c]"), + .Slice => try writer.writeAll("[]"), + } + if (info.@"align" != 0 or info.host_size != 0 or info.vector_index != .none) { + if (info.@"align" != 0) { + try writer.print("align({d}", .{info.@"align"}); + } else { + const alignment = info.pointee_type.abiAlignment(mod); + try writer.print("align({d}", .{alignment}); + } + + if (info.bit_offset != 0 or info.host_size != 0) { + try writer.print(":{d}:{d}", .{ info.bit_offset, info.host_size }); + } + if (info.vector_index == .runtime) { + try writer.writeAll(":?"); + } else if (info.vector_index != .none) { + try writer.print(":{d}", .{@enumToInt(info.vector_index)}); + } + try writer.writeAll(") "); + } + if (info.@"addrspace" != .generic) { + try writer.print("addrspace(.{s}) ", .{@tagName(info.@"addrspace")}); + } + if (!info.mutable) try writer.writeAll("const "); + if (info.@"volatile") try writer.writeAll("volatile "); + if (info.@"allowzero" and info.size != .C) try writer.writeAll("allowzero "); + + try print(info.pointee_type, writer, mod); + return; + }, + .array_type => |array_type| { + if (array_type.sentinel == .none) { + try writer.print("[{d}]", .{array_type.len}); + try print(array_type.child.toType(), writer, mod); + } else { + try writer.print("[{d}:{}]", .{ + array_type.len, + array_type.sentinel.toValue().fmtValue(array_type.child.toType(), mod), + }); + try print(array_type.child.toType(), writer, mod); + } + return; + }, + .vector_type => |vector_type| { + try writer.print("@Vector({d}, ", .{vector_type.len}); + try print(vector_type.child.toType(), writer, mod); + try writer.writeAll(")"); + return; + }, + .opt_type => |child| { + try writer.writeByte('?'); + try print(child.toType(), writer, mod); + return; + }, + .error_union_type => |error_union_type| { + try print(error_union_type.error_set_type.toType(), writer, mod); + try writer.writeByte('!'); + try print(error_union_type.payload_type.toType(), writer, mod); + return; + }, .simple_type => |s| return writer.writeAll(@tagName(s)), .struct_type => @panic("TODO"), .union_type => @panic("TODO"), @@ -2055,8 +2121,8 @@ pub const Type = struct { return AbiAlignmentAdvanced{ .scalar = alignment }; }, - .opt_type => @panic("TODO"), - .error_union_type => @panic("TODO"), + .opt_type => return abiAlignmentAdvancedOptional(ty, mod, strat), + .error_union_type => return abiAlignmentAdvancedErrorUnion(ty, mod, strat), .simple_type => |t| switch (t) { .bool, .atomic_order, @@ -2157,64 +2223,8 @@ pub const Type = struct { .array, .array_sentinel => return ty.childType(mod).abiAlignmentAdvanced(mod, strat), - .optional => { - const child_type = ty.optionalChild(mod); - - switch (child_type.zigTypeTag(mod)) { - .Pointer => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, - .ErrorSet => return abiAlignmentAdvanced(Type.anyerror, mod, strat), - .NoReturn => return AbiAlignmentAdvanced{ .scalar = 0 }, - else => {}, - } - - switch (strat) { - .eager, .sema => { - if (!(child_type.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) { - error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) }, - else => |e| return e, - })) { - return AbiAlignmentAdvanced{ .scalar = 1 }; - } - return child_type.abiAlignmentAdvanced(mod, strat); - }, - .lazy => |arena| switch (try child_type.abiAlignmentAdvanced(mod, strat)) { - .scalar => |x| return AbiAlignmentAdvanced{ .scalar = @max(x, 1) }, - .val => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) }, - }, - } - }, - - .error_union => { - // This code needs to be kept in sync with the equivalent switch prong - // in abiSizeAdvanced. - const data = ty.castTag(.error_union).?.data; - const code_align = abiAlignment(Type.anyerror, mod); - switch (strat) { - .eager, .sema => { - if (!(data.payload.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) { - error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) }, - else => |e| return e, - })) { - return AbiAlignmentAdvanced{ .scalar = code_align }; - } - return AbiAlignmentAdvanced{ .scalar = @max( - code_align, - (try data.payload.abiAlignmentAdvanced(mod, strat)).scalar, - ) }; - }, - .lazy => |arena| { - switch (try data.payload.abiAlignmentAdvanced(mod, strat)) { - .scalar => |payload_align| { - return AbiAlignmentAdvanced{ - .scalar = @max(code_align, payload_align), - }; - }, - .val => {}, - } - return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) }; - }, - } - }, + .optional => return abiAlignmentAdvancedOptional(ty, mod, strat), + .error_union => return abiAlignmentAdvancedErrorUnion(ty, mod, strat), .@"struct" => { const struct_obj = ty.castTag(.@"struct").?.data; @@ -2321,6 +2331,74 @@ pub const Type = struct { } } + fn abiAlignmentAdvancedErrorUnion( + ty: Type, + mod: *const Module, + strat: AbiAlignmentAdvancedStrat, + ) Module.CompileError!AbiAlignmentAdvanced { + // This code needs to be kept in sync with the equivalent switch prong + // in abiSizeAdvanced. + const data = ty.castTag(.error_union).?.data; + const code_align = abiAlignment(Type.anyerror, mod); + switch (strat) { + .eager, .sema => { + if (!(data.payload.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) { + error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) }, + else => |e| return e, + })) { + return AbiAlignmentAdvanced{ .scalar = code_align }; + } + return AbiAlignmentAdvanced{ .scalar = @max( + code_align, + (try data.payload.abiAlignmentAdvanced(mod, strat)).scalar, + ) }; + }, + .lazy => |arena| { + switch (try data.payload.abiAlignmentAdvanced(mod, strat)) { + .scalar => |payload_align| { + return AbiAlignmentAdvanced{ + .scalar = @max(code_align, payload_align), + }; + }, + .val => {}, + } + return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) }; + }, + } + } + + fn abiAlignmentAdvancedOptional( + ty: Type, + mod: *const Module, + strat: AbiAlignmentAdvancedStrat, + ) Module.CompileError!AbiAlignmentAdvanced { + const target = mod.getTarget(); + const child_type = ty.optionalChild(mod); + + switch (child_type.zigTypeTag(mod)) { + .Pointer => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, + .ErrorSet => return abiAlignmentAdvanced(Type.anyerror, mod, strat), + .NoReturn => return AbiAlignmentAdvanced{ .scalar = 0 }, + else => {}, + } + + switch (strat) { + .eager, .sema => { + if (!(child_type.hasRuntimeBitsAdvanced(mod, false, strat) catch |err| switch (err) { + error.NeedLazy => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(strat.lazy, ty) }, + else => |e| return e, + })) { + return AbiAlignmentAdvanced{ .scalar = 1 }; + } + return child_type.abiAlignmentAdvanced(mod, strat); + }, + .lazy => |arena| switch (try child_type.abiAlignmentAdvanced(mod, strat)) { + .scalar => |x| return AbiAlignmentAdvanced{ .scalar = @max(x, 1) }, + .val => return AbiAlignmentAdvanced{ .val = try Value.Tag.lazy_align.create(arena, ty) }, + }, + } + } + pub fn abiAlignmentAdvancedUnion( ty: Type, mod: *const Module, diff --git a/src/value.zig b/src/value.zig index 588218f670..a34a022dea 100644 --- a/src/value.zig +++ b/src/value.zig @@ -1848,8 +1848,6 @@ pub const Value = struct { /// Asserts the value is comparable. /// If opt_sema is null then this function asserts things are resolved and cannot fail. pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *const Module, opt_sema: ?*Sema) !std.math.Order { - const lhs_tag = lhs.tag(); - const rhs_tag = rhs.tag(); const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(mod, opt_sema); const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(mod, opt_sema); switch (lhs_against_zero) { @@ -1866,6 +1864,8 @@ pub const Value = struct { const lhs_float = lhs.isFloat(); const rhs_float = rhs.isFloat(); if (lhs_float and rhs_float) { + const lhs_tag = lhs.tag(); + const rhs_tag = rhs.tag(); if (lhs_tag == rhs_tag) { return switch (lhs.tag()) { .float_16 => return std.math.order(lhs.castTag(.float_16).?.data, rhs.castTag(.float_16).?.data), @@ -2601,12 +2601,15 @@ pub const Value = struct { /// to a decl, or if it points to some part of a decl (like field_ptr or element_ptr), /// this function returns null. pub fn pointerDecl(val: Value) ?Module.Decl.Index { - return switch (val.tag()) { - .decl_ref_mut => val.castTag(.decl_ref_mut).?.data.decl_index, - .extern_fn => val.castTag(.extern_fn).?.data.owner_decl, - .function => val.castTag(.function).?.data.owner_decl, - .variable => val.castTag(.variable).?.data.owner_decl, - .decl_ref => val.cast(Payload.Decl).?.data, + return switch (val.ip_index) { + .none => switch (val.tag()) { + .decl_ref_mut => val.castTag(.decl_ref_mut).?.data.decl_index, + .extern_fn => val.castTag(.extern_fn).?.data.owner_decl, + .function => val.castTag(.function).?.data.owner_decl, + .variable => val.castTag(.variable).?.data.owner_decl, + .decl_ref => val.cast(Payload.Decl).?.data, + else => null, + }, else => null, }; } @@ -3831,35 +3834,44 @@ pub const Value = struct { /// Returns true if the value is a floating point type and is NaN. Returns false otherwise. pub fn isNan(val: Value) bool { - return switch (val.tag()) { - .float_16 => std.math.isNan(val.castTag(.float_16).?.data), - .float_32 => std.math.isNan(val.castTag(.float_32).?.data), - .float_64 => std.math.isNan(val.castTag(.float_64).?.data), - .float_80 => std.math.isNan(val.castTag(.float_80).?.data), - .float_128 => std.math.isNan(val.castTag(.float_128).?.data), + return switch (val.ip_index) { + .none => switch (val.tag()) { + .float_16 => std.math.isNan(val.castTag(.float_16).?.data), + .float_32 => std.math.isNan(val.castTag(.float_32).?.data), + .float_64 => std.math.isNan(val.castTag(.float_64).?.data), + .float_80 => std.math.isNan(val.castTag(.float_80).?.data), + .float_128 => std.math.isNan(val.castTag(.float_128).?.data), + else => false, + }, else => false, }; } /// Returns true if the value is a floating point type and is infinite. Returns false otherwise. pub fn isInf(val: Value) bool { - return switch (val.tag()) { - .float_16 => std.math.isInf(val.castTag(.float_16).?.data), - .float_32 => std.math.isInf(val.castTag(.float_32).?.data), - .float_64 => std.math.isInf(val.castTag(.float_64).?.data), - .float_80 => std.math.isInf(val.castTag(.float_80).?.data), - .float_128 => std.math.isInf(val.castTag(.float_128).?.data), + return switch (val.ip_index) { + .none => switch (val.tag()) { + .float_16 => std.math.isInf(val.castTag(.float_16).?.data), + .float_32 => std.math.isInf(val.castTag(.float_32).?.data), + .float_64 => std.math.isInf(val.castTag(.float_64).?.data), + .float_80 => std.math.isInf(val.castTag(.float_80).?.data), + .float_128 => std.math.isInf(val.castTag(.float_128).?.data), + else => false, + }, else => false, }; } pub fn isNegativeInf(val: Value) bool { - return switch (val.tag()) { - .float_16 => std.math.isNegativeInf(val.castTag(.float_16).?.data), - .float_32 => std.math.isNegativeInf(val.castTag(.float_32).?.data), - .float_64 => std.math.isNegativeInf(val.castTag(.float_64).?.data), - .float_80 => std.math.isNegativeInf(val.castTag(.float_80).?.data), - .float_128 => std.math.isNegativeInf(val.castTag(.float_128).?.data), + return switch (val.ip_index) { + .none => switch (val.tag()) { + .float_16 => std.math.isNegativeInf(val.castTag(.float_16).?.data), + .float_32 => std.math.isNegativeInf(val.castTag(.float_32).?.data), + .float_64 => std.math.isNegativeInf(val.castTag(.float_64).?.data), + .float_80 => std.math.isNegativeInf(val.castTag(.float_80).?.data), + .float_128 => std.math.isNegativeInf(val.castTag(.float_128).?.data), + else => false, + }, else => false, }; } |
