authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-02-19 23:27:43-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 18:54:34-07:00
loge8e7fbf8432899d12888bcabeba17ea8e51dc62d
treef56e0352bca6220ebfdb34c411f1be899684a0d3
parentb53e4e84bd5641d3e506f88481c92e1abafb1325

Configuration: implement Storage.EnumOptional


3 files changed, 54 insertions(+), 13 deletions(-)

lib/compiler/Maker/ScannedConfig.zig+2-1
...@@ -74,6 +74,7 @@ fn printValue(sc: *const ScannedConfig, s: *Serializer, comptime Field: type, fi...@@ -74,6 +74,7 @@ fn printValue(sc: *const ScannedConfig, s: *Serializer, comptime Field: type, fi
74 try sub_struct.end();74 try sub_struct.end();
75 },75 },
76 .flag_optional => comptime unreachable,76 .flag_optional => comptime unreachable,
77 .enum_optional => comptime unreachable,
77 } else if (std.enums.tagName(Field, field_value)) |name| {78 } else if (std.enums.tagName(Field, field_value)) |name| {
78 try s.ident(name);79 try s.ident(name);
79 } else {80 } else {
...@@ -85,7 +86,7 @@ fn printValue(sc: *const ScannedConfig, s: *Serializer, comptime Field: type, fi...@@ -85,7 +86,7 @@ fn printValue(sc: *const ScannedConfig, s: *Serializer, comptime Field: type, fi
85 try s.value(field_value, .{});86 try s.value(field_value, .{});
86 },87 },
87 .auto => switch (Field.storage) {88 .auto => switch (Field.storage) {
88 .flag_optional => {89 .flag_optional, .enum_optional => {
89 if (field_value.value) |some| {90 if (field_value.value) |some| {
90 try printValue(sc, s, Field.Value, some);91 try printValue(sc, s, Field.Value, some);
91 } else {92 } else {
lib/compiler/configure_runner.zig+8
...@@ -458,6 +458,14 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {...@@ -458,6 +458,14 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
458 .stack_size = .{ .value = c.stack_size },458 .stack_size = .{ .value = c.stack_size },
459 .headerpad_size = .{ .value = c.headerpad_size },459 .headerpad_size = .{ .value = c.headerpad_size },
460 .error_limit = .{ .value = c.error_limit },460 .error_limit = .{ .value = c.error_limit },
461 .entry = .{ .value = switch (c.entry) {
462 .symbol_name => |name| try wc.addString(name),
463 .default, .disabled, .enabled => null,
464 } },
465 .build_id = .{ .value = if (c.build_id) |id| switch (id) {
466 .hexstring => |*hexstring| try wc.addString(hexstring.toSlice()),
467 .none, .fast, .uuid, .sha1, .md5 => null,
468 } else null },
461 }));469 }));
462470
463 log.err("TODO serialize the trailing Compile step data", .{});471 log.err("TODO serialize the trailing Compile step data", .{});
lib/std/zig/Configuration.zig+44-12
...@@ -225,11 +225,11 @@ pub const Wip = struct {...@@ -225,11 +225,11 @@ pub const Wip = struct {
225 .glibc_version = .{ .value = glibc_version },225 .glibc_version = .{ .value = glibc_version },
226 .android_api_level = .{ .value = q.android_api_level },226 .android_api_level = .{ .value = q.android_api_level },
227 .dynamic_linker = .{ .value = dynamic_linker },227 .dynamic_linker = .{ .value = dynamic_linker },
228 .cpu_name = .{ .value = cpu_name },
228 })));229 })));
229 std.log.err("TODO serialize more target query stuff", .{});230 std.log.err("TODO serialize more target query stuff", .{});
230 _ = os_version_min;231 _ = os_version_min;
231 _ = os_version_max;232 _ = os_version_max;
232 _ = cpu_name;
233233
234 // Deduplicate.234 // Deduplicate.
235 const gop = try wip.targets_table.getOrPutContext(gpa, result_index, @as(TargetsTableContext, .{235 const gop = try wip.targets_table.getOrPutContext(gpa, result_index, @as(TargetsTableContext, .{
...@@ -306,9 +306,9 @@ pub const Wip = struct {...@@ -306,9 +306,9 @@ pub const Wip = struct {
306 .glibc_version = .{ .value = glibc_version },306 .glibc_version = .{ .value = glibc_version },
307 .android_api_level = .{ .value = android_api_level },307 .android_api_level = .{ .value = android_api_level },
308 .dynamic_linker = .{ .value = dynamic_linker },308 .dynamic_linker = .{ .value = dynamic_linker },
309 .cpu_name = .{ .value = cpu_name },
309 })));310 })));
310 std.log.err("TODO serialize more target stuff", .{});311 std.log.err("TODO serialize more target stuff", .{});
311 _ = cpu_name;
312 _ = os_version_min;312 _ = os_version_min;
313 _ = os_version_max;313 _ = os_version_max;
314314
...@@ -598,7 +598,7 @@ pub const Step = extern struct {...@@ -598,7 +598,7 @@ pub const Step = extern struct {
598 win32_module_definition: Storage.FlagOptional(.flags3, .win32_module_definition, LazyPath),598 win32_module_definition: Storage.FlagOptional(.flags3, .win32_module_definition, LazyPath),
599 entitlements: Storage.FlagOptional(.flags4, .entitlements, LazyPath),599 entitlements: Storage.FlagOptional(.flags4, .entitlements, LazyPath),
600 version: Storage.FlagOptional(.flags3, .version, String), // semantic version string600 version: Storage.FlagOptional(.flags3, .version, String), // semantic version string
601 //entry: EnumOptional(.flags3, .entry, .symbol, String),601 entry: Storage.EnumOptional(.flags3, .entry, .symbol_name, String),
602 install_name: Storage.FlagOptional(.flags4, .install_name, String),602 install_name: Storage.FlagOptional(.flags4, .install_name, String),
603 initial_memory: Storage.FlagOptional(.flags3, .initial_memory, u64),603 initial_memory: Storage.FlagOptional(.flags3, .initial_memory, u64),
604 max_memory: Storage.FlagOptional(.flags3, .max_memory, u64),604 max_memory: Storage.FlagOptional(.flags3, .max_memory, u64),
...@@ -610,7 +610,7 @@ pub const Step = extern struct {...@@ -610,7 +610,7 @@ pub const Step = extern struct {
610 stack_size: Storage.FlagOptional(.flags4, .stack_size, u64),610 stack_size: Storage.FlagOptional(.flags4, .stack_size, u64),
611 headerpad_size: Storage.FlagOptional(.flags4, .headerpad_size, u32),611 headerpad_size: Storage.FlagOptional(.flags4, .headerpad_size, u32),
612 error_limit: Storage.FlagOptional(.flags4, .error_limit, u32),612 error_limit: Storage.FlagOptional(.flags4, .error_limit, u32),
613 //build_id: EnumOptional(.flags3, .build_id, .hexstring, Hexstring),613 build_id: Storage.EnumOptional(.flags3, .build_id, .hexstring, String),
614614
615 pub const ExpectErrors = enum(u3) { contains, exact, starts_with, stderr_contains, none };615 pub const ExpectErrors = enum(u3) { contains, exact, starts_with, stderr_contains, none };
616 pub const TestRunnerMode = enum(u2) { default, simple, server };616 pub const TestRunnerMode = enum(u2) { default, simple, server };
...@@ -1378,15 +1378,20 @@ pub const TargetQuery = struct {...@@ -1378,15 +1378,20 @@ pub const TargetQuery = struct {
13781378
1379 cpu_features_add: Storage.FlagOptional(.flags, .cpu_features_add, std.Target.Cpu.Feature.Set),1379 cpu_features_add: Storage.FlagOptional(.flags, .cpu_features_add, std.Target.Cpu.Feature.Set),
1380 cpu_features_sub: Storage.FlagOptional(.flags, .cpu_features_sub, std.Target.Cpu.Feature.Set),1380 cpu_features_sub: Storage.FlagOptional(.flags, .cpu_features_sub, std.Target.Cpu.Feature.Set),
1381 //cpu_name: Storage.EnumOptional(.flags, .cpu_name, .explicit, String),1381 cpu_name: Storage.EnumOptional(.flags, .cpu_model, .explicit, String),
1382 //os_version_min: Storage.EnumOptional(.flags, .os_version_min, .windows, WindowsVersion),1382 //os_version_min: Storage.FlagsUnion(.flags, .os_version_min, VersionStorage),
1383 //os_version_min: Storage.EnumOptional(.flags, .os_version_min, .semver, String),1383 //os_version_max: Storage.FlagsUnion(.flags, .os_version_max, VersionStorage),
1384 //os_version_max: Storage.EnumOptional(.flags, .os_version_max, .windows, WindowsVersion),
1385 //os_version_max: Storage.EnumOptional(.flags, .os_version_max, .semver, String),
1386 glibc_version: Storage.FlagOptional(.flags, .glibc_version, String),1384 glibc_version: Storage.FlagOptional(.flags, .glibc_version, String),
1387 android_api_level: Storage.FlagOptional(.flags, .android_api_level, u32),1385 android_api_level: Storage.FlagOptional(.flags, .android_api_level, u32),
1388 dynamic_linker: Storage.FlagOptional(.flags, .dynamic_linker, String),1386 dynamic_linker: Storage.FlagOptional(.flags, .dynamic_linker, String),
13891387
1388 const VersionStorage = union(OsVersion) {
1389 none: void,
1390 semver: String,
1391 windows: std.Target.Os.WindowsVersion,
1392 default: void,
1393 };
1394
1390 pub const Index = enum(u32) {1395 pub const Index = enum(u32) {
1391 _,1396 _,
13921397
...@@ -1629,6 +1634,7 @@ pub const TargetQuery = struct {...@@ -1629,6 +1634,7 @@ pub const TargetQuery = struct {
16291634
1630pub const Storage = enum {1635pub const Storage = enum {
1631 flag_optional,1636 flag_optional,
1637 enum_optional,
1632 extended,1638 extended,
16331639
1634 /// The presence of the field is determined by a boolean within a packed1640 /// The presence of the field is determined by a boolean within a packed
...@@ -1641,9 +1647,27 @@ pub const Storage = enum {...@@ -1641,9 +1647,27 @@ pub const Storage = enum {
1641 return struct {1647 return struct {
1642 value: ?Value,1648 value: ?Value,
16431649
1650 pub const storage: Storage = .flag_optional;
1644 pub const flags = flags_arg;1651 pub const flags = flags_arg;
1645 pub const flag = flag_arg;1652 pub const flag = flag_arg;
1646 pub const storage: Storage = .flag_optional;1653 pub const Value = ValueArg;
1654 };
1655 }
1656
1657 /// The field is present if an enum tag from flags matches a specific value.
1658 pub fn EnumOptional(
1659 comptime flags_arg: @EnumLiteral(),
1660 comptime flag_arg: @EnumLiteral(),
1661 comptime tag_arg: @EnumLiteral(),
1662 comptime ValueArg: type,
1663 ) type {
1664 return struct {
1665 value: ?Value,
1666
1667 pub const storage: Storage = .enum_optional;
1668 pub const flags = flags_arg;
1669 pub const flag = flag_arg;
1670 pub const tag = tag_arg;
1647 pub const Value = ValueArg;1671 pub const Value = ValueArg;
1648 };1672 };
1649 }1673 }
...@@ -1736,6 +1760,14 @@ pub const Storage = enum {...@@ -1736,6 +1760,14 @@ pub const Storage = enum {
1736 .value = if (flag) dataField(buffer, i, container, Field.Value) else null,1760 .value = if (flag) dataField(buffer, i, container, Field.Value) else null,
1737 };1761 };
1738 },1762 },
1763 .enum_optional => {
1764 const flags = @field(container, @tagName(Field.flags));
1765 const tag = @field(flags, @tagName(Field.flag));
1766 const match = tag == Field.tag;
1767 return .{
1768 .value = if (match) dataField(buffer, i, container, Field.Value) else null,
1769 };
1770 },
1739 .extended => @compileError("TODO"),1771 .extended => @compileError("TODO"),
1740 },1772 },
1741 },1773 },
...@@ -1800,7 +1832,7 @@ pub const Storage = enum {...@@ -1800,7 +1832,7 @@ pub const Storage = enum {
1800 return casted.len;1832 return casted.len;
1801 },1833 },
1802 else => switch (Field.storage) {1834 else => switch (Field.storage) {
1803 .flag_optional => {1835 .flag_optional, .enum_optional => {
1804 return if (value.value) |v| setExtraField(buffer, i, Field.Value, v) else 0;1836 return if (value.value) |v| setExtraField(buffer, i, Field.Value, v) else 0;
1805 },1837 },
1806 .extended => @compileError("TODO"),1838 .extended => @compileError("TODO"),
...@@ -1827,7 +1859,7 @@ pub const Storage = enum {...@@ -1827,7 +1859,7 @@ pub const Storage = enum {
1827 else => comptime unreachable,1859 else => comptime unreachable,
1828 },1860 },
1829 .auto => switch (Field.storage) {1861 .auto => switch (Field.storage) {
1830 .flag_optional, .extended => 1,1862 .flag_optional, .enum_optional, .extended => 1,
1831 },1863 },
1832 .@"extern" => comptime unreachable,1864 .@"extern" => comptime unreachable,
1833 },1865 },