authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-10-23 18:43:24-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-10-23 19:09:49-04:00
log17eb24a7e4b2bc5740dc15996acc4736833cb2a0
tree7568873daeb3667768cee4a083a49acac2b53149
parentef62452363de75240b21299e9f80b4851433faaa
signaturelock-open Commit is signed but in an unrecognized format.

move types from builtin to std

* All the data types from `@import("builtin")` are moved to `@import("std").builtin`. The target-related types are moved to `std.Target`. This allows the data types to have methods, such as `std.Target.current.isDarwin()`. * `std.os.windows.subsystem` is moved to `std.Target.current.subsystem`. * Remove the concept of the panic package from the compiler implementation. Instead, `std.builtin.panic` is always the panic function. It checks for `@hasDecl(@import("root"), "panic")`, or else provides a default implementation. This is an important step for multibuilds (#3028). Without this change, the types inside the builtin namespace look like different types, when trying to merge builds with different target settings. With this change, Zig can figure out that, e.g., `std.builtin.Os` (the enum type) from one compilation and `std.builtin.Os` from another compilation are the same type, even if the target OS value differs.

16 files changed, 1212 insertions(+), 949 deletions(-)

lib/std/build.zig+8-427
......@@ -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 },
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/os.zig+16-18
......@@ -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,22 @@ 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 if (builtin.is_test) {
38 _ = darwin;
39 _ = freebsd;
40 _ = linux;
41 _ = netbsd;
42 _ = uefi;
43 _ = wasi;
44 _ = windows;
45 _ = zen;
46
47 _ = @import("os/test.zig");
48 }
49}
50
3951/// When linking libc, this is the C API. Otherwise, it is the OS-specific system interface.
4052pub const system = if (builtin.link_libc) std.c else switch (builtin.os) {
4153 .macosx, .ios, .watchos, .tvos => darwin,
......@@ -1063,7 +1075,6 @@ pub fn unlinkatW(dirfd: fd_t, sub_path_w: [*]const u16, flags: u32) UnlinkatErro
10631075 return error.FileBusy;
10641076 }
10651077
1066
10671078 var attr = w.OBJECT_ATTRIBUTES{
10681079 .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
10691080 .RootDirectory = dirfd,
......@@ -2813,16 +2824,3 @@ pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 {
28132824
28142825 @compileError("TODO implement gethostname for this OS");
28152826}
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/windows.zig-26
......@@ -22,32 +22,6 @@ pub usingnamespace @import("windows/bits.zig");
2222
2323pub const self_process_handle = @intToPtr(HANDLE, maxInt(usize));
2424
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
5125pub const CreateFileError = error{
5226 SharingViolation,
5327 PathAlreadyExists,
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+2
......@@ -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");
lib/std/target.zig created+614
......@@ -0,0 +1,614 @@
1const std = @import("std.zig");
2const builtin = std.builtin;
3
4pub const Target = union(enum) {
5 Native: void,
6 Cross: Cross,
7
8 pub const Os = enum {
9 freestanding,
10 ananas,
11 cloudabi,
12 dragonfly,
13 freebsd,
14 fuchsia,
15 ios,
16 kfreebsd,
17 linux,
18 lv2,
19 macosx,
20 netbsd,
21 openbsd,
22 solaris,
23 windows,
24 haiku,
25 minix,
26 rtems,
27 nacl,
28 cnk,
29 aix,
30 cuda,
31 nvcl,
32 amdhsa,
33 ps4,
34 elfiamcu,
35 tvos,
36 watchos,
37 mesa3d,
38 contiki,
39 amdpal,
40 hermit,
41 hurd,
42 wasi,
43 emscripten,
44 zen,
45 uefi,
46 };
47
48 pub const Arch = union(enum) {
49 arm: Arm32,
50 armeb: Arm32,
51 aarch64: Arm64,
52 aarch64_be: Arm64,
53 aarch64_32: Arm64,
54 arc,
55 avr,
56 bpfel,
57 bpfeb,
58 hexagon,
59 mips,
60 mipsel,
61 mips64,
62 mips64el,
63 msp430,
64 powerpc,
65 powerpc64,
66 powerpc64le,
67 r600,
68 amdgcn,
69 riscv32,
70 riscv64,
71 sparc,
72 sparcv9,
73 sparcel,
74 s390x,
75 tce,
76 tcele,
77 thumb: Arm32,
78 thumbeb: Arm32,
79 i386,
80 x86_64,
81 xcore,
82 nvptx,
83 nvptx64,
84 le32,
85 le64,
86 amdil,
87 amdil64,
88 hsail,
89 hsail64,
90 spir,
91 spir64,
92 kalimba: Kalimba,
93 shave,
94 lanai,
95 wasm32,
96 wasm64,
97 renderscript32,
98 renderscript64,
99
100 pub const Arm32 = enum {
101 v8_5a,
102 v8_4a,
103 v8_3a,
104 v8_2a,
105 v8_1a,
106 v8,
107 v8r,
108 v8m_baseline,
109 v8m_mainline,
110 v8_1m_mainline,
111 v7,
112 v7em,
113 v7m,
114 v7s,
115 v7k,
116 v7ve,
117 v6,
118 v6m,
119 v6k,
120 v6t2,
121 v5,
122 v5te,
123 v4t,
124 };
125 pub const Arm64 = enum {
126 v8_5a,
127 v8_4a,
128 v8_3a,
129 v8_2a,
130 v8_1a,
131 v8,
132 v8r,
133 v8m_baseline,
134 v8m_mainline,
135 };
136 pub const Kalimba = enum {
137 v5,
138 v4,
139 v3,
140 };
141 pub const Mips = enum {
142 r6,
143 };
144 };
145
146 pub const Abi = enum {
147 none,
148 gnu,
149 gnuabin32,
150 gnuabi64,
151 gnueabi,
152 gnueabihf,
153 gnux32,
154 code16,
155 eabi,
156 eabihf,
157 elfv1,
158 elfv2,
159 android,
160 musl,
161 musleabi,
162 musleabihf,
163 msvc,
164 itanium,
165 cygnus,
166 coreclr,
167 simulator,
168 macabi,
169 };
170
171 pub const ObjectFormat = enum {
172 unknown,
173 coff,
174 elf,
175 macho,
176 wasm,
177 };
178
179 pub const SubSystem = enum {
180 Console,
181 Windows,
182 Posix,
183 Native,
184 EfiApplication,
185 EfiBootServiceDriver,
186 EfiRom,
187 EfiRuntimeDriver,
188 };
189
190 pub const Cross = struct {
191 arch: Arch,
192 os: Os,
193 abi: Abi,
194 };
195
196 pub const current = Target{
197 .Cross = Cross{
198 .arch = builtin.arch,
199 .os = builtin.os,
200 .abi = builtin.abi,
201 },
202 };
203
204 pub fn zigTriple(self: Target, allocator: *std.mem.Allocator) ![]u8 {
205 return std.fmt.allocPrint(
206 allocator,
207 "{}{}-{}-{}",
208 @tagName(self.getArch()),
209 Target.archSubArchName(self.getArch()),
210 @tagName(self.getOs()),
211 @tagName(self.getAbi()),
212 );
213 }
214
215 pub fn allocDescription(self: Target, allocator: *std.mem.Allocator) ![]u8 {
216 // TODO is there anything else worthy of the description that is not
217 // already captured in the triple?
218 return self.zigTriple(allocator);
219 }
220
221 pub fn zigTripleNoSubArch(self: Target, allocator: *std.mem.Allocator) ![]u8 {
222 return std.fmt.allocPrint(
223 allocator,
224 "{}-{}-{}",
225 @tagName(self.getArch()),
226 @tagName(self.getOs()),
227 @tagName(self.getAbi()),
228 );
229 }
230
231 pub fn linuxTriple(self: Target, allocator: *std.mem.Allocator) ![]u8 {
232 return std.fmt.allocPrint(
233 allocator,
234 "{}-{}-{}",
235 @tagName(self.getArch()),
236 @tagName(self.getOs()),
237 @tagName(self.getAbi()),
238 );
239 }
240
241 pub fn parse(text: []const u8) !Target {
242 var it = mem.separate(text, "-");
243 const arch_name = it.next() orelse return error.MissingArchitecture;
244 const os_name = it.next() orelse return error.MissingOperatingSystem;
245 const abi_name = it.next();
246
247 var cross = Cross{
248 .arch = try parseArchSub(arch_name),
249 .os = try parseOs(os_name),
250 .abi = undefined,
251 };
252 cross.abi = if (abi_name) |n| try parseAbi(n) else defaultAbi(cross.arch, cross.os);
253 return Target{ .Cross = cross };
254 }
255
256 pub fn defaultAbi(arch: Arch, target_os: Os) Abi {
257 switch (arch) {
258 .wasm32, .wasm64 => return .musl,
259 else => {},
260 }
261 switch (target_os) {
262 .freestanding,
263 .ananas,
264 .cloudabi,
265 .dragonfly,
266 .lv2,
267 .solaris,
268 .haiku,
269 .minix,
270 .rtems,
271 .nacl,
272 .cnk,
273 .aix,
274 .cuda,
275 .nvcl,
276 .amdhsa,
277 .ps4,
278 .elfiamcu,
279 .mesa3d,
280 .contiki,
281 .amdpal,
282 .zen,
283 .hermit,
284 => return .eabi,
285 .openbsd,
286 .macosx,
287 .freebsd,
288 .ios,
289 .tvos,
290 .watchos,
291 .fuchsia,
292 .kfreebsd,
293 .netbsd,
294 .hurd,
295 => return .gnu,
296 .windows,
297 .uefi,
298 => return .msvc,
299 .linux,
300 .wasi,
301 .emscripten,
302 => return .musl,
303 }
304 }
305
306 pub const ParseArchSubError = error{
307 UnknownArchitecture,
308 UnknownSubArchitecture,
309 };
310
311 pub fn parseArchSub(text: []const u8) ParseArchSubError!Arch {
312 const info = @typeInfo(Arch);
313 inline for (info.Union.fields) |field| {
314 if (mem.eql(u8, text, field.name)) {
315 if (field.field_type == void) {
316 return (Arch)(@field(Arch, field.name));
317 } else {
318 const sub_info = @typeInfo(field.field_type);
319 inline for (sub_info.Enum.fields) |sub_field| {
320 const combined = field.name ++ sub_field.name;
321 if (mem.eql(u8, text, combined)) {
322 return @unionInit(Arch, field.name, @field(field.field_type, sub_field.name));
323 }
324 }
325 return error.UnknownSubArchitecture;
326 }
327 }
328 }
329 return error.UnknownArchitecture;
330 }
331
332 pub fn parseOs(text: []const u8) !Os {
333 const info = @typeInfo(Os);
334 inline for (info.Enum.fields) |field| {
335 if (mem.eql(u8, text, field.name)) {
336 return @field(Os, field.name);
337 }
338 }
339 return error.UnknownOperatingSystem;
340 }
341
342 pub fn parseAbi(text: []const u8) !Abi {
343 const info = @typeInfo(Abi);
344 inline for (info.Enum.fields) |field| {
345 if (mem.eql(u8, text, field.name)) {
346 return @field(Abi, field.name);
347 }
348 }
349 return error.UnknownApplicationBinaryInterface;
350 }
351
352 fn archSubArchName(arch: Arch) []const u8 {
353 return switch (arch) {
354 .arm => |sub| @tagName(sub),
355 .armeb => |sub| @tagName(sub),
356 .thumb => |sub| @tagName(sub),
357 .thumbeb => |sub| @tagName(sub),
358 .aarch64 => |sub| @tagName(sub),
359 .aarch64_be => |sub| @tagName(sub),
360 .kalimba => |sub| @tagName(sub),
361 else => "",
362 };
363 }
364
365 pub fn subArchName(self: Target) []const u8 {
366 switch (self) {
367 .Native => return archSubArchName(builtin.arch),
368 .Cross => |cross| return archSubArchName(cross.arch),
369 }
370 }
371
372 pub fn oFileExt(self: Target) []const u8 {
373 return switch (self.getAbi()) {
374 .msvc => ".obj",
375 else => ".o",
376 };
377 }
378
379 pub fn exeFileExt(self: Target) []const u8 {
380 if (self.isWindows()) {
381 return ".exe";
382 } else if (self.isUefi()) {
383 return ".efi";
384 } else if (self.isWasm()) {
385 return ".wasm";
386 } else {
387 return "";
388 }
389 }
390
391 pub fn staticLibSuffix(self: Target) []const u8 {
392 if (self.isWasm()) {
393 return ".wasm";
394 }
395 switch (self.getAbi()) {
396 .msvc => return ".lib",
397 else => return ".a",
398 }
399 }
400
401 pub fn dynamicLibSuffix(self: Target) []const u8 {
402 if (self.isDarwin()) {
403 return ".dylib";
404 }
405 switch (self.getOs()) {
406 .windows => return ".dll",
407 else => return ".so",
408 }
409 }
410
411 pub fn libPrefix(self: Target) []const u8 {
412 if (self.isWasm()) {
413 return "";
414 }
415 switch (self.getAbi()) {
416 .msvc => return "",
417 else => return "lib",
418 }
419 }
420
421 pub fn getOs(self: Target) Os {
422 return switch (self) {
423 .Native => builtin.os,
424 .Cross => |t| t.os,
425 };
426 }
427
428 pub fn getArch(self: Target) Arch {
429 switch (self) {
430 .Native => return builtin.arch,
431 .Cross => |t| return t.arch,
432 }
433 }
434
435 pub fn getAbi(self: Target) Abi {
436 switch (self) {
437 .Native => return builtin.abi,
438 .Cross => |t| return t.abi,
439 }
440 }
441
442 pub fn isMinGW(self: Target) bool {
443 return self.isWindows() and self.isGnu();
444 }
445
446 pub fn isGnu(self: Target) bool {
447 return switch (self.getAbi()) {
448 .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => true,
449 else => false,
450 };
451 }
452
453 pub fn isDarwin(self: Target) bool {
454 return switch (self.getOs()) {
455 .ios, .macosx, .watchos, .tvos => true,
456 else => false,
457 };
458 }
459
460 pub fn isWindows(self: Target) bool {
461 return switch (self.getOs()) {
462 .windows => true,
463 else => false,
464 };
465 }
466
467 pub fn isLinux(self: Target) bool {
468 return switch (self.getOs()) {
469 .linux => true,
470 else => false,
471 };
472 }
473
474 pub fn isUefi(self: Target) bool {
475 return switch (self.getOs()) {
476 .uefi => true,
477 else => false,
478 };
479 }
480
481 pub fn isWasm(self: Target) bool {
482 return switch (self.getArch()) {
483 .wasm32, .wasm64 => true,
484 else => false,
485 };
486 }
487
488 pub fn isFreeBSD(self: Target) bool {
489 return switch (self.getOs()) {
490 .freebsd => true,
491 else => false,
492 };
493 }
494
495 pub fn isNetBSD(self: Target) bool {
496 return switch (self.getOs()) {
497 .netbsd => true,
498 else => false,
499 };
500 }
501
502 pub fn wantSharedLibSymLinks(self: Target) bool {
503 return !self.isWindows();
504 }
505
506 pub fn osRequiresLibC(self: Target) bool {
507 return self.isDarwin() or self.isFreeBSD() or self.isNetBSD();
508 }
509
510 pub fn getArchPtrBitWidth(self: Target) u32 {
511 switch (self.getArch()) {
512 .avr,
513 .msp430,
514 => return 16,
515
516 .arc,
517 .arm,
518 .armeb,
519 .hexagon,
520 .le32,
521 .mips,
522 .mipsel,
523 .powerpc,
524 .r600,
525 .riscv32,
526 .sparc,
527 .sparcel,
528 .tce,
529 .tcele,
530 .thumb,
531 .thumbeb,
532 .i386,
533 .xcore,
534 .nvptx,
535 .amdil,
536 .hsail,
537 .spir,
538 .kalimba,
539 .shave,
540 .lanai,
541 .wasm32,
542 .renderscript32,
543 .aarch64_32,
544 => return 32,
545
546 .aarch64,
547 .aarch64_be,
548 .mips64,
549 .mips64el,
550 .powerpc64,
551 .powerpc64le,
552 .riscv64,
553 .x86_64,
554 .nvptx64,
555 .le64,
556 .amdil64,
557 .hsail64,
558 .spir64,
559 .wasm64,
560 .renderscript64,
561 .amdgcn,
562 .bpfel,
563 .bpfeb,
564 .sparcv9,
565 .s390x,
566 => return 64,
567 }
568 }
569
570 pub const Executor = union(enum) {
571 native,
572 qemu: []const u8,
573 wine: []const u8,
574 unavailable,
575 };
576
577 pub fn getExternalExecutor(self: Target) Executor {
578 if (@TagType(Target)(self) == .Native) return .native;
579
580 // If the target OS matches the host OS, we can use QEMU to emulate a foreign architecture.
581 if (self.getOs() == builtin.os) {
582 return switch (self.getArch()) {
583 .aarch64 => Executor{ .qemu = "qemu-aarch64" },
584 .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" },
585 .arm => Executor{ .qemu = "qemu-arm" },
586 .armeb => Executor{ .qemu = "qemu-armeb" },
587 .i386 => Executor{ .qemu = "qemu-i386" },
588 .mips => Executor{ .qemu = "qemu-mips" },
589 .mipsel => Executor{ .qemu = "qemu-mipsel" },
590 .mips64 => Executor{ .qemu = "qemu-mips64" },
591 .mips64el => Executor{ .qemu = "qemu-mips64el" },
592 .powerpc => Executor{ .qemu = "qemu-ppc" },
593 .powerpc64 => Executor{ .qemu = "qemu-ppc64" },
594 .powerpc64le => Executor{ .qemu = "qemu-ppc64le" },
595 .riscv32 => Executor{ .qemu = "qemu-riscv32" },
596 .riscv64 => Executor{ .qemu = "qemu-riscv64" },
597 .s390x => Executor{ .qemu = "qemu-s390x" },
598 .sparc => Executor{ .qemu = "qemu-sparc" },
599 .x86_64 => Executor{ .qemu = "qemu-x86_64" },
600 else => return .unavailable,
601 };
602 }
603
604 if (self.isWindows()) {
605 switch (self.getArchPtrBitWidth()) {
606 32 => return Executor{ .wine = "wine" },
607 64 => return Executor{ .wine = "wine64" },
608 else => return .unavailable,
609 }
610 }
611
612 return .unavailable;
613 }
614};
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(