authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-09-14 02:47:54-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-09-14 02:47:54-04:00
logc65fe384ddb5f5f6a5f22cb636539fd91701de4d
tree8ae6966a01439c347bd69f87e40a9fc5e4f62476
parent06f2f4d64b63cf78a3ff77cc64dbc822123f454d
parentf1761632dae8951d21e62cb13e14bd4b4b0ed8a8

Merge branch 'macos-aindigo'

Closes #189

11 files changed, 334 insertions(+), 92 deletions(-)

CMakeLists.txt+2
......@@ -213,6 +213,8 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/io.zig" DESTINATION "${ZIG_STD_DEST}")
213213install(FILES "${CMAKE_SOURCE_DIR}/std/linux.zig" DESTINATION "${ZIG_STD_DEST}")
214214install(FILES "${CMAKE_SOURCE_DIR}/std/linux_i386.zig" DESTINATION "${ZIG_STD_DEST}")
215215install(FILES "${CMAKE_SOURCE_DIR}/std/linux_x86_64.zig" DESTINATION "${ZIG_STD_DEST}")
216install(FILES "${CMAKE_SOURCE_DIR}/std/darwin.zig" DESTINATION "${ZIG_STD_DEST}")
217install(FILES "${CMAKE_SOURCE_DIR}/std/darwin_x86_64.zig" DESTINATION "${ZIG_STD_DEST}")
216218install(FILES "${CMAKE_SOURCE_DIR}/std/list.zig" DESTINATION "${ZIG_STD_DEST}")
217219install(FILES "${CMAKE_SOURCE_DIR}/std/math.zig" DESTINATION "${ZIG_STD_DEST}")
218220install(FILES "${CMAKE_SOURCE_DIR}/std/mem.zig" DESTINATION "${ZIG_STD_DEST}")
src/codegen.cpp-2
......@@ -42,8 +42,6 @@ static void init_darwin_native(CodeGen *g) {
4242 g->mmacosx_version_min = buf_create_from_str(osx_target);
4343 } else if (ios_target) {
4444 g->mios_version_min = buf_create_from_str(ios_target);
45 } else {
46 zig_panic("unable to determine -mmacosx-version-min or -mios-version-min");
4745 }
4846}
4947
src/link.cpp+6
......@@ -643,6 +643,12 @@ static void construct_linker_job_darwin(LinkJob *lj) {
643643
644644 lj->args.append((const char *)buf_ptr(&lj->out_file_o));
645645
646 if (g->is_test_build) {
647 const char *test_runner_name = g->link_libc ? "test_runner_libc" : "test_runner_nolibc";
648 Buf *test_runner_o_path = build_o(g, test_runner_name);
649 lj->args.append(buf_ptr(test_runner_o_path));
650 }
651
646652 for (int i = 0; i < g->link_libs.length; i += 1) {
647653 Buf *link_lib = g->link_libs.at(i);
648654 Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib));
src/main.cpp+2
......@@ -388,9 +388,11 @@ int main(int argc, char **argv) {
388388 fprintf(stderr, "-mmacosx-version-min and -mios-version-min options not allowed together\n");
389389 return EXIT_FAILURE;
390390 }
391
391392 if (mmacosx_version_min) {
392393 codegen_set_mmacosx_version_min(g, buf_create_from_str(mmacosx_version_min));
393394 }
395
394396 if (mios_version_min) {
395397 codegen_set_mios_version_min(g, buf_create_from_str(mios_version_min));
396398 }
std/darwin.zig created+113
......@@ -0,0 +1,113 @@
1
2const arch = switch (@compileVar("arch")) {
3 x86_64 => @import("darwin_x86_64.zig"),
4 else => @compile_err("unsupported arch"),
5};
6
7const errno = @import("errno.zig");
8
9pub const O_LARGEFILE = 0x0000;
10pub const O_RDONLY = 0x0000;
11
12pub const SEEK_SET = 0x0;
13pub const SEEK_CUR = 0x1;
14pub const SEEK_END = 0x2;
15
16pub const SIGHUP = 1;
17pub const SIGINT = 2;
18pub const SIGQUIT = 3;
19pub const SIGILL = 4;
20pub const SIGTRAP = 5;
21pub const SIGABRT = 6;
22pub const SIGIOT = SIGABRT;
23pub const SIGBUS = 7;
24pub const SIGFPE = 8;
25pub const SIGKILL = 9;
26pub const SIGUSR1 = 10;
27pub const SIGSEGV = 11;
28pub const SIGUSR2 = 12;
29pub const SIGPIPE = 13;
30pub const SIGALRM = 14;
31pub const SIGTERM = 15;
32pub const SIGSTKFLT = 16;
33pub const SIGCHLD = 17;
34pub const SIGCONT = 18;
35pub const SIGSTOP = 19;
36pub const SIGTSTP = 20;
37pub const SIGTTIN = 21;
38pub const SIGTTOU = 22;
39pub const SIGURG = 23;
40pub const SIGXCPU = 24;
41pub const SIGXFSZ = 25;
42pub const SIGVTALRM = 26;
43pub const SIGPROF = 27;
44pub const SIGWINCH = 28;
45pub const SIGIO = 29;
46pub const SIGPOLL = 29;
47pub const SIGPWR = 30;
48pub const SIGSYS = 31;
49pub const SIGUNUSED = SIGSYS;
50
51/// Get the errno from a syscall return value, or 0 for no error.
52pub fn getErrno(r: usize) -> usize {
53 const signed_r = *(&isize)(&r);
54 if (signed_r > -4096 && signed_r < 0) usize(-signed_r) else 0
55}
56
57pub fn write(fd: i32, buf: &const u8, count: usize) -> usize {
58 arch.syscall3(arch.SYS_write, usize(fd), usize(buf), count)
59}
60
61pub fn close(fd: i32) -> usize {
62 arch.syscall1(arch.SYS_close, usize(fd))
63}
64
65pub fn open_c(path: &const u8, flags: usize, perm: usize) -> usize {
66 arch.syscall3(arch.SYS_open, usize(path), flags, perm)
67}
68
69pub fn open(path: []const u8, flags: usize, perm: usize) -> usize {
70 var buf: [path.len + 1]u8 = undefined;
71 @memcpy(&buf[0], &path[0], path.len);
72 buf[path.len] = 0;
73 return open_c(buf.ptr, flags, perm);
74}
75
76pub fn read(fd: i32, buf: &u8, count: usize) -> usize {
77 arch.syscall3(arch.SYS_read, usize(fd), usize(buf), count)
78}
79
80pub fn lseek(fd: i32, offset: usize, ref_pos: usize) -> usize {
81 arch.syscall3(arch.SYS_lseek, usize(fd), offset, ref_pos)
82}
83
84pub const stat = arch.stat;
85pub const timespec = arch.timespec;
86
87pub fn fstat(fd: i32, stat_buf: &stat) -> usize {
88 arch.syscall2(arch.SYS_fstat, usize(fd), usize(stat_buf))
89}
90
91pub error Unexpected;
92
93pub fn getrandom(buf: &u8, count: usize) -> usize {
94 const rr = open_c(c"/dev/urandom", O_LARGEFILE | O_RDONLY, 0);
95
96 if(getErrno(rr) > 0) return rr;
97
98 var fd: i32 = i32(rr);
99 const readRes = read(fd, buf, count);
100 readRes
101}
102
103pub fn raise(sig: i32) -> i32 {
104 // TODO investigate whether we need to block signals before calling kill
105 // like we do in the linux version of raise
106
107 //var set: sigset_t = undefined;
108 //blockAppSignals(&set);
109 const pid = i32(arch.syscall0(arch.SYS_getpid));
110 const ret = i32(arch.syscall2(arch.SYS_kill, usize(pid), usize(sig)));
111 //restoreSignals(&set);
112 return ret;
113}
std/darwin_x86_64.zig created+86
......@@ -0,0 +1,86 @@
1
2pub const SYSCALL_CLASS_SHIFT = 24;
3pub const SYSCALL_CLASS_MASK = 0xFF << SYSCALL_CLASS_SHIFT;
4// pub const SYSCALL_NUMBER_MASK = ~SYSCALL_CLASS_MASK; // ~ modifier not supported yet
5
6pub const SYSCALL_CLASS_NONE = 0; // Invalid
7pub const SYSCALL_CLASS_MACH = 1; // Mach
8pub const SYSCALL_CLASS_UNIX = 2; // Unix/BSD
9pub const SYSCALL_CLASS_MDEP = 3; // Machine-dependent
10pub const SYSCALL_CLASS_DIAG = 4; // Diagnostics
11
12// TODO: use the above constants to create the below values
13
14pub const SYS_read = 0x2000003;
15pub const SYS_write = 0x2000004;
16pub const SYS_open = 0x2000005;
17pub const SYS_close = 0x2000006;
18pub const SYS_kill = 0x2000025;
19pub const SYS_getpid = 0x2000030;
20pub const SYS_fstat = 0x20000BD;
21pub const SYS_lseek = 0x20000C7;
22
23pub inline fn syscall0(number: usize) -> usize {
24 asm volatile ("syscall"
25 : [ret] "={rax}" (-> usize)
26 : [number] "{rax}" (number)
27 : "rcx", "r11")
28}
29
30pub inline fn syscall1(number: usize, arg1: usize) -> usize {
31 asm volatile ("syscall"
32 : [ret] "={rax}" (-> usize)
33 : [number] "{rax}" (number),
34 [arg1] "{rdi}" (arg1)
35 : "rcx", "r11")
36}
37
38pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {
39 asm volatile ("syscall"
40 : [ret] "={rax}" (-> usize)
41 : [number] "{rax}" (number),
42 [arg1] "{rdi}" (arg1),
43 [arg2] "{rsi}" (arg2)
44 : "rcx", "r11")
45}
46
47pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {
48 asm volatile ("syscall"
49 : [ret] "={rax}" (-> usize)
50 : [number] "{rax}" (number),
51 [arg1] "{rdi}" (arg1),
52 [arg2] "{rsi}" (arg2),
53 [arg3] "{rdx}" (arg3)
54 : "rcx", "r11")
55}
56
57
58
59
60export struct stat {
61 dev: u32,
62 mode: u16,
63 nlink: u16,
64 ino: u64,
65 uid: u32,
66 gid: u32,
67 rdev: u64,
68
69 atim: timespec,
70 mtim: timespec,
71 ctim: timespec,
72
73 size: u64,
74 blocks: u64,
75 blksize: u32,
76 flags: u32,
77 gen: u32,
78 lspare: i32,
79 qspare: [2]u64,
80
81}
82
83export struct timespec {
84 tv_sec: isize,
85 tv_nsec: isize,
86}
std/debug.zig+1-1
......@@ -49,7 +49,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream) -> %void {
4949 out_stream.write("(stack trace unavailable for COFF object format)\n");
5050 },
5151 macho => {
52 out_stream.write("(stack trace unavailable for Mach-O object format)\n");
52 %return out_stream.write("(stack trace unavailable for Mach-O object format)\n");
5353 },
5454 unknown => {
5555 out_stream.write("(stack trace unavailable for unknown object format)\n");
std/index.zig+4-1
......@@ -13,5 +13,8 @@ pub const linux = switch(@compileVar("os")) {
1313 linux => @import("linux.zig"),
1414 else => null_import,
1515};
16
16pub const darwin = switch(@compileVar("os")) {
17 darwin => @import("darwin.zig"),
18 else => null_import,
19};
1720const null_import = @import("empty.zig");
std/io.zig+57-47
......@@ -1,9 +1,15 @@
1const linux = @import("linux.zig");
1const system = switch(@compileVar("os")) {
2 linux => @import("linux.zig"),
3 darwin => @import("darwin.zig"),
4 else => @compileError("Unsupported OS"),
5};
6
27const errno = @import("errno.zig");
38const math = @import("math.zig");
49const endian = @import("endian.zig");
510const debug = @import("debug.zig");
611const assert = debug.assert;
12const os = @import("os.zig");
713
814pub const stdin_fileno = 0;
915pub const stdout_fileno = 1;
......@@ -67,23 +73,23 @@ pub struct OutStream {
6773 buffer: [buffer_size]u8,
6874 index: usize,
6975
70 pub fn writeByte(os: &OutStream, b: u8) -> %void {
71 if (os.buffer.len == os.index) %return os.flush();
72 os.buffer[os.index] = b;
73 os.index += 1;
76 pub fn writeByte(self: &OutStream, b: u8) -> %void {
77 if (self.buffer.len == self.index) %return self.flush();
78 self.buffer[self.index] = b;
79 self.index += 1;
7480 }
7581
76 pub fn write(os: &OutStream, bytes: []const u8) -> %usize {
82 pub fn write(self: &OutStream, bytes: []const u8) -> %usize {
7783 var src_bytes_left = bytes.len;
7884 var src_index: @typeOf(bytes.len) = 0;
79 const dest_space_left = os.buffer.len - os.index;
85 const dest_space_left = self.buffer.len - self.index;
8086
8187 while (src_bytes_left > 0) {
8288 const copy_amt = math.min(dest_space_left, src_bytes_left);
83 @memcpy(&os.buffer[os.index], &bytes[src_index], copy_amt);
84 os.index += copy_amt;
85 if (os.index == os.buffer.len) {
86 %return os.flush();
89 @memcpy(&self.buffer[self.index], &bytes[src_index], copy_amt);
90 self.index += copy_amt;
91 if (self.index == self.buffer.len) {
92 %return self.flush();
8793 }
8894 src_bytes_left -= copy_amt;
8995 }
......@@ -92,30 +98,29 @@ pub struct OutStream {
9298
9399 /// Prints a byte buffer, flushes the buffer, then returns the number of
94100 /// bytes printed. The "f" is for "flush".
95 pub fn printf(os: &OutStream, str: []const u8) -> %usize {
96 const byte_count = %return os.write(str);
97 %return os.flush();
101 pub fn printf(self: &OutStream, str: []const u8) -> %usize {
102 const byte_count = %return self.write(str);
103 %return self.flush();
98104 return byte_count;
99105 }
100106
101 pub fn printInt(os: &OutStream, inline T: type, x: T) -> %usize {
107 pub fn printInt(self: &OutStream, inline T: type, x: T) -> %usize {
102108 // TODO replace max_u64_base10_digits with math.log10(math.pow(2, @sizeOf(T)))
103 if (os.index + max_u64_base10_digits >= os.buffer.len) {
104 %return os.flush();
109 if (self.index + max_u64_base10_digits >= self.buffer.len) {
110 %return self.flush();
105111 }
106 const amt_printed = bufPrintInt(T, os.buffer[os.index...], x);
107 os.index += amt_printed;
112 const amt_printed = bufPrintInt(T, self.buffer[self.index...], x);
113 self.index += amt_printed;
108114 return amt_printed;
109115 }
110116
111 pub fn flush(os: &OutStream) -> %void {
117 pub fn flush(self: &OutStream) -> %void {
112118 while (true) {
113 const write_ret = linux.write(os.fd, &os.buffer[0], os.index);
114 const write_err = linux.getErrno(write_ret);
119 const write_ret = system.write(self.fd, &self.buffer[0], self.index);
120 const write_err = system.getErrno(write_ret);
115121 if (write_err > 0) {
116122 return switch (write_err) {
117123 errno.EINTR => continue,
118
119124 errno.EINVAL => @unreachable(),
120125 errno.EDQUOT => error.DiskQuota,
121126 errno.EFBIG => error.FileTooBig,
......@@ -126,15 +131,15 @@ pub struct OutStream {
126131 else => error.Unexpected,
127132 }
128133 }
129 os.index = 0;
134 self.index = 0;
130135 return;
131136 }
132137 }
133138
134 pub fn close(os: &OutStream) -> %void {
139 pub fn close(self: &OutStream) -> %void {
135140 while (true) {
136 const close_ret = linux.close(os.fd);
137 const close_err = linux.getErrno(close_ret);
141 const close_ret = system.close(self.fd);
142 const close_err = system.getErrno(close_ret);
138143 if (close_err > 0) {
139144 return switch (close_err) {
140145 errno.EINTR => continue,
......@@ -157,10 +162,10 @@ pub struct InStream {
157162 /// Call close to clean up.
158163 pub fn open(is: &InStream, path: []const u8) -> %void {
159164 switch (@compileVar("os")) {
160 linux => {
165 linux, darwin => {
161166 while (true) {
162 const result = linux.open(path, linux.O_LARGEFILE|linux.O_RDONLY, 0);
163 const err = linux.getErrno(result);
167 const result = system.open(path, system.O_LARGEFILE|system.O_RDONLY, 0);
168 const err = system.getErrno(result);
164169 if (err > 0) {
165170 return switch (err) {
166171 errno.EINTR => continue,
......@@ -189,16 +194,17 @@ pub struct InStream {
189194 },
190195 else => @compileError("unsupported OS"),
191196 }
197
192198 }
193199
194200 /// Upon success, the stream is in an uninitialized state. To continue using it,
195201 /// you must use the open() function.
196202 pub fn close(is: &InStream) -> %void {
197203 switch (@compileVar("os")) {
198 linux => {
204 linux, darwin => {
199205 while (true) {
200 const close_ret = linux.close(is.fd);
201 const close_err = linux.getErrno(close_ret);
206 const close_ret = system.close(is.fd);
207 const close_err = system.getErrno(close_ret);
202208 if (close_err > 0) {
203209 return switch (close_err) {
204210 errno.EINTR => continue,
......@@ -219,11 +225,11 @@ pub struct InStream {
219225 /// the stream reached End Of File.
220226 pub fn read(is: &InStream, buf: []u8) -> %usize {
221227 switch (@compileVar("os")) {
222 linux => {
228 linux, darwin => {
223229 var index: usize = 0;
224230 while (index < buf.len) {
225 const amt_read = linux.read(is.fd, &buf[index], buf.len - index);
226 const read_err = linux.getErrno(amt_read);
231 const amt_read = system.read(is.fd, &buf[index], buf.len - index);
232 const read_err = system.getErrno(amt_read);
227233 if (read_err > 0) {
228234 switch (read_err) {
229235 errno.EINTR => continue,
......@@ -287,9 +293,9 @@ pub struct InStream {
287293
288294 pub fn seekForward(is: &InStream, amount: usize) -> %void {
289295 switch (@compileVar("os")) {
290 linux => {
291 const result = linux.lseek(is.fd, amount, linux.SEEK_CUR);
292 const err = linux.getErrno(result);
296 linux, darwin => {
297 const result = system.lseek(is.fd, amount, system.SEEK_CUR);
298 const err = system.getErrno(result);
293299 if (err > 0) {
294300 return switch (err) {
295301 errno.EBADF => error.BadFd,
......@@ -307,9 +313,9 @@ pub struct InStream {
307313
308314 pub fn seekTo(is: &InStream, pos: usize) -> %void {
309315 switch (@compileVar("os")) {
310 linux => {
311 const result = linux.lseek(is.fd, pos, linux.SEEK_SET);
312 const err = linux.getErrno(result);
316 linux, darwin => {
317 const result = system.lseek(is.fd, pos, system.SEEK_SET);
318 const err = system.getErrno(result);
313319 if (err > 0) {
314320 return switch (err) {
315321 errno.EBADF => error.BadFd,
......@@ -327,9 +333,9 @@ pub struct InStream {
327333
328334 pub fn getPos(is: &InStream) -> %usize {
329335 switch (@compileVar("os")) {
330 linux => {
331 const result = linux.lseek(is.fd, 0, linux.SEEK_CUR);
332 const err = linux.getErrno(result);
336 linux, darwin => {
337 const result = system.lseek(is.fd, 0, system.SEEK_CUR);
338 const err = system.getErrno(result);
333339 if (err > 0) {
334340 return switch (err) {
335341 errno.EBADF => error.BadFd,
......@@ -347,8 +353,8 @@ pub struct InStream {
347353 }
348354
349355 pub fn getEndPos(is: &InStream) -> %usize {
350 var stat: linux.stat = undefined;
351 const err = linux.getErrno(linux.fstat(is.fd, &stat));
356 var stat: system.stat = undefined;
357 const err = system.getErrno(system.fstat(is.fd, &stat));
352358 if (err > 0) {
353359 return switch (err) {
354360 errno.EBADF => error.BadFd,
......@@ -436,6 +442,10 @@ pub fn openSelfExe(stream: &InStream) -> %void {
436442 linux => {
437443 %return stream.open("/proc/self/exe");
438444 },
445 darwin => {
446 %%stderr.printf("TODO: openSelfExe on Darwin\n");
447 os.abort();
448 },
439449 else => @compileError("unsupported os"),
440450 }
441451}
std/os.zig+23-18
......@@ -1,33 +1,38 @@
1const linux = @import("linux.zig");
1const system = switch(@compileVar("os")) {
2 linux => @import("linux.zig"),
3 darwin => @import("darwin.zig"),
4 else => @compileError("Unsupported OS"),
5};
26const errno = @import("errno.zig");
37
4pub error SigInterrupt;
58pub error Unexpected;
69
710pub fn getRandomBytes(buf: []u8) -> %void {
8 switch (@compileVar("os")) {
9 linux => {
10 const ret = linux.getrandom(buf.ptr, buf.len, 0);
11 const err = linux.getErrno(ret);
12 if (err > 0) {
13 return switch (err) {
14 errno.EINVAL => @unreachable(),
15 errno.EFAULT => @unreachable(),
16 errno.EINTR => error.SigInterrupt,
17 else => error.Unexpected,
18 }
11 while (true) {
12 const ret = switch (@compileVar("os")) {
13 linux => system.getrandom(buf.ptr, buf.len, 0),
14 darwin => system.getrandom(buf.ptr, buf.len),
15 else => @compileError("unsupported os"),
16 };
17 const err = system.getErrno(ret);
18 if (err > 0) {
19 return switch (err) {
20 errno.EINVAL => @unreachable(),
21 errno.EFAULT => @unreachable(),
22 errno.EINTR => continue,
23 else => error.Unexpected,
1924 }
20 },
21 else => @compileError("unsupported os"),
25 }
26 return;
2227 }
2328}
2429
2530#attribute("cold")
2631pub fn abort() -> unreachable {
2732 switch (@compileVar("os")) {
28 linux => {
29 linux.raise(linux.SIGABRT);
30 linux.raise(linux.SIGKILL);
33 linux, darwin => {
34 system.raise(system.SIGABRT);
35 system.raise(system.SIGKILL);
3136 while (true) {}
3237 },
3338 else => @compileError("unsupported os"),
test/run_tests.cpp+40-23
......@@ -18,6 +18,11 @@ struct TestSourceFile {
1818 const char *source_code;
1919};
2020
21enum AllowWarnings {
22 AllowWarningsNo,
23 AllowWarningsYes,
24};
25
2126struct TestCase {
2227 const char *case_name;
2328 const char *output;
......@@ -29,6 +34,7 @@ struct TestCase {
2934 bool is_self_hosted;
3035 bool is_release_mode;
3136 bool is_debug_safety;
37 AllowWarnings allow_warnings;
3238};
3339
3440static ZigList<TestCase*> test_cases = {0};
......@@ -173,13 +179,16 @@ static void add_debug_safety_case(const char *case_name, const char *source) {
173179 }
174180}
175181
176static TestCase *add_parseh_case(const char *case_name, const char *source, int count, ...) {
182static TestCase *add_parseh_case(const char *case_name, AllowWarnings allow_warnings,
183 const char *source, int count, ...)
184{
177185 va_list ap;
178186 va_start(ap, count);
179187
180188 TestCase *test_case = allocate<TestCase>(1);
181189 test_case->case_name = case_name;
182190 test_case->is_parseh = true;
191 test_case->allow_warnings = allow_warnings;
183192
184193 test_case->source_files.resize(1);
185194 test_case->source_files.at(0).relative_path = tmp_h_path;
......@@ -1635,7 +1644,7 @@ fn unsigned_cast(x: i32) -> u32 {
16351644//////////////////////////////////////////////////////////////////////////////
16361645
16371646static void add_parseh_test_cases(void) {
1638 add_parseh_case("simple data types", R"SOURCE(
1647 add_parseh_case("simple data types", AllowWarningsYes, R"SOURCE(
16391648#include <stdint.h>
16401649int foo(char a, unsigned char b, signed char c);
16411650int foo(char a, unsigned char b, signed char c); // test a duplicate prototype
......@@ -1646,11 +1655,11 @@ void baz(int8_t a, int16_t b, int32_t c, int64_t d);
16461655 "pub extern fn bar(a: u8, b: u16, c: u32, d: u64);",
16471656 "pub extern fn baz(a: i8, b: i16, c: i32, d: i64);");
16481657
1649 add_parseh_case("noreturn attribute", R"SOURCE(
1658 add_parseh_case("noreturn attribute", AllowWarningsNo, R"SOURCE(
16501659void foo(void) __attribute__((noreturn));
16511660 )SOURCE", 1, R"OUTPUT(pub extern fn foo() -> unreachable;)OUTPUT");
16521661
1653 add_parseh_case("enums", R"SOURCE(
1662 add_parseh_case("enums", AllowWarningsNo, R"SOURCE(
16541663enum Foo {
16551664 FooA,
16561665 FooB,
......@@ -1665,11 +1674,11 @@ pub const FooB = enum_Foo.B;
16651674pub const Foo1 = enum_Foo.@"1";)",
16661675 R"(pub const Foo = enum_Foo;)");
16671676
1668 add_parseh_case("restrict -> noalias", R"SOURCE(
1677 add_parseh_case("restrict -> noalias", AllowWarningsNo, R"SOURCE(
16691678void foo(void *restrict bar, void *restrict);
16701679 )SOURCE", 1, R"OUTPUT(pub extern fn foo(noalias bar: ?&c_void, noalias arg1: ?&c_void);)OUTPUT");
16711680
1672 add_parseh_case("simple struct", R"SOURCE(
1681 add_parseh_case("simple struct", AllowWarningsNo, R"SOURCE(
16731682struct Foo {
16741683 int x;
16751684 char *y;
......@@ -1680,7 +1689,7 @@ struct Foo {
16801689 y: ?&u8,
16811690})OUTPUT", R"OUTPUT(pub const Foo = struct_Foo;)OUTPUT");
16821691
1683 add_parseh_case("qualified struct and enum", R"SOURCE(
1692 add_parseh_case("qualified struct and enum", AllowWarningsNo, R"SOURCE(
16841693struct Foo {
16851694 int x;
16861695 int y;
......@@ -1703,12 +1712,13 @@ pub const BarB = enum_Bar.B;)OUTPUT",
17031712 R"OUTPUT(pub const Foo = struct_Foo;
17041713pub const Bar = enum_Bar;)OUTPUT");
17051714
1706 add_parseh_case("constant size array", R"SOURCE(
1715 add_parseh_case("constant size array", AllowWarningsNo, R"SOURCE(
17071716void func(int array[20]);
17081717 )SOURCE", 1, "pub extern fn func(array: ?&c_int);");
17091718
17101719
1711 add_parseh_case("self referential struct with function pointer", R"SOURCE(
1720 add_parseh_case("self referential struct with function pointer",
1721 AllowWarningsNo, R"SOURCE(
17121722struct Foo {
17131723 void (*derp)(struct Foo *foo);
17141724};
......@@ -1717,7 +1727,7 @@ struct Foo {
17171727})OUTPUT", R"OUTPUT(pub const Foo = struct_Foo;)OUTPUT");
17181728
17191729
1720 add_parseh_case("struct prototype used in func", R"SOURCE(
1730 add_parseh_case("struct prototype used in func", AllowWarningsNo, R"SOURCE(
17211731struct Foo;
17221732struct Foo *some_func(struct Foo *foo, int x);
17231733 )SOURCE", 2, R"OUTPUT(pub type struct_Foo = u8;
......@@ -1725,17 +1735,19 @@ pub extern fn some_func(foo: ?&struct_Foo, x: c_int) -> ?&struct_Foo;)OUTPUT",
17251735 R"OUTPUT(pub const Foo = struct_Foo;)OUTPUT");
17261736
17271737
1728 add_parseh_case("#define a char literal", R"SOURCE(
1738 add_parseh_case("#define a char literal", AllowWarningsNo, R"SOURCE(
17291739#define A_CHAR 'a'
17301740 )SOURCE", 1, R"OUTPUT(pub const A_CHAR = 'a';)OUTPUT");
17311741
17321742
1733 add_parseh_case("#define an unsigned integer literal", R"SOURCE(
1743 add_parseh_case("#define an unsigned integer literal", AllowWarningsNo,
1744 R"SOURCE(
17341745#define CHANNEL_COUNT 24
17351746 )SOURCE", 1, R"OUTPUT(pub const CHANNEL_COUNT = 24;)OUTPUT");
17361747
17371748
1738 add_parseh_case("#define referencing another #define", R"SOURCE(
1749 add_parseh_case("#define referencing another #define", AllowWarningsNo,
1750 R"SOURCE(
17391751#define THING2 THING1
17401752#define THING1 1234
17411753 )SOURCE", 2,
......@@ -1743,7 +1755,7 @@ pub extern fn some_func(foo: ?&struct_Foo, x: c_int) -> ?&struct_Foo;)OUTPUT",
17431755 "pub const THING2 = THING1;");
17441756
17451757
1746 add_parseh_case("variables", R"SOURCE(
1758 add_parseh_case("variables", AllowWarningsNo, R"SOURCE(
17471759extern int extern_var;
17481760static const int int_var = 13;
17491761 )SOURCE", 2,
......@@ -1751,7 +1763,7 @@ static const int int_var = 13;
17511763 "pub const int_var: c_int = 13;");
17521764
17531765
1754 add_parseh_case("circular struct definitions", R"SOURCE(
1766 add_parseh_case("circular struct definitions", AllowWarningsNo, R"SOURCE(
17551767struct Bar;
17561768
17571769struct Foo {
......@@ -1770,14 +1782,15 @@ struct Bar {
17701782})SOURCE");
17711783
17721784
1773 add_parseh_case("typedef void", R"SOURCE(
1785 add_parseh_case("typedef void", AllowWarningsNo, R"SOURCE(
17741786typedef void Foo;
17751787Foo fun(Foo *a);
17761788 )SOURCE", 2,
17771789 "pub const Foo = c_void;",
17781790 "pub extern fn fun(a: ?&c_void);");
17791791
1780 add_parseh_case("generate inline func for #define global extern fn", R"SOURCE(
1792 add_parseh_case("generate inline func for #define global extern fn", AllowWarningsNo,
1793 R"SOURCE(
17811794extern void (*fn_ptr)(void);
17821795#define foo fn_ptr
17831796 )SOURCE", 2,
......@@ -1787,19 +1800,19 @@ extern void (*fn_ptr)(void);
17871800})SOURCE");
17881801
17891802
1790 add_parseh_case("#define string", R"SOURCE(
1803 add_parseh_case("#define string", AllowWarningsNo, R"SOURCE(
17911804#define foo "a string"
17921805 )SOURCE", 1, "pub const foo = c\"a string\";");
17931806
1794 add_parseh_case("__cdecl doesn't mess up function pointers", R"SOURCE(
1807 add_parseh_case("__cdecl doesn't mess up function pointers", AllowWarningsNo, R"SOURCE(
17951808void foo(void (__cdecl *fn_ptr)(void));
17961809 )SOURCE", 1, "pub extern fn foo(fn_ptr: ?extern fn());");
17971810
1798 add_parseh_case("comment after integer literal", R"SOURCE(
1811 add_parseh_case("comment after integer literal", AllowWarningsNo, R"SOURCE(
17991812#define SDL_INIT_VIDEO 0x00000020 /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
18001813 )SOURCE", 1, "pub const SDL_INIT_VIDEO = 32;");
18011814
1802 add_parseh_case("zig keywords in C code", R"SOURCE(
1815 add_parseh_case("zig keywords in C code", AllowWarningsNo, R"SOURCE(
18031816struct type {
18041817 int defer;
18051818};
......@@ -1807,7 +1820,7 @@ struct type {
18071820 @"defer": c_int,
18081821})", R"(pub const @"type" = struct_type;)");
18091822
1810 add_parseh_case("macro defines string literal with octal", R"SOURCE(
1823 add_parseh_case("macro defines string literal with octal", AllowWarningsNo, R"SOURCE(
18111824#define FOO "aoeu\023 derp"
18121825#define FOO2 "aoeu\0234 derp"
18131826#define FOO_CHAR '\077'
......@@ -1926,9 +1939,13 @@ static void run_test(TestCase *test_case) {
19261939 if (test_case->is_parseh) {
19271940 if (buf_len(&zig_stderr) > 0) {
19281941 printf("\nparseh emitted warnings:\n");
1942 printf("------------------------------\n");
19291943 print_compiler_invocation(test_case);
19301944 printf("%s\n", buf_ptr(&zig_stderr));
1931 exit(1);
1945 printf("------------------------------\n");
1946 if (test_case->allow_warnings == AllowWarningsNo) {
1947 exit(1);
1948 }
19321949 }
19331950
19341951 for (int i = 0; i < test_case->compile_errors.length; i += 1) {