authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-10-24 02:25:22-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-10-24 02:25:22-04:00
log345042ecbc7fb645fd17b69df4e57ffefa5be5a5
tree457ea0157f0f42dccf905593426154be8682812b
parentef62452363de75240b21299e9f80b4851433faaa
parent60cd11bd4b48e4dfdf11d1f25cb1ee842a49ee1d
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #3519 from ziglang/move-builtin-types

move types from builtin to std

39 files changed, 1385 insertions(+), 1117 deletions(-)

lib/std/build.zig+9-428
......@@ -971,433 +971,14 @@ test "builder.findProgram compiles" {
971971 _ = builder.findProgram([_][]const u8{}, [_][]const u8{}) catch null;
972972}
973973
974pub const Version = struct {
975 major: u32,
976 minor: u32,
977 patch: u32,
978};
979
980pub const CrossTarget = struct {
981 arch: builtin.Arch,
982 os: builtin.Os,
983 abi: builtin.Abi,
984};
985
986pub const Target = union(enum) {
987 Native: void,
988 Cross: CrossTarget,
989
990 pub fn zigTriple(self: Target, allocator: *Allocator) ![]u8 {
991 return std.fmt.allocPrint(
992 allocator,
993 "{}{}-{}-{}",
994 @tagName(self.getArch()),
995 Target.archSubArchName(self.getArch()),
996 @tagName(self.getOs()),
997 @tagName(self.getAbi()),
998 );
999 }
1000
1001 pub fn allocDescription(self: Target, allocator: *Allocator) ![]u8 {
1002 // TODO is there anything else worthy of the description that is not
1003 // already captured in the triple?
1004 return self.zigTriple(allocator);
1005 }
1006
1007 pub fn zigTripleNoSubArch(self: Target, allocator: *Allocator) ![]u8 {
1008 return std.fmt.allocPrint(
1009 allocator,
1010 "{}-{}-{}",
1011 @tagName(self.getArch()),
1012 @tagName(self.getOs()),
1013 @tagName(self.getAbi()),
1014 );
1015 }
1016
1017 pub fn linuxTriple(self: Target, allocator: *Allocator) ![]u8 {
1018 return std.fmt.allocPrint(
1019 allocator,
1020 "{}-{}-{}",
1021 @tagName(self.getArch()),
1022 @tagName(self.getOs()),
1023 @tagName(self.getAbi()),
1024 );
1025 }
1026
1027 pub fn parse(text: []const u8) !Target {
1028 var it = mem.separate(text, "-");
1029 const arch_name = it.next() orelse return error.MissingArchitecture;
1030 const os_name = it.next() orelse return error.MissingOperatingSystem;
1031 const abi_name = it.next();
1032
1033 var cross = CrossTarget{
1034 .arch = try parseArchSub(arch_name),
1035 .os = try parseOs(os_name),
1036 .abi = undefined,
1037 };
1038 cross.abi = if (abi_name) |n| try parseAbi(n) else defaultAbi(cross.arch, cross.os);
1039 return Target{ .Cross = cross };
1040 }
1041
1042 pub fn defaultAbi(arch: builtin.Arch, target_os: builtin.Os) builtin.Abi {
1043 switch (arch) {
1044 .wasm32, .wasm64 => return .musl,
1045 else => {},
1046 }
1047 switch (target_os) {
1048 .freestanding,
1049 .ananas,
1050 .cloudabi,
1051 .dragonfly,
1052 .lv2,
1053 .solaris,
1054 .haiku,
1055 .minix,
1056 .rtems,
1057 .nacl,
1058 .cnk,
1059 .aix,
1060 .cuda,
1061 .nvcl,
1062 .amdhsa,
1063 .ps4,
1064 .elfiamcu,
1065 .mesa3d,
1066 .contiki,
1067 .amdpal,
1068 .zen,
1069 .hermit,
1070 => return .eabi,
1071 .openbsd,
1072 .macosx,
1073 .freebsd,
1074 .ios,
1075 .tvos,
1076 .watchos,
1077 .fuchsia,
1078 .kfreebsd,
1079 .netbsd,
1080 .hurd,
1081 => return .gnu,
1082 .windows,
1083 .uefi,
1084 => return .msvc,
1085 .linux,
1086 .wasi,
1087 .emscripten,
1088 => return .musl,
1089 }
1090 }
1091
1092 pub const ParseArchSubError = error{
1093 UnknownArchitecture,
1094 UnknownSubArchitecture,
1095 };
1096
1097 pub fn parseArchSub(text: []const u8) ParseArchSubError!builtin.Arch {
1098 const info = @typeInfo(builtin.Arch);
1099 inline for (info.Union.fields) |field| {
1100 if (mem.eql(u8, text, field.name)) {
1101 if (field.field_type == void) {
1102 return (builtin.Arch)(@field(builtin.Arch, field.name));
1103 } else {
1104 const sub_info = @typeInfo(field.field_type);
1105 inline for (sub_info.Enum.fields) |sub_field| {
1106 const combined = field.name ++ sub_field.name;
1107 if (mem.eql(u8, text, combined)) {
1108 return @unionInit(builtin.Arch, field.name, @field(field.field_type, sub_field.name));
1109 }
1110 }
1111 return error.UnknownSubArchitecture;
1112 }
1113 }
1114 }
1115 return error.UnknownArchitecture;
1116 }
1117
1118 pub fn parseOs(text: []const u8) !builtin.Os {
1119 const info = @typeInfo(builtin.Os);
1120 inline for (info.Enum.fields) |field| {
1121 if (mem.eql(u8, text, field.name)) {
1122 return @field(builtin.Os, field.name);
1123 }
1124 }
1125 return error.UnknownOperatingSystem;
1126 }
1127
1128 pub fn parseAbi(text: []const u8) !builtin.Abi {
1129 const info = @typeInfo(builtin.Abi);
1130 inline for (info.Enum.fields) |field| {
1131 if (mem.eql(u8, text, field.name)) {
1132 return @field(builtin.Abi, field.name);
1133 }
1134 }
1135 return error.UnknownApplicationBinaryInterface;
1136 }
1137
1138 fn archSubArchName(arch: builtin.Arch) []const u8 {
1139 return switch (arch) {
1140 .arm => |sub| @tagName(sub),
1141 .armeb => |sub| @tagName(sub),
1142 .thumb => |sub| @tagName(sub),
1143 .thumbeb => |sub| @tagName(sub),
1144 .aarch64 => |sub| @tagName(sub),
1145 .aarch64_be => |sub| @tagName(sub),
1146 .kalimba => |sub| @tagName(sub),
1147 else => "",
1148 };
1149 }
1150
1151 pub fn subArchName(self: Target) []const u8 {
1152 switch (self) {
1153 .Native => return archSubArchName(builtin.arch),
1154 .Cross => |cross| return archSubArchName(cross.arch),
1155 }
1156 }
1157
1158 pub fn oFileExt(self: Target) []const u8 {
1159 return switch (self.getAbi()) {
1160 builtin.Abi.msvc => ".obj",
1161 else => ".o",
1162 };
1163 }
1164
1165 pub fn exeFileExt(self: Target) []const u8 {
1166 if (self.isWindows()) {
1167 return ".exe";
1168 } else if (self.isUefi()) {
1169 return ".efi";
1170 } else if (self.isWasm()) {
1171 return ".wasm";
1172 } else {
1173 return "";
1174 }
1175 }
974/// Deprecated. Use `builtin.Version`.
975pub const Version = builtin.Version;
1176976
1177 pub fn staticLibSuffix(self: Target) []const u8 {
1178 if (self.isWasm()) {
1179 return ".wasm";
1180 }
1181 switch (self.getAbi()) {
1182 .msvc => return ".lib",
1183 else => return ".a",
1184 }
1185 }
1186
1187 pub fn dynamicLibSuffix(self: Target) []const u8 {
1188 if (self.isDarwin()) {
1189 return ".dylib";
1190 }
1191 switch (self.getOs()) {
1192 .windows => return ".dll",
1193 else => return ".so",
1194 }
1195 }
1196
1197 pub fn libPrefix(self: Target) []const u8 {
1198 if (self.isWasm()) {
1199 return "";
1200 }
1201 switch (self.getAbi()) {
1202 .msvc => return "",
1203 else => return "lib",
1204 }
1205 }
977/// Deprecated. Use `std.Target.Cross`.
978pub const CrossTarget = std.Target.Cross;
1206979
1207 pub fn getOs(self: Target) builtin.Os {
1208 return switch (self) {
1209 .Native => builtin.os,
1210 .Cross => |t| t.os,
1211 };
1212 }
1213
1214 pub fn getArch(self: Target) builtin.Arch {
1215 switch (self) {
1216 .Native => return builtin.arch,
1217 .Cross => |t| return t.arch,
1218 }
1219 }
1220
1221 pub fn getAbi(self: Target) builtin.Abi {
1222 switch (self) {
1223 .Native => return builtin.abi,
1224 .Cross => |t| return t.abi,
1225 }
1226 }
1227
1228 pub fn isMinGW(self: Target) bool {
1229 return self.isWindows() and self.isGnu();
1230 }
1231
1232 pub fn isGnu(self: Target) bool {
1233 return switch (self.getAbi()) {
1234 .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => true,
1235 else => false,
1236 };
1237 }
1238
1239 pub fn isDarwin(self: Target) bool {
1240 return switch (self.getOs()) {
1241 .ios, .macosx, .watchos, .tvos => true,
1242 else => false,
1243 };
1244 }
1245
1246 pub fn isWindows(self: Target) bool {
1247 return switch (self.getOs()) {
1248 .windows => true,
1249 else => false,
1250 };
1251 }
1252
1253 pub fn isLinux(self: Target) bool {
1254 return switch (self.getOs()) {
1255 .linux => true,
1256 else => false,
1257 };
1258 }
1259
1260 pub fn isUefi(self: Target) bool {
1261 return switch (self.getOs()) {
1262 .uefi => true,
1263 else => false,
1264 };
1265 }
1266
1267 pub fn isWasm(self: Target) bool {
1268 return switch (self.getArch()) {
1269 .wasm32, .wasm64 => true,
1270 else => false,
1271 };
1272 }
1273
1274 pub fn isFreeBSD(self: Target) bool {
1275 return switch (self.getOs()) {
1276 .freebsd => true,
1277 else => false,
1278 };
1279 }
1280
1281 pub fn isNetBSD(self: Target) bool {
1282 return switch (self.getOs()) {
1283 .netbsd => true,
1284 else => false,
1285 };
1286 }
1287
1288 pub fn wantSharedLibSymLinks(self: Target) bool {
1289 return !self.isWindows();
1290 }
1291
1292 pub fn osRequiresLibC(self: Target) bool {
1293 return self.isDarwin() or self.isFreeBSD() or self.isNetBSD();
1294 }
1295
1296 pub fn getArchPtrBitWidth(self: Target) u32 {
1297 switch (self.getArch()) {
1298 .avr,
1299 .msp430,
1300 => return 16,
1301
1302 .arc,
1303 .arm,
1304 .armeb,
1305 .hexagon,
1306 .le32,
1307 .mips,
1308 .mipsel,
1309 .powerpc,
1310 .r600,
1311 .riscv32,
1312 .sparc,
1313 .sparcel,
1314 .tce,
1315 .tcele,
1316 .thumb,
1317 .thumbeb,
1318 .i386,
1319 .xcore,
1320 .nvptx,
1321 .amdil,
1322 .hsail,
1323 .spir,
1324 .kalimba,
1325 .shave,
1326 .lanai,
1327 .wasm32,
1328 .renderscript32,
1329 .aarch64_32,
1330 => return 32,
1331
1332 .aarch64,
1333 .aarch64_be,
1334 .mips64,
1335 .mips64el,
1336 .powerpc64,
1337 .powerpc64le,
1338 .riscv64,
1339 .x86_64,
1340 .nvptx64,
1341 .le64,
1342 .amdil64,
1343 .hsail64,
1344 .spir64,
1345 .wasm64,
1346 .renderscript64,
1347 .amdgcn,
1348 .bpfel,
1349 .bpfeb,
1350 .sparcv9,
1351 .s390x,
1352 => return 64,
1353 }
1354 }
1355
1356 pub const Executor = union(enum) {
1357 native,
1358 qemu: []const u8,
1359 wine: []const u8,
1360 unavailable,
1361 };
1362
1363 pub fn getExternalExecutor(self: Target) Executor {
1364 if (@TagType(Target)(self) == .Native) return .native;
1365
1366 // If the target OS matches the host OS, we can use QEMU to emulate a foreign architecture.
1367 if (self.getOs() == builtin.os) {
1368 return switch (self.getArch()) {
1369 .aarch64 => Executor{ .qemu = "qemu-aarch64" },
1370 .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" },
1371 .arm => Executor{ .qemu = "qemu-arm" },
1372 .armeb => Executor{ .qemu = "qemu-armeb" },
1373 .i386 => Executor{ .qemu = "qemu-i386" },
1374 .mips => Executor{ .qemu = "qemu-mips" },
1375 .mipsel => Executor{ .qemu = "qemu-mipsel" },
1376 .mips64 => Executor{ .qemu = "qemu-mips64" },
1377 .mips64el => Executor{ .qemu = "qemu-mips64el" },
1378 .powerpc => Executor{ .qemu = "qemu-ppc" },
1379 .powerpc64 => Executor{ .qemu = "qemu-ppc64" },
1380 .powerpc64le => Executor{ .qemu = "qemu-ppc64le" },
1381 .riscv32 => Executor{ .qemu = "qemu-riscv32" },
1382 .riscv64 => Executor{ .qemu = "qemu-riscv64" },
1383 .s390x => Executor{ .qemu = "qemu-s390x" },
1384 .sparc => Executor{ .qemu = "qemu-sparc" },
1385 .x86_64 => Executor{ .qemu = "qemu-x86_64" },
1386 else => return .unavailable,
1387 };
1388 }
1389
1390 if (self.isWindows()) {
1391 switch (self.getArchPtrBitWidth()) {
1392 32 => return Executor{ .wine = "wine" },
1393 64 => return Executor{ .wine = "wine64" },
1394 else => return .unavailable,
1395 }
1396 }
1397
1398 return .unavailable;
1399 }
1400};
980/// Deprecated. Use `std.Target`.
981pub const Target = std.Target;
1401982
1402983const Pkg = struct {
1403984 name: []const u8,
......@@ -2168,8 +1749,8 @@ pub const LibExeObjStep = struct {
21681749 }
21691750
21701751 switch (self.target) {
2171 Target.Native => {},
2172 Target.Cross => {
1752 .Native => {},
1753 .Cross => {
21731754 try zig_args.append("-target");
21741755 try zig_args.append(self.target.zigTriple(builder.allocator) catch unreachable);
21751756 },
......@@ -2419,7 +2000,7 @@ pub const RunStep = struct {
24192000 }
24202001
24212002 pub fn addPathDir(self: *RunStep, search_path: []const u8) void {
2422 const PATH = if (std.os.windows.is_the_target) "Path" else "PATH";
2003 const PATH = if (builtin.os == .windows) "Path" else "PATH";
24232004 const env_map = self.getEnvMap();
24242005 const prev_path = env_map.get(PATH) orelse {
24252006 env_map.set(PATH, search_path) catch unreachable;
lib/std/builtin.zig created+413
......@@ -0,0 +1,413 @@
1pub usingnamespace @import("builtin");
2
3/// Deprecated: use `std.Target.Os`.
4pub const Os = std.Target.Os;
5
6/// Deprecated: use `std.Target.Arch`.
7pub const Arch = std.Target.Arch;
8
9/// Deprecated: use `std.Target.Abi`.
10pub const Abi = std.Target.Abi;
11
12/// Deprecated: use `std.Target.ObjectFormat`.
13pub const ObjectFormat = std.Target.ObjectFormat;
14
15/// Deprecated: use `std.Target.SubSystem`.
16pub const SubSystem = std.Target.SubSystem;
17
18/// `explicit_subsystem` is missing when the subsystem is automatically detected,
19/// so Zig standard library has the subsystem detection logic here. This should generally be
20/// used rather than `explicit_subsystem`.
21/// On non-Windows targets, this is `null`.
22pub const subsystem: ?SubSystem = blk: {
23 if (@hasDecl(@This(), "explicit_subsystem")) break :blk explicit_subsystem;
24 switch (os) {
25 .windows => {
26 if (is_test) {
27 break :blk SubSystem.Console;
28 }
29 if (@hasDecl(root, "WinMain") or
30 @hasDecl(root, "wWinMain") or
31 @hasDecl(root, "WinMainCRTStartup") or
32 @hasDecl(root, "wWinMainCRTStartup"))
33 {
34 break :blk SubSystem.Windows;
35 } else {
36 break :blk SubSystem.Console;
37 }
38 },
39 else => break :blk null,
40 }
41};
42
43/// This data structure is used by the Zig language code generation and
44/// therefore must be kept in sync with the compiler implementation.
45pub const StackTrace = struct {
46 index: usize,
47 instruction_addresses: []usize,
48};
49
50/// This data structure is used by the Zig language code generation and
51/// therefore must be kept in sync with the compiler implementation.
52pub const GlobalLinkage = enum {
53 Internal,
54 Strong,
55 Weak,
56 LinkOnce,
57};
58
59/// This data structure is used by the Zig language code generation and
60/// therefore must be kept in sync with the compiler implementation.
61pub const AtomicOrder = enum {
62 Unordered,
63 Monotonic,
64 Acquire,
65 Release,
66 AcqRel,
67 SeqCst,
68};
69
70/// This data structure is used by the Zig language code generation and
71/// therefore must be kept in sync with the compiler implementation.
72pub const AtomicRmwOp = enum {
73 Xchg,
74 Add,
75 Sub,
76 And,
77 Nand,
78 Or,
79 Xor,
80 Max,
81 Min,
82};
83
84/// This data structure is used by the Zig language code generation and
85/// therefore must be kept in sync with the compiler implementation.
86pub const Mode = enum {
87 Debug,
88 ReleaseSafe,
89 ReleaseFast,
90 ReleaseSmall,
91};
92
93/// This data structure is used by the Zig language code generation and
94/// therefore must be kept in sync with the compiler implementation.
95pub const TypeId = enum {
96 Type,
97 Void,
98 Bool,
99 NoReturn,
100 Int,
101 Float,
102 Pointer,
103 Array,
104 Struct,
105 ComptimeFloat,
106 ComptimeInt,
107 Undefined,
108 Null,
109 Optional,
110 ErrorUnion,
111 ErrorSet,
112 Enum,
113 Union,
114 Fn,
115 BoundFn,
116 ArgTuple,
117 Opaque,
118 Frame,
119 AnyFrame,
120 Vector,
121 EnumLiteral,
122};
123
124/// This data structure is used by the Zig language code generation and
125/// therefore must be kept in sync with the compiler implementation.
126pub const TypeInfo = union(TypeId) {
127 Type: void,
128 Void: void,
129 Bool: void,
130 NoReturn: void,
131 Int: Int,
132 Float: Float,
133 Pointer: Pointer,
134 Array: Array,
135 Struct: Struct,
136 ComptimeFloat: void,
137 ComptimeInt: void,
138 Undefined: void,
139 Null: void,
140 Optional: Optional,
141 ErrorUnion: ErrorUnion,
142 ErrorSet: ErrorSet,
143 Enum: Enum,
144 Union: Union,
145 Fn: Fn,
146 BoundFn: Fn,
147 ArgTuple: void,
148 Opaque: void,
149 Frame: void,
150 AnyFrame: AnyFrame,
151 Vector: Vector,
152 EnumLiteral: void,
153
154 /// This data structure is used by the Zig language code generation and
155 /// therefore must be kept in sync with the compiler implementation.
156 pub const Int = struct {
157 is_signed: bool,
158 bits: comptime_int,
159 };
160
161 /// This data structure is used by the Zig language code generation and
162 /// therefore must be kept in sync with the compiler implementation.
163 pub const Float = struct {
164 bits: comptime_int,
165 };
166
167 /// This data structure is used by the Zig language code generation and
168 /// therefore must be kept in sync with the compiler implementation.
169 pub const Pointer = struct {
170 size: Size,
171 is_const: bool,
172 is_volatile: bool,
173 alignment: comptime_int,
174 child: type,
175 is_allowzero: bool,
176
177 /// This data structure is used by the Zig language code generation and
178 /// therefore must be kept in sync with the compiler implementation.
179 pub const Size = enum {
180 One,
181 Many,
182 Slice,
183 C,
184 };
185 };
186
187 /// This data structure is used by the Zig language code generation and
188 /// therefore must be kept in sync with the compiler implementation.
189 pub const Array = struct {
190 len: comptime_int,
191 child: type,
192 };
193
194 /// This data structure is used by the Zig language code generation and
195 /// therefore must be kept in sync with the compiler implementation.
196 pub const ContainerLayout = enum {
197 Auto,
198 Extern,
199 Packed,
200 };
201
202 /// This data structure is used by the Zig language code generation and
203 /// therefore must be kept in sync with the compiler implementation.
204 pub const StructField = struct {
205 name: []const u8,
206 offset: ?comptime_int,
207 field_type: type,
208 };
209
210 /// This data structure is used by the Zig language code generation and
211 /// therefore must be kept in sync with the compiler implementation.
212 pub const Struct = struct {
213 layout: ContainerLayout,
214 fields: []StructField,
215 decls: []Declaration,
216 };
217
218 /// This data structure is used by the Zig language code generation and
219 /// therefore must be kept in sync with the compiler implementation.
220 pub const Optional = struct {
221 child: type,
222 };
223
224 /// This data structure is used by the Zig language code generation and
225 /// therefore must be kept in sync with the compiler implementation.
226 pub const ErrorUnion = struct {
227 error_set: type,
228 payload: type,
229 };
230
231 /// This data structure is used by the Zig language code generation and
232 /// therefore must be kept in sync with the compiler implementation.
233 pub const Error = struct {
234 name: []const u8,
235 value: comptime_int,
236 };
237
238 /// This data structure is used by the Zig language code generation and
239 /// therefore must be kept in sync with the compiler implementation.
240 pub const ErrorSet = ?[]Error;
241
242 /// This data structure is used by the Zig language code generation and
243 /// therefore must be kept in sync with the compiler implementation.
244 pub const EnumField = struct {
245 name: []const u8,
246 value: comptime_int,
247 };
248
249 /// This data structure is used by the Zig language code generation and
250 /// therefore must be kept in sync with the compiler implementation.
251 pub const Enum = struct {
252 layout: ContainerLayout,
253 tag_type: type,
254 fields: []EnumField,
255 decls: []Declaration,
256 };
257
258 /// This data structure is used by the Zig language code generation and
259 /// therefore must be kept in sync with the compiler implementation.
260 pub const UnionField = struct {
261 name: []const u8,
262 enum_field: ?EnumField,
263 field_type: type,
264 };
265
266 /// This data structure is used by the Zig language code generation and
267 /// therefore must be kept in sync with the compiler implementation.
268 pub const Union = struct {
269 layout: ContainerLayout,
270 tag_type: ?type,
271 fields: []UnionField,
272 decls: []Declaration,
273 };
274
275 /// This data structure is used by the Zig language code generation and
276 /// therefore must be kept in sync with the compiler implementation.
277 pub const CallingConvention = enum {
278 Unspecified,
279 C,
280 Cold,
281 Naked,
282 Stdcall,
283 Async,
284 };
285
286 /// This data structure is used by the Zig language code generation and
287 /// therefore must be kept in sync with the compiler implementation.
288 pub const FnArg = struct {
289 is_generic: bool,
290 is_noalias: bool,
291 arg_type: ?type,
292 };
293
294 /// This data structure is used by the Zig language code generation and
295 /// therefore must be kept in sync with the compiler implementation.
296 pub const Fn = struct {
297 calling_convention: CallingConvention,
298 is_generic: bool,
299 is_var_args: bool,
300 return_type: ?type,
301 args: []FnArg,
302 };
303
304 /// This data structure is used by the Zig language code generation and
305 /// therefore must be kept in sync with the compiler implementation.
306 pub const AnyFrame = struct {
307 child: ?type,
308 };
309
310 /// This data structure is used by the Zig language code generation and
311 /// therefore must be kept in sync with the compiler implementation.
312 pub const Vector = struct {
313 len: comptime_int,
314 child: type,
315 };
316
317 /// This data structure is used by the Zig language code generation and
318 /// therefore must be kept in sync with the compiler implementation.
319 pub const Declaration = struct {
320 name: []const u8,
321 is_pub: bool,
322 data: Data,
323
324 /// This data structure is used by the Zig language code generation and
325 /// therefore must be kept in sync with the compiler implementation.
326 pub const Data = union(enum) {
327 Type: type,
328 Var: type,
329 Fn: FnDecl,
330
331 /// This data structure is used by the Zig language code generation and
332 /// therefore must be kept in sync with the compiler implementation.
333 pub const FnDecl = struct {
334 fn_type: type,
335 inline_type: Inline,
336 calling_convention: CallingConvention,
337 is_var_args: bool,
338 is_extern: bool,
339 is_export: bool,
340 lib_name: ?[]const u8,
341 return_type: type,
342 arg_names: [][]const u8,
343
344 /// This data structure is used by the Zig language code generation and
345 /// therefore must be kept in sync with the compiler implementation.
346 pub const Inline = enum {
347 Auto,
348 Always,
349 Never,
350 };
351 };
352 };
353 };
354};
355
356/// This data structure is used by the Zig language code generation and
357/// therefore must be kept in sync with the compiler implementation.
358pub const FloatMode = enum {
359 Strict,
360 Optimized,
361};
362
363/// This data structure is used by the Zig language code generation and
364/// therefore must be kept in sync with the compiler implementation.
365pub const Endian = enum {
366 Big,
367 Little,
368};
369
370/// This data structure is used by the Zig language code generation and
371/// therefore must be kept in sync with the compiler implementation.
372pub const Version = struct {
373 major: u32,
374 minor: u32,
375 patch: u32,
376};
377
378/// This function type is used by the Zig language code generation and
379/// therefore must be kept in sync with the compiler implementation.
380pub const PanicFn = fn ([]const u8, ?*StackTrace) noreturn;
381
382/// This function is used by the Zig language code generation and
383/// therefore must be kept in sync with the compiler implementation.
384pub const panic: PanicFn = if (@hasDecl(root, "panic")) root.panic else default_panic;
385
386/// This function is used by the Zig language code generation and
387/// therefore must be kept in sync with the compiler implementation.
388pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn {
389 @setCold(true);
390 switch (os) {
391 .freestanding => {
392 while (true) {
393 @breakpoint();
394 }
395 },
396 .wasi => {
397 std.debug.warn("{}", msg);
398 _ = std.os.wasi.proc_raise(std.os.wasi.SIGABRT);
399 unreachable;
400 },
401 .uefi => {
402 // TODO look into using the debug info and logging helpful messages
403 std.os.abort();
404 },
405 else => {
406 const first_trace_addr = @returnAddress();
407 std.debug.panicExtra(error_return_trace, first_trace_addr, "{}", msg);
408 },
409 }
410}
411
412const std = @import("std.zig");
413const root = @import("root");
lib/std/c/darwin.zig+1-1
......@@ -36,7 +36,7 @@ const mach_hdr = if (@sizeOf(usize) == 8) mach_header_64 else mach_header;
3636/// export a weak symbol here, to be overridden by the real one.
3737pub extern "c" var _mh_execute_header: mach_hdr = undefined;
3838comptime {
39 if (std.os.darwin.is_the_target) {
39 if (std.Target.current.isDarwin()) {
4040 @export("_mh_execute_header", _mh_execute_header, .Weak);
4141 }
4242}
lib/std/child_process.zig+12-12
......@@ -17,9 +17,9 @@ const TailQueue = std.TailQueue;
1717const maxInt = std.math.maxInt;
1818
1919pub const ChildProcess = struct {
20 pid: if (os.windows.is_the_target) void else i32,
21 handle: if (os.windows.is_the_target) windows.HANDLE else void,
22 thread_handle: if (os.windows.is_the_target) windows.HANDLE else void,
20 pid: if (builtin.os == .windows) void else i32,
21 handle: if (builtin.os == .windows) windows.HANDLE else void,
22 thread_handle: if (builtin.os == .windows) windows.HANDLE else void,
2323
2424 allocator: *mem.Allocator,
2525
......@@ -39,16 +39,16 @@ pub const ChildProcess = struct {
3939 stderr_behavior: StdIo,
4040
4141 /// Set to change the user id when spawning the child process.
42 uid: if (os.windows.is_the_target) void else ?u32,
42 uid: if (builtin.os == .windows) void else ?u32,
4343
4444 /// Set to change the group id when spawning the child process.
45 gid: if (os.windows.is_the_target) void else ?u32,
45 gid: if (builtin.os == .windows) void else ?u32,
4646
4747 /// Set to change the current working directory when spawning the child process.
4848 cwd: ?[]const u8,
4949
50 err_pipe: if (os.windows.is_the_target) void else [2]os.fd_t,
51 llnode: if (os.windows.is_the_target) void else TailQueue(*ChildProcess).Node,
50 err_pipe: if (builtin.os == .windows) void else [2]os.fd_t,
51 llnode: if (builtin.os == .windows) void else TailQueue(*ChildProcess).Node,
5252
5353 pub const SpawnError = error{OutOfMemory} || os.ExecveError || os.SetIdError ||
5454 os.ChangeCurDirError || windows.CreateProcessError;
......@@ -82,8 +82,8 @@ pub const ChildProcess = struct {
8282 .term = null,
8383 .env_map = null,
8484 .cwd = null,
85 .uid = if (os.windows.is_the_target) {} else null,
86 .gid = if (os.windows.is_the_target) {} else null,
85 .uid = if (builtin.os == .windows) {} else null,
86 .gid = if (builtin.os == .windows) {} else null,
8787 .stdin = null,
8888 .stdout = null,
8989 .stderr = null,
......@@ -103,7 +103,7 @@ pub const ChildProcess = struct {
103103
104104 /// On success must call `kill` or `wait`.
105105 pub fn spawn(self: *ChildProcess) !void {
106 if (os.windows.is_the_target) {
106 if (builtin.os == .windows) {
107107 return self.spawnWindows();
108108 } else {
109109 return self.spawnPosix();
......@@ -117,7 +117,7 @@ pub const ChildProcess = struct {
117117
118118 /// Forcibly terminates child process and then cleans up all resources.
119119 pub fn kill(self: *ChildProcess) !Term {
120 if (os.windows.is_the_target) {
120 if (builtin.os == .windows) {
121121 return self.killWindows(1);
122122 } else {
123123 return self.killPosix();
......@@ -147,7 +147,7 @@ pub const ChildProcess = struct {
147147
148148 /// Blocks until child process terminates and then cleans up all resources.
149149 pub fn wait(self: *ChildProcess) !Term {
150 if (os.windows.is_the_target) {
150 if (builtin.os == .windows) {
151151 return self.waitWindows();
152152 } else {
153153 return self.waitPosix();
lib/std/debug.zig+8-8
......@@ -133,7 +133,7 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {
133133/// chopping off the irrelevant frames and shifting so that the returned addresses pointer
134134/// equals the passed in addresses pointer.
135135pub fn captureStackTrace(first_address: ?usize, stack_trace: *builtin.StackTrace) void {
136 if (windows.is_the_target) {
136 if (builtin.os == .windows) {
137137 const addrs = stack_trace.instruction_addresses;
138138 const u32_addrs_len = @intCast(u32, addrs.len);
139139 const first_addr = first_address orelse {
......@@ -310,7 +310,7 @@ pub const StackIterator = struct {
310310};
311311
312312pub fn writeCurrentStackTrace(out_stream: var, debug_info: *DebugInfo, tty_color: bool, start_addr: ?usize) !void {
313 if (windows.is_the_target) {
313 if (builtin.os == .windows) {
314314 return writeCurrentStackTraceWindows(out_stream, debug_info, tty_color, start_addr);
315315 }
316316 var it = StackIterator.init(start_addr);
......@@ -342,10 +342,10 @@ pub fn writeCurrentStackTraceWindows(
342342/// TODO once https://github.com/ziglang/zig/issues/3157 is fully implemented,
343343/// make this `noasync fn` and remove the individual noasync calls.
344344pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void {
345 if (windows.is_the_target) {
345 if (builtin.os == .windows) {
346346 return noasync printSourceAtAddressWindows(debug_info, out_stream, address, tty_color);
347347 }
348 if (os.darwin.is_the_target) {
348 if (comptime std.Target.current.isDarwin()) {
349349 return noasync printSourceAtAddressMacOs(debug_info, out_stream, address, tty_color);
350350 }
351351 return noasync printSourceAtAddressPosix(debug_info, out_stream, address, tty_color);
......@@ -832,10 +832,10 @@ pub const OpenSelfDebugInfoError = error{
832832pub fn openSelfDebugInfo(allocator: *mem.Allocator) !DebugInfo {
833833 if (builtin.strip_debug_info)
834834 return error.MissingDebugInfo;
835 if (windows.is_the_target) {
835 if (builtin.os == .windows) {
836836 return noasync openSelfDebugInfoWindows(allocator);
837837 }
838 if (os.darwin.is_the_target) {
838 if (comptime std.Target.current.isDarwin()) {
839839 return noasync openSelfDebugInfoMacOs(allocator);
840840 }
841841 return noasync openSelfDebugInfoPosix(allocator);
......@@ -2364,7 +2364,7 @@ pub fn attachSegfaultHandler() void {
23642364 if (!have_segfault_handling_support) {
23652365 @compileError("segfault handler not supported for this target");
23662366 }
2367 if (windows.is_the_target) {
2367 if (builtin.os == .windows) {
23682368 windows_segfault_handle = windows.kernel32.AddVectoredExceptionHandler(0, handleSegfaultWindows);
23692369 return;
23702370 }
......@@ -2378,7 +2378,7 @@ pub fn attachSegfaultHandler() void {
23782378}
23792379
23802380fn resetSegfaultHandler() void {
2381 if (windows.is_the_target) {
2381 if (builtin.os == .windows) {
23822382 if (windows_segfault_handle) |handle| {
23832383 assert(windows.kernel32.RemoveVectoredExceptionHandler(handle) != 0);
23842384 windows_segfault_handle = null;
lib/std/event/channel.zig+1-1
......@@ -307,7 +307,7 @@ test "std.event.Channel" {
307307 // https://github.com/ziglang/zig/issues/1908
308308 if (builtin.single_threaded) return error.SkipZigTest;
309309 // https://github.com/ziglang/zig/issues/3251
310 if (std.os.freebsd.is_the_target) return error.SkipZigTest;
310 if (builtin.os == .freebsd) return error.SkipZigTest;
311311
312312 var loop: Loop = undefined;
313313 // TODO make a multi threaded test
lib/std/event/fs.zig+1-1
......@@ -909,7 +909,7 @@ fn hashString(s: []const u16) u32 {
909909// var close_op_consumed = false;
910910// defer if (!close_op_consumed) close_op.finish();
911911//
912// const flags = if (os.darwin.is_the_target) os.O_SYMLINK | os.O_EVTONLY else 0;
912// const flags = if (comptime std.Target.current.isDarwin()) os.O_SYMLINK | os.O_EVTONLY else 0;
913913// const mode = 0;
914914// const fd = try await (async openPosix(self.channel.loop, resolved_path, flags, mode) catch unreachable);
915915// close_op.setHandle(fd);
lib/std/event/future.zig+1-1
......@@ -86,7 +86,7 @@ test "std.event.Future" {
8686 // https://github.com/ziglang/zig/issues/1908
8787 if (builtin.single_threaded) return error.SkipZigTest;
8888 // https://github.com/ziglang/zig/issues/3251
89 if (std.os.freebsd.is_the_target) return error.SkipZigTest;
89 if (builtin.os == .freebsd) return error.SkipZigTest;
9090
9191 const allocator = std.heap.direct_allocator;
9292
lib/std/event/lock.zig+1-1
......@@ -119,7 +119,7 @@ test "std.event.Lock" {
119119 // TODO https://github.com/ziglang/zig/issues/1908
120120 if (builtin.single_threaded) return error.SkipZigTest;
121121 // TODO https://github.com/ziglang/zig/issues/3251
122 if (std.os.freebsd.is_the_target) return error.SkipZigTest;
122 if (builtin.os == .freebsd) return error.SkipZigTest;
123123
124124 const allocator = std.heap.direct_allocator;
125125
lib/std/fs.zig+9-9
......@@ -255,7 +255,7 @@ pub const AtomicFile = struct {
255255 assert(!self.finished);
256256 self.file.close();
257257 self.finished = true;
258 if (os.windows.is_the_target) {
258 if (builtin.os == .windows) {
259259 const dest_path_w = try os.windows.sliceToPrefixedFileW(self.dest_path);
260260 const tmp_path_w = try os.windows.cStrToPrefixedFileW(&self.tmp_path_buf);
261261 return os.renameW(&tmp_path_w, &dest_path_w);
......@@ -659,7 +659,7 @@ pub const Dir = struct {
659659 /// Closing the returned `Dir` is checked illegal behavior.
660660 /// On POSIX targets, this function is comptime-callable.
661661 pub fn cwd() Dir {
662 if (os.windows.is_the_target) {
662 if (builtin.os == .windows) {
663663 return Dir{ .fd = os.windows.peb().ProcessParameters.CurrentDirectory.Handle };
664664 } else {
665665 return Dir{ .fd = os.AT_FDCWD };
......@@ -711,7 +711,7 @@ pub const Dir = struct {
711711
712712 /// Call `close` on the result when done.
713713 pub fn openDir(self: Dir, sub_path: []const u8) OpenError!Dir {
714 if (os.windows.is_the_target) {
714 if (builtin.os == .windows) {
715715 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);
716716 return self.openDirW(&sub_path_w);
717717 }
......@@ -722,7 +722,7 @@ pub const Dir = struct {
722722
723723 /// Same as `openDir` except the parameter is null-terminated.
724724 pub fn openDirC(self: Dir, sub_path_c: [*]const u8) OpenError!Dir {
725 if (os.windows.is_the_target) {
725 if (builtin.os == .windows) {
726726 const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path_c);
727727 return self.openDirW(&sub_path_w);
728728 }
......@@ -829,7 +829,7 @@ pub const Dir = struct {
829829 /// Returns `error.DirNotEmpty` if the directory is not empty.
830830 /// To delete a directory recursively, see `deleteTree`.
831831 pub fn deleteDir(self: Dir, sub_path: []const u8) DeleteDirError!void {
832 if (os.windows.is_the_target) {
832 if (builtin.os == .windows) {
833833 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);
834834 return self.deleteDirW(&sub_path_w);
835835 }
......@@ -1146,10 +1146,10 @@ pub fn readLinkC(pathname_c: [*]const u8, buffer: *[MAX_PATH_BYTES]u8) ![]u8 {
11461146pub const OpenSelfExeError = os.OpenError || os.windows.CreateFileError || SelfExePathError;
11471147
11481148pub fn openSelfExe() OpenSelfExeError!File {
1149 if (os.linux.is_the_target) {
1149 if (builtin.os == .linux) {
11501150 return File.openReadC(c"/proc/self/exe");
11511151 }
1152 if (os.windows.is_the_target) {
1152 if (builtin.os == .windows) {
11531153 var buf: [os.windows.PATH_MAX_WIDE]u16 = undefined;
11541154 const wide_slice = try selfExePathW(&buf);
11551155 return File.openReadW(wide_slice.ptr);
......@@ -1180,7 +1180,7 @@ pub const SelfExePathError = os.ReadLinkError || os.SysCtlError;
11801180/// been deleted, the file path looks something like `/a/b/c/exe (deleted)`.
11811181/// TODO make the return type of this a null terminated pointer
11821182pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]u8 {
1183 if (os.darwin.is_the_target) {
1183 if (comptime std.Target.current.isDarwin()) {
11841184 var u32_len: u32 = out_buffer.len;
11851185 const rc = std.c._NSGetExecutablePath(out_buffer, &u32_len);
11861186 if (rc != 0) return error.NameTooLong;
......@@ -1228,7 +1228,7 @@ pub fn selfExeDirPathAlloc(allocator: *Allocator) ![]u8 {
12281228/// Get the directory path that contains the current executable.
12291229/// Returned value is a slice of out_buffer.
12301230pub fn selfExeDirPath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]const u8 {
1231 if (os.linux.is_the_target) {
1231 if (builtin.os == .linux) {
12321232 // If the currently executing binary has been deleted,
12331233 // the file path looks something like `/a/b/c/exe (deleted)`
12341234 // This path cannot be opened, but it's valid for determining the directory
lib/std/fs/file.zig+11-11
......@@ -27,7 +27,7 @@ pub const File = struct {
2727
2828 /// Call close to clean up.
2929 pub fn openRead(path: []const u8) OpenError!File {
30 if (windows.is_the_target) {
30 if (builtin.os == .windows) {
3131 const path_w = try windows.sliceToPrefixedFileW(path);
3232 return openReadW(&path_w);
3333 }
......@@ -37,7 +37,7 @@ pub const File = struct {
3737
3838 /// `openRead` except with a null terminated path
3939 pub fn openReadC(path: [*]const u8) OpenError!File {
40 if (windows.is_the_target) {
40 if (builtin.os == .windows) {
4141 const path_w = try windows.cStrToPrefixedFileW(path);
4242 return openReadW(&path_w);
4343 }
......@@ -69,7 +69,7 @@ pub const File = struct {
6969 /// If a file already exists in the destination it will be truncated.
7070 /// Call close to clean up.
7171 pub fn openWriteMode(path: []const u8, file_mode: Mode) OpenError!File {
72 if (windows.is_the_target) {
72 if (builtin.os == .windows) {
7373 const path_w = try windows.sliceToPrefixedFileW(path);
7474 return openWriteModeW(&path_w, file_mode);
7575 }
......@@ -79,7 +79,7 @@ pub const File = struct {
7979
8080 /// Same as `openWriteMode` except `path` is null-terminated.
8181 pub fn openWriteModeC(path: [*]const u8, file_mode: Mode) OpenError!File {
82 if (windows.is_the_target) {
82 if (builtin.os == .windows) {
8383 const path_w = try windows.cStrToPrefixedFileW(path);
8484 return openWriteModeW(&path_w, file_mode);
8585 }
......@@ -106,7 +106,7 @@ pub const File = struct {
106106 /// If a file already exists in the destination this returns OpenError.PathAlreadyExists
107107 /// Call close to clean up.
108108 pub fn openWriteNoClobber(path: []const u8, file_mode: Mode) OpenError!File {
109 if (windows.is_the_target) {
109 if (builtin.os == .windows) {
110110 const path_w = try windows.sliceToPrefixedFileW(path);
111111 return openWriteNoClobberW(&path_w, file_mode);
112112 }
......@@ -115,7 +115,7 @@ pub const File = struct {
115115 }
116116
117117 pub fn openWriteNoClobberC(path: [*]const u8, file_mode: Mode) OpenError!File {
118 if (windows.is_the_target) {
118 if (builtin.os == .windows) {
119119 const path_w = try windows.cStrToPrefixedFileW(path);
120120 return openWriteNoClobberW(&path_w, file_mode);
121121 }
......@@ -174,7 +174,7 @@ pub const File = struct {
174174
175175 /// Test whether ANSI escape codes will be treated as such.
176176 pub fn supportsAnsiEscapeCodes(self: File) bool {
177 if (windows.is_the_target) {
177 if (builtin.os == .windows) {
178178 return os.isCygwinPty(self.handle);
179179 }
180180 if (self.isTty()) {
......@@ -214,7 +214,7 @@ pub const File = struct {
214214 }
215215
216216 pub fn getEndPos(self: File) GetPosError!u64 {
217 if (windows.is_the_target) {
217 if (builtin.os == .windows) {
218218 return windows.GetFileSizeEx(self.handle);
219219 }
220220 return (try self.stat()).size;
......@@ -223,7 +223,7 @@ pub const File = struct {
223223 pub const ModeError = os.FStatError;
224224
225225 pub fn mode(self: File) ModeError!Mode {
226 if (windows.is_the_target) {
226 if (builtin.os == .windows) {
227227 return {};
228228 }
229229 return (try self.stat()).mode;
......@@ -246,7 +246,7 @@ pub const File = struct {
246246 pub const StatError = os.FStatError;
247247
248248 pub fn stat(self: File) StatError!Stat {
249 if (windows.is_the_target) {
249 if (builtin.os == .windows) {
250250 var io_status_block: windows.IO_STATUS_BLOCK = undefined;
251251 var info: windows.FILE_ALL_INFORMATION = undefined;
252252 const rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation);
......@@ -291,7 +291,7 @@ pub const File = struct {
291291 /// last modification timestamp in nanoseconds
292292 mtime: i64,
293293 ) UpdateTimesError!void {
294 if (windows.is_the_target) {
294 if (builtin.os == .windows) {
295295 const atime_ft = windows.nanoSecondsToFileTime(atime);
296296 const mtime_ft = windows.nanoSecondsToFileTime(mtime);
297297 return windows.SetFileTime(self.handle, null, &atime_ft, &mtime_ft);
lib/std/fs/path.zig+17-17
......@@ -13,16 +13,16 @@ const process = std.process;
1313
1414pub const sep_windows = '\\';
1515pub const sep_posix = '/';
16pub const sep = if (windows.is_the_target) sep_windows else sep_posix;
16pub const sep = if (builtin.os == .windows) sep_windows else sep_posix;
1717
1818pub const sep_str = [1]u8{sep};
1919
2020pub const delimiter_windows = ';';
2121pub const delimiter_posix = ':';
22pub const delimiter = if (windows.is_the_target) delimiter_windows else delimiter_posix;
22pub const delimiter = if (builtin.os == .windows) delimiter_windows else delimiter_posix;
2323
2424pub fn isSep(byte: u8) bool {
25 if (windows.is_the_target) {
25 if (builtin.os == .windows) {
2626 return byte == '/' or byte == '\\';
2727 } else {
2828 return byte == '/';
......@@ -72,7 +72,7 @@ fn joinSep(allocator: *Allocator, separator: u8, paths: []const []const u8) ![]u
7272 return buf;
7373}
7474
75pub const join = if (windows.is_the_target) joinWindows else joinPosix;
75pub const join = if (builtin.os == .windows) joinWindows else joinPosix;
7676
7777/// Naively combines a series of paths with the native path seperator.
7878/// Allocates memory for the result, which must be freed by the caller.
......@@ -129,7 +129,7 @@ test "join" {
129129}
130130
131131pub fn isAbsolute(path: []const u8) bool {
132 if (windows.is_the_target) {
132 if (builtin.os == .windows) {
133133 return isAbsoluteWindows(path);
134134 } else {
135135 return isAbsolutePosix(path);
......@@ -327,7 +327,7 @@ test "windowsParsePath" {
327327}
328328
329329pub fn diskDesignator(path: []const u8) []const u8 {
330 if (windows.is_the_target) {
330 if (builtin.os == .windows) {
331331 return diskDesignatorWindows(path);
332332 } else {
333333 return "";
......@@ -392,7 +392,7 @@ fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) bool {
392392
393393/// On Windows, this calls `resolveWindows` and on POSIX it calls `resolvePosix`.
394394pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 {
395 if (windows.is_the_target) {
395 if (builtin.os == .windows) {
396396 return resolveWindows(allocator, paths);
397397 } else {
398398 return resolvePosix(allocator, paths);
......@@ -409,7 +409,7 @@ pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 {
409409/// Without performing actual syscalls, resolving `..` could be incorrect.
410410pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
411411 if (paths.len == 0) {
412 assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd
412 assert(builtin.os == .windows); // resolveWindows called on non windows can't use getCwd
413413 return process.getCwdAlloc(allocator);
414414 }
415415
......@@ -504,7 +504,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
504504 result_disk_designator = result[0..result_index];
505505 },
506506 WindowsPath.Kind.None => {
507 assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd
507 assert(builtin.os == .windows); // resolveWindows called on non windows can't use getCwd
508508 const cwd = try process.getCwdAlloc(allocator);
509509 defer allocator.free(cwd);
510510 const parsed_cwd = windowsParsePath(cwd);
......@@ -519,7 +519,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
519519 },
520520 }
521521 } else {
522 assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd
522 assert(builtin.os == .windows); // resolveWindows called on non windows can't use getCwd
523523 // TODO call get cwd for the result_disk_designator instead of the global one
524524 const cwd = try process.getCwdAlloc(allocator);
525525 defer allocator.free(cwd);
......@@ -590,7 +590,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
590590/// Without performing actual syscalls, resolving `..` could be incorrect.
591591pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
592592 if (paths.len == 0) {
593 assert(!windows.is_the_target); // resolvePosix called on windows can't use getCwd
593 assert(builtin.os != .windows); // resolvePosix called on windows can't use getCwd
594594 return process.getCwdAlloc(allocator);
595595 }
596596
......@@ -612,7 +612,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
612612 if (have_abs) {
613613 result = try allocator.alloc(u8, max_size);
614614 } else {
615 assert(!windows.is_the_target); // resolvePosix called on windows can't use getCwd
615 assert(builtin.os != .windows); // resolvePosix called on windows can't use getCwd
616616 const cwd = try process.getCwdAlloc(allocator);
617617 defer allocator.free(cwd);
618618 result = try allocator.alloc(u8, max_size + cwd.len + 1);
......@@ -653,7 +653,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
653653
654654test "resolve" {
655655 const cwd = try process.getCwdAlloc(debug.global_allocator);
656 if (windows.is_the_target) {
656 if (builtin.os == .windows) {
657657 if (windowsParsePath(cwd).kind == WindowsPath.Kind.Drive) {
658658 cwd[0] = asciiUpper(cwd[0]);
659659 }
......@@ -669,7 +669,7 @@ test "resolveWindows" {
669669 // TODO https://github.com/ziglang/zig/issues/3288
670670 return error.SkipZigTest;
671671 }
672 if (windows.is_the_target) {
672 if (builtin.os == .windows) {
673673 const cwd = try process.getCwdAlloc(debug.global_allocator);
674674 const parsed_cwd = windowsParsePath(cwd);
675675 {
......@@ -735,7 +735,7 @@ fn testResolvePosix(paths: []const []const u8) []u8 {
735735/// If the path is a file in the current directory (no directory component)
736736/// then returns null
737737pub fn dirname(path: []const u8) ?[]const u8 {
738 if (windows.is_the_target) {
738 if (builtin.os == .windows) {
739739 return dirnameWindows(path);
740740 } else {
741741 return dirnamePosix(path);
......@@ -867,7 +867,7 @@ fn testDirnameWindows(input: []const u8, expected_output: ?[]const u8) void {
867867}
868868
869869pub fn basename(path: []const u8) []const u8 {
870 if (windows.is_the_target) {
870 if (builtin.os == .windows) {
871871 return basenameWindows(path);
872872 } else {
873873 return basenamePosix(path);
......@@ -983,7 +983,7 @@ fn testBasenameWindows(input: []const u8, expected_output: []const u8) void {
983983/// string is returned.
984984/// On Windows this canonicalizes the drive to a capital letter and paths to `\\`.
985985pub fn relative(allocator: *Allocator, from: []const u8, to: []const u8) ![]u8 {
986 if (windows.is_the_target) {
986 if (builtin.os == .windows) {
987987 return relativeWindows(allocator, from, to);
988988 } else {
989989 return relativePosix(allocator, from, to);
lib/std/heap.zig+3-3
......@@ -44,7 +44,7 @@ const DirectAllocator = struct {
4444 if (n == 0)
4545 return (([*]u8)(undefined))[0..0];
4646
47 if (os.windows.is_the_target) {
47 if (builtin.os == .windows) {
4848 const w = os.windows;
4949
5050 // Although officially it's at least aligned to page boundary,
......@@ -130,7 +130,7 @@ const DirectAllocator = struct {
130130
131131 fn shrink(allocator: *Allocator, old_mem_unaligned: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 {
132132 const old_mem = @alignCast(mem.page_size, old_mem_unaligned);
133 if (os.windows.is_the_target) {
133 if (builtin.os == .windows) {
134134 const w = os.windows;
135135 if (new_size == 0) {
136136 // From the docs:
......@@ -170,7 +170,7 @@ const DirectAllocator = struct {
170170
171171 fn realloc(allocator: *Allocator, old_mem_unaligned: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 {
172172 const old_mem = @alignCast(mem.page_size, old_mem_unaligned);
173 if (os.windows.is_the_target) {
173 if (builtin.os == .windows) {
174174 if (old_mem.len == 0) {
175175 return alloc(allocator, new_size, new_align);
176176 }
lib/std/io.zig+3-3
......@@ -37,7 +37,7 @@ pub const is_async = mode != .blocking;
3737pub const GetStdIoError = os.windows.GetStdHandleError;
3838
3939pub fn getStdOut() GetStdIoError!File {
40 if (os.windows.is_the_target) {
40 if (builtin.os == .windows) {
4141 const handle = try os.windows.GetStdHandle(os.windows.STD_OUTPUT_HANDLE);
4242 return File.openHandle(handle);
4343 }
......@@ -45,7 +45,7 @@ pub fn getStdOut() GetStdIoError!File {
4545}
4646
4747pub fn getStdErr() GetStdIoError!File {
48 if (os.windows.is_the_target) {
48 if (builtin.os == .windows) {
4949 const handle = try os.windows.GetStdHandle(os.windows.STD_ERROR_HANDLE);
5050 return File.openHandle(handle);
5151 }
......@@ -53,7 +53,7 @@ pub fn getStdErr() GetStdIoError!File {
5353}
5454
5555pub fn getStdIn() GetStdIoError!File {
56 if (os.windows.is_the_target) {
56 if (builtin.os == .windows) {
5757 const handle = try os.windows.GetStdHandle(os.windows.STD_INPUT_HANDLE);
5858 return File.openHandle(handle);
5959 }
lib/std/math.zig+1-1
......@@ -202,7 +202,7 @@ pub const Complex = complex.Complex;
202202
203203pub const big = @import("math/big.zig");
204204
205comptime {
205test "" {
206206 std.meta.refAllDecls(@This());
207207}
208208
lib/std/os.zig+81-79
......@@ -23,10 +23,6 @@ const elf = std.elf;
2323const dl = @import("dynamic_library.zig");
2424const MAX_PATH_BYTES = std.fs.MAX_PATH_BYTES;
2525
26comptime {
27 assert(@import("std") == std); // std lib tests require --override-lib-dir
28}
29
3026pub const darwin = @import("os/darwin.zig");
3127pub const freebsd = @import("os/freebsd.zig");
3228pub const linux = @import("os/linux.zig");
......@@ -36,6 +32,23 @@ pub const wasi = @import("os/wasi.zig");
3632pub const windows = @import("os/windows.zig");
3733pub const zen = @import("os/zen.zig");
3834
35comptime {
36 assert(@import("std") == std); // std lib tests require --override-lib-dir
37}
38
39test "" {
40 _ = darwin;
41 _ = freebsd;
42 _ = linux;
43 _ = netbsd;
44 _ = uefi;
45 _ = wasi;
46 _ = windows;
47 _ = zen;
48
49 _ = @import("os/test.zig");
50}
51
3952/// When linking libc, this is the C API. Otherwise, it is the OS-specific system interface.
4053pub const system = if (builtin.link_libc) std.c else switch (builtin.os) {
4154 .macosx, .ios, .watchos, .tvos => darwin,
......@@ -72,13 +85,13 @@ pub const errno = system.getErrno;
7285/// must call `fsync` before `close`.
7386/// Note: The Zig standard library does not support POSIX thread cancellation.
7487pub fn close(fd: fd_t) void {
75 if (windows.is_the_target) {
88 if (builtin.os == .windows) {
7689 return windows.CloseHandle(fd);
7790 }
78 if (wasi.is_the_target) {
91 if (builtin.os == .wasi) {
7992 _ = wasi.fd_close(fd);
8093 }
81 if (darwin.is_the_target) {
94 if (comptime std.Target.current.isDarwin()) {
8295 // This avoids the EINTR problem.
8396 switch (darwin.getErrno(darwin.@"close$NOCANCEL"(fd))) {
8497 EBADF => unreachable, // Always a race condition.
......@@ -100,12 +113,12 @@ pub const GetRandomError = OpenError;
100113/// appropriate OS-specific library call. Otherwise it uses the zig standard
101114/// library implementation.
102115pub fn getrandom(buffer: []u8) GetRandomError!void {
103 if (windows.is_the_target) {
116 if (builtin.os == .windows) {
104117 return windows.RtlGenRandom(buffer);
105118 }
106 if (linux.is_the_target or freebsd.is_the_target) {
119 if (builtin.os == .linux or builtin.os == .freebsd) {
107120 var buf = buffer;
108 const use_c = !linux.is_the_target or
121 const use_c = builtin.os != .linux or
109122 std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok;
110123
111124 while (buf.len != 0) {
......@@ -132,7 +145,7 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {
132145 }
133146 return;
134147 }
135 if (wasi.is_the_target) {
148 if (builtin.os == .wasi) {
136149 switch (wasi.random_get(buffer.ptr, buffer.len)) {
137150 0 => return,
138151 else => |err| return unexpectedErrno(err),
......@@ -162,7 +175,7 @@ pub fn abort() noreturn {
162175 // MSVCRT abort() sometimes opens a popup window which is undesirable, so
163176 // even when linking libc on Windows we use our own abort implementation.
164177 // See https://github.com/ziglang/zig/issues/2071 for more details.
165 if (windows.is_the_target) {
178 if (builtin.os == .windows) {
166179 if (builtin.mode == .Debug) {
167180 @breakpoint();
168181 }
......@@ -193,14 +206,14 @@ pub fn raise(sig: u8) RaiseError!void {
193206 }
194207 }
195208
196 if (wasi.is_the_target) {
209 if (builtin.os == .wasi) {
197210 switch (wasi.proc_raise(SIGABRT)) {
198211 0 => return,
199212 else => |err| return unexpectedErrno(err),
200213 }
201214 }
202215
203 if (linux.is_the_target) {
216 if (builtin.os == .linux) {
204217 var set: linux.sigset_t = undefined;
205218 linux.blockAppSignals(&set);
206219 const tid = linux.syscall0(linux.SYS_gettid);
......@@ -232,16 +245,16 @@ pub fn exit(status: u8) noreturn {
232245 if (builtin.link_libc) {
233246 system.exit(status);
234247 }
235 if (windows.is_the_target) {
248 if (builtin.os == .windows) {
236249 windows.kernel32.ExitProcess(status);
237250 }
238 if (wasi.is_the_target) {
251 if (builtin.os == .wasi) {
239252 wasi.proc_exit(status);
240253 }
241 if (linux.is_the_target and !builtin.single_threaded) {
254 if (builtin.os == .linux and !builtin.single_threaded) {
242255 linux.exit_group(status);
243256 }
244 if (uefi.is_the_target) {
257 if (builtin.os == .uefi) {
245258 // exit() is only avaliable if exitBootServices() has not been called yet.
246259 // This call to exit should not fail, so we don't care about its return value.
247260 if (uefi.system_table.boot_services) |bs| {
......@@ -270,11 +283,11 @@ pub const ReadError = error{
270283/// If the application has a global event loop enabled, EAGAIN is handled
271284/// via the event loop. Otherwise EAGAIN results in error.WouldBlock.
272285pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
273 if (windows.is_the_target) {
286 if (builtin.os == .windows) {
274287 return windows.ReadFile(fd, buf);
275288 }
276289
277 if (wasi.is_the_target and !builtin.link_libc) {
290 if (builtin.os == .wasi and !builtin.link_libc) {
278291 const iovs = [1]iovec{iovec{
279292 .iov_base = buf.ptr,
280293 .iov_len = buf.len,
......@@ -314,7 +327,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
314327/// Number of bytes read is returned. Upon reading end-of-file, zero is returned.
315328/// This function is for blocking file descriptors only.
316329pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) ReadError!usize {
317 if (darwin.is_the_target) {
330 if (comptime std.Target.current.isDarwin()) {
318331 // Darwin does not have preadv but it does have pread.
319332 var off: usize = 0;
320333 var iov_i: usize = 0;
......@@ -385,11 +398,11 @@ pub const WriteError = error{
385398/// Write to a file descriptor. Keeps trying if it gets interrupted.
386399/// This function is for blocking file descriptors only.
387400pub fn write(fd: fd_t, bytes: []const u8) WriteError!void {
388 if (windows.is_the_target) {
401 if (builtin.os == .windows) {
389402 return windows.WriteFile(fd, bytes);
390403 }
391404
392 if (wasi.is_the_target and !builtin.link_libc) {
405 if (builtin.os == .wasi and !builtin.link_libc) {
393406 const ciovs = [1]iovec_const{iovec_const{
394407 .iov_base = bytes.ptr,
395408 .iov_len = bytes.len,
......@@ -464,7 +477,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!void {
464477/// This function is for blocking file descriptors only. For non-blocking, see
465478/// `pwritevAsync`.
466479pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) WriteError!void {
467 if (darwin.is_the_target) {
480 if (comptime std.Target.current.isDarwin()) {
468481 // Darwin does not have pwritev but it does have pwrite.
469482 var off: usize = 0;
470483 var iov_i: usize = 0;
......@@ -828,7 +841,7 @@ pub const GetCwdError = error{
828841
829842/// The result is a slice of out_buffer, indexed from 0.
830843pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {
831 if (windows.is_the_target) {
844 if (builtin.os == .windows) {
832845 return windows.GetCurrentDirectory(out_buffer);
833846 }
834847
......@@ -869,7 +882,7 @@ pub const SymLinkError = error{
869882/// If `sym_link_path` exists, it will not be overwritten.
870883/// See also `symlinkC` and `symlinkW`.
871884pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!void {
872 if (windows.is_the_target) {
885 if (builtin.os == .windows) {
873886 const target_path_w = try windows.sliceToPrefixedFileW(target_path);
874887 const sym_link_path_w = try windows.sliceToPrefixedFileW(sym_link_path);
875888 return windows.CreateSymbolicLinkW(&sym_link_path_w, &target_path_w, 0);
......@@ -883,7 +896,7 @@ pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!
883896/// This is the same as `symlink` except the parameters are null-terminated pointers.
884897/// See also `symlink`.
885898pub fn symlinkC(target_path: [*]const u8, sym_link_path: [*]const u8) SymLinkError!void {
886 if (windows.is_the_target) {
899 if (builtin.os == .windows) {
887900 const target_path_w = try windows.cStrToPrefixedFileW(target_path);
888901 const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path);
889902 return windows.CreateSymbolicLinkW(&sym_link_path_w, &target_path_w, 0);
......@@ -958,7 +971,7 @@ pub const UnlinkError = error{
958971/// Delete a name and possibly the file it refers to.
959972/// See also `unlinkC`.
960973pub fn unlink(file_path: []const u8) UnlinkError!void {
961 if (windows.is_the_target) {
974 if (builtin.os == .windows) {
962975 const file_path_w = try windows.sliceToPrefixedFileW(file_path);
963976 return windows.DeleteFileW(&file_path_w);
964977 } else {
......@@ -969,7 +982,7 @@ pub fn unlink(file_path: []const u8) UnlinkError!void {
969982
970983/// Same as `unlink` except the parameter is a null terminated UTF8-encoded string.
971984pub fn unlinkC(file_path: [*]const u8) UnlinkError!void {
972 if (windows.is_the_target) {
985 if (builtin.os == .windows) {
973986 const file_path_w = try windows.cStrToPrefixedFileW(file_path);
974987 return windows.DeleteFileW(&file_path_w);
975988 }
......@@ -999,7 +1012,7 @@ pub const UnlinkatError = UnlinkError || error{
9991012
10001013/// Delete a file name and possibly the file it refers to, based on an open directory handle.
10011014pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void {
1002 if (windows.is_the_target) {
1015 if (builtin.os == .windows) {
10031016 const file_path_w = try windows.sliceToPrefixedFileW(file_path);
10041017 return unlinkatW(dirfd, &file_path_w, flags);
10051018 }
......@@ -1009,7 +1022,7 @@ pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!vo
10091022
10101023/// Same as `unlinkat` but `file_path` is a null-terminated string.
10111024pub fn unlinkatC(dirfd: fd_t, file_path_c: [*]const u8, flags: u32) UnlinkatError!void {
1012 if (windows.is_the_target) {
1025 if (builtin.os == .windows) {
10131026 const file_path_w = try windows.cStrToPrefixedFileW(file_path_c);
10141027 return unlinkatW(dirfd, &file_path_w, flags);
10151028 }
......@@ -1063,7 +1076,6 @@ pub fn unlinkatW(dirfd: fd_t, sub_path_w: [*]const u16, flags: u32) UnlinkatErro
10631076 return error.FileBusy;
10641077 }
10651078
1066
10671079 var attr = w.OBJECT_ATTRIBUTES{
10681080 .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
10691081 .RootDirectory = dirfd,
......@@ -1121,7 +1133,7 @@ const RenameError = error{
11211133
11221134/// Change the name or location of a file.
11231135pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void {
1124 if (windows.is_the_target) {
1136 if (builtin.os == .windows) {
11251137 const old_path_w = try windows.sliceToPrefixedFileW(old_path);
11261138 const new_path_w = try windows.sliceToPrefixedFileW(new_path);
11271139 return renameW(&old_path_w, &new_path_w);
......@@ -1134,7 +1146,7 @@ pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void {
11341146
11351147/// Same as `rename` except the parameters are null-terminated byte arrays.
11361148pub fn renameC(old_path: [*]const u8, new_path: [*]const u8) RenameError!void {
1137 if (windows.is_the_target) {
1149 if (builtin.os == .windows) {
11381150 const old_path_w = try windows.cStrToPrefixedFileW(old_path);
11391151 const new_path_w = try windows.cStrToPrefixedFileW(new_path);
11401152 return renameW(&old_path_w, &new_path_w);
......@@ -1189,7 +1201,7 @@ pub const MakeDirError = error{
11891201/// Create a directory.
11901202/// `mode` is ignored on Windows.
11911203pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void {
1192 if (windows.is_the_target) {
1204 if (builtin.os == .windows) {
11931205 const dir_path_w = try windows.sliceToPrefixedFileW(dir_path);
11941206 return windows.CreateDirectoryW(&dir_path_w, null);
11951207 } else {
......@@ -1200,7 +1212,7 @@ pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void {
12001212
12011213/// Same as `mkdir` but the parameter is a null-terminated UTF8-encoded string.
12021214pub fn mkdirC(dir_path: [*]const u8, mode: u32) MakeDirError!void {
1203 if (windows.is_the_target) {
1215 if (builtin.os == .windows) {
12041216 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);
12051217 return windows.CreateDirectoryW(&dir_path_w, null);
12061218 }
......@@ -1239,7 +1251,7 @@ pub const DeleteDirError = error{
12391251
12401252/// Deletes an empty directory.
12411253pub fn rmdir(dir_path: []const u8) DeleteDirError!void {
1242 if (windows.is_the_target) {
1254 if (builtin.os == .windows) {
12431255 const dir_path_w = try windows.sliceToPrefixedFileW(dir_path);
12441256 return windows.RemoveDirectoryW(&dir_path_w);
12451257 } else {
......@@ -1250,7 +1262,7 @@ pub fn rmdir(dir_path: []const u8) DeleteDirError!void {
12501262
12511263/// Same as `rmdir` except the parameter is null-terminated.
12521264pub fn rmdirC(dir_path: [*]const u8) DeleteDirError!void {
1253 if (windows.is_the_target) {
1265 if (builtin.os == .windows) {
12541266 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);
12551267 return windows.RemoveDirectoryW(&dir_path_w);
12561268 }
......@@ -1286,7 +1298,7 @@ pub const ChangeCurDirError = error{
12861298/// Changes the current working directory of the calling process.
12871299/// `dir_path` is recommended to be a UTF-8 encoded string.
12881300pub fn chdir(dir_path: []const u8) ChangeCurDirError!void {
1289 if (windows.is_the_target) {
1301 if (builtin.os == .windows) {
12901302 const dir_path_w = try windows.sliceToPrefixedFileW(dir_path);
12911303 @compileError("TODO implement chdir for Windows");
12921304 } else {
......@@ -1297,7 +1309,7 @@ pub fn chdir(dir_path: []const u8) ChangeCurDirError!void {
12971309
12981310/// Same as `chdir` except the parameter is null-terminated.
12991311pub fn chdirC(dir_path: [*]const u8) ChangeCurDirError!void {
1300 if (windows.is_the_target) {
1312 if (builtin.os == .windows) {
13011313 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);
13021314 @compileError("TODO implement chdir for Windows");
13031315 }
......@@ -1328,7 +1340,7 @@ pub const ReadLinkError = error{
13281340/// Read value of a symbolic link.
13291341/// The return value is a slice of `out_buffer` from index 0.
13301342pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {
1331 if (windows.is_the_target) {
1343 if (builtin.os == .windows) {
13321344 const file_path_w = try windows.sliceToPrefixedFileW(file_path);
13331345 @compileError("TODO implement readlink for Windows");
13341346 } else {
......@@ -1339,7 +1351,7 @@ pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {
13391351
13401352/// Same as `readlink` except `file_path` is null-terminated.
13411353pub fn readlinkC(file_path: [*]const u8, out_buffer: []u8) ReadLinkError![]u8 {
1342 if (windows.is_the_target) {
1354 if (builtin.os == .windows) {
13431355 const file_path_w = try windows.cStrToPrefixedFileW(file_path);
13441356 @compileError("TODO implement readlink for Windows");
13451357 }
......@@ -1360,7 +1372,7 @@ pub fn readlinkC(file_path: [*]const u8, out_buffer: []u8) ReadLinkError![]u8 {
13601372}
13611373
13621374pub fn readlinkatC(dirfd: fd_t, file_path: [*]const u8, out_buffer: []u8) ReadLinkError![]u8 {
1363 if (windows.is_the_target) {
1375 if (builtin.os == .windows) {
13641376 const file_path_w = try windows.cStrToPrefixedFileW(file_path);
13651377 @compileError("TODO implement readlink for Windows");
13661378 }
......@@ -1428,7 +1440,7 @@ pub fn setregid(rgid: u32, egid: u32) SetIdError!void {
14281440
14291441/// Test whether a file descriptor refers to a terminal.
14301442pub fn isatty(handle: fd_t) bool {
1431 if (windows.is_the_target) {
1443 if (builtin.os == .windows) {
14321444 if (isCygwinPty(handle))
14331445 return true;
14341446
......@@ -1438,10 +1450,10 @@ pub fn isatty(handle: fd_t) bool {
14381450 if (builtin.link_libc) {
14391451 return system.isatty(handle) != 0;
14401452 }
1441 if (wasi.is_the_target) {
1453 if (builtin.os == .wasi) {
14421454 @compileError("TODO implement std.os.isatty for WASI");
14431455 }
1444 if (linux.is_the_target) {
1456 if (builtin.os == .linux) {
14451457 var wsz: linux.winsize = undefined;
14461458 return linux.syscall3(linux.SYS_ioctl, @bitCast(usize, isize(handle)), linux.TIOCGWINSZ, @ptrToInt(&wsz)) == 0;
14471459 }
......@@ -1449,7 +1461,7 @@ pub fn isatty(handle: fd_t) bool {
14491461}
14501462
14511463pub fn isCygwinPty(handle: fd_t) bool {
1452 if (!windows.is_the_target) return false;
1464 if (builtin.os != .windows) return false;
14531465
14541466 const size = @sizeOf(windows.FILE_NAME_INFO);
14551467 var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = [_]u8{0} ** (size + windows.MAX_PATH);
......@@ -1949,7 +1961,7 @@ pub const FStatError = error{SystemResources} || UnexpectedError;
19491961
19501962pub fn fstat(fd: fd_t) FStatError!Stat {
19511963 var stat: Stat = undefined;
1952 if (darwin.is_the_target) {
1964 if (comptime std.Target.current.isDarwin()) {
19531965 switch (darwin.getErrno(darwin.@"fstat$INODE64"(fd, &stat))) {
19541966 0 => return stat,
19551967 EINVAL => unreachable,
......@@ -2215,7 +2227,7 @@ pub const AccessError = error{
22152227/// check user's permissions for a file
22162228/// TODO currently this assumes `mode` is `F_OK` on Windows.
22172229pub fn access(path: []const u8, mode: u32) AccessError!void {
2218 if (windows.is_the_target) {
2230 if (builtin.os == .windows) {
22192231 const path_w = try windows.sliceToPrefixedFileW(path);
22202232 _ = try windows.GetFileAttributesW(&path_w);
22212233 return;
......@@ -2226,7 +2238,7 @@ pub fn access(path: []const u8, mode: u32) AccessError!void {
22262238
22272239/// Same as `access` except `path` is null-terminated.
22282240pub fn accessC(path: [*]const u8, mode: u32) AccessError!void {
2229 if (windows.is_the_target) {
2241 if (builtin.os == .windows) {
22302242 const path_w = try windows.cStrToPrefixedFileW(path);
22312243 _ = try windows.GetFileAttributesW(&path_w);
22322244 return;
......@@ -2346,7 +2358,7 @@ pub const SeekError = error{Unseekable} || UnexpectedError;
23462358
23472359/// Repositions read/write file offset relative to the beginning.
23482360pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
2349 if (linux.is_the_target and !builtin.link_libc and @sizeOf(usize) == 4) {
2361 if (builtin.os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
23502362 var result: u64 = undefined;
23512363 switch (errno(system.llseek(fd, offset, &result, SEEK_SET))) {
23522364 0 => return,
......@@ -2358,7 +2370,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
23582370 else => |err| return unexpectedErrno(err),
23592371 }
23602372 }
2361 if (windows.is_the_target) {
2373 if (builtin.os == .windows) {
23622374 return windows.SetFilePointerEx_BEGIN(fd, offset);
23632375 }
23642376 const ipos = @bitCast(i64, offset); // the OS treats this as unsigned
......@@ -2375,7 +2387,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void {
23752387
23762388/// Repositions read/write file offset relative to the current offset.
23772389pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
2378 if (linux.is_the_target and !builtin.link_libc and @sizeOf(usize) == 4) {
2390 if (builtin.os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
23792391 var result: u64 = undefined;
23802392 switch (errno(system.llseek(fd, @bitCast(u64, offset), &result, SEEK_CUR))) {
23812393 0 => return,
......@@ -2387,7 +2399,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
23872399 else => |err| return unexpectedErrno(err),
23882400 }
23892401 }
2390 if (windows.is_the_target) {
2402 if (builtin.os == .windows) {
23912403 return windows.SetFilePointerEx_CURRENT(fd, offset);
23922404 }
23932405 switch (errno(system.lseek(fd, offset, SEEK_CUR))) {
......@@ -2403,7 +2415,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void {
24032415
24042416/// Repositions read/write file offset relative to the end.
24052417pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
2406 if (linux.is_the_target and !builtin.link_libc and @sizeOf(usize) == 4) {
2418 if (builtin.os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
24072419 var result: u64 = undefined;
24082420 switch (errno(system.llseek(fd, @bitCast(u64, offset), &result, SEEK_END))) {
24092421 0 => return,
......@@ -2415,7 +2427,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
24152427 else => |err| return unexpectedErrno(err),
24162428 }
24172429 }
2418 if (windows.is_the_target) {
2430 if (builtin.os == .windows) {
24192431 return windows.SetFilePointerEx_END(fd, offset);
24202432 }
24212433 switch (errno(system.lseek(fd, offset, SEEK_END))) {
......@@ -2431,7 +2443,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void {
24312443
24322444/// Returns the read/write file offset relative to the beginning.
24332445pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {
2434 if (linux.is_the_target and !builtin.link_libc and @sizeOf(usize) == 4) {
2446 if (builtin.os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) {
24352447 var result: u64 = undefined;
24362448 switch (errno(system.llseek(fd, 0, &result, SEEK_CUR))) {
24372449 0 => return result,
......@@ -2443,7 +2455,7 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 {
24432455 else => |err| return unexpectedErrno(err),
24442456 }
24452457 }
2446 if (windows.is_the_target) {
2458 if (builtin.os == .windows) {
24472459 return windows.SetFilePointerEx_CURRENT_get(fd);
24482460 }
24492461 const rc = system.lseek(fd, 0, SEEK_CUR);
......@@ -2492,7 +2504,7 @@ pub const RealPathError = error{
24922504/// The return value is a slice of `out_buffer`, but not necessarily from the beginning.
24932505/// See also `realpathC` and `realpathW`.
24942506pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
2495 if (windows.is_the_target) {
2507 if (builtin.os == .windows) {
24962508 const pathname_w = try windows.sliceToPrefixedFileW(pathname);
24972509 return realpathW(&pathname_w, out_buffer);
24982510 }
......@@ -2502,11 +2514,11 @@ pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathE
25022514
25032515/// Same as `realpath` except `pathname` is null-terminated.
25042516pub fn realpathC(pathname: [*]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
2505 if (windows.is_the_target) {
2517 if (builtin.os == .windows) {
25062518 const pathname_w = try windows.cStrToPrefixedFileW(pathname);
25072519 return realpathW(&pathname_w, out_buffer);
25082520 }
2509 if (linux.is_the_target and !builtin.link_libc) {
2521 if (builtin.os == .linux and !builtin.link_libc) {
25102522 const fd = try openC(pathname, linux.O_PATH | linux.O_NONBLOCK | linux.O_CLOEXEC, 0);
25112523 defer close(fd);
25122524
......@@ -2584,9 +2596,12 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void {
25842596 }
25852597}
25862598
2587pub fn dl_iterate_phdr(comptime T: type, callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*T) i32, data: ?*T) isize {
2588 // This is implemented only for systems using ELF executables
2589 if (windows.is_the_target or builtin.os == .uefi or wasi.is_the_target or darwin.is_the_target)
2599pub fn dl_iterate_phdr(
2600 comptime T: type,
2601 callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*T) i32,
2602 data: ?*T,
2603) isize {
2604 if (builtin.object_format != .elf)
25902605 @compileError("dl_iterate_phdr is not available for this target");
25912606
25922607 if (builtin.link_libc) {
......@@ -2725,7 +2740,7 @@ pub const SigaltstackError = error{
27252740} || UnexpectedError;
27262741
27272742pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void {
2728 if (windows.is_the_target or uefi.is_the_target or wasi.is_the_target)
2743 if (builtin.os == .windows or builtin.os == .uefi or builtin.os == .wasi)
27292744 @compileError("std.os.sigaltstack not available for this target");
27302745
27312746 switch (errno(system.sigaltstack(ss, old_ss))) {
......@@ -2797,7 +2812,7 @@ pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 {
27972812 else => |err| return unexpectedErrno(err),
27982813 }
27992814 }
2800 if (linux.is_the_target) {
2815 if (builtin.os == .linux) {
28012816 var uts: utsname = undefined;
28022817 switch (errno(system.uname(&uts))) {
28032818 0 => {
......@@ -2813,16 +2828,3 @@ pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 {
28132828
28142829 @compileError("TODO implement gethostname for this OS");
28152830}
2816
2817test "" {
2818 _ = @import("os/darwin.zig");
2819 _ = @import("os/freebsd.zig");
2820 _ = @import("os/linux.zig");
2821 _ = @import("os/netbsd.zig");
2822 _ = @import("os/uefi.zig");
2823 _ = @import("os/wasi.zig");
2824 _ = @import("os/windows.zig");
2825 _ = @import("os/zen.zig");
2826
2827 _ = @import("os/test.zig");
2828}
lib/std/os/darwin.zig-4
......@@ -1,8 +1,4 @@
11const builtin = @import("builtin");
22const std = @import("../std.zig");
3pub const is_the_target = switch (builtin.os) {
4 .macosx, .tvos, .watchos, .ios => true,
5 else => false,
6};
73pub usingnamespace std.c;
84pub usingnamespace @import("bits.zig");
lib/std/os/freebsd.zig-2
......@@ -1,5 +1,3 @@
11const std = @import("../std.zig");
2const builtin = @import("builtin");
3pub const is_the_target = builtin.os == .freebsd;
42pub usingnamespace std.c;
53pub usingnamespace @import("bits.zig");
lib/std/os/linux.zig+1-2
......@@ -13,7 +13,6 @@ const elf = std.elf;
1313const vdso = @import("linux/vdso.zig");
1414const dl = @import("../dynamic_library.zig");
1515
16pub const is_the_target = builtin.os == .linux;
1716pub usingnamespace switch (builtin.arch) {
1817 .x86_64 => @import("linux/x86_64.zig"),
1918 .aarch64 => @import("linux/arm64.zig"),
......@@ -1079,7 +1078,7 @@ pub fn io_uring_register(fd: i32, opcode: u32, arg: ?*const c_void, nr_args: u32
10791078}
10801079
10811080test "" {
1082 if (is_the_target) {
1081 if (builtin.os == .linux) {
10831082 _ = @import("linux/test.zig");
10841083 }
10851084}
lib/std/os/netbsd.zig-2
......@@ -1,5 +1,3 @@
1const builtin = @import("builtin");
21const std = @import("../std.zig");
3pub const is_the_target = builtin.os == .netbsd;
42pub usingnamespace std.c;
53pub usingnamespace @import("bits.zig");
lib/std/os/test.zig+3-3
......@@ -53,7 +53,7 @@ test "std.Thread.getCurrentId" {
5353 thread.wait();
5454 if (Thread.use_pthreads) {
5555 expect(thread_current_id == thread_id);
56 } else if (os.windows.is_the_target) {
56 } else if (builtin.os == .windows) {
5757 expect(Thread.getCurrentId() != thread_current_id);
5858 } else {
5959 // If the thread completes very quickly, then thread_id can be 0. See the
......@@ -212,7 +212,7 @@ test "dl_iterate_phdr" {
212212}
213213
214214test "gethostname" {
215 if (os.windows.is_the_target)
215 if (builtin.os == .windows)
216216 return error.SkipZigTest;
217217
218218 var buf: [os.HOST_NAME_MAX]u8 = undefined;
......@@ -221,7 +221,7 @@ test "gethostname" {
221221}
222222
223223test "pipe" {
224 if (os.windows.is_the_target)
224 if (builtin.os == .windows)
225225 return error.SkipZigTest;
226226
227227 var fds = try os.pipe();
lib/std/os/uefi.zig+13-3
......@@ -1,16 +1,15 @@
11/// A protocol is an interface identified by a GUID.
22pub const protocols = @import("uefi/protocols.zig");
3
34/// Status codes returned by EFI interfaces
45pub const status = @import("uefi/status.zig");
56pub const tables = @import("uefi/tables.zig");
67
78const fmt = @import("std").fmt;
89
9const builtin = @import("builtin");
10pub const is_the_target = builtin.os == .uefi;
11
1210/// The EFI image's handle that is passed to its entry point.
1311pub var handle: Handle = undefined;
12
1413/// A pointer to the EFI System Table that is passed to the EFI image's entry point.
1514pub var system_table: *tables.SystemTable = undefined;
1615
......@@ -50,26 +49,35 @@ pub const Handle = *@OpaqueType();
5049pub const Time = extern struct {
5150 /// 1900 - 9999
5251 year: u16,
52
5353 /// 1 - 12
5454 month: u8,
55
5556 /// 1 - 31
5657 day: u8,
58
5759 /// 0 - 23
5860 hour: u8,
61
5962 /// 0 - 59
6063 minute: u8,
64
6165 /// 0 - 59
6266 second: u8,
6367 _pad1: u8,
68
6469 /// 0 - 999999999
6570 nanosecond: u32,
71
6672 /// The time's offset in minutes from UTC.
6773 /// Allowed values are -1440 to 1440 or unspecified_timezone
6874 timezone: i16,
6975 daylight: packed struct {
7076 _pad1: u6,
77
7178 /// If true, the time has been adjusted for daylight savings time.
7279 in_daylight: bool,
80
7381 /// If true, the time is affected by daylight savings time.
7482 adjust_daylight: bool,
7583 },
......@@ -83,8 +91,10 @@ pub const Time = extern struct {
8391pub const TimeCapabilities = extern struct {
8492 /// Resolution in Hz
8593 resolution: u32,
94
8695 /// Accuracy in an error rate of 1e-6 parts per million.
8796 accuracy: u32,
97
8898 /// If true, a time set operation clears the device's time below the resolution level.
8999 sets_to_zero: bool,
90100};
lib/std/os/wasi.zig-2
......@@ -1,10 +1,8 @@
11// Based on https://github.com/CraneStation/wasi-sysroot/blob/wasi/libc-bottom-half/headers/public/wasi/core.h
22// and https://github.com/WebAssembly/WASI/blob/master/design/WASI-core.md
3const builtin = @import("builtin");
43const std = @import("std");
54const assert = std.debug.assert;
65
7pub const is_the_target = builtin.os == .wasi;
86pub usingnamespace @import("bits.zig");
97
108comptime {
lib/std/os/windows.zig-27
......@@ -11,7 +11,6 @@ const assert = std.debug.assert;
1111const math = std.math;
1212const maxInt = std.math.maxInt;
1313
14pub const is_the_target = builtin.os == .windows;
1514pub const advapi32 = @import("windows/advapi32.zig");
1615pub const kernel32 = @import("windows/kernel32.zig");
1716pub const ntdll = @import("windows/ntdll.zig");
......@@ -22,32 +21,6 @@ pub usingnamespace @import("windows/bits.zig");
2221
2322pub const self_process_handle = @intToPtr(HANDLE, maxInt(usize));
2423
25/// `builtin` is missing `subsystem` when the subsystem is automatically detected,
26/// so Zig standard library has the subsystem detection logic here. This should generally be
27/// used rather than `builtin.subsystem`.
28/// On non-windows targets, this is `null`.
29pub const subsystem: ?builtin.SubSystem = blk: {
30 if (@hasDecl(builtin, "subsystem")) break :blk builtin.subsystem;
31 switch (builtin.os) {
32 .windows => {
33 if (builtin.is_test) {
34 break :blk builtin.SubSystem.Console;
35 }
36 const root = @import("root");
37 if (@hasDecl(root, "WinMain") or
38 @hasDecl(root, "wWinMain") or
39 @hasDecl(root, "WinMainCRTStartup") or
40 @hasDecl(root, "wWinMainCRTStartup"))
41 {
42 break :blk builtin.SubSystem.Windows;
43 } else {
44 break :blk builtin.SubSystem.Console;
45 }
46 },
47 else => break :blk null,
48 }
49};
50
5124pub const CreateFileError = error{
5225 SharingViolation,
5326 PathAlreadyExists,
lib/std/process.zig+2-2
......@@ -39,7 +39,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
3939 var result = BufMap.init(allocator);
4040 errdefer result.deinit();
4141
42 if (os.windows.is_the_target) {
42 if (builtin.os == .windows) {
4343 const ptr = try os.windows.GetEnvironmentStringsW();
4444 defer os.windows.FreeEnvironmentStringsW(ptr);
4545
......@@ -129,7 +129,7 @@ pub const GetEnvVarOwnedError = error{
129129/// Caller must free returned memory.
130130/// TODO make this go through libc when we have it
131131pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {
132 if (os.windows.is_the_target) {
132 if (builtin.os == .windows) {
133133 const key_with_null = try std.unicode.utf8ToUtf16LeWithNull(allocator, key);
134134 defer allocator.free(key_with_null);
135135
lib/std/special/panic.zig deleted-31
......@@ -1,31 +0,0 @@
1// This file is the default panic handler if the root source file does not
2// have a `pub fn panic`.
3// If this file wants to import other files *by name*, support for that would
4// have to be added in the compiler.
5
6const builtin = @import("builtin");
7const std = @import("std");
8
9pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
10 @setCold(true);
11 switch (builtin.os) {
12 .freestanding => {
13 while (true) {
14 @breakpoint();
15 }
16 },
17 .wasi => {
18 std.debug.warn("{}", msg);
19 _ = std.os.wasi.proc_raise(std.os.wasi.SIGABRT);
20 unreachable;
21 },
22 .uefi => {
23 // TODO look into using the debug info and logging helpful messages
24 std.os.abort();
25 },
26 else => {
27 const first_trace_addr = @returnAddress();
28 std.debug.panicExtra(error_return_trace, first_trace_addr, "{}", msg);
29 },
30 }
31}
lib/std/std.zig+3-1
......@@ -22,11 +22,13 @@ pub const SpinLock = @import("spinlock.zig").SpinLock;
2222pub const StaticallyInitializedMutex = @import("statically_initialized_mutex.zig").StaticallyInitializedMutex;
2323pub const StringHashMap = @import("hash_map.zig").StringHashMap;
2424pub const TailQueue = @import("linked_list.zig").TailQueue;
25pub const Target = @import("target.zig").Target;
2526pub const Thread = @import("thread.zig").Thread;
2627
2728pub const atomic = @import("atomic.zig");
2829pub const base64 = @import("base64.zig");
2930pub const build = @import("build.zig");
31pub const builtin = @import("builtin.zig");
3032pub const c = @import("c.zig");
3133pub const coff = @import("coff.zig");
3234pub const crypto = @import("crypto.zig");
......@@ -63,6 +65,6 @@ pub const unicode = @import("unicode.zig");
6365pub const valgrind = @import("valgrind.zig");
6466pub const zig = @import("zig.zig");
6567
66comptime {
68test "" {
6769 meta.refAllDecls(@This());
6870}
lib/std/target.zig created+617
......@@ -0,0 +1,617 @@
1const std = @import("std.zig");
2const builtin = std.builtin;
3
4/// TODO Nearly all the functions in this namespace would be
5/// better off if https://github.com/ziglang/zig/issues/425
6/// was solved.
7pub const Target = union(enum) {
8 Native: void,
9 Cross: Cross,
10
11 pub const Os = enum {
12 freestanding,
13 ananas,
14 cloudabi,
15 dragonfly,
16 freebsd,
17 fuchsia,
18 ios,
19 kfreebsd,
20 linux,
21 lv2,
22 macosx,
23 netbsd,
24 openbsd,
25 solaris,
26 windows,
27 haiku,
28 minix,
29 rtems,
30 nacl,
31 cnk,
32 aix,
33 cuda,
34 nvcl,
35 amdhsa,
36 ps4,
37 elfiamcu,
38 tvos,
39 watchos,
40 mesa3d,
41 contiki,
42 amdpal,
43 hermit,
44 hurd,
45 wasi,
46 emscripten,
47 zen,
48 uefi,
49 };
50
51 pub const Arch = union(enum) {
52 arm: Arm32,
53 armeb: Arm32,
54 aarch64: Arm64,
55 aarch64_be: Arm64,
56 aarch64_32: Arm64,
57 arc,
58 avr,
59 bpfel,
60 bpfeb,
61 hexagon,
62 mips,
63 mipsel,
64 mips64,
65 mips64el,
66 msp430,
67 powerpc,
68 powerpc64,
69 powerpc64le,
70 r600,
71 amdgcn,
72 riscv32,
73 riscv64,
74 sparc,
75 sparcv9,
76 sparcel,
77 s390x,
78 tce,
79 tcele,
80 thumb: Arm32,
81 thumbeb: Arm32,
82 i386,
83 x86_64,
84 xcore,
85 nvptx,
86 nvptx64,
87 le32,
88 le64,
89 amdil,
90 amdil64,
91 hsail,
92 hsail64,
93 spir,
94 spir64,
95 kalimba: Kalimba,
96 shave,
97 lanai,
98 wasm32,
99 wasm64,
100 renderscript32,
101 renderscript64,
102
103 pub const Arm32 = enum {
104 v8_5a,
105 v8_4a,
106 v8_3a,
107 v8_2a,
108 v8_1a,
109 v8,
110 v8r,
111 v8m_baseline,
112 v8m_mainline,
113 v8_1m_mainline,
114 v7,
115 v7em,
116 v7m,
117 v7s,
118 v7k,
119 v7ve,
120 v6,
121 v6m,
122 v6k,
123 v6t2,
124 v5,
125 v5te,
126 v4t,
127 };
128 pub const Arm64 = enum {
129 v8_5a,
130 v8_4a,
131 v8_3a,
132 v8_2a,
133 v8_1a,
134 v8,
135 v8r,
136 v8m_baseline,
137 v8m_mainline,
138 };
139 pub const Kalimba = enum {
140 v5,
141 v4,
142 v3,
143 };
144 pub const Mips = enum {
145 r6,
146 };
147 };
148
149 pub const Abi = enum {
150 none,
151 gnu,
152 gnuabin32,
153 gnuabi64,
154 gnueabi,
155 gnueabihf,
156 gnux32,
157 code16,
158 eabi,
159 eabihf,
160 elfv1,
161 elfv2,
162 android,
163 musl,
164 musleabi,
165 musleabihf,
166 msvc,
167 itanium,
168 cygnus,
169 coreclr,
170 simulator,
171 macabi,
172 };
173
174 pub const ObjectFormat = enum {
175 unknown,
176 coff,
177 elf,
178 macho,
179 wasm,
180 };
181
182 pub const SubSystem = enum {
183 Console,
184 Windows,
185 Posix,
186 Native,
187 EfiApplication,
188 EfiBootServiceDriver,
189 EfiRom,
190 EfiRuntimeDriver,
191 };
192
193 pub const Cross = struct {
194 arch: Arch,
195 os: Os,
196 abi: Abi,
197 };
198
199 pub const current = Target{
200 .Cross = Cross{
201 .arch = builtin.arch,
202 .os = builtin.os,
203 .abi = builtin.abi,
204 },
205 };
206
207 pub fn zigTriple(self: Target, allocator: *std.mem.Allocator) ![]u8 {
208 return std.fmt.allocPrint(
209 allocator,
210 "{}{}-{}-{}",
211 @tagName(self.getArch()),
212 Target.archSubArchName(self.getArch()),
213 @tagName(self.getOs()),
214 @tagName(self.getAbi()),
215 );
216 }
217
218 pub fn allocDescription(self: Target, allocator: *std.mem.Allocator) ![]u8 {
219 // TODO is there anything else worthy of the description that is not
220 // already captured in the triple?
221 return self.zigTriple(allocator);
222 }
223
224 pub fn zigTripleNoSubArch(self: Target, allocator: *std.mem.Allocator) ![]u8 {
225 return std.fmt.allocPrint(
226 allocator,
227 "{}-{}-{}",
228 @tagName(self.getArch()),
229 @tagName(self.getOs()),
230 @tagName(self.getAbi()),
231 );
232 }
233
234 pub fn linuxTriple(self: Target, allocator: *std.mem.Allocator) ![]u8 {
235 return std.fmt.allocPrint(
236 allocator,
237 "{}-{}-{}",
238 @tagName(self.getArch()),
239 @tagName(self.getOs()),
240 @tagName(self.getAbi()),
241 );
242 }
243
244 pub fn parse(text: []const u8) !Target {
245 var it = mem.separate(text, "-");
246 const arch_name = it.next() orelse return error.MissingArchitecture;
247 const os_name = it.next() orelse return error.MissingOperatingSystem;
248 const abi_name = it.next();
249
250 var cross = Cross{
251 .arch = try parseArchSub(arch_name),
252 .os = try parseOs(os_name),
253 .abi = undefined,
254 };
255 cross.abi = if (abi_name) |n| try parseAbi(n) else defaultAbi(cross.arch, cross.os);
256 return Target{ .Cross = cross };
257 }
258
259 pub fn defaultAbi(arch: Arch, target_os: Os) Abi {
260 switch (arch) {
261 .wasm32, .wasm64 => return .musl,
262 else => {},
263 }
264 switch (target_os) {
265 .freestanding,
266 .ananas,
267 .cloudabi,
268 .dragonfly,
269 .lv2,
270 .solaris,
271 .haiku,
272 .minix,
273 .rtems,
274 .nacl,
275 .cnk,
276 .aix,
277 .cuda,
278 .nvcl,
279 .amdhsa,
280 .ps4,
281 .elfiamcu,
282 .mesa3d,
283 .contiki,
284 .amdpal,
285 .zen,
286 .hermit,
287 => return .eabi,
288 .openbsd,
289 .macosx,
290 .freebsd,
291 .ios,
292 .tvos,
293 .watchos,
294 .fuchsia,
295 .kfreebsd,
296 .netbsd,
297 .hurd,
298 => return .gnu,
299 .windows,
300 .uefi,
301 => return .msvc,
302 .linux,
303 .wasi,
304 .emscripten,
305 => return .musl,
306 }
307 }
308
309 pub const ParseArchSubError = error{
310 UnknownArchitecture,
311 UnknownSubArchitecture,
312 };
313
314 pub fn parseArchSub(text: []const u8) ParseArchSubError!Arch {
315 const info = @typeInfo(Arch);
316 inline for (info.Union.fields) |field| {
317 if (mem.eql(u8, text, field.name)) {
318 if (field.field_type == void) {
319 return (Arch)(@field(Arch, field.name));
320 } else {
321 const sub_info = @typeInfo(field.field_type);
322 inline for (sub_info.Enum.fields) |sub_field| {
323 const combined = field.name ++ sub_field.name;
324 if (mem.eql(u8, text, combined)) {
325 return @unionInit(Arch, field.name, @field(field.field_type, sub_field.name));
326 }
327 }
328 return error.UnknownSubArchitecture;
329 }
330 }
331 }
332 return error.UnknownArchitecture;
333 }
334
335 pub fn parseOs(text: []const u8) !Os {
336 const info = @typeInfo(Os);
337 inline for (info.Enum.fields) |field| {
338 if (mem.eql(u8, text, field.name)) {
339 return @field(Os, field.name);
340 }
341 }
342 return error.UnknownOperatingSystem;
343 }
344
345 pub fn parseAbi(text: []const u8) !Abi {
346 const info = @typeInfo(Abi);
347 inline for (info.Enum.fields) |field| {
348 if (mem.eql(u8, text, field.name)) {
349 return @field(Abi, field.name);
350 }
351 }
352 return error.UnknownApplicationBinaryInterface;
353 }
354
355 fn archSubArchName(arch: Arch) []const u8 {
356 return switch (arch) {
357 .arm => |sub| @tagName(sub),
358 .armeb => |sub| @tagName(sub),
359 .thumb => |sub| @tagName(sub),
360 .thumbeb => |sub| @tagName(sub),
361 .aarch64 => |sub| @tagName(sub),
362 .aarch64_be => |sub| @tagName(sub),
363 .kalimba => |sub| @tagName(sub),
364 else => "",
365 };
366 }
367
368 pub fn subArchName(self: Target) []const u8 {
369 switch (self) {
370 .Native => return archSubArchName(builtin.arch),
371 .Cross => |cross| return archSubArchName(cross.arch),
372 }
373 }
374
375 pub fn oFileExt(self: Target) []const u8 {
376 return switch (self.getAbi()) {
377 .msvc => ".obj",
378 else => ".o",
379 };
380 }
381
382 pub fn exeFileExt(self: Target) []const u8 {
383 if (self.isWindows()) {
384 return ".exe";
385 } else if (self.isUefi()) {
386 return ".efi";
387 } else if (self.isWasm()) {
388 return ".wasm";
389 } else {
390 return "";
391 }
392 }
393
394 pub fn staticLibSuffix(self: Target) []const u8 {
395 if (self.isWasm()) {
396 return ".wasm";
397 }
398 switch (self.getAbi()) {
399 .msvc => return ".lib",
400 else => return ".a",
401 }
402 }
403
404 pub fn dynamicLibSuffix(self: Target) []const u8 {
405 if (self.isDarwin()) {
406 return ".dylib";
407 }
408 switch (self.getOs()) {
409 .windows => return ".dll",
410 else => return ".so",
411 }
412 }
413
414 pub fn libPrefix(self: Target) []const u8 {
415 if (self.isWasm()) {
416 return "";
417 }
418 switch (self.getAbi()) {
419 .msvc => return "",
420 else => return "lib",
421 }
422 }
423
424 pub fn getOs(self: Target) Os {
425 return switch (self) {
426 .Native => builtin.os,
427 .Cross => |t| t.os,
428 };
429 }
430
431 pub fn getArch(self: Target) Arch {
432 switch (self) {
433 .Native => return builtin.arch,
434 .Cross => |t| return t.arch,
435 }
436 }
437
438 pub fn getAbi(self: Target) Abi {
439 switch (self) {
440 .Native => return builtin.abi,
441 .Cross => |t| return t.abi,
442 }
443 }
444
445 pub fn isMinGW(self: Target) bool {
446 return self.isWindows() and self.isGnu();
447 }
448
449 pub fn isGnu(self: Target) bool {
450 return switch (self.getAbi()) {
451 .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => true,
452 else => false,
453 };
454 }
455
456 pub fn isDarwin(self: Target) bool {
457 return switch (self.getOs()) {
458 .ios, .macosx, .watchos, .tvos => true,
459 else => false,
460 };
461 }
462
463 pub fn isWindows(self: Target) bool {
464 return switch (self.getOs()) {
465 .windows => true,
466 else => false,
467 };
468 }
469
470 pub fn isLinux(self: Target) bool {
471 return switch (self.getOs()) {
472 .linux => true,
473 else => false,
474 };
475 }
476
477 pub fn isUefi(self: Target) bool {
478 return switch (self.getOs()) {
479 .uefi => true,
480 else => false,
481 };
482 }
483
484 pub fn isWasm(self: Target) bool {
485 return switch (self.getArch()) {
486 .wasm32, .wasm64 => true,
487 else => false,
488 };
489 }
490
491 pub fn isFreeBSD(self: Target) bool {
492 return switch (self.getOs()) {
493 .freebsd => true,
494 else => false,
495 };
496 }
497
498 pub fn isNetBSD(self: Target) bool {
499 return switch (self.getOs()) {
500 .netbsd => true,
501 else => false,
502 };
503 }
504
505 pub fn wantSharedLibSymLinks(self: Target) bool {
506 return !self.isWindows();
507 }
508
509 pub fn osRequiresLibC(self: Target) bool {
510 return self.isDarwin() or self.isFreeBSD() or self.isNetBSD();
511 }
512
513 pub fn getArchPtrBitWidth(self: Target) u32 {
514 switch (self.getArch()) {
515 .avr,
516 .msp430,
517 => return 16,
518
519 .arc,
520 .arm,
521 .armeb,
522 .hexagon,
523 .le32,
524 .mips,
525 .mipsel,
526 .powerpc,
527 .r600,
528 .riscv32,
529 .sparc,
530 .sparcel,
531 .tce,
532 .tcele,
533 .thumb,
534 .thumbeb,
535 .i386,
536 .xcore,
537 .nvptx,
538 .amdil,
539 .hsail,
540 .spir,
541 .kalimba,
542 .shave,
543 .lanai,
544 .wasm32,
545 .renderscript32,
546 .aarch64_32,
547 => return 32,
548
549 .aarch64,
550 .aarch64_be,
551 .mips64,
552 .mips64el,
553 .powerpc64,
554 .powerpc64le,
555 .riscv64,
556 .x86_64,
557 .nvptx64,
558 .le64,
559 .amdil64,
560 .hsail64,
561 .spir64,
562 .wasm64,
563 .renderscript64,
564 .amdgcn,
565 .bpfel,
566 .bpfeb,
567 .sparcv9,
568 .s390x,
569 => return 64,
570 }
571 }
572
573 pub const Executor = union(enum) {
574 native,
575 qemu: []const u8,
576 wine: []const u8,
577 unavailable,
578 };
579
580 pub fn getExternalExecutor(self: Target) Executor {
581 if (@TagType(Target)(self) == .Native) return .native;
582
583 // If the target OS matches the host OS, we can use QEMU to emulate a foreign architecture.
584 if (self.getOs() == builtin.os) {
585 return switch (self.getArch()) {
586 .aarch64 => Executor{ .qemu = "qemu-aarch64" },
587 .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" },
588 .arm => Executor{ .qemu = "qemu-arm" },
589 .armeb => Executor{ .qemu = "qemu-armeb" },
590 .i386 => Executor{ .qemu = "qemu-i386" },
591 .mips => Executor{ .qemu = "qemu-mips" },
592 .mipsel => Executor{ .qemu = "qemu-mipsel" },
593 .mips64 => Executor{ .qemu = "qemu-mips64" },
594 .mips64el => Executor{ .qemu = "qemu-mips64el" },
595 .powerpc => Executor{ .qemu = "qemu-ppc" },
596 .powerpc64 => Executor{ .qemu = "qemu-ppc64" },
597 .powerpc64le => Executor{ .qemu = "qemu-ppc64le" },
598 .riscv32 => Executor{ .qemu = "qemu-riscv32" },
599 .riscv64 => Executor{ .qemu = "qemu-riscv64" },
600 .s390x => Executor{ .qemu = "qemu-s390x" },
601 .sparc => Executor{ .qemu = "qemu-sparc" },
602 .x86_64 => Executor{ .qemu = "qemu-x86_64" },
603 else => return .unavailable,
604 };
605 }
606
607 if (self.isWindows()) {
608 switch (self.getArchPtrBitWidth()) {
609 32 => return Executor{ .wine = "wine" },
610 64 => return Executor{ .wine = "wine64" },
611 else => return .unavailable,
612 }
613 }
614
615 return .unavailable;
616 }
617};
lib/std/thread.zig+5-5
......@@ -9,7 +9,7 @@ const assert = std.debug.assert;
99pub const Thread = struct {
1010 data: Data,
1111
12 pub const use_pthreads = !windows.is_the_target and builtin.link_libc;
12 pub const use_pthreads = builtin.os != .windows and builtin.link_libc;
1313
1414 /// Represents a kernel thread handle.
1515 /// May be an integer or a pointer depending on the platform.
......@@ -309,7 +309,7 @@ pub const Thread = struct {
309309 os.EINVAL => unreachable,
310310 else => return os.unexpectedErrno(@intCast(usize, err)),
311311 }
312 } else if (os.linux.is_the_target) {
312 } else if (builtin.os == .linux) {
313313 var flags: u32 = os.CLONE_VM | os.CLONE_FS | os.CLONE_FILES | os.CLONE_SIGHAND |
314314 os.CLONE_THREAD | os.CLONE_SYSVSEM | os.CLONE_PARENT_SETTID | os.CLONE_CHILD_CLEARTID |
315315 os.CLONE_DETACHED;
......@@ -342,18 +342,18 @@ pub const Thread = struct {
342342 };
343343
344344 pub fn cpuCount() CpuCountError!usize {
345 if (os.linux.is_the_target) {
345 if (builtin.os == .linux) {
346346 const cpu_set = try os.sched_getaffinity(0);
347347 return usize(os.CPU_COUNT(cpu_set)); // TODO should not need this usize cast
348348 }
349 if (os.windows.is_the_target) {
349 if (builtin.os == .windows) {
350350 var system_info: windows.SYSTEM_INFO = undefined;
351351 windows.kernel32.GetSystemInfo(&system_info);
352352 return @intCast(usize, system_info.dwNumberOfProcessors);
353353 }
354354 var count: c_int = undefined;
355355 var count_len: usize = @sizeOf(c_int);
356 const name = if (os.darwin.is_the_target) c"hw.logicalcpu" else c"hw.ncpu";
356 const name = if (comptime std.Target.current.isDarwin()) c"hw.logicalcpu" else c"hw.ncpu";
357357 os.sysctlbynameC(name, &count, &count_len, null, 0) catch |err| switch (err) {
358358 error.NameTooLong => unreachable,
359359 else => |e| return e,
lib/std/time.zig+10-10
......@@ -9,7 +9,7 @@ pub const epoch = @import("time/epoch.zig");
99
1010/// Spurious wakeups are possible and no precision of timing is guaranteed.
1111pub fn sleep(nanoseconds: u64) void {
12 if (os.windows.is_the_target) {
12 if (builtin.os == .windows) {
1313 const ns_per_ms = ns_per_s / ms_per_s;
1414 const big_ms_from_ns = nanoseconds / ns_per_ms;
1515 const ms = math.cast(os.windows.DWORD, big_ms_from_ns) catch math.maxInt(os.windows.DWORD);
......@@ -30,7 +30,7 @@ pub fn timestamp() u64 {
3030/// Get the posix timestamp, UTC, in milliseconds
3131/// TODO audit this function. is it possible to return an error?
3232pub fn milliTimestamp() u64 {
33 if (os.windows.is_the_target) {
33 if (builtin.os == .windows) {
3434 //FileTime has a granularity of 100 nanoseconds
3535 // and uses the NTFS/Windows epoch
3636 var ft: os.windows.FILETIME = undefined;
......@@ -41,7 +41,7 @@ pub fn milliTimestamp() u64 {
4141 const ft64 = (u64(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
4242 return @divFloor(ft64, hns_per_ms) - -epoch_adj;
4343 }
44 if (os.wasi.is_the_target and !builtin.link_libc) {
44 if (builtin.os == .wasi and !builtin.link_libc) {
4545 var ns: os.wasi.timestamp_t = undefined;
4646
4747 // TODO: Verify that precision is ignored
......@@ -51,7 +51,7 @@ pub fn milliTimestamp() u64 {
5151 const ns_per_ms = 1000;
5252 return @divFloor(ns, ns_per_ms);
5353 }
54 if (os.darwin.is_the_target) {
54 if (comptime std.Target.current.isDarwin()) {
5555 var tv: os.darwin.timeval = undefined;
5656 var err = os.darwin.gettimeofday(&tv, null);
5757 assert(err == 0);
......@@ -126,11 +126,11 @@ pub const Timer = struct {
126126 pub fn start() Error!Timer {
127127 var self: Timer = undefined;
128128
129 if (os.windows.is_the_target) {
129 if (builtin.os == .windows) {
130130 self.frequency = os.windows.QueryPerformanceFrequency();
131131 self.resolution = @divFloor(ns_per_s, self.frequency);
132132 self.start_time = os.windows.QueryPerformanceCounter();
133 } else if (os.darwin.is_the_target) {
133 } else if (comptime std.Target.current.isDarwin()) {
134134 os.darwin.mach_timebase_info(&self.frequency);
135135 self.resolution = @divFloor(self.frequency.numer, self.frequency.denom);
136136 self.start_time = os.darwin.mach_absolute_time();
......@@ -154,10 +154,10 @@ pub const Timer = struct {
154154 /// Reads the timer value since start or the last reset in nanoseconds
155155 pub fn read(self: *Timer) u64 {
156156 var clock = clockNative() - self.start_time;
157 if (os.windows.is_the_target) {
157 if (builtin.os == .windows) {
158158 return @divFloor(clock * ns_per_s, self.frequency);
159159 }
160 if (os.darwin.is_the_target) {
160 if (comptime std.Target.current.isDarwin()) {
161161 return @divFloor(clock * self.frequency.numer, self.frequency.denom);
162162 }
163163 return clock;
......@@ -177,10 +177,10 @@ pub const Timer = struct {
177177 }
178178
179179 fn clockNative() u64 {
180 if (os.windows.is_the_target) {
180 if (builtin.os == .windows) {
181181 return os.windows.QueryPerformanceCounter();
182182 }
183 if (os.darwin.is_the_target) {
183 if (comptime std.Target.current.isDarwin()) {
184184 return os.darwin.mach_absolute_time();
185185 }
186186 var ts: os.timespec = undefined;
src-self-hosted/target.zig+2
......@@ -3,6 +3,8 @@ const builtin = @import("builtin");
33const llvm = @import("llvm.zig");
44const CInt = @import("c_int.zig").CInt;
55
6// TODO delete this file and use std.Target
7
68pub const FloatAbi = enum {
79 Hard,
810 Soft,
src/all_types.hpp-3
......@@ -1930,7 +1930,6 @@ struct CodeGen {
19301930 ZigList<ZigType *> type_resolve_stack;
19311931
19321932 ZigPackage *std_package;
1933 ZigPackage *panic_package;
19341933 ZigPackage *test_runner_package;
19351934 ZigPackage *compile_var_package;
19361935 ZigType *compile_var_import;
......@@ -2006,7 +2005,6 @@ struct CodeGen {
20062005 ZigFn *cur_fn;
20072006 ZigFn *main_fn;
20082007 ZigFn *panic_fn;
2009 TldFn *panic_tld_fn;
20102008
20112009 ZigFn *largest_frame_fn;
20122010
......@@ -2030,7 +2028,6 @@ struct CodeGen {
20302028 bool have_winmain;
20312029 bool have_winmain_crt_startup;
20322030 bool have_dllmain_crt_startup;
2033 bool have_pub_panic;
20342031 bool have_err_ret_tracing;
20352032 bool c_want_stdint;
20362033 bool c_want_stdbool;
src/analyze.cpp+62-27
......@@ -3232,21 +3232,6 @@ static bool scope_is_root_decls(Scope *scope) {
32323232 zig_unreachable();
32333233}
32343234
3235void typecheck_panic_fn(CodeGen *g, TldFn *tld_fn, ZigFn *panic_fn) {
3236 ConstExprValue *panic_fn_type_val = get_builtin_value(g, "PanicFn");
3237 assert(panic_fn_type_val != nullptr);
3238 assert(panic_fn_type_val->type->id == ZigTypeIdMetaType);
3239 ZigType *panic_fn_type = panic_fn_type_val->data.x_type;
3240
3241 AstNode *fake_decl = allocate<AstNode>(1);
3242 *fake_decl = *panic_fn->proto_node;
3243 fake_decl->type = NodeTypeSymbol;
3244 fake_decl->data.symbol_expr.symbol = tld_fn->base.name;
3245
3246 // call this for the side effects of casting to panic_fn_type
3247 analyze_const_value(g, tld_fn->base.parent_scope, fake_decl, panic_fn_type, nullptr, UndefBad);
3248}
3249
32503235ZigType *get_test_fn_type(CodeGen *g) {
32513236 if (g->test_fn_type)
32523237 return g->test_fn_type;
......@@ -3356,16 +3341,9 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
33563341 fn_table_entry->inferred_async_node = fn_table_entry->proto_node;
33573342 }
33583343
3359 if (scope_is_root_decls(tld_fn->base.parent_scope) &&
3360 (import == g->root_import || import->data.structure.root_struct->package == g->panic_package))
3361 {
3344 if (scope_is_root_decls(tld_fn->base.parent_scope) && import == g->root_import) {
33623345 if (g->have_pub_main && buf_eql_str(tld_fn->base.name, "main")) {
33633346 g->main_fn = fn_table_entry;
3364 } else if ((import->data.structure.root_struct->package == g->panic_package || g->have_pub_panic) &&
3365 buf_eql_str(tld_fn->base.name, "panic"))
3366 {
3367 g->panic_fn = fn_table_entry;
3368 g->panic_tld_fn = tld_fn;
33693347 }
33703348 }
33713349 } else if (source_node->type == NodeTypeTestDecl) {
......@@ -4710,8 +4688,8 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
47104688 ast_print(stderr, root_node, 0);
47114689 }
47124690
4713 if (source_kind == SourceKindRoot || package == g->panic_package) {
4714 // Look for panic and main
4691 if (source_kind == SourceKindRoot) {
4692 // Look for main
47154693 for (size_t decl_i = 0; decl_i < root_node->data.container_decl.decls.length; decl_i += 1) {
47164694 AstNode *top_level_decl = root_node->data.container_decl.decls.at(decl_i);
47174695
......@@ -4724,8 +4702,6 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
47244702 if (is_pub) {
47254703 if (buf_eql_str(proto_name, "main")) {
47264704 g->have_pub_main = true;
4727 } else if (buf_eql_str(proto_name, "panic")) {
4728 g->have_pub_panic = true;
47294705 }
47304706 }
47314707 }
......@@ -8932,3 +8908,62 @@ IrInstruction *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node,
89328908 return &alloca_gen->base;
89338909}
89348910
8911Error analyze_import(CodeGen *g, ZigType *source_import, Buf *import_target_str,
8912 ZigType **out_import, Buf **out_import_target_path, Buf *out_full_path)
8913{
8914 Error err;
8915
8916 Buf *search_dir;
8917 ZigPackage *cur_scope_pkg = source_import->data.structure.root_struct->package;
8918 assert(cur_scope_pkg);
8919 ZigPackage *target_package;
8920 auto package_entry = cur_scope_pkg->package_table.maybe_get(import_target_str);
8921 SourceKind source_kind;
8922 if (package_entry) {
8923 target_package = package_entry->value;
8924 *out_import_target_path = &target_package->root_src_path;
8925 search_dir = &target_package->root_src_dir;
8926 source_kind = SourceKindPkgMain;
8927 } else {
8928 // try it as a filename
8929 target_package = cur_scope_pkg;
8930 *out_import_target_path = import_target_str;
8931
8932 // search relative to importing file
8933 search_dir = buf_alloc();
8934 os_path_dirname(source_import->data.structure.root_struct->path, search_dir);
8935
8936 source_kind = SourceKindNonRoot;
8937 }
8938
8939 buf_resize(out_full_path, 0);
8940 os_path_join(search_dir, *out_import_target_path, out_full_path);
8941
8942 Buf *import_code = buf_alloc();
8943 Buf *resolved_path = buf_alloc();
8944
8945 Buf *resolve_paths[] = { out_full_path, };
8946 *resolved_path = os_path_resolve(resolve_paths, 1);
8947
8948 auto import_entry = g->import_table.maybe_get(resolved_path);
8949 if (import_entry) {
8950 *out_import = import_entry->value;
8951 return ErrorNone;
8952 }
8953
8954 if (source_kind == SourceKindNonRoot) {
8955 Buf *pkg_root_src_dir = &cur_scope_pkg->root_src_dir;
8956 Buf resolved_root_src_dir = os_path_resolve(&pkg_root_src_dir, 1);
8957 if (!buf_starts_with_buf(resolved_path, &resolved_root_src_dir)) {
8958 return ErrorImportOutsidePkgPath;
8959 }
8960 }
8961
8962 if ((err = file_fetch(g, resolved_path, import_code))) {
8963 return err;
8964 }
8965
8966 *out_import = add_source_file(g, target_package, resolved_path, import_code, source_kind);
8967 return ErrorNone;
8968}
8969
src/analyze.hpp+2
......@@ -262,5 +262,7 @@ void add_async_error_notes(CodeGen *g, ErrorMsg *msg, ZigFn *fn);
262262
263263IrInstruction *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn,
264264 ZigType *var_type, const char *name_hint);
265Error analyze_import(CodeGen *codegen, ZigType *source_import, Buf *import_target_str,
266 ZigType **out_import, Buf **out_import_target_path, Buf *out_full_path);
265267
266268#endif
src/codegen.cpp+67-357
......@@ -8125,55 +8125,37 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
81258125 g->have_err_ret_tracing = detect_err_ret_tracing(g);
81268126
81278127 Buf *contents = buf_alloc();
8128
8129 // NOTE: when editing this file, you may need to make modifications to the
8130 // cache input parameters in define_builtin_compile_vars
8131
8132 // Modifications to this struct must be coordinated with code that does anything with
8133 // g->stack_trace_type. There are hard-coded references to the field indexes.
8134 buf_append_str(contents,
8135 "pub const StackTrace = struct {\n"
8136 " index: usize,\n"
8137 " instruction_addresses: []usize,\n"
8138 "};\n\n");
8139
8140 buf_append_str(contents, "pub const PanicFn = fn([]const u8, ?*StackTrace) noreturn;\n\n");
8128 buf_appendf(contents, "usingnamespace @import(\"std\").builtin;\n\n");
81418129
81428130 const char *cur_os = nullptr;
81438131 {
8144 buf_appendf(contents, "pub const Os = enum {\n");
81458132 uint32_t field_count = (uint32_t)target_os_count();
81468133 for (uint32_t i = 0; i < field_count; i += 1) {
81478134 Os os_type = target_os_enum(i);
81488135 const char *name = target_os_name(os_type);
8149 buf_appendf(contents, " %s,\n", name);
81508136
81518137 if (os_type == g->zig_target->os) {
81528138 g->target_os_index = i;
81538139 cur_os = name;
81548140 }
81558141 }
8156 buf_appendf(contents, "};\n\n");
81578142 }
81588143 assert(cur_os != nullptr);
81598144
81608145 const char *cur_arch = nullptr;
81618146 {
8162 buf_appendf(contents, "pub const Arch = union(enum) {\n");
81638147 uint32_t field_count = (uint32_t)target_arch_count();
81648148 for (uint32_t arch_i = 0; arch_i < field_count; arch_i += 1) {
81658149 ZigLLVM_ArchType arch = target_arch_enum(arch_i);
81668150 const char *arch_name = target_arch_name(arch);
81678151 SubArchList sub_arch_list = target_subarch_list(arch);
81688152 if (sub_arch_list == SubArchListNone) {
8169 buf_appendf(contents, " %s,\n", arch_name);
81708153 if (arch == g->zig_target->arch) {
81718154 g->target_arch_index = arch_i;
81728155 cur_arch = buf_ptr(buf_sprintf("Arch.%s", arch_name));
81738156 }
81748157 } else {
81758158 const char *sub_arch_list_name = target_subarch_list_name(sub_arch_list);
8176 buf_appendf(contents, " %s: %s,\n", arch_name, sub_arch_list_name);
81778159 if (arch == g->zig_target->arch) {
81788160 size_t sub_count = target_subarch_count(sub_arch_list);
81798161 for (size_t sub_i = 0; sub_i < sub_count; sub_i += 1) {
......@@ -8187,50 +8169,30 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
81878169 }
81888170 }
81898171 }
8190
8191 uint32_t list_count = target_subarch_list_count();
8192 // start at index 1 to skip None
8193 for (uint32_t list_i = 1; list_i < list_count; list_i += 1) {
8194 SubArchList sub_arch_list = target_subarch_list_enum(list_i);
8195 const char *subarch_list_name = target_subarch_list_name(sub_arch_list);
8196 buf_appendf(contents, " pub const %s = enum {\n", subarch_list_name);
8197 size_t sub_count = target_subarch_count(sub_arch_list);
8198 for (size_t sub_i = 0; sub_i < sub_count; sub_i += 1) {
8199 ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i);
8200 buf_appendf(contents, " %s,\n", target_subarch_name(sub));
8201 }
8202 buf_appendf(contents, " };\n");
8203 }
8204 buf_appendf(contents, "};\n\n");
82058172 }
82068173 assert(cur_arch != nullptr);
82078174
82088175 const char *cur_abi = nullptr;
82098176 {
8210 buf_appendf(contents, "pub const Abi = enum {\n");
82118177 uint32_t field_count = (uint32_t)target_abi_count();
82128178 for (uint32_t i = 0; i < field_count; i += 1) {
82138179 ZigLLVM_EnvironmentType abi = target_abi_enum(i);
82148180 const char *name = target_abi_name(abi);
8215 buf_appendf(contents, " %s,\n", name);
82168181
82178182 if (abi == g->zig_target->abi) {
82188183 g->target_abi_index = i;
82198184 cur_abi = name;
82208185 }
82218186 }
8222 buf_appendf(contents, "};\n\n");
82238187 }
82248188 assert(cur_abi != nullptr);
82258189
82268190 const char *cur_obj_fmt = nullptr;
82278191 {
8228 buf_appendf(contents, "pub const ObjectFormat = enum {\n");
82298192 uint32_t field_count = (uint32_t)target_oformat_count();
82308193 for (uint32_t i = 0; i < field_count; i += 1) {
82318194 ZigLLVM_ObjectFormatType oformat = target_oformat_enum(i);
82328195 const char *name = target_oformat_name(oformat);
8233 buf_appendf(contents, " %s,\n", name);
82348196
82358197 ZigLLVM_ObjectFormatType target_oformat = target_object_format(g->zig_target);
82368198 if (oformat == target_oformat) {
......@@ -8239,311 +8201,39 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
82398201 }
82408202 }
82418203
8242 buf_appendf(contents, "};\n\n");
82438204 }
82448205 assert(cur_obj_fmt != nullptr);
82458206
8246 {
8247 buf_appendf(contents, "pub const GlobalLinkage = enum {\n");
8248 uint32_t field_count = array_length(global_linkage_values);
8249 for (uint32_t i = 0; i < field_count; i += 1) {
8250 const GlobalLinkageValue *value = &global_linkage_values[i];
8251 buf_appendf(contents, " %s,\n", value->name);
8252 }
8253 buf_appendf(contents, "};\n\n");
8254 }
8255 {
8256 buf_appendf(contents,
8257 "pub const AtomicOrder = enum {\n"
8258 " Unordered,\n"
8259 " Monotonic,\n"
8260 " Acquire,\n"
8261 " Release,\n"
8262 " AcqRel,\n"
8263 " SeqCst,\n"
8264 "};\n\n");
8265 }
8266 {
8267 buf_appendf(contents,
8268 "pub const AtomicRmwOp = enum {\n"
8269 " Xchg,\n"
8270 " Add,\n"
8271 " Sub,\n"
8272 " And,\n"
8273 " Nand,\n"
8274 " Or,\n"
8275 " Xor,\n"
8276 " Max,\n"
8277 " Min,\n"
8278 "};\n\n");
8279 }
8280 {
8281 buf_appendf(contents,
8282 "pub const Mode = enum {\n"
8283 " Debug,\n"
8284 " ReleaseSafe,\n"
8285 " ReleaseFast,\n"
8286 " ReleaseSmall,\n"
8287 "};\n\n");
8288 }
8289 {
8290 buf_appendf(contents, "pub const TypeId = enum {\n");
8291 size_t field_count = type_id_len();
8292 for (size_t i = 0; i < field_count; i += 1) {
8293 const ZigTypeId id = type_id_at_index(i);
8294 buf_appendf(contents, " %s,\n", type_id_name(id));
8295 }
8296 buf_appendf(contents, "};\n\n");
8297 }
8298 {
8299 buf_appendf(contents,
8300 "pub const TypeInfo = union(TypeId) {\n"
8301 " Type: void,\n"
8302 " Void: void,\n"
8303 " Bool: void,\n"
8304 " NoReturn: void,\n"
8305 " Int: Int,\n"
8306 " Float: Float,\n"
8307 " Pointer: Pointer,\n"
8308 " Array: Array,\n"
8309 " Struct: Struct,\n"
8310 " ComptimeFloat: void,\n"
8311 " ComptimeInt: void,\n"
8312 " Undefined: void,\n"
8313 " Null: void,\n"
8314 " Optional: Optional,\n"
8315 " ErrorUnion: ErrorUnion,\n"
8316 " ErrorSet: ErrorSet,\n"
8317 " Enum: Enum,\n"
8318 " Union: Union,\n"
8319 " Fn: Fn,\n"
8320 " BoundFn: Fn,\n"
8321 " ArgTuple: void,\n"
8322 " Opaque: void,\n"
8323 " Frame: void,\n"
8324 " AnyFrame: AnyFrame,\n"
8325 " Vector: Vector,\n"
8326 " EnumLiteral: void,\n"
8327 "\n\n"
8328 " pub const Int = struct {\n"
8329 " is_signed: bool,\n"
8330 " bits: comptime_int,\n"
8331 " };\n"
8332 "\n"
8333 " pub const Float = struct {\n"
8334 " bits: comptime_int,\n"
8335 " };\n"
8336 "\n"
8337 " pub const Pointer = struct {\n"
8338 " size: Size,\n"
8339 " is_const: bool,\n"
8340 " is_volatile: bool,\n"
8341 " alignment: comptime_int,\n"
8342 " child: type,\n"
8343 " is_allowzero: bool,\n"
8344 "\n"
8345 " pub const Size = enum {\n"
8346 " One,\n"
8347 " Many,\n"
8348 " Slice,\n"
8349 " C,\n"
8350 " };\n"
8351 " };\n"
8352 "\n"
8353 " pub const Array = struct {\n"
8354 " len: comptime_int,\n"
8355 " child: type,\n"
8356 " };\n"
8357 "\n"
8358 " pub const ContainerLayout = enum {\n"
8359 " Auto,\n"
8360 " Extern,\n"
8361 " Packed,\n"
8362 " };\n"
8363 "\n"
8364 " pub const StructField = struct {\n"
8365 " name: []const u8,\n"
8366 " offset: ?comptime_int,\n"
8367 " field_type: type,\n"
8368 " };\n"
8369 "\n"
8370 " pub const Struct = struct {\n"
8371 " layout: ContainerLayout,\n"
8372 " fields: []StructField,\n"
8373 " decls: []Declaration,\n"
8374 " };\n"
8375 "\n"
8376 " pub const Optional = struct {\n"
8377 " child: type,\n"
8378 " };\n"
8379 "\n"
8380 " pub const ErrorUnion = struct {\n"
8381 " error_set: type,\n"
8382 " payload: type,\n"
8383 " };\n"
8384 "\n"
8385 " pub const Error = struct {\n"
8386 " name: []const u8,\n"
8387 " value: comptime_int,\n"
8388 " };\n"
8389 "\n"
8390 " pub const ErrorSet = ?[]Error;\n"
8391 "\n"
8392 " pub const EnumField = struct {\n"
8393 " name: []const u8,\n"
8394 " value: comptime_int,\n"
8395 " };\n"
8396 "\n"
8397 " pub const Enum = struct {\n"
8398 " layout: ContainerLayout,\n"
8399 " tag_type: type,\n"
8400 " fields: []EnumField,\n"
8401 " decls: []Declaration,\n"
8402 " };\n"
8403 "\n"
8404 " pub const UnionField = struct {\n"
8405 " name: []const u8,\n"
8406 " enum_field: ?EnumField,\n"
8407 " field_type: type,\n"
8408 " };\n"
8409 "\n"
8410 " pub const Union = struct {\n"
8411 " layout: ContainerLayout,\n"
8412 " tag_type: ?type,\n"
8413 " fields: []UnionField,\n"
8414 " decls: []Declaration,\n"
8415 " };\n"
8416 "\n"
8417 " pub const CallingConvention = enum {\n"
8418 " Unspecified,\n"
8419 " C,\n"
8420 " Cold,\n"
8421 " Naked,\n"
8422 " Stdcall,\n"
8423 " Async,\n"
8424 " };\n"
8425 "\n"
8426 " pub const FnArg = struct {\n"
8427 " is_generic: bool,\n"
8428 " is_noalias: bool,\n"
8429 " arg_type: ?type,\n"
8430 " };\n"
8431 "\n"
8432 " pub const Fn = struct {\n"
8433 " calling_convention: CallingConvention,\n"
8434 " is_generic: bool,\n"
8435 " is_var_args: bool,\n"
8436 " return_type: ?type,\n"
8437 " args: []FnArg,\n"
8438 " };\n"
8439 "\n"
8440 " pub const AnyFrame = struct {\n"
8441 " child: ?type,\n"
8442 " };\n"
8443 "\n"
8444 " pub const Vector = struct {\n"
8445 " len: comptime_int,\n"
8446 " child: type,\n"
8447 " };\n"
8448 "\n"
8449 " pub const Declaration = struct {\n"
8450 " name: []const u8,\n"
8451 " is_pub: bool,\n"
8452 " data: Data,\n"
8453 "\n"
8454 " pub const Data = union(enum) {\n"
8455 " Type: type,\n"
8456 " Var: type,\n"
8457 " Fn: FnDecl,\n"
8458 "\n"
8459 " pub const FnDecl = struct {\n"
8460 " fn_type: type,\n"
8461 " inline_type: Inline,\n"
8462 " calling_convention: CallingConvention,\n"
8463 " is_var_args: bool,\n"
8464 " is_extern: bool,\n"
8465 " is_export: bool,\n"
8466 " lib_name: ?[]const u8,\n"
8467 " return_type: type,\n"
8468 " arg_names: [][] const u8,\n"
8469 "\n"
8470 " pub const Inline = enum {\n"
8471 " Auto,\n"
8472 " Always,\n"
8473 " Never,\n"
8474 " };\n"
8475 " };\n"
8476 " };\n"
8477 " };\n"
8478 "};\n\n");
8479 static_assert(ContainerLayoutAuto == 0, "");
8480 static_assert(ContainerLayoutExtern == 1, "");
8481 static_assert(ContainerLayoutPacked == 2, "");
8482
8483 static_assert(CallingConventionUnspecified == 0, "");
8484 static_assert(CallingConventionC == 1, "");
8485 static_assert(CallingConventionCold == 2, "");
8486 static_assert(CallingConventionNaked == 3, "");
8487 static_assert(CallingConventionStdcall == 4, "");
8488 static_assert(CallingConventionAsync == 5, "");
8489
8490 static_assert(FnInlineAuto == 0, "");
8491 static_assert(FnInlineAlways == 1, "");
8492 static_assert(FnInlineNever == 2, "");
8493
8494 static_assert(BuiltinPtrSizeOne == 0, "");
8495 static_assert(BuiltinPtrSizeMany == 1, "");
8496 static_assert(BuiltinPtrSizeSlice == 2, "");
8497 static_assert(BuiltinPtrSizeC == 3, "");
8498 }
8499 {
8500 buf_appendf(contents,
8501 "pub const FloatMode = enum {\n"
8502 " Strict,\n"
8503 " Optimized,\n"
8504 "};\n\n");
8505 assert(FloatModeStrict == 0);
8506 assert(FloatModeOptimized == 1);
8507 }
8508 {
8509 buf_appendf(contents,
8510 "pub const Endian = enum {\n"
8511 " Big,\n"
8512 " Little,\n"
8513 "};\n\n");
8514 //assert(EndianBig == 0);
8515 //assert(EndianLittle == 1);
8516 }
8517 {
8518 buf_appendf(contents,
8519 "pub const Version = struct {\n"
8520 " major: u32,\n"
8521 " minor: u32,\n"
8522 " patch: u32,\n"
8523 "};\n\n");
8524 }
8525 {
8526 buf_appendf(contents,
8527 "pub const SubSystem = enum {\n"
8528 " Console,\n"
8529 " Windows,\n"
8530 " Posix,\n"
8531 " Native,\n"
8532 " EfiApplication,\n"
8533 " EfiBootServiceDriver,\n"
8534 " EfiRom,\n"
8535 " EfiRuntimeDriver,\n"
8536 "};\n\n");
8537
8538 assert(TargetSubsystemConsole == 0);
8539 assert(TargetSubsystemWindows == 1);
8540 assert(TargetSubsystemPosix == 2);
8541 assert(TargetSubsystemNative == 3);
8542 assert(TargetSubsystemEfiApplication == 4);
8543 assert(TargetSubsystemEfiBootServiceDriver == 5);
8544 assert(TargetSubsystemEfiRom == 6);
8545 assert(TargetSubsystemEfiRuntimeDriver == 7);
8546 }
8207 // If any of these asserts trip then you need to either fix the internal compiler enum
8208 // or the corresponding one in std.Target or std.builtin.
8209 static_assert(ContainerLayoutAuto == 0, "");
8210 static_assert(ContainerLayoutExtern == 1, "");
8211 static_assert(ContainerLayoutPacked == 2, "");
8212
8213 static_assert(CallingConventionUnspecified == 0, "");
8214 static_assert(CallingConventionC == 1, "");
8215 static_assert(CallingConventionCold == 2, "");
8216 static_assert(CallingConventionNaked == 3, "");
8217 static_assert(CallingConventionStdcall == 4, "");
8218 static_assert(CallingConventionAsync == 5, "");
8219
8220 static_assert(FnInlineAuto == 0, "");
8221 static_assert(FnInlineAlways == 1, "");
8222 static_assert(FnInlineNever == 2, "");
8223
8224 static_assert(BuiltinPtrSizeOne == 0, "");
8225 static_assert(BuiltinPtrSizeMany == 1, "");
8226 static_assert(BuiltinPtrSizeSlice == 2, "");
8227 static_assert(BuiltinPtrSizeC == 3, "");
8228
8229 static_assert(TargetSubsystemConsole == 0, "");
8230 static_assert(TargetSubsystemWindows == 1, "");
8231 static_assert(TargetSubsystemPosix == 2, "");
8232 static_assert(TargetSubsystemNative == 3, "");
8233 static_assert(TargetSubsystemEfiApplication == 4, "");
8234 static_assert(TargetSubsystemEfiBootServiceDriver == 5, "");
8235 static_assert(TargetSubsystemEfiRom == 6, "");
8236 static_assert(TargetSubsystemEfiRuntimeDriver == 7, "");
85478237 {
85488238 const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little";
85498239 buf_appendf(contents, "pub const endian = %s;\n", endian_str);
......@@ -8573,7 +8263,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
85738263 {
85748264 TargetSubsystem detected_subsystem = detect_subsystem(g);
85758265 if (detected_subsystem != TargetSubsystemAuto) {
8576 buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_to_str(detected_subsystem));
8266 buf_appendf(contents, "pub const explicit_subsystem = SubSystem.%s;\n", subsystem_to_str(detected_subsystem));
85778267 }
85788268 }
85798269
......@@ -8594,10 +8284,6 @@ static ZigPackage *create_test_runner_pkg(CodeGen *g) {
85948284 return codegen_create_package(g, buf_ptr(g->zig_std_special_dir), "test_runner.zig", "std.special");
85958285}
85968286
8597static ZigPackage *create_panic_pkg(CodeGen *g) {
8598 return codegen_create_package(g, buf_ptr(g->zig_std_special_dir), "panic.zig", "std.special");
8599}
8600
86018287static Error define_builtin_compile_vars(CodeGen *g) {
86028288 if (g->std_package == nullptr)
86038289 return ErrorNone;
......@@ -8679,6 +8365,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
86798365 assert(g->root_package);
86808366 assert(g->std_package);
86818367 g->compile_var_package = new_package(buf_ptr(this_dir), builtin_zig_basename, "builtin");
8368 g->compile_var_package->package_table.put(buf_create_from_str("std"), g->std_package);
86828369 g->root_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
86838370 g->std_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
86848371 g->std_package->package_table.put(buf_create_from_str("std"), g->std_package);
......@@ -9377,16 +9064,43 @@ static void gen_root_source(CodeGen *g) {
93779064
93789065 if (!g->is_dummy_so) {
93799066 // Zig has lazy top level definitions. Here we semantically analyze the panic function.
9380 ZigType *import_with_panic;
9381 if (g->have_pub_panic) {
9382 import_with_panic = g->root_import;
9383 } else {
9384 g->panic_package = create_panic_pkg(g);
9385 import_with_panic = add_special_code(g, g->panic_package, "panic.zig");
9067 Buf *import_target_path;
9068 Buf full_path = BUF_INIT;
9069 ZigType *std_import;
9070 if ((err = analyze_import(g, g->root_import, buf_create_from_str("std"), &std_import,
9071 &import_target_path, &full_path)))
9072 {
9073 if (err == ErrorFileNotFound) {
9074 fprintf(stderr, "unable to find '%s'", buf_ptr(import_target_path));
9075 } else {
9076 fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(&full_path), err_str(err));
9077 }
9078 exit(1);
93869079 }
9387 Tld *panic_tld = find_decl(g, &get_container_scope(import_with_panic)->base, buf_create_from_str("panic"));
9080
9081 Tld *builtin_tld = find_decl(g, &get_container_scope(std_import)->base,
9082 buf_create_from_str("builtin"));
9083 assert(builtin_tld != nullptr);
9084 resolve_top_level_decl(g, builtin_tld, nullptr, false);
9085 report_errors_and_maybe_exit(g);
9086 assert(builtin_tld->id == TldIdVar);
9087 TldVar *builtin_tld_var = (TldVar*)builtin_tld;
9088 ConstExprValue *builtin_val = builtin_tld_var->var->const_value;
9089 assert(builtin_val->type->id == ZigTypeIdMetaType);
9090 ZigType *builtin_type = builtin_val->data.x_type;
9091
9092 Tld *panic_tld = find_decl(g, &get_container_scope(builtin_type)->base,
9093 buf_create_from_str("panic"));
93889094 assert(panic_tld != nullptr);
93899095 resolve_top_level_decl(g, panic_tld, nullptr, false);
9096 report_errors_and_maybe_exit(g);
9097 assert(panic_tld->id == TldIdVar);
9098 TldVar *panic_tld_var = (TldVar*)panic_tld;
9099 ConstExprValue *panic_fn_val = panic_tld_var->var->const_value;
9100 assert(panic_fn_val->type->id == ZigTypeIdFn);
9101 assert(panic_fn_val->data.x_ptr.special == ConstPtrSpecialFunction);
9102 g->panic_fn = panic_fn_val->data.x_ptr.data.fn.fn_entry;
9103 assert(g->panic_fn != nullptr);
93909104 }
93919105
93929106
......@@ -9416,10 +9130,6 @@ static void gen_root_source(CodeGen *g) {
94169130 }
94179131 }
94189132
9419 if (!g->is_dummy_so) {
9420 typecheck_panic_fn(g, g->panic_tld_fn, g->panic_fn);
9421 }
9422
94239133 report_errors_and_maybe_exit(g);
94249134
94259135}
src/error.cpp+1
......@@ -57,6 +57,7 @@ const char *err_str(Error err) {
5757 case ErrorNoCCompilerInstalled: return "no C compiler installed";
5858 case ErrorNotLazy: return "not lazy";
5959 case ErrorIsAsync: return "is async";
60 case ErrorImportOutsidePkgPath: return "import of file outside package path";
6061 }
6162 return "(invalid error)";
6263}
src/ir.cpp+6-47
......@@ -19589,57 +19589,18 @@ static IrInstruction *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructio
1958919589 AstNode *source_node = import_instruction->base.source_node;
1959019590 ZigType *import = source_node->owner;
1959119591
19592 ZigType *target_import;
1959219593 Buf *import_target_path;
19593 Buf *search_dir;
19594 assert(import->data.structure.root_struct->package);
19595 ZigPackage *target_package;
19596 auto package_entry = import->data.structure.root_struct->package->package_table.maybe_get(import_target_str);
19597 SourceKind source_kind;
19598 if (package_entry) {
19599 target_package = package_entry->value;
19600 import_target_path = &target_package->root_src_path;
19601 search_dir = &target_package->root_src_dir;
19602 source_kind = SourceKindPkgMain;
19603 } else {
19604 // try it as a filename
19605 target_package = import->data.structure.root_struct->package;
19606 import_target_path = import_target_str;
19607
19608 // search relative to importing file
19609 search_dir = buf_alloc();
19610 os_path_dirname(import->data.structure.root_struct->path, search_dir);
19611
19612 source_kind = SourceKindNonRoot;
19613 }
19614
1961519594 Buf full_path = BUF_INIT;
19616 os_path_join(search_dir, import_target_path, &full_path);
19617
19618 Buf *import_code = buf_alloc();
19619 Buf *resolved_path = buf_alloc();
19620
19621 Buf *resolve_paths[] = { &full_path, };
19622 *resolved_path = os_path_resolve(resolve_paths, 1);
19623
19624 auto import_entry = ira->codegen->import_table.maybe_get(resolved_path);
19625 if (import_entry) {
19626 return ir_const_type(ira, &import_instruction->base, import_entry->value);
19627 }
19628
19629 if (source_kind == SourceKindNonRoot) {
19630 ZigPackage *cur_scope_pkg = scope_package(import_instruction->base.scope);
19631 Buf *pkg_root_src_dir = &cur_scope_pkg->root_src_dir;
19632 Buf resolved_root_src_dir = os_path_resolve(&pkg_root_src_dir, 1);
19633 if (!buf_starts_with_buf(resolved_path, &resolved_root_src_dir)) {
19595 if ((err = analyze_import(ira->codegen, import, import_target_str, &target_import,
19596 &import_target_path, &full_path)))
19597 {
19598 if (err == ErrorImportOutsidePkgPath) {
1963419599 ir_add_error_node(ira, source_node,
1963519600 buf_sprintf("import of file outside package path: '%s'",
1963619601 buf_ptr(import_target_path)));
1963719602 return ira->codegen->invalid_instruction;
19638 }
19639 }
19640
19641 if ((err = file_fetch(ira->codegen, resolved_path, import_code))) {
19642 if (err == ErrorFileNotFound) {
19603 } else if (err == ErrorFileNotFound) {
1964319604 ir_add_error_node(ira, source_node,
1964419605 buf_sprintf("unable to find '%s'", buf_ptr(import_target_path)));
1964519606 return ira->codegen->invalid_instruction;
......@@ -19650,8 +19611,6 @@ static IrInstruction *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructio
1965019611 }
1965119612 }
1965219613
19653 ZigType *target_import = add_source_file(ira->codegen, target_package, resolved_path, import_code, source_kind);
19654
1965519614 return ir_const_type(ira, &import_instruction->base, target_import);
1965619615}
1965719616
src/userland.h+1
......@@ -77,6 +77,7 @@ enum Error {
7777 ErrorNoSpaceLeft,
7878 ErrorNotLazy,
7979 ErrorIsAsync,
80 ErrorImportOutsidePkgPath,
8081};
8182
8283// ABI warning
test/compile_errors.zig+18-13
......@@ -64,7 +64,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6464 \\ _ = @Type(0);
6565 \\}
6666 ,
67 "tmp.zig:2:15: error: expected type 'builtin.TypeInfo', found 'comptime_int'",
67 "tmp.zig:2:15: error: expected type 'std.builtin.TypeInfo', found 'comptime_int'",
6868 );
6969
7070 cases.add(
......@@ -88,7 +88,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
8888 \\ });
8989 \\}
9090 ,
91 "tmp.zig:3:36: error: expected type 'builtin.TypeInfo', found 'builtin.Int'",
91 "tmp.zig:3:36: error: expected type 'std.builtin.TypeInfo', found 'std.builtin.Int'",
9292 );
9393
9494 cases.add(
......@@ -806,7 +806,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
806806 \\pub fn panic() void {}
807807 \\
808808 ,
809 "tmp.zig:3:5: error: expected type 'fn([]const u8, ?*builtin.StackTrace) noreturn', found 'fn() void'",
809 "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn() void'",
810810 );
811811
812812 cases.add(
......@@ -815,8 +815,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
815815 \\ while (true) {}
816816 \\}
817817 ,
818 "tmp.zig:1:5: error: expected type 'fn([]const u8, ?*builtin.StackTrace) noreturn', found 'fn([]const u8,var)var'",
819 "tmp.zig:1:5: note: only one of the functions is generic",
818 "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn([]const u8,var)var'",
819 "note: only one of the functions is generic",
820820 );
821821
822822 cases.add(
......@@ -1473,7 +1473,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
14731473 \\ const field = @typeInfo(Struct).Struct.fields[index];
14741474 \\}
14751475 ,
1476 "tmp.zig:9:51: error: values of type 'builtin.StructField' must be comptime known, but index value is runtime known",
1476 "tmp.zig:9:51: error: values of type 'std.builtin.StructField' must be comptime known, but index value is runtime known",
14771477 );
14781478
14791479 cases.add(
......@@ -3743,13 +3743,19 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
37433743 );
37443744
37453745 cases.add(
3746 "missing function name and param name",
3746 "missing function name",
37473747 \\fn () void {}
3748 \\fn f(i32) void {}
37493748 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
37503749 ,
37513750 "tmp.zig:1:1: error: missing function name",
3752 "tmp.zig:2:6: error: missing parameter name",
3751 );
3752
3753 cases.add(
3754 "missing param name",
3755 \\fn f(i32) void {}
3756 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
3757 ,
3758 "tmp.zig:1:6: error: missing parameter name",
37533759 );
37543760
37553761 cases.add(
......@@ -3782,7 +3788,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
37823788 \\export fn entry() usize { return @sizeOf(@typeOf(func)); }
37833789 ,
37843790 "tmp.zig:2:1: error: redefinition of 'func'",
3785 "tmp.zig:1:11: error: use of undeclared identifier 'bogus'",
37863791 );
37873792
37883793 cases.add(
......@@ -5086,7 +5091,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
50865091 \\ const foo = builtin.Arch.x86;
50875092 \\}
50885093 ,
5089 "tmp.zig:3:29: error: container 'builtin.Arch' has no member called 'x86'",
5094 "tmp.zig:3:29: error: container 'std.target.Arch' has no member called 'x86'",
50905095 );
50915096
50925097 cases.add(
......@@ -5731,7 +5736,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
57315736 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, u32(1234), u32(1234))) {}
57325737 \\}
57335738 ,
5734 "tmp.zig:3:50: error: expected type 'builtin.AtomicOrder', found 'u32'",
5739 "tmp.zig:3:50: error: expected type 'std.builtin.AtomicOrder', found 'u32'",
57355740 );
57365741
57375742 cases.add(
......@@ -5741,7 +5746,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
57415746 \\ @export("entry", entry, u32(1234));
57425747 \\}
57435748 ,
5744 "tmp.zig:3:32: error: expected type 'builtin.GlobalLinkage', found 'u32'",
5749 "tmp.zig:3:32: error: expected type 'std.builtin.GlobalLinkage', found 'u32'",
57455750 );
57465751
57475752 cases.add(