authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-24 01:38:21-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-28 14:51:50-05:00
logfba39ff331a84f1a32d076ccbb8b87cd02ea7121
tree51133625f5bae70a9f3d5991d9f79839ad1ffc68
parent68dbba212dd7393c90ab0e914dedeac975fa0224
signature Commit is signed but in an unrecognized format.

restructuring std.Target for OS version ranges, pass 1


4 files changed, 383 insertions(+), 111 deletions(-)

lib/std/builtin.zig+31-1
...@@ -398,7 +398,37 @@ pub const LinkMode = enum {...@@ -398,7 +398,37 @@ pub const LinkMode = enum {
398pub const Version = struct {398pub const Version = struct {
399 major: u32,399 major: u32,
400 minor: u32,400 minor: u32,
401 patch: u32,401 patch: u32 = 0,
402
403 pub const Range = struct {
404 min: Version,
405 max: Version,
406
407 pub fn includesVersion(self: LinuxVersionRange, ver: Version) bool {
408 if (self.min.compare(ver) == .gt) return false;
409 if (self.max.compare(ver) == .lt) return false;
410 return true;
411 }
412 };
413
414 pub fn order(lhs: Version, rhs: version) std.math.Order {
415 if (lhs.major < rhs.major) return .lt;
416 if (lhs.major > rhs.major) return .gt;
417 if (lhs.minor < rhs.minor) return .lt;
418 if (lhs.minor > rhs.minor) return .gt;
419 if (lhs.patch < rhs.patch) return .lt;
420 if (lhs.patch > rhs.patch) return .gt;
421 return .eq;
422 }
423
424 pub fn parse(text: []const u8) !Version {
425 var it = std.mem.separate(text, ".");
426 return Version{
427 .major = try std.fmt.parseInt(u32, it.next() orelse return error.InvalidVersion, 10),
428 .minor = try std.fmt.parseInt(u32, it.next() orelse "0", 10),
429 .patch = try std.fmt.parseInt(u32, it.next() orelse "0", 10),
430 };
431 }
402};432};
403433
404/// This data structure is used by the Zig language code generation and434/// This data structure is used by the Zig language code generation and
lib/std/target.zig+336-94
...@@ -1,30 +1,53 @@...@@ -1,30 +1,53 @@
1const std = @import("std.zig");1const std = @import("std.zig");
2const mem = std.mem;2const mem = std.mem;
3const builtin = std.builtin;3const builtin = std.builtin;
4const Version = std.builtin.Version;
45
5/// TODO Nearly all the functions in this namespace would be6/// TODO Nearly all the functions in this namespace would be
6/// better off if https://github.com/ziglang/zig/issues/4257/// better off if https://github.com/ziglang/zig/issues/425
7/// was solved.8/// was solved.
8pub const Target = union(enum) {9pub const Target = struct {
9 Native: void,10 cpu: Cpu,
10 Cross: Cross,11 os: Os,
1112 abi: Abi,
12 pub const Os = enum {13
14 /// The version ranges here represent the minimum OS version to be supported
15 /// and the maximum OS version to be supported. The default values represent
16 /// the range that the Zig Standard Library bases its abstractions on.
17 ///
18 /// The minimum version of the range is the main setting to tweak for a target.
19 /// Usually, the maximum target OS version will remain the default, which is
20 /// the latest released version of the OS.
21 ///
22 /// To test at compile time if the target is guaranteed to support a given OS feature,
23 /// one should check that the minimum version of the range is greater than or equal to
24 /// the version the feature was introduced in.
25 ///
26 /// To test at compile time if the target certainly will not support a given OS feature,
27 /// one should check that the maximum version of the range is less than the version the
28 /// feature was introduced in.
29 ///
30 /// If neither of these cases apply, a runtime check should be used to determine if the
31 /// target supports a given OS feature.
32 ///
33 /// Binaries built with a given maximum version will continue to function on newer operating system
34 /// versions. However, such a binary may not take full advantage of the newer operating system APIs.
35 pub const Os = union(enum) {
13 freestanding,36 freestanding,
14 ananas,37 ananas,
15 cloudabi,38 cloudabi,
16 dragonfly,39 dragonfly,
17 freebsd,40 freebsd: Version.Range,
18 fuchsia,41 fuchsia,
19 ios,42 ios,
20 kfreebsd,43 kfreebsd,
21 linux,44 linux: LinuxVersionRange,
22 lv2,45 lv2,
23 macosx,46 macosx: Version.Range,
24 netbsd,47 netbsd: Version.Range,
25 openbsd,48 openbsd: Version.Range,
26 solaris,49 solaris,
27 windows,50 windows: WindowsVersion.Range,
28 haiku,51 haiku,
29 minix,52 minix,
30 rtems,53 rtems,
...@@ -48,14 +71,230 @@ pub const Target = union(enum) {...@@ -48,14 +71,230 @@ pub const Target = union(enum) {
48 uefi,71 uefi,
49 other,72 other,
5073
74 /// See the documentation for `Os` for an explanation of the default version range.
75 pub fn defaultVersionRange(tag: @TagType(Os)) Os {
76 switch (tag) {
77 .freestanding => return .freestanding,
78 .ananas => return .ananas,
79 .cloudabi => return .cloudabi,
80 .dragonfly => return .dragonfly,
81 .freebsd => return .{
82 .freebsd = Version.Range{
83 .min = .{ .major = 12, .minor = 0 },
84 .max = .{ .major = 12, .minor = 1 },
85 },
86 },
87 .fuchsia => return .fuchsia,
88 .ios => return .ios,
89 .kfreebsd => return .kfreebsd,
90 .linux => return .{
91 .linux = .{
92 .range = .{
93 .min = .{ .major = 3, .minor = 16 },
94 .max = .{ .major = 5, .minor = 5, .patch = 5 },
95 },
96 .glibc = .{ .major = 2, .minor = 17 },
97 },
98 },
99 .lv2 => return .lv2,
100 .macosx => return .{
101 .min = .{ .major = 10, .minor = 13 },
102 .max = .{ .major = 10, .minor = 15, .patch = 3 },
103 },
104 .netbsd => return .{
105 .min = .{ .major = 8, .minor = 0 },
106 .max = .{ .major = 9, .minor = 0 },
107 },
108 .openbsd => return .{
109 .min = .{ .major = 6, .minor = 6 },
110 .max = .{ .major = 6, .minor = 6 },
111 },
112 solaris => return .solaris,
113 windows => return .{
114 .windows = .{
115 .min = .win8_1,
116 .max = .win10_19h1,
117 },
118 },
119 haiku => return .haiku,
120 minix => return .minix,
121 rtems => return .rtems,
122 nacl => return .nacl,
123 cnk => return .cnk,
124 aix => return .aix,
125 cuda => return .cuda,
126 nvcl => return .nvcl,
127 amdhsa => return .amdhsa,
128 ps4 => return .ps4,
129 elfiamcu => return .elfiamcu,
130 tvos => return .tvos,
131 watchos => return .watchos,
132 mesa3d => return .mesa3d,
133 contiki => return .contiki,
134 amdpal => return .amdpal,
135 hermit => return .hermit,
136 hurd => return .hurd,
137 wasi => return .wasi,
138 emscripten => return .emscripten,
139 uefi => return .uefi,
140 other => return .other,
141 }
142 }
143
144 pub const LinuxVersionRange = struct {
145 range: Version.Range,
146 glibc: Version,
147
148 pub fn includesVersion(self: LinuxVersionRange, ver: Version) bool {
149 return self.range.includesVersion(ver);
150 }
151 };
152
153 /// Based on NTDDI version constants from
154 /// https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt
155 pub const WindowsVersion = enum(u32) {
156 nt4 = 0x04000000,
157 win2k = 0x05000000,
158 xp = 0x05010000,
159 ws2003 = 0x05020000,
160 vista = 0x06000000,
161 win7 = 0x06010000,
162 win8 = 0x06020000,
163 win8_1 = 0x06030000,
164 win10 = 0x0A000000,
165 win10_th2 = 0x0A000001,
166 win10_rs1 = 0x0A000002,
167 win10_rs2 = 0x0A000003,
168 win10_rs3 = 0x0A000004,
169 win10_rs4 = 0x0A000005,
170 win10_rs5 = 0x0A000006,
171 win10_19h1 = 0x0A000007,
172
173 pub const Range = struct {
174 min: WindowsVersion,
175 max: WindowsVersion,
176
177 pub fn includesVersion(self: Range, ver: WindowsVersion) bool {
178 return @enumToInt(ver) >= @enumToInt(self.min) and @enumToInt(ver) <= @enumToInt(self.max);
179 }
180 };
181
182 pub fn nameToTag(name: []const u8) ?WindowsVersion {
183 const info = @typeInfo(WindowsVersion);
184 inline for (info.Enum.fields) |field| {
185 if (mem.eql(u8, name, field.name)) {
186 return @field(WindowsVersion, field.name);
187 }
188 }
189 return null;
190 }
191 };
192
51 pub fn parse(text: []const u8) !Os {193 pub fn parse(text: []const u8) !Os {
194 var it = mem.separate(text, ".");
195 const os_name = it.next().?;
196 const tag = nameToTag(os_name) orelse return error.UnknownOperatingSystem;
197 const version_text = it.rest();
198 const S = struct {
199 fn parseNone(s: []const u8) !void {
200 if (s.len != 0) return error.InvalidOperatingSystemVersion;
201 }
202 fn parseSemVer(s: []const u8, default: Version.Range) !Version.Range {
203 if (s.len == 0) return default;
204 var range_it = mem.separate(s, "...");
205
206 const min_text = range_it.next().?;
207 const min_ver = Version.parse(min_text) catch |err| switch (err) {
208 error.Overflow => return error.InvalidOperatingSystemVersion,
209 error.InvalidCharacter => return error.InvalidOperatingSystemVersion,
210 error.InvalidVersion => return error.InvalidOperatingSystemVersion,
211 };
212
213 const max_text = range_it.next() orelse return Version.Range{
214 .min = min_ver,
215 .max = default.max,
216 };
217 const max_ver = Version.parse(max_text) catch |err| switch (err) {
218 error.Overflow => return error.InvalidOperatingSystemVersion,
219 error.InvalidCharacter => return error.InvalidOperatingSystemVersion,
220 error.InvalidVersion => return error.InvalidOperatingSystemVersion,
221 };
222
223 return Version.Range{ .min = min_ver, .max = max_ver };
224 }
225 fn parseWindows(s: []const u8, default: WindowsVersion.Range) !WindowsVersion.Range {
226 if (s.len == 0) return default;
227 var range_it = mem.separate(s, "...");
228
229 const min_text = range_it.next().?;
230 const min_ver = WindowsVersion.nameToTag(min_text) orelse
231 return error.InvalidOperatingSystemVersion;
232
233 const max_text = range_it.next() orelse return WindowsVersion.Range{
234 .min = min_ver,
235 .max = default.max,
236 };
237 const max_ver = WindowsVersion.nameToTag(max_text) orelse
238 return error.InvalidOperatingSystemVersion;
239
240 return WindowsVersion.Range{ .min = min_ver, .max = max_ver };
241 }
242 };
243 const default = defaultVersionRange(tag);
244 switch (tag) {
245 .freestanding => return Os{ .freestanding = try S.parseNone(version_text) },
246 .ananas => return Os{ .ananas = try S.parseNone(version_text) },
247 .cloudabi => return Os{ .cloudabi = try S.parseNone(version_text) },
248 .dragonfly => return Os{ .dragonfly = try S.parseNone(version_text) },
249 .freebsd => return Os{ .freebsd = try S.parseSemVer(version_text, default.freebsd) },
250 .fuchsia => return Os{ .fuchsia = try S.parseNone(version_text) },
251 .ios => return Os{ .ios = try S.parseNone(version_text) },
252 .kfreebsd => return Os{ .kfreebsd = try S.parseNone(version_text) },
253 .linux => return Os{
254 .linux = .{
255 .range = try S.parseSemVer(version_text, default.linux.range),
256 .glibc = default.linux.glibc,
257 },
258 },
259 .lv2 => return Os{ .lv2 = try S.parseNone(version_text) },
260 .macosx => return Os{ .macosx = try S.parseSemVer(version_text, default.macosx) },
261 .netbsd => return Os{ .netbsd = try S.parseSemVer(version_text, default.netbsd) },
262 .openbsd => return Os{ .openbsd = try S.parseSemVer(version_text, default.openbsd) },
263 .solaris => return Os{ .solaris = try S.parseNone(version_text) },
264 .windows => return Os{ .windows = try S.parseWindows(version_text, default.windows) },
265 .haiku => return Os{ .haiku = try S.parseNone(version_text) },
266 .minix => return Os{ .minix = try S.parseNone(version_text) },
267 .rtems => return Os{ .rtems = try S.parseNone(version_text) },
268 .nacl => return Os{ .nacl = try S.parseNone(version_text) },
269 .cnk => return Os{ .cnk = try S.parseNone(version_text) },
270 .aix => return Os{ .aix = try S.parseNone(version_text) },
271 .cuda => return Os{ .cuda = try S.parseNone(version_text) },
272 .nvcl => return Os{ .nvcl = try S.parseNone(version_text) },
273 .amdhsa => return Os{ .amdhsa = try S.parseNone(version_text) },
274 .ps4 => return Os{ .ps4 = try S.parseNone(version_text) },
275 .elfiamcu => return Os{ .elfiamcu = try S.parseNone(version_text) },
276 .tvos => return Os{ .tvos = try S.parseNone(version_text) },
277 .watchos => return Os{ .watchos = try S.parseNone(version_text) },
278 .mesa3d => return Os{ .mesa3d = try S.parseNone(version_text) },
279 .contiki => return Os{ .contiki = try S.parseNone(version_text) },
280 .amdpal => return Os{ .amdpal = try S.parseNone(version_text) },
281 .hermit => return Os{ .hermit = try S.parseNone(version_text) },
282 .hurd => return Os{ .hurd = try S.parseNone(version_text) },
283 .wasi => return Os{ .wasi = try S.parseNone(version_text) },
284 .emscripten => return Os{ .emscripten = try S.parseNone(version_text) },
285 .uefi => return Os{ .uefi = try S.parseNone(version_text) },
286 .other => return Os{ .other = try S.parseNone(version_text) },
287 }
288 }
289
290 pub fn nameToTag(name: []const u8) ?@TagType(Os) {
52 const info = @typeInfo(Os);291 const info = @typeInfo(Os);
53 inline for (info.Enum.fields) |field| {292 inline for (info.Union.fields) |field| {
54 if (mem.eql(u8, text, field.name)) {293 if (mem.eql(u8, name, field.name)) {
55 return @field(Os, field.name);294 return @field(Os, field.name);
56 }295 }
57 }296 }
58 return error.UnknownOperatingSystem;297 return null;
59 }298 }
60 };299 };
61300
...@@ -149,14 +388,39 @@ pub const Target = union(enum) {...@@ -149,14 +388,39 @@ pub const Target = union(enum) {
149 }388 }
150 }389 }
151390
152 pub fn parse(text: []const u8) !Abi {391 pub fn nameToTag(text: []const u8) ?Abi {
153 const info = @typeInfo(Abi);392 const info = @typeInfo(Abi);
154 inline for (info.Enum.fields) |field| {393 inline for (info.Enum.fields) |field| {
155 if (mem.eql(u8, text, field.name)) {394 if (mem.eql(u8, text, field.name)) {
156 return @field(Abi, field.name);395 return @field(Abi, field.name);
157 }396 }
158 }397 }
159 return error.UnknownApplicationBinaryInterface;398 return null;
399 }
400
401 pub fn parse(text: []const u8, os: *Os) !Abi {
402 var it = mem.separate(text, ".");
403 const tag = nameToTag(it.next().?) orelse return error.UnknownApplicationBinaryInterface;
404 const version_text = it.rest();
405 if (version_text.len != 0) {
406 if (@as(@TagType(Os), os.*) == .linux and tag.isGnu()) {
407 os.linux.glibc = Version.parse(version_text) catch |err| switch (err) {
408 error.Overflow => return error.InvalidGlibcVersion,
409 error.InvalidCharacter => return error.InvalidGlibcVersion,
410 error.InvalidVersion => return error.InvalidGlibcVersion,
411 };
412 } else {
413 return error.InvalidAbiVersion;
414 }
415 }
416 return tag;
417 }
418
419 pub fn isGnu(abi: Abi) bool {
420 return switch (abi) {
421 .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => true,
422 else => false,
423 };
160 }424 }
161 };425 };
162426
...@@ -179,12 +443,6 @@ pub const Target = union(enum) {...@@ -179,12 +443,6 @@ pub const Target = union(enum) {
179 EfiRuntimeDriver,443 EfiRuntimeDriver,
180 };444 };
181445
182 pub const Cross = struct {
183 cpu: Cpu,
184 os: Os,
185 abi: Abi,
186 };
187
188 pub const Cpu = struct {446 pub const Cpu = struct {
189 /// Architecture447 /// Architecture
190 arch: Arch,448 arch: Arch,
...@@ -641,20 +899,19 @@ pub const Target = union(enum) {...@@ -641,20 +899,19 @@ pub const Target = union(enum) {
641 };899 };
642900
643 pub const current = Target{901 pub const current = Target{
644 .Cross = Cross{902 .cpu = builtin.cpu,
645 .cpu = builtin.cpu,903 .os = builtin.os,
646 .os = builtin.os,904 .abi = builtin.abi,
647 .abi = builtin.abi,
648 },
649 };905 };
650906
651 pub const stack_align = 16;907 pub const stack_align = 16;
652908
909 /// TODO add OS version ranges and glibc version
653 pub fn zigTriple(self: Target, allocator: *mem.Allocator) ![]u8 {910 pub fn zigTriple(self: Target, allocator: *mem.Allocator) ![]u8 {
654 return std.fmt.allocPrint(allocator, "{}-{}-{}", .{911 return std.fmt.allocPrint(allocator, "{}-{}-{}", .{
655 @tagName(self.getArch()),912 @tagName(self.getArch()),
656 @tagName(self.getOs()),913 @tagName(self.os),
657 @tagName(self.getAbi()),914 @tagName(self.abi),
658 });915 });
659 }916 }
660917
...@@ -678,7 +935,7 @@ pub const Target = union(enum) {...@@ -678,7 +935,7 @@ pub const Target = union(enum) {
678 else => return error.VcpkgNoSuchArchitecture,935 else => return error.VcpkgNoSuchArchitecture,
679 };936 };
680937
681 const os = switch (target.getOs()) {938 const os = switch (target.os) {
682 .windows => "windows",939 .windows => "windows",
683 .linux => "linux",940 .linux => "linux",
684 .macosx => "macos",941 .macosx => "macos",
...@@ -701,16 +958,16 @@ pub const Target = union(enum) {...@@ -701,16 +958,16 @@ pub const Target = union(enum) {
701 pub fn zigTripleNoSubArch(self: Target, allocator: *mem.Allocator) ![]u8 {958 pub fn zigTripleNoSubArch(self: Target, allocator: *mem.Allocator) ![]u8 {
702 return std.fmt.allocPrint(allocator, "{}-{}-{}", .{959 return std.fmt.allocPrint(allocator, "{}-{}-{}", .{
703 @tagName(self.getArch()),960 @tagName(self.getArch()),
704 @tagName(self.getOs()),961 @tagName(self.os),
705 @tagName(self.getAbi()),962 @tagName(self.abi),
706 });963 });
707 }964 }
708965
709 pub fn linuxTriple(self: Target, allocator: *mem.Allocator) ![]u8 {966 pub fn linuxTriple(self: Target, allocator: *mem.Allocator) ![]u8 {
710 return std.fmt.allocPrint(allocator, "{}-{}-{}", .{967 return std.fmt.allocPrint(allocator, "{}-{}-{}", .{
711 @tagName(self.getArch()),968 @tagName(self.getArch()),
712 @tagName(self.getOs()),969 @tagName(self.os),
713 @tagName(self.getAbi()),970 @tagName(self.abi),
714 });971 });
715 }972 }
716973
...@@ -760,11 +1017,11 @@ pub const Target = union(enum) {...@@ -760,11 +1017,11 @@ pub const Target = union(enum) {
760 diags.arch = arch;1017 diags.arch = arch;
7611018
762 const os_name = it.next() orelse return error.MissingOperatingSystem;1019 const os_name = it.next() orelse return error.MissingOperatingSystem;
763 const os = try Os.parse(os_name);1020 var os = try Os.parse(os_name); // var because Abi.parse can update linux.glibc version
764 diags.os = os;1021 diags.os = os;
7651022
766 const abi_name = it.next();1023 const abi_name = it.next();
767 const abi = if (abi_name) |n| try Abi.parse(n) else Abi.default(arch, os);1024 const abi = if (abi_name) |n| try Abi.parse(n, &os) else Abi.default(arch, os);
768 diags.abi = abi;1025 diags.abi = abi;
7691026
770 if (it.next() != null) return error.UnexpectedExtraField;1027 if (it.next() != null) return error.UnexpectedExtraField;
...@@ -817,16 +1074,15 @@ pub const Target = union(enum) {...@@ -817,16 +1074,15 @@ pub const Target = union(enum) {
817 .features = set,1074 .features = set,
818 };1075 };
819 };1076 };
820 var cross = Cross{1077 return Target{
821 .cpu = cpu,1078 .cpu = cpu,
822 .os = os,1079 .os = os,
823 .abi = abi,1080 .abi = abi,
824 };1081 };
825 return Target{ .Cross = cross };
826 }1082 }
8271083
828 pub fn oFileExt(self: Target) []const u8 {1084 pub fn oFileExt(self: Target) []const u8 {
829 return switch (self.getAbi()) {1085 return switch (self.abi) {
830 .msvc => ".obj",1086 .msvc => ".obj",
831 else => ".o",1087 else => ".o",
832 };1088 };
...@@ -848,7 +1104,7 @@ pub const Target = union(enum) {...@@ -848,7 +1104,7 @@ pub const Target = union(enum) {
848 if (self.isWasm()) {1104 if (self.isWasm()) {
849 return ".wasm";1105 return ".wasm";
850 }1106 }
851 switch (self.getAbi()) {1107 switch (self.abi) {
852 .msvc => return ".lib",1108 .msvc => return ".lib",
853 else => return ".a",1109 else => return ".a",
854 }1110 }
...@@ -858,7 +1114,7 @@ pub const Target = union(enum) {...@@ -858,7 +1114,7 @@ pub const Target = union(enum) {
858 if (self.isDarwin()) {1114 if (self.isDarwin()) {
859 return ".dylib";1115 return ".dylib";
860 }1116 }
861 switch (self.getOs()) {1117 switch (self.os) {
862 .windows => return ".dll",1118 .windows => return ".dll",
863 else => return ".so",1119 else => return ".so",
864 }1120 }
...@@ -868,52 +1124,41 @@ pub const Target = union(enum) {...@@ -868,52 +1124,41 @@ pub const Target = union(enum) {
868 if (self.isWasm()) {1124 if (self.isWasm()) {
869 return "";1125 return "";
870 }1126 }
871 switch (self.getAbi()) {1127 switch (self.abi) {
872 .msvc => return "",1128 .msvc => return "",
873 else => return "lib",1129 else => return "lib",
874 }1130 }
875 }1131 }
8761132
877 pub fn getOs(self: Target) Os {1133 /// Deprecated; access the `os` field directly.
878 return switch (self) {1134 pub fn getOs(self: Target) @TagType(Os) {
879 .Native => builtin.os,1135 return self.os;
880 .Cross => |t| t.os,
881 };
882 }1136 }
8831137
1138 /// Deprecated; access the `cpu` field directly.
884 pub fn getCpu(self: Target) Cpu {1139 pub fn getCpu(self: Target) Cpu {
885 return switch (self) {1140 return self.cpu;
886 .Native => builtin.cpu,
887 .Cross => |cross| cross.cpu,
888 };
889 }1141 }
8901142
891 pub fn getArch(self: Target) Cpu.Arch {1143 /// Deprecated; access the `abi` field directly.
892 return self.getCpu().arch;1144 pub fn getAbi(self: Target) Abi {
1145 return self.abi;
893 }1146 }
8941147
895 pub fn getAbi(self: Target) Abi {1148 pub fn getArch(self: Target) Cpu.Arch {
896 switch (self) {1149 return self.cpu.arch;
897 .Native => return builtin.abi,
898 .Cross => |t| return t.abi,
899 }
900 }1150 }
9011151
902 pub fn getObjectFormat(self: Target) ObjectFormat {1152 pub fn getObjectFormat(self: Target) ObjectFormat {
903 switch (self) {1153 if (self.isWindows() or self.isUefi()) {
904 .Native => return @import("builtin").object_format,1154 return .coff;
905 .Cross => blk: {1155 } else if (self.isDarwin()) {
906 if (self.isWindows() or self.isUefi()) {1156 return .macho;
907 return .coff;1157 }
908 } else if (self.isDarwin()) {1158 if (self.isWasm()) {
909 return .macho;1159 return .wasm;
910 }
911 if (self.isWasm()) {
912 return .wasm;
913 }
914 return .elf;
915 },
916 }1160 }
1161 return .elf;
917 }1162 }
9181163
919 pub fn isMinGW(self: Target) bool {1164 pub fn isMinGW(self: Target) bool {
...@@ -921,56 +1166,53 @@ pub const Target = union(enum) {...@@ -921,56 +1166,53 @@ pub const Target = union(enum) {
921 }1166 }
9221167
923 pub fn isGnu(self: Target) bool {1168 pub fn isGnu(self: Target) bool {
924 return switch (self.getAbi()) {1169 return self.abi.isGnu();
925 .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => true,
926 else => false,
927 };
928 }1170 }
9291171
930 pub fn isMusl(self: Target) bool {1172 pub fn isMusl(self: Target) bool {
931 return switch (self.getAbi()) {1173 return switch (self.abi) {
932 .musl, .musleabi, .musleabihf => true,1174 .musl, .musleabi, .musleabihf => true,
933 else => false,1175 else => false,
934 };1176 };
935 }1177 }
9361178
937 pub fn isDarwin(self: Target) bool {1179 pub fn isDarwin(self: Target) bool {
938 return switch (self.getOs()) {1180 return switch (self.os) {
939 .ios, .macosx, .watchos, .tvos => true,1181 .ios, .macosx, .watchos, .tvos => true,
940 else => false,1182 else => false,
941 };1183 };
942 }1184 }
9431185
944 pub fn isWindows(self: Target) bool {1186 pub fn isWindows(self: Target) bool {
945 return switch (self.getOs()) {1187 return switch (self.os) {
946 .windows => true,1188 .windows => true,
947 else => false,1189 else => false,
948 };1190 };
949 }1191 }
9501192
951 pub fn isLinux(self: Target) bool {1193 pub fn isLinux(self: Target) bool {
952 return switch (self.getOs()) {1194 return switch (self.os) {
953 .linux => true,1195 .linux => true,
954 else => false,1196 else => false,
955 };1197 };
956 }1198 }
9571199
958 pub fn isAndroid(self: Target) bool {1200 pub fn isAndroid(self: Target) bool {
959 return switch (self.getAbi()) {1201 return switch (self.abi) {
960 .android => true,1202 .android => true,
961 else => false,1203 else => false,
962 };1204 };
963 }1205 }
9641206
965 pub fn isDragonFlyBSD(self: Target) bool {1207 pub fn isDragonFlyBSD(self: Target) bool {
966 return switch (self.getOs()) {1208 return switch (self.os) {
967 .dragonfly => true,1209 .dragonfly => true,
968 else => false,1210 else => false,
969 };1211 };
970 }1212 }
9711213
972 pub fn isUefi(self: Target) bool {1214 pub fn isUefi(self: Target) bool {
973 return switch (self.getOs()) {1215 return switch (self.os) {
974 .uefi => true,1216 .uefi => true,
975 else => false,1217 else => false,
976 };1218 };
...@@ -984,14 +1226,14 @@ pub const Target = union(enum) {...@@ -984,14 +1226,14 @@ pub const Target = union(enum) {
984 }1226 }
9851227
986 pub fn isFreeBSD(self: Target) bool {1228 pub fn isFreeBSD(self: Target) bool {
987 return switch (self.getOs()) {1229 return switch (self.os) {
988 .freebsd => true,1230 .freebsd => true,
989 else => false,1231 else => false,
990 };1232 };
991 }1233 }
9921234
993 pub fn isNetBSD(self: Target) bool {1235 pub fn isNetBSD(self: Target) bool {
994 return switch (self.getOs()) {1236 return switch (self.os) {
995 .netbsd => true,1237 .netbsd => true,
996 else => false,1238 else => false,
997 };1239 };
...@@ -1081,7 +1323,7 @@ pub const Target = union(enum) {...@@ -1081,7 +1323,7 @@ pub const Target = union(enum) {
1081 if (@as(@TagType(Target), self) == .Native) return .native;1323 if (@as(@TagType(Target), self) == .Native) return .native;
10821324
1083 // If the target OS matches the host OS, we can use QEMU to emulate a foreign architecture.1325 // If the target OS matches the host OS, we can use QEMU to emulate a foreign architecture.
1084 if (self.getOs() == builtin.os) {1326 if (self.os == builtin.os) {
1085 return switch (self.getArch()) {1327 return switch (self.getArch()) {
1086 .aarch64 => Executor{ .qemu = "qemu-aarch64" },1328 .aarch64 => Executor{ .qemu = "qemu-aarch64" },
1087 .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" },1329 .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" },
...@@ -1112,7 +1354,7 @@ pub const Target = union(enum) {...@@ -1112,7 +1354,7 @@ pub const Target = union(enum) {
1112 }1354 }
1113 }1355 }
11141356
1115 if (self.getOs() == .wasi) {1357 if (self.os == .wasi) {
1116 switch (self.getArchPtrBitWidth()) {1358 switch (self.getArchPtrBitWidth()) {
1117 32 => return Executor{ .wasmtime = "wasmtime" },1359 32 => return Executor{ .wasmtime = "wasmtime" },
1118 else => return .unavailable,1360 else => return .unavailable,
...@@ -1129,7 +1371,7 @@ pub const Target = union(enum) {...@@ -1129,7 +1371,7 @@ pub const Target = union(enum) {
1129 };1371 };
11301372
1131 pub fn getFloatAbi(self: Target) FloatAbi {1373 pub fn getFloatAbi(self: Target) FloatAbi {
1132 return switch (self.getAbi()) {1374 return switch (self.abi) {
1133 .gnueabihf,1375 .gnueabihf,
1134 .eabihf,1376 .eabihf,
1135 .musleabihf,1377 .musleabihf,
...@@ -1145,7 +1387,7 @@ pub const Target = union(enum) {...@@ -1145,7 +1387,7 @@ pub const Target = union(enum) {
1145 => return false,1387 => return false,
1146 else => {},1388 else => {},
1147 }1389 }
1148 switch (self.getOs()) {1390 switch (self.os) {
1149 .freestanding,1391 .freestanding,
1150 .ios,1392 .ios,
1151 .tvos,1393 .tvos,
...@@ -1200,7 +1442,7 @@ pub const Target = union(enum) {...@@ -1200,7 +1442,7 @@ pub const Target = union(enum) {
1200 return result.toOwnedSlice();1442 return result.toOwnedSlice();
1201 }1443 }
12021444
1203 switch (self.getOs()) {1445 switch (self.os) {
1204 .freebsd => return mem.dupeZ(a, u8, "/libexec/ld-elf.so.1"),1446 .freebsd => return mem.dupeZ(a, u8, "/libexec/ld-elf.so.1"),
1205 .netbsd => return mem.dupeZ(a, u8, "/libexec/ld.elf_so"),1447 .netbsd => return mem.dupeZ(a, u8, "/libexec/ld.elf_so"),
1206 .dragonfly => return mem.dupeZ(a, u8, "/libexec/ld-elf.so.2"),1448 .dragonfly => return mem.dupeZ(a, u8, "/libexec/ld-elf.so.2"),
...@@ -1233,7 +1475,7 @@ pub const Target = union(enum) {...@@ -1233,7 +1475,7 @@ pub const Target = union(enum) {
1233 .powerpc64, .powerpc64le => return mem.dupeZ(a, u8, "/lib64/ld64.so.2"),1475 .powerpc64, .powerpc64le => return mem.dupeZ(a, u8, "/lib64/ld64.so.2"),
1234 .s390x => return mem.dupeZ(a, u8, "/lib64/ld64.so.1"),1476 .s390x => return mem.dupeZ(a, u8, "/lib64/ld64.so.1"),
1235 .sparcv9 => return mem.dupeZ(a, u8, "/lib64/ld-linux.so.2"),1477 .sparcv9 => return mem.dupeZ(a, u8, "/lib64/ld-linux.so.2"),
1236 .x86_64 => return mem.dupeZ(a, u8, switch (self.getAbi()) {1478 .x86_64 => return mem.dupeZ(a, u8, switch (self.abi) {
1237 .gnux32 => "/libx32/ld-linux-x32.so.2",1479 .gnux32 => "/libx32/ld-linux-x32.so.2",
1238 else => "/lib64/ld-linux-x86-64.so.2",1480 else => "/lib64/ld-linux-x86-64.so.2",
1239 }),1481 }),
...@@ -1292,10 +1534,10 @@ pub const Target = union(enum) {...@@ -1292,10 +1534,10 @@ pub const Target = union(enum) {
12921534
1293test "Target.parse" {1535test "Target.parse" {
1294 {1536 {
1295 const target = (try Target.parse(.{1537 const target = try Target.parse(.{
1296 .arch_os_abi = "x86_64-linux-gnu",1538 .arch_os_abi = "x86_64-linux-gnu",
1297 .cpu_features = "x86_64-sse-sse2-avx-cx8",1539 .cpu_features = "x86_64-sse-sse2-avx-cx8",
1298 })).Cross;1540 });
12991541
1300 std.testing.expect(target.os == .linux);1542 std.testing.expect(target.os == .linux);
1301 std.testing.expect(target.abi == .gnu);1543 std.testing.expect(target.abi == .gnu);
...@@ -1307,10 +1549,10 @@ test "Target.parse" {...@@ -1307,10 +1549,10 @@ test "Target.parse" {
1307 std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .fxsr));1549 std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .fxsr));
1308 }1550 }
1309 {1551 {
1310 const target = (try Target.parse(.{1552 const target = try Target.parse(.{
1311 .arch_os_abi = "arm-linux-musleabihf",1553 .arch_os_abi = "arm-linux-musleabihf",
1312 .cpu_features = "generic+v8a",1554 .cpu_features = "generic+v8a",
1313 })).Cross;1555 });
13141556
1315 std.testing.expect(target.os == .linux);1557 std.testing.expect(target.os == .linux);
1316 std.testing.expect(target.abi == .musleabihf);1558 std.testing.expect(target.abi == .musleabihf);
src/analyze.cpp+1-1
...@@ -3963,7 +3963,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) {...@@ -3963,7 +3963,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) {
39633963
3964 // TODO more validation for types that can't be used for export/extern variables3964 // TODO more validation for types that can't be used for export/extern variables
3965 ZigType *implicit_type = nullptr;3965 ZigType *implicit_type = nullptr;
3966 if (explicit_type != nullptr && explicit_type->id == ZigTypeIdInvalid) {3966 if (explicit_type != nullptr && type_is_invalid(explicit_type)) {
3967 implicit_type = explicit_type;3967 implicit_type = explicit_type;
3968 } else if (var_decl->expr) {3968 } else if (var_decl->expr) {
3969 init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type,3969 init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type,
test/tests.zig+15-15
...@@ -56,7 +56,7 @@ const test_targets = blk: {...@@ -56,7 +56,7 @@ const test_targets = blk: {
56 .target = Target{56 .target = Target{
57 .Cross = CrossTarget{57 .Cross = CrossTarget{
58 .cpu = Target.Cpu.baseline(.x86_64),58 .cpu = Target.Cpu.baseline(.x86_64),
59 .os = .linux,59 .os = Target.Os.defaultVersionRange(.linux),
60 .abi = .none,60 .abi = .none,
61 },61 },
62 },62 },
...@@ -65,7 +65,7 @@ const test_targets = blk: {...@@ -65,7 +65,7 @@ const test_targets = blk: {
65 .target = Target{65 .target = Target{
66 .Cross = CrossTarget{66 .Cross = CrossTarget{
67 .cpu = Target.Cpu.baseline(.x86_64),67 .cpu = Target.Cpu.baseline(.x86_64),
68 .os = .linux,68 .os = Target.Os.defaultVersionRange(.linux),
69 .abi = .gnu,69 .abi = .gnu,
70 },70 },
71 },71 },
...@@ -75,7 +75,7 @@ const test_targets = blk: {...@@ -75,7 +75,7 @@ const test_targets = blk: {
75 .target = Target{75 .target = Target{
76 .Cross = CrossTarget{76 .Cross = CrossTarget{
77 .cpu = Target.Cpu.baseline(.x86_64),77 .cpu = Target.Cpu.baseline(.x86_64),
78 .os = .linux,78 .os = Target.Os.defaultVersionRange(.linux),
79 .abi = .musl,79 .abi = .musl,
80 },80 },
81 },81 },
...@@ -86,7 +86,7 @@ const test_targets = blk: {...@@ -86,7 +86,7 @@ const test_targets = blk: {
86 .target = Target{86 .target = Target{
87 .Cross = CrossTarget{87 .Cross = CrossTarget{
88 .cpu = Target.Cpu.baseline(.i386),88 .cpu = Target.Cpu.baseline(.i386),
89 .os = .linux,89 .os = Target.Os.defaultVersionRange(.linux),
90 .abi = .none,90 .abi = .none,
91 },91 },
92 },92 },
...@@ -95,7 +95,7 @@ const test_targets = blk: {...@@ -95,7 +95,7 @@ const test_targets = blk: {
95 .target = Target{95 .target = Target{
96 .Cross = CrossTarget{96 .Cross = CrossTarget{
97 .cpu = Target.Cpu.baseline(.i386),97 .cpu = Target.Cpu.baseline(.i386),
98 .os = .linux,98 .os = Target.Os.defaultVersionRange(.linux),
99 .abi = .musl,99 .abi = .musl,
100 },100 },
101 },101 },
...@@ -106,7 +106,7 @@ const test_targets = blk: {...@@ -106,7 +106,7 @@ const test_targets = blk: {
106 .target = Target{106 .target = Target{
107 .Cross = CrossTarget{107 .Cross = CrossTarget{
108 .cpu = Target.Cpu.baseline(.aarch64),108 .cpu = Target.Cpu.baseline(.aarch64),
109 .os = .linux,109 .os = Target.Os.defaultVersionRange(.linux),
110 .abi = .none,110 .abi = .none,
111 },111 },
112 },112 },
...@@ -115,7 +115,7 @@ const test_targets = blk: {...@@ -115,7 +115,7 @@ const test_targets = blk: {
115 .target = Target{115 .target = Target{
116 .Cross = CrossTarget{116 .Cross = CrossTarget{
117 .cpu = Target.Cpu.baseline(.aarch64),117 .cpu = Target.Cpu.baseline(.aarch64),
118 .os = .linux,118 .os = Target.Os.defaultVersionRange(.linux),
119 .abi = .musl,119 .abi = .musl,
120 },120 },
121 },121 },
...@@ -125,7 +125,7 @@ const test_targets = blk: {...@@ -125,7 +125,7 @@ const test_targets = blk: {
125 .target = Target{125 .target = Target{
126 .Cross = CrossTarget{126 .Cross = CrossTarget{
127 .cpu = Target.Cpu.baseline(.aarch64),127 .cpu = Target.Cpu.baseline(.aarch64),
128 .os = .linux,128 .os = Target.Os.defaultVersionRange(.linux),
129 .abi = .gnu,129 .abi = .gnu,
130 },130 },
131 },131 },
...@@ -158,7 +158,7 @@ const test_targets = blk: {...@@ -158,7 +158,7 @@ const test_targets = blk: {
158 .target = Target{158 .target = Target{
159 .Cross = CrossTarget{159 .Cross = CrossTarget{
160 .cpu = Target.Cpu.baseline(.mipsel),160 .cpu = Target.Cpu.baseline(.mipsel),
161 .os = .linux,161 .os = Target.Os.defaultVersionRange(.linux),
162 .abi = .none,162 .abi = .none,
163 },163 },
164 },164 },
...@@ -167,7 +167,7 @@ const test_targets = blk: {...@@ -167,7 +167,7 @@ const test_targets = blk: {
167 .target = Target{167 .target = Target{
168 .Cross = CrossTarget{168 .Cross = CrossTarget{
169 .cpu = Target.Cpu.baseline(.mipsel),169 .cpu = Target.Cpu.baseline(.mipsel),
170 .os = .linux,170 .os = Target.Os.defaultVersionRange(.linux),
171 .abi = .musl,171 .abi = .musl,
172 },172 },
173 },173 },
...@@ -178,7 +178,7 @@ const test_targets = blk: {...@@ -178,7 +178,7 @@ const test_targets = blk: {
178 .target = Target{178 .target = Target{
179 .Cross = CrossTarget{179 .Cross = CrossTarget{
180 .cpu = Target.Cpu.baseline(.x86_64),180 .cpu = Target.Cpu.baseline(.x86_64),
181 .os = .macosx,181 .os = Target.Os.defaultVersionRange(.macosx),
182 .abi = .gnu,182 .abi = .gnu,
183 },183 },
184 },184 },
...@@ -190,7 +190,7 @@ const test_targets = blk: {...@@ -190,7 +190,7 @@ const test_targets = blk: {
190 .target = Target{190 .target = Target{
191 .Cross = CrossTarget{191 .Cross = CrossTarget{
192 .cpu = Target.Cpu.baseline(.i386),192 .cpu = Target.Cpu.baseline(.i386),
193 .os = .windows,193 .os = Target.Os.defaultVersionRange(.windows),
194 .abi = .msvc,194 .abi = .msvc,
195 },195 },
196 },196 },
...@@ -200,7 +200,7 @@ const test_targets = blk: {...@@ -200,7 +200,7 @@ const test_targets = blk: {
200 .target = Target{200 .target = Target{
201 .Cross = CrossTarget{201 .Cross = CrossTarget{
202 .cpu = Target.Cpu.baseline(.x86_64),202 .cpu = Target.Cpu.baseline(.x86_64),
203 .os = .windows,203 .os = Target.Os.defaultVersionRange(.windows),
204 .abi = .msvc,204 .abi = .msvc,
205 },205 },
206 },206 },
...@@ -210,7 +210,7 @@ const test_targets = blk: {...@@ -210,7 +210,7 @@ const test_targets = blk: {
210 .target = Target{210 .target = Target{
211 .Cross = CrossTarget{211 .Cross = CrossTarget{
212 .cpu = Target.Cpu.baseline(.i386),212 .cpu = Target.Cpu.baseline(.i386),
213 .os = .windows,213 .os = Target.Os.defaultVersionRange(.windows),
214 .abi = .gnu,214 .abi = .gnu,
215 },215 },
216 },216 },
...@@ -221,7 +221,7 @@ const test_targets = blk: {...@@ -221,7 +221,7 @@ const test_targets = blk: {
221 .target = Target{221 .target = Target{
222 .Cross = CrossTarget{222 .Cross = CrossTarget{
223 .cpu = Target.Cpu.baseline(.x86_64),223 .cpu = Target.Cpu.baseline(.x86_64),
224 .os = .windows,224 .os = Target.Os.defaultVersionRange(.windows),
225 .abi = .gnu,225 .abi = .gnu,
226 },226 },
227 },227 },