zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 6e8a83282f10bcce7f80c9f213d2ae6407651163 (tree)
parent 64c5cc80471ccd167af2403741dc2037824e0c8c
Author: Ali Cheraghi <alichraghi@proton.me>
Date:   Sun, 21 Jun 2026 08:31:03 +0330

Sema: implement `@typeInfo` for spirv types

Forgotten in #35461

Diffstat:
Msrc/Sema.zig | 38+++++++++++++++++++++++++++++++++++++-
Msrc/Zcu.zig | 14+++++++++++++-
Mtest/behavior/type_info.zig | 40++++++++++++++++++++++++++++++++++++++++
3 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/src/Sema.zig b/src/Sema.zig @@ -16793,7 +16793,43 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai .val = (try pt.aggregateValue(type_opaque_ty, &field_values)).toIntern(), }))); }, - .spirv => unreachable, // TODO: ALI + .spirv => { + const spirv_info = ip.loadSpirvType(ty.toIntern()); + const spirv_union_ty = try sema.getStdLangType(src, .@"Type.Spirv"); + const spirv_tag_ty = spirv_union_ty.unionTagType(zcu).?; + const spirv_tag_val = try pt.enumValueFieldIndex(spirv_tag_ty, @intFromEnum(spirv_info.flags.tag)); + const spirv_payload_val: Value = switch (spirv_info.flags.tag) { + .sampler => .void, + .sampled_image, .runtime_array => .fromInterned(spirv_info.ty), + .image => image: { + const image_ty = try sema.getStdLangType(src, .@"Type.Spirv.Image"); + const usage_union_ty = try sema.getStdLangType(src, .@"Type.Spirv.Image.Usage"); + const format_ty = try sema.getStdLangType(src, .@"Type.Spirv.Image.Format"); + const dim_ty = try sema.getStdLangType(src, .@"Type.Spirv.Image.Dimensionality"); + const depth_ty = try sema.getStdLangType(src, .@"Type.Spirv.Image.Depth"); + const access_ty = try sema.getStdLangType(src, .@"Type.Spirv.Image.Access"); + const usage_tag_ty = usage_union_ty.unionTagType(zcu).?; + const usage_tag_val = try pt.enumValueFieldIndex(usage_tag_ty, @intFromEnum(spirv_info.flags.usage)); + const usage_val = try pt.unionValue(usage_union_ty, usage_tag_val, .fromInterned(spirv_info.ty)); + const image_field_vals = [_]InternPool.Index{ + usage_val.toIntern(), + (try pt.enumValueFieldIndex(format_ty, @intFromEnum(spirv_info.flags.format))).toIntern(), + (try pt.enumValueFieldIndex(dim_ty, @intFromEnum(spirv_info.flags.dim))).toIntern(), + (try pt.enumValueFieldIndex(depth_ty, @intFromEnum(spirv_info.flags.depth))).toIntern(), + (try pt.enumValueFieldIndex(access_ty, @intFromEnum(spirv_info.flags.access))).toIntern(), + Value.makeBool(spirv_info.flags.is_arrayed).toIntern(), + Value.makeBool(spirv_info.flags.is_multisampled).toIntern(), + }; + break :image try pt.aggregateValue(image_ty, &image_field_vals); + }, + }; + const spirv_val = try pt.unionValue(spirv_union_ty, spirv_tag_val, spirv_payload_val); + return Air.internedToRef((try pt.internUnion(.{ + .ty = type_info_ty.toIntern(), + .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.lang.TypeId.spirv))).toIntern(), + .val = spirv_val.toIntern(), + }))); + }, .frame => return sema.failWithUseOfAsync(block, src), .@"anyframe" => return sema.failWithUseOfAsync(block, src), } diff --git a/src/Zcu.zig b/src/Zcu.zig @@ -469,6 +469,12 @@ pub const StdLangDecl = enum { @"Type.ContainerLayout", @"Type.Opaque", @"Type.Spirv", + @"Type.Spirv.Image", + @"Type.Spirv.Image.Usage", + @"Type.Spirv.Image.Format", + @"Type.Spirv.Image.Dimensionality", + @"Type.Spirv.Image.Depth", + @"Type.Spirv.Image.Access", panic, @"panic.call", @@ -550,6 +556,12 @@ pub const StdLangDecl = enum { .@"Type.ContainerLayout", .@"Type.Opaque", .@"Type.Spirv", + .@"Type.Spirv.Image", + .@"Type.Spirv.Image.Usage", + .@"Type.Spirv.Image.Format", + .@"Type.Spirv.Image.Dimensionality", + .@"Type.Spirv.Image.Depth", + .@"Type.Spirv.Image.Access", => .type, .panic => .type, @@ -603,7 +615,7 @@ pub const StdLangDecl = enum { .VaList => .va_list, .assembly, .@"assembly.Clobbers" => .assembly, else => { - if (@intFromEnum(decl) <= @intFromEnum(StdLangDecl.@"Type.Spirv")) { + if (@intFromEnum(decl) <= @intFromEnum(StdLangDecl.@"Type.Spirv.Image.Access")) { return .main; } else { return .panic; diff --git a/test/behavior/type_info.zig b/test/behavior/type_info.zig @@ -613,3 +613,43 @@ test "@typeInfo function with generic return type and inferred error set" { const ret_ty = @typeInfo(@TypeOf(S.testFn)).@"fn".return_type; comptime assert(ret_ty == null); } + +test "type info: spirv info" { + if (builtin.zig_backend != .stage2_spirv) return error.SkipZigTest; + + try testSpirv(); + try comptime testSpirv(); +} + +fn testSpirv() !void { + const image_info = @typeInfo(Image); + try expect(image_info.spirv.image.usage.sampled == f32); + try expect(image_info.spirv.image.format == .unknown); + try expect(image_info.spirv.image.dim == .@"2d"); + try expect(image_info.spirv.image.depth == .not_depth); + try expect(image_info.spirv.image.arrayed == false); + try expect(image_info.spirv.image.multisampled == false); + try expect(image_info.spirv.image.access == .unknown); + + const sampled_image_info = @typeInfo(SampledImage); + try expect(sampled_image_info.spirv.sampled_image == Image); + + const sampler_info = @typeInfo(Sampler); + try expect(sampler_info.spirv.sampler == {}); + + const runtime_array_info = @typeInfo(RuntimeArray); + try expect(runtime_array_info.spirv.runtime_array == f32); +} + +pub const Image = @SpirvType(.{ .image = .{ + .usage = .{ .sampled = f32 }, + .format = .unknown, + .dim = .@"2d", + .depth = .not_depth, + .arrayed = false, + .multisampled = false, + .access = .unknown, +} }); +pub const SampledImage = @SpirvType(.{ .sampled_image = Image }); +pub const Sampler = @SpirvType(.sampler); +pub const RuntimeArray = @SpirvType(.{ .runtime_array = f32 });