diff --git a/doc/docgen.zig b/doc/docgen.zig index 83855b3b5075..0218f504199f 100644 --- a/doc/docgen.zig +++ b/doc/docgen.zig @@ -818,6 +818,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok .Keyword_resume, .Keyword_return, .Keyword_linksection, + .Keyword_callconv, .Keyword_stdcallcc, .Keyword_struct, .Keyword_suspend, diff --git a/doc/langref.html.in b/doc/langref.html.in index 3be3131843bf..dd77bcaa63ac 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -2829,7 +2829,7 @@ test "@tagName" {
By default, enums are not guaranteed to be compatible with the C ABI:
- {#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'ccc'#} + {#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'C'#} const Foo = enum { A, B, C }; export fn entry(foo: Foo) void { } {#code_end#} diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index 687e169bbe46..9b3be8f424b6 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -91,6 +91,25 @@ pub const Mode = enum { ReleaseSmall, }; +/// This data structure is used by the Zig language code generation and +/// therefore must be kept in sync with the compiler implementation. +pub const CallingConvention = enum { + Unspecified, + C, + Cold, + Naked, + Async, + Interrupt, + Signal, + Stdcall, + Fastcall, + Vectorcall, + Thiscall, + APCS, + AAPCS, + AAPCSVFP, +}; + pub const TypeId = @TagType(TypeInfo); /// This data structure is used by the Zig language code generation and @@ -253,17 +272,6 @@ pub const TypeInfo = union(enum) { decls: []Declaration, }; - /// This data structure is used by the Zig language code generation and - /// therefore must be kept in sync with the compiler implementation. - pub const CallingConvention = enum { - Unspecified, - C, - Cold, - Naked, - Stdcall, - Async, - }; - /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. pub const FnArg = struct { @@ -416,7 +424,7 @@ pub const CallOptions = struct { /// therefore must be kept in sync with the compiler implementation. pub const TestFn = struct { name: []const u8, - func: fn()anyerror!void, + func: fn () anyerror!void, }; /// This function type is used by the Zig language code generation and diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 76685666adb9..5ef25ec9fcb8 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -2475,7 +2475,7 @@ extern fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *con os.abort(); } -stdcallcc fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) c_long { +fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) callconv(.Stdcall) c_long { const exception_address = @ptrToInt(info.ExceptionRecord.ExceptionAddress); switch (info.ExceptionRecord.ExceptionCode) { windows.EXCEPTION_DATATYPE_MISALIGNMENT => panicExtra(null, exception_address, "Unaligned Memory Access", .{}), diff --git a/lib/std/fs.zig b/lib/std/fs.zig index ea62086f590a..deb671f0a1e2 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -230,7 +230,7 @@ pub const AtomicFile = struct { b64_fs_encoder.encode(tmp_path_slice[dirname_component_len..tmp_path_len], &rand_buf); const file = my_cwd.createFileC( - tmp_path_slice, + tmp_path_slice, .{ .mode = mode, .exclusive = true }, ) catch |err| switch (err) { error.PathAlreadyExists => continue, diff --git a/lib/std/mutex.zig b/lib/std/mutex.zig index a96402a31c2b..c13d5a2aa40d 100644 --- a/lib/std/mutex.zig +++ b/lib/std/mutex.zig @@ -48,8 +48,8 @@ pub const Mutex = if (builtin.single_threaded) return self.tryAcquire() orelse @panic("deadlock detected"); } } -else if (builtin.os == .windows) - // https://locklessinc.com/articles/keyed_events/ +else if (builtin.os == .windows) +// https://locklessinc.com/articles/keyed_events/ extern union { locked: u8, waiters: u32, @@ -97,8 +97,8 @@ else if (builtin.os == .windows) return Held{ .mutex = self }; } - // otherwise, try and update the waiting count. - // then unset the WAKE bit so that another unlocker can wake up a thread. + // otherwise, try and update the waiting count. + // then unset the WAKE bit so that another unlocker can wake up a thread. } else if (@cmpxchgWeak(u32, &self.waiters, waiters, (waiters + WAIT) | 1, .Monotonic, .Monotonic) == null) { const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null); assert(rc == 0); @@ -118,7 +118,7 @@ else if (builtin.os == .windows) while (true) : (SpinLock.loopHint(1)) { const waiters = @atomicLoad(u32, &self.mutex.waiters, .Monotonic); - + // no one is waiting if (waiters < WAIT) return; // someone grabbed the lock and will do the wake instead @@ -130,14 +130,14 @@ else if (builtin.os == .windows) if (@cmpxchgWeak(u32, &self.mutex.waiters, waiters, waiters - WAIT + WAKE, .Release, .Monotonic) == null) { const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null); assert(rc == 0); - return; + return; } } } }; } else if (builtin.link_libc or builtin.os == .linux) - // stack-based version of https://github.com/Amanieu/parking_lot/blob/master/core/src/word_lock.rs +// stack-based version of https://github.com/Amanieu/parking_lot/blob/master/core/src/word_lock.rs struct { state: usize, @@ -170,8 +170,8 @@ else if (builtin.link_libc or builtin.os == .linux) pub fn acquire(self: *Mutex) Held { return self.tryAcquire() orelse { - self.acquireSlow(); - return Held{ .mutex = self }; + self.acquireSlow(); + return Held{ .mutex = self }; }; } @@ -237,7 +237,7 @@ else if (builtin.link_libc or builtin.os == .linux) fn releaseSlow(self: *Mutex) void { @setCold(true); - + // try and lock the LFIO queue to pop a node off, // stopping altogether if its already locked or the queue is empty var state = @atomicLoad(usize, &self.state, .Monotonic); @@ -265,9 +265,10 @@ else if (builtin.link_libc or builtin.os == .linux) } } -// for platforms without a known OS blocking -// primitive, default to SpinLock for correctness -else SpinLock; + // for platforms without a known OS blocking + // primitive, default to SpinLock for correctness +else + SpinLock; const TestContext = struct { mutex: *Mutex, diff --git a/lib/std/net.zig b/lib/std/net.zig index d4e68b2e1779..47ce95c99f29 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -451,11 +451,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !* .next = null, }; var res: *os.addrinfo = undefined; - switch (os.system.getaddrinfo( - name_c.ptr, - @ptrCast([*:0]const u8, port_c.ptr), - &hints, - &res)) { + switch (os.system.getaddrinfo(name_c.ptr, @ptrCast([*:0]const u8, port_c.ptr), &hints, &res)) { 0 => {}, c.EAI_ADDRFAMILY => return error.HostLacksNetworkAddresses, c.EAI_AGAIN => return error.TemporaryNameServerFailure, diff --git a/lib/std/os/linux/arm-eabi.zig b/lib/std/os/linux/arm-eabi.zig index c457e10bebf4..879805696c04 100644 --- a/lib/std/os/linux/arm-eabi.zig +++ b/lib/std/os/linux/arm-eabi.zig @@ -97,7 +97,7 @@ pub extern fn getThreadPointer() usize { ); } -pub nakedcc fn restore() void { +pub fn restore() callconv(.Naked) void { return asm volatile ("svc #0" : : [number] "{r7}" (@as(usize, SYS_sigreturn)) @@ -105,7 +105,7 @@ pub nakedcc fn restore() void { ); } -pub nakedcc fn restore_rt() void { +pub fn restore_rt() callconv(.Naked) void { return asm volatile ("svc #0" : : [number] "{r7}" (@as(usize, SYS_rt_sigreturn)) diff --git a/lib/std/os/linux/arm64.zig b/lib/std/os/linux/arm64.zig index ac2bb3bfdfdf..f565bea4895f 100644 --- a/lib/std/os/linux/arm64.zig +++ b/lib/std/os/linux/arm64.zig @@ -90,7 +90,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, a pub const restore = restore_rt; -pub nakedcc fn restore_rt() void { +pub fn restore_rt() callconv(.Naked) void { return asm volatile ("svc #0" : : [number] "{x8}" (@as(usize, SYS_rt_sigreturn)) diff --git a/lib/std/os/linux/i386.zig b/lib/std/os/linux/i386.zig index 3345f9904df4..7652ece43ed1 100644 --- a/lib/std/os/linux/i386.zig +++ b/lib/std/os/linux/i386.zig @@ -102,7 +102,7 @@ pub fn socketcall(call: usize, args: [*]usize) usize { /// This matches the libc clone function. pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; -pub nakedcc fn restore() void { +pub fn restore() callconv(.Naked) void { return asm volatile ("int $0x80" : : [number] "{eax}" (@as(usize, SYS_sigreturn)) @@ -110,7 +110,7 @@ pub nakedcc fn restore() void { ); } -pub nakedcc fn restore_rt() void { +pub fn restore_rt() callconv(.Naked) void { return asm volatile ("int $0x80" : : [number] "{eax}" (@as(usize, SYS_rt_sigreturn)) diff --git a/lib/std/os/linux/mipsel.zig b/lib/std/os/linux/mipsel.zig index 60408c1e8434..5193133f6c16 100644 --- a/lib/std/os/linux/mipsel.zig +++ b/lib/std/os/linux/mipsel.zig @@ -144,7 +144,7 @@ pub fn syscall6( /// This matches the libc clone function. pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; -pub nakedcc fn restore() void { +pub fn restore() callconv(.Naked) void { return asm volatile ("syscall" : : [number] "{$2}" (@as(usize, SYS_sigreturn)) @@ -152,7 +152,7 @@ pub nakedcc fn restore() void { ); } -pub nakedcc fn restore_rt() void { +pub fn restore_rt() callconv(.Naked) void { return asm volatile ("syscall" : : [number] "{$2}" (@as(usize, SYS_rt_sigreturn)) diff --git a/lib/std/os/linux/riscv64.zig b/lib/std/os/linux/riscv64.zig index b7c59a9039a6..2259dad78ecf 100644 --- a/lib/std/os/linux/riscv64.zig +++ b/lib/std/os/linux/riscv64.zig @@ -89,7 +89,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, a pub const restore = restore_rt; -pub nakedcc fn restore_rt() void { +pub fn restore_rt() callconv(.Naked) void { return asm volatile ("ecall" : : [number] "{x17}" (@as(usize, SYS_rt_sigreturn)) diff --git a/lib/std/os/linux/x86_64.zig b/lib/std/os/linux/x86_64.zig index d037b3c6aee2..d6067f9b187d 100644 --- a/lib/std/os/linux/x86_64.zig +++ b/lib/std/os/linux/x86_64.zig @@ -90,7 +90,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: usize, pub const restore = restore_rt; -pub nakedcc fn restore_rt() void { +pub fn restore_rt() callconv(.Naked) void { return asm volatile ("syscall" : : [number] "{rax}" (@as(usize, SYS_rt_sigreturn)) diff --git a/lib/std/os/test.zig b/lib/std/os/test.zig index 09e8c24899d5..877b95af1fb8 100644 --- a/lib/std/os/test.zig +++ b/lib/std/os/test.zig @@ -166,7 +166,7 @@ test "sigaltstack" { // analyzed const dl_phdr_info = if (@hasDecl(os, "dl_phdr_info")) os.dl_phdr_info else c_void; -export fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) i32 { +extern fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) i32 { if (builtin.os == .windows or builtin.os == .wasi or builtin.os == .macosx) return 0; diff --git a/lib/std/os/uefi/protocols/simple_text_input_protocol.zig b/lib/std/os/uefi/protocols/simple_text_input_protocol.zig index e1c5f6446fad..b56ff728ef12 100644 --- a/lib/std/os/uefi/protocols/simple_text_input_protocol.zig +++ b/lib/std/os/uefi/protocols/simple_text_input_protocol.zig @@ -27,4 +27,3 @@ pub const SimpleTextInputProtocol = extern struct { .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b }, }; }; - diff --git a/lib/std/os/windows/advapi32.zig b/lib/std/os/windows/advapi32.zig index 940f10994cb2..6364c5bddbed 100644 --- a/lib/std/os/windows/advapi32.zig +++ b/lib/std/os/windows/advapi32.zig @@ -1,23 +1,23 @@ usingnamespace @import("bits.zig"); -pub extern "advapi32" stdcallcc fn RegOpenKeyExW( +pub extern "advapi32" fn RegOpenKeyExW( hKey: HKEY, lpSubKey: LPCWSTR, ulOptions: DWORD, samDesired: REGSAM, phkResult: *HKEY, -) LSTATUS; +) callconv(.Stdcall) LSTATUS; -pub extern "advapi32" stdcallcc fn RegQueryValueExW( +pub extern "advapi32" fn RegQueryValueExW( hKey: HKEY, lpValueName: LPCWSTR, lpReserved: LPDWORD, lpType: LPDWORD, lpData: LPBYTE, lpcbData: LPDWORD, -) LSTATUS; +) callconv(.Stdcall) LSTATUS; // RtlGenRandom is known as SystemFunction036 under advapi32 // http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx */ -pub extern "advapi32" stdcallcc fn SystemFunction036(output: [*]u8, length: ULONG) BOOL; +pub extern "advapi32" fn SystemFunction036(output: [*]u8, length: ULONG) callconv(.Stdcall) BOOL; pub const RtlGenRandom = SystemFunction036; diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig index def987bd2306..7d87ae075a85 100644 --- a/lib/std/os/windows/bits.zig +++ b/lib/std/os/windows/bits.zig @@ -892,7 +892,7 @@ pub const EXCEPTION_POINTERS = extern struct { ContextRecord: *c_void, }; -pub const VECTORED_EXCEPTION_HANDLER = stdcallcc fn (ExceptionInfo: *EXCEPTION_POINTERS) c_long; +pub const VECTORED_EXCEPTION_HANDLER = fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(.Stdcall) c_long; pub const OBJECT_ATTRIBUTES = extern struct { Length: ULONG, diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig index 33e56abce165..1af68f4abd1e 100644 --- a/lib/std/os/windows/kernel32.zig +++ b/lib/std/os/windows/kernel32.zig @@ -1,22 +1,22 @@ usingnamespace @import("bits.zig"); -pub extern "kernel32" stdcallcc fn AddVectoredExceptionHandler(First: c_ulong, Handler: ?VECTORED_EXCEPTION_HANDLER) ?*c_void; -pub extern "kernel32" stdcallcc fn RemoveVectoredExceptionHandler(Handle: HANDLE) c_ulong; +pub extern "kernel32" fn AddVectoredExceptionHandler(First: c_ulong, Handler: ?VECTORED_EXCEPTION_HANDLER) callconv(.Stdcall) ?*c_void; +pub extern "kernel32" fn RemoveVectoredExceptionHandler(Handle: HANDLE) callconv(.Stdcall) c_ulong; -pub extern "kernel32" stdcallcc fn CancelIoEx(hFile: HANDLE, lpOverlapped: LPOVERLAPPED) BOOL; +pub extern "kernel32" fn CancelIoEx(hFile: HANDLE, lpOverlapped: LPOVERLAPPED) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) BOOL; +pub extern "kernel32" fn CloseHandle(hObject: HANDLE) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn CreateDirectoryW(lpPathName: [*]const u16, lpSecurityAttributes: ?*SECURITY_ATTRIBUTES) BOOL; +pub extern "kernel32" fn CreateDirectoryW(lpPathName: [*]const u16, lpSecurityAttributes: ?*SECURITY_ATTRIBUTES) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn CreateEventExW( +pub extern "kernel32" fn CreateEventExW( lpEventAttributes: ?*SECURITY_ATTRIBUTES, lpName: [*:0]const u16, dwFlags: DWORD, dwDesiredAccess: DWORD, -) ?HANDLE; +) callconv(.Stdcall) ?HANDLE; -pub extern "kernel32" stdcallcc fn CreateFileW( +pub extern "kernel32" fn CreateFileW( lpFileName: [*]const u16, // TODO null terminated pointer type dwDesiredAccess: DWORD, dwShareMode: DWORD, @@ -24,16 +24,16 @@ pub extern "kernel32" stdcallcc fn CreateFileW( dwCreationDisposition: DWORD, dwFlagsAndAttributes: DWORD, hTemplateFile: ?HANDLE, -) HANDLE; +) callconv(.Stdcall) HANDLE; -pub extern "kernel32" stdcallcc fn CreatePipe( +pub extern "kernel32" fn CreatePipe( hReadPipe: *HANDLE, hWritePipe: *HANDLE, lpPipeAttributes: *const SECURITY_ATTRIBUTES, nSize: DWORD, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn CreateProcessW( +pub extern "kernel32" fn CreateProcessW( lpApplicationName: ?LPWSTR, lpCommandLine: LPWSTR, lpProcessAttributes: ?*SECURITY_ATTRIBUTES, @@ -44,15 +44,15 @@ pub extern "kernel32" stdcallcc fn CreateProcessW( lpCurrentDirectory: ?LPWSTR, lpStartupInfo: *STARTUPINFOW, lpProcessInformation: *PROCESS_INFORMATION, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn CreateSymbolicLinkW(lpSymlinkFileName: [*]const u16, lpTargetFileName: [*]const u16, dwFlags: DWORD) BOOLEAN; +pub extern "kernel32" fn CreateSymbolicLinkW(lpSymlinkFileName: [*]const u16, lpTargetFileName: [*]const u16, dwFlags: DWORD) callconv(.Stdcall) BOOLEAN; -pub extern "kernel32" stdcallcc fn CreateIoCompletionPort(FileHandle: HANDLE, ExistingCompletionPort: ?HANDLE, CompletionKey: ULONG_PTR, NumberOfConcurrentThreads: DWORD) ?HANDLE; +pub extern "kernel32" fn CreateIoCompletionPort(FileHandle: HANDLE, ExistingCompletionPort: ?HANDLE, CompletionKey: ULONG_PTR, NumberOfConcurrentThreads: DWORD) callconv(.Stdcall) ?HANDLE; -pub extern "kernel32" stdcallcc fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) ?HANDLE; +pub extern "kernel32" fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) callconv(.Stdcall) ?HANDLE; -pub extern "kernel32" stdcallcc fn DeviceIoControl( +pub extern "kernel32" fn DeviceIoControl( h: HANDLE, dwIoControlCode: DWORD, lpInBuffer: ?*const c_void, @@ -61,107 +61,107 @@ pub extern "kernel32" stdcallcc fn DeviceIoControl( nOutBufferSize: DWORD, lpBytesReturned: ?*DWORD, lpOverlapped: ?*OVERLAPPED, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn DeleteFileW(lpFileName: [*]const u16) BOOL; +pub extern "kernel32" fn DeleteFileW(lpFileName: [*]const u16) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn DuplicateHandle(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE, hTargetProcessHandle: HANDLE, lpTargetHandle: *HANDLE, dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwOptions: DWORD) BOOL; +pub extern "kernel32" fn DuplicateHandle(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE, hTargetProcessHandle: HANDLE, lpTargetHandle: *HANDLE, dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwOptions: DWORD) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: UINT) noreturn; +pub extern "kernel32" fn ExitProcess(exit_code: UINT) callconv(.Stdcall) noreturn; -pub extern "kernel32" stdcallcc fn FindFirstFileW(lpFileName: [*]const u16, lpFindFileData: *WIN32_FIND_DATAW) HANDLE; -pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL; -pub extern "kernel32" stdcallcc fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) BOOL; +pub extern "kernel32" fn FindFirstFileW(lpFileName: [*]const u16, lpFindFileData: *WIN32_FIND_DATAW) callconv(.Stdcall) HANDLE; +pub extern "kernel32" fn FindClose(hFindFile: HANDLE) callconv(.Stdcall) BOOL; +pub extern "kernel32" fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn FormatMessageW(dwFlags: DWORD, lpSource: ?LPVOID, dwMessageId: DWORD, dwLanguageId: DWORD, lpBuffer: LPWSTR, nSize: DWORD, Arguments: ?*va_list) DWORD; +pub extern "kernel32" fn FormatMessageW(dwFlags: DWORD, lpSource: ?LPVOID, dwMessageId: DWORD, dwLanguageId: DWORD, lpBuffer: LPWSTR, nSize: DWORD, Arguments: ?*va_list) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsW(penv: [*]u16) BOOL; +pub extern "kernel32" fn FreeEnvironmentStringsW(penv: [*]u16) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR; +pub extern "kernel32" fn GetCommandLineA() callconv(.Stdcall) LPSTR; -pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: *DWORD) BOOL; +pub extern "kernel32" fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: *DWORD) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetConsoleScreenBufferInfo(hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: *CONSOLE_SCREEN_BUFFER_INFO) BOOL; +pub extern "kernel32" fn GetConsoleScreenBufferInfo(hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: *CONSOLE_SCREEN_BUFFER_INFO) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: ?[*]WCHAR) DWORD; +pub extern "kernel32" fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: ?[*]WCHAR) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn GetCurrentThread() HANDLE; -pub extern "kernel32" stdcallcc fn GetCurrentThreadId() DWORD; +pub extern "kernel32" fn GetCurrentThread() callconv(.Stdcall) HANDLE; +pub extern "kernel32" fn GetCurrentThreadId() callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn GetEnvironmentStringsW() ?[*]u16; +pub extern "kernel32" fn GetEnvironmentStringsW() callconv(.Stdcall) ?[*]u16; -pub extern "kernel32" stdcallcc fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) DWORD; +pub extern "kernel32" fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: *DWORD) BOOL; +pub extern "kernel32" fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: *DWORD) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetFileSizeEx(hFile: HANDLE, lpFileSize: *LARGE_INTEGER) BOOL; +pub extern "kernel32" fn GetFileSizeEx(hFile: HANDLE, lpFileSize: *LARGE_INTEGER) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetFileAttributesW(lpFileName: [*]const WCHAR) DWORD; +pub extern "kernel32" fn GetFileAttributesW(lpFileName: [*]const WCHAR) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn GetModuleFileNameW(hModule: ?HMODULE, lpFilename: [*]u16, nSize: DWORD) DWORD; +pub extern "kernel32" fn GetModuleFileNameW(hModule: ?HMODULE, lpFilename: [*]u16, nSize: DWORD) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn GetModuleHandleW(lpModuleName: ?[*]const WCHAR) HMODULE; +pub extern "kernel32" fn GetModuleHandleW(lpModuleName: ?[*]const WCHAR) callconv(.Stdcall) HMODULE; -pub extern "kernel32" stdcallcc fn GetLastError() DWORD; +pub extern "kernel32" fn GetLastError() callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn GetFileInformationByHandle( +pub extern "kernel32" fn GetFileInformationByHandle( hFile: HANDLE, lpFileInformation: *BY_HANDLE_FILE_INFORMATION, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx( +pub extern "kernel32" fn GetFileInformationByHandleEx( in_hFile: HANDLE, in_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, out_lpFileInformation: *c_void, in_dwBufferSize: DWORD, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetFinalPathNameByHandleW( +pub extern "kernel32" fn GetFinalPathNameByHandleW( hFile: HANDLE, lpszFilePath: [*]u16, cchFilePath: DWORD, dwFlags: DWORD, -) DWORD; +) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERLAPPED, lpNumberOfBytesTransferred: *DWORD, bWait: BOOL) BOOL; +pub extern "kernel32" fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERLAPPED, lpNumberOfBytesTransferred: *DWORD, bWait: BOOL) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetProcessHeap() ?HANDLE; -pub extern "kernel32" stdcallcc fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) BOOL; +pub extern "kernel32" fn GetProcessHeap() callconv(.Stdcall) ?HANDLE; +pub extern "kernel32" fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) void; -pub extern "kernel32" stdcallcc fn GetSystemTimeAsFileTime(*FILETIME) void; +pub extern "kernel32" fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) callconv(.Stdcall) void; +pub extern "kernel32" fn GetSystemTimeAsFileTime(*FILETIME) callconv(.Stdcall) void; -pub extern "kernel32" stdcallcc fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) ?HANDLE; -pub extern "kernel32" stdcallcc fn HeapDestroy(hHeap: HANDLE) BOOL; -pub extern "kernel32" stdcallcc fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void, dwBytes: SIZE_T) ?*c_void; -pub extern "kernel32" stdcallcc fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) SIZE_T; -pub extern "kernel32" stdcallcc fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) SIZE_T; -pub extern "kernel32" stdcallcc fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) BOOL; +pub extern "kernel32" fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) callconv(.Stdcall) ?HANDLE; +pub extern "kernel32" fn HeapDestroy(hHeap: HANDLE) callconv(.Stdcall) BOOL; +pub extern "kernel32" fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void, dwBytes: SIZE_T) callconv(.Stdcall) ?*c_void; +pub extern "kernel32" fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) callconv(.Stdcall) SIZE_T; +pub extern "kernel32" fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) callconv(.Stdcall) SIZE_T; +pub extern "kernel32" fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetStdHandle(in_nStdHandle: DWORD) ?HANDLE; +pub extern "kernel32" fn GetStdHandle(in_nStdHandle: DWORD) callconv(.Stdcall) ?HANDLE; -pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) ?*c_void; +pub extern "kernel32" fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) callconv(.Stdcall) ?*c_void; -pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void) BOOL; +pub extern "kernel32" fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: ?*const c_void) BOOL; +pub extern "kernel32" fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: ?*const c_void) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn VirtualAlloc(lpAddress: ?LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD) ?LPVOID; -pub extern "kernel32" stdcallcc fn VirtualFree(lpAddress: ?LPVOID, dwSize: SIZE_T, dwFreeType: DWORD) BOOL; +pub extern "kernel32" fn VirtualAlloc(lpAddress: ?LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD) callconv(.Stdcall) ?LPVOID; +pub extern "kernel32" fn VirtualFree(lpAddress: ?LPVOID, dwSize: SIZE_T, dwFreeType: DWORD) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn MoveFileExW( +pub extern "kernel32" fn MoveFileExW( lpExistingFileName: [*]const u16, lpNewFileName: [*]const u16, dwFlags: DWORD, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn PostQueuedCompletionStatus(CompletionPort: HANDLE, dwNumberOfBytesTransferred: DWORD, dwCompletionKey: ULONG_PTR, lpOverlapped: ?*OVERLAPPED) BOOL; +pub extern "kernel32" fn PostQueuedCompletionStatus(CompletionPort: HANDLE, dwNumberOfBytesTransferred: DWORD, dwCompletionKey: ULONG_PTR, lpOverlapped: ?*OVERLAPPED) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn QueryPerformanceCounter(lpPerformanceCount: *LARGE_INTEGER) BOOL; +pub extern "kernel32" fn QueryPerformanceCounter(lpPerformanceCount: *LARGE_INTEGER) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn QueryPerformanceFrequency(lpFrequency: *LARGE_INTEGER) BOOL; +pub extern "kernel32" fn QueryPerformanceFrequency(lpFrequency: *LARGE_INTEGER) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn ReadDirectoryChangesW( +pub extern "kernel32" fn ReadDirectoryChangesW( hDirectory: HANDLE, lpBuffer: [*]align(@alignOf(FILE_NOTIFY_INFORMATION)) u8, nBufferLength: DWORD, @@ -170,79 +170,79 @@ pub extern "kernel32" stdcallcc fn ReadDirectoryChangesW( lpBytesReturned: ?*DWORD, lpOverlapped: ?*OVERLAPPED, lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn ReadFile( +pub extern "kernel32" fn ReadFile( in_hFile: HANDLE, out_lpBuffer: [*]u8, in_nNumberOfBytesToRead: DWORD, out_lpNumberOfBytesRead: ?*DWORD, in_out_lpOverlapped: ?*OVERLAPPED, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn RemoveDirectoryW(lpPathName: [*]const u16) BOOL; +pub extern "kernel32" fn RemoveDirectoryW(lpPathName: [*]const u16) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) BOOL; +pub extern "kernel32" fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn SetFilePointerEx( +pub extern "kernel32" fn SetFilePointerEx( in_fFile: HANDLE, in_liDistanceToMove: LARGE_INTEGER, out_opt_ldNewFilePointer: ?*LARGE_INTEGER, in_dwMoveMethod: DWORD, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn SetFileTime( +pub extern "kernel32" fn SetFileTime( hFile: HANDLE, lpCreationTime: ?*const FILETIME, lpLastAccessTime: ?*const FILETIME, lpLastWriteTime: ?*const FILETIME, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) BOOL; +pub extern "kernel32" fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD) void; +pub extern "kernel32" fn Sleep(dwMilliseconds: DWORD) callconv(.Stdcall) void; -pub extern "kernel32" stdcallcc fn SwitchToThread() BOOL; +pub extern "kernel32" fn SwitchToThread() callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) BOOL; +pub extern "kernel32" fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn TlsAlloc() DWORD; +pub extern "kernel32" fn TlsAlloc() callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn TlsFree(dwTlsIndex: DWORD) BOOL; +pub extern "kernel32" fn TlsFree(dwTlsIndex: DWORD) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) DWORD; +pub extern "kernel32" fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn WaitForSingleObjectEx(hHandle: HANDLE, dwMilliseconds: DWORD, bAlertable: BOOL) DWORD; +pub extern "kernel32" fn WaitForSingleObjectEx(hHandle: HANDLE, dwMilliseconds: DWORD, bAlertable: BOOL) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn WaitForMultipleObjects(nCount: DWORD, lpHandle: [*]const HANDLE, bWaitAll: BOOL, dwMilliseconds: DWORD) DWORD; +pub extern "kernel32" fn WaitForMultipleObjects(nCount: DWORD, lpHandle: [*]const HANDLE, bWaitAll: BOOL, dwMilliseconds: DWORD) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn WaitForMultipleObjectsEx( +pub extern "kernel32" fn WaitForMultipleObjectsEx( nCount: DWORD, lpHandle: [*]const HANDLE, bWaitAll: BOOL, dwMilliseconds: DWORD, bAlertable: BOOL, -) DWORD; +) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn WriteFile( +pub extern "kernel32" fn WriteFile( in_hFile: HANDLE, in_lpBuffer: [*]const u8, in_nNumberOfBytesToWrite: DWORD, out_lpNumberOfBytesWritten: ?*DWORD, in_out_lpOverlapped: ?*OVERLAPPED, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn WriteFileEx(hFile: HANDLE, lpBuffer: [*]const u8, nNumberOfBytesToWrite: DWORD, lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE) BOOL; +pub extern "kernel32" fn WriteFileEx(hFile: HANDLE, lpBuffer: [*]const u8, nNumberOfBytesToWrite: DWORD, lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn LoadLibraryW(lpLibFileName: [*]const u16) ?HMODULE; +pub extern "kernel32" fn LoadLibraryW(lpLibFileName: [*]const u16) callconv(.Stdcall) ?HMODULE; -pub extern "kernel32" stdcallcc fn GetProcAddress(hModule: HMODULE, lpProcName: [*]const u8) ?FARPROC; +pub extern "kernel32" fn GetProcAddress(hModule: HMODULE, lpProcName: [*]const u8) callconv(.Stdcall) ?FARPROC; -pub extern "kernel32" stdcallcc fn FreeLibrary(hModule: HMODULE) BOOL; +pub extern "kernel32" fn FreeLibrary(hModule: HMODULE) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn InitializeCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void; -pub extern "kernel32" stdcallcc fn EnterCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void; -pub extern "kernel32" stdcallcc fn LeaveCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void; -pub extern "kernel32" stdcallcc fn DeleteCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void; +pub extern "kernel32" fn InitializeCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void; +pub extern "kernel32" fn EnterCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void; +pub extern "kernel32" fn LeaveCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void; +pub extern "kernel32" fn DeleteCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void; -pub extern "kernel32" stdcallcc fn InitOnceExecuteOnce(InitOnce: *INIT_ONCE, InitFn: INIT_ONCE_FN, Parameter: ?*c_void, Context: ?*c_void) BOOL; +pub extern "kernel32" fn InitOnceExecuteOnce(InitOnce: *INIT_ONCE, InitFn: INIT_ONCE_FN, Parameter: ?*c_void, Context: ?*c_void) callconv(.Stdcall) BOOL; diff --git a/lib/std/os/windows/ntdll.zig b/lib/std/os/windows/ntdll.zig index 84de0ca94680..695cd7727433 100644 --- a/lib/std/os/windows/ntdll.zig +++ b/lib/std/os/windows/ntdll.zig @@ -1,14 +1,14 @@ usingnamespace @import("bits.zig"); -pub extern "NtDll" stdcallcc fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) WORD; -pub extern "NtDll" stdcallcc fn NtQueryInformationFile( +pub extern "NtDll" fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) callconv(.Stdcall) WORD; +pub extern "NtDll" fn NtQueryInformationFile( FileHandle: HANDLE, IoStatusBlock: *IO_STATUS_BLOCK, FileInformation: *c_void, Length: ULONG, FileInformationClass: FILE_INFORMATION_CLASS, -) NTSTATUS; -pub extern "NtDll" stdcallcc fn NtCreateFile( +) callconv(.Stdcall) NTSTATUS; +pub extern "NtDll" fn NtCreateFile( FileHandle: *HANDLE, DesiredAccess: ACCESS_MASK, ObjectAttributes: *OBJECT_ATTRIBUTES, @@ -20,8 +20,8 @@ pub extern "NtDll" stdcallcc fn NtCreateFile( CreateOptions: ULONG, EaBuffer: ?*c_void, EaLength: ULONG, -) NTSTATUS; -pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile( +) callconv(.Stdcall) NTSTATUS; +pub extern "NtDll" fn NtDeviceIoControlFile( FileHandle: HANDLE, Event: ?HANDLE, ApcRoutine: ?IO_APC_ROUTINE, @@ -32,17 +32,17 @@ pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile( InputBufferLength: ULONG, OutputBuffer: ?PVOID, OutputBufferLength: ULONG, -) NTSTATUS; -pub extern "NtDll" stdcallcc fn NtClose(Handle: HANDLE) NTSTATUS; -pub extern "NtDll" stdcallcc fn RtlDosPathNameToNtPathName_U( +) callconv(.Stdcall) NTSTATUS; +pub extern "NtDll" fn NtClose(Handle: HANDLE) callconv(.Stdcall) NTSTATUS; +pub extern "NtDll" fn RtlDosPathNameToNtPathName_U( DosPathName: [*]const u16, NtPathName: *UNICODE_STRING, NtFileNamePart: ?*?[*]const u16, DirectoryInfo: ?*CURDIR, -) BOOL; -pub extern "NtDll" stdcallcc fn RtlFreeUnicodeString(UnicodeString: *UNICODE_STRING) void; +) callconv(.Stdcall) BOOL; +pub extern "NtDll" fn RtlFreeUnicodeString(UnicodeString: *UNICODE_STRING) callconv(.Stdcall) void; -pub extern "NtDll" stdcallcc fn NtQueryDirectoryFile( +pub extern "NtDll" fn NtQueryDirectoryFile( FileHandle: HANDLE, Event: ?HANDLE, ApcRoutine: ?IO_APC_ROUTINE, @@ -54,22 +54,22 @@ pub extern "NtDll" stdcallcc fn NtQueryDirectoryFile( ReturnSingleEntry: BOOLEAN, FileName: ?*UNICODE_STRING, RestartScan: BOOLEAN, -) NTSTATUS; -pub extern "NtDll" stdcallcc fn NtCreateKeyedEvent( +) callconv(.Stdcall) NTSTATUS; +pub extern "NtDll" fn NtCreateKeyedEvent( KeyedEventHandle: *HANDLE, DesiredAccess: ACCESS_MASK, ObjectAttributes: ?PVOID, Flags: ULONG, -) NTSTATUS; -pub extern "NtDll" stdcallcc fn NtReleaseKeyedEvent( +) callconv(.Stdcall) NTSTATUS; +pub extern "NtDll" fn NtReleaseKeyedEvent( EventHandle: HANDLE, Key: *const c_void, Alertable: BOOLEAN, Timeout: ?*LARGE_INTEGER, -) NTSTATUS; -pub extern "NtDll" stdcallcc fn NtWaitForKeyedEvent( +) callconv(.Stdcall) NTSTATUS; +pub extern "NtDll" fn NtWaitForKeyedEvent( EventHandle: HANDLE, Key: *const c_void, Alertable: BOOLEAN, Timeout: ?*LARGE_INTEGER, -) NTSTATUS; +) callconv(.Stdcall) NTSTATUS; diff --git a/lib/std/os/windows/ole32.zig b/lib/std/os/windows/ole32.zig index 39c12d074c01..a47208907842 100644 --- a/lib/std/os/windows/ole32.zig +++ b/lib/std/os/windows/ole32.zig @@ -1,6 +1,6 @@ usingnamespace @import("bits.zig"); -pub extern "ole32" stdcallcc fn CoTaskMemFree(pv: LPVOID) void; -pub extern "ole32" stdcallcc fn CoUninitialize() void; -pub extern "ole32" stdcallcc fn CoGetCurrentProcess() DWORD; -pub extern "ole32" stdcallcc fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) HRESULT; +pub extern "ole32" fn CoTaskMemFree(pv: LPVOID) callconv(.Stdcall) void; +pub extern "ole32" fn CoUninitialize() callconv(.Stdcall) void; +pub extern "ole32" fn CoGetCurrentProcess() callconv(.Stdcall) DWORD; +pub extern "ole32" fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) callconv(.Stdcall) HRESULT; diff --git a/lib/std/os/windows/shell32.zig b/lib/std/os/windows/shell32.zig index c178997aad9e..aa1667d01d8c 100644 --- a/lib/std/os/windows/shell32.zig +++ b/lib/std/os/windows/shell32.zig @@ -1,3 +1,3 @@ usingnamespace @import("bits.zig"); -pub extern "shell32" stdcallcc fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*]WCHAR) HRESULT; +pub extern "shell32" fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*]WCHAR) callconv(.Stdcall) HRESULT; diff --git a/lib/std/os/windows/ws2_32.zig b/lib/std/os/windows/ws2_32.zig index c3dece290951..70cb62ac514e 100644 --- a/lib/std/os/windows/ws2_32.zig +++ b/lib/std/os/windows/ws2_32.zig @@ -315,30 +315,30 @@ const IOC_WS2 = 0x08000000; pub const SIO_BASE_HANDLE = IOC_OUT | IOC_WS2 | 34; -pub extern "ws2_32" stdcallcc fn WSAStartup( +pub extern "ws2_32" fn WSAStartup( wVersionRequired: WORD, lpWSAData: *WSADATA, -) c_int; -pub extern "ws2_32" stdcallcc fn WSACleanup() c_int; -pub extern "ws2_32" stdcallcc fn WSAGetLastError() c_int; -pub extern "ws2_32" stdcallcc fn WSASocketA( +) callconv(.Stdcall) c_int; +pub extern "ws2_32" fn WSACleanup() callconv(.Stdcall) c_int; +pub extern "ws2_32" fn WSAGetLastError() callconv(.Stdcall) c_int; +pub extern "ws2_32" fn WSASocketA( af: c_int, type: c_int, protocol: c_int, lpProtocolInfo: ?*WSAPROTOCOL_INFOA, g: GROUP, dwFlags: DWORD, -) SOCKET; -pub extern "ws2_32" stdcallcc fn WSASocketW( +) callconv(.Stdcall) SOCKET; +pub extern "ws2_32" fn WSASocketW( af: c_int, type: c_int, protocol: c_int, lpProtocolInfo: ?*WSAPROTOCOL_INFOW, g: GROUP, dwFlags: DWORD, -) SOCKET; -pub extern "ws2_32" stdcallcc fn closesocket(s: SOCKET) c_int; -pub extern "ws2_32" stdcallcc fn WSAIoctl( +) callconv(.Stdcall) SOCKET; +pub extern "ws2_32" fn closesocket(s: SOCKET) callconv(.Stdcall) c_int; +pub extern "ws2_32" fn WSAIoctl( s: SOCKET, dwIoControlCode: DWORD, lpvInBuffer: ?*const c_void, @@ -348,18 +348,18 @@ pub extern "ws2_32" stdcallcc fn WSAIoctl( lpcbBytesReturned: LPDWORD, lpOverlapped: ?*WSAOVERLAPPED, lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, -) c_int; -pub extern "ws2_32" stdcallcc fn accept( +) callconv(.Stdcall) c_int; +pub extern "ws2_32" fn accept( s: SOCKET, addr: ?*sockaddr, addrlen: socklen_t, -) SOCKET; -pub extern "ws2_32" stdcallcc fn connect( +) callconv(.Stdcall) SOCKET; +pub extern "ws2_32" fn connect( s: SOCKET, name: *const sockaddr, namelen: socklen_t, -) c_int; -pub extern "ws2_32" stdcallcc fn WSARecv( +) callconv(.Stdcall) c_int; +pub extern "ws2_32" fn WSARecv( s: SOCKET, lpBuffers: [*]const WSABUF, dwBufferCount: DWORD, @@ -367,8 +367,8 @@ pub extern "ws2_32" stdcallcc fn WSARecv( lpFlags: *DWORD, lpOverlapped: ?*WSAOVERLAPPED, lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, -) c_int; -pub extern "ws2_32" stdcallcc fn WSARecvFrom( +) callconv(.Stdcall) c_int; +pub extern "ws2_32" fn WSARecvFrom( s: SOCKET, lpBuffers: [*]const WSABUF, dwBufferCount: DWORD, @@ -378,8 +378,8 @@ pub extern "ws2_32" stdcallcc fn WSARecvFrom( lpFromlen: socklen_t, lpOverlapped: ?*WSAOVERLAPPED, lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, -) c_int; -pub extern "ws2_32" stdcallcc fn WSASend( +) callconv(.Stdcall) c_int; +pub extern "ws2_32" fn WSASend( s: SOCKET, lpBuffers: [*]WSABUF, dwBufferCount: DWORD, @@ -387,8 +387,8 @@ pub extern "ws2_32" stdcallcc fn WSASend( dwFlags: DWORD, lpOverlapped: ?*WSAOVERLAPPED, lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, -) c_int; -pub extern "ws2_32" stdcallcc fn WSASendTo( +) callconv(.Stdcall) c_int; +pub extern "ws2_32" fn WSASendTo( s: SOCKET, lpBuffers: [*]WSABUF, dwBufferCount: DWORD, @@ -398,4 +398,4 @@ pub extern "ws2_32" stdcallcc fn WSASendTo( iTolen: socklen_t, lpOverlapped: ?*WSAOVERLAPPED, lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, -) c_int; +) callconv(.Stdcall) c_int; diff --git a/lib/std/reset_event.zig b/lib/std/reset_event.zig index 86bc5ba5aa4b..b9d9517c6d96 100644 --- a/lib/std/reset_event.zig +++ b/lib/std/reset_event.zig @@ -14,13 +14,12 @@ const windows = os.windows; pub const ResetEvent = struct { os_event: OsEvent, - pub const OsEvent = - if (builtin.single_threaded) - DebugEvent - else if (builtin.link_libc and builtin.os != .windows and builtin.os != .linux) - PosixEvent - else - AtomicEvent; + pub const OsEvent = if (builtin.single_threaded) + DebugEvent + else if (builtin.link_libc and builtin.os != .windows and builtin.os != .linux) + PosixEvent + else + AtomicEvent; pub fn init() ResetEvent { return ResetEvent{ .os_event = OsEvent.init() }; @@ -105,7 +104,7 @@ const PosixEvent = struct { } fn deinit(self: *PosixEvent) void { - // on dragonfly, *destroy() functions can return EINVAL + // on dragonfly, *destroy() functions can return EINVAL // for statically initialized pthread structures const err = if (builtin.os == .dragonfly) os.EINVAL else 0; @@ -212,8 +211,7 @@ const AtomicEvent = struct { fn wait(self: *AtomicEvent, timeout: ?u64) !void { var waiters = @atomicLoad(u32, &self.waiters, .Acquire); while (waiters != WAKE) { - waiters = @cmpxchgWeak(u32, &self.waiters, waiters, waiters + WAIT, .Acquire, .Acquire) - orelse return Futex.wait(&self.waiters, timeout); + waiters = @cmpxchgWeak(u32, &self.waiters, waiters, waiters + WAIT, .Acquire, .Acquire) orelse return Futex.wait(&self.waiters, timeout); } } @@ -281,7 +279,7 @@ const AtomicEvent = struct { pub fn wake(waiters: *u32, wake_count: u32) void { const handle = getEventHandle() orelse return SpinFutex.wake(waiters, wake_count); const key = @ptrCast(*const c_void, waiters); - + var waiting = wake_count; while (waiting != 0) : (waiting -= 1) { const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null); @@ -408,7 +406,7 @@ test "std.ResetEvent" { // wait for receiver to update value and signal output self.out.wait(); testing.expect(self.value == 2); - + // update value and signal final input self.value = 3; self.in.set(); @@ -418,12 +416,12 @@ test "std.ResetEvent" { // wait for sender to update value and signal input self.in.wait(); assert(self.value == 1); - + // update value and signal output self.in.reset(); self.value = 2; self.out.set(); - + // wait for sender to update value and signal final input self.in.wait(); assert(self.value == 3); diff --git a/lib/std/special/c.zig b/lib/std/special/c.zig index 0895b1e6f9f0..c0ee9a938ef6 100644 --- a/lib/std/special/c.zig +++ b/lib/std/special/c.zig @@ -195,7 +195,7 @@ extern fn __stack_chk_fail() noreturn { // TODO we should be able to put this directly in std/linux/x86_64.zig but // it causes a segfault in release mode. this is a workaround of calling it // across .o file boundaries. fix comptime @ptrCast of nakedcc functions. -nakedcc fn clone() void { +fn clone() callconv(.Naked) void { switch (builtin.arch) { .i386 => { // __clone(func, stack, flags, arg, ptid, tls, ctid) diff --git a/lib/std/special/compiler_rt.zig b/lib/std/special/compiler_rt.zig index 0426f72417f8..f821918ccc5d 100644 --- a/lib/std/special/compiler_rt.zig +++ b/lib/std/special/compiler_rt.zig @@ -528,7 +528,7 @@ fn usesThumb1PreArmv6(arch: builtin.Arch) bool { }; } -nakedcc fn __aeabi_memcpy() noreturn { +fn __aeabi_memcpy() callconv(.Naked) noreturn { @setRuntimeSafety(false); if (use_thumb_1) { asm volatile ( @@ -544,7 +544,7 @@ nakedcc fn __aeabi_memcpy() noreturn { unreachable; } -nakedcc fn __aeabi_memmove() noreturn { +fn __aeabi_memmove() callconv(.Naked) noreturn { @setRuntimeSafety(false); if (use_thumb_1) { asm volatile ( @@ -560,7 +560,7 @@ nakedcc fn __aeabi_memmove() noreturn { unreachable; } -nakedcc fn __aeabi_memset() noreturn { +fn __aeabi_memset() callconv(.Naked) noreturn { @setRuntimeSafety(false); if (use_thumb_1_pre_armv6) { asm volatile ( @@ -591,7 +591,7 @@ nakedcc fn __aeabi_memset() noreturn { unreachable; } -nakedcc fn __aeabi_memclr() noreturn { +fn __aeabi_memclr() callconv(.Naked) noreturn { @setRuntimeSafety(false); if (use_thumb_1_pre_armv6) { asm volatile ( @@ -619,7 +619,7 @@ nakedcc fn __aeabi_memclr() noreturn { unreachable; } -nakedcc fn __aeabi_memcmp() noreturn { +fn __aeabi_memcmp() callconv(.Naked) noreturn { @setRuntimeSafety(false); if (use_thumb_1) { asm volatile ( diff --git a/lib/std/special/compiler_rt/arm/aeabi_dcmp.zig b/lib/std/special/compiler_rt/arm/aeabi_dcmp.zig index 7463c499316b..d75c343fbbf0 100644 --- a/lib/std/special/compiler_rt/arm/aeabi_dcmp.zig +++ b/lib/std/special/compiler_rt/arm/aeabi_dcmp.zig @@ -12,31 +12,31 @@ const ConditionalOperator = enum { Gt, }; -pub nakedcc fn __aeabi_dcmpeq() noreturn { +pub fn __aeabi_dcmpeq() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Eq}); unreachable; } -pub nakedcc fn __aeabi_dcmplt() noreturn { +pub fn __aeabi_dcmplt() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Lt}); unreachable; } -pub nakedcc fn __aeabi_dcmple() noreturn { +pub fn __aeabi_dcmple() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Le}); unreachable; } -pub nakedcc fn __aeabi_dcmpge() noreturn { +pub fn __aeabi_dcmpge() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Ge}); unreachable; } -pub nakedcc fn __aeabi_dcmpgt() noreturn { +pub fn __aeabi_dcmpgt() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Gt}); unreachable; diff --git a/lib/std/special/compiler_rt/arm/aeabi_fcmp.zig b/lib/std/special/compiler_rt/arm/aeabi_fcmp.zig index 9a24641d9a6b..bf36e78ad215 100644 --- a/lib/std/special/compiler_rt/arm/aeabi_fcmp.zig +++ b/lib/std/special/compiler_rt/arm/aeabi_fcmp.zig @@ -12,31 +12,31 @@ const ConditionalOperator = enum { Gt, }; -pub nakedcc fn __aeabi_fcmpeq() noreturn { +pub fn __aeabi_fcmpeq() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Eq}); unreachable; } -pub nakedcc fn __aeabi_fcmplt() noreturn { +pub fn __aeabi_fcmplt() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Lt}); unreachable; } -pub nakedcc fn __aeabi_fcmple() noreturn { +pub fn __aeabi_fcmple() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Le}); unreachable; } -pub nakedcc fn __aeabi_fcmpge() noreturn { +pub fn __aeabi_fcmpge() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Ge}); unreachable; } -pub nakedcc fn __aeabi_fcmpgt() noreturn { +pub fn __aeabi_fcmpgt() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Gt}); unreachable; diff --git a/lib/std/special/compiler_rt/aulldiv.zig b/lib/std/special/compiler_rt/aulldiv.zig index dfca4f4c43a2..afc96492c102 100644 --- a/lib/std/special/compiler_rt/aulldiv.zig +++ b/lib/std/special/compiler_rt/aulldiv.zig @@ -1,6 +1,6 @@ const builtin = @import("builtin"); -pub extern stdcallcc fn _alldiv(a: i64, b: i64) i64 { +pub extern fn _alldiv(a: i64, b: i64) callconv(.Stdcall) i64 { @setRuntimeSafety(builtin.is_test); const s_a = a >> (i64.bit_count - 1); const s_b = b >> (i64.bit_count - 1); @@ -13,7 +13,7 @@ pub extern stdcallcc fn _alldiv(a: i64, b: i64) i64 { return (@bitCast(i64, r) ^ s) -% s; } -pub nakedcc fn _aulldiv() void { +pub fn _aulldiv() callconv(.Naked) void { @setRuntimeSafety(false); // The stack layout is: diff --git a/lib/std/special/compiler_rt/aullrem.zig b/lib/std/special/compiler_rt/aullrem.zig index c1fee7203205..748aaa0f8917 100644 --- a/lib/std/special/compiler_rt/aullrem.zig +++ b/lib/std/special/compiler_rt/aullrem.zig @@ -1,6 +1,6 @@ const builtin = @import("builtin"); -pub extern stdcallcc fn _allrem(a: i64, b: i64) i64 { +pub extern fn _allrem(a: i64, b: i64) callconv(.Stdcall) i64 { @setRuntimeSafety(builtin.is_test); const s_a = a >> (i64.bit_count - 1); const s_b = b >> (i64.bit_count - 1); @@ -13,7 +13,7 @@ pub extern stdcallcc fn _allrem(a: i64, b: i64) i64 { return (@bitCast(i64, r) ^ s) -% s; } -pub nakedcc fn _aullrem() void { +pub fn _aullrem() callconv(.Naked) void { @setRuntimeSafety(false); // The stack layout is: diff --git a/lib/std/special/compiler_rt/stack_probe.zig b/lib/std/special/compiler_rt/stack_probe.zig index 6406f3977a9a..dd441b2f329f 100644 --- a/lib/std/special/compiler_rt/stack_probe.zig +++ b/lib/std/special/compiler_rt/stack_probe.zig @@ -1,7 +1,7 @@ const builtin = @import("builtin"); // Zig's own stack-probe routine (available only on x86 and x86_64) -pub nakedcc fn zig_probe_stack() void { +pub fn zig_probe_stack() callconv(.Naked) void { @setRuntimeSafety(false); // 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 { // ___chkstk (__alloca) | yes | yes | // ___chkstk_ms | no | no | -pub nakedcc fn _chkstk() void { +pub fn _chkstk() callconv(.Naked) void { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}); } -pub nakedcc fn __chkstk() void { +pub fn __chkstk() callconv(.Naked) void { @setRuntimeSafety(false); switch (builtin.arch) { .i386 => @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}), @@ -192,15 +192,15 @@ pub nakedcc fn __chkstk() void { else => unreachable, } } -pub nakedcc fn ___chkstk() void { +pub fn ___chkstk() callconv(.Naked) void { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}); } -pub nakedcc fn __chkstk_ms() void { +pub fn __chkstk_ms() callconv(.Naked) void { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{}); } -pub nakedcc fn ___chkstk_ms() void { +pub fn ___chkstk_ms() callconv(.Naked) void { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{}); } diff --git a/lib/std/spinlock.zig b/lib/std/spinlock.zig index 4efd24436779..1a3239a95cf6 100644 --- a/lib/std/spinlock.zig +++ b/lib/std/spinlock.zig @@ -60,8 +60,16 @@ pub const SpinLock = struct { switch (builtin.arch) { // these instructions use a memory clobber as they // flush the pipeline of any speculated reads/writes. - .i386, .x86_64 => asm volatile ("pause" ::: "memory"), - .arm, .aarch64 => asm volatile ("yield" ::: "memory"), + .i386, .x86_64 => asm volatile ("pause" + : + : + : "memory" + ), + .arm, .aarch64 => asm volatile ("yield" + : + : + : "memory" + ), else => std.os.sched_yield() catch {}, } } diff --git a/lib/std/start.zig b/lib/std/start.zig index 3c46449949d3..a91910726605 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -43,11 +43,11 @@ comptime { } } -stdcallcc fn _DllMainCRTStartup( +fn _DllMainCRTStartup( hinstDLL: std.os.windows.HINSTANCE, fdwReason: std.os.windows.DWORD, lpReserved: std.os.windows.LPVOID, -) std.os.windows.BOOL { +) callconv(.Stdcall) std.os.windows.BOOL { if (@hasDecl(root, "DllMain")) { return root.DllMain(hinstDLL, fdwReason, lpReserved); } @@ -84,7 +84,7 @@ extern fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) u } } -nakedcc fn _start() noreturn { +fn _start() callconv(.Naked) noreturn { if (builtin.os == builtin.Os.wasi) { // This is marked inline because for some reason LLVM in release mode fails to inline it, // and we want fewer call frames in stack traces. @@ -127,7 +127,7 @@ nakedcc fn _start() noreturn { @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{}); } -stdcallcc fn WinMainCRTStartup() noreturn { +fn WinMainCRTStartup() callconv(.Stdcall) noreturn { @setAlignStack(16); if (!builtin.single_threaded) { _ = @import("start_windows_tls.zig"); diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig index adbcef165e20..b921213f0c86 100644 --- a/lib/std/zig/ast.zig +++ b/lib/std/zig/ast.zig @@ -860,6 +860,7 @@ pub const Node = struct { lib_name: ?*Node, // populated if this is an extern declaration align_expr: ?*Node, // populated if align(A) is present section_expr: ?*Node, // populated if linksection(A) is present + callconv_expr: ?*Node, // populated if callconv(A) is present pub const ParamList = SegmentedList(*Node, 2); diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index 14d5a0a400b9..c9c995615920 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -311,6 +311,7 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { const rparen = try expectToken(it, tree, .RParen); const align_expr = try parseByteAlign(arena, it, tree); const section_expr = try parseLinkSection(arena, it, tree); + const callconv_expr = try parseCallconv(arena, it, tree); const exclamation_token = eatToken(it, .Bang); const return_type_expr = (try parseVarType(arena, it, tree)) orelse @@ -347,6 +348,7 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { .lib_name = null, .align_expr = align_expr, .section_expr = section_expr, + .callconv_expr = callconv_expr, }; if (cc) |kind| { @@ -1678,6 +1680,17 @@ fn parseLinkSection(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node return expr_node; } +/// CallConv <- KEYWORD_callconv LPAREN Expr RPAREN +fn parseCallconv(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { + _ = eatToken(it, .Keyword_callconv) orelse return null; + _ = try expectToken(it, tree, .LParen); + const expr_node = try expectNode(arena, it, tree, parseExpr, AstError{ + .ExpectedExpr = AstError.ExpectedExpr{ .token = it.index }, + }); + _ = try expectToken(it, tree, .RParen); + return expr_node; +} + /// FnCC /// <- KEYWORD_nakedcc /// / KEYWORD_stdcallcc diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index f193e1b6ef3d..bd6dabdc5228 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -9,6 +9,18 @@ test "zig fmt: change @typeOf to @TypeOf" { ); } +// TODO: Remove nakedcc/stdcallcc once zig 0.6.0 is released. See https://github.com/ziglang/zig/pull/3977 +test "zig fmt: convert nakedcc/stdcallcc into callconv(...)" { + try testTransform( + \\nakedcc fn foo1() void {} + \\stdcallcc fn foo2() void {} + , + \\fn foo1() callconv(.Naked) void {} + \\fn foo2() callconv(.Stdcall) void {} + \\ + ); +} + test "zig fmt: comptime struct field" { try testCanonical( \\const Foo = struct { @@ -219,7 +231,7 @@ test "zig fmt: threadlocal" { test "zig fmt: linksection" { try testCanonical( \\export var aoeu: u64 linksection(".text.derp") = 1234; - \\export nakedcc fn _start() linksection(".text.boot") noreturn {} + \\export fn _start() linksection(".text.boot") callconv(.Naked) noreturn {} \\ ); } @@ -2311,7 +2323,7 @@ test "zig fmt: fn type" { \\ \\const a: fn (u8) u8 = undefined; \\const b: extern fn (u8) u8 = undefined; - \\const c: nakedcc fn (u8) u8 = undefined; + \\const c: fn (u8) callconv(.Naked) u8 = undefined; \\const ap: fn (u8) u8 = a; \\ ); diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 6e1ee4a601c7..a6f37d19b081 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -1295,8 +1295,16 @@ fn renderExpression( try renderExpression(allocator, stream, tree, indent, start_col, lib_name, Space.Space); } + // Some extra machinery is needed to rewrite the old-style cc + // notation to the new callconv one + var cc_rewrite_str: ?[*:0]const u8 = null; if (fn_proto.cc_token) |cc_token| { - try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc + var str = tree.tokenSlicePtr(tree.tokens.at(cc_token)); + if (mem.eql(u8, str, "stdcallcc")) { + cc_rewrite_str = ".Stdcall"; + } else if (mem.eql(u8, str, "nakedcc")) { + cc_rewrite_str = ".Naked"; + } else try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc } const lparen = if (fn_proto.name_token) |name_token| blk: { @@ -1368,6 +1376,21 @@ fn renderExpression( try renderToken(tree, stream, section_rparen, indent, start_col, Space.Space); // ) } + if (fn_proto.callconv_expr) |callconv_expr| { + const callconv_rparen = tree.nextToken(callconv_expr.lastToken()); + const callconv_lparen = tree.prevToken(callconv_expr.firstToken()); + const callconv_kw = tree.prevToken(callconv_lparen); + + try renderToken(tree, stream, callconv_kw, indent, start_col, Space.None); // section + try renderToken(tree, stream, callconv_lparen, indent, start_col, Space.None); // ( + try renderExpression(allocator, stream, tree, indent, start_col, callconv_expr, Space.None); + try renderToken(tree, stream, callconv_rparen, indent, start_col, Space.Space); // ) + } else if (cc_rewrite_str) |str| { + try stream.write("callconv("); + try stream.write(mem.toSliceConst(u8, str)); + try stream.write(") "); + } + switch (fn_proto.return_type) { ast.Node.FnProto.ReturnType.Explicit => |node| { return renderExpression(allocator, stream, tree, indent, start_col, node, space); diff --git a/lib/std/zig/tokenizer.zig b/lib/std/zig/tokenizer.zig index d95fb47d41ac..327700f59141 100644 --- a/lib/std/zig/tokenizer.zig +++ b/lib/std/zig/tokenizer.zig @@ -30,6 +30,7 @@ pub const Token = struct { Keyword.init("async", .Keyword_async), Keyword.init("await", .Keyword_await), Keyword.init("break", .Keyword_break), + Keyword.init("callconv", .Keyword_callconv), Keyword.init("catch", .Keyword_catch), Keyword.init("comptime", .Keyword_comptime), Keyword.init("const", .Keyword_const), @@ -162,6 +163,7 @@ pub const Token = struct { Keyword_async, Keyword_await, Keyword_break, + Keyword_callconv, Keyword_catch, Keyword_comptime, Keyword_const, @@ -286,6 +288,7 @@ pub const Token = struct { .Keyword_async => "async", .Keyword_await => "await", .Keyword_break => "break", + .Keyword_callconv => "callconv", .Keyword_catch => "catch", .Keyword_comptime => "comptime", .Keyword_const => "const", diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index b49989732e30..1323c1a86d5d 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -11,7 +11,7 @@ const CToken = ctok.CToken; const mem = std.mem; const math = std.math; -const CallingConvention = std.builtin.TypeInfo.CallingConvention; +const CallingConvention = std.builtin.CallingConvention; pub const ClangErrMsg = Stage2ErrorMsg; @@ -3529,6 +3529,7 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a .lib_name = null, .align_expr = null, .section_expr = null, + .callconv_expr = null, }; const block = try transCreateNodeBlock(c, null); @@ -3972,6 +3973,11 @@ fn transCC( switch (clang_cc) { .C => return CallingConvention.C, .X86StdCall => return CallingConvention.Stdcall, + .X86FastCall => return CallingConvention.Fastcall, + .X86VectorCall, .AArch64VectorCall => return CallingConvention.Vectorcall, + .X86ThisCall => return CallingConvention.Thiscall, + .AAPCS => return CallingConvention.AAPCS, + .AAPCS_VFP => return CallingConvention.AAPCSVFP, else => return revertAndWarn( rp, error.UnsupportedType, @@ -4027,7 +4033,6 @@ fn finishTransFnProto( // pub extern fn name(...) T const pub_tok = if (is_pub) try appendToken(rp.c, .Keyword_pub, "pub") else null; - const cc_tok = if (cc == .Stdcall) try appendToken(rp.c, .Keyword_stdcallcc, "stdcallcc") else null; const extern_export_inline_tok = if (is_export) try appendToken(rp.c, .Keyword_export, "export") else if (cc == .C and is_extern) @@ -4100,6 +4105,14 @@ fn finishTransFnProto( const rparen_tok = try appendToken(rp.c, .RParen, ")"); + const callconv_expr = if (extern_export_inline_tok != null) null else blk: { + _ = try appendToken(rp.c, .Keyword_callconv, "callconv"); + _ = try appendToken(rp.c, .LParen, "("); + const expr = try transCreateNodeEnumLiteral(rp.c, @tagName(cc)); + _ = try appendToken(rp.c, .RParen, ")"); + break :blk expr; + }; + const return_type_node = blk: { if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) { break :blk try transCreateNodeIdentifier(rp.c, "noreturn"); @@ -4130,11 +4143,12 @@ fn finishTransFnProto( .return_type = .{ .Explicit = return_type_node }, .var_args_token = null, // TODO this field is broken in the AST data model .extern_export_inline_token = extern_export_inline_tok, - .cc_token = cc_tok, + .cc_token = null, .body_node = null, .lib_name = null, .align_expr = null, .section_expr = null, + .callconv_expr = callconv_expr, }; return fn_proto; } @@ -4483,6 +4497,7 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u .lib_name = null, .align_expr = null, .section_expr = null, + .callconv_expr = null, }; const block = try transCreateNodeBlock(c, null); diff --git a/src-self-hosted/type.zig b/src-self-hosted/type.zig index d3f3ba746a74..d4ffc355c0fb 100644 --- a/src-self-hosted/type.zig +++ b/src-self-hosted/type.zig @@ -337,7 +337,7 @@ pub const Type = struct { } }; - const CallingConvention = builtin.TypeInfo.CallingConvention; + const CallingConvention = builtin.CallingConvention; pub const Param = struct { is_noalias: bool, @@ -352,6 +352,7 @@ pub const Type = struct { .Naked => "nakedcc ", .Stdcall => "stdcallcc ", .Async => "async ", + else => unreachable, }; } diff --git a/src/all_types.hpp b/src/all_types.hpp index ea46ab81a6dd..9ce29b6873b8 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -57,6 +57,23 @@ enum PtrLen { PtrLenC, }; +enum CallingConvention { + CallingConventionUnspecified, + CallingConventionC, + CallingConventionCold, + CallingConventionNaked, + CallingConventionAsync, + CallingConventionInterrupt, + CallingConventionSignal, + CallingConventionStdcall, + CallingConventionFastcall, + CallingConventionVectorcall, + CallingConventionThiscall, + CallingConventionAPCS, + CallingConventionAAPCS, + CallingConventionAAPCSVFP, +}; + // This one corresponds to the builtin.zig enum. enum BuiltinPtrSize { BuiltinPtrSizeOne, @@ -398,6 +415,7 @@ struct LazyValueFnType { IrInstruction *align_inst; // can be null IrInstruction *return_type; + CallingConvention cc; bool is_generic; }; @@ -612,15 +630,6 @@ enum NodeType { NodeTypeVarFieldType, }; -enum CallingConvention { - CallingConventionUnspecified, - CallingConventionC, - CallingConventionCold, - CallingConventionNaked, - CallingConventionStdcall, - CallingConventionAsync, -}; - enum FnInline { FnInlineAuto, FnInlineAlways, @@ -639,10 +648,14 @@ struct AstNodeFnProto { AstNode *align_expr; // populated if the "section(S)" is present AstNode *section_expr; + // populated if the "callconv(S)" is present + AstNode *callconv_expr; Buf doc_comments; FnInline fn_inline; - CallingConvention cc; + bool is_nakedcc; + bool is_stdcallcc; + bool is_async; VisibMod visib_mod; bool auto_err_set; @@ -1597,6 +1610,7 @@ struct ZigFn { Buf **param_names; IrInstruction *err_code_spill; AstNode *assumed_non_async; + CallingConvention cc; AstNode *fn_no_inline_set_node; AstNode *fn_static_eval_set_node; @@ -3549,6 +3563,7 @@ struct IrInstructionFnProto { IrInstruction **param_types; IrInstruction *align_value; + IrInstruction *callconv_value; IrInstruction *return_type; bool is_var_args; }; diff --git a/src/analyze.cpp b/src/analyze.cpp index 8be25b759251..b71d3322a14f 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -919,24 +919,20 @@ ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry) { const char *calling_convention_name(CallingConvention cc) { switch (cc) { - case CallingConventionUnspecified: return "undefined"; - case CallingConventionC: return "ccc"; - case CallingConventionCold: return "coldcc"; - case CallingConventionNaked: return "nakedcc"; - case CallingConventionStdcall: return "stdcallcc"; - case CallingConventionAsync: return "async"; - } - zig_unreachable(); -} - -static const char *calling_convention_fn_type_str(CallingConvention cc) { - switch (cc) { - case CallingConventionUnspecified: return ""; - case CallingConventionC: return "extern "; - case CallingConventionCold: return "coldcc "; - case CallingConventionNaked: return "nakedcc "; - case CallingConventionStdcall: return "stdcallcc "; - case CallingConventionAsync: return "async "; + case CallingConventionUnspecified: return "Unspecified"; + case CallingConventionC: return "C"; + case CallingConventionCold: return "Cold"; + case CallingConventionNaked: return "Naked"; + case CallingConventionAsync: return "Async"; + case CallingConventionInterrupt: return "Interrupt"; + case CallingConventionSignal: return "Signal"; + case CallingConventionStdcall: return "Stdcall"; + case CallingConventionFastcall: return "Fastcall"; + case CallingConventionVectorcall: return "Vectorcall"; + case CallingConventionThiscall: return "Thiscall"; + case CallingConventionAPCS: return "Apcs"; + case CallingConventionAAPCS: return "Aapcs"; + case CallingConventionAAPCSVFP: return "Aapcsvfp"; } zig_unreachable(); } @@ -949,7 +945,15 @@ bool calling_convention_allows_zig_types(CallingConvention cc) { case CallingConventionC: case CallingConventionCold: case CallingConventionNaked: + case CallingConventionInterrupt: + case CallingConventionSignal: case CallingConventionStdcall: + case CallingConventionFastcall: + case CallingConventionVectorcall: + case CallingConventionThiscall: + case CallingConventionAPCS: + case CallingConventionAAPCS: + case CallingConventionAAPCSVFP: return false; } zig_unreachable(); @@ -1006,8 +1010,8 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { // populate the name of the type buf_resize(&fn_type->name, 0); - const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc); - buf_appendf(&fn_type->name, "%s", cc_str); + if (fn_type->data.fn.fn_type_id.cc == CallingConventionC) + buf_append_str(&fn_type->name, "extern "); buf_appendf(&fn_type->name, "fn("); for (size_t i = 0; i < fn_type_id->param_count; i += 1) { FnTypeParamInfo *param_info = &fn_type_id->param_info[i]; @@ -1026,6 +1030,9 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { if (fn_type_id->alignment != 0) { buf_appendf(&fn_type->name, " align(%" PRIu32 ")", fn_type_id->alignment); } + if (fn_type_id->cc != CallingConventionUnspecified && fn_type_id->cc != CallingConventionC) { + buf_appendf(&fn_type->name, " callconv(%s)", calling_convention_name(fn_type_id->cc)); + } buf_appendf(&fn_type->name, " %s", buf_ptr(&fn_type_id->return_type->name)); // The fn_type is a pointer; not to be confused with the raw function type. @@ -1442,8 +1449,8 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) { ZigType *fn_type = new_type_table_entry(ZigTypeIdFn); buf_resize(&fn_type->name, 0); - const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc); - buf_appendf(&fn_type->name, "%s", cc_str); + if (fn_type->data.fn.fn_type_id.cc == CallingConventionC) + buf_append_str(&fn_type->name, "extern "); buf_appendf(&fn_type->name, "fn("); size_t i = 0; for (; i < fn_type_id->next_param_index; i += 1) { @@ -1455,7 +1462,11 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) { const char *comma_str = (i == 0) ? "" : ","; buf_appendf(&fn_type->name, "%svar", comma_str); } - buf_appendf(&fn_type->name, ")var"); + buf_append_str(&fn_type->name, ")"); + if (fn_type_id->cc != CallingConventionUnspecified && fn_type_id->cc != CallingConventionC) { + buf_appendf(&fn_type->name, " callconv(%s)", calling_convention_name(fn_type_id->cc)); + } + buf_append_str(&fn_type->name, " var"); fn_type->data.fn.fn_type_id = *fn_type_id; fn_type->data.fn.is_generic = true; @@ -1465,17 +1476,25 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) { return fn_type; } -void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc) { +CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto) { + if (fn_proto->is_nakedcc) + return CallingConventionNaked; + if (fn_proto->is_stdcallcc) + return CallingConventionStdcall; + if (fn_proto->is_async) + return CallingConventionAsync; + // Compatible with the C ABI + if (fn_proto->is_extern || fn_proto->is_export) + return CallingConventionC; + + return CallingConventionUnspecified; +} + +void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, CallingConvention cc, size_t param_count_alloc) { assert(proto_node->type == NodeTypeFnProto); AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; - if (fn_proto->cc == CallingConventionUnspecified) { - bool extern_abi = fn_proto->is_extern || fn_proto->is_export; - fn_type_id->cc = extern_abi ? CallingConventionC : CallingConventionUnspecified; - } else { - fn_type_id->cc = fn_proto->cc; - } - + fn_type_id->cc = cc; fn_type_id->param_count = fn_proto->params.length; fn_type_id->param_info = allocate