authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-12-23 21:52:06+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-02 18:53:16+01:00
log563d9ebfe597b313b265a5a30296c081fe35d87a
tree9b67e280b607498d1592fbc420d10ec39d835440
parent7bd80f207147167821634e16983edf9e9b115c9f

Implement the callconv() annotation


50 files changed, 572 insertions(+), 358 deletions(-)

doc/docgen.zig+1
...@@ -818,6 +818,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok...@@ -818,6 +818,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
818 .Keyword_resume,818 .Keyword_resume,
819 .Keyword_return,819 .Keyword_return,
820 .Keyword_linksection,820 .Keyword_linksection,
821 .Keyword_callconv,
821 .Keyword_stdcallcc,822 .Keyword_stdcallcc,
822 .Keyword_struct,823 .Keyword_struct,
823 .Keyword_suspend,824 .Keyword_suspend,
doc/langref.html.in+1-1
...@@ -2829,7 +2829,7 @@ test "@tagName" {...@@ -2829,7 +2829,7 @@ test "@tagName" {
2829 <p>2829 <p>
2830 By default, enums are not guaranteed to be compatible with the C ABI:2830 By default, enums are not guaranteed to be compatible with the C ABI:
2831 </p>2831 </p>
2832 {#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'ccc'#}2832 {#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'C'#}
2833const Foo = enum { A, B, C };2833const Foo = enum { A, B, C };
2834export fn entry(foo: Foo) void { }2834export fn entry(foo: Foo) void { }
2835 {#code_end#}2835 {#code_end#}
lib/std/builtin.zig+19-12
...@@ -91,6 +91,24 @@ pub const Mode = enum {...@@ -91,6 +91,24 @@ pub const Mode = enum {
91 ReleaseSmall,91 ReleaseSmall,
92};92};
9393
94/// This data structure is used by the Zig language code generation and
95/// therefore must be kept in sync with the compiler implementation.
96pub const CallingConvention = enum {
97 Unspecified,
98 C,
99 Cold,
100 Naked,
101 Async,
102 Interrupt,
103 Signal,
104 Stdcall,
105 Fastcall,
106 Vectorcall,
107 APCS,
108 AAPCS,
109 AAPCSVFP,
110};
111
94pub const TypeId = @TagType(TypeInfo);112pub const TypeId = @TagType(TypeInfo);
95113
96/// This data structure is used by the Zig language code generation and114/// This data structure is used by the Zig language code generation and
...@@ -253,17 +271,6 @@ pub const TypeInfo = union(enum) {...@@ -253,17 +271,6 @@ pub const TypeInfo = union(enum) {
253 decls: []Declaration,271 decls: []Declaration,
254 };272 };
255273
256 /// This data structure is used by the Zig language code generation and
257 /// therefore must be kept in sync with the compiler implementation.
258 pub const CallingConvention = enum {
259 Unspecified,
260 C,
261 Cold,
262 Naked,
263 Stdcall,
264 Async,
265 };
266
267 /// This data structure is used by the Zig language code generation and274 /// This data structure is used by the Zig language code generation and
268 /// therefore must be kept in sync with the compiler implementation.275 /// therefore must be kept in sync with the compiler implementation.
269 pub const FnArg = struct {276 pub const FnArg = struct {
...@@ -416,7 +423,7 @@ pub const CallOptions = struct {...@@ -416,7 +423,7 @@ pub const CallOptions = struct {
416/// therefore must be kept in sync with the compiler implementation.423/// therefore must be kept in sync with the compiler implementation.
417pub const TestFn = struct {424pub const TestFn = struct {
418 name: []const u8,425 name: []const u8,
419 func: fn()anyerror!void,426 func: fn () anyerror!void,
420};427};
421428
422/// This function type is used by the Zig language code generation and429/// This function type is used by the Zig language code generation and
lib/std/debug.zig+1-1
...@@ -2475,7 +2475,7 @@ extern fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *con...@@ -2475,7 +2475,7 @@ extern fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *con
2475 os.abort();2475 os.abort();
2476}2476}
24772477
2478stdcallcc fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) c_long {2478fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) callconv(.Stdcall) c_long {
2479 const exception_address = @ptrToInt(info.ExceptionRecord.ExceptionAddress);2479 const exception_address = @ptrToInt(info.ExceptionRecord.ExceptionAddress);
2480 switch (info.ExceptionRecord.ExceptionCode) {2480 switch (info.ExceptionRecord.ExceptionCode) {
2481 windows.EXCEPTION_DATATYPE_MISALIGNMENT => panicExtra(null, exception_address, "Unaligned Memory Access", .{}),2481 windows.EXCEPTION_DATATYPE_MISALIGNMENT => panicExtra(null, exception_address, "Unaligned Memory Access", .{}),
lib/std/fs.zig+1-1
...@@ -230,7 +230,7 @@ pub const AtomicFile = struct {...@@ -230,7 +230,7 @@ pub const AtomicFile = struct {
230 b64_fs_encoder.encode(tmp_path_slice[dirname_component_len..tmp_path_len], &rand_buf);230 b64_fs_encoder.encode(tmp_path_slice[dirname_component_len..tmp_path_len], &rand_buf);
231231
232 const file = my_cwd.createFileC(232 const file = my_cwd.createFileC(
233 tmp_path_slice, 233 tmp_path_slice,
234 .{ .mode = mode, .exclusive = true },234 .{ .mode = mode, .exclusive = true },
235 ) catch |err| switch (err) {235 ) catch |err| switch (err) {
236 error.PathAlreadyExists => continue,236 error.PathAlreadyExists => continue,
lib/std/mutex.zig+14-13
...@@ -48,8 +48,8 @@ pub const Mutex = if (builtin.single_threaded)...@@ -48,8 +48,8 @@ pub const Mutex = if (builtin.single_threaded)
48 return self.tryAcquire() orelse @panic("deadlock detected");48 return self.tryAcquire() orelse @panic("deadlock detected");
49 }49 }
50 }50 }
51else if (builtin.os == .windows) 51else if (builtin.os == .windows)
52 // https://locklessinc.com/articles/keyed_events/52// https://locklessinc.com/articles/keyed_events/
53 extern union {53 extern union {
54 locked: u8,54 locked: u8,
55 waiters: u32,55 waiters: u32,
...@@ -97,8 +97,8 @@ else if (builtin.os == .windows)...@@ -97,8 +97,8 @@ else if (builtin.os == .windows)
97 return Held{ .mutex = self };97 return Held{ .mutex = self };
98 }98 }
9999
100 // otherwise, try and update the waiting count.100 // otherwise, try and update the waiting count.
101 // then unset the WAKE bit so that another unlocker can wake up a thread.101 // then unset the WAKE bit so that another unlocker can wake up a thread.
102 } else if (@cmpxchgWeak(u32, &self.waiters, waiters, (waiters + WAIT) | 1, .Monotonic, .Monotonic) == null) {102 } else if (@cmpxchgWeak(u32, &self.waiters, waiters, (waiters + WAIT) | 1, .Monotonic, .Monotonic) == null) {
103 const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null);103 const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null);
104 assert(rc == 0);104 assert(rc == 0);
...@@ -118,7 +118,7 @@ else if (builtin.os == .windows)...@@ -118,7 +118,7 @@ else if (builtin.os == .windows)
118118
119 while (true) : (SpinLock.loopHint(1)) {119 while (true) : (SpinLock.loopHint(1)) {
120 const waiters = @atomicLoad(u32, &self.mutex.waiters, .Monotonic);120 const waiters = @atomicLoad(u32, &self.mutex.waiters, .Monotonic);
121 121
122 // no one is waiting122 // no one is waiting
123 if (waiters < WAIT) return;123 if (waiters < WAIT) return;
124 // someone grabbed the lock and will do the wake instead124 // someone grabbed the lock and will do the wake instead
...@@ -130,14 +130,14 @@ else if (builtin.os == .windows)...@@ -130,14 +130,14 @@ else if (builtin.os == .windows)
130 if (@cmpxchgWeak(u32, &self.mutex.waiters, waiters, waiters - WAIT + WAKE, .Release, .Monotonic) == null) {130 if (@cmpxchgWeak(u32, &self.mutex.waiters, waiters, waiters - WAIT + WAKE, .Release, .Monotonic) == null) {
131 const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null);131 const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null);
132 assert(rc == 0);132 assert(rc == 0);
133 return; 133 return;
134 }134 }
135 }135 }
136 }136 }
137 };137 };
138 }138 }
139else if (builtin.link_libc or builtin.os == .linux)139else if (builtin.link_libc or builtin.os == .linux)
140 // stack-based version of https://github.com/Amanieu/parking_lot/blob/master/core/src/word_lock.rs140// stack-based version of https://github.com/Amanieu/parking_lot/blob/master/core/src/word_lock.rs
141 struct {141 struct {
142 state: usize,142 state: usize,
143143
...@@ -170,8 +170,8 @@ else if (builtin.link_libc or builtin.os == .linux)...@@ -170,8 +170,8 @@ else if (builtin.link_libc or builtin.os == .linux)
170170
171 pub fn acquire(self: *Mutex) Held {171 pub fn acquire(self: *Mutex) Held {
172 return self.tryAcquire() orelse {172 return self.tryAcquire() orelse {
173 self.acquireSlow();173 self.acquireSlow();
174 return Held{ .mutex = self };174 return Held{ .mutex = self };
175 };175 };
176 }176 }
177177
...@@ -237,7 +237,7 @@ else if (builtin.link_libc or builtin.os == .linux)...@@ -237,7 +237,7 @@ else if (builtin.link_libc or builtin.os == .linux)
237237
238 fn releaseSlow(self: *Mutex) void {238 fn releaseSlow(self: *Mutex) void {
239 @setCold(true);239 @setCold(true);
240 240
241 // try and lock the LFIO queue to pop a node off,241 // try and lock the LFIO queue to pop a node off,
242 // stopping altogether if its already locked or the queue is empty242 // stopping altogether if its already locked or the queue is empty
243 var state = @atomicLoad(usize, &self.state, .Monotonic);243 var state = @atomicLoad(usize, &self.state, .Monotonic);
...@@ -265,9 +265,10 @@ else if (builtin.link_libc or builtin.os == .linux)...@@ -265,9 +265,10 @@ else if (builtin.link_libc or builtin.os == .linux)
265 }265 }
266 }266 }
267267
268// for platforms without a known OS blocking268 // for platforms without a known OS blocking
269// primitive, default to SpinLock for correctness269 // primitive, default to SpinLock for correctness
270else SpinLock;270else
271 SpinLock;
271272
272const TestContext = struct {273const TestContext = struct {
273 mutex: *Mutex,274 mutex: *Mutex,
lib/std/net.zig+1-5
...@@ -451,11 +451,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*...@@ -451,11 +451,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
451 .next = null,451 .next = null,
452 };452 };
453 var res: *os.addrinfo = undefined;453 var res: *os.addrinfo = undefined;
454 switch (os.system.getaddrinfo(454 switch (os.system.getaddrinfo(name_c.ptr, @ptrCast([*:0]const u8, port_c.ptr), &hints, &res)) {
455 name_c.ptr,
456 @ptrCast([*:0]const u8, port_c.ptr),
457 &hints,
458 &res)) {
459 0 => {},455 0 => {},
460 c.EAI_ADDRFAMILY => return error.HostLacksNetworkAddresses,456 c.EAI_ADDRFAMILY => return error.HostLacksNetworkAddresses,
461 c.EAI_AGAIN => return error.TemporaryNameServerFailure,457 c.EAI_AGAIN => return error.TemporaryNameServerFailure,
lib/std/os/linux/arm-eabi.zig+2-2
...@@ -97,7 +97,7 @@ pub extern fn getThreadPointer() usize {...@@ -97,7 +97,7 @@ pub extern fn getThreadPointer() usize {
97 );97 );
98}98}
9999
100pub nakedcc fn restore() void {100pub fn restore() callconv(.Naked) void {
101 return asm volatile ("svc #0"101 return asm volatile ("svc #0"
102 :102 :
103 : [number] "{r7}" (@as(usize, SYS_sigreturn))103 : [number] "{r7}" (@as(usize, SYS_sigreturn))
...@@ -105,7 +105,7 @@ pub nakedcc fn restore() void {...@@ -105,7 +105,7 @@ pub nakedcc fn restore() void {
105 );105 );
106}106}
107107
108pub nakedcc fn restore_rt() void {108pub fn restore_rt() callconv(.Naked) void {
109 return asm volatile ("svc #0"109 return asm volatile ("svc #0"
110 :110 :
111 : [number] "{r7}" (@as(usize, SYS_rt_sigreturn))111 : [number] "{r7}" (@as(usize, SYS_rt_sigreturn))
lib/std/os/linux/arm64.zig+1-1
...@@ -90,7 +90,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, a...@@ -90,7 +90,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, a
9090
91pub const restore = restore_rt;91pub const restore = restore_rt;
9292
93pub nakedcc fn restore_rt() void {93pub fn restore_rt() callconv(.Naked) void {
94 return asm volatile ("svc #0"94 return asm volatile ("svc #0"
95 :95 :
96 : [number] "{x8}" (@as(usize, SYS_rt_sigreturn))96 : [number] "{x8}" (@as(usize, SYS_rt_sigreturn))
lib/std/os/linux/i386.zig+2-2
...@@ -102,7 +102,7 @@ pub fn socketcall(call: usize, args: [*]usize) usize {...@@ -102,7 +102,7 @@ pub fn socketcall(call: usize, args: [*]usize) usize {
102/// This matches the libc clone function.102/// This matches the libc clone function.
103pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;103pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
104104
105pub nakedcc fn restore() void {105pub fn restore() callconv(.Naked) void {
106 return asm volatile ("int $0x80"106 return asm volatile ("int $0x80"
107 :107 :
108 : [number] "{eax}" (@as(usize, SYS_sigreturn))108 : [number] "{eax}" (@as(usize, SYS_sigreturn))
...@@ -110,7 +110,7 @@ pub nakedcc fn restore() void {...@@ -110,7 +110,7 @@ pub nakedcc fn restore() void {
110 );110 );
111}111}
112112
113pub nakedcc fn restore_rt() void {113pub fn restore_rt() callconv(.Naked) void {
114 return asm volatile ("int $0x80"114 return asm volatile ("int $0x80"
115 :115 :
116 : [number] "{eax}" (@as(usize, SYS_rt_sigreturn))116 : [number] "{eax}" (@as(usize, SYS_rt_sigreturn))
lib/std/os/linux/mipsel.zig+2-2
...@@ -144,7 +144,7 @@ pub fn syscall6(...@@ -144,7 +144,7 @@ pub fn syscall6(
144/// This matches the libc clone function.144/// This matches the libc clone function.
145pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;145pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
146146
147pub nakedcc fn restore() void {147pub fn restore() callconv(.Naked) void {
148 return asm volatile ("syscall"148 return asm volatile ("syscall"
149 :149 :
150 : [number] "{$2}" (@as(usize, SYS_sigreturn))150 : [number] "{$2}" (@as(usize, SYS_sigreturn))
...@@ -152,7 +152,7 @@ pub nakedcc fn restore() void {...@@ -152,7 +152,7 @@ pub nakedcc fn restore() void {
152 );152 );
153}153}
154154
155pub nakedcc fn restore_rt() void {155pub fn restore_rt() callconv(.Naked) void {
156 return asm volatile ("syscall"156 return asm volatile ("syscall"
157 :157 :
158 : [number] "{$2}" (@as(usize, SYS_rt_sigreturn))158 : [number] "{$2}" (@as(usize, SYS_rt_sigreturn))
lib/std/os/linux/riscv64.zig+1-1
...@@ -89,7 +89,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, a...@@ -89,7 +89,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, a
8989
90pub const restore = restore_rt;90pub const restore = restore_rt;
9191
92pub nakedcc fn restore_rt() void {92pub fn restore_rt() callconv(.Naked) void {
93 return asm volatile ("ecall"93 return asm volatile ("ecall"
94 :94 :
95 : [number] "{x17}" (@as(usize, SYS_rt_sigreturn))95 : [number] "{x17}" (@as(usize, SYS_rt_sigreturn))
lib/std/os/linux/x86_64.zig+1-1
...@@ -90,7 +90,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: usize,...@@ -90,7 +90,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: usize,
9090
91pub const restore = restore_rt;91pub const restore = restore_rt;
9292
93pub nakedcc fn restore_rt() void {93pub fn restore_rt() callconv(.Naked) void {
94 return asm volatile ("syscall"94 return asm volatile ("syscall"
95 :95 :
96 : [number] "{rax}" (@as(usize, SYS_rt_sigreturn))96 : [number] "{rax}" (@as(usize, SYS_rt_sigreturn))
lib/std/os/test.zig+1-1
...@@ -166,7 +166,7 @@ test "sigaltstack" {...@@ -166,7 +166,7 @@ test "sigaltstack" {
166// analyzed166// analyzed
167const dl_phdr_info = if (@hasDecl(os, "dl_phdr_info")) os.dl_phdr_info else c_void;167const dl_phdr_info = if (@hasDecl(os, "dl_phdr_info")) os.dl_phdr_info else c_void;
168168
169export fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) i32 {169extern fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) i32 {
170 if (builtin.os == .windows or builtin.os == .wasi or builtin.os == .macosx)170 if (builtin.os == .windows or builtin.os == .wasi or builtin.os == .macosx)
171 return 0;171 return 0;
172172
lib/std/os/uefi/protocols/simple_text_input_protocol.zig-1
...@@ -27,4 +27,3 @@ pub const SimpleTextInputProtocol = extern struct {...@@ -27,4 +27,3 @@ pub const SimpleTextInputProtocol = extern struct {
27 .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b },27 .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b },
28 };28 };
29};29};
30
lib/std/os/windows/advapi32.zig+5-5
...@@ -1,23 +1,23 @@...@@ -1,23 +1,23 @@
1usingnamespace @import("bits.zig");1usingnamespace @import("bits.zig");
22
3pub extern "advapi32" stdcallcc fn RegOpenKeyExW(3pub extern "advapi32" fn RegOpenKeyExW(
4 hKey: HKEY,4 hKey: HKEY,
5 lpSubKey: LPCWSTR,5 lpSubKey: LPCWSTR,
6 ulOptions: DWORD,6 ulOptions: DWORD,
7 samDesired: REGSAM,7 samDesired: REGSAM,
8 phkResult: *HKEY,8 phkResult: *HKEY,
9) LSTATUS;9) callconv(.Stdcall) LSTATUS;
1010
11pub extern "advapi32" stdcallcc fn RegQueryValueExW(11pub extern "advapi32" fn RegQueryValueExW(
12 hKey: HKEY,12 hKey: HKEY,
13 lpValueName: LPCWSTR,13 lpValueName: LPCWSTR,
14 lpReserved: LPDWORD,14 lpReserved: LPDWORD,
15 lpType: LPDWORD,15 lpType: LPDWORD,
16 lpData: LPBYTE,16 lpData: LPBYTE,
17 lpcbData: LPDWORD,17 lpcbData: LPDWORD,
18) LSTATUS;18) callconv(.Stdcall) LSTATUS;
1919
20// RtlGenRandom is known as SystemFunction036 under advapi3220// RtlGenRandom is known as SystemFunction036 under advapi32
21// http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx */21// http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx */
22pub extern "advapi32" stdcallcc fn SystemFunction036(output: [*]u8, length: ULONG) BOOL;22pub extern "advapi32" fn SystemFunction036(output: [*]u8, length: ULONG) callconv(.Stdcall) BOOL;
23pub const RtlGenRandom = SystemFunction036;23pub const RtlGenRandom = SystemFunction036;
lib/std/os/windows/bits.zig+1-1
...@@ -892,7 +892,7 @@ pub const EXCEPTION_POINTERS = extern struct {...@@ -892,7 +892,7 @@ pub const EXCEPTION_POINTERS = extern struct {
892 ContextRecord: *c_void,892 ContextRecord: *c_void,
893};893};
894894
895pub const VECTORED_EXCEPTION_HANDLER = stdcallcc fn (ExceptionInfo: *EXCEPTION_POINTERS) c_long;895pub const VECTORED_EXCEPTION_HANDLER = fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(.Stdcall) c_long;
896896
897pub const OBJECT_ATTRIBUTES = extern struct {897pub const OBJECT_ATTRIBUTES = extern struct {
898 Length: ULONG,898 Length: ULONG,
lib/std/os/windows/kernel32.zig+100-100
...@@ -1,22 +1,22 @@...@@ -1,22 +1,22 @@
1usingnamespace @import("bits.zig");1usingnamespace @import("bits.zig");
22
3pub extern "kernel32" stdcallcc fn AddVectoredExceptionHandler(First: c_ulong, Handler: ?VECTORED_EXCEPTION_HANDLER) ?*c_void;3pub extern "kernel32" fn AddVectoredExceptionHandler(First: c_ulong, Handler: ?VECTORED_EXCEPTION_HANDLER) callconv(.Stdcall) ?*c_void;
4pub extern "kernel32" stdcallcc fn RemoveVectoredExceptionHandler(Handle: HANDLE) c_ulong;4pub extern "kernel32" fn RemoveVectoredExceptionHandler(Handle: HANDLE) callconv(.Stdcall) c_ulong;
55
6pub extern "kernel32" stdcallcc fn CancelIoEx(hFile: HANDLE, lpOverlapped: LPOVERLAPPED) BOOL;6pub extern "kernel32" fn CancelIoEx(hFile: HANDLE, lpOverlapped: LPOVERLAPPED) callconv(.Stdcall) BOOL;
77
8pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) BOOL;8pub extern "kernel32" fn CloseHandle(hObject: HANDLE) callconv(.Stdcall) BOOL;
99
10pub extern "kernel32" stdcallcc fn CreateDirectoryW(lpPathName: [*]const u16, lpSecurityAttributes: ?*SECURITY_ATTRIBUTES) BOOL;10pub extern "kernel32" fn CreateDirectoryW(lpPathName: [*]const u16, lpSecurityAttributes: ?*SECURITY_ATTRIBUTES) callconv(.Stdcall) BOOL;
1111
12pub extern "kernel32" stdcallcc fn CreateEventExW(12pub extern "kernel32" fn CreateEventExW(
13 lpEventAttributes: ?*SECURITY_ATTRIBUTES,13 lpEventAttributes: ?*SECURITY_ATTRIBUTES,
14 lpName: [*:0]const u16,14 lpName: [*:0]const u16,
15 dwFlags: DWORD,15 dwFlags: DWORD,
16 dwDesiredAccess: DWORD,16 dwDesiredAccess: DWORD,
17) ?HANDLE;17) callconv(.Stdcall) ?HANDLE;
1818
19pub extern "kernel32" stdcallcc fn CreateFileW(19pub extern "kernel32" fn CreateFileW(
20 lpFileName: [*]const u16, // TODO null terminated pointer type20 lpFileName: [*]const u16, // TODO null terminated pointer type
21 dwDesiredAccess: DWORD,21 dwDesiredAccess: DWORD,
22 dwShareMode: DWORD,22 dwShareMode: DWORD,
...@@ -24,16 +24,16 @@ pub extern "kernel32" stdcallcc fn CreateFileW(...@@ -24,16 +24,16 @@ pub extern "kernel32" stdcallcc fn CreateFileW(
24 dwCreationDisposition: DWORD,24 dwCreationDisposition: DWORD,
25 dwFlagsAndAttributes: DWORD,25 dwFlagsAndAttributes: DWORD,
26 hTemplateFile: ?HANDLE,26 hTemplateFile: ?HANDLE,
27) HANDLE;27) callconv(.Stdcall) HANDLE;
2828
29pub extern "kernel32" stdcallcc fn CreatePipe(29pub extern "kernel32" fn CreatePipe(
30 hReadPipe: *HANDLE,30 hReadPipe: *HANDLE,
31 hWritePipe: *HANDLE,31 hWritePipe: *HANDLE,
32 lpPipeAttributes: *const SECURITY_ATTRIBUTES,32 lpPipeAttributes: *const SECURITY_ATTRIBUTES,
33 nSize: DWORD,33 nSize: DWORD,
34) BOOL;34) callconv(.Stdcall) BOOL;
3535
36pub extern "kernel32" stdcallcc fn CreateProcessW(36pub extern "kernel32" fn CreateProcessW(
37 lpApplicationName: ?LPWSTR,37 lpApplicationName: ?LPWSTR,
38 lpCommandLine: LPWSTR,38 lpCommandLine: LPWSTR,
39 lpProcessAttributes: ?*SECURITY_ATTRIBUTES,39 lpProcessAttributes: ?*SECURITY_ATTRIBUTES,
...@@ -44,15 +44,15 @@ pub extern "kernel32" stdcallcc fn CreateProcessW(...@@ -44,15 +44,15 @@ pub extern "kernel32" stdcallcc fn CreateProcessW(
44 lpCurrentDirectory: ?LPWSTR,44 lpCurrentDirectory: ?LPWSTR,
45 lpStartupInfo: *STARTUPINFOW,45 lpStartupInfo: *STARTUPINFOW,
46 lpProcessInformation: *PROCESS_INFORMATION,46 lpProcessInformation: *PROCESS_INFORMATION,
47) BOOL;47) callconv(.Stdcall) BOOL;
4848
49pub extern "kernel32" stdcallcc fn CreateSymbolicLinkW(lpSymlinkFileName: [*]const u16, lpTargetFileName: [*]const u16, dwFlags: DWORD) BOOLEAN;49pub extern "kernel32" fn CreateSymbolicLinkW(lpSymlinkFileName: [*]const u16, lpTargetFileName: [*]const u16, dwFlags: DWORD) callconv(.Stdcall) BOOLEAN;
5050
51pub extern "kernel32" stdcallcc fn CreateIoCompletionPort(FileHandle: HANDLE, ExistingCompletionPort: ?HANDLE, CompletionKey: ULONG_PTR, NumberOfConcurrentThreads: DWORD) ?HANDLE;51pub extern "kernel32" fn CreateIoCompletionPort(FileHandle: HANDLE, ExistingCompletionPort: ?HANDLE, CompletionKey: ULONG_PTR, NumberOfConcurrentThreads: DWORD) callconv(.Stdcall) ?HANDLE;
5252
53pub extern "kernel32" stdcallcc fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) ?HANDLE;53pub extern "kernel32" fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) callconv(.Stdcall) ?HANDLE;
5454
55pub extern "kernel32" stdcallcc fn DeviceIoControl(55pub extern "kernel32" fn DeviceIoControl(
56 h: HANDLE,56 h: HANDLE,
57 dwIoControlCode: DWORD,57 dwIoControlCode: DWORD,
58 lpInBuffer: ?*const c_void,58 lpInBuffer: ?*const c_void,
...@@ -61,107 +61,107 @@ pub extern "kernel32" stdcallcc fn DeviceIoControl(...@@ -61,107 +61,107 @@ pub extern "kernel32" stdcallcc fn DeviceIoControl(
61 nOutBufferSize: DWORD,61 nOutBufferSize: DWORD,
62 lpBytesReturned: ?*DWORD,62 lpBytesReturned: ?*DWORD,
63 lpOverlapped: ?*OVERLAPPED,63 lpOverlapped: ?*OVERLAPPED,
64) BOOL;64) callconv(.Stdcall) BOOL;
6565
66pub extern "kernel32" stdcallcc fn DeleteFileW(lpFileName: [*]const u16) BOOL;66pub extern "kernel32" fn DeleteFileW(lpFileName: [*]const u16) callconv(.Stdcall) BOOL;
6767
68pub extern "kernel32" stdcallcc fn DuplicateHandle(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE, hTargetProcessHandle: HANDLE, lpTargetHandle: *HANDLE, dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwOptions: DWORD) BOOL;68pub extern "kernel32" fn DuplicateHandle(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE, hTargetProcessHandle: HANDLE, lpTargetHandle: *HANDLE, dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwOptions: DWORD) callconv(.Stdcall) BOOL;
6969
70pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: UINT) noreturn;70pub extern "kernel32" fn ExitProcess(exit_code: UINT) callconv(.Stdcall) noreturn;
7171
72pub extern "kernel32" stdcallcc fn FindFirstFileW(lpFileName: [*]const u16, lpFindFileData: *WIN32_FIND_DATAW) HANDLE;72pub extern "kernel32" fn FindFirstFileW(lpFileName: [*]const u16, lpFindFileData: *WIN32_FIND_DATAW) callconv(.Stdcall) HANDLE;
73pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL;73pub extern "kernel32" fn FindClose(hFindFile: HANDLE) callconv(.Stdcall) BOOL;
74pub extern "kernel32" stdcallcc fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) BOOL;74pub extern "kernel32" fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) callconv(.Stdcall) BOOL;
7575
76pub extern "kernel32" stdcallcc fn FormatMessageW(dwFlags: DWORD, lpSource: ?LPVOID, dwMessageId: DWORD, dwLanguageId: DWORD, lpBuffer: LPWSTR, nSize: DWORD, Arguments: ?*va_list) DWORD;76pub extern "kernel32" fn FormatMessageW(dwFlags: DWORD, lpSource: ?LPVOID, dwMessageId: DWORD, dwLanguageId: DWORD, lpBuffer: LPWSTR, nSize: DWORD, Arguments: ?*va_list) callconv(.Stdcall) DWORD;
7777
78pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsW(penv: [*]u16) BOOL;78pub extern "kernel32" fn FreeEnvironmentStringsW(penv: [*]u16) callconv(.Stdcall) BOOL;
7979
80pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR;80pub extern "kernel32" fn GetCommandLineA() callconv(.Stdcall) LPSTR;
8181
82pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: *DWORD) BOOL;82pub extern "kernel32" fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: *DWORD) callconv(.Stdcall) BOOL;
8383
84pub extern "kernel32" stdcallcc fn GetConsoleScreenBufferInfo(hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: *CONSOLE_SCREEN_BUFFER_INFO) BOOL;84pub extern "kernel32" fn GetConsoleScreenBufferInfo(hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: *CONSOLE_SCREEN_BUFFER_INFO) callconv(.Stdcall) BOOL;
8585
86pub extern "kernel32" stdcallcc fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: ?[*]WCHAR) DWORD;86pub extern "kernel32" fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: ?[*]WCHAR) callconv(.Stdcall) DWORD;
8787
88pub extern "kernel32" stdcallcc fn GetCurrentThread() HANDLE;88pub extern "kernel32" fn GetCurrentThread() callconv(.Stdcall) HANDLE;
89pub extern "kernel32" stdcallcc fn GetCurrentThreadId() DWORD;89pub extern "kernel32" fn GetCurrentThreadId() callconv(.Stdcall) DWORD;
9090
91pub extern "kernel32" stdcallcc fn GetEnvironmentStringsW() ?[*]u16;91pub extern "kernel32" fn GetEnvironmentStringsW() callconv(.Stdcall) ?[*]u16;
9292
93pub extern "kernel32" stdcallcc fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) DWORD;93pub extern "kernel32" fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) callconv(.Stdcall) DWORD;
9494
95pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: *DWORD) BOOL;95pub extern "kernel32" fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: *DWORD) callconv(.Stdcall) BOOL;
9696
97pub extern "kernel32" stdcallcc fn GetFileSizeEx(hFile: HANDLE, lpFileSize: *LARGE_INTEGER) BOOL;97pub extern "kernel32" fn GetFileSizeEx(hFile: HANDLE, lpFileSize: *LARGE_INTEGER) callconv(.Stdcall) BOOL;
9898
99pub extern "kernel32" stdcallcc fn GetFileAttributesW(lpFileName: [*]const WCHAR) DWORD;99pub extern "kernel32" fn GetFileAttributesW(lpFileName: [*]const WCHAR) callconv(.Stdcall) DWORD;
100100
101pub extern "kernel32" stdcallcc fn GetModuleFileNameW(hModule: ?HMODULE, lpFilename: [*]u16, nSize: DWORD) DWORD;101pub extern "kernel32" fn GetModuleFileNameW(hModule: ?HMODULE, lpFilename: [*]u16, nSize: DWORD) callconv(.Stdcall) DWORD;
102102
103pub extern "kernel32" stdcallcc fn GetModuleHandleW(lpModuleName: ?[*]const WCHAR) HMODULE;103pub extern "kernel32" fn GetModuleHandleW(lpModuleName: ?[*]const WCHAR) callconv(.Stdcall) HMODULE;
104104
105pub extern "kernel32" stdcallcc fn GetLastError() DWORD;105pub extern "kernel32" fn GetLastError() callconv(.Stdcall) DWORD;
106106
107pub extern "kernel32" stdcallcc fn GetFileInformationByHandle(107pub extern "kernel32" fn GetFileInformationByHandle(
108 hFile: HANDLE,108 hFile: HANDLE,
109 lpFileInformation: *BY_HANDLE_FILE_INFORMATION,109 lpFileInformation: *BY_HANDLE_FILE_INFORMATION,
110) BOOL;110) callconv(.Stdcall) BOOL;
111111
112pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx(112pub extern "kernel32" fn GetFileInformationByHandleEx(
113 in_hFile: HANDLE,113 in_hFile: HANDLE,
114 in_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,114 in_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,
115 out_lpFileInformation: *c_void,115 out_lpFileInformation: *c_void,
116 in_dwBufferSize: DWORD,116 in_dwBufferSize: DWORD,
117) BOOL;117) callconv(.Stdcall) BOOL;
118118
119pub extern "kernel32" stdcallcc fn GetFinalPathNameByHandleW(119pub extern "kernel32" fn GetFinalPathNameByHandleW(
120 hFile: HANDLE,120 hFile: HANDLE,
121 lpszFilePath: [*]u16,121 lpszFilePath: [*]u16,
122 cchFilePath: DWORD,122 cchFilePath: DWORD,
123 dwFlags: DWORD,123 dwFlags: DWORD,
124) DWORD;124) callconv(.Stdcall) DWORD;
125125
126pub extern "kernel32" stdcallcc fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERLAPPED, lpNumberOfBytesTransferred: *DWORD, bWait: BOOL) BOOL;126pub extern "kernel32" fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERLAPPED, lpNumberOfBytesTransferred: *DWORD, bWait: BOOL) callconv(.Stdcall) BOOL;
127127
128pub extern "kernel32" stdcallcc fn GetProcessHeap() ?HANDLE;128pub extern "kernel32" fn GetProcessHeap() callconv(.Stdcall) ?HANDLE;
129pub extern "kernel32" stdcallcc fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) BOOL;129pub extern "kernel32" fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) callconv(.Stdcall) BOOL;
130130
131pub extern "kernel32" stdcallcc fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) void;131pub extern "kernel32" fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) callconv(.Stdcall) void;
132pub extern "kernel32" stdcallcc fn GetSystemTimeAsFileTime(*FILETIME) void;132pub extern "kernel32" fn GetSystemTimeAsFileTime(*FILETIME) callconv(.Stdcall) void;
133133
134pub extern "kernel32" stdcallcc fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) ?HANDLE;134pub extern "kernel32" fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) callconv(.Stdcall) ?HANDLE;
135pub extern "kernel32" stdcallcc fn HeapDestroy(hHeap: HANDLE) BOOL;135pub extern "kernel32" fn HeapDestroy(hHeap: HANDLE) callconv(.Stdcall) BOOL;
136pub extern "kernel32" stdcallcc fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void, dwBytes: SIZE_T) ?*c_void;136pub extern "kernel32" fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void, dwBytes: SIZE_T) callconv(.Stdcall) ?*c_void;
137pub extern "kernel32" stdcallcc fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) SIZE_T;137pub extern "kernel32" fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) callconv(.Stdcall) SIZE_T;
138pub extern "kernel32" stdcallcc fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) SIZE_T;138pub extern "kernel32" fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) callconv(.Stdcall) SIZE_T;
139pub extern "kernel32" stdcallcc fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) BOOL;139pub extern "kernel32" fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) callconv(.Stdcall) BOOL;
140140
141pub extern "kernel32" stdcallcc fn GetStdHandle(in_nStdHandle: DWORD) ?HANDLE;141pub extern "kernel32" fn GetStdHandle(in_nStdHandle: DWORD) callconv(.Stdcall) ?HANDLE;
142142
143pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) ?*c_void;143pub extern "kernel32" fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) callconv(.Stdcall) ?*c_void;
144144
145pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void) BOOL;145pub extern "kernel32" fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void) callconv(.Stdcall) BOOL;
146146
147pub extern "kernel32" stdcallcc fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: ?*const c_void) BOOL;147pub extern "kernel32" fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: ?*const c_void) callconv(.Stdcall) BOOL;
148148
149pub extern "kernel32" stdcallcc fn VirtualAlloc(lpAddress: ?LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD) ?LPVOID;149pub extern "kernel32" fn VirtualAlloc(lpAddress: ?LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD) callconv(.Stdcall) ?LPVOID;
150pub extern "kernel32" stdcallcc fn VirtualFree(lpAddress: ?LPVOID, dwSize: SIZE_T, dwFreeType: DWORD) BOOL;150pub extern "kernel32" fn VirtualFree(lpAddress: ?LPVOID, dwSize: SIZE_T, dwFreeType: DWORD) callconv(.Stdcall) BOOL;
151151
152pub extern "kernel32" stdcallcc fn MoveFileExW(152pub extern "kernel32" fn MoveFileExW(
153 lpExistingFileName: [*]const u16,153 lpExistingFileName: [*]const u16,
154 lpNewFileName: [*]const u16,154 lpNewFileName: [*]const u16,
155 dwFlags: DWORD,155 dwFlags: DWORD,
156) BOOL;156) callconv(.Stdcall) BOOL;
157157
158pub extern "kernel32" stdcallcc fn PostQueuedCompletionStatus(CompletionPort: HANDLE, dwNumberOfBytesTransferred: DWORD, dwCompletionKey: ULONG_PTR, lpOverlapped: ?*OVERLAPPED) BOOL;158pub extern "kernel32" fn PostQueuedCompletionStatus(CompletionPort: HANDLE, dwNumberOfBytesTransferred: DWORD, dwCompletionKey: ULONG_PTR, lpOverlapped: ?*OVERLAPPED) callconv(.Stdcall) BOOL;
159159
160pub extern "kernel32" stdcallcc fn QueryPerformanceCounter(lpPerformanceCount: *LARGE_INTEGER) BOOL;160pub extern "kernel32" fn QueryPerformanceCounter(lpPerformanceCount: *LARGE_INTEGER) callconv(.Stdcall) BOOL;
161161
162pub extern "kernel32" stdcallcc fn QueryPerformanceFrequency(lpFrequency: *LARGE_INTEGER) BOOL;162pub extern "kernel32" fn QueryPerformanceFrequency(lpFrequency: *LARGE_INTEGER) callconv(.Stdcall) BOOL;
163163
164pub extern "kernel32" stdcallcc fn ReadDirectoryChangesW(164pub extern "kernel32" fn ReadDirectoryChangesW(
165 hDirectory: HANDLE,165 hDirectory: HANDLE,
166 lpBuffer: [*]align(@alignOf(FILE_NOTIFY_INFORMATION)) u8,166 lpBuffer: [*]align(@alignOf(FILE_NOTIFY_INFORMATION)) u8,
167 nBufferLength: DWORD,167 nBufferLength: DWORD,
...@@ -170,79 +170,79 @@ pub extern "kernel32" stdcallcc fn ReadDirectoryChangesW(...@@ -170,79 +170,79 @@ pub extern "kernel32" stdcallcc fn ReadDirectoryChangesW(
170 lpBytesReturned: ?*DWORD,170 lpBytesReturned: ?*DWORD,
171 lpOverlapped: ?*OVERLAPPED,171 lpOverlapped: ?*OVERLAPPED,
172 lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE,172 lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE,
173) BOOL;173) callconv(.Stdcall) BOOL;
174174
175pub extern "kernel32" stdcallcc fn ReadFile(175pub extern "kernel32" fn ReadFile(
176 in_hFile: HANDLE,176 in_hFile: HANDLE,
177 out_lpBuffer: [*]u8,177 out_lpBuffer: [*]u8,
178 in_nNumberOfBytesToRead: DWORD,178 in_nNumberOfBytesToRead: DWORD,
179 out_lpNumberOfBytesRead: ?*DWORD,179 out_lpNumberOfBytesRead: ?*DWORD,
180 in_out_lpOverlapped: ?*OVERLAPPED,180 in_out_lpOverlapped: ?*OVERLAPPED,
181) BOOL;181) callconv(.Stdcall) BOOL;
182182
183pub extern "kernel32" stdcallcc fn RemoveDirectoryW(lpPathName: [*]const u16) BOOL;183pub extern "kernel32" fn RemoveDirectoryW(lpPathName: [*]const u16) callconv(.Stdcall) BOOL;
184184
185pub extern "kernel32" stdcallcc fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) BOOL;185pub extern "kernel32" fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) callconv(.Stdcall) BOOL;
186186
187pub extern "kernel32" stdcallcc fn SetFilePointerEx(187pub extern "kernel32" fn SetFilePointerEx(
188 in_fFile: HANDLE,188 in_fFile: HANDLE,
189 in_liDistanceToMove: LARGE_INTEGER,189 in_liDistanceToMove: LARGE_INTEGER,
190 out_opt_ldNewFilePointer: ?*LARGE_INTEGER,190 out_opt_ldNewFilePointer: ?*LARGE_INTEGER,
191 in_dwMoveMethod: DWORD,191 in_dwMoveMethod: DWORD,
192) BOOL;192) callconv(.Stdcall) BOOL;
193193
194pub extern "kernel32" stdcallcc fn SetFileTime(194pub extern "kernel32" fn SetFileTime(
195 hFile: HANDLE,195 hFile: HANDLE,
196 lpCreationTime: ?*const FILETIME,196 lpCreationTime: ?*const FILETIME,
197 lpLastAccessTime: ?*const FILETIME,197 lpLastAccessTime: ?*const FILETIME,
198 lpLastWriteTime: ?*const FILETIME,198 lpLastWriteTime: ?*const FILETIME,
199) BOOL;199) callconv(.Stdcall) BOOL;
200200
201pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) BOOL;201pub extern "kernel32" fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) callconv(.Stdcall) BOOL;
202202
203pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD) void;203pub extern "kernel32" fn Sleep(dwMilliseconds: DWORD) callconv(.Stdcall) void;
204204
205pub extern "kernel32" stdcallcc fn SwitchToThread() BOOL;205pub extern "kernel32" fn SwitchToThread() callconv(.Stdcall) BOOL;
206206
207pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) BOOL;207pub extern "kernel32" fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) callconv(.Stdcall) BOOL;
208208
209pub extern "kernel32" stdcallcc fn TlsAlloc() DWORD;209pub extern "kernel32" fn TlsAlloc() callconv(.Stdcall) DWORD;
210210
211pub extern "kernel32" stdcallcc fn TlsFree(dwTlsIndex: DWORD) BOOL;211pub extern "kernel32" fn TlsFree(dwTlsIndex: DWORD) callconv(.Stdcall) BOOL;
212212
213pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) DWORD;213pub extern "kernel32" fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) callconv(.Stdcall) DWORD;
214214
215pub extern "kernel32" stdcallcc fn WaitForSingleObjectEx(hHandle: HANDLE, dwMilliseconds: DWORD, bAlertable: BOOL) DWORD;215pub extern "kernel32" fn WaitForSingleObjectEx(hHandle: HANDLE, dwMilliseconds: DWORD, bAlertable: BOOL) callconv(.Stdcall) DWORD;
216216
217pub extern "kernel32" stdcallcc fn WaitForMultipleObjects(nCount: DWORD, lpHandle: [*]const HANDLE, bWaitAll: BOOL, dwMilliseconds: DWORD) DWORD;217pub extern "kernel32" fn WaitForMultipleObjects(nCount: DWORD, lpHandle: [*]const HANDLE, bWaitAll: BOOL, dwMilliseconds: DWORD) callconv(.Stdcall) DWORD;
218218
219pub extern "kernel32" stdcallcc fn WaitForMultipleObjectsEx(219pub extern "kernel32" fn WaitForMultipleObjectsEx(
220 nCount: DWORD,220 nCount: DWORD,
221 lpHandle: [*]const HANDLE,221 lpHandle: [*]const HANDLE,
222 bWaitAll: BOOL,222 bWaitAll: BOOL,
223 dwMilliseconds: DWORD,223 dwMilliseconds: DWORD,
224 bAlertable: BOOL,224 bAlertable: BOOL,
225) DWORD;225) callconv(.Stdcall) DWORD;
226226
227pub extern "kernel32" stdcallcc fn WriteFile(227pub extern "kernel32" fn WriteFile(
228 in_hFile: HANDLE,228 in_hFile: HANDLE,
229 in_lpBuffer: [*]const u8,229 in_lpBuffer: [*]const u8,
230 in_nNumberOfBytesToWrite: DWORD,230 in_nNumberOfBytesToWrite: DWORD,
231 out_lpNumberOfBytesWritten: ?*DWORD,231 out_lpNumberOfBytesWritten: ?*DWORD,
232 in_out_lpOverlapped: ?*OVERLAPPED,232 in_out_lpOverlapped: ?*OVERLAPPED,
233) BOOL;233) callconv(.Stdcall) BOOL;
234234
235pub extern "kernel32" stdcallcc fn WriteFileEx(hFile: HANDLE, lpBuffer: [*]const u8, nNumberOfBytesToWrite: DWORD, lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE) BOOL;235pub extern "kernel32" fn WriteFileEx(hFile: HANDLE, lpBuffer: [*]const u8, nNumberOfBytesToWrite: DWORD, lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE) callconv(.Stdcall) BOOL;
236236
237pub extern "kernel32" stdcallcc fn LoadLibraryW(lpLibFileName: [*]const u16) ?HMODULE;237pub extern "kernel32" fn LoadLibraryW(lpLibFileName: [*]const u16) callconv(.Stdcall) ?HMODULE;
238238
239pub extern "kernel32" stdcallcc fn GetProcAddress(hModule: HMODULE, lpProcName: [*]const u8) ?FARPROC;239pub extern "kernel32" fn GetProcAddress(hModule: HMODULE, lpProcName: [*]const u8) callconv(.Stdcall) ?FARPROC;
240240
241pub extern "kernel32" stdcallcc fn FreeLibrary(hModule: HMODULE) BOOL;241pub extern "kernel32" fn FreeLibrary(hModule: HMODULE) callconv(.Stdcall) BOOL;
242242
243pub extern "kernel32" stdcallcc fn InitializeCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void;243pub extern "kernel32" fn InitializeCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void;
244pub extern "kernel32" stdcallcc fn EnterCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void;244pub extern "kernel32" fn EnterCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void;
245pub extern "kernel32" stdcallcc fn LeaveCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void;245pub extern "kernel32" fn LeaveCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void;
246pub extern "kernel32" stdcallcc fn DeleteCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void;246pub extern "kernel32" fn DeleteCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void;
247247
248pub extern "kernel32" stdcallcc fn InitOnceExecuteOnce(InitOnce: *INIT_ONCE, InitFn: INIT_ONCE_FN, Parameter: ?*c_void, Context: ?*c_void) BOOL;248pub extern "kernel32" fn InitOnceExecuteOnce(InitOnce: *INIT_ONCE, InitFn: INIT_ONCE_FN, Parameter: ?*c_void, Context: ?*c_void) callconv(.Stdcall) BOOL;
lib/std/os/windows/ntdll.zig+19-19
...@@ -1,14 +1,14 @@...@@ -1,14 +1,14 @@
1usingnamespace @import("bits.zig");1usingnamespace @import("bits.zig");
22
3pub extern "NtDll" stdcallcc fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) WORD;3pub extern "NtDll" fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) callconv(.Stdcall) WORD;
4pub extern "NtDll" stdcallcc fn NtQueryInformationFile(4pub extern "NtDll" fn NtQueryInformationFile(
5 FileHandle: HANDLE,5 FileHandle: HANDLE,
6 IoStatusBlock: *IO_STATUS_BLOCK,6 IoStatusBlock: *IO_STATUS_BLOCK,
7 FileInformation: *c_void,7 FileInformation: *c_void,
8 Length: ULONG,8 Length: ULONG,
9 FileInformationClass: FILE_INFORMATION_CLASS,9 FileInformationClass: FILE_INFORMATION_CLASS,
10) NTSTATUS;10) callconv(.Stdcall) NTSTATUS;
11pub extern "NtDll" stdcallcc fn NtCreateFile(11pub extern "NtDll" fn NtCreateFile(
12 FileHandle: *HANDLE,12 FileHandle: *HANDLE,
13 DesiredAccess: ACCESS_MASK,13 DesiredAccess: ACCESS_MASK,
14 ObjectAttributes: *OBJECT_ATTRIBUTES,14 ObjectAttributes: *OBJECT_ATTRIBUTES,
...@@ -20,8 +20,8 @@ pub extern "NtDll" stdcallcc fn NtCreateFile(...@@ -20,8 +20,8 @@ pub extern "NtDll" stdcallcc fn NtCreateFile(
20 CreateOptions: ULONG,20 CreateOptions: ULONG,
21 EaBuffer: ?*c_void,21 EaBuffer: ?*c_void,
22 EaLength: ULONG,22 EaLength: ULONG,
23) NTSTATUS;23) callconv(.Stdcall) NTSTATUS;
24pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile(24pub extern "NtDll" fn NtDeviceIoControlFile(
25 FileHandle: HANDLE,25 FileHandle: HANDLE,
26 Event: ?HANDLE,26 Event: ?HANDLE,
27 ApcRoutine: ?IO_APC_ROUTINE,27 ApcRoutine: ?IO_APC_ROUTINE,
...@@ -32,17 +32,17 @@ pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile(...@@ -32,17 +32,17 @@ pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile(
32 InputBufferLength: ULONG,32 InputBufferLength: ULONG,
33 OutputBuffer: ?PVOID,33 OutputBuffer: ?PVOID,
34 OutputBufferLength: ULONG,34 OutputBufferLength: ULONG,
35) NTSTATUS;35) callconv(.Stdcall) NTSTATUS;
36pub extern "NtDll" stdcallcc fn NtClose(Handle: HANDLE) NTSTATUS;36pub extern "NtDll" fn NtClose(Handle: HANDLE) callconv(.Stdcall) NTSTATUS;
37pub extern "NtDll" stdcallcc fn RtlDosPathNameToNtPathName_U(37pub extern "NtDll" fn RtlDosPathNameToNtPathName_U(
38 DosPathName: [*]const u16,38 DosPathName: [*]const u16,
39 NtPathName: *UNICODE_STRING,39 NtPathName: *UNICODE_STRING,
40 NtFileNamePart: ?*?[*]const u16,40 NtFileNamePart: ?*?[*]const u16,
41 DirectoryInfo: ?*CURDIR,41 DirectoryInfo: ?*CURDIR,
42) BOOL;42) callconv(.Stdcall) BOOL;
43pub extern "NtDll" stdcallcc fn RtlFreeUnicodeString(UnicodeString: *UNICODE_STRING) void;43pub extern "NtDll" fn RtlFreeUnicodeString(UnicodeString: *UNICODE_STRING) callconv(.Stdcall) void;
4444
45pub extern "NtDll" stdcallcc fn NtQueryDirectoryFile(45pub extern "NtDll" fn NtQueryDirectoryFile(
46 FileHandle: HANDLE,46 FileHandle: HANDLE,
47 Event: ?HANDLE,47 Event: ?HANDLE,
48 ApcRoutine: ?IO_APC_ROUTINE,48 ApcRoutine: ?IO_APC_ROUTINE,
...@@ -54,22 +54,22 @@ pub extern "NtDll" stdcallcc fn NtQueryDirectoryFile(...@@ -54,22 +54,22 @@ pub extern "NtDll" stdcallcc fn NtQueryDirectoryFile(
54 ReturnSingleEntry: BOOLEAN,54 ReturnSingleEntry: BOOLEAN,
55 FileName: ?*UNICODE_STRING,55 FileName: ?*UNICODE_STRING,
56 RestartScan: BOOLEAN,56 RestartScan: BOOLEAN,
57) NTSTATUS;57) callconv(.Stdcall) NTSTATUS;
58pub extern "NtDll" stdcallcc fn NtCreateKeyedEvent(58pub extern "NtDll" fn NtCreateKeyedEvent(
59 KeyedEventHandle: *HANDLE,59 KeyedEventHandle: *HANDLE,
60 DesiredAccess: ACCESS_MASK,60 DesiredAccess: ACCESS_MASK,
61 ObjectAttributes: ?PVOID,61 ObjectAttributes: ?PVOID,
62 Flags: ULONG,62 Flags: ULONG,
63) NTSTATUS;63) callconv(.Stdcall) NTSTATUS;
64pub extern "NtDll" stdcallcc fn NtReleaseKeyedEvent(64pub extern "NtDll" fn NtReleaseKeyedEvent(
65 EventHandle: HANDLE,65 EventHandle: HANDLE,
66 Key: *const c_void,66 Key: *const c_void,
67 Alertable: BOOLEAN,67 Alertable: BOOLEAN,
68 Timeout: ?*LARGE_INTEGER,68 Timeout: ?*LARGE_INTEGER,
69) NTSTATUS;69) callconv(.Stdcall) NTSTATUS;
70pub extern "NtDll" stdcallcc fn NtWaitForKeyedEvent(70pub extern "NtDll" fn NtWaitForKeyedEvent(
71 EventHandle: HANDLE,71 EventHandle: HANDLE,
72 Key: *const c_void,72 Key: *const c_void,
73 Alertable: BOOLEAN,73 Alertable: BOOLEAN,
74 Timeout: ?*LARGE_INTEGER,74 Timeout: ?*LARGE_INTEGER,
75) NTSTATUS;75) callconv(.Stdcall) NTSTATUS;
lib/std/os/windows/ole32.zig+4-4
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1usingnamespace @import("bits.zig");1usingnamespace @import("bits.zig");
22
3pub extern "ole32" stdcallcc fn CoTaskMemFree(pv: LPVOID) void;3pub extern "ole32" fn CoTaskMemFree(pv: LPVOID) callconv(.Stdcall) void;
4pub extern "ole32" stdcallcc fn CoUninitialize() void;4pub extern "ole32" fn CoUninitialize() callconv(.Stdcall) void;
5pub extern "ole32" stdcallcc fn CoGetCurrentProcess() DWORD;5pub extern "ole32" fn CoGetCurrentProcess() callconv(.Stdcall) DWORD;
6pub extern "ole32" stdcallcc fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) HRESULT;6pub extern "ole32" fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) callconv(.Stdcall) HRESULT;
lib/std/os/windows/shell32.zig+1-1
...@@ -1,3 +1,3 @@...@@ -1,3 +1,3 @@
1usingnamespace @import("bits.zig");1usingnamespace @import("bits.zig");
22
3pub extern "shell32" stdcallcc fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*]WCHAR) HRESULT;3pub extern "shell32" fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*]WCHAR) callconv(.Stdcall) HRESULT;
lib/std/os/windows/ws2_32.zig+23-23
...@@ -315,30 +315,30 @@ const IOC_WS2 = 0x08000000;...@@ -315,30 +315,30 @@ const IOC_WS2 = 0x08000000;
315315
316pub const SIO_BASE_HANDLE = IOC_OUT | IOC_WS2 | 34;316pub const SIO_BASE_HANDLE = IOC_OUT | IOC_WS2 | 34;
317317
318pub extern "ws2_32" stdcallcc fn WSAStartup(318pub extern "ws2_32" fn WSAStartup(
319 wVersionRequired: WORD,319 wVersionRequired: WORD,
320 lpWSAData: *WSADATA,320 lpWSAData: *WSADATA,
321) c_int;321) callconv(.Stdcall) c_int;
322pub extern "ws2_32" stdcallcc fn WSACleanup() c_int;322pub extern "ws2_32" fn WSACleanup() callconv(.Stdcall) c_int;
323pub extern "ws2_32" stdcallcc fn WSAGetLastError() c_int;323pub extern "ws2_32" fn WSAGetLastError() callconv(.Stdcall) c_int;
324pub extern "ws2_32" stdcallcc fn WSASocketA(324pub extern "ws2_32" fn WSASocketA(
325 af: c_int,325 af: c_int,
326 type: c_int,326 type: c_int,
327 protocol: c_int,327 protocol: c_int,
328 lpProtocolInfo: ?*WSAPROTOCOL_INFOA,328 lpProtocolInfo: ?*WSAPROTOCOL_INFOA,
329 g: GROUP,329 g: GROUP,
330 dwFlags: DWORD,330 dwFlags: DWORD,
331) SOCKET;331) callconv(.Stdcall) SOCKET;
332pub extern "ws2_32" stdcallcc fn WSASocketW(332pub extern "ws2_32" fn WSASocketW(
333 af: c_int,333 af: c_int,
334 type: c_int,334 type: c_int,
335 protocol: c_int,335 protocol: c_int,
336 lpProtocolInfo: ?*WSAPROTOCOL_INFOW,336 lpProtocolInfo: ?*WSAPROTOCOL_INFOW,
337 g: GROUP,337 g: GROUP,
338 dwFlags: DWORD,338 dwFlags: DWORD,
339) SOCKET;339) callconv(.Stdcall) SOCKET;
340pub extern "ws2_32" stdcallcc fn closesocket(s: SOCKET) c_int;340pub extern "ws2_32" fn closesocket(s: SOCKET) callconv(.Stdcall) c_int;
341pub extern "ws2_32" stdcallcc fn WSAIoctl(341pub extern "ws2_32" fn WSAIoctl(
342 s: SOCKET,342 s: SOCKET,
343 dwIoControlCode: DWORD,343 dwIoControlCode: DWORD,
344 lpvInBuffer: ?*const c_void,344 lpvInBuffer: ?*const c_void,
...@@ -348,18 +348,18 @@ pub extern "ws2_32" stdcallcc fn WSAIoctl(...@@ -348,18 +348,18 @@ pub extern "ws2_32" stdcallcc fn WSAIoctl(
348 lpcbBytesReturned: LPDWORD,348 lpcbBytesReturned: LPDWORD,
349 lpOverlapped: ?*WSAOVERLAPPED,349 lpOverlapped: ?*WSAOVERLAPPED,
350 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,350 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
351) c_int;351) callconv(.Stdcall) c_int;
352pub extern "ws2_32" stdcallcc fn accept(352pub extern "ws2_32" fn accept(
353 s: SOCKET,353 s: SOCKET,
354 addr: ?*sockaddr,354 addr: ?*sockaddr,
355 addrlen: socklen_t,355 addrlen: socklen_t,
356) SOCKET;356) callconv(.Stdcall) SOCKET;
357pub extern "ws2_32" stdcallcc fn connect(357pub extern "ws2_32" fn connect(
358 s: SOCKET,358 s: SOCKET,
359 name: *const sockaddr,359 name: *const sockaddr,
360 namelen: socklen_t,360 namelen: socklen_t,
361) c_int;361) callconv(.Stdcall) c_int;
362pub extern "ws2_32" stdcallcc fn WSARecv(362pub extern "ws2_32" fn WSARecv(
363 s: SOCKET,363 s: SOCKET,
364 lpBuffers: [*]const WSABUF,364 lpBuffers: [*]const WSABUF,
365 dwBufferCount: DWORD,365 dwBufferCount: DWORD,
...@@ -367,8 +367,8 @@ pub extern "ws2_32" stdcallcc fn WSARecv(...@@ -367,8 +367,8 @@ pub extern "ws2_32" stdcallcc fn WSARecv(
367 lpFlags: *DWORD,367 lpFlags: *DWORD,
368 lpOverlapped: ?*WSAOVERLAPPED,368 lpOverlapped: ?*WSAOVERLAPPED,
369 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,369 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
370) c_int;370) callconv(.Stdcall) c_int;
371pub extern "ws2_32" stdcallcc fn WSARecvFrom(371pub extern "ws2_32" fn WSARecvFrom(
372 s: SOCKET,372 s: SOCKET,
373 lpBuffers: [*]const WSABUF,373 lpBuffers: [*]const WSABUF,
374 dwBufferCount: DWORD,374 dwBufferCount: DWORD,
...@@ -378,8 +378,8 @@ pub extern "ws2_32" stdcallcc fn WSARecvFrom(...@@ -378,8 +378,8 @@ pub extern "ws2_32" stdcallcc fn WSARecvFrom(
378 lpFromlen: socklen_t,378 lpFromlen: socklen_t,
379 lpOverlapped: ?*WSAOVERLAPPED,379 lpOverlapped: ?*WSAOVERLAPPED,
380 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,380 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
381) c_int;381) callconv(.Stdcall) c_int;
382pub extern "ws2_32" stdcallcc fn WSASend(382pub extern "ws2_32" fn WSASend(
383 s: SOCKET,383 s: SOCKET,
384 lpBuffers: [*]WSABUF,384 lpBuffers: [*]WSABUF,
385 dwBufferCount: DWORD,385 dwBufferCount: DWORD,
...@@ -387,8 +387,8 @@ pub extern "ws2_32" stdcallcc fn WSASend(...@@ -387,8 +387,8 @@ pub extern "ws2_32" stdcallcc fn WSASend(
387 dwFlags: DWORD,387 dwFlags: DWORD,
388 lpOverlapped: ?*WSAOVERLAPPED,388 lpOverlapped: ?*WSAOVERLAPPED,
389 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,389 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
390) c_int;390) callconv(.Stdcall) c_int;
391pub extern "ws2_32" stdcallcc fn WSASendTo(391pub extern "ws2_32" fn WSASendTo(
392 s: SOCKET,392 s: SOCKET,
393 lpBuffers: [*]WSABUF,393 lpBuffers: [*]WSABUF,
394 dwBufferCount: DWORD,394 dwBufferCount: DWORD,
...@@ -398,4 +398,4 @@ pub extern "ws2_32" stdcallcc fn WSASendTo(...@@ -398,4 +398,4 @@ pub extern "ws2_32" stdcallcc fn WSASendTo(
398 iTolen: socklen_t,398 iTolen: socklen_t,
399 lpOverlapped: ?*WSAOVERLAPPED,399 lpOverlapped: ?*WSAOVERLAPPED,
400 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,400 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
401) c_int;401) callconv(.Stdcall) c_int;
lib/std/reset_event.zig+12-14
...@@ -14,13 +14,12 @@ const windows = os.windows;...@@ -14,13 +14,12 @@ const windows = os.windows;
14pub const ResetEvent = struct {14pub const ResetEvent = struct {
15 os_event: OsEvent,15 os_event: OsEvent,
1616
17 pub const OsEvent = 17 pub const OsEvent = if (builtin.single_threaded)
18 if (builtin.single_threaded)18 DebugEvent
19 DebugEvent19 else if (builtin.link_libc and builtin.os != .windows and builtin.os != .linux)
20 else if (builtin.link_libc and builtin.os != .windows and builtin.os != .linux)20 PosixEvent
21 PosixEvent21 else
22 else22 AtomicEvent;
23 AtomicEvent;
2423
25 pub fn init() ResetEvent {24 pub fn init() ResetEvent {
26 return ResetEvent{ .os_event = OsEvent.init() };25 return ResetEvent{ .os_event = OsEvent.init() };
...@@ -105,7 +104,7 @@ const PosixEvent = struct {...@@ -105,7 +104,7 @@ const PosixEvent = struct {
105 }104 }
106105
107 fn deinit(self: *PosixEvent) void {106 fn deinit(self: *PosixEvent) void {
108 // on dragonfly, *destroy() functions can return EINVAL 107 // on dragonfly, *destroy() functions can return EINVAL
109 // for statically initialized pthread structures108 // for statically initialized pthread structures
110 const err = if (builtin.os == .dragonfly) os.EINVAL else 0;109 const err = if (builtin.os == .dragonfly) os.EINVAL else 0;
111110
...@@ -212,8 +211,7 @@ const AtomicEvent = struct {...@@ -212,8 +211,7 @@ const AtomicEvent = struct {
212 fn wait(self: *AtomicEvent, timeout: ?u64) !void {211 fn wait(self: *AtomicEvent, timeout: ?u64) !void {
213 var waiters = @atomicLoad(u32, &self.waiters, .Acquire);212 var waiters = @atomicLoad(u32, &self.waiters, .Acquire);
214 while (waiters != WAKE) {213 while (waiters != WAKE) {
215 waiters = @cmpxchgWeak(u32, &self.waiters, waiters, waiters + WAIT, .Acquire, .Acquire)214 waiters = @cmpxchgWeak(u32, &self.waiters, waiters, waiters + WAIT, .Acquire, .Acquire) orelse return Futex.wait(&self.waiters, timeout);
216 orelse return Futex.wait(&self.waiters, timeout);
217 }215 }
218 }216 }
219217
...@@ -281,7 +279,7 @@ const AtomicEvent = struct {...@@ -281,7 +279,7 @@ const AtomicEvent = struct {
281 pub fn wake(waiters: *u32, wake_count: u32) void {279 pub fn wake(waiters: *u32, wake_count: u32) void {
282 const handle = getEventHandle() orelse return SpinFutex.wake(waiters, wake_count);280 const handle = getEventHandle() orelse return SpinFutex.wake(waiters, wake_count);
283 const key = @ptrCast(*const c_void, waiters);281 const key = @ptrCast(*const c_void, waiters);
284 282
285 var waiting = wake_count;283 var waiting = wake_count;
286 while (waiting != 0) : (waiting -= 1) {284 while (waiting != 0) : (waiting -= 1) {
287 const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null);285 const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null);
...@@ -408,7 +406,7 @@ test "std.ResetEvent" {...@@ -408,7 +406,7 @@ test "std.ResetEvent" {
408 // wait for receiver to update value and signal output406 // wait for receiver to update value and signal output
409 self.out.wait();407 self.out.wait();
410 testing.expect(self.value == 2);408 testing.expect(self.value == 2);
411 409
412 // update value and signal final input410 // update value and signal final input
413 self.value = 3;411 self.value = 3;
414 self.in.set();412 self.in.set();
...@@ -418,12 +416,12 @@ test "std.ResetEvent" {...@@ -418,12 +416,12 @@ test "std.ResetEvent" {
418 // wait for sender to update value and signal input416 // wait for sender to update value and signal input
419 self.in.wait();417 self.in.wait();
420 assert(self.value == 1);418 assert(self.value == 1);
421 419
422 // update value and signal output420 // update value and signal output
423 self.in.reset();421 self.in.reset();
424 self.value = 2;422 self.value = 2;
425 self.out.set();423 self.out.set();
426 424
427 // wait for sender to update value and signal final input425 // wait for sender to update value and signal final input
428 self.in.wait();426 self.in.wait();
429 assert(self.value == 3);427 assert(self.value == 3);
lib/std/special/c.zig+1-1
...@@ -195,7 +195,7 @@ extern fn __stack_chk_fail() noreturn {...@@ -195,7 +195,7 @@ extern fn __stack_chk_fail() noreturn {
195// TODO we should be able to put this directly in std/linux/x86_64.zig but195// TODO we should be able to put this directly in std/linux/x86_64.zig but
196// it causes a segfault in release mode. this is a workaround of calling it196// it causes a segfault in release mode. this is a workaround of calling it
197// across .o file boundaries. fix comptime @ptrCast of nakedcc functions.197// across .o file boundaries. fix comptime @ptrCast of nakedcc functions.
198nakedcc fn clone() void {198fn clone() callconv(.Naked) void {
199 switch (builtin.arch) {199 switch (builtin.arch) {
200 .i386 => {200 .i386 => {
201 // __clone(func, stack, flags, arg, ptid, tls, ctid)201 // __clone(func, stack, flags, arg, ptid, tls, ctid)
lib/std/special/compiler_rt.zig+5-5
...@@ -528,7 +528,7 @@ fn usesThumb1PreArmv6(arch: builtin.Arch) bool {...@@ -528,7 +528,7 @@ fn usesThumb1PreArmv6(arch: builtin.Arch) bool {
528 };528 };
529}529}
530530
531nakedcc fn __aeabi_memcpy() noreturn {531fn __aeabi_memcpy() callconv(.Naked) noreturn {
532 @setRuntimeSafety(false);532 @setRuntimeSafety(false);
533 if (use_thumb_1) {533 if (use_thumb_1) {
534 asm volatile (534 asm volatile (
...@@ -544,7 +544,7 @@ nakedcc fn __aeabi_memcpy() noreturn {...@@ -544,7 +544,7 @@ nakedcc fn __aeabi_memcpy() noreturn {
544 unreachable;544 unreachable;
545}545}
546546
547nakedcc fn __aeabi_memmove() noreturn {547fn __aeabi_memmove() callconv(.Naked) noreturn {
548 @setRuntimeSafety(false);548 @setRuntimeSafety(false);
549 if (use_thumb_1) {549 if (use_thumb_1) {
550 asm volatile (550 asm volatile (
...@@ -560,7 +560,7 @@ nakedcc fn __aeabi_memmove() noreturn {...@@ -560,7 +560,7 @@ nakedcc fn __aeabi_memmove() noreturn {
560 unreachable;560 unreachable;
561}561}
562562
563nakedcc fn __aeabi_memset() noreturn {563fn __aeabi_memset() callconv(.Naked) noreturn {
564 @setRuntimeSafety(false);564 @setRuntimeSafety(false);
565 if (use_thumb_1_pre_armv6) {565 if (use_thumb_1_pre_armv6) {
566 asm volatile (566 asm volatile (
...@@ -591,7 +591,7 @@ nakedcc fn __aeabi_memset() noreturn {...@@ -591,7 +591,7 @@ nakedcc fn __aeabi_memset() noreturn {
591 unreachable;591 unreachable;
592}592}
593593
594nakedcc fn __aeabi_memclr() noreturn {594fn __aeabi_memclr() callconv(.Naked) noreturn {
595 @setRuntimeSafety(false);595 @setRuntimeSafety(false);
596 if (use_thumb_1_pre_armv6) {596 if (use_thumb_1_pre_armv6) {
597 asm volatile (597 asm volatile (
...@@ -619,7 +619,7 @@ nakedcc fn __aeabi_memclr() noreturn {...@@ -619,7 +619,7 @@ nakedcc fn __aeabi_memclr() noreturn {
619 unreachable;619 unreachable;
620}620}
621621
622nakedcc fn __aeabi_memcmp() noreturn {622fn __aeabi_memcmp() callconv(.Naked) noreturn {
623 @setRuntimeSafety(false);623 @setRuntimeSafety(false);
624 if (use_thumb_1) {624 if (use_thumb_1) {
625 asm volatile (625 asm volatile (
lib/std/special/compiler_rt/arm/aeabi_dcmp.zig+5-5
...@@ -12,31 +12,31 @@ const ConditionalOperator = enum {...@@ -12,31 +12,31 @@ const ConditionalOperator = enum {
12 Gt,12 Gt,
13};13};
1414
15pub nakedcc fn __aeabi_dcmpeq() noreturn {15pub fn __aeabi_dcmpeq() callconv(.Naked) noreturn {
16 @setRuntimeSafety(false);16 @setRuntimeSafety(false);
17 @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Eq});17 @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Eq});
18 unreachable;18 unreachable;
19}19}
2020
21pub nakedcc fn __aeabi_dcmplt() noreturn {21pub fn __aeabi_dcmplt() callconv(.Naked) noreturn {
22 @setRuntimeSafety(false);22 @setRuntimeSafety(false);
23 @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Lt});23 @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Lt});
24 unreachable;24 unreachable;
25}25}
2626
27pub nakedcc fn __aeabi_dcmple() noreturn {27pub fn __aeabi_dcmple() callconv(.Naked) noreturn {
28 @setRuntimeSafety(false);28 @setRuntimeSafety(false);
29 @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Le});29 @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Le});
30 unreachable;30 unreachable;
31}31}
3232
33pub nakedcc fn __aeabi_dcmpge() noreturn {33pub fn __aeabi_dcmpge() callconv(.Naked) noreturn {
34 @setRuntimeSafety(false);34 @setRuntimeSafety(false);
35 @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Ge});35 @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Ge});
36 unreachable;36 unreachable;
37}37}
3838
39pub nakedcc fn __aeabi_dcmpgt() noreturn {39pub fn __aeabi_dcmpgt() callconv(.Naked) noreturn {
40 @setRuntimeSafety(false);40 @setRuntimeSafety(false);
41 @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Gt});41 @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Gt});
42 unreachable;42 unreachable;
lib/std/special/compiler_rt/arm/aeabi_fcmp.zig+5-5
...@@ -12,31 +12,31 @@ const ConditionalOperator = enum {...@@ -12,31 +12,31 @@ const ConditionalOperator = enum {
12 Gt,12 Gt,
13};13};
1414
15pub nakedcc fn __aeabi_fcmpeq() noreturn {15pub fn __aeabi_fcmpeq() callconv(.Naked) noreturn {
16 @setRuntimeSafety(false);16 @setRuntimeSafety(false);
17 @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Eq});17 @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Eq});
18 unreachable;18 unreachable;
19}19}
2020
21pub nakedcc fn __aeabi_fcmplt() noreturn {21pub fn __aeabi_fcmplt() callconv(.Naked) noreturn {
22 @setRuntimeSafety(false);22 @setRuntimeSafety(false);
23 @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Lt});23 @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Lt});
24 unreachable;24 unreachable;
25}25}
2626
27pub nakedcc fn __aeabi_fcmple() noreturn {27pub fn __aeabi_fcmple() callconv(.Naked) noreturn {
28 @setRuntimeSafety(false);28 @setRuntimeSafety(false);
29 @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Le});29 @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Le});
30 unreachable;30 unreachable;
31}31}
3232
33pub nakedcc fn __aeabi_fcmpge() noreturn {33pub fn __aeabi_fcmpge() callconv(.Naked) noreturn {
34 @setRuntimeSafety(false);34 @setRuntimeSafety(false);
35 @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Ge});35 @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Ge});
36 unreachable;36 unreachable;
37}37}
3838
39pub nakedcc fn __aeabi_fcmpgt() noreturn {39pub fn __aeabi_fcmpgt() callconv(.Naked) noreturn {
40 @setRuntimeSafety(false);40 @setRuntimeSafety(false);
41 @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Gt});41 @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Gt});
42 unreachable;42 unreachable;
lib/std/special/compiler_rt/aulldiv.zig+2-2
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
22
3pub extern stdcallcc fn _alldiv(a: i64, b: i64) i64 {3pub extern fn _alldiv(a: i64, b: i64) callconv(.Stdcall) i64 {
4 @setRuntimeSafety(builtin.is_test);4 @setRuntimeSafety(builtin.is_test);
5 const s_a = a >> (i64.bit_count - 1);5 const s_a = a >> (i64.bit_count - 1);
6 const s_b = b >> (i64.bit_count - 1);6 const s_b = b >> (i64.bit_count - 1);
...@@ -13,7 +13,7 @@ pub extern stdcallcc fn _alldiv(a: i64, b: i64) i64 {...@@ -13,7 +13,7 @@ pub extern stdcallcc fn _alldiv(a: i64, b: i64) i64 {
13 return (@bitCast(i64, r) ^ s) -% s;13 return (@bitCast(i64, r) ^ s) -% s;
14}14}
1515
16pub nakedcc fn _aulldiv() void {16pub fn _aulldiv() callconv(.Naked) void {
17 @setRuntimeSafety(false);17 @setRuntimeSafety(false);
1818
19 // The stack layout is:19 // The stack layout is:
lib/std/special/compiler_rt/aullrem.zig+2-2
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
22
3pub extern stdcallcc fn _allrem(a: i64, b: i64) i64 {3pub extern fn _allrem(a: i64, b: i64) callconv(.Stdcall) i64 {
4 @setRuntimeSafety(builtin.is_test);4 @setRuntimeSafety(builtin.is_test);
5 const s_a = a >> (i64.bit_count - 1);5 const s_a = a >> (i64.bit_count - 1);
6 const s_b = b >> (i64.bit_count - 1);6 const s_b = b >> (i64.bit_count - 1);
...@@ -13,7 +13,7 @@ pub extern stdcallcc fn _allrem(a: i64, b: i64) i64 {...@@ -13,7 +13,7 @@ pub extern stdcallcc fn _allrem(a: i64, b: i64) i64 {
13 return (@bitCast(i64, r) ^ s) -% s;13 return (@bitCast(i64, r) ^ s) -% s;
14}14}
1515
16pub nakedcc fn _aullrem() void {16pub fn _aullrem() callconv(.Naked) void {
17 @setRuntimeSafety(false);17 @setRuntimeSafety(false);
1818
19 // The stack layout is:19 // The stack layout is:
lib/std/special/compiler_rt/stack_probe.zig+6-6
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
22
3// Zig's own stack-probe routine (available only on x86 and x86_64)3// Zig's own stack-probe routine (available only on x86 and x86_64)
4pub nakedcc fn zig_probe_stack() void {4pub fn zig_probe_stack() callconv(.Naked) void {
5 @setRuntimeSafety(false);5 @setRuntimeSafety(false);
66
7 // Versions of the Linux kernel before 5.1 treat any access below SP as7 // Versions of the Linux kernel before 5.1 treat any access below SP as
...@@ -180,11 +180,11 @@ fn win_probe_stack_adjust_sp() void {...@@ -180,11 +180,11 @@ fn win_probe_stack_adjust_sp() void {
180// ___chkstk (__alloca) | yes | yes |180// ___chkstk (__alloca) | yes | yes |
181// ___chkstk_ms | no | no |181// ___chkstk_ms | no | no |
182182
183pub nakedcc fn _chkstk() void {183pub fn _chkstk() callconv(.Naked) void {
184 @setRuntimeSafety(false);184 @setRuntimeSafety(false);
185 @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{});185 @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{});
186}186}
187pub nakedcc fn __chkstk() void {187pub fn __chkstk() callconv(.Naked) void {
188 @setRuntimeSafety(false);188 @setRuntimeSafety(false);
189 switch (builtin.arch) {189 switch (builtin.arch) {
190 .i386 => @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}),190 .i386 => @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}),
...@@ -192,15 +192,15 @@ pub nakedcc fn __chkstk() void {...@@ -192,15 +192,15 @@ pub nakedcc fn __chkstk() void {
192 else => unreachable,192 else => unreachable,
193 }193 }
194}194}
195pub nakedcc fn ___chkstk() void {195pub fn ___chkstk() callconv(.Naked) void {
196 @setRuntimeSafety(false);196 @setRuntimeSafety(false);
197 @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{});197 @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{});
198}198}
199pub nakedcc fn __chkstk_ms() void {199pub fn __chkstk_ms() callconv(.Naked) void {
200 @setRuntimeSafety(false);200 @setRuntimeSafety(false);
201 @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{});201 @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{});
202}202}
203pub nakedcc fn ___chkstk_ms() void {203pub fn ___chkstk_ms() callconv(.Naked) void {
204 @setRuntimeSafety(false);204 @setRuntimeSafety(false);
205 @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{});205 @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{});
206}206}
lib/std/spinlock.zig+10-2
...@@ -60,8 +60,16 @@ pub const SpinLock = struct {...@@ -60,8 +60,16 @@ pub const SpinLock = struct {
60 switch (builtin.arch) {60 switch (builtin.arch) {
61 // these instructions use a memory clobber as they61 // these instructions use a memory clobber as they
62 // flush the pipeline of any speculated reads/writes.62 // flush the pipeline of any speculated reads/writes.
63 .i386, .x86_64 => asm volatile ("pause" ::: "memory"),63 .i386, .x86_64 => asm volatile ("pause"
64 .arm, .aarch64 => asm volatile ("yield" ::: "memory"),64 :
65 :
66 : "memory"
67 ),
68 .arm, .aarch64 => asm volatile ("yield"
69 :
70 :
71 : "memory"
72 ),
65 else => std.os.sched_yield() catch {},73 else => std.os.sched_yield() catch {},
66 }74 }
67 }75 }
lib/std/start.zig+4-4
...@@ -43,11 +43,11 @@ comptime {...@@ -43,11 +43,11 @@ comptime {
43 }43 }
44}44}
4545
46stdcallcc fn _DllMainCRTStartup(46fn _DllMainCRTStartup(
47 hinstDLL: std.os.windows.HINSTANCE,47 hinstDLL: std.os.windows.HINSTANCE,
48 fdwReason: std.os.windows.DWORD,48 fdwReason: std.os.windows.DWORD,
49 lpReserved: std.os.windows.LPVOID,49 lpReserved: std.os.windows.LPVOID,
50) std.os.windows.BOOL {50) callconv(.Stdcall) std.os.windows.BOOL {
51 if (@hasDecl(root, "DllMain")) {51 if (@hasDecl(root, "DllMain")) {
52 return root.DllMain(hinstDLL, fdwReason, lpReserved);52 return root.DllMain(hinstDLL, fdwReason, lpReserved);
53 }53 }
...@@ -84,7 +84,7 @@ extern fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) u...@@ -84,7 +84,7 @@ extern fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) u
84 }84 }
85}85}
8686
87nakedcc fn _start() noreturn {87fn _start() callconv(.Naked) noreturn {
88 if (builtin.os == builtin.Os.wasi) {88 if (builtin.os == builtin.Os.wasi) {
89 // This is marked inline because for some reason LLVM in release mode fails to inline it,89 // This is marked inline because for some reason LLVM in release mode fails to inline it,
90 // and we want fewer call frames in stack traces.90 // and we want fewer call frames in stack traces.
...@@ -127,7 +127,7 @@ nakedcc fn _start() noreturn {...@@ -127,7 +127,7 @@ nakedcc fn _start() noreturn {
127 @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});127 @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
128}128}
129129
130stdcallcc fn WinMainCRTStartup() noreturn {130fn WinMainCRTStartup() callconv(.Stdcall) noreturn {
131 @setAlignStack(16);131 @setAlignStack(16);
132 if (!builtin.single_threaded) {132 if (!builtin.single_threaded) {
133 _ = @import("start_windows_tls.zig");133 _ = @import("start_windows_tls.zig");
lib/std/zig/ast.zig+1
...@@ -860,6 +860,7 @@ pub const Node = struct {...@@ -860,6 +860,7 @@ pub const Node = struct {
860 lib_name: ?*Node, // populated if this is an extern declaration860 lib_name: ?*Node, // populated if this is an extern declaration
861 align_expr: ?*Node, // populated if align(A) is present861 align_expr: ?*Node, // populated if align(A) is present
862 section_expr: ?*Node, // populated if linksection(A) is present862 section_expr: ?*Node, // populated if linksection(A) is present
863 callconv_expr: ?*Node, // populated if callconv(A) is present
863864
864 pub const ParamList = SegmentedList(*Node, 2);865 pub const ParamList = SegmentedList(*Node, 2);
865866
lib/std/zig/parse.zig+13
...@@ -311,6 +311,7 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -311,6 +311,7 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
311 const rparen = try expectToken(it, tree, .RParen);311 const rparen = try expectToken(it, tree, .RParen);
312 const align_expr = try parseByteAlign(arena, it, tree);312 const align_expr = try parseByteAlign(arena, it, tree);
313 const section_expr = try parseLinkSection(arena, it, tree);313 const section_expr = try parseLinkSection(arena, it, tree);
314 const callconv_expr = try parseCallconv(arena, it, tree);
314 const exclamation_token = eatToken(it, .Bang);315 const exclamation_token = eatToken(it, .Bang);
315316
316 const return_type_expr = (try parseVarType(arena, it, tree)) orelse317 const return_type_expr = (try parseVarType(arena, it, tree)) orelse
...@@ -347,6 +348,7 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -347,6 +348,7 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
347 .lib_name = null,348 .lib_name = null,
348 .align_expr = align_expr,349 .align_expr = align_expr,
349 .section_expr = section_expr,350 .section_expr = section_expr,
351 .callconv_expr = callconv_expr,
350 };352 };
351353
352 if (cc) |kind| {354 if (cc) |kind| {
...@@ -1678,6 +1680,17 @@ fn parseLinkSection(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -1678,6 +1680,17 @@ fn parseLinkSection(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
1678 return expr_node;1680 return expr_node;
1679}1681}
16801682
1683/// CallConv <- KEYWORD_callconv LPAREN Expr RPAREN
1684fn parseCallconv(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1685 _ = eatToken(it, .Keyword_callconv) orelse return null;
1686 _ = try expectToken(it, tree, .LParen);
1687 const expr_node = try expectNode(arena, it, tree, parseExpr, AstError{
1688 .ExpectedExpr = AstError.ExpectedExpr{ .token = it.index },
1689 });
1690 _ = try expectToken(it, tree, .RParen);
1691 return expr_node;
1692}
1693
1681/// FnCC1694/// FnCC
1682/// <- KEYWORD_nakedcc1695/// <- KEYWORD_nakedcc
1683/// / KEYWORD_stdcallcc1696/// / KEYWORD_stdcallcc
lib/std/zig/parser_test.zig+2-2
...@@ -219,7 +219,7 @@ test "zig fmt: threadlocal" {...@@ -219,7 +219,7 @@ test "zig fmt: threadlocal" {
219test "zig fmt: linksection" {219test "zig fmt: linksection" {
220 try testCanonical(220 try testCanonical(
221 \\export var aoeu: u64 linksection(".text.derp") = 1234;221 \\export var aoeu: u64 linksection(".text.derp") = 1234;
222 \\export nakedcc fn _start() linksection(".text.boot") noreturn {}222 \\export fn _start() linksection(".text.boot") callconv(.Naked) noreturn {}
223 \\223 \\
224 );224 );
225}225}
...@@ -2311,7 +2311,7 @@ test "zig fmt: fn type" {...@@ -2311,7 +2311,7 @@ test "zig fmt: fn type" {
2311 \\2311 \\
2312 \\const a: fn (u8) u8 = undefined;2312 \\const a: fn (u8) u8 = undefined;
2313 \\const b: extern fn (u8) u8 = undefined;2313 \\const b: extern fn (u8) u8 = undefined;
2314 \\const c: nakedcc fn (u8) u8 = undefined;2314 \\const c: fn (u8) callconv(.Naked) u8 = undefined;
2315 \\const ap: fn (u8) u8 = a;2315 \\const ap: fn (u8) u8 = a;
2316 \\2316 \\
2317 );2317 );
lib/std/zig/render.zig+24-1
...@@ -1295,8 +1295,16 @@ fn renderExpression(...@@ -1295,8 +1295,16 @@ fn renderExpression(
1295 try renderExpression(allocator, stream, tree, indent, start_col, lib_name, Space.Space);1295 try renderExpression(allocator, stream, tree, indent, start_col, lib_name, Space.Space);
1296 }1296 }
12971297
1298 // Some extra machinery is needed to rewrite the old-style cc
1299 // notation to the new callconv one
1300 var cc_rewrite_str: ?[*:0]const u8 = null;
1298 if (fn_proto.cc_token) |cc_token| {1301 if (fn_proto.cc_token) |cc_token| {
1299 try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc1302 var str = tree.tokenSlicePtr(tree.tokens.at(cc_token));
1303 if (mem.eql(u8, str, "stdcallcc")) {
1304 cc_rewrite_str = ".Stdcall";
1305 } else if (mem.eql(u8, str, "nakedcc")) {
1306 cc_rewrite_str = ".Naked";
1307 } else try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc
1300 }1308 }
13011309
1302 const lparen = if (fn_proto.name_token) |name_token| blk: {1310 const lparen = if (fn_proto.name_token) |name_token| blk: {
...@@ -1368,6 +1376,21 @@ fn renderExpression(...@@ -1368,6 +1376,21 @@ fn renderExpression(
1368 try renderToken(tree, stream, section_rparen, indent, start_col, Space.Space); // )1376 try renderToken(tree, stream, section_rparen, indent, start_col, Space.Space); // )
1369 }1377 }
13701378
1379 if (fn_proto.callconv_expr) |callconv_expr| {
1380 const section_rparen = tree.nextToken(callconv_expr.lastToken());
1381 const section_lparen = tree.prevToken(callconv_expr.firstToken());
1382 const section_kw = tree.prevToken(section_lparen);
1383
1384 try renderToken(tree, stream, section_kw, indent, start_col, Space.None); // section
1385 try renderToken(tree, stream, section_lparen, indent, start_col, Space.None); // (
1386 try renderExpression(allocator, stream, tree, indent, start_col, callconv_expr, Space.None);
1387 try renderToken(tree, stream, section_rparen, indent, start_col, Space.Space); // )
1388 } else if (cc_rewrite_str) |str| {
1389 try stream.write("callconv(");
1390 try stream.write(mem.toSliceConst(u8, str));
1391 try stream.write(") ");
1392 }
1393
1371 switch (fn_proto.return_type) {1394 switch (fn_proto.return_type) {
1372 ast.Node.FnProto.ReturnType.Explicit => |node| {1395 ast.Node.FnProto.ReturnType.Explicit => |node| {
1373 return renderExpression(allocator, stream, tree, indent, start_col, node, space);1396 return renderExpression(allocator, stream, tree, indent, start_col, node, space);
lib/std/zig/tokenizer.zig+3
...@@ -30,6 +30,7 @@ pub const Token = struct {...@@ -30,6 +30,7 @@ pub const Token = struct {
30 Keyword.init("async", .Keyword_async),30 Keyword.init("async", .Keyword_async),
31 Keyword.init("await", .Keyword_await),31 Keyword.init("await", .Keyword_await),
32 Keyword.init("break", .Keyword_break),32 Keyword.init("break", .Keyword_break),
33 Keyword.init("callconv", .Keyword_callconv),
33 Keyword.init("catch", .Keyword_catch),34 Keyword.init("catch", .Keyword_catch),
34 Keyword.init("comptime", .Keyword_comptime),35 Keyword.init("comptime", .Keyword_comptime),
35 Keyword.init("const", .Keyword_const),36 Keyword.init("const", .Keyword_const),
...@@ -162,6 +163,7 @@ pub const Token = struct {...@@ -162,6 +163,7 @@ pub const Token = struct {
162 Keyword_async,163 Keyword_async,
163 Keyword_await,164 Keyword_await,
164 Keyword_break,165 Keyword_break,
166 Keyword_callconv,
165 Keyword_catch,167 Keyword_catch,
166 Keyword_comptime,168 Keyword_comptime,
167 Keyword_const,169 Keyword_const,
...@@ -286,6 +288,7 @@ pub const Token = struct {...@@ -286,6 +288,7 @@ pub const Token = struct {
286 .Keyword_async => "async",288 .Keyword_async => "async",
287 .Keyword_await => "await",289 .Keyword_await => "await",
288 .Keyword_break => "break",290 .Keyword_break => "break",
291 .Keyword_callconv => "callconv",
289 .Keyword_catch => "catch",292 .Keyword_catch => "catch",
290 .Keyword_comptime => "comptime",293 .Keyword_comptime => "comptime",
291 .Keyword_const => "const",294 .Keyword_const => "const",
src-self-hosted/translate_c.zig+4-1
...@@ -11,7 +11,7 @@ const CToken = ctok.CToken;...@@ -11,7 +11,7 @@ const CToken = ctok.CToken;
11const mem = std.mem;11const mem = std.mem;
12const math = std.math;12const math = std.math;
1313
14const CallingConvention = std.builtin.TypeInfo.CallingConvention;14const CallingConvention = std.builtin.CallingConvention;
1515
16pub const ClangErrMsg = Stage2ErrorMsg;16pub const ClangErrMsg = Stage2ErrorMsg;
1717
...@@ -3529,6 +3529,7 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a...@@ -3529,6 +3529,7 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a
3529 .lib_name = null,3529 .lib_name = null,
3530 .align_expr = null,3530 .align_expr = null,
3531 .section_expr = null,3531 .section_expr = null,
3532 .callconv_expr = null,
3532 };3533 };
35333534
3534 const block = try transCreateNodeBlock(c, null);3535 const block = try transCreateNodeBlock(c, null);
...@@ -4135,6 +4136,7 @@ fn finishTransFnProto(...@@ -4135,6 +4136,7 @@ fn finishTransFnProto(
4135 .lib_name = null,4136 .lib_name = null,
4136 .align_expr = null,4137 .align_expr = null,
4137 .section_expr = null,4138 .section_expr = null,
4139 .callconv_expr = null,
4138 };4140 };
4139 return fn_proto;4141 return fn_proto;
4140}4142}
...@@ -4483,6 +4485,7 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u...@@ -4483,6 +4485,7 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u
4483 .lib_name = null,4485 .lib_name = null,
4484 .align_expr = null,4486 .align_expr = null,
4485 .section_expr = null,4487 .section_expr = null,
4488 .callconv_expr = null,
4486 };4489 };
44874490
4488 const block = try transCreateNodeBlock(c, null);4491 const block = try transCreateNodeBlock(c, null);
src-self-hosted/type.zig+2-1
...@@ -337,7 +337,7 @@ pub const Type = struct {...@@ -337,7 +337,7 @@ pub const Type = struct {
337 }337 }
338 };338 };
339339
340 const CallingConvention = builtin.TypeInfo.CallingConvention;340 const CallingConvention = builtin.CallingConvention;
341341
342 pub const Param = struct {342 pub const Param = struct {
343 is_noalias: bool,343 is_noalias: bool,
...@@ -352,6 +352,7 @@ pub const Type = struct {...@@ -352,6 +352,7 @@ pub const Type = struct {
352 .Naked => "nakedcc ",352 .Naked => "nakedcc ",
353 .Stdcall => "stdcallcc ",353 .Stdcall => "stdcallcc ",
354 .Async => "async ",354 .Async => "async ",
355 else => unreachable,
355 };356 };
356 }357 }
357358
src/all_types.hpp+24-10
...@@ -57,6 +57,22 @@ enum PtrLen {...@@ -57,6 +57,22 @@ enum PtrLen {
57 PtrLenC,57 PtrLenC,
58};58};
5959
60enum CallingConvention {
61 CallingConventionUnspecified,
62 CallingConventionC,
63 CallingConventionCold,
64 CallingConventionNaked,
65 CallingConventionAsync,
66 CallingConventionInterrupt,
67 CallingConventionSignal,
68 CallingConventionStdcall,
69 CallingConventionFastcall,
70 CallingConventionVectorcall,
71 CallingConventionAPCS,
72 CallingConventionAAPCS,
73 CallingConventionAAPCSVFP,
74};
75
60// This one corresponds to the builtin.zig enum.76// This one corresponds to the builtin.zig enum.
61enum BuiltinPtrSize {77enum BuiltinPtrSize {
62 BuiltinPtrSizeOne,78 BuiltinPtrSizeOne,
...@@ -398,6 +414,7 @@ struct LazyValueFnType {...@@ -398,6 +414,7 @@ struct LazyValueFnType {
398 IrInstruction *align_inst; // can be null414 IrInstruction *align_inst; // can be null
399 IrInstruction *return_type;415 IrInstruction *return_type;
400416
417 CallingConvention cc;
401 bool is_generic;418 bool is_generic;
402};419};
403420
...@@ -612,15 +629,6 @@ enum NodeType {...@@ -612,15 +629,6 @@ enum NodeType {
612 NodeTypeVarFieldType,629 NodeTypeVarFieldType,
613};630};
614631
615enum CallingConvention {
616 CallingConventionUnspecified,
617 CallingConventionC,
618 CallingConventionCold,
619 CallingConventionNaked,
620 CallingConventionStdcall,
621 CallingConventionAsync,
622};
623
624enum FnInline {632enum FnInline {
625 FnInlineAuto,633 FnInlineAuto,
626 FnInlineAlways,634 FnInlineAlways,
...@@ -639,10 +647,14 @@ struct AstNodeFnProto {...@@ -639,10 +647,14 @@ struct AstNodeFnProto {
639 AstNode *align_expr;647 AstNode *align_expr;
640 // populated if the "section(S)" is present648 // populated if the "section(S)" is present
641 AstNode *section_expr;649 AstNode *section_expr;
650 // populated if the "callconv(S)" is present
651 AstNode *callconv_expr;
642 Buf doc_comments;652 Buf doc_comments;
643653
644 FnInline fn_inline;654 FnInline fn_inline;
645 CallingConvention cc;655 bool is_nakedcc;
656 bool is_stdcallcc;
657 bool is_async;
646658
647 VisibMod visib_mod;659 VisibMod visib_mod;
648 bool auto_err_set;660 bool auto_err_set;
...@@ -1597,6 +1609,7 @@ struct ZigFn {...@@ -1597,6 +1609,7 @@ struct ZigFn {
1597 Buf **param_names;1609 Buf **param_names;
1598 IrInstruction *err_code_spill;1610 IrInstruction *err_code_spill;
1599 AstNode *assumed_non_async;1611 AstNode *assumed_non_async;
1612 CallingConvention cc;
16001613
1601 AstNode *fn_no_inline_set_node;1614 AstNode *fn_no_inline_set_node;
1602 AstNode *fn_static_eval_set_node;1615 AstNode *fn_static_eval_set_node;
...@@ -3549,6 +3562,7 @@ struct IrInstructionFnProto {...@@ -3549,6 +3562,7 @@ struct IrInstructionFnProto {
35493562
3550 IrInstruction **param_types;3563 IrInstruction **param_types;
3551 IrInstruction *align_value;3564 IrInstruction *align_value;
3565 IrInstruction *callconv_value;
3552 IrInstruction *return_type;3566 IrInstruction *return_type;
3553 bool is_var_args;3567 bool is_var_args;
3554};3568};
src/analyze.cpp+99-55
...@@ -919,24 +919,19 @@ ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry) {...@@ -919,24 +919,19 @@ ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry) {
919919
920const char *calling_convention_name(CallingConvention cc) {920const char *calling_convention_name(CallingConvention cc) {
921 switch (cc) {921 switch (cc) {
922 case CallingConventionUnspecified: return "undefined";922 case CallingConventionUnspecified: return "Unspecified";
923 case CallingConventionC: return "ccc";923 case CallingConventionC: return "C";
924 case CallingConventionCold: return "coldcc";924 case CallingConventionCold: return "Cold";
925 case CallingConventionNaked: return "nakedcc";925 case CallingConventionNaked: return "Naked";
926 case CallingConventionStdcall: return "stdcallcc";926 case CallingConventionAsync: return "Async";
927 case CallingConventionAsync: return "async";927 case CallingConventionInterrupt: return "Interrupt";
928 }928 case CallingConventionSignal: return "Signal";
929 zig_unreachable();929 case CallingConventionStdcall: return "Stdcall";
930}930 case CallingConventionFastcall: return "Fastcall";
931931 case CallingConventionVectorcall: return "Vectorcall";
932static const char *calling_convention_fn_type_str(CallingConvention cc) {932 case CallingConventionAPCS: return "Apcs";
933 switch (cc) {933 case CallingConventionAAPCS: return "Aapcs";
934 case CallingConventionUnspecified: return "";934 case CallingConventionAAPCSVFP: return "Aapcsvfp";
935 case CallingConventionC: return "extern ";
936 case CallingConventionCold: return "coldcc ";
937 case CallingConventionNaked: return "nakedcc ";
938 case CallingConventionStdcall: return "stdcallcc ";
939 case CallingConventionAsync: return "async ";
940 }935 }
941 zig_unreachable();936 zig_unreachable();
942}937}
...@@ -949,7 +944,14 @@ bool calling_convention_allows_zig_types(CallingConvention cc) {...@@ -949,7 +944,14 @@ bool calling_convention_allows_zig_types(CallingConvention cc) {
949 case CallingConventionC:944 case CallingConventionC:
950 case CallingConventionCold:945 case CallingConventionCold:
951 case CallingConventionNaked:946 case CallingConventionNaked:
947 case CallingConventionInterrupt:
948 case CallingConventionSignal:
952 case CallingConventionStdcall:949 case CallingConventionStdcall:
950 case CallingConventionFastcall:
951 case CallingConventionVectorcall:
952 case CallingConventionAPCS:
953 case CallingConventionAAPCS:
954 case CallingConventionAAPCSVFP:
953 return false;955 return false;
954 }956 }
955 zig_unreachable();957 zig_unreachable();
...@@ -1006,8 +1008,8 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -1006,8 +1008,8 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
10061008
1007 // populate the name of the type1009 // populate the name of the type
1008 buf_resize(&fn_type->name, 0);1010 buf_resize(&fn_type->name, 0);
1009 const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc);1011 if (fn_type->data.fn.fn_type_id.cc == CallingConventionC)
1010 buf_appendf(&fn_type->name, "%s", cc_str);1012 buf_append_str(&fn_type->name, "extern ");
1011 buf_appendf(&fn_type->name, "fn(");1013 buf_appendf(&fn_type->name, "fn(");
1012 for (size_t i = 0; i < fn_type_id->param_count; i += 1) {1014 for (size_t i = 0; i < fn_type_id->param_count; i += 1) {
1013 FnTypeParamInfo *param_info = &fn_type_id->param_info[i];1015 FnTypeParamInfo *param_info = &fn_type_id->param_info[i];
...@@ -1026,6 +1028,9 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -1026,6 +1028,9 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
1026 if (fn_type_id->alignment != 0) {1028 if (fn_type_id->alignment != 0) {
1027 buf_appendf(&fn_type->name, " align(%" PRIu32 ")", fn_type_id->alignment);1029 buf_appendf(&fn_type->name, " align(%" PRIu32 ")", fn_type_id->alignment);
1028 }1030 }
1031 if (fn_type_id->cc != CallingConventionUnspecified && fn_type_id->cc != CallingConventionC) {
1032 buf_appendf(&fn_type->name, " callconv(%s)", calling_convention_name(fn_type_id->cc));
1033 }
1029 buf_appendf(&fn_type->name, " %s", buf_ptr(&fn_type_id->return_type->name));1034 buf_appendf(&fn_type->name, " %s", buf_ptr(&fn_type_id->return_type->name));
10301035
1031 // The fn_type is a pointer; not to be confused with the raw function type.1036 // The fn_type is a pointer; not to be confused with the raw function type.
...@@ -1442,8 +1447,8 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {...@@ -1442,8 +1447,8 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
1442ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {1447ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
1443 ZigType *fn_type = new_type_table_entry(ZigTypeIdFn);1448 ZigType *fn_type = new_type_table_entry(ZigTypeIdFn);
1444 buf_resize(&fn_type->name, 0);1449 buf_resize(&fn_type->name, 0);
1445 const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc);1450 if (fn_type->data.fn.fn_type_id.cc == CallingConventionC)
1446 buf_appendf(&fn_type->name, "%s", cc_str);1451 buf_append_str(&fn_type->name, "extern ");
1447 buf_appendf(&fn_type->name, "fn(");1452 buf_appendf(&fn_type->name, "fn(");
1448 size_t i = 0;1453 size_t i = 0;
1449 for (; i < fn_type_id->next_param_index; i += 1) {1454 for (; i < fn_type_id->next_param_index; i += 1) {
...@@ -1455,7 +1460,11 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -1455,7 +1460,11 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
1455 const char *comma_str = (i == 0) ? "" : ",";1460 const char *comma_str = (i == 0) ? "" : ",";
1456 buf_appendf(&fn_type->name, "%svar", comma_str);1461 buf_appendf(&fn_type->name, "%svar", comma_str);
1457 }1462 }
1458 buf_appendf(&fn_type->name, ")var");1463 buf_append_str(&fn_type->name, ")");
1464 if (fn_type_id->cc != CallingConventionUnspecified && fn_type_id->cc != CallingConventionC) {
1465 buf_appendf(&fn_type->name, " callconv(%s)", calling_convention_name(fn_type_id->cc));
1466 }
1467 buf_append_str(&fn_type->name, " var");
14591468
1460 fn_type->data.fn.fn_type_id = *fn_type_id;1469 fn_type->data.fn.fn_type_id = *fn_type_id;
1461 fn_type->data.fn.is_generic = true;1470 fn_type->data.fn.is_generic = true;
...@@ -1465,17 +1474,25 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -1465,17 +1474,25 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
1465 return fn_type;1474 return fn_type;
1466}1475}
14671476
1468void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc) {1477CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto) {
1478 if (fn_proto->is_nakedcc)
1479 return CallingConventionNaked;
1480 if (fn_proto->is_stdcallcc)
1481 return CallingConventionStdcall;
1482 if (fn_proto->is_async)
1483 return CallingConventionAsync;
1484 // Compatible with the C ABI
1485 if (fn_proto->is_extern || fn_proto->is_export)
1486 return CallingConventionC;
1487
1488 return CallingConventionUnspecified;
1489}
1490
1491void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, CallingConvention cc, size_t param_count_alloc) {
1469 assert(proto_node->type == NodeTypeFnProto);1492 assert(proto_node->type == NodeTypeFnProto);
1470 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;1493 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
14711494
1472 if (fn_proto->cc == CallingConventionUnspecified) {1495 fn_type_id->cc = cc;
1473 bool extern_abi = fn_proto->is_extern || fn_proto->is_export;
1474 fn_type_id->cc = extern_abi ? CallingConventionC : CallingConventionUnspecified;
1475 } else {
1476 fn_type_id->cc = fn_proto->cc;
1477 }
1478
1479 fn_type_id->param_count = fn_proto->params.length;1496 fn_type_id->param_count = fn_proto->params.length;
1480 fn_type_id->param_info = allocate<FnTypeParamInfo>(param_count_alloc);1497 fn_type_id->param_info = allocate<FnTypeParamInfo>(param_count_alloc);
1481 fn_type_id->next_param_index = 0;1498 fn_type_id->next_param_index = 0;
...@@ -1690,7 +1707,8 @@ Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result) {...@@ -1690,7 +1707,8 @@ Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result) {
1690 return type_allowed_in_extern(g, type_entry->data.array.child_type, result);1707 return type_allowed_in_extern(g, type_entry->data.array.child_type, result);
1691 case ZigTypeIdFn:1708 case ZigTypeIdFn:
1692 *result = type_entry->data.fn.fn_type_id.cc == CallingConventionC ||1709 *result = type_entry->data.fn.fn_type_id.cc == CallingConventionC ||
1693 type_entry->data.fn.fn_type_id.cc == CallingConventionStdcall;1710 type_entry->data.fn.fn_type_id.cc == CallingConventionStdcall ||
1711 type_entry->data.fn.fn_type_id.cc == CallingConventionAAPCS;
1694 return ErrorNone;1712 return ErrorNone;
1695 case ZigTypeIdPointer:1713 case ZigTypeIdPointer:
1696 if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))1714 if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
...@@ -1750,7 +1768,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc...@@ -1750,7 +1768,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
1750 Error err;1768 Error err;
17511769
1752 FnTypeId fn_type_id = {0};1770 FnTypeId fn_type_id = {0};
1753 init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length);1771 init_fn_type_id(&fn_type_id, proto_node, fn_entry->cc, proto_node->data.fn_proto.params.length);
17541772
1755 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) {1773 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) {
1756 AstNode *param_node = fn_proto->params.at(fn_type_id.next_param_index);1774 AstNode *param_node = fn_proto->params.at(fn_type_id.next_param_index);
...@@ -3393,27 +3411,6 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -3393,27 +3411,6 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
3393 get_fully_qualified_decl_name(g, &fn_table_entry->symbol_name, &tld_fn->base, false);3411 get_fully_qualified_decl_name(g, &fn_table_entry->symbol_name, &tld_fn->base, false);
3394 }3412 }
33953413
3396 if (fn_proto->is_export) {
3397 switch (fn_proto->cc) {
3398 case CallingConventionAsync: {
3399 add_node_error(g, fn_def_node,
3400 buf_sprintf("exported function cannot be async"));
3401 } break;
3402 case CallingConventionC:
3403 case CallingConventionNaked:
3404 case CallingConventionCold:
3405 case CallingConventionStdcall:
3406 case CallingConventionUnspecified:
3407 // An exported function without a specific calling
3408 // convention defaults to C
3409 CallingConvention cc = (fn_proto->cc != CallingConventionUnspecified) ?
3410 fn_proto->cc : CallingConventionC;
3411 add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name),
3412 GlobalLinkageIdStrong, cc);
3413 break;
3414 }
3415 }
3416
3417 if (!is_extern) {3414 if (!is_extern) {
3418 fn_table_entry->fndef_scope = create_fndef_scope(g,3415 fn_table_entry->fndef_scope = create_fndef_scope(g,
3419 fn_table_entry->body_node, tld_fn->base.parent_scope, fn_table_entry);3416 fn_table_entry->body_node, tld_fn->base.parent_scope, fn_table_entry);
...@@ -3432,6 +3429,21 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -3432,6 +3429,21 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
34323429
3433 Scope *child_scope = fn_table_entry->fndef_scope ? &fn_table_entry->fndef_scope->base : tld_fn->base.parent_scope;3430 Scope *child_scope = fn_table_entry->fndef_scope ? &fn_table_entry->fndef_scope->base : tld_fn->base.parent_scope;
34343431
3432 fn_table_entry->cc = cc_from_fn_proto(fn_proto);
3433 if (fn_proto->callconv_expr != nullptr) {
3434 ZigType *cc_enum_value = get_builtin_type(g, "CallingConvention");
3435
3436 ZigValue *result_val = analyze_const_value(g, child_scope, fn_proto->callconv_expr,
3437 cc_enum_value, nullptr, UndefBad);
3438 if (type_is_invalid(result_val->type)) {
3439 fn_table_entry->type_entry = g->builtin_types.entry_invalid;
3440 tld_fn->base.resolution = TldResolutionInvalid;
3441 return;
3442 }
3443
3444 fn_table_entry->cc = (CallingConvention)bigint_as_u32(&result_val->data.x_enum_tag);
3445 }
3446
3435 fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry);3447 fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry);
34363448
3437 if (fn_proto->section_expr != nullptr) {3449 if (fn_proto->section_expr != nullptr) {
...@@ -3450,10 +3462,42 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -3450,10 +3462,42 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
3450 g->fn_defs.append(fn_table_entry);3462 g->fn_defs.append(fn_table_entry);
3451 }3463 }
34523464
3465 const CallingConvention fn_cc = fn_table_entry->type_entry->data.fn.fn_type_id.cc;
3466
3467 if (fn_proto->is_export) {
3468 switch (fn_cc) {
3469 case CallingConventionAsync:
3470 add_node_error(g, fn_def_node,
3471 buf_sprintf("exported function cannot be async"));
3472 tld_fn->base.resolution = TldResolutionInvalid;
3473 return;
3474 case CallingConventionC:
3475 case CallingConventionCold:
3476 case CallingConventionNaked:
3477 case CallingConventionInterrupt:
3478 case CallingConventionSignal:
3479 case CallingConventionStdcall:
3480 case CallingConventionFastcall:
3481 case CallingConventionVectorcall:
3482 case CallingConventionAPCS:
3483 case CallingConventionAAPCS:
3484 case CallingConventionAAPCSVFP:
3485 add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name),
3486 GlobalLinkageIdStrong, fn_cc);
3487 break;
3488 case CallingConventionUnspecified:
3489 // An exported function without a specific calling
3490 // convention defaults to C
3491 add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name),
3492 GlobalLinkageIdStrong, CallingConventionC);
3493 break;
3494 }
3495 }
3496
3453 // if the calling convention implies that it cannot be async, we save that for later3497 // if the calling convention implies that it cannot be async, we save that for later
3454 // and leave the value to be nullptr to indicate that we have not emitted possible3498 // and leave the value to be nullptr to indicate that we have not emitted possible
3455 // compile errors for improperly calling async functions.3499 // compile errors for improperly calling async functions.
3456 if (fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync) {3500 if (fn_cc == CallingConventionAsync) {
3457 fn_table_entry->inferred_async_node = fn_table_entry->proto_node;3501 fn_table_entry->inferred_async_node = fn_table_entry->proto_node;
3458 }3502 }
3459 } else if (source_node->type == NodeTypeTestDecl) {3503 } else if (source_node->type == NodeTypeTestDecl) {
src/analyze.hpp+2-1
...@@ -100,7 +100,7 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node);...@@ -100,7 +100,7 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node);
100void append_namespace_qualification(CodeGen *g, Buf *buf, ZigType *container_type);100void append_namespace_qualification(CodeGen *g, Buf *buf, ZigType *container_type);
101ZigFn *create_fn(CodeGen *g, AstNode *proto_node);101ZigFn *create_fn(CodeGen *g, AstNode *proto_node);
102ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value);102ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value);
103void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc);103void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, CallingConvention cc, size_t param_count_alloc);
104AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index);104AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index);
105Error ATTRIBUTE_MUST_USE type_resolve(CodeGen *g, ZigType *type_entry, ResolveStatus status);105Error ATTRIBUTE_MUST_USE type_resolve(CodeGen *g, ZigType *type_entry, ResolveStatus status);
106void complete_enum(CodeGen *g, ZigType *enum_type);106void complete_enum(CodeGen *g, ZigType *enum_type);
...@@ -259,6 +259,7 @@ ZigValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *...@@ -259,6 +259,7 @@ ZigValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *
259259
260void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);260void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);
261bool fn_is_async(ZigFn *fn);261bool fn_is_async(ZigFn *fn);
262CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto);
262263
263Error type_val_resolve_abi_align(CodeGen *g, ZigValue *type_val, uint32_t *abi_align);264Error type_val_resolve_abi_align(CodeGen *g, ZigValue *type_val, uint32_t *abi_align);
264Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ZigValue *type_val,265Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ZigValue *type_val,
src/ast_render.cpp+5
...@@ -488,6 +488,11 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -488,6 +488,11 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
488 render_node_grouped(ar, node->data.fn_proto.section_expr);488 render_node_grouped(ar, node->data.fn_proto.section_expr);
489 fprintf(ar->f, ")");489 fprintf(ar->f, ")");
490 }490 }
491 if (node->data.fn_proto.callconv_expr) {
492 fprintf(ar->f, " callconv(");
493 render_node_grouped(ar, node->data.fn_proto.callconv_expr);
494 fprintf(ar->f, ")");
495 }
491496
492 if (node->data.fn_proto.return_var_token != nullptr) {497 if (node->data.fn_proto.return_var_token != nullptr) {
493 fprintf(ar->f, "var");498 fprintf(ar->f, "var");
src/codegen.cpp+50-7
...@@ -284,14 +284,43 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) {...@@ -284,14 +284,43 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) {
284 case CallingConventionNaked:284 case CallingConventionNaked:
285 zig_unreachable();285 zig_unreachable();
286 case CallingConventionStdcall:286 case CallingConventionStdcall:
287 // stdcall calling convention only works on x86.287 if (g->zig_target->arch == ZigLLVM_x86)
288 if (g->zig_target->arch == ZigLLVM_x86) {
289 return LLVMX86StdcallCallConv;288 return LLVMX86StdcallCallConv;
290 } else {289 return LLVMCCallConv;
291 return LLVMCCallConv;290 case CallingConventionFastcall:
292 }291 if (g->zig_target->arch == ZigLLVM_x86)
292 return LLVMX86FastcallCallConv;
293 return LLVMFastCallConv;
294 case CallingConventionVectorcall:
295 if (g->zig_target->arch == ZigLLVM_x86)
296 return LLVMX86VectorCallCallConv;
297 return LLVMCCallConv;
293 case CallingConventionAsync:298 case CallingConventionAsync:
294 return LLVMFastCallConv;299 return LLVMFastCallConv;
300 case CallingConventionAPCS:
301 if (target_is_arm(g->zig_target))
302 return LLVMARMAPCSCallConv;
303 return LLVMCCallConv;
304 case CallingConventionAAPCS:
305 if (target_is_arm(g->zig_target))
306 return LLVMARMAAPCSCallConv;
307 return LLVMCCallConv;
308 case CallingConventionAAPCSVFP:
309 if (target_is_arm(g->zig_target))
310 return LLVMARMAAPCSVFPCallConv;
311 return LLVMCCallConv;
312 case CallingConventionInterrupt:
313 if (g->zig_target->arch == ZigLLVM_x86 || g->zig_target->arch == ZigLLVM_x86_64)
314 return LLVMX86INTRCallConv;
315 if (g->zig_target->arch == ZigLLVM_avr)
316 return LLVMAVRINTRCallConv;
317 if (g->zig_target->arch == ZigLLVM_msp430)
318 return LLVMMSP430INTRCallConv;
319 return LLVMCCallConv;
320 case CallingConventionSignal:
321 if (g->zig_target->arch == ZigLLVM_avr)
322 return LLVMAVRSIGNALCallConv;
323 return LLVMCCallConv;
295 }324 }
296 zig_unreachable();325 zig_unreachable();
297}326}
...@@ -383,7 +412,14 @@ static bool cc_want_sret_attr(CallingConvention cc) {...@@ -383,7 +412,14 @@ static bool cc_want_sret_attr(CallingConvention cc) {
383 zig_unreachable();412 zig_unreachable();
384 case CallingConventionC:413 case CallingConventionC:
385 case CallingConventionCold:414 case CallingConventionCold:
415 case CallingConventionInterrupt:
416 case CallingConventionSignal:
386 case CallingConventionStdcall:417 case CallingConventionStdcall:
418 case CallingConventionFastcall:
419 case CallingConventionVectorcall:
420 case CallingConventionAPCS:
421 case CallingConventionAAPCS:
422 case CallingConventionAAPCSVFP:
387 return true;423 return true;
388 case CallingConventionAsync:424 case CallingConventionAsync:
389 case CallingConventionUnspecified:425 case CallingConventionUnspecified:
...@@ -8463,8 +8499,15 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -8463,8 +8499,15 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
8463 static_assert(CallingConventionC == 1, "");8499 static_assert(CallingConventionC == 1, "");
8464 static_assert(CallingConventionCold == 2, "");8500 static_assert(CallingConventionCold == 2, "");
8465 static_assert(CallingConventionNaked == 3, "");8501 static_assert(CallingConventionNaked == 3, "");
8466 static_assert(CallingConventionStdcall == 4, "");8502 static_assert(CallingConventionAsync == 4, "");
8467 static_assert(CallingConventionAsync == 5, "");8503 static_assert(CallingConventionInterrupt == 5, "");
8504 static_assert(CallingConventionSignal == 6, "");
8505 static_assert(CallingConventionStdcall == 7, "");
8506 static_assert(CallingConventionFastcall == 8, "");
8507 static_assert(CallingConventionVectorcall == 9, "");
8508 static_assert(CallingConventionAPCS == 10, "");
8509 static_assert(CallingConventionAAPCS == 11, "");
8510 static_assert(CallingConventionAAPCSVFP == 12, "");
84688511
8469 static_assert(FnInlineAuto == 0, "");8512 static_assert(FnInlineAuto == 0, "");
8470 static_assert(FnInlineAlways == 1, "");8513 static_assert(FnInlineAlways == 1, "");
src/ir.cpp+45-12
...@@ -3250,12 +3250,13 @@ static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope,...@@ -3250,12 +3250,13 @@ static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope,
3250}3250}
32513251
3252static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *source_node,3252static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *source_node,
3253 IrInstruction **param_types, IrInstruction *align_value, IrInstruction *return_type,3253 IrInstruction **param_types, IrInstruction *align_value, IrInstruction *callconv_value,
3254 bool is_var_args)3254 IrInstruction *return_type, bool is_var_args)
3255{3255{
3256 IrInstructionFnProto *instruction = ir_build_instruction<IrInstructionFnProto>(irb, scope, source_node);3256 IrInstructionFnProto *instruction = ir_build_instruction<IrInstructionFnProto>(irb, scope, source_node);
3257 instruction->param_types = param_types;3257 instruction->param_types = param_types;
3258 instruction->align_value = align_value;3258 instruction->align_value = align_value;
3259 instruction->callconv_value = callconv_value;
3259 instruction->return_type = return_type;3260 instruction->return_type = return_type;
3260 instruction->is_var_args = is_var_args;3261 instruction->is_var_args = is_var_args;
32613262
...@@ -3266,6 +3267,7 @@ static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *s...@@ -3266,6 +3267,7 @@ static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *s
3266 if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block);3267 if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block);
3267 }3268 }
3268 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block);3269 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block);
3270 if (callconv_value != nullptr) ir_ref_instruction(callconv_value, irb->current_basic_block);
3269 ir_ref_instruction(return_type, irb->current_basic_block);3271 ir_ref_instruction(return_type, irb->current_basic_block);
32703272
3271 return &instruction->base;3273 return &instruction->base;
...@@ -8850,6 +8852,13 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -8850,6 +8852,13 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
8850 return irb->codegen->invalid_instruction;8852 return irb->codegen->invalid_instruction;
8851 }8853 }
88528854
8855 IrInstruction *callconv_value = nullptr;
8856 if (node->data.fn_proto.callconv_expr != nullptr) {
8857 callconv_value = ir_gen_node(irb, node->data.fn_proto.callconv_expr, parent_scope);
8858 if (callconv_value == irb->codegen->invalid_instruction)
8859 return irb->codegen->invalid_instruction;
8860 }
8861
8853 IrInstruction *return_type;8862 IrInstruction *return_type;
8854 if (node->data.fn_proto.return_var_token == nullptr) {8863 if (node->data.fn_proto.return_var_token == nullptr) {
8855 if (node->data.fn_proto.return_type == nullptr) {8864 if (node->data.fn_proto.return_type == nullptr) {
...@@ -8866,7 +8875,7 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -8866,7 +8875,7 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
8866 //return_type = nullptr;8875 //return_type = nullptr;
8867 }8876 }
88688877
8869 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args);8878 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, callconv_value, return_type, is_var_args);
8870}8879}
88718880
8872static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) {8881static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) {
...@@ -16736,9 +16745,16 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio...@@ -16736,9 +16745,16 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
16736 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here"));16745 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here"));
16737 } break;16746 } break;
16738 case CallingConventionC:16747 case CallingConventionC:
16739 case CallingConventionNaked:
16740 case CallingConventionCold:16748 case CallingConventionCold:
16749 case CallingConventionNaked:
16750 case CallingConventionInterrupt:
16751 case CallingConventionSignal:
16741 case CallingConventionStdcall:16752 case CallingConventionStdcall:
16753 case CallingConventionFastcall:
16754 case CallingConventionVectorcall:
16755 case CallingConventionAPCS:
16756 case CallingConventionAAPCS:
16757 case CallingConventionAAPCSVFP:
16742 add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, cc);16758 add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, cc);
16743 break;16759 break;
16744 }16760 }
...@@ -18101,7 +18117,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i...@@ -18101,7 +18117,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i
18101 return ira->codegen->invalid_instruction;18117 return ira->codegen->invalid_instruction;
18102 }18118 }
1810318119
18104
18105 if (fn_type_id->is_var_args) {18120 if (fn_type_id->is_var_args) {
18106 if (call_param_count < src_param_count) {18121 if (call_param_count < src_param_count) {
18107 ErrorMsg *msg = ir_add_error_node(ira, source_node,18122 ErrorMsg *msg = ir_add_error_node(ira, source_node,
...@@ -18254,8 +18269,9 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i...@@ -18254,8 +18269,9 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i
18254 buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name);18269 buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name);
18255 impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn);18270 impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn);
18256 impl_fn->child_scope = &impl_fn->fndef_scope->base;18271 impl_fn->child_scope = &impl_fn->fndef_scope->base;
18272 impl_fn->cc = fn_entry->cc;
18257 FnTypeId inst_fn_type_id = {0};18273 FnTypeId inst_fn_type_id = {0};
18258 init_fn_type_id(&inst_fn_type_id, fn_proto_node, new_fn_arg_count);18274 init_fn_type_id(&inst_fn_type_id, fn_proto_node, fn_type_id->cc, new_fn_arg_count);
18259 inst_fn_type_id.param_count = 0;18275 inst_fn_type_id.param_count = 0;
18260 inst_fn_type_id.is_var_args = false;18276 inst_fn_type_id.is_var_args = false;
1826118277
...@@ -22592,8 +22608,8 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr...@@ -22592,8 +22608,8 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
22592 // calling_convention: TypeInfo.CallingConvention22608 // calling_convention: TypeInfo.CallingConvention
22593 ensure_field_index(fn_decl_val->type, "calling_convention", 2);22609 ensure_field_index(fn_decl_val->type, "calling_convention", 2);
22594 fn_decl_fields[2]->special = ConstValSpecialStatic;22610 fn_decl_fields[2]->special = ConstValSpecialStatic;
22595 fn_decl_fields[2]->type = ir_type_info_get_type(ira, "CallingConvention", nullptr);22611 fn_decl_fields[2]->type = get_builtin_type(ira->codegen, "CallingConvention");
22596 bigint_init_unsigned(&fn_decl_fields[2]->data.x_enum_tag, fn_node->cc);22612 bigint_init_unsigned(&fn_decl_fields[2]->data.x_enum_tag, fn_entry->cc);
22597 // is_var_args: bool22613 // is_var_args: bool
22598 ensure_field_index(fn_decl_val->type, "is_var_args", 3);22614 ensure_field_index(fn_decl_val->type, "is_var_args", 3);
22599 bool is_varargs = fn_node->is_var_args;22615 bool is_varargs = fn_node->is_var_args;
...@@ -23280,7 +23296,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -23280,7 +23296,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
23280 // calling_convention: TypeInfo.CallingConvention23296 // calling_convention: TypeInfo.CallingConvention
23281 ensure_field_index(result->type, "calling_convention", 0);23297 ensure_field_index(result->type, "calling_convention", 0);
23282 fields[0]->special = ConstValSpecialStatic;23298 fields[0]->special = ConstValSpecialStatic;
23283 fields[0]->type = ir_type_info_get_type(ira, "CallingConvention", nullptr);23299 fields[0]->type = get_builtin_type(ira->codegen, "CallingConvention");
23284 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc);23300 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc);
23285 // is_generic: bool23301 // is_generic: bool
23286 ensure_field_index(result->type, "is_generic", 1);23302 ensure_field_index(result->type, "is_generic", 1);
...@@ -26192,6 +26208,21 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct...@@ -26192,6 +26208,21 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct
26192 return ira->codegen->invalid_instruction;26208 return ira->codegen->invalid_instruction;
26193 }26209 }
2619426210
26211 lazy_fn_type->cc = cc_from_fn_proto(&proto_node->data.fn_proto);
26212 if (instruction->callconv_value != nullptr) {
26213 ZigType *cc_enum_type = get_builtin_type(ira->codegen, "CallingConvention");
26214
26215 IrInstruction *casted_value = ir_implicit_cast(ira, instruction->callconv_value, cc_enum_type);
26216 if (type_is_invalid(casted_value->value->type))
26217 return ira->codegen->invalid_instruction;
26218
26219 ZigValue *const_value = ir_resolve_const(ira, casted_value, UndefBad);
26220 if (const_value == nullptr)
26221 return ira->codegen->invalid_instruction;
26222
26223 lazy_fn_type->cc = (CallingConvention)bigint_as_u32(&const_value->data.x_enum_tag);
26224 }
26225
26195 size_t param_count = proto_node->data.fn_proto.params.length;26226 size_t param_count = proto_node->data.fn_proto.params.length;
26196 lazy_fn_type->proto_node = proto_node;26227 lazy_fn_type->proto_node = proto_node;
26197 lazy_fn_type->param_types = allocate<IrInstruction *>(param_count);26228 lazy_fn_type->param_types = allocate<IrInstruction *>(param_count);
...@@ -26202,9 +26233,11 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct...@@ -26202,9 +26233,11 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct
2620226233
26203 bool param_is_var_args = param_node->data.param_decl.is_var_args;26234 bool param_is_var_args = param_node->data.param_decl.is_var_args;
26204 if (param_is_var_args) {26235 if (param_is_var_args) {
26205 if (proto_node->data.fn_proto.cc == CallingConventionC) {26236 const CallingConvention cc = lazy_fn_type->cc;
26237
26238 if (cc == CallingConventionC) {
26206 break;26239 break;
26207 } else if (proto_node->data.fn_proto.cc == CallingConventionUnspecified) {26240 } else if (cc == CallingConventionUnspecified) {
26208 lazy_fn_type->is_generic = true;26241 lazy_fn_type->is_generic = true;
26209 return result;26242 return result;
26210 } else {26243 } else {
...@@ -29062,7 +29095,7 @@ static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, La...@@ -29062,7 +29095,7 @@ static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, La
29062 AstNode *proto_node = lazy_fn_type->proto_node;29095 AstNode *proto_node = lazy_fn_type->proto_node;
2906329096
29064 FnTypeId fn_type_id = {0};29097 FnTypeId fn_type_id = {0};
29065 init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length);29098 init_fn_type_id(&fn_type_id, proto_node, lazy_fn_type->cc, proto_node->data.fn_proto.params.length);
2906629099
29067 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) {29100 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) {
29068 AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index);29101 AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index);
src/parser.cpp+25-8
...@@ -92,6 +92,7 @@ static Token *ast_parse_block_label(ParseContext *pc);...@@ -92,6 +92,7 @@ static Token *ast_parse_block_label(ParseContext *pc);
92static AstNode *ast_parse_field_init(ParseContext *pc);92static AstNode *ast_parse_field_init(ParseContext *pc);
93static AstNode *ast_parse_while_continue_expr(ParseContext *pc);93static AstNode *ast_parse_while_continue_expr(ParseContext *pc);
94static AstNode *ast_parse_link_section(ParseContext *pc);94static AstNode *ast_parse_link_section(ParseContext *pc);
95static AstNode *ast_parse_callconv(ParseContext *pc);
95static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc);96static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc);
96static AstNode *ast_parse_param_decl(ParseContext *pc);97static AstNode *ast_parse_param_decl(ParseContext *pc);
97static AstNode *ast_parse_param_type(ParseContext *pc);98static AstNode *ast_parse_param_type(ParseContext *pc);
...@@ -676,7 +677,9 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B...@@ -676,7 +677,9 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
676 fn_proto->column = first->start_column;677 fn_proto->column = first->start_column;
677 fn_proto->data.fn_proto.visib_mod = visib_mod;678 fn_proto->data.fn_proto.visib_mod = visib_mod;
678 fn_proto->data.fn_proto.doc_comments = *doc_comments;679 fn_proto->data.fn_proto.doc_comments = *doc_comments;
679 fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern;680 // ast_parse_fn_cc may set it
681 if (!fn_proto->data.fn_proto.is_extern)
682 fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern;
680 fn_proto->data.fn_proto.is_export = first->id == TokenIdKeywordExport;683 fn_proto->data.fn_proto.is_export = first->id == TokenIdKeywordExport;
681 switch (first->id) {684 switch (first->id) {
682 case TokenIdKeywordInline:685 case TokenIdKeywordInline:
...@@ -761,7 +764,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {...@@ -761,7 +764,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
761 // The extern keyword for fn CC is also used for container decls.764 // The extern keyword for fn CC is also used for container decls.
762 // We therefore put it back, as allow container decl to consume it765 // We therefore put it back, as allow container decl to consume it
763 // later.766 // later.
764 if (fn_cc.cc == CallingConventionC) {767 if (fn_cc.is_extern) {
765 fn = eat_token_if(pc, TokenIdKeywordFn);768 fn = eat_token_if(pc, TokenIdKeywordFn);
766 if (fn == nullptr) {769 if (fn == nullptr) {
767 put_back_token(pc);770 put_back_token(pc);
...@@ -784,6 +787,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {...@@ -784,6 +787,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
784787
785 AstNode *align_expr = ast_parse_byte_align(pc);788 AstNode *align_expr = ast_parse_byte_align(pc);
786 AstNode *section_expr = ast_parse_link_section(pc);789 AstNode *section_expr = ast_parse_link_section(pc);
790 AstNode *callconv_expr = ast_parse_callconv(pc);
787 Token *var = eat_token_if(pc, TokenIdKeywordVar);791 Token *var = eat_token_if(pc, TokenIdKeywordVar);
788 Token *exmark = nullptr;792 Token *exmark = nullptr;
789 AstNode *return_type = nullptr;793 AstNode *return_type = nullptr;
...@@ -798,6 +802,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {...@@ -798,6 +802,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
798 res->data.fn_proto.params = params;802 res->data.fn_proto.params = params;
799 res->data.fn_proto.align_expr = align_expr;803 res->data.fn_proto.align_expr = align_expr;
800 res->data.fn_proto.section_expr = section_expr;804 res->data.fn_proto.section_expr = section_expr;
805 res->data.fn_proto.callconv_expr = callconv_expr;
801 res->data.fn_proto.return_var_token = var;806 res->data.fn_proto.return_var_token = var;
802 res->data.fn_proto.auto_err_set = exmark != nullptr;807 res->data.fn_proto.auto_err_set = exmark != nullptr;
803 res->data.fn_proto.return_type = return_type;808 res->data.fn_proto.return_type = return_type;
...@@ -2099,6 +2104,18 @@ static AstNode *ast_parse_link_section(ParseContext *pc) {...@@ -2099,6 +2104,18 @@ static AstNode *ast_parse_link_section(ParseContext *pc) {
2099 return res;2104 return res;
2100}2105}
21012106
2107// CallConv <- KEYWORD_callconv LPAREN Expr RPAREN
2108static AstNode *ast_parse_callconv(ParseContext *pc) {
2109 Token *first = eat_token_if(pc, TokenIdKeywordCallconv);
2110 if (first == nullptr)
2111 return nullptr;
2112
2113 expect_token(pc, TokenIdLParen);
2114 AstNode *res = ast_expect(pc, ast_parse_expr);
2115 expect_token(pc, TokenIdRParen);
2116 return res;
2117}
2118
2102// FnCC2119// FnCC
2103// <- KEYWORD_nakedcc2120// <- KEYWORD_nakedcc
2104// / KEYWORD_stdcallcc2121// / KEYWORD_stdcallcc
...@@ -2107,19 +2124,19 @@ static AstNode *ast_parse_link_section(ParseContext *pc) {...@@ -2107,19 +2124,19 @@ static AstNode *ast_parse_link_section(ParseContext *pc) {
2107static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc) {2124static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc) {
2108 AstNodeFnProto res = {};2125 AstNodeFnProto res = {};
2109 if (eat_token_if(pc, TokenIdKeywordNakedCC) != nullptr) {2126 if (eat_token_if(pc, TokenIdKeywordNakedCC) != nullptr) {
2110 res.cc = CallingConventionNaked;2127 res.is_nakedcc = true;
2111 return Optional<AstNodeFnProto>::some(res);2128 return Optional<AstNodeFnProto>::some(res);
2112 }2129 }
2113 if (eat_token_if(pc, TokenIdKeywordStdcallCC) != nullptr) {2130 if (eat_token_if(pc, TokenIdKeywordStdcallCC) != nullptr) {
2114 res.cc = CallingConventionStdcall;2131 res.is_stdcallcc = true;
2115 return Optional<AstNodeFnProto>::some(res);2132 return Optional<AstNodeFnProto>::some(res);
2116 }2133 }
2117 if (eat_token_if(pc, TokenIdKeywordExtern) != nullptr) {2134 if (eat_token_if(pc, TokenIdKeywordAsync) != nullptr) {
2118 res.cc = CallingConventionC;2135 res.is_async = true;
2119 return Optional<AstNodeFnProto>::some(res);2136 return Optional<AstNodeFnProto>::some(res);
2120 }2137 }
2121 if (eat_token_if(pc, TokenIdKeywordAsync) != nullptr) {2138 if (eat_token_if(pc, TokenIdKeywordExtern) != nullptr) {
2122 res.cc = CallingConventionAsync;2139 res.is_extern = true;
2123 return Optional<AstNodeFnProto>::some(res);2140 return Optional<AstNodeFnProto>::some(res);
2124 }2141 }
21252142
src/tokenizer.cpp+2
...@@ -110,6 +110,7 @@ static const struct ZigKeyword zig_keywords[] = {...@@ -110,6 +110,7 @@ static const struct ZigKeyword zig_keywords[] = {
110 {"async", TokenIdKeywordAsync},110 {"async", TokenIdKeywordAsync},
111 {"await", TokenIdKeywordAwait},111 {"await", TokenIdKeywordAwait},
112 {"break", TokenIdKeywordBreak},112 {"break", TokenIdKeywordBreak},
113 {"callconv", TokenIdKeywordCallconv},
113 {"catch", TokenIdKeywordCatch},114 {"catch", TokenIdKeywordCatch},
114 {"comptime", TokenIdKeywordCompTime},115 {"comptime", TokenIdKeywordCompTime},
115 {"const", TokenIdKeywordConst},116 {"const", TokenIdKeywordConst},
...@@ -1545,6 +1546,7 @@ const char * token_name(TokenId id) {...@@ -1545,6 +1546,7 @@ const char * token_name(TokenId id) {
1545 case TokenIdKeywordAsm: return "asm";1546 case TokenIdKeywordAsm: return "asm";
1546 case TokenIdKeywordBreak: return "break";1547 case TokenIdKeywordBreak: return "break";
1547 case TokenIdKeywordCatch: return "catch";1548 case TokenIdKeywordCatch: return "catch";
1549 case TokenIdKeywordCallconv: return "callconv";
1548 case TokenIdKeywordCompTime: return "comptime";1550 case TokenIdKeywordCompTime: return "comptime";
1549 case TokenIdKeywordConst: return "const";1551 case TokenIdKeywordConst: return "const";
1550 case TokenIdKeywordContinue: return "continue";1552 case TokenIdKeywordContinue: return "continue";
src/tokenizer.hpp+1
...@@ -59,6 +59,7 @@ enum TokenId {...@@ -59,6 +59,7 @@ enum TokenId {
59 TokenIdKeywordAwait,59 TokenIdKeywordAwait,
60 TokenIdKeywordBreak,60 TokenIdKeywordBreak,
61 TokenIdKeywordCatch,61 TokenIdKeywordCatch,
62 TokenIdKeywordCallconv,
62 TokenIdKeywordCompTime,63 TokenIdKeywordCompTime,
63 TokenIdKeywordConst,64 TokenIdKeywordConst,
64 TokenIdKeywordContinue,65 TokenIdKeywordContinue,
test/compile_errors.zig+15-15
...@@ -752,7 +752,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -752,7 +752,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
752 \\ _ = @frame();752 \\ _ = @frame();
753 \\}753 \\}
754 , &[_][]const u8{754 , &[_][]const u8{
755 "tmp.zig:1:1: error: function with calling convention 'ccc' cannot be async",755 "tmp.zig:1:1: error: function with calling convention 'C' cannot be async",
756 "tmp.zig:5:9: note: @frame() causes function to be async",756 "tmp.zig:5:9: note: @frame() causes function to be async",
757 });757 });
758758
...@@ -765,7 +765,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -765,7 +765,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
765 \\ suspend;765 \\ suspend;
766 \\}766 \\}
767 , &[_][]const u8{767 , &[_][]const u8{
768 "tmp.zig:1:1: error: function with calling convention 'ccc' cannot be async",768 "tmp.zig:1:1: error: function with calling convention 'C' cannot be async",
769 "tmp.zig:3:18: note: await here is a suspend point",769 "tmp.zig:3:18: note: await here is a suspend point",
770 });770 });
771771
...@@ -843,7 +843,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -843,7 +843,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
843 \\ suspend;843 \\ suspend;
844 \\}844 \\}
845 , &[_][]const u8{845 , &[_][]const u8{
846 "tmp.zig:1:1: error: function with calling convention 'ccc' cannot be async",846 "tmp.zig:1:1: error: function with calling convention 'C' cannot be async",
847 "tmp.zig:2:8: note: async function call here",847 "tmp.zig:2:8: note: async function call here",
848 "tmp.zig:5:8: note: async function call here",848 "tmp.zig:5:8: note: async function call here",
849 "tmp.zig:8:5: note: suspends here",849 "tmp.zig:8:5: note: suspends here",
...@@ -1140,7 +1140,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1140,7 +1140,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1140 \\ while (true) {}1140 \\ while (true) {}
1141 \\}1141 \\}
1142 , &[_][]const u8{1142 , &[_][]const u8{
1143 "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn([]const u8,var)var'",1143 "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn([]const u8,var) var'",
1144 "note: only one of the functions is generic",1144 "note: only one of the functions is generic",
1145 });1145 });
11461146
...@@ -1362,7 +1362,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1362,7 +1362,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1362 \\ return 0;1362 \\ return 0;
1363 \\}1363 \\}
1364 , &[_][]const u8{1364 , &[_][]const u8{
1365 "tmp.zig:1:15: error: parameter of type 'var' not allowed in function with calling convention 'ccc'",1365 "tmp.zig:1:15: error: parameter of type 'var' not allowed in function with calling convention 'C'",
1366 });1366 });
13671367
1368 cases.add("C pointer to c_void",1368 cases.add("C pointer to c_void",
...@@ -2187,7 +2187,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2187,7 +2187,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2187 \\ f(g);2187 \\ f(g);
2188 \\}2188 \\}
2189 , &[_][]const u8{2189 , &[_][]const u8{
2190 "tmp.zig:1:9: error: parameter of type 'fn(var)var' must be declared comptime",2190 "tmp.zig:1:9: error: parameter of type 'fn(var) var' must be declared comptime",
2191 });2191 });
21922192
2193 cases.add("optional pointer to void in extern struct",2193 cases.add("optional pointer to void in extern struct",
...@@ -2859,7 +2859,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2859,7 +2859,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2859 \\const Foo = enum { A, B, C };2859 \\const Foo = enum { A, B, C };
2860 \\export fn entry(foo: Foo) void { }2860 \\export fn entry(foo: Foo) void { }
2861 , &[_][]const u8{2861 , &[_][]const u8{
2862 "tmp.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'",2862 "tmp.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'",
2863 });2863 });
28642864
2865 cases.add("function with non-extern non-packed struct parameter",2865 cases.add("function with non-extern non-packed struct parameter",
...@@ -2870,7 +2870,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2870,7 +2870,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2870 \\};2870 \\};
2871 \\export fn entry(foo: Foo) void { }2871 \\export fn entry(foo: Foo) void { }
2872 , &[_][]const u8{2872 , &[_][]const u8{
2873 "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'",2873 "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'",
2874 });2874 });
28752875
2876 cases.add("function with non-extern non-packed union parameter",2876 cases.add("function with non-extern non-packed union parameter",
...@@ -2881,7 +2881,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2881,7 +2881,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2881 \\};2881 \\};
2882 \\export fn entry(foo: Foo) void { }2882 \\export fn entry(foo: Foo) void { }
2883 , &[_][]const u8{2883 , &[_][]const u8{
2884 "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'",2884 "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'",
2885 });2885 });
28862886
2887 cases.add("switch on enum with 1 field with no prongs",2887 cases.add("switch on enum with 1 field with no prongs",
...@@ -2977,8 +2977,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2977,8 +2977,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2977 \\ bar(&{});2977 \\ bar(&{});
2978 \\}2978 \\}
2979 , &[_][]const u8{2979 , &[_][]const u8{
2980 "tmp.zig:1:30: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'ccc'",2980 "tmp.zig:1:30: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'",
2981 "tmp.zig:7:18: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'ccc'",2981 "tmp.zig:7:18: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'",
2982 });2982 });
29832983
2984 cases.add("implicit semicolon - block statement",2984 cases.add("implicit semicolon - block statement",
...@@ -4552,7 +4552,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4552,7 +4552,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4552 \\ return x + y;4552 \\ return x + y;
4553 \\}4553 \\}
4554 , &[_][]const u8{4554 , &[_][]const u8{
4555 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'",4555 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'",
4556 });4556 });
45574557
4558 cases.add("extern function with comptime parameter",4558 cases.add("extern function with comptime parameter",
...@@ -4562,7 +4562,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4562,7 +4562,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4562 \\}4562 \\}
4563 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }4563 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }
4564 , &[_][]const u8{4564 , &[_][]const u8{
4565 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'",4565 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'",
4566 });4566 });
45674567
4568 cases.add("convert fixed size array to slice with invalid size",4568 cases.add("convert fixed size array to slice with invalid size",
...@@ -6303,7 +6303,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6303,7 +6303,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6303 \\ _ = @TypeOf(generic).ReturnType;6303 \\ _ = @TypeOf(generic).ReturnType;
6304 \\}6304 \\}
6305 , &[_][]const u8{6305 , &[_][]const u8{
6306 "tmp.zig:3:25: error: ReturnType has not been resolved because 'fn(var)var' is generic",6306 "tmp.zig:3:25: error: ReturnType has not been resolved because 'fn(var) var' is generic",
6307 });6307 });
63086308
6309 cases.add("getting @ArgType of generic function",6309 cases.add("getting @ArgType of generic function",
...@@ -6312,7 +6312,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6312,7 +6312,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6312 \\ _ = @ArgType(@TypeOf(generic), 0);6312 \\ _ = @ArgType(@TypeOf(generic), 0);
6313 \\}6313 \\}
6314 , &[_][]const u8{6314 , &[_][]const u8{
6315 "tmp.zig:3:36: error: @ArgType could not resolve the type of arg 0 because 'fn(var)var' is generic",6315 "tmp.zig:3:36: error: @ArgType could not resolve the type of arg 0 because 'fn(var) var' is generic",
6316 });6316 });
63176317
6318 cases.add("unsupported modifier at start of asm output constraint",6318 cases.add("unsupported modifier at start of asm output constraint",
test/stage1/behavior/type_info.zig+2-2
...@@ -202,7 +202,7 @@ fn testUnion() void {...@@ -202,7 +202,7 @@ fn testUnion() void {
202 expect(typeinfo_info.Union.fields[4].enum_field != null);202 expect(typeinfo_info.Union.fields[4].enum_field != null);
203 expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);203 expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
204 expect(typeinfo_info.Union.fields[4].field_type == @TypeOf(@typeInfo(u8).Int));204 expect(typeinfo_info.Union.fields[4].field_type == @TypeOf(@typeInfo(u8).Int));
205 expect(typeinfo_info.Union.decls.len == 21);205 expect(typeinfo_info.Union.decls.len == 20);
206206
207 const TestNoTagUnion = union {207 const TestNoTagUnion = union {
208 Foo: void,208 Foo: void,
...@@ -266,7 +266,7 @@ test "type info: function type info" {...@@ -266,7 +266,7 @@ test "type info: function type info" {
266fn testFunction() void {266fn testFunction() void {
267 const fn_info = @typeInfo(@TypeOf(foo));267 const fn_info = @typeInfo(@TypeOf(foo));
268 expect(@as(TypeId, fn_info) == TypeId.Fn);268 expect(@as(TypeId, fn_info) == TypeId.Fn);
269 expect(fn_info.Fn.calling_convention == TypeInfo.CallingConvention.Unspecified);269 expect(fn_info.Fn.calling_convention == .Unspecified);
270 expect(fn_info.Fn.is_generic);270 expect(fn_info.Fn.is_generic);
271 expect(fn_info.Fn.args.len == 2);271 expect(fn_info.Fn.args.len == 2);
272 expect(fn_info.Fn.is_var_args);272 expect(fn_info.Fn.is_var_args);