diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-05-15 21:44:38 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-05-15 21:44:38 -0700 |
| commit | 597082adf45cebbf2c6a81c3f732b6d2ce4a1435 (patch) | |
| tree | 9309977e204cceaac2c18efbea2153a69f86d1f4 /lib/std | |
| parent | 07606d12daabe8c201dba3d5b27e702ce58d0ffb (diff) | |
| parent | d98e39fa6864f287bc50f265f98b7195849afa68 (diff) | |
| download | zig-597082adf45cebbf2c6a81c3f732b6d2ce4a1435.tar.gz zig-597082adf45cebbf2c6a81c3f732b6d2ce4a1435.zip | |
Merge remote-tracking branch 'origin/master' into stage2-whole-file-astgen
Conflicts:
* build.zig
* src/Compilation.zig
* src/codegen/spirv/spec.zig
* src/link/SpirV.zig
* test/stage2/darwin.zig
- this one might be problematic; start.zig looks for `main` in the
root source file, not `_main`. Not sure why there is an underscore
there in master branch.
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/build.zig | 8 | ||||
| -rw-r--r-- | lib/std/debug.zig | 6 | ||||
| -rw-r--r-- | lib/std/fs.zig | 4 | ||||
| -rw-r--r-- | lib/std/hash_map.zig | 25 | ||||
| -rw-r--r-- | lib/std/json.zig | 55 | ||||
| -rw-r--r-- | lib/std/json/test.zig | 6 | ||||
| -rw-r--r-- | lib/std/math/isnormal.zig | 11 | ||||
| -rw-r--r-- | lib/std/math/scalbn.zig | 132 | ||||
| -rw-r--r-- | lib/std/os/bits/linux/errno-sparc.zig | 1 | ||||
| -rw-r--r-- | lib/std/special/compiler_rt.zig | 10 | ||||
| -rw-r--r-- | lib/std/special/compiler_rt/mulXf3.zig | 12 | ||||
| -rw-r--r-- | lib/std/special/compiler_rt/mulXf3_test.zig | 14 | ||||
| -rw-r--r-- | lib/std/special/compiler_rt/sparc.zig | 42 | ||||
| -rw-r--r-- | lib/std/start.zig | 2 | ||||
| -rw-r--r-- | lib/std/target.zig | 14 | ||||
| -rw-r--r-- | lib/std/target/spirv.zig | 2135 | ||||
| -rw-r--r-- | lib/std/testing.zig | 32 | ||||
| -rw-r--r-- | lib/std/zig/cross_target.zig | 10 | ||||
| -rw-r--r-- | lib/std/zig/parse.zig | 318 | ||||
| -rw-r--r-- | lib/std/zig/parser_test.zig | 11 |
20 files changed, 2489 insertions, 359 deletions
diff --git a/lib/std/build.zig b/lib/std/build.zig index 1137aa0804..bd6360d8d6 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -1398,6 +1398,9 @@ pub const LibExeObjStep = struct { /// Uses system Wasmtime installation to run cross compiled wasm/wasi build artifacts. enable_wasmtime: bool = false, + /// Experimental. Uses system Darling installation to run cross compiled macOS build artifacts. + enable_darling: bool = false, + /// After following the steps in https://github.com/ziglang/zig/wiki/Updating-libc#glibc, /// this will be the directory $glibc-build-dir/install/glibcs /// Given the example of the aarch64 target, this is the directory @@ -2514,6 +2517,11 @@ pub const LibExeObjStep = struct { try zig_args.append("--dir=."); try zig_args.append("--test-cmd-bin"); }, + .darling => |bin_name| if (self.enable_darling) { + try zig_args.append("--test-cmd"); + try zig_args.append(bin_name); + try zig_args.append("--test-cmd-bin"); + }, } for (self.packages.items) |pkg| { diff --git a/lib/std/debug.zig b/lib/std/debug.zig index d988665996..bfaf6f0df4 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -309,6 +309,7 @@ const RED = "\x1b[31;1m"; const GREEN = "\x1b[32;1m"; const CYAN = "\x1b[36;1m"; const WHITE = "\x1b[37;1m"; +const BOLD = "\x1b[1m"; const DIM = "\x1b[2m"; const RESET = "\x1b[0m"; @@ -479,8 +480,9 @@ pub const TTY = struct { .Red => out_stream.writeAll(RED) catch return, .Green => out_stream.writeAll(GREEN) catch return, .Cyan => out_stream.writeAll(CYAN) catch return, - .White, .Bold => out_stream.writeAll(WHITE) catch return, + .White => out_stream.writeAll(WHITE) catch return, .Dim => out_stream.writeAll(DIM) catch return, + .Bold => out_stream.writeAll(BOLD) catch return, .Reset => out_stream.writeAll(RESET) catch return, }, .windows_api => if (native_os == .windows) { @@ -632,7 +634,7 @@ fn printLineInfo( comptime printLineFromFile: anytype, ) !void { nosuspend { - tty_config.setColor(out_stream, .White); + tty_config.setColor(out_stream, .Bold); if (line_info) |*li| { try out_stream.print("{s}:{d}:{d}", .{ li.file_name, li.line, li.column }); diff --git a/lib/std/fs.zig b/lib/std/fs.zig index ea1080e31c..2e3d4fca05 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -501,7 +501,9 @@ pub const Dir = struct { }, .linux => struct { dir: Dir, - buf: [8192]u8, // TODO align(@alignOf(os.dirent64)), + // The if guard is solely there to prevent compile errors from missing `os.linux.dirent64` + // definition when compiling for other OSes. It doesn't do anything when compiling for Linux. + buf: [8192]u8 align(if (builtin.os.tag != .linux) 1 else @alignOf(os.linux.dirent64)), index: usize, end_index: usize, diff --git a/lib/std/hash_map.zig b/lib/std/hash_map.zig index c369e5421b..62f577de1a 100644 --- a/lib/std/hash_map.zig +++ b/lib/std/hash_map.zig @@ -303,29 +303,32 @@ pub fn HashMapUnmanaged( /// Metadata for a slot. It can be in three states: empty, used or /// tombstone. Tombstones indicate that an entry was previously used, /// they are a simple way to handle removal. - /// To this state, we add 6 bits from the slot's key hash. These are + /// To this state, we add 7 bits from the slot's key hash. These are /// used as a fast way to disambiguate between entries without /// having to use the equality function. If two fingerprints are /// different, we know that we don't have to compare the keys at all. - /// The 6 bits are the highest ones from a 64 bit hash. This way, not + /// The 7 bits are the highest ones from a 64 bit hash. This way, not /// only we use the `log2(capacity)` lowest bits from the hash to determine - /// a slot index, but we use 6 more bits to quickly resolve collisions - /// when multiple elements with different hashes end up wanting to be in / the same slot. + /// a slot index, but we use 7 more bits to quickly resolve collisions + /// when multiple elements with different hashes end up wanting to be in the same slot. /// Not using the equality function means we don't have to read into - /// the entries array, avoiding a likely cache miss. + /// the entries array, likely avoiding a cache miss and a potentially + /// costly function call. const Metadata = packed struct { - const FingerPrint = u6; + const FingerPrint = u7; + const free: FingerPrint = 0; + const tombstone: FingerPrint = 1; + + fingerprint: FingerPrint = free, used: u1 = 0, - tombstone: u1 = 0, - fingerprint: FingerPrint = 0, pub fn isUsed(self: Metadata) bool { return self.used == 1; } pub fn isTombstone(self: Metadata) bool { - return self.tombstone == 1; + return !self.isUsed() and self.fingerprint == tombstone; } pub fn takeFingerprint(hash: Hash) FingerPrint { @@ -336,14 +339,12 @@ pub fn HashMapUnmanaged( pub fn fill(self: *Metadata, fp: FingerPrint) void { self.used = 1; - self.tombstone = 0; self.fingerprint = fp; } pub fn remove(self: *Metadata) void { self.used = 0; - self.tombstone = 1; - self.fingerprint = 0; + self.fingerprint = tombstone; } }; diff --git a/lib/std/json.zig b/lib/std/json.zig index 109167bbc1..56d379f9f8 100644 --- a/lib/std/json.zig +++ b/lib/std/json.zig @@ -623,7 +623,7 @@ pub const StreamingParser = struct { .ObjectSeparator => switch (c) { ':' => { - p.state = .ValueBegin; + p.state = .ValueBeginNoClosing; p.after_string_state = .ValueEnd; }, 0x09, 0x0A, 0x0D, 0x20 => { @@ -1205,6 +1205,13 @@ test "json.token mismatched close" { try testing.expectError(error.UnexpectedClosingBrace, p.next()); } +test "json.token premature object close" { + var p = TokenStream.init("{ \"key\": }"); + try checkNext(&p, .ObjectBegin); + try checkNext(&p, .String); + try testing.expectError(error.InvalidValueBegin, p.next()); +} + /// Validate a JSON string. This does not limit number precision so a decoder may not necessarily /// be able to decode the string even if this returns true. pub fn validate(s: []const u8) bool { @@ -1566,11 +1573,16 @@ fn parseInternal(comptime T: type, token: Token, tokens: *TokenStream, options: // .UseLast => {}, // } if (options.duplicate_field_behavior == .UseFirst) { + // unconditonally ignore value. for comptime fields, this skips check against default_value + parseFree(field.field_type, try parse(field.field_type, tokens, options), options); + found = true; break; } else if (options.duplicate_field_behavior == .Error) { return error.DuplicateJSONField; } else if (options.duplicate_field_behavior == .UseLast) { - parseFree(field.field_type, @field(r, field.name), options); + if (!field.is_comptime) { + parseFree(field.field_type, @field(r, field.name), options); + } fields_seen[i] = false; } } @@ -1724,7 +1736,9 @@ pub fn parseFree(comptime T: type, value: T, options: ParseOptions) void { }, .Struct => |structInfo| { inline for (structInfo.fields) |field| { - parseFree(field.field_type, @field(value, field.name), options); + if (!field.is_comptime) { + parseFree(field.field_type, @field(value, field.name), options); + } } }, .Array => |arrayInfo| { @@ -1901,14 +1915,19 @@ test "parse with comptime field" { }, }; - const r = try std.json.parse(T, &std.json.TokenStream.init( + const options = ParseOptions{ + .allocator = std.testing.allocator, + }; + + const r = try parse(T, &TokenStream.init( \\{ \\ "kind": "float", \\ "b": 1.0 \\} - ), .{ - .allocator = std.testing.allocator, - }); + ), options); + + // check that parseFree doesn't try to free comptime fields + parseFree(T, r, options); } } @@ -1995,17 +2014,33 @@ test "parse into struct with duplicate field" { const ballast = try testing.allocator.alloc(u64, 1); defer testing.allocator.free(ballast); - const options = ParseOptions{ + const options_first = ParseOptions{ + .allocator = testing.allocator, + .duplicate_field_behavior = .UseFirst + }; + + const options_last = ParseOptions{ .allocator = testing.allocator, .duplicate_field_behavior = .UseLast, }; + const str = "{ \"a\": 1, \"a\": 0.25 }"; const T1 = struct { a: *u64 }; - try testing.expectError(error.UnexpectedToken, parse(T1, &TokenStream.init(str), options)); + // both .UseFirst and .UseLast should fail because second "a" value isn't a u64 + try testing.expectError(error.UnexpectedToken, parse(T1, &TokenStream.init(str), options_first)); + try testing.expectError(error.UnexpectedToken, parse(T1, &TokenStream.init(str), options_last)); const T2 = struct { a: f64 }; - try testing.expectEqual(T2{ .a = 0.25 }, try parse(T2, &TokenStream.init(str), options)); + try testing.expectEqual(T2{ .a = 1.0 }, try parse(T2, &TokenStream.init(str), options_first)); + try testing.expectEqual(T2{ .a = 0.25 }, try parse(T2, &TokenStream.init(str), options_last)); + + const T3 = struct { comptime a: f64 = 1.0 }; + // .UseFirst should succeed because second "a" value is unconditionally ignored (even though != 1.0) + const t3 = T3{ .a = 1.0 }; + try testing.expectEqual(t3, try parse(T3, &TokenStream.init(str), options_first)); + // .UseLast should fail because second "a" value is 0.25 which is not equal to default value of 1.0 + try testing.expectError(error.UnexpectedValue, parse(T3, &TokenStream.init(str), options_last)); } /// A non-stream JSON parser which constructs a tree of Value's. diff --git a/lib/std/json/test.zig b/lib/std/json/test.zig index e37ba72113..027f6acaca 100644 --- a/lib/std/json/test.zig +++ b/lib/std/json/test.zig @@ -76,6 +76,12 @@ test "y_trailing_comma_after_empty" { ); } +test "n_object_closed_missing_value" { + try err( + \\{"a":} + ); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// test "y_array_arraysWithSpaces" { diff --git a/lib/std/math/isnormal.zig b/lib/std/math/isnormal.zig index b10a6e2286..f3942d121c 100644 --- a/lib/std/math/isnormal.zig +++ b/lib/std/math/isnormal.zig @@ -14,16 +14,20 @@ pub fn isNormal(x: anytype) bool { switch (T) { f16 => { const bits = @bitCast(u16, x); - return (bits + 1024) & 0x7FFF >= 2048; + return (bits + (1 << 10)) & (maxInt(u16) >> 1) >= (1 << 11); }, f32 => { const bits = @bitCast(u32, x); - return (bits + 0x00800000) & 0x7FFFFFFF >= 0x01000000; + return (bits + (1 << 23)) & (maxInt(u32) >> 1) >= (1 << 24); }, f64 => { const bits = @bitCast(u64, x); return (bits + (1 << 52)) & (maxInt(u64) >> 1) >= (1 << 53); }, + f128 => { + const bits = @bitCast(u128, x); + return (bits + (1 << 112)) & (maxInt(u128) >> 1) >= (1 << 113); + }, else => { @compileError("isNormal not implemented for " ++ @typeName(T)); }, @@ -34,10 +38,13 @@ test "math.isNormal" { try expect(!isNormal(math.nan(f16))); try expect(!isNormal(math.nan(f32))); try expect(!isNormal(math.nan(f64))); + try expect(!isNormal(math.nan(f128))); try expect(!isNormal(@as(f16, 0))); try expect(!isNormal(@as(f32, 0))); try expect(!isNormal(@as(f64, 0))); + try expect(!isNormal(@as(f128, 0))); try expect(isNormal(@as(f16, 1.0))); try expect(isNormal(@as(f32, 1.0))); try expect(isNormal(@as(f64, 1.0))); + try expect(isNormal(@as(f128, 1.0))); } diff --git a/lib/std/math/scalbn.zig b/lib/std/math/scalbn.zig index 49aea08931..bdf382a303 100644 --- a/lib/std/math/scalbn.zig +++ b/lib/std/math/scalbn.zig @@ -9,89 +9,89 @@ // https://git.musl-libc.org/cgit/musl/tree/src/math/scalbnf.c // https://git.musl-libc.org/cgit/musl/tree/src/math/scalbn.c -const std = @import("../std.zig"); +const std = @import("std"); const math = std.math; +const assert = std.debug.assert; const expect = std.testing.expect; /// Returns x * 2^n. pub fn scalbn(x: anytype, n: i32) @TypeOf(x) { - const T = @TypeOf(x); - return switch (T) { - f32 => scalbn32(x, n), - f64 => scalbn64(x, n), - else => @compileError("scalbn not implemented for " ++ @typeName(T)), - }; -} - -fn scalbn32(x: f32, n_: i32) f32 { - var y = x; - var n = n_; + var base = x; + var shift = n; - if (n > 127) { - y *= 0x1.0p127; - n -= 127; - if (n > 1023) { - y *= 0x1.0p127; - n -= 127; - if (n > 127) { - n = 127; - } - } - } else if (n < -126) { - y *= 0x1.0p-126 * 0x1.0p24; - n += 126 - 24; - if (n < -126) { - y *= 0x1.0p-126 * 0x1.0p24; - n += 126 - 24; - if (n < -126) { - n = -126; - } - } + const T = @TypeOf(base); + const IntT = std.meta.Int(.unsigned, @bitSizeOf(T)); + if (@typeInfo(T) != .Float) { + @compileError("scalbn not implemented for " ++ @typeName(T)); } - const u = @intCast(u32, n +% 0x7F) << 23; - return y * @bitCast(f32, u); -} + const mantissa_bits = math.floatMantissaBits(T); + const exponent_bits = math.floatExponentBits(T); + const exponent_bias = (1 << (exponent_bits - 1)) - 1; + const exponent_min = 1 - exponent_bias; + const exponent_max = exponent_bias; -fn scalbn64(x: f64, n_: i32) f64 { - var y = x; - var n = n_; + // fix double rounding errors in subnormal ranges + // https://git.musl-libc.org/cgit/musl/commit/src/math/scalbn.c?id=8c44a060243f04283ca68dad199aab90336141db + const scale_min_expo = exponent_min + mantissa_bits + 1; + const scale_min = @bitCast(T, @as(IntT, scale_min_expo + exponent_bias) << mantissa_bits); + const scale_max = @bitCast(T, @intCast(IntT, exponent_max + exponent_bias) << mantissa_bits); - if (n > 1023) { - y *= 0x1.0p1023; - n -= 1023; - if (n > 1023) { - y *= 0x1.0p1023; - n -= 1023; - if (n > 1023) { - n = 1023; - } + // scale `shift` within floating point limits, if possible + // second pass is possible due to subnormal range + // third pass always results in +/-0.0 or +/-inf + if (shift > exponent_max) { + base *= scale_max; + shift -= exponent_max; + if (shift > exponent_max) { + base *= scale_max; + shift -= exponent_max; + if (shift > exponent_max) shift = exponent_max; } - } else if (n < -1022) { - y *= 0x1.0p-1022 * 0x1.0p53; - n += 1022 - 53; - if (n < -1022) { - y *= 0x1.0p-1022 * 0x1.0p53; - n += 1022 - 53; - if (n < -1022) { - n = -1022; - } + } else if (shift < exponent_min) { + base *= scale_min; + shift -= scale_min_expo; + if (shift < exponent_min) { + base *= scale_min; + shift -= scale_min_expo; + if (shift < exponent_min) shift = exponent_min; } } - const u = @intCast(u64, n +% 0x3FF) << 52; - return y * @bitCast(f64, u); + return base * @bitCast(T, @intCast(IntT, shift + exponent_bias) << mantissa_bits); } test "math.scalbn" { - try expect(scalbn(@as(f32, 1.5), 4) == scalbn32(1.5, 4)); - try expect(scalbn(@as(f64, 1.5), 4) == scalbn64(1.5, 4)); -} + // basic usage + try expect(scalbn(@as(f16, 1.5), 4) == 24.0); + try expect(scalbn(@as(f32, 1.5), 4) == 24.0); + try expect(scalbn(@as(f64, 1.5), 4) == 24.0); + try expect(scalbn(@as(f128, 1.5), 4) == 24.0); -test "math.scalbn32" { - try expect(scalbn32(1.5, 4) == 24.0); -} + // subnormals + try expect(math.isNormal(scalbn(@as(f16, 1.0), -14))); + try expect(!math.isNormal(scalbn(@as(f16, 1.0), -15))); + try expect(math.isNormal(scalbn(@as(f32, 1.0), -126))); + try expect(!math.isNormal(scalbn(@as(f32, 1.0), -127))); + try expect(math.isNormal(scalbn(@as(f64, 1.0), -1022))); + try expect(!math.isNormal(scalbn(@as(f64, 1.0), -1023))); + try expect(math.isNormal(scalbn(@as(f128, 1.0), -16382))); + try expect(!math.isNormal(scalbn(@as(f128, 1.0), -16383))); + // unreliable due to lack of native f16 support, see talk on PR #8733 + // try expect(scalbn(@as(f16, 0x1.1FFp-1), -14 - 9) == math.f16_true_min); + try expect(scalbn(@as(f32, 0x1.3FFFFFp-1), -126 - 22) == math.f32_true_min); + try expect(scalbn(@as(f64, 0x1.7FFFFFFFFFFFFp-1), -1022 - 51) == math.f64_true_min); + try expect(scalbn(@as(f128, 0x1.7FFFFFFFFFFFFFFFFFFFFFFFFFFFp-1), -16382 - 111) == math.f128_true_min); -test "math.scalbn64" { - try expect(scalbn64(1.5, 4) == 24.0); + // float limits + try expect(scalbn(@as(f32, math.f32_max), -128 - 149) > 0.0); + try expect(scalbn(@as(f32, math.f32_max), -128 - 149 - 1) == 0.0); + try expect(!math.isPositiveInf(scalbn(@as(f16, math.f16_true_min), 15 + 24))); + try expect(math.isPositiveInf(scalbn(@as(f16, math.f16_true_min), 15 + 24 + 1))); + try expect(!math.isPositiveInf(scalbn(@as(f32, math.f32_true_min), 127 + 149))); + try expect(math.isPositiveInf(scalbn(@as(f32, math.f32_true_min), 127 + 149 + 1))); + try expect(!math.isPositiveInf(scalbn(@as(f64, math.f64_true_min), 1023 + 1074))); + try expect(math.isPositiveInf(scalbn(@as(f64, math.f64_true_min), 1023 + 1074 + 1))); + try expect(!math.isPositiveInf(scalbn(@as(f128, math.f128_true_min), 16383 + 16494))); + try expect(math.isPositiveInf(scalbn(@as(f128, math.f128_true_min), 16383 + 16494 + 1))); } diff --git a/lib/std/os/bits/linux/errno-sparc.zig b/lib/std/os/bits/linux/errno-sparc.zig index bbeabaaef0..94b696fc35 100644 --- a/lib/std/os/bits/linux/errno-sparc.zig +++ b/lib/std/os/bits/linux/errno-sparc.zig @@ -52,6 +52,7 @@ pub const ENOPROTOOPT = 42; pub const EPROTONOSUPPORT = 43; pub const ESOCKTNOSUPPORT = 44; pub const EOPNOTSUPP = 45; +pub const ENOTSUP = EOPNOTSUPP; pub const EPFNOSUPPORT = 46; pub const EAFNOSUPPORT = 47; pub const EADDRINUSE = 48; diff --git a/lib/std/special/compiler_rt.zig b/lib/std/special/compiler_rt.zig index a13097765e..9be31f7d09 100644 --- a/lib/std/special/compiler_rt.zig +++ b/lib/std/special/compiler_rt.zig @@ -297,7 +297,17 @@ comptime { @export(@import("compiler_rt/sparc.zig")._Qp_fgt, .{ .name = "_Qp_fgt", .linkage = linkage }); @export(@import("compiler_rt/sparc.zig")._Qp_fge, .{ .name = "_Qp_fge", .linkage = linkage }); + @export(@import("compiler_rt/sparc.zig")._Qp_itoq, .{ .name = "_Qp_itoq", .linkage = linkage }); + @export(@import("compiler_rt/sparc.zig")._Qp_uitoq, .{ .name = "_Qp_uitoq", .linkage = linkage }); + @export(@import("compiler_rt/sparc.zig")._Qp_xtoq, .{ .name = "_Qp_xtoq", .linkage = linkage }); + @export(@import("compiler_rt/sparc.zig")._Qp_uxtoq, .{ .name = "_Qp_uxtoq", .linkage = linkage }); + @export(@import("compiler_rt/sparc.zig")._Qp_stoq, .{ .name = "_Qp_stoq", .linkage = linkage }); @export(@import("compiler_rt/sparc.zig")._Qp_dtoq, .{ .name = "_Qp_dtoq", .linkage = linkage }); + @export(@import("compiler_rt/sparc.zig")._Qp_qtoi, .{ .name = "_Qp_qtoi", .linkage = linkage }); + @export(@import("compiler_rt/sparc.zig")._Qp_qtoui, .{ .name = "_Qp_qtoui", .linkage = linkage }); + @export(@import("compiler_rt/sparc.zig")._Qp_qtox, .{ .name = "_Qp_qtox", .linkage = linkage }); + @export(@import("compiler_rt/sparc.zig")._Qp_qtoux, .{ .name = "_Qp_qtoux", .linkage = linkage }); + @export(@import("compiler_rt/sparc.zig")._Qp_qtos, .{ .name = "_Qp_qtos", .linkage = linkage }); @export(@import("compiler_rt/sparc.zig")._Qp_qtod, .{ .name = "_Qp_qtod", .linkage = linkage }); } diff --git a/lib/std/special/compiler_rt/mulXf3.zig b/lib/std/special/compiler_rt/mulXf3.zig index a4c71529d1..20828badd3 100644 --- a/lib/std/special/compiler_rt/mulXf3.zig +++ b/lib/std/special/compiler_rt/mulXf3.zig @@ -98,8 +98,8 @@ fn mulXf3(comptime T: type, a: T, b: T) T { // one or both of a or b is denormal, the other (if applicable) is a // normal number. Renormalize one or both of a and b, and set scale to // include the necessary exponent adjustment. - if (aAbs < implicitBit) scale +%= normalize(T, &aSignificand); - if (bAbs < implicitBit) scale +%= normalize(T, &bSignificand); + if (aAbs < implicitBit) scale += normalize(T, &aSignificand); + if (bAbs < implicitBit) scale += normalize(T, &bSignificand); } // Or in the implicit significand bit. (If we fell through from the @@ -277,7 +277,7 @@ fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeInfo(T const shift = @clz(Z, significand.*) - @clz(Z, implicitBit); significand.* <<= @intCast(std.math.Log2Int(Z), shift); - return 1 - shift; + return @as(i32, 1) - shift; } fn wideRightShiftWithSticky(comptime Z: type, hi: *Z, lo: *Z, count: u32) void { @@ -285,15 +285,15 @@ fn wideRightShiftWithSticky(comptime Z: type, hi: *Z, lo: *Z, count: u32) void { const typeWidth = @typeInfo(Z).Int.bits; const S = std.math.Log2Int(Z); if (count < typeWidth) { - const sticky = @truncate(u8, lo.* << @intCast(S, typeWidth -% count)); + const sticky = @boolToInt((lo.* << @intCast(S, typeWidth -% count)) != 0); lo.* = (hi.* << @intCast(S, typeWidth -% count)) | (lo.* >> @intCast(S, count)) | sticky; hi.* = hi.* >> @intCast(S, count); } else if (count < 2 * typeWidth) { - const sticky = @truncate(u8, hi.* << @intCast(S, 2 * typeWidth -% count) | lo.*); + const sticky = @boolToInt((hi.* << @intCast(S, 2 * typeWidth -% count) | lo.*) != 0); lo.* = hi.* >> @intCast(S, count -% typeWidth) | sticky; hi.* = 0; } else { - const sticky = @truncate(u8, hi.* | lo.*); + const sticky = @boolToInt((hi.* | lo.*) != 0); lo.* = sticky; hi.* = 0; } diff --git a/lib/std/special/compiler_rt/mulXf3_test.zig b/lib/std/special/compiler_rt/mulXf3_test.zig index b73f03d6c1..d3a61710a1 100644 --- a/lib/std/special/compiler_rt/mulXf3_test.zig +++ b/lib/std/special/compiler_rt/mulXf3_test.zig @@ -88,4 +88,18 @@ test "multf3" { ); try test__multf3(0x1.23456734245345p-10000, 0x1.edcba524498724p-6497, 0x0, 0x0); + + // Denormal operands. + try test__multf3( + 0x0.0000000000000000000000000001p-16382, + 0x1.p16383, + 0x3f90000000000000, + 0x0, + ); + try test__multf3( + 0x1.p16383, + 0x0.0000000000000000000000000001p-16382, + 0x3f90000000000000, + 0x0, + ); } diff --git a/lib/std/special/compiler_rt/sparc.zig b/lib/std/special/compiler_rt/sparc.zig index d86c240ab8..12c9de888a 100644 --- a/lib/std/special/compiler_rt/sparc.zig +++ b/lib/std/special/compiler_rt/sparc.zig @@ -68,12 +68,52 @@ pub fn _Qp_fge(a: *f128, b: *f128) callconv(.C) bool { return cmp == @enumToInt(FCMP.Greater) or cmp == @enumToInt(FCMP.Equal); } -// Casting +// Conversion + +pub fn _Qp_itoq(c: *f128, a: i32) callconv(.C) void { + c.* = @import("floatsiXf.zig").__floatsitf(a); +} + +pub fn _Qp_uitoq(c: *f128, a: u32) callconv(.C) void { + c.* = @import("floatunsitf.zig").__floatunsitf(a); +} + +pub fn _Qp_xtoq(c: *f128, a: i64) callconv(.C) void { + c.* = @import("floatditf.zig").__floatditf(a); +} + +pub fn _Qp_uxtoq(c: *f128, a: u64) callconv(.C) void { + c.* = @import("floatunditf.zig").__floatunditf(a); +} + +pub fn _Qp_stoq(c: *f128, a: f32) callconv(.C) void { + c.* = @import("extendXfYf2.zig").__extendsftf2(a); +} pub fn _Qp_dtoq(c: *f128, a: f64) callconv(.C) void { c.* = @import("extendXfYf2.zig").__extenddftf2(a); } +pub fn _Qp_qtoi(a: *f128) callconv(.C) i32 { + return @import("fixtfsi.zig").__fixtfsi(a.*); +} + +pub fn _Qp_qtoui(a: *f128) callconv(.C) u32 { + return @import("fixunstfsi.zig").__fixunstfsi(a.*); +} + +pub fn _Qp_qtox(a: *f128) callconv(.C) i64 { + return @import("fixtfdi.zig").__fixtfdi(a.*); +} + +pub fn _Qp_qtoux(a: *f128) callconv(.C) u64 { + return @import("fixunstfdi.zig").__fixunstfdi(a.*); +} + +pub fn _Qp_qtos(a: *f128) callconv(.C) f32 { + return @import("truncXfYf2.zig").__trunctfsf2(a.*); +} + pub fn _Qp_qtod(a: *f128) callconv(.C) f64 { return @import("truncXfYf2.zig").__trunctfdf2(a.*); } diff --git a/lib/std/start.zig b/lib/std/start.zig index fa9d5a92b6..d3bf121c1b 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -46,7 +46,7 @@ comptime { } else if (builtin.output_mode == .Exe or @hasDecl(root, "main")) { if (builtin.link_libc and @hasDecl(root, "main")) { if (@typeInfo(@TypeOf(root.main)).Fn.calling_convention != .C) { - @export(main, .{ .name = "main", .linkage = .Weak }); + @export(main, .{ .name = "main" }); } } else if (native_os == .windows) { if (!@hasDecl(root, "WinMain") and !@hasDecl(root, "WinMainCRTStartup") and diff --git a/lib/std/target.zig b/lib/std/target.zig index 31cec9cf82..fb54d2e18f 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -431,6 +431,7 @@ pub const Target = struct { pub const powerpc = @import("target/powerpc.zig"); pub const riscv = @import("target/riscv.zig"); pub const sparc = @import("target/sparc.zig"); + pub const spirv = @import("target/spirv.zig"); pub const systemz = @import("target/systemz.zig"); pub const ve = @import("target/ve.zig"); pub const wasm = @import("target/wasm.zig"); @@ -594,7 +595,7 @@ pub const Target = struct { pub const Set = struct { ints: [usize_count]usize, - pub const needed_bit_count = 172; + pub const needed_bit_count = 288; pub const byte_count = (needed_bit_count + 7) / 8; pub const usize_count = (byte_count + (@sizeOf(usize) - 1)) / @sizeOf(usize); pub const Index = std.math.Log2Int(std.meta.Int(.unsigned, usize_count * @bitSizeOf(usize))); @@ -822,6 +823,13 @@ pub const Target = struct { }; } + pub fn isSPIRV(arch: Arch) bool { + return switch (arch) { + .spirv32, .spirv64 => true, + else => false, + }; + } + pub fn parseCpuModel(arch: Arch, cpu_name: []const u8) !*const Cpu.Model { for (arch.allCpuModels()) |cpu| { if (mem.eql(u8, cpu_name, cpu.name)) { @@ -1116,6 +1124,7 @@ pub const Target = struct { .amdgcn => &amdgpu.all_features, .riscv32, .riscv64 => &riscv.all_features, .sparc, .sparcv9, .sparcel => &sparc.all_features, + .spirv32, .spirv64 => &spirv.all_features, .s390x => &systemz.all_features, .i386, .x86_64 => &x86.all_features, .nvptx, .nvptx64 => &nvptx.all_features, @@ -1320,6 +1329,9 @@ pub const Target = struct { if (cpu_arch.isWasm()) { return .wasm; } + if (cpu_arch.isSPIRV()) { + return .spirv; + } return .elf; } diff --git a/lib/std/target/spirv.zig b/lib/std/target/spirv.zig new file mode 100644 index 0000000000..690501f731 --- /dev/null +++ b/lib/std/target/spirv.zig @@ -0,0 +1,2135 @@ +//! This file is auto-generated by tools/update_spirv_features.zig. +//! TODO: Dependencies of capabilities on extensions. +//! TODO: Dependencies of extensions on extensions. +//! TODO: Dependencies of extensions on versions. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + v1_1, + v1_2, + v1_3, + v1_4, + v1_5, + SPV_AMD_shader_fragment_mask, + SPV_AMD_gpu_shader_int16, + SPV_AMD_gpu_shader_half_float, + SPV_AMD_texture_gather_bias_lod, + SPV_AMD_shader_ballot, + SPV_AMD_gcn_shader, + SPV_AMD_shader_image_load_store_lod, + SPV_AMD_shader_explicit_vertex_parameter, + SPV_AMD_shader_trinary_minmax, + SPV_AMD_gpu_shader_half_float_fetch, + SPV_GOOGLE_hlsl_functionality1, + SPV_GOOGLE_user_type, + SPV_GOOGLE_decorate_string, + SPV_EXT_demote_to_helper_invocation, + SPV_EXT_descriptor_indexing, + SPV_EXT_fragment_fully_covered, + SPV_EXT_shader_stencil_export, + SPV_EXT_physical_storage_buffer, + SPV_EXT_shader_atomic_float_add, + SPV_EXT_shader_atomic_float_min_max, + SPV_EXT_shader_image_int64, + SPV_EXT_fragment_shader_interlock, + SPV_EXT_fragment_invocation_density, + SPV_EXT_shader_viewport_index_layer, + SPV_INTEL_loop_fuse, + SPV_INTEL_fpga_dsp_control, + SPV_INTEL_fpga_reg, + SPV_INTEL_fpga_memory_accesses, + SPV_INTEL_fpga_loop_controls, + SPV_INTEL_io_pipes, + SPV_INTEL_unstructured_loop_controls, + SPV_INTEL_blocking_pipes, + SPV_INTEL_device_side_avc_motion_estimation, + SPV_INTEL_fpga_memory_attributes, + SPV_INTEL_fp_fast_math_mode, + SPV_INTEL_media_block_io, + SPV_INTEL_shader_integer_functions2, + SPV_INTEL_subgroups, + SPV_INTEL_fpga_cluster_attributes, + SPV_INTEL_kernel_attributes, + SPV_INTEL_arbitrary_precision_integers, + SPV_KHR_8bit_storage, + SPV_KHR_shader_clock, + SPV_KHR_device_group, + SPV_KHR_16bit_storage, + SPV_KHR_variable_pointers, + SPV_KHR_no_integer_wrap_decoration, + SPV_KHR_subgroup_vote, + SPV_KHR_multiview, + SPV_KHR_shader_ballot, + SPV_KHR_vulkan_memory_model, + SPV_KHR_physical_storage_buffer, + SPV_KHR_workgroup_memory_explicit_layout, + SPV_KHR_fragment_shading_rate, + SPV_KHR_shader_atomic_counter_ops, + SPV_KHR_shader_draw_parameters, + SPV_KHR_storage_buffer_storage_class, + SPV_KHR_linkonce_odr, + SPV_KHR_terminate_invocation, + SPV_KHR_non_semantic_info, + SPV_KHR_post_depth_coverage, + SPV_KHR_expect_assume, + SPV_KHR_ray_tracing, + SPV_KHR_ray_query, + SPV_KHR_float_controls, + SPV_NV_viewport_array2, + SPV_NV_shader_subgroup_partitioned, + SPV_NVX_multiview_per_view_attributes, + SPV_NV_ray_tracing, + SPV_NV_shader_image_footprint, + SPV_NV_shading_rate, + SPV_NV_stereo_view_rendering, + SPV_NV_compute_shader_derivatives, + SPV_NV_shader_sm_builtins, + SPV_NV_mesh_shader, + SPV_NV_geometry_shader_passthrough, + SPV_NV_fragment_shader_barycentric, + SPV_NV_cooperative_matrix, + SPV_NV_sample_mask_override_coverage, + Matrix, + Shader, + Geometry, + Tessellation, + Addresses, + Linkage, + Kernel, + Vector16, + Float16Buffer, + Float16, + Float64, + Int64, + Int64Atomics, + ImageBasic, + ImageReadWrite, + ImageMipmap, + Pipes, + Groups, + DeviceEnqueue, + LiteralSampler, + AtomicStorage, + Int16, + TessellationPointSize, + GeometryPointSize, + ImageGatherExtended, + StorageImageMultisample, + UniformBufferArrayDynamicIndexing, + SampledImageArrayDynamicIndexing, + StorageBufferArrayDynamicIndexing, + StorageImageArrayDynamicIndexing, + ClipDistance, + CullDistance, + ImageCubeArray, + SampleRateShading, + ImageRect, + SampledRect, + GenericPointer, + Int8, + InputAttachment, + SparseResidency, + MinLod, + Sampled1D, + Image1D, + SampledCubeArray, + SampledBuffer, + ImageBuffer, + ImageMSArray, + StorageImageExtendedFormats, + ImageQuery, + DerivativeControl, + InterpolationFunction, + TransformFeedback, + GeometryStreams, + StorageImageReadWithoutFormat, + StorageImageWriteWithoutFormat, + MultiViewport, + SubgroupDispatch, + NamedBarrier, + PipeStorage, + GroupNonUniform, + GroupNonUniformVote, + GroupNonUniformArithmetic, + GroupNonUniformBallot, + GroupNonUniformShuffle, + GroupNonUniformShuffleRelative, + GroupNonUniformClustered, + GroupNonUniformQuad, + ShaderLayer, + ShaderViewportIndex, + FragmentShadingRateKHR, + SubgroupBallotKHR, + DrawParameters, + WorkgroupMemoryExplicitLayoutKHR, + WorkgroupMemoryExplicitLayout8BitAccessKHR, + WorkgroupMemoryExplicitLayout16BitAccessKHR, + SubgroupVoteKHR, + StorageBuffer16BitAccess, + StorageUniformBufferBlock16, + UniformAndStorageBuffer16BitAccess, + StorageUniform16, + StoragePushConstant16, + StorageInputOutput16, + DeviceGroup, + MultiView, + VariablePointersStorageBuffer, + VariablePointers, + AtomicStorageOps, + SampleMaskPostDepthCoverage, + StorageBuffer8BitAccess, + UniformAndStorageBuffer8BitAccess, + StoragePushConstant8, + DenormPreserve, + DenormFlushToZero, + SignedZeroInfNanPreserve, + RoundingModeRTE, + RoundingModeRTZ, + RayQueryProvisionalKHR, + RayQueryKHR, + RayTraversalPrimitiveCullingKHR, + RayTracingKHR, + Float16ImageAMD, + ImageGatherBiasLodAMD, + FragmentMaskAMD, + StencilExportEXT, + ImageReadWriteLodAMD, + Int64ImageEXT, + ShaderClockKHR, + SampleMaskOverrideCoverageNV, + GeometryShaderPassthroughNV, + ShaderViewportIndexLayerEXT, + ShaderViewportIndexLayerNV, + ShaderViewportMaskNV, + ShaderStereoViewNV, + PerViewAttributesNV, + FragmentFullyCoveredEXT, + MeshShadingNV, + ImageFootprintNV, + FragmentBarycentricNV, + ComputeDerivativeGroupQuadsNV, + FragmentDensityEXT, + ShadingRateNV, + GroupNonUniformPartitionedNV, + ShaderNonUniform, + ShaderNonUniformEXT, + RuntimeDescriptorArray, + RuntimeDescriptorArrayEXT, + InputAttachmentArrayDynamicIndexing, + InputAttachmentArrayDynamicIndexingEXT, + UniformTexelBufferArrayDynamicIndexing, + UniformTexelBufferArrayDynamicIndexingEXT, + StorageTexelBufferArrayDynamicIndexing, + StorageTexelBufferArrayDynamicIndexingEXT, + UniformBufferArrayNonUniformIndexing, + UniformBufferArrayNonUniformIndexingEXT, + SampledImageArrayNonUniformIndexing, + SampledImageArrayNonUniformIndexingEXT, + StorageBufferArrayNonUniformIndexing, + StorageBufferArrayNonUniformIndexingEXT, + StorageImageArrayNonUniformIndexing, + StorageImageArrayNonUniformIndexingEXT, + InputAttachmentArrayNonUniformIndexing, + InputAttachmentArrayNonUniformIndexingEXT, + UniformTexelBufferArrayNonUniformIndexing, + UniformTexelBufferArrayNonUniformIndexingEXT, + StorageTexelBufferArrayNonUniformIndexing, + StorageTexelBufferArrayNonUniformIndexingEXT, + RayTracingNV, + VulkanMemoryModel, + VulkanMemoryModelKHR, + VulkanMemoryModelDeviceScope, + VulkanMemoryModelDeviceScopeKHR, + PhysicalStorageBufferAddresses, + PhysicalStorageBufferAddressesEXT, + ComputeDerivativeGroupLinearNV, + RayTracingProvisionalKHR, + CooperativeMatrixNV, + FragmentShaderSampleInterlockEXT, + FragmentShaderShadingRateInterlockEXT, + ShaderSMBuiltinsNV, + FragmentShaderPixelInterlockEXT, + DemoteToHelperInvocationEXT, + SubgroupShuffleINTEL, + SubgroupBufferBlockIOINTEL, + SubgroupImageBlockIOINTEL, + SubgroupImageMediaBlockIOINTEL, + RoundToInfinityINTEL, + FloatingPointModeINTEL, + IntegerFunctions2INTEL, + FunctionPointersINTEL, + IndirectReferencesINTEL, + AsmINTEL, + AtomicFloat32MinMaxEXT, + AtomicFloat64MinMaxEXT, + AtomicFloat16MinMaxEXT, + VectorComputeINTEL, + VectorAnyINTEL, + ExpectAssumeKHR, + SubgroupAvcMotionEstimationINTEL, + SubgroupAvcMotionEstimationIntraINTEL, + SubgroupAvcMotionEstimationChromaINTEL, + VariableLengthArrayINTEL, + FunctionFloatControlINTEL, + FPGAMemoryAttributesINTEL, + FPFastMathModeINTEL, + ArbitraryPrecisionIntegersINTEL, + UnstructuredLoopControlsINTEL, + FPGALoopControlsINTEL, + KernelAttributesINTEL, + FPGAKernelAttributesINTEL, + FPGAMemoryAccessesINTEL, + FPGAClusterAttributesINTEL, + LoopFuseINTEL, + FPGABufferLocationINTEL, + USMStorageClassesINTEL, + IOPipesINTEL, + BlockingPipesINTEL, + FPGARegINTEL, + AtomicFloat32AddEXT, + AtomicFloat64AddEXT, + LongConstantCompositeINTEL, +}; + +pub usingnamespace CpuFeature.feature_set_fns(Feature); + +pub const all_features = blk: { + @setEvalBranchQuota(2000); + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@enumToInt(Feature.v1_1)] = .{ + .llvm_name = null, + .description = "SPIR-V version 1.1", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.v1_2)] = .{ + .llvm_name = null, + .description = "SPIR-V version 1.2", + .dependencies = featureSet(&[_]Feature{ + .v1_1, + }), + }; + result[@enumToInt(Feature.v1_3)] = .{ + .llvm_name = null, + .description = "SPIR-V version 1.3", + .dependencies = featureSet(&[_]Feature{ + .v1_2, + }), + }; + result[@enumToInt(Feature.v1_4)] = .{ + .llvm_name = null, + .description = "SPIR-V version 1.4", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + }), + }; + result[@enumToInt(Feature.v1_5)] = .{ + .llvm_name = null, + .description = "SPIR-V version 1.5", + .dependencies = featureSet(&[_]Feature{ + .v1_4, + }), + }; + result[@enumToInt(Feature.SPV_AMD_shader_fragment_mask)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_shader_fragment_mask", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_AMD_gpu_shader_int16)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_gpu_shader_int16", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_AMD_gpu_shader_half_float)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_gpu_shader_half_float", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_AMD_texture_gather_bias_lod)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_texture_gather_bias_lod", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_AMD_shader_ballot)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_shader_ballot", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_AMD_gcn_shader)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_gcn_shader", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_AMD_shader_image_load_store_lod)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_shader_image_load_store_lod", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_AMD_shader_explicit_vertex_parameter)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_shader_explicit_vertex_parameter", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_AMD_shader_trinary_minmax)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_shader_trinary_minmax", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_AMD_gpu_shader_half_float_fetch)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_gpu_shader_half_float_fetch", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_GOOGLE_hlsl_functionality1)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_GOOGLE_hlsl_functionality1", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_GOOGLE_user_type)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_GOOGLE_user_type", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_GOOGLE_decorate_string)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_GOOGLE_decorate_string", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_EXT_demote_to_helper_invocation)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_demote_to_helper_invocation", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_EXT_descriptor_indexing)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_descriptor_indexing", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_EXT_fragment_fully_covered)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_fragment_fully_covered", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_EXT_shader_stencil_export)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_shader_stencil_export", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_EXT_physical_storage_buffer)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_physical_storage_buffer", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_EXT_shader_atomic_float_add)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_shader_atomic_float_add", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_EXT_shader_atomic_float_min_max)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_shader_atomic_float_min_max", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_EXT_shader_image_int64)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_shader_image_int64", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_EXT_fragment_shader_interlock)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_fragment_shader_interlock", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_EXT_fragment_invocation_density)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_fragment_invocation_density", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_EXT_shader_viewport_index_layer)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_shader_viewport_index_layer", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_loop_fuse)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_loop_fuse", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_fpga_dsp_control)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_fpga_dsp_control", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_fpga_reg)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_fpga_reg", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_fpga_memory_accesses)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_fpga_memory_accesses", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_fpga_loop_controls)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_fpga_loop_controls", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_io_pipes)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_io_pipes", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_unstructured_loop_controls)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_unstructured_loop_controls", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_blocking_pipes)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_blocking_pipes", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_device_side_avc_motion_estimation)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_device_side_avc_motion_estimation", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_fpga_memory_attributes)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_fpga_memory_attributes", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_fp_fast_math_mode)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_fp_fast_math_mode", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_media_block_io)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_media_block_io", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_shader_integer_functions2)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_shader_integer_functions2", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_subgroups)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_subgroups", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_fpga_cluster_attributes)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_fpga_cluster_attributes", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_kernel_attributes)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_kernel_attributes", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_INTEL_arbitrary_precision_integers)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_arbitrary_precision_integers", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_8bit_storage)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_8bit_storage", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_shader_clock)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_shader_clock", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_device_group)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_device_group", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_16bit_storage)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_16bit_storage", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_variable_pointers)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_variable_pointers", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_no_integer_wrap_decoration)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_no_integer_wrap_decoration", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_subgroup_vote)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_subgroup_vote", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_multiview)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_multiview", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_shader_ballot)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_shader_ballot", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_vulkan_memory_model)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_vulkan_memory_model", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_physical_storage_buffer)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_physical_storage_buffer", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_workgroup_memory_explicit_layout)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_workgroup_memory_explicit_layout", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_fragment_shading_rate)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_fragment_shading_rate", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_shader_atomic_counter_ops)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_shader_atomic_counter_ops", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_shader_draw_parameters)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_shader_draw_parameters", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_storage_buffer_storage_class)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_storage_buffer_storage_class", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_linkonce_odr)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_linkonce_odr", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_terminate_invocation)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_terminate_invocation", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_non_semantic_info)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_non_semantic_info", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_post_depth_coverage)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_post_depth_coverage", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_expect_assume)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_expect_assume", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_ray_tracing)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_ray_tracing", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_ray_query)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_ray_query", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_KHR_float_controls)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_float_controls", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_NV_viewport_array2)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_viewport_array2", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_NV_shader_subgroup_partitioned)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_shader_subgroup_partitioned", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_NVX_multiview_per_view_attributes)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NVX_multiview_per_view_attributes", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_NV_ray_tracing)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_ray_tracing", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_NV_shader_image_footprint)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_shader_image_footprint", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_NV_shading_rate)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_shading_rate", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_NV_stereo_view_rendering)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_stereo_view_rendering", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_NV_compute_shader_derivatives)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_compute_shader_derivatives", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_NV_shader_sm_builtins)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_shader_sm_builtins", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_NV_mesh_shader)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_mesh_shader", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_NV_geometry_shader_passthrough)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_geometry_shader_passthrough", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_NV_fragment_shader_barycentric)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_fragment_shader_barycentric", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_NV_cooperative_matrix)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_cooperative_matrix", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.SPV_NV_sample_mask_override_coverage)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_sample_mask_override_coverage", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@enumToInt(Feature.Matrix)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Matrix", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.Shader)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Shader", + .dependencies = featureSet(&[_]Feature{ + .Matrix, + }), + }; + result[@enumToInt(Feature.Geometry)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Geometry", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.Tessellation)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Tessellation", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.Addresses)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Addresses", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.Linkage)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Linkage", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.Kernel)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Kernel", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.Vector16)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Vector16", + .dependencies = featureSet(&[_]Feature{ + .Kernel, + }), + }; + result[@enumToInt(Feature.Float16Buffer)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Float16Buffer", + .dependencies = featureSet(&[_]Feature{ + .Kernel, + }), + }; + result[@enumToInt(Feature.Float16)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Float16", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.Float64)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Float64", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.Int64)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Int64", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.Int64Atomics)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Int64Atomics", + .dependencies = featureSet(&[_]Feature{ + .Int64, + }), + }; + result[@enumToInt(Feature.ImageBasic)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageBasic", + .dependencies = featureSet(&[_]Feature{ + .Kernel, + }), + }; + result[@enumToInt(Feature.ImageReadWrite)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageReadWrite", + .dependencies = featureSet(&[_]Feature{ + .ImageBasic, + }), + }; + result[@enumToInt(Feature.ImageMipmap)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageMipmap", + .dependencies = featureSet(&[_]Feature{ + .ImageBasic, + }), + }; + result[@enumToInt(Feature.Pipes)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Pipes", + .dependencies = featureSet(&[_]Feature{ + .Kernel, + }), + }; + result[@enumToInt(Feature.Groups)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Groups", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.DeviceEnqueue)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability DeviceEnqueue", + .dependencies = featureSet(&[_]Feature{ + .Kernel, + }), + }; + result[@enumToInt(Feature.LiteralSampler)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability LiteralSampler", + .dependencies = featureSet(&[_]Feature{ + .Kernel, + }), + }; + result[@enumToInt(Feature.AtomicStorage)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability AtomicStorage", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.Int16)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Int16", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.TessellationPointSize)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability TessellationPointSize", + .dependencies = featureSet(&[_]Feature{ + .Tessellation, + }), + }; + result[@enumToInt(Feature.GeometryPointSize)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GeometryPointSize", + .dependencies = featureSet(&[_]Feature{ + .Geometry, + }), + }; + result[@enumToInt(Feature.ImageGatherExtended)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageGatherExtended", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.StorageImageMultisample)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageImageMultisample", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.UniformBufferArrayDynamicIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformBufferArrayDynamicIndexing", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.SampledImageArrayDynamicIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampledImageArrayDynamicIndexing", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.StorageBufferArrayDynamicIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageBufferArrayDynamicIndexing", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.StorageImageArrayDynamicIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageImageArrayDynamicIndexing", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.ClipDistance)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ClipDistance", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.CullDistance)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability CullDistance", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.ImageCubeArray)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageCubeArray", + .dependencies = featureSet(&[_]Feature{ + .SampledCubeArray, + }), + }; + result[@enumToInt(Feature.SampleRateShading)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampleRateShading", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.ImageRect)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageRect", + .dependencies = featureSet(&[_]Feature{ + .SampledRect, + }), + }; + result[@enumToInt(Feature.SampledRect)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampledRect", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.GenericPointer)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GenericPointer", + .dependencies = featureSet(&[_]Feature{ + .Addresses, + }), + }; + result[@enumToInt(Feature.Int8)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Int8", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.InputAttachment)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability InputAttachment", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.SparseResidency)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SparseResidency", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.MinLod)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability MinLod", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.Sampled1D)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Sampled1D", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.Image1D)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Image1D", + .dependencies = featureSet(&[_]Feature{ + .Sampled1D, + }), + }; + result[@enumToInt(Feature.SampledCubeArray)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampledCubeArray", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.SampledBuffer)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampledBuffer", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.ImageBuffer)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageBuffer", + .dependencies = featureSet(&[_]Feature{ + .SampledBuffer, + }), + }; + result[@enumToInt(Feature.ImageMSArray)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageMSArray", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.StorageImageExtendedFormats)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageImageExtendedFormats", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.ImageQuery)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageQuery", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.DerivativeControl)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability DerivativeControl", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.InterpolationFunction)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability InterpolationFunction", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.TransformFeedback)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability TransformFeedback", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.GeometryStreams)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GeometryStreams", + .dependencies = featureSet(&[_]Feature{ + .Geometry, + }), + }; + result[@enumToInt(Feature.StorageImageReadWithoutFormat)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageImageReadWithoutFormat", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.StorageImageWriteWithoutFormat)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageImageWriteWithoutFormat", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.MultiViewport)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability MultiViewport", + .dependencies = featureSet(&[_]Feature{ + .Geometry, + }), + }; + result[@enumToInt(Feature.SubgroupDispatch)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupDispatch", + .dependencies = featureSet(&[_]Feature{ + .v1_1, + .DeviceEnqueue, + }), + }; + result[@enumToInt(Feature.NamedBarrier)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability NamedBarrier", + .dependencies = featureSet(&[_]Feature{ + .v1_1, + .Kernel, + }), + }; + result[@enumToInt(Feature.PipeStorage)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability PipeStorage", + .dependencies = featureSet(&[_]Feature{ + .v1_1, + .Pipes, + }), + }; + result[@enumToInt(Feature.GroupNonUniform)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniform", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + }), + }; + result[@enumToInt(Feature.GroupNonUniformVote)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniformVote", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .GroupNonUniform, + }), + }; + result[@enumToInt(Feature.GroupNonUniformArithmetic)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniformArithmetic", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .GroupNonUniform, + }), + }; + result[@enumToInt(Feature.GroupNonUniformBallot)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniformBallot", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .GroupNonUniform, + }), + }; + result[@enumToInt(Feature.GroupNonUniformShuffle)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniformShuffle", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .GroupNonUniform, + }), + }; + result[@enumToInt(Feature.GroupNonUniformShuffleRelative)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniformShuffleRelative", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .GroupNonUniform, + }), + }; + result[@enumToInt(Feature.GroupNonUniformClustered)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniformClustered", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .GroupNonUniform, + }), + }; + result[@enumToInt(Feature.GroupNonUniformQuad)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniformQuad", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .GroupNonUniform, + }), + }; + result[@enumToInt(Feature.ShaderLayer)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderLayer", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + }), + }; + result[@enumToInt(Feature.ShaderViewportIndex)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderViewportIndex", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + }), + }; + result[@enumToInt(Feature.FragmentShadingRateKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FragmentShadingRateKHR", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.SubgroupBallotKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupBallotKHR", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.DrawParameters)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability DrawParameters", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .Shader, + }), + }; + result[@enumToInt(Feature.WorkgroupMemoryExplicitLayoutKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability WorkgroupMemoryExplicitLayoutKHR", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.WorkgroupMemoryExplicitLayout8BitAccessKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability WorkgroupMemoryExplicitLayout8BitAccessKHR", + .dependencies = featureSet(&[_]Feature{ + .WorkgroupMemoryExplicitLayoutKHR, + }), + }; + result[@enumToInt(Feature.WorkgroupMemoryExplicitLayout16BitAccessKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability WorkgroupMemoryExplicitLayout16BitAccessKHR", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.SubgroupVoteKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupVoteKHR", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.StorageBuffer16BitAccess)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageBuffer16BitAccess", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + }), + }; + result[@enumToInt(Feature.StorageUniformBufferBlock16)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageUniformBufferBlock16", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + }), + }; + result[@enumToInt(Feature.UniformAndStorageBuffer16BitAccess)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformAndStorageBuffer16BitAccess", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .StorageBuffer16BitAccess, + .StorageUniformBufferBlock16, + }), + }; + result[@enumToInt(Feature.StorageUniform16)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageUniform16", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .StorageBuffer16BitAccess, + .StorageUniformBufferBlock16, + }), + }; + result[@enumToInt(Feature.StoragePushConstant16)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StoragePushConstant16", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + }), + }; + result[@enumToInt(Feature.StorageInputOutput16)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageInputOutput16", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + }), + }; + result[@enumToInt(Feature.DeviceGroup)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability DeviceGroup", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + }), + }; + result[@enumToInt(Feature.MultiView)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability MultiView", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .Shader, + }), + }; + result[@enumToInt(Feature.VariablePointersStorageBuffer)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VariablePointersStorageBuffer", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .Shader, + }), + }; + result[@enumToInt(Feature.VariablePointers)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VariablePointers", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .VariablePointersStorageBuffer, + }), + }; + result[@enumToInt(Feature.AtomicStorageOps)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability AtomicStorageOps", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.SampleMaskPostDepthCoverage)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampleMaskPostDepthCoverage", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.StorageBuffer8BitAccess)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageBuffer8BitAccess", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + }), + }; + result[@enumToInt(Feature.UniformAndStorageBuffer8BitAccess)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformAndStorageBuffer8BitAccess", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .StorageBuffer8BitAccess, + }), + }; + result[@enumToInt(Feature.StoragePushConstant8)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StoragePushConstant8", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + }), + }; + result[@enumToInt(Feature.DenormPreserve)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability DenormPreserve", + .dependencies = featureSet(&[_]Feature{ + .v1_4, + }), + }; + result[@enumToInt(Feature.DenormFlushToZero)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability DenormFlushToZero", + .dependencies = featureSet(&[_]Feature{ + .v1_4, + }), + }; + result[@enumToInt(Feature.SignedZeroInfNanPreserve)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SignedZeroInfNanPreserve", + .dependencies = featureSet(&[_]Feature{ + .v1_4, + }), + }; + result[@enumToInt(Feature.RoundingModeRTE)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RoundingModeRTE", + .dependencies = featureSet(&[_]Feature{ + .v1_4, + }), + }; + result[@enumToInt(Feature.RoundingModeRTZ)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RoundingModeRTZ", + .dependencies = featureSet(&[_]Feature{ + .v1_4, + }), + }; + result[@enumToInt(Feature.RayQueryProvisionalKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RayQueryProvisionalKHR", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.RayQueryKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RayQueryKHR", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.RayTraversalPrimitiveCullingKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RayTraversalPrimitiveCullingKHR", + .dependencies = featureSet(&[_]Feature{ + .RayQueryKHR, + .RayTracingKHR, + }), + }; + result[@enumToInt(Feature.RayTracingKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RayTracingKHR", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.Float16ImageAMD)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Float16ImageAMD", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.ImageGatherBiasLodAMD)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageGatherBiasLodAMD", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.FragmentMaskAMD)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FragmentMaskAMD", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.StencilExportEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StencilExportEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.ImageReadWriteLodAMD)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageReadWriteLodAMD", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.Int64ImageEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Int64ImageEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.ShaderClockKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderClockKHR", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.SampleMaskOverrideCoverageNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampleMaskOverrideCoverageNV", + .dependencies = featureSet(&[_]Feature{ + .SampleRateShading, + }), + }; + result[@enumToInt(Feature.GeometryShaderPassthroughNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GeometryShaderPassthroughNV", + .dependencies = featureSet(&[_]Feature{ + .Geometry, + }), + }; + result[@enumToInt(Feature.ShaderViewportIndexLayerEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderViewportIndexLayerEXT", + .dependencies = featureSet(&[_]Feature{ + .MultiViewport, + }), + }; + result[@enumToInt(Feature.ShaderViewportIndexLayerNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderViewportIndexLayerNV", + .dependencies = featureSet(&[_]Feature{ + .MultiViewport, + }), + }; + result[@enumToInt(Feature.ShaderViewportMaskNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderViewportMaskNV", + .dependencies = featureSet(&[_]Feature{ + .ShaderViewportIndexLayerNV, + }), + }; + result[@enumToInt(Feature.ShaderStereoViewNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderStereoViewNV", + .dependencies = featureSet(&[_]Feature{ + .ShaderViewportMaskNV, + }), + }; + result[@enumToInt(Feature.PerViewAttributesNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability PerViewAttributesNV", + .dependencies = featureSet(&[_]Feature{ + .MultiView, + }), + }; + result[@enumToInt(Feature.FragmentFullyCoveredEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FragmentFullyCoveredEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.MeshShadingNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability MeshShadingNV", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.ImageFootprintNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageFootprintNV", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.FragmentBarycentricNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FragmentBarycentricNV", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.ComputeDerivativeGroupQuadsNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ComputeDerivativeGroupQuadsNV", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.FragmentDensityEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FragmentDensityEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.ShadingRateNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShadingRateNV", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.GroupNonUniformPartitionedNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniformPartitionedNV", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.ShaderNonUniform)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderNonUniform", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .Shader, + }), + }; + result[@enumToInt(Feature.ShaderNonUniformEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderNonUniformEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .Shader, + }), + }; + result[@enumToInt(Feature.RuntimeDescriptorArray)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RuntimeDescriptorArray", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .Shader, + }), + }; + result[@enumToInt(Feature.RuntimeDescriptorArrayEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RuntimeDescriptorArrayEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .Shader, + }), + }; + result[@enumToInt(Feature.InputAttachmentArrayDynamicIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability InputAttachmentArrayDynamicIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .InputAttachment, + }), + }; + result[@enumToInt(Feature.InputAttachmentArrayDynamicIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability InputAttachmentArrayDynamicIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .InputAttachment, + }), + }; + result[@enumToInt(Feature.UniformTexelBufferArrayDynamicIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformTexelBufferArrayDynamicIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .SampledBuffer, + }), + }; + result[@enumToInt(Feature.UniformTexelBufferArrayDynamicIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformTexelBufferArrayDynamicIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .SampledBuffer, + }), + }; + result[@enumToInt(Feature.StorageTexelBufferArrayDynamicIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageTexelBufferArrayDynamicIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ImageBuffer, + }), + }; + result[@enumToInt(Feature.StorageTexelBufferArrayDynamicIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageTexelBufferArrayDynamicIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ImageBuffer, + }), + }; + result[@enumToInt(Feature.UniformBufferArrayNonUniformIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformBufferArrayNonUniformIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ShaderNonUniform, + }), + }; + result[@enumToInt(Feature.UniformBufferArrayNonUniformIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformBufferArrayNonUniformIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ShaderNonUniform, + }), + }; + result[@enumToInt(Feature.SampledImageArrayNonUniformIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampledImageArrayNonUniformIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ShaderNonUniform, + }), + }; + result[@enumToInt(Feature.SampledImageArrayNonUniformIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampledImageArrayNonUniformIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ShaderNonUniform, + }), + }; + result[@enumToInt(Feature.StorageBufferArrayNonUniformIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageBufferArrayNonUniformIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ShaderNonUniform, + }), + }; + result[@enumToInt(Feature.StorageBufferArrayNonUniformIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageBufferArrayNonUniformIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ShaderNonUniform, + }), + }; + result[@enumToInt(Feature.StorageImageArrayNonUniformIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageImageArrayNonUniformIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ShaderNonUniform, + }), + }; + result[@enumToInt(Feature.StorageImageArrayNonUniformIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageImageArrayNonUniformIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ShaderNonUniform, + }), + }; + result[@enumToInt(Feature.InputAttachmentArrayNonUniformIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability InputAttachmentArrayNonUniformIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .InputAttachment, + .ShaderNonUniform, + }), + }; + result[@enumToInt(Feature.InputAttachmentArrayNonUniformIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability InputAttachmentArrayNonUniformIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .InputAttachment, + .ShaderNonUniform, + }), + }; + result[@enumToInt(Feature.UniformTexelBufferArrayNonUniformIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformTexelBufferArrayNonUniformIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .SampledBuffer, + .ShaderNonUniform, + }), + }; + result[@enumToInt(Feature.UniformTexelBufferArrayNonUniformIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformTexelBufferArrayNonUniformIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .SampledBuffer, + .ShaderNonUniform, + }), + }; + result[@enumToInt(Feature.StorageTexelBufferArrayNonUniformIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageTexelBufferArrayNonUniformIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ImageBuffer, + .ShaderNonUniform, + }), + }; + result[@enumToInt(Feature.StorageTexelBufferArrayNonUniformIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageTexelBufferArrayNonUniformIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ImageBuffer, + .ShaderNonUniform, + }), + }; + result[@enumToInt(Feature.RayTracingNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RayTracingNV", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.VulkanMemoryModel)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VulkanMemoryModel", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + }), + }; + result[@enumToInt(Feature.VulkanMemoryModelKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VulkanMemoryModelKHR", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + }), + }; + result[@enumToInt(Feature.VulkanMemoryModelDeviceScope)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VulkanMemoryModelDeviceScope", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + }), + }; + result[@enumToInt(Feature.VulkanMemoryModelDeviceScopeKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VulkanMemoryModelDeviceScopeKHR", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + }), + }; + result[@enumToInt(Feature.PhysicalStorageBufferAddresses)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability PhysicalStorageBufferAddresses", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .Shader, + }), + }; + result[@enumToInt(Feature.PhysicalStorageBufferAddressesEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability PhysicalStorageBufferAddressesEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .Shader, + }), + }; + result[@enumToInt(Feature.ComputeDerivativeGroupLinearNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ComputeDerivativeGroupLinearNV", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.RayTracingProvisionalKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RayTracingProvisionalKHR", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.CooperativeMatrixNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability CooperativeMatrixNV", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.FragmentShaderSampleInterlockEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FragmentShaderSampleInterlockEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.FragmentShaderShadingRateInterlockEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FragmentShaderShadingRateInterlockEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.ShaderSMBuiltinsNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderSMBuiltinsNV", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.FragmentShaderPixelInterlockEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FragmentShaderPixelInterlockEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.DemoteToHelperInvocationEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability DemoteToHelperInvocationEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.SubgroupShuffleINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupShuffleINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.SubgroupBufferBlockIOINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupBufferBlockIOINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.SubgroupImageBlockIOINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupImageBlockIOINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.SubgroupImageMediaBlockIOINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupImageMediaBlockIOINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.RoundToInfinityINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RoundToInfinityINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.FloatingPointModeINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FloatingPointModeINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.IntegerFunctions2INTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability IntegerFunctions2INTEL", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.FunctionPointersINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FunctionPointersINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.IndirectReferencesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability IndirectReferencesINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.AsmINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability AsmINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.AtomicFloat32MinMaxEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability AtomicFloat32MinMaxEXT", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.AtomicFloat64MinMaxEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability AtomicFloat64MinMaxEXT", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.AtomicFloat16MinMaxEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability AtomicFloat16MinMaxEXT", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.VectorComputeINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VectorComputeINTEL", + .dependencies = featureSet(&[_]Feature{ + .VectorAnyINTEL, + }), + }; + result[@enumToInt(Feature.VectorAnyINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VectorAnyINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.ExpectAssumeKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ExpectAssumeKHR", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.SubgroupAvcMotionEstimationINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupAvcMotionEstimationINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.SubgroupAvcMotionEstimationIntraINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupAvcMotionEstimationIntraINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.SubgroupAvcMotionEstimationChromaINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupAvcMotionEstimationChromaINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.VariableLengthArrayINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VariableLengthArrayINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.FunctionFloatControlINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FunctionFloatControlINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.FPGAMemoryAttributesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FPGAMemoryAttributesINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.FPFastMathModeINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FPFastMathModeINTEL", + .dependencies = featureSet(&[_]Feature{ + .Kernel, + }), + }; + result[@enumToInt(Feature.ArbitraryPrecisionIntegersINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ArbitraryPrecisionIntegersINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.UnstructuredLoopControlsINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UnstructuredLoopControlsINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.FPGALoopControlsINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FPGALoopControlsINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.KernelAttributesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability KernelAttributesINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.FPGAKernelAttributesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FPGAKernelAttributesINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.FPGAMemoryAccessesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FPGAMemoryAccessesINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.FPGAClusterAttributesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FPGAClusterAttributesINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.LoopFuseINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability LoopFuseINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.FPGABufferLocationINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FPGABufferLocationINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.USMStorageClassesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability USMStorageClassesINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.IOPipesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability IOPipesINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.BlockingPipesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability BlockingPipesINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.FPGARegINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FPGARegINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + result[@enumToInt(Feature.AtomicFloat32AddEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability AtomicFloat32AddEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.AtomicFloat64AddEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability AtomicFloat64AddEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@enumToInt(Feature.LongConstantCompositeINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability LongConstantCompositeINTEL", + .dependencies = featureSet(&[_]Feature{ + }), + }; + const ti = @typeInfo(Feature); + for (result) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 61b71cf5ff..be3e76dcdb 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -29,11 +29,11 @@ pub var zig_exe_path: []const u8 = undefined; /// and then aborts when actual_error_union is not expected_error. pub fn expectError(expected_error: anyerror, actual_error_union: anytype) !void { if (actual_error_union) |actual_payload| { - std.debug.print("expected error.{s}, found {any}", .{ @errorName(expected_error), actual_payload }); + std.debug.print("expected error.{s}, found {any}\n", .{ @errorName(expected_error), actual_payload }); return error.TestUnexpectedError; } else |actual_error| { if (expected_error != actual_error) { - std.debug.print("expected error.{s}, found error.{s}", .{ + std.debug.print("expected error.{s}, found error.{s}\n", .{ @errorName(expected_error), @errorName(actual_error), }); @@ -62,7 +62,7 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) !void { .Type => { if (actual != expected) { - std.debug.print("expected type {s}, found type {s}", .{ @typeName(expected), @typeName(actual) }); + std.debug.print("expected type {s}, found type {s}\n", .{ @typeName(expected), @typeName(actual) }); return error.TestExpectedEqual; } }, @@ -78,7 +78,7 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) !void { .ErrorSet, => { if (actual != expected) { - std.debug.print("expected {}, found {}", .{ expected, actual }); + std.debug.print("expected {}, found {}\n", .{ expected, actual }); return error.TestExpectedEqual; } }, @@ -87,17 +87,17 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) !void { switch (pointer.size) { .One, .Many, .C => { if (actual != expected) { - std.debug.print("expected {*}, found {*}", .{ expected, actual }); + std.debug.print("expected {*}, found {*}\n", .{ expected, actual }); return error.TestExpectedEqual; } }, .Slice => { if (actual.ptr != expected.ptr) { - std.debug.print("expected slice ptr {*}, found {*}", .{ expected.ptr, actual.ptr }); + std.debug.print("expected slice ptr {*}, found {*}\n", .{ expected.ptr, actual.ptr }); return error.TestExpectedEqual; } if (actual.len != expected.len) { - std.debug.print("expected slice len {}, found {}", .{ expected.len, actual.len }); + std.debug.print("expected slice len {}, found {}\n", .{ expected.len, actual.len }); return error.TestExpectedEqual; } }, @@ -110,7 +110,7 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) !void { var i: usize = 0; while (i < vectorType.len) : (i += 1) { if (!std.meta.eql(expected[i], actual[i])) { - std.debug.print("index {} incorrect. expected {}, found {}", .{ i, expected[i], actual[i] }); + std.debug.print("index {} incorrect. expected {}, found {}\n", .{ i, expected[i], actual[i] }); return error.TestExpectedEqual; } } @@ -153,12 +153,12 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) !void { if (actual) |actual_payload| { try expectEqual(expected_payload, actual_payload); } else { - std.debug.print("expected {any}, found null", .{expected_payload}); + std.debug.print("expected {any}, found null\n", .{expected_payload}); return error.TestExpectedEqual; } } else { if (actual) |actual_payload| { - std.debug.print("expected null, found {any}", .{actual_payload}); + std.debug.print("expected null, found {any}\n", .{actual_payload}); return error.TestExpectedEqual; } } @@ -169,12 +169,12 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) !void { if (actual) |actual_payload| { try expectEqual(expected_payload, actual_payload); } else |actual_err| { - std.debug.print("expected {any}, found {}", .{ expected_payload, actual_err }); + std.debug.print("expected {any}, found {}\n", .{ expected_payload, actual_err }); return error.TestExpectedEqual; } } else |expected_err| { if (actual) |actual_payload| { - std.debug.print("expected {}, found {any}", .{ expected_err, actual_payload }); + std.debug.print("expected {}, found {any}\n", .{ expected_err, actual_payload }); return error.TestExpectedEqual; } else |actual_err| { try expectEqual(expected_err, actual_err); @@ -225,7 +225,7 @@ pub fn expectApproxEqAbs(expected: anytype, actual: @TypeOf(expected), tolerance switch (@typeInfo(T)) { .Float => if (!math.approxEqAbs(T, expected, actual, tolerance)) { - std.debug.print("actual {}, not within absolute tolerance {} of expected {}", .{ actual, tolerance, expected }); + std.debug.print("actual {}, not within absolute tolerance {} of expected {}\n", .{ actual, tolerance, expected }); return error.TestExpectedApproxEqAbs; }, @@ -257,7 +257,7 @@ pub fn expectApproxEqRel(expected: anytype, actual: @TypeOf(expected), tolerance switch (@typeInfo(T)) { .Float => if (!math.approxEqRel(T, expected, actual, tolerance)) { - std.debug.print("actual {}, not within relative tolerance {} of expected {}", .{ actual, tolerance, expected }); + std.debug.print("actual {}, not within relative tolerance {} of expected {}\n", .{ actual, tolerance, expected }); return error.TestExpectedApproxEqRel; }, @@ -292,13 +292,13 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const // If the child type is u8 and no weird bytes, we could print it as strings // Even for the length difference, it would be useful to see the values of the slices probably. if (expected.len != actual.len) { - std.debug.print("slice lengths differ. expected {d}, found {d}", .{ expected.len, actual.len }); + std.debug.print("slice lengths differ. expected {d}, found {d}\n", .{ expected.len, actual.len }); return error.TestExpectedEqual; } var i: usize = 0; while (i < expected.len) : (i += 1) { if (!std.meta.eql(expected[i], actual[i])) { - std.debug.print("index {} incorrect. expected {any}, found {any}", .{ i, expected[i], actual[i] }); + std.debug.print("index {} incorrect. expected {any}, found {any}\n", .{ i, expected[i], actual[i] }); return error.TestExpectedEqual; } } diff --git a/lib/std/zig/cross_target.zig b/lib/std/zig/cross_target.zig index bf62a49ef6..e724be17ae 100644 --- a/lib/std/zig/cross_target.zig +++ b/lib/std/zig/cross_target.zig @@ -606,6 +606,7 @@ pub const CrossTarget = struct { qemu: []const u8, wine: []const u8, wasmtime: []const u8, + darling: []const u8, unavailable, }; @@ -667,6 +668,15 @@ pub const CrossTarget = struct { 32 => return Executor{ .wasmtime = "wasmtime" }, else => return .unavailable, }, + .macos => { + // TODO loosen this check once upstream adds QEMU-based emulation + // layer for non-host architectures: + // https://github.com/darlinghq/darling/issues/863 + if (cpu_arch != Target.current.cpu.arch) { + return .unavailable; + } + return Executor{ .darling = "darling" }; + }, else => return .unavailable, } } diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index b0da57f0e2..32eeeb4add 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -1309,9 +1309,8 @@ const Parser = struct { return expr; } - /// Expr <- BoolOrExpr fn parseExpr(p: *Parser) Error!Node.Index { - return p.parseBoolOrExpr(); + return p.parseExprPrecedence(0); } fn expectExpr(p: *Parser) Error!Node.Index { @@ -1323,263 +1322,100 @@ const Parser = struct { } } - /// BoolOrExpr <- BoolAndExpr (KEYWORD_or BoolAndExpr)* - fn parseBoolOrExpr(p: *Parser) Error!Node.Index { - var res = try p.parseBoolAndExpr(); - if (res == 0) return null_node; + const Assoc = enum { + left, + none, + }; - while (true) { - switch (p.token_tags[p.tok_i]) { - .keyword_or => { - const or_token = p.nextToken(); - const rhs = try p.parseBoolAndExpr(); - if (rhs == 0) { - return p.fail(.invalid_token); - } - res = try p.addNode(.{ - .tag = .bool_or, - .main_token = or_token, - .data = .{ - .lhs = res, - .rhs = rhs, - }, - }); - }, - else => return res, - } - } - } + const OperInfo = struct { + prec: i8, + tag: Node.Tag, + assoc: Assoc = Assoc.left, + }; - /// BoolAndExpr <- CompareExpr (KEYWORD_and CompareExpr)* - fn parseBoolAndExpr(p: *Parser) !Node.Index { - var res = try p.parseCompareExpr(); - if (res == 0) return null_node; + // A table of binary operator information. Higher precedence numbers are + // stickier. All operators at the same precedence level should have the same + // associativity. + const operTable = std.enums.directEnumArrayDefault(Token.Tag, OperInfo, .{ .prec = -1, .tag = Node.Tag.root }, 0, .{ + .keyword_or = .{ .prec = 10, .tag = .bool_or }, + + .keyword_and = .{ .prec = 20, .tag = .bool_and }, + .invalid_ampersands = .{ .prec = 20, .tag = .bool_and }, + + .equal_equal = .{ .prec = 30, .tag = .equal_equal, .assoc = Assoc.none }, + .bang_equal = .{ .prec = 30, .tag = .bang_equal, .assoc = Assoc.none }, + .angle_bracket_left = .{ .prec = 30, .tag = .less_than, .assoc = Assoc.none }, + .angle_bracket_right = .{ .prec = 30, .tag = .greater_than, .assoc = Assoc.none }, + .angle_bracket_left_equal = .{ .prec = 30, .tag = .less_or_equal, .assoc = Assoc.none }, + .angle_bracket_right_equal = .{ .prec = 30, .tag = .greater_or_equal, .assoc = Assoc.none }, + + .ampersand = .{ .prec = 40, .tag = .bit_and }, + .caret = .{ .prec = 40, .tag = .bit_xor }, + .pipe = .{ .prec = 40, .tag = .bit_or }, + .keyword_orelse = .{ .prec = 40, .tag = .@"orelse" }, + .keyword_catch = .{ .prec = 40, .tag = .@"catch" }, + + .angle_bracket_angle_bracket_left = .{ .prec = 50, .tag = .bit_shift_left }, + .angle_bracket_angle_bracket_right = .{ .prec = 50, .tag = .bit_shift_right }, + + .plus = .{ .prec = 60, .tag = .add }, + .minus = .{ .prec = 60, .tag = .sub }, + .plus_plus = .{ .prec = 60, .tag = .array_cat }, + .plus_percent = .{ .prec = 60, .tag = .add_wrap }, + .minus_percent = .{ .prec = 60, .tag = .sub_wrap }, + + .pipe_pipe = .{ .prec = 70, .tag = .merge_error_sets }, + .asterisk = .{ .prec = 70, .tag = .mul }, + .slash = .{ .prec = 70, .tag = .div }, + .percent = .{ .prec = 70, .tag = .mod }, + .asterisk_asterisk = .{ .prec = 70, .tag = .array_mult }, + .asterisk_percent = .{ .prec = 70, .tag = .mul_wrap }, + }); - while (true) { - switch (p.token_tags[p.tok_i]) { - .keyword_and => { - const and_token = p.nextToken(); - const rhs = try p.parseCompareExpr(); - if (rhs == 0) { - return p.fail(.invalid_token); - } - res = try p.addNode(.{ - .tag = .bool_and, - .main_token = and_token, - .data = .{ - .lhs = res, - .rhs = rhs, - }, - }); - }, - .invalid_ampersands => { - try p.warn(.invalid_and); - p.tok_i += 1; - return p.parseCompareExpr(); - }, - else => return res, - } + fn parseExprPrecedence(p: *Parser, min_prec: i32) Error!Node.Index { + var node = try p.parsePrefixExpr(); + if (node == 0) { + return null_node; } - } - /// CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr)? - /// CompareOp - /// <- EQUALEQUAL - /// / EXCLAMATIONMARKEQUAL - /// / LARROW - /// / RARROW - /// / LARROWEQUAL - /// / RARROWEQUAL - fn parseCompareExpr(p: *Parser) !Node.Index { - const expr = try p.parseBitwiseExpr(); - if (expr == 0) return null_node; - - const tag: Node.Tag = switch (p.token_tags[p.tok_i]) { - .equal_equal => .equal_equal, - .bang_equal => .bang_equal, - .angle_bracket_left => .less_than, - .angle_bracket_right => .greater_than, - .angle_bracket_left_equal => .less_or_equal, - .angle_bracket_right_equal => .greater_or_equal, - else => return expr, - }; - return p.addNode(.{ - .tag = tag, - .main_token = p.nextToken(), - .data = .{ - .lhs = expr, - .rhs = try p.expectBitwiseExpr(), - }, - }); - } - - /// BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)* - /// BitwiseOp - /// <- AMPERSAND - /// / CARET - /// / PIPE - /// / KEYWORD_orelse - /// / KEYWORD_catch Payload? - fn parseBitwiseExpr(p: *Parser) !Node.Index { - var res = try p.parseBitShiftExpr(); - if (res == 0) return null_node; + var banned_prec: i8 = -1; while (true) { - const tag: Node.Tag = switch (p.token_tags[p.tok_i]) { - .ampersand => .bit_and, - .caret => .bit_xor, - .pipe => .bit_or, - .keyword_orelse => .@"orelse", + const tok_tag = p.token_tags[p.tok_i]; + const info = operTable[@intCast(usize, @enumToInt(tok_tag))]; + if (info.prec < min_prec or info.prec == banned_prec) { + break; + } + const oper_token = p.nextToken(); + // Special-case handling for "catch" and "&&". + switch (tok_tag) { .keyword_catch => { - const catch_token = p.nextToken(); _ = try p.parsePayload(); - const rhs = try p.parseBitShiftExpr(); - if (rhs == 0) { - return p.fail(.invalid_token); - } - res = try p.addNode(.{ - .tag = .@"catch", - .main_token = catch_token, - .data = .{ - .lhs = res, - .rhs = rhs, - }, - }); - continue; - }, - else => return res, - }; - res = try p.addNode(.{ - .tag = tag, - .main_token = p.nextToken(), - .data = .{ - .lhs = res, - .rhs = try p.expectBitShiftExpr(), }, - }); - } - } - - fn expectBitwiseExpr(p: *Parser) Error!Node.Index { - const node = try p.parseBitwiseExpr(); - if (node == 0) { - return p.fail(.invalid_token); - } else { - return node; - } - } - - /// BitShiftExpr <- AdditionExpr (BitShiftOp AdditionExpr)* - /// BitShiftOp - /// <- LARROW2 - /// / RARROW2 - fn parseBitShiftExpr(p: *Parser) Error!Node.Index { - var res = try p.parseAdditionExpr(); - if (res == 0) return null_node; - - while (true) { - const tag: Node.Tag = switch (p.token_tags[p.tok_i]) { - .angle_bracket_angle_bracket_left => .bit_shift_left, - .angle_bracket_angle_bracket_right => .bit_shift_right, - else => return res, - }; - res = try p.addNode(.{ - .tag = tag, - .main_token = p.nextToken(), - .data = .{ - .lhs = res, - .rhs = try p.expectAdditionExpr(), + .invalid_ampersands => { + try p.warn(.invalid_and); }, - }); - } - } - - fn expectBitShiftExpr(p: *Parser) Error!Node.Index { - const node = try p.parseBitShiftExpr(); - if (node == 0) { - return p.fail(.invalid_token); - } else { - return node; - } - } - - /// AdditionExpr <- MultiplyExpr (AdditionOp MultiplyExpr)* - /// AdditionOp - /// <- PLUS - /// / MINUS - /// / PLUS2 - /// / PLUSPERCENT - /// / MINUSPERCENT - fn parseAdditionExpr(p: *Parser) Error!Node.Index { - var res = try p.parseMultiplyExpr(); - if (res == 0) return null_node; + else => {}, + } + const rhs = try p.parseExprPrecedence(info.prec + 1); + if (rhs == 0) { + return p.fail(.invalid_token); + } - while (true) { - const tag: Node.Tag = switch (p.token_tags[p.tok_i]) { - .plus => .add, - .minus => .sub, - .plus_plus => .array_cat, - .plus_percent => .add_wrap, - .minus_percent => .sub_wrap, - else => return res, - }; - res = try p.addNode(.{ - .tag = tag, - .main_token = p.nextToken(), + node = try p.addNode(.{ + .tag = info.tag, + .main_token = oper_token, .data = .{ - .lhs = res, - .rhs = try p.expectMultiplyExpr(), + .lhs = node, + .rhs = rhs, }, }); - } - } - fn expectAdditionExpr(p: *Parser) Error!Node.Index { - const node = try p.parseAdditionExpr(); - if (node == 0) { - return p.fail(.invalid_token); - } - return node; - } - - /// MultiplyExpr <- PrefixExpr (MultiplyOp PrefixExpr)* - /// MultiplyOp - /// <- PIPE2 - /// / ASTERISK - /// / SLASH - /// / PERCENT - /// / ASTERISK2 - /// / ASTERISKPERCENT - fn parseMultiplyExpr(p: *Parser) Error!Node.Index { - var res = try p.parsePrefixExpr(); - if (res == 0) return null_node; - - while (true) { - const tag: Node.Tag = switch (p.token_tags[p.tok_i]) { - .pipe_pipe => .merge_error_sets, - .asterisk => .mul, - .slash => .div, - .percent => .mod, - .asterisk_asterisk => .array_mult, - .asterisk_percent => .mul_wrap, - else => return res, - }; - res = try p.addNode(.{ - .tag = tag, - .main_token = p.nextToken(), - .data = .{ - .lhs = res, - .rhs = try p.expectPrefixExpr(), - }, - }); + if (info.assoc == Assoc.none) { + banned_prec = info.prec; + } } - } - fn expectMultiplyExpr(p: *Parser) Error!Node.Index { - const node = try p.parseMultiplyExpr(); - if (node == 0) { - return p.fail(.invalid_token); - } return node; } diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 9cc350b1ad..03586bc777 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -2828,6 +2828,7 @@ test "zig fmt: precedence" { \\ a or b and c; \\ (a or b) and c; \\ (a or b) and c; + \\ a == b and c == d; \\} \\ ); @@ -4892,6 +4893,16 @@ test "recovery: missing comma" { }); } +test "recovery: non-associative operators" { + try testError( + \\const x = a == b == c; + \\const x = a == b != c; + , &[_]Error{ + .expected_token, + .expected_token, + }); +} + test "recovery: extra qualifier" { try testError( \\const a: *const const u8; |
