authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-06 14:07:56-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-06 14:07:56-05:00
log0a9daeb37e997ff75dcd16d1fc3b4cc143314e85
tree05ca7f6b64b1e40fc16a595816f3a632a986617c
parentc30106c90665079f525129e344cc1c13e4db162b
parentd09bd3d86c4d36ad608a91b36c9a6eb6208c9626
signature Commit is signed but in an unrecognized format.

Merge branch 'cc-work' of https://github.com/LemonBoy/zig into LemonBoy-cc-work


54 files changed, 822 insertions(+), 413 deletions(-)

doc/docgen.zig+1
......@@ -818,6 +818,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
818818 .Keyword_resume,
819819 .Keyword_return,
820820 .Keyword_linksection,
821 .Keyword_callconv,
821822 .Keyword_stdcallcc,
822823 .Keyword_struct,
823824 .Keyword_suspend,
doc/langref.html.in+1-1
......@@ -2829,7 +2829,7 @@ test "@tagName" {
28292829 <p>
28302830 By default, enums are not guaranteed to be compatible with the C ABI:
28312831 </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'#}
28332833const Foo = enum { A, B, C };
28342834export fn entry(foo: Foo) void { }
28352835 {#code_end#}
lib/std/build/translate_c.zig+23-9
......@@ -14,6 +14,7 @@ pub const TranslateCStep = struct {
1414 source: build.FileSource,
1515 output_dir: ?[]const u8,
1616 out_basename: []const u8,
17 target: std.Target = .Native,
1718
1819 pub fn create(builder: *Builder, source: build.FileSource) *TranslateCStep {
1920 const self = builder.allocator.create(TranslateCStep) catch unreachable;
......@@ -38,6 +39,10 @@ pub const TranslateCStep = struct {
3839 ) catch unreachable;
3940 }
4041
42 pub fn setTarget(self: *TranslateCStep, target: std.Target) void {
43 self.target = target;
44 }
45
4146 /// Creates a step to build an executable from the translated source.
4247 pub fn addExecutable(self: *TranslateCStep) *LibExeObjStep {
4348 return self.builder.addExecutableSource("translated_c", @as(build.FileSource, .{ .translate_c = self }));
......@@ -50,16 +55,25 @@ pub const TranslateCStep = struct {
5055 fn make(step: *Step) !void {
5156 const self = @fieldParentPtr(TranslateCStep, "step", step);
5257
53 const argv = [_][]const u8{
54 self.builder.zig_exe,
55 "translate-c",
56 "-lc",
57 "--cache",
58 "on",
59 self.source.getPath(self.builder),
60 };
58 var argv_list = std.ArrayList([]const u8).init(self.builder.allocator);
59 try argv_list.append(self.builder.zig_exe);
60 try argv_list.append("translate-c");
61 try argv_list.append("-lc");
62
63 try argv_list.append("--cache");
64 try argv_list.append("on");
65
66 switch (self.target) {
67 .Native => {},
68 .Cross => {
69 try argv_list.append("-target");
70 try argv_list.append(try self.target.zigTriple(self.builder.allocator));
71 },
72 }
73
74 try argv_list.append(self.source.getPath(self.builder));
6175
62 const output_path_nl = try self.builder.exec(&argv);
76 const output_path_nl = try self.builder.exec(argv_list.toSliceConst());
6377 const output_path = mem.trimRight(u8, output_path_nl, "\r\n");
6478
6579 self.out_basename = fs.path.basename(output_path);
lib/std/builtin.zig+20-12
......@@ -91,6 +91,25 @@ pub const Mode = enum {
9191 ReleaseSmall,
9292};
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 Thiscall,
108 APCS,
109 AAPCS,
110 AAPCSVFP,
111};
112
94113pub const TypeId = @TagType(TypeInfo);
95114
96115/// This data structure is used by the Zig language code generation and
......@@ -253,17 +272,6 @@ pub const TypeInfo = union(enum) {
253272 decls: []Declaration,
254273 };
255274
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
267275 /// This data structure is used by the Zig language code generation and
268276 /// therefore must be kept in sync with the compiler implementation.
269277 pub const FnArg = struct {
......@@ -416,7 +424,7 @@ pub const CallOptions = struct {
416424/// therefore must be kept in sync with the compiler implementation.
417425pub const TestFn = struct {
418426 name: []const u8,
419 func: fn()anyerror!void,
427 func: fn () anyerror!void,
420428};
421429
422430/// 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
24752475 os.abort();
24762476}
24772477
2478stdcallcc fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) c_long {
2478fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) callconv(.Stdcall) c_long {
24792479 const exception_address = @ptrToInt(info.ExceptionRecord.ExceptionAddress);
24802480 switch (info.ExceptionRecord.ExceptionCode) {
24812481 windows.EXCEPTION_DATATYPE_MISALIGNMENT => panicExtra(null, exception_address, "Unaligned Memory Access", .{}),
lib/std/mutex.zig+14-13
......@@ -73,8 +73,8 @@ pub const Mutex = if (builtin.single_threaded)
7373 return self.tryAcquire() orelse @panic("deadlock detected");
7474 }
7575 }
76else if (builtin.os == .windows)
77 // https://locklessinc.com/articles/keyed_events/
76else if (builtin.os == .windows)
77// https://locklessinc.com/articles/keyed_events/
7878 extern union {
7979 locked: u8,
8080 waiters: u32,
......@@ -122,8 +122,8 @@ else if (builtin.os == .windows)
122122 return Held{ .mutex = self };
123123 }
124124
125 // otherwise, try and update the waiting count.
126 // then unset the WAKE bit so that another unlocker can wake up a thread.
125 // otherwise, try and update the waiting count.
126 // then unset the WAKE bit so that another unlocker can wake up a thread.
127127 } else if (@cmpxchgWeak(u32, &self.waiters, waiters, (waiters + WAIT) | 1, .Monotonic, .Monotonic) == null) {
128128 const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null);
129129 assert(rc == 0);
......@@ -143,7 +143,7 @@ else if (builtin.os == .windows)
143143
144144 while (true) : (SpinLock.loopHint(1)) {
145145 const waiters = @atomicLoad(u32, &self.mutex.waiters, .Monotonic);
146
146
147147 // no one is waiting
148148 if (waiters < WAIT) return;
149149 // someone grabbed the lock and will do the wake instead
......@@ -155,14 +155,14 @@ else if (builtin.os == .windows)
155155 if (@cmpxchgWeak(u32, &self.mutex.waiters, waiters, waiters - WAIT + WAKE, .Release, .Monotonic) == null) {
156156 const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null);
157157 assert(rc == 0);
158 return;
158 return;
159159 }
160160 }
161161 }
162162 };
163163 }
164164else if (builtin.link_libc or builtin.os == .linux)
165 // stack-based version of https://github.com/Amanieu/parking_lot/blob/master/core/src/word_lock.rs
165// stack-based version of https://github.com/Amanieu/parking_lot/blob/master/core/src/word_lock.rs
166166 struct {
167167 state: usize,
168168
......@@ -195,8 +195,8 @@ else if (builtin.link_libc or builtin.os == .linux)
195195
196196 pub fn acquire(self: *Mutex) Held {
197197 return self.tryAcquire() orelse {
198 self.acquireSlow();
199 return Held{ .mutex = self };
198 self.acquireSlow();
199 return Held{ .mutex = self };
200200 };
201201 }
202202
......@@ -265,7 +265,7 @@ else if (builtin.link_libc or builtin.os == .linux)
265265
266266 fn releaseSlow(self: *Mutex) void {
267267 @setCold(true);
268
268
269269 // try and lock the LFIO queue to pop a node off,
270270 // stopping altogether if its already locked or the queue is empty
271271 var state = @atomicLoad(usize, &self.state, .Monotonic);
......@@ -293,9 +293,10 @@ else if (builtin.link_libc or builtin.os == .linux)
293293 }
294294 }
295295
296// for platforms without a known OS blocking
297// primitive, default to SpinLock for correctness
298else SpinLock;
296 // for platforms without a known OS blocking
297 // primitive, default to SpinLock for correctness
298else
299 SpinLock;
299300
300301const TestContext = struct {
301302 mutex: *Mutex,
lib/std/net.zig+1-5
......@@ -451,11 +451,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
451451 .next = null,
452452 };
453453 var res: *os.addrinfo = undefined;
454 switch (os.system.getaddrinfo(
455 name_c.ptr,
456 @ptrCast([*:0]const u8, port_c.ptr),
457 &hints,
458 &res)) {
454 switch (os.system.getaddrinfo(name_c.ptr, @ptrCast([*:0]const u8, port_c.ptr), &hints, &res)) {
459455 0 => {},
460456 c.EAI_ADDRFAMILY => return error.HostLacksNetworkAddresses,
461457 c.EAI_AGAIN => return error.TemporaryNameServerFailure,
lib/std/os/linux/arm-eabi.zig+2-2
......@@ -97,7 +97,7 @@ pub extern fn getThreadPointer() usize {
9797 );
9898}
9999
100pub nakedcc fn restore() void {
100pub fn restore() callconv(.Naked) void {
101101 return asm volatile ("svc #0"
102102 :
103103 : [number] "{r7}" (@as(usize, SYS_sigreturn))
......@@ -105,7 +105,7 @@ pub nakedcc fn restore() void {
105105 );
106106}
107107
108pub nakedcc fn restore_rt() void {
108pub fn restore_rt() callconv(.Naked) void {
109109 return asm volatile ("svc #0"
110110 :
111111 : [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
9090
9191pub const restore = restore_rt;
9292
93pub nakedcc fn restore_rt() void {
93pub fn restore_rt() callconv(.Naked) void {
9494 return asm volatile ("svc #0"
9595 :
9696 : [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 {
102102/// This matches the libc clone function.
103103pub 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 {
106106 return asm volatile ("int $0x80"
107107 :
108108 : [number] "{eax}" (@as(usize, SYS_sigreturn))
......@@ -110,7 +110,7 @@ pub nakedcc fn restore() void {
110110 );
111111}
112112
113pub nakedcc fn restore_rt() void {
113pub fn restore_rt() callconv(.Naked) void {
114114 return asm volatile ("int $0x80"
115115 :
116116 : [number] "{eax}" (@as(usize, SYS_rt_sigreturn))
lib/std/os/linux/mipsel.zig+2-2
......@@ -144,7 +144,7 @@ pub fn syscall6(
144144/// This matches the libc clone function.
145145pub 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 {
148148 return asm volatile ("syscall"
149149 :
150150 : [number] "{$2}" (@as(usize, SYS_sigreturn))
......@@ -152,7 +152,7 @@ pub nakedcc fn restore() void {
152152 );
153153}
154154
155pub nakedcc fn restore_rt() void {
155pub fn restore_rt() callconv(.Naked) void {
156156 return asm volatile ("syscall"
157157 :
158158 : [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
8989
9090pub const restore = restore_rt;
9191
92pub nakedcc fn restore_rt() void {
92pub fn restore_rt() callconv(.Naked) void {
9393 return asm volatile ("ecall"
9494 :
9595 : [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,
9090
9191pub const restore = restore_rt;
9292
93pub nakedcc fn restore_rt() void {
93pub fn restore_rt() callconv(.Naked) void {
9494 return asm volatile ("syscall"
9595 :
9696 : [number] "{rax}" (@as(usize, SYS_rt_sigreturn))
lib/std/os/test.zig+1-1
......@@ -166,7 +166,7 @@ test "sigaltstack" {
166166// analyzed
167167const 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 {
170170 if (builtin.os == .windows or builtin.os == .wasi or builtin.os == .macosx)
171171 return 0;
172172
lib/std/os/uefi/protocols/simple_text_input_protocol.zig-1
......@@ -27,4 +27,3 @@ pub const SimpleTextInputProtocol = extern struct {
2727 .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b },
2828 };
2929};
30
lib/std/os/windows/advapi32.zig+5-5
......@@ -1,23 +1,23 @@
11usingnamespace @import("bits.zig");
22
3pub extern "advapi32" stdcallcc fn RegOpenKeyExW(
3pub extern "advapi32" fn RegOpenKeyExW(
44 hKey: HKEY,
55 lpSubKey: LPCWSTR,
66 ulOptions: DWORD,
77 samDesired: REGSAM,
88 phkResult: *HKEY,
9) LSTATUS;
9) callconv(.Stdcall) LSTATUS;
1010
11pub extern "advapi32" stdcallcc fn RegQueryValueExW(
11pub extern "advapi32" fn RegQueryValueExW(
1212 hKey: HKEY,
1313 lpValueName: LPCWSTR,
1414 lpReserved: LPDWORD,
1515 lpType: LPDWORD,
1616 lpData: LPBYTE,
1717 lpcbData: LPDWORD,
18) LSTATUS;
18) callconv(.Stdcall) LSTATUS;
1919
2020// RtlGenRandom is known as SystemFunction036 under advapi32
2121// 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;
2323pub const RtlGenRandom = SystemFunction036;
lib/std/os/windows/bits.zig+1-1
......@@ -892,7 +892,7 @@ pub const EXCEPTION_POINTERS = extern struct {
892892 ContextRecord: *c_void,
893893};
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
897897pub const OBJECT_ATTRIBUTES = extern struct {
898898 Length: ULONG,
lib/std/os/windows/kernel32.zig+100-100
......@@ -1,22 +1,22 @@
11usingnamespace @import("bits.zig");
22
3pub extern "kernel32" stdcallcc fn AddVectoredExceptionHandler(First: c_ulong, Handler: ?VECTORED_EXCEPTION_HANDLER) ?*c_void;
4pub extern "kernel32" stdcallcc fn RemoveVectoredExceptionHandler(Handle: HANDLE) c_ulong;
3pub extern "kernel32" fn AddVectoredExceptionHandler(First: c_ulong, Handler: ?VECTORED_EXCEPTION_HANDLER) callconv(.Stdcall) ?*c_void;
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(
1313 lpEventAttributes: ?*SECURITY_ATTRIBUTES,
1414 lpName: [*:0]const u16,
1515 dwFlags: DWORD,
1616 dwDesiredAccess: DWORD,
17) ?HANDLE;
17) callconv(.Stdcall) ?HANDLE;
1818
19pub extern "kernel32" stdcallcc fn CreateFileW(
19pub extern "kernel32" fn CreateFileW(
2020 lpFileName: [*]const u16, // TODO null terminated pointer type
2121 dwDesiredAccess: DWORD,
2222 dwShareMode: DWORD,
......@@ -24,16 +24,16 @@ pub extern "kernel32" stdcallcc fn CreateFileW(
2424 dwCreationDisposition: DWORD,
2525 dwFlagsAndAttributes: DWORD,
2626 hTemplateFile: ?HANDLE,
27) HANDLE;
27) callconv(.Stdcall) HANDLE;
2828
29pub extern "kernel32" stdcallcc fn CreatePipe(
29pub extern "kernel32" fn CreatePipe(
3030 hReadPipe: *HANDLE,
3131 hWritePipe: *HANDLE,
3232 lpPipeAttributes: *const SECURITY_ATTRIBUTES,
3333 nSize: DWORD,
34) BOOL;
34) callconv(.Stdcall) BOOL;
3535
36pub extern "kernel32" stdcallcc fn CreateProcessW(
36pub extern "kernel32" fn CreateProcessW(
3737 lpApplicationName: ?LPWSTR,
3838 lpCommandLine: LPWSTR,
3939 lpProcessAttributes: ?*SECURITY_ATTRIBUTES,
......@@ -44,15 +44,15 @@ pub extern "kernel32" stdcallcc fn CreateProcessW(
4444 lpCurrentDirectory: ?LPWSTR,
4545 lpStartupInfo: *STARTUPINFOW,
4646 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(
5656 h: HANDLE,
5757 dwIoControlCode: DWORD,
5858 lpInBuffer: ?*const c_void,
......@@ -61,107 +61,107 @@ pub extern "kernel32" stdcallcc fn DeviceIoControl(
6161 nOutBufferSize: DWORD,
6262 lpBytesReturned: ?*DWORD,
6363 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;
73pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL;
74pub extern "kernel32" stdcallcc fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) BOOL;
72pub extern "kernel32" fn FindFirstFileW(lpFileName: [*]const u16, lpFindFileData: *WIN32_FIND_DATAW) callconv(.Stdcall) HANDLE;
73pub extern "kernel32" fn FindClose(hFindFile: HANDLE) callconv(.Stdcall) 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;
89pub extern "kernel32" stdcallcc fn GetCurrentThreadId() DWORD;
88pub extern "kernel32" fn GetCurrentThread() callconv(.Stdcall) HANDLE;
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(
108108 hFile: HANDLE,
109109 lpFileInformation: *BY_HANDLE_FILE_INFORMATION,
110) BOOL;
110) callconv(.Stdcall) BOOL;
111111
112pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx(
112pub extern "kernel32" fn GetFileInformationByHandleEx(
113113 in_hFile: HANDLE,
114114 in_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,
115115 out_lpFileInformation: *c_void,
116116 in_dwBufferSize: DWORD,
117) BOOL;
117) callconv(.Stdcall) BOOL;
118118
119pub extern "kernel32" stdcallcc fn GetFinalPathNameByHandleW(
119pub extern "kernel32" fn GetFinalPathNameByHandleW(
120120 hFile: HANDLE,
121121 lpszFilePath: [*]u16,
122122 cchFilePath: DWORD,
123123 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;
129pub extern "kernel32" stdcallcc fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) BOOL;
128pub extern "kernel32" fn GetProcessHeap() callconv(.Stdcall) ?HANDLE;
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;
132pub extern "kernel32" stdcallcc fn GetSystemTimeAsFileTime(*FILETIME) void;
131pub extern "kernel32" fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) callconv(.Stdcall) 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;
135pub extern "kernel32" stdcallcc fn HeapDestroy(hHeap: HANDLE) BOOL;
136pub extern "kernel32" stdcallcc fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void, dwBytes: SIZE_T) ?*c_void;
137pub extern "kernel32" stdcallcc fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) SIZE_T;
138pub extern "kernel32" stdcallcc fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) SIZE_T;
139pub extern "kernel32" stdcallcc fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) BOOL;
134pub extern "kernel32" fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) callconv(.Stdcall) ?HANDLE;
135pub extern "kernel32" fn HeapDestroy(hHeap: HANDLE) callconv(.Stdcall) BOOL;
136pub extern "kernel32" fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void, dwBytes: SIZE_T) callconv(.Stdcall) ?*c_void;
137pub extern "kernel32" fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) callconv(.Stdcall) SIZE_T;
138pub extern "kernel32" fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) callconv(.Stdcall) SIZE_T;
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;
150pub extern "kernel32" stdcallcc fn VirtualFree(lpAddress: ?LPVOID, dwSize: SIZE_T, dwFreeType: DWORD) BOOL;
149pub extern "kernel32" fn VirtualAlloc(lpAddress: ?LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD) callconv(.Stdcall) ?LPVOID;
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(
153153 lpExistingFileName: [*]const u16,
154154 lpNewFileName: [*]const u16,
155155 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(
165165 hDirectory: HANDLE,
166166 lpBuffer: [*]align(@alignOf(FILE_NOTIFY_INFORMATION)) u8,
167167 nBufferLength: DWORD,
......@@ -170,79 +170,79 @@ pub extern "kernel32" stdcallcc fn ReadDirectoryChangesW(
170170 lpBytesReturned: ?*DWORD,
171171 lpOverlapped: ?*OVERLAPPED,
172172 lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE,
173) BOOL;
173) callconv(.Stdcall) BOOL;
174174
175pub extern "kernel32" stdcallcc fn ReadFile(
175pub extern "kernel32" fn ReadFile(
176176 in_hFile: HANDLE,
177177 out_lpBuffer: [*]u8,
178178 in_nNumberOfBytesToRead: DWORD,
179179 out_lpNumberOfBytesRead: ?*DWORD,
180180 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(
188188 in_fFile: HANDLE,
189189 in_liDistanceToMove: LARGE_INTEGER,
190190 out_opt_ldNewFilePointer: ?*LARGE_INTEGER,
191191 in_dwMoveMethod: DWORD,
192) BOOL;
192) callconv(.Stdcall) BOOL;
193193
194pub extern "kernel32" stdcallcc fn SetFileTime(
194pub extern "kernel32" fn SetFileTime(
195195 hFile: HANDLE,
196196 lpCreationTime: ?*const FILETIME,
197197 lpLastAccessTime: ?*const FILETIME,
198198 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(
220220 nCount: DWORD,
221221 lpHandle: [*]const HANDLE,
222222 bWaitAll: BOOL,
223223 dwMilliseconds: DWORD,
224224 bAlertable: BOOL,
225) DWORD;
225) callconv(.Stdcall) DWORD;
226226
227pub extern "kernel32" stdcallcc fn WriteFile(
227pub extern "kernel32" fn WriteFile(
228228 in_hFile: HANDLE,
229229 in_lpBuffer: [*]const u8,
230230 in_nNumberOfBytesToWrite: DWORD,
231231 out_lpNumberOfBytesWritten: ?*DWORD,
232232 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;
244pub extern "kernel32" stdcallcc fn EnterCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void;
245pub extern "kernel32" stdcallcc fn LeaveCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void;
246pub extern "kernel32" stdcallcc fn DeleteCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void;
243pub extern "kernel32" fn InitializeCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void;
244pub extern "kernel32" fn EnterCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void;
245pub extern "kernel32" fn LeaveCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) 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 @@
11usingnamespace @import("bits.zig");
22
3pub extern "NtDll" stdcallcc fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) WORD;
4pub extern "NtDll" stdcallcc fn NtQueryInformationFile(
3pub extern "NtDll" fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) callconv(.Stdcall) WORD;
4pub extern "NtDll" fn NtQueryInformationFile(
55 FileHandle: HANDLE,
66 IoStatusBlock: *IO_STATUS_BLOCK,
77 FileInformation: *c_void,
88 Length: ULONG,
99 FileInformationClass: FILE_INFORMATION_CLASS,
10) NTSTATUS;
11pub extern "NtDll" stdcallcc fn NtCreateFile(
10) callconv(.Stdcall) NTSTATUS;
11pub extern "NtDll" fn NtCreateFile(
1212 FileHandle: *HANDLE,
1313 DesiredAccess: ACCESS_MASK,
1414 ObjectAttributes: *OBJECT_ATTRIBUTES,
......@@ -20,8 +20,8 @@ pub extern "NtDll" stdcallcc fn NtCreateFile(
2020 CreateOptions: ULONG,
2121 EaBuffer: ?*c_void,
2222 EaLength: ULONG,
23) NTSTATUS;
24pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile(
23) callconv(.Stdcall) NTSTATUS;
24pub extern "NtDll" fn NtDeviceIoControlFile(
2525 FileHandle: HANDLE,
2626 Event: ?HANDLE,
2727 ApcRoutine: ?IO_APC_ROUTINE,
......@@ -32,17 +32,17 @@ pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile(
3232 InputBufferLength: ULONG,
3333 OutputBuffer: ?PVOID,
3434 OutputBufferLength: ULONG,
35) NTSTATUS;
36pub extern "NtDll" stdcallcc fn NtClose(Handle: HANDLE) NTSTATUS;
37pub extern "NtDll" stdcallcc fn RtlDosPathNameToNtPathName_U(
35) callconv(.Stdcall) NTSTATUS;
36pub extern "NtDll" fn NtClose(Handle: HANDLE) callconv(.Stdcall) NTSTATUS;
37pub extern "NtDll" fn RtlDosPathNameToNtPathName_U(
3838 DosPathName: [*]const u16,
3939 NtPathName: *UNICODE_STRING,
4040 NtFileNamePart: ?*?[*]const u16,
4141 DirectoryInfo: ?*CURDIR,
42) BOOL;
43pub extern "NtDll" stdcallcc fn RtlFreeUnicodeString(UnicodeString: *UNICODE_STRING) void;
42) callconv(.Stdcall) BOOL;
43pub extern "NtDll" fn RtlFreeUnicodeString(UnicodeString: *UNICODE_STRING) callconv(.Stdcall) void;
4444
45pub extern "NtDll" stdcallcc fn NtQueryDirectoryFile(
45pub extern "NtDll" fn NtQueryDirectoryFile(
4646 FileHandle: HANDLE,
4747 Event: ?HANDLE,
4848 ApcRoutine: ?IO_APC_ROUTINE,
......@@ -54,22 +54,22 @@ pub extern "NtDll" stdcallcc fn NtQueryDirectoryFile(
5454 ReturnSingleEntry: BOOLEAN,
5555 FileName: ?*UNICODE_STRING,
5656 RestartScan: BOOLEAN,
57) NTSTATUS;
58pub extern "NtDll" stdcallcc fn NtCreateKeyedEvent(
57) callconv(.Stdcall) NTSTATUS;
58pub extern "NtDll" fn NtCreateKeyedEvent(
5959 KeyedEventHandle: *HANDLE,
6060 DesiredAccess: ACCESS_MASK,
6161 ObjectAttributes: ?PVOID,
6262 Flags: ULONG,
63) NTSTATUS;
64pub extern "NtDll" stdcallcc fn NtReleaseKeyedEvent(
63) callconv(.Stdcall) NTSTATUS;
64pub extern "NtDll" fn NtReleaseKeyedEvent(
6565 EventHandle: HANDLE,
6666 Key: *const c_void,
6767 Alertable: BOOLEAN,
6868 Timeout: ?*LARGE_INTEGER,
69) NTSTATUS;
70pub extern "NtDll" stdcallcc fn NtWaitForKeyedEvent(
69) callconv(.Stdcall) NTSTATUS;
70pub extern "NtDll" fn NtWaitForKeyedEvent(
7171 EventHandle: HANDLE,
7272 Key: *const c_void,
7373 Alertable: BOOLEAN,
7474 Timeout: ?*LARGE_INTEGER,
75) NTSTATUS;
75) callconv(.Stdcall) NTSTATUS;
lib/std/os/windows/ole32.zig+4-4
......@@ -1,6 +1,6 @@
11usingnamespace @import("bits.zig");
22
3pub extern "ole32" stdcallcc fn CoTaskMemFree(pv: LPVOID) void;
4pub extern "ole32" stdcallcc fn CoUninitialize() void;
5pub extern "ole32" stdcallcc fn CoGetCurrentProcess() DWORD;
6pub extern "ole32" stdcallcc fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) HRESULT;
3pub extern "ole32" fn CoTaskMemFree(pv: LPVOID) callconv(.Stdcall) void;
4pub extern "ole32" fn CoUninitialize() callconv(.Stdcall) void;
5pub extern "ole32" fn CoGetCurrentProcess() callconv(.Stdcall) DWORD;
6pub extern "ole32" fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) callconv(.Stdcall) HRESULT;
lib/std/os/windows/shell32.zig+1-1
......@@ -1,3 +1,3 @@
11usingnamespace @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;
315315
316316pub const SIO_BASE_HANDLE = IOC_OUT | IOC_WS2 | 34;
317317
318pub extern "ws2_32" stdcallcc fn WSAStartup(
318pub extern "ws2_32" fn WSAStartup(
319319 wVersionRequired: WORD,
320320 lpWSAData: *WSADATA,
321) c_int;
322pub extern "ws2_32" stdcallcc fn WSACleanup() c_int;
323pub extern "ws2_32" stdcallcc fn WSAGetLastError() c_int;
324pub extern "ws2_32" stdcallcc fn WSASocketA(
321) callconv(.Stdcall) c_int;
322pub extern "ws2_32" fn WSACleanup() callconv(.Stdcall) c_int;
323pub extern "ws2_32" fn WSAGetLastError() callconv(.Stdcall) c_int;
324pub extern "ws2_32" fn WSASocketA(
325325 af: c_int,
326326 type: c_int,
327327 protocol: c_int,
328328 lpProtocolInfo: ?*WSAPROTOCOL_INFOA,
329329 g: GROUP,
330330 dwFlags: DWORD,
331) SOCKET;
332pub extern "ws2_32" stdcallcc fn WSASocketW(
331) callconv(.Stdcall) SOCKET;
332pub extern "ws2_32" fn WSASocketW(
333333 af: c_int,
334334 type: c_int,
335335 protocol: c_int,
336336 lpProtocolInfo: ?*WSAPROTOCOL_INFOW,
337337 g: GROUP,
338338 dwFlags: DWORD,
339) SOCKET;
340pub extern "ws2_32" stdcallcc fn closesocket(s: SOCKET) c_int;
341pub extern "ws2_32" stdcallcc fn WSAIoctl(
339) callconv(.Stdcall) SOCKET;
340pub extern "ws2_32" fn closesocket(s: SOCKET) callconv(.Stdcall) c_int;
341pub extern "ws2_32" fn WSAIoctl(
342342 s: SOCKET,
343343 dwIoControlCode: DWORD,
344344 lpvInBuffer: ?*const c_void,
......@@ -348,18 +348,18 @@ pub extern "ws2_32" stdcallcc fn WSAIoctl(
348348 lpcbBytesReturned: LPDWORD,
349349 lpOverlapped: ?*WSAOVERLAPPED,
350350 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
351) c_int;
352pub extern "ws2_32" stdcallcc fn accept(
351) callconv(.Stdcall) c_int;
352pub extern "ws2_32" fn accept(
353353 s: SOCKET,
354354 addr: ?*sockaddr,
355355 addrlen: socklen_t,
356) SOCKET;
357pub extern "ws2_32" stdcallcc fn connect(
356) callconv(.Stdcall) SOCKET;
357pub extern "ws2_32" fn connect(
358358 s: SOCKET,
359359 name: *const sockaddr,
360360 namelen: socklen_t,
361) c_int;
362pub extern "ws2_32" stdcallcc fn WSARecv(
361) callconv(.Stdcall) c_int;
362pub extern "ws2_32" fn WSARecv(
363363 s: SOCKET,
364364 lpBuffers: [*]const WSABUF,
365365 dwBufferCount: DWORD,
......@@ -367,8 +367,8 @@ pub extern "ws2_32" stdcallcc fn WSARecv(
367367 lpFlags: *DWORD,
368368 lpOverlapped: ?*WSAOVERLAPPED,
369369 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
370) c_int;
371pub extern "ws2_32" stdcallcc fn WSARecvFrom(
370) callconv(.Stdcall) c_int;
371pub extern "ws2_32" fn WSARecvFrom(
372372 s: SOCKET,
373373 lpBuffers: [*]const WSABUF,
374374 dwBufferCount: DWORD,
......@@ -378,8 +378,8 @@ pub extern "ws2_32" stdcallcc fn WSARecvFrom(
378378 lpFromlen: socklen_t,
379379 lpOverlapped: ?*WSAOVERLAPPED,
380380 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
381) c_int;
382pub extern "ws2_32" stdcallcc fn WSASend(
381) callconv(.Stdcall) c_int;
382pub extern "ws2_32" fn WSASend(
383383 s: SOCKET,
384384 lpBuffers: [*]WSABUF,
385385 dwBufferCount: DWORD,
......@@ -387,8 +387,8 @@ pub extern "ws2_32" stdcallcc fn WSASend(
387387 dwFlags: DWORD,
388388 lpOverlapped: ?*WSAOVERLAPPED,
389389 lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE,
390) c_int;
391pub extern "ws2_32" stdcallcc fn WSASendTo(
390) callconv(.Stdcall) c_int;
391pub extern "ws2_32" fn WSASendTo(
392392 s: SOCKET,
393393 lpBuffers: [*]WSABUF,
394394 dwBufferCount: DWORD,
......@@ -398,4 +398,4 @@ pub extern "ws2_32" stdcallcc fn WSASendTo(
398398 iTolen: socklen_t,
399399 lpOverlapped: ?*WSAOVERLAPPED,
400400 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;
1414pub const ResetEvent = struct {
1515 os_event: OsEvent,
1616
17 pub const OsEvent =
18 if (builtin.single_threaded)
19 DebugEvent
20 else if (builtin.link_libc and builtin.os != .windows and builtin.os != .linux)
21 PosixEvent
22 else
23 AtomicEvent;
17 pub const OsEvent = if (builtin.single_threaded)
18 DebugEvent
19 else if (builtin.link_libc and builtin.os != .windows and builtin.os != .linux)
20 PosixEvent
21 else
22 AtomicEvent;
2423
2524 pub fn init() ResetEvent {
2625 return ResetEvent{ .os_event = OsEvent.init() };
......@@ -105,7 +104,7 @@ const PosixEvent = struct {
105104 }
106105
107106 fn deinit(self: *PosixEvent) void {
108 // on dragonfly, *destroy() functions can return EINVAL
107 // on dragonfly, *destroy() functions can return EINVAL
109108 // for statically initialized pthread structures
110109 const err = if (builtin.os == .dragonfly) os.EINVAL else 0;
111110
......@@ -212,8 +211,7 @@ const AtomicEvent = struct {
212211 fn wait(self: *AtomicEvent, timeout: ?u64) !void {
213212 var waiters = @atomicLoad(u32, &self.waiters, .Acquire);
214213 while (waiters != WAKE) {
215 waiters = @cmpxchgWeak(u32, &self.waiters, waiters, waiters + WAIT, .Acquire, .Acquire)
216 orelse return Futex.wait(&self.waiters, timeout);
214 waiters = @cmpxchgWeak(u32, &self.waiters, waiters, waiters + WAIT, .Acquire, .Acquire) orelse return Futex.wait(&self.waiters, timeout);
217215 }
218216 }
219217
......@@ -281,7 +279,7 @@ const AtomicEvent = struct {
281279 pub fn wake(waiters: *u32, wake_count: u32) void {
282280 const handle = getEventHandle() orelse return SpinFutex.wake(waiters, wake_count);
283281 const key = @ptrCast(*const c_void, waiters);
284
282
285283 var waiting = wake_count;
286284 while (waiting != 0) : (waiting -= 1) {
287285 const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null);
......@@ -408,7 +406,7 @@ test "std.ResetEvent" {
408406 // wait for receiver to update value and signal output
409407 self.out.wait();
410408 testing.expect(self.value == 2);
411
409
412410 // update value and signal final input
413411 self.value = 3;
414412 self.in.set();
......@@ -418,12 +416,12 @@ test "std.ResetEvent" {
418416 // wait for sender to update value and signal input
419417 self.in.wait();
420418 assert(self.value == 1);
421
419
422420 // update value and signal output
423421 self.in.reset();
424422 self.value = 2;
425423 self.out.set();
426
424
427425 // wait for sender to update value and signal final input
428426 self.in.wait();
429427 assert(self.value == 3);
lib/std/special/c.zig+1-1
......@@ -195,7 +195,7 @@ extern fn __stack_chk_fail() noreturn {
195195// TODO we should be able to put this directly in std/linux/x86_64.zig but
196196// it causes a segfault in release mode. this is a workaround of calling it
197197// across .o file boundaries. fix comptime @ptrCast of nakedcc functions.
198nakedcc fn clone() void {
198fn clone() callconv(.Naked) void {
199199 switch (builtin.arch) {
200200 .i386 => {
201201 // __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 {
528528 };
529529}
530530
531nakedcc fn __aeabi_memcpy() noreturn {
531fn __aeabi_memcpy() callconv(.Naked) noreturn {
532532 @setRuntimeSafety(false);
533533 if (use_thumb_1) {
534534 asm volatile (
......@@ -544,7 +544,7 @@ nakedcc fn __aeabi_memcpy() noreturn {
544544 unreachable;
545545}
546546
547nakedcc fn __aeabi_memmove() noreturn {
547fn __aeabi_memmove() callconv(.Naked) noreturn {
548548 @setRuntimeSafety(false);
549549 if (use_thumb_1) {
550550 asm volatile (
......@@ -560,7 +560,7 @@ nakedcc fn __aeabi_memmove() noreturn {
560560 unreachable;
561561}
562562
563nakedcc fn __aeabi_memset() noreturn {
563fn __aeabi_memset() callconv(.Naked) noreturn {
564564 @setRuntimeSafety(false);
565565 if (use_thumb_1_pre_armv6) {
566566 asm volatile (
......@@ -591,7 +591,7 @@ nakedcc fn __aeabi_memset() noreturn {
591591 unreachable;
592592}
593593
594nakedcc fn __aeabi_memclr() noreturn {
594fn __aeabi_memclr() callconv(.Naked) noreturn {
595595 @setRuntimeSafety(false);
596596 if (use_thumb_1_pre_armv6) {
597597 asm volatile (
......@@ -619,7 +619,7 @@ nakedcc fn __aeabi_memclr() noreturn {
619619 unreachable;
620620}
621621
622nakedcc fn __aeabi_memcmp() noreturn {
622fn __aeabi_memcmp() callconv(.Naked) noreturn {
623623 @setRuntimeSafety(false);
624624 if (use_thumb_1) {
625625 asm volatile (
lib/std/special/compiler_rt/arm/aeabi_dcmp.zig+5-5
......@@ -12,31 +12,31 @@ const ConditionalOperator = enum {
1212 Gt,
1313};
1414
15pub nakedcc fn __aeabi_dcmpeq() noreturn {
15pub fn __aeabi_dcmpeq() callconv(.Naked) noreturn {
1616 @setRuntimeSafety(false);
1717 @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Eq});
1818 unreachable;
1919}
2020
21pub nakedcc fn __aeabi_dcmplt() noreturn {
21pub fn __aeabi_dcmplt() callconv(.Naked) noreturn {
2222 @setRuntimeSafety(false);
2323 @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Lt});
2424 unreachable;
2525}
2626
27pub nakedcc fn __aeabi_dcmple() noreturn {
27pub fn __aeabi_dcmple() callconv(.Naked) noreturn {
2828 @setRuntimeSafety(false);
2929 @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Le});
3030 unreachable;
3131}
3232
33pub nakedcc fn __aeabi_dcmpge() noreturn {
33pub fn __aeabi_dcmpge() callconv(.Naked) noreturn {
3434 @setRuntimeSafety(false);
3535 @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Ge});
3636 unreachable;
3737}
3838
39pub nakedcc fn __aeabi_dcmpgt() noreturn {
39pub fn __aeabi_dcmpgt() callconv(.Naked) noreturn {
4040 @setRuntimeSafety(false);
4141 @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Gt});
4242 unreachable;
lib/std/special/compiler_rt/arm/aeabi_fcmp.zig+5-5
......@@ -12,31 +12,31 @@ const ConditionalOperator = enum {
1212 Gt,
1313};
1414
15pub nakedcc fn __aeabi_fcmpeq() noreturn {
15pub fn __aeabi_fcmpeq() callconv(.Naked) noreturn {
1616 @setRuntimeSafety(false);
1717 @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Eq});
1818 unreachable;
1919}
2020
21pub nakedcc fn __aeabi_fcmplt() noreturn {
21pub fn __aeabi_fcmplt() callconv(.Naked) noreturn {
2222 @setRuntimeSafety(false);
2323 @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Lt});
2424 unreachable;
2525}
2626
27pub nakedcc fn __aeabi_fcmple() noreturn {
27pub fn __aeabi_fcmple() callconv(.Naked) noreturn {
2828 @setRuntimeSafety(false);
2929 @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Le});
3030 unreachable;
3131}
3232
33pub nakedcc fn __aeabi_fcmpge() noreturn {
33pub fn __aeabi_fcmpge() callconv(.Naked) noreturn {
3434 @setRuntimeSafety(false);
3535 @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Ge});
3636 unreachable;
3737}
3838
39pub nakedcc fn __aeabi_fcmpgt() noreturn {
39pub fn __aeabi_fcmpgt() callconv(.Naked) noreturn {
4040 @setRuntimeSafety(false);
4141 @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Gt});
4242 unreachable;
lib/std/special/compiler_rt/aulldiv.zig+2-2
......@@ -1,6 +1,6 @@
11const 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 {
44 @setRuntimeSafety(builtin.is_test);
55 const s_a = a >> (i64.bit_count - 1);
66 const s_b = b >> (i64.bit_count - 1);
......@@ -13,7 +13,7 @@ pub extern stdcallcc fn _alldiv(a: i64, b: i64) i64 {
1313 return (@bitCast(i64, r) ^ s) -% s;
1414}
1515
16pub nakedcc fn _aulldiv() void {
16pub fn _aulldiv() callconv(.Naked) void {
1717 @setRuntimeSafety(false);
1818
1919 // The stack layout is:
lib/std/special/compiler_rt/aullrem.zig+2-2
......@@ -1,6 +1,6 @@
11const 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 {
44 @setRuntimeSafety(builtin.is_test);
55 const s_a = a >> (i64.bit_count - 1);
66 const s_b = b >> (i64.bit_count - 1);
......@@ -13,7 +13,7 @@ pub extern stdcallcc fn _allrem(a: i64, b: i64) i64 {
1313 return (@bitCast(i64, r) ^ s) -% s;
1414}
1515
16pub nakedcc fn _aullrem() void {
16pub fn _aullrem() callconv(.Naked) void {
1717 @setRuntimeSafety(false);
1818
1919 // The stack layout is:
lib/std/special/compiler_rt/stack_probe.zig+6-6
......@@ -1,7 +1,7 @@
11const builtin = @import("builtin");
22
33// 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 {
55 @setRuntimeSafety(false);
66
77 // 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 {
180180// ___chkstk (__alloca) | yes | yes |
181181// ___chkstk_ms | no | no |
182182
183pub nakedcc fn _chkstk() void {
183pub fn _chkstk() callconv(.Naked) void {
184184 @setRuntimeSafety(false);
185185 @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{});
186186}
187pub nakedcc fn __chkstk() void {
187pub fn __chkstk() callconv(.Naked) void {
188188 @setRuntimeSafety(false);
189189 switch (builtin.arch) {
190190 .i386 => @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}),
......@@ -192,15 +192,15 @@ pub nakedcc fn __chkstk() void {
192192 else => unreachable,
193193 }
194194}
195pub nakedcc fn ___chkstk() void {
195pub fn ___chkstk() callconv(.Naked) void {
196196 @setRuntimeSafety(false);
197197 @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{});
198198}
199pub nakedcc fn __chkstk_ms() void {
199pub fn __chkstk_ms() callconv(.Naked) void {
200200 @setRuntimeSafety(false);
201201 @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{});
202202}
203pub nakedcc fn ___chkstk_ms() void {
203pub fn ___chkstk_ms() callconv(.Naked) void {
204204 @setRuntimeSafety(false);
205205 @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{});
206206}
lib/std/spinlock.zig+10-2
......@@ -60,8 +60,16 @@ pub const SpinLock = struct {
6060 switch (builtin.arch) {
6161 // these instructions use a memory clobber as they
6262 // flush the pipeline of any speculated reads/writes.
63 .i386, .x86_64 => asm volatile ("pause" ::: "memory"),
64 .arm, .aarch64 => asm volatile ("yield" ::: "memory"),
63 .i386, .x86_64 => asm volatile ("pause"
64 :
65 :
66 : "memory"
67 ),
68 .arm, .aarch64 => asm volatile ("yield"
69 :
70 :
71 : "memory"
72 ),
6573 else => std.os.sched_yield() catch {},
6674 }
6775 }
lib/std/start.zig+4-4
......@@ -43,11 +43,11 @@ comptime {
4343 }
4444}
4545
46stdcallcc fn _DllMainCRTStartup(
46fn _DllMainCRTStartup(
4747 hinstDLL: std.os.windows.HINSTANCE,
4848 fdwReason: std.os.windows.DWORD,
4949 lpReserved: std.os.windows.LPVOID,
50) std.os.windows.BOOL {
50) callconv(.Stdcall) std.os.windows.BOOL {
5151 if (@hasDecl(root, "DllMain")) {
5252 return root.DllMain(hinstDLL, fdwReason, lpReserved);
5353 }
......@@ -84,7 +84,7 @@ extern fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) u
8484 }
8585}
8686
87nakedcc fn _start() noreturn {
87fn _start() callconv(.Naked) noreturn {
8888 if (builtin.os == builtin.Os.wasi) {
8989 // This is marked inline because for some reason LLVM in release mode fails to inline it,
9090 // and we want fewer call frames in stack traces.
......@@ -127,7 +127,7 @@ nakedcc fn _start() noreturn {
127127 @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
128128}
129129
130stdcallcc fn WinMainCRTStartup() noreturn {
130fn WinMainCRTStartup() callconv(.Stdcall) noreturn {
131131 @setAlignStack(16);
132132 if (!builtin.single_threaded) {
133133 _ = @import("start_windows_tls.zig");
lib/std/zig/ast.zig+1
......@@ -860,6 +860,7 @@ pub const Node = struct {
860860 lib_name: ?*Node, // populated if this is an extern declaration
861861 align_expr: ?*Node, // populated if align(A) is present
862862 section_expr: ?*Node, // populated if linksection(A) is present
863 callconv_expr: ?*Node, // populated if callconv(A) is present
863864
864865 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 {
311311 const rparen = try expectToken(it, tree, .RParen);
312312 const align_expr = try parseByteAlign(arena, it, tree);
313313 const section_expr = try parseLinkSection(arena, it, tree);
314 const callconv_expr = try parseCallconv(arena, it, tree);
314315 const exclamation_token = eatToken(it, .Bang);
315316
316317 const return_type_expr = (try parseVarType(arena, it, tree)) orelse
......@@ -347,6 +348,7 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
347348 .lib_name = null,
348349 .align_expr = align_expr,
349350 .section_expr = section_expr,
351 .callconv_expr = callconv_expr,
350352 };
351353
352354 if (cc) |kind| {
......@@ -1678,6 +1680,17 @@ fn parseLinkSection(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
16781680 return expr_node;
16791681}
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
16811694/// FnCC
16821695/// <- KEYWORD_nakedcc
16831696/// / KEYWORD_stdcallcc
lib/std/zig/parser_test.zig+14-2
......@@ -9,6 +9,18 @@ test "zig fmt: change @typeOf to @TypeOf" {
99 );
1010}
1111
12// TODO: Remove nakedcc/stdcallcc once zig 0.6.0 is released. See https://github.com/ziglang/zig/pull/3977
13test "zig fmt: convert nakedcc/stdcallcc into callconv(...)" {
14 try testTransform(
15 \\nakedcc fn foo1() void {}
16 \\stdcallcc fn foo2() void {}
17 ,
18 \\fn foo1() callconv(.Naked) void {}
19 \\fn foo2() callconv(.Stdcall) void {}
20 \\
21 );
22}
23
1224test "zig fmt: comptime struct field" {
1325 try testCanonical(
1426 \\const Foo = struct {
......@@ -234,7 +246,7 @@ test "zig fmt: threadlocal" {
234246test "zig fmt: linksection" {
235247 try testCanonical(
236248 \\export var aoeu: u64 linksection(".text.derp") = 1234;
237 \\export nakedcc fn _start() linksection(".text.boot") noreturn {}
249 \\export fn _start() linksection(".text.boot") callconv(.Naked) noreturn {}
238250 \\
239251 );
240252}
......@@ -2326,7 +2338,7 @@ test "zig fmt: fn type" {
23262338 \\
23272339 \\const a: fn (u8) u8 = undefined;
23282340 \\const b: extern fn (u8) u8 = undefined;
2329 \\const c: nakedcc fn (u8) u8 = undefined;
2341 \\const c: fn (u8) callconv(.Naked) u8 = undefined;
23302342 \\const ap: fn (u8) u8 = a;
23312343 \\
23322344 );
lib/std/zig/render.zig+24-1
......@@ -1319,8 +1319,16 @@ fn renderExpression(
13191319 try renderExpression(allocator, stream, tree, indent, start_col, lib_name, Space.Space);
13201320 }
13211321
1322 // Some extra machinery is needed to rewrite the old-style cc
1323 // notation to the new callconv one
1324 var cc_rewrite_str: ?[*:0]const u8 = null;
13221325 if (fn_proto.cc_token) |cc_token| {
1323 try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc
1326 var str = tree.tokenSlicePtr(tree.tokens.at(cc_token));
1327 if (mem.eql(u8, str, "stdcallcc")) {
1328 cc_rewrite_str = ".Stdcall";
1329 } else if (mem.eql(u8, str, "nakedcc")) {
1330 cc_rewrite_str = ".Naked";
1331 } else try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc
13241332 }
13251333
13261334 const lparen = if (fn_proto.name_token) |name_token| blk: {
......@@ -1392,6 +1400,21 @@ fn renderExpression(
13921400 try renderToken(tree, stream, section_rparen, indent, start_col, Space.Space); // )
13931401 }
13941402
1403 if (fn_proto.callconv_expr) |callconv_expr| {
1404 const callconv_rparen = tree.nextToken(callconv_expr.lastToken());
1405 const callconv_lparen = tree.prevToken(callconv_expr.firstToken());
1406 const callconv_kw = tree.prevToken(callconv_lparen);
1407
1408 try renderToken(tree, stream, callconv_kw, indent, start_col, Space.None); // section
1409 try renderToken(tree, stream, callconv_lparen, indent, start_col, Space.None); // (
1410 try renderExpression(allocator, stream, tree, indent, start_col, callconv_expr, Space.None);
1411 try renderToken(tree, stream, callconv_rparen, indent, start_col, Space.Space); // )
1412 } else if (cc_rewrite_str) |str| {
1413 try stream.write("callconv(");
1414 try stream.write(mem.toSliceConst(u8, str));
1415 try stream.write(") ");
1416 }
1417
13951418 switch (fn_proto.return_type) {
13961419 ast.Node.FnProto.ReturnType.Explicit => |node| {
13971420 return renderExpression(allocator, stream, tree, indent, start_col, node, space);
lib/std/zig/tokenizer.zig+3
......@@ -30,6 +30,7 @@ pub const Token = struct {
3030 Keyword.init("async", .Keyword_async),
3131 Keyword.init("await", .Keyword_await),
3232 Keyword.init("break", .Keyword_break),
33 Keyword.init("callconv", .Keyword_callconv),
3334 Keyword.init("catch", .Keyword_catch),
3435 Keyword.init("comptime", .Keyword_comptime),
3536 Keyword.init("const", .Keyword_const),
......@@ -162,6 +163,7 @@ pub const Token = struct {
162163 Keyword_async,
163164 Keyword_await,
164165 Keyword_break,
166 Keyword_callconv,
165167 Keyword_catch,
166168 Keyword_comptime,
167169 Keyword_const,
......@@ -286,6 +288,7 @@ pub const Token = struct {
286288 .Keyword_async => "async",
287289 .Keyword_await => "await",
288290 .Keyword_break => "break",
291 .Keyword_callconv => "callconv",
289292 .Keyword_catch => "catch",
290293 .Keyword_comptime => "comptime",
291294 .Keyword_const => "const",
src-self-hosted/translate_c.zig+18-3
......@@ -11,7 +11,7 @@ const CToken = ctok.CToken;
1111const mem = std.mem;
1212const math = std.math;
1313
14const CallingConvention = std.builtin.TypeInfo.CallingConvention;
14const CallingConvention = std.builtin.CallingConvention;
1515
1616pub const ClangErrMsg = Stage2ErrorMsg;
1717
......@@ -3690,6 +3690,7 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a
36903690 .lib_name = null,
36913691 .align_expr = null,
36923692 .section_expr = null,
3693 .callconv_expr = null,
36933694 };
36943695
36953696 const block = try transCreateNodeBlock(c, null);
......@@ -4141,6 +4142,11 @@ fn transCC(
41414142 switch (clang_cc) {
41424143 .C => return CallingConvention.C,
41434144 .X86StdCall => return CallingConvention.Stdcall,
4145 .X86FastCall => return CallingConvention.Fastcall,
4146 .X86VectorCall, .AArch64VectorCall => return CallingConvention.Vectorcall,
4147 .X86ThisCall => return CallingConvention.Thiscall,
4148 .AAPCS => return CallingConvention.AAPCS,
4149 .AAPCS_VFP => return CallingConvention.AAPCSVFP,
41444150 else => return revertAndWarn(
41454151 rp,
41464152 error.UnsupportedType,
......@@ -4196,7 +4202,6 @@ fn finishTransFnProto(
41964202
41974203 // pub extern fn name(...) T
41984204 const pub_tok = if (is_pub) try appendToken(rp.c, .Keyword_pub, "pub") else null;
4199 const cc_tok = if (cc == .Stdcall) try appendToken(rp.c, .Keyword_stdcallcc, "stdcallcc") else null;
42004205 const extern_export_inline_tok = if (is_export)
42014206 try appendToken(rp.c, .Keyword_export, "export")
42024207 else if (cc == .C and is_extern)
......@@ -4303,6 +4308,14 @@ fn finishTransFnProto(
43034308 break :blk null;
43044309 };
43054310
4311 const callconv_expr = if (extern_export_inline_tok != null) null else blk: {
4312 _ = try appendToken(rp.c, .Keyword_callconv, "callconv");
4313 _ = try appendToken(rp.c, .LParen, "(");
4314 const expr = try transCreateNodeEnumLiteral(rp.c, @tagName(cc));
4315 _ = try appendToken(rp.c, .RParen, ")");
4316 break :blk expr;
4317 };
4318
43064319 const return_type_node = blk: {
43074320 if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) {
43084321 break :blk try transCreateNodeIdentifier(rp.c, "noreturn");
......@@ -4333,11 +4346,12 @@ fn finishTransFnProto(
43334346 .return_type = .{ .Explicit = return_type_node },
43344347 .var_args_token = null, // TODO this field is broken in the AST data model
43354348 .extern_export_inline_token = extern_export_inline_tok,
4336 .cc_token = cc_tok,
4349 .cc_token = null,
43374350 .body_node = null,
43384351 .lib_name = null,
43394352 .align_expr = align_expr,
43404353 .section_expr = linksection_expr,
4354 .callconv_expr = callconv_expr,
43414355 };
43424356 return fn_proto;
43434357}
......@@ -4686,6 +4700,7 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u
46864700 .lib_name = null,
46874701 .align_expr = null,
46884702 .section_expr = null,
4703 .callconv_expr = null,
46894704 };
46904705
46914706 const block = try transCreateNodeBlock(c, null);
src-self-hosted/type.zig+2-1
......@@ -337,7 +337,7 @@ pub const Type = struct {
337337 }
338338 };
339339
340 const CallingConvention = builtin.TypeInfo.CallingConvention;
340 const CallingConvention = builtin.CallingConvention;
341341
342342 pub const Param = struct {
343343 is_noalias: bool,
......@@ -352,6 +352,7 @@ pub const Type = struct {
352352 .Naked => "nakedcc ",
353353 .Stdcall => "stdcallcc ",
354354 .Async => "async ",
355 else => unreachable,
355356 };
356357 }
357358
src/all_types.hpp+25-10
......@@ -57,6 +57,23 @@ enum PtrLen {
5757 PtrLenC,
5858};
5959
60enum CallingConvention {
61 CallingConventionUnspecified,
62 CallingConventionC,
63 CallingConventionCold,
64 CallingConventionNaked,
65 CallingConventionAsync,
66 CallingConventionInterrupt,
67 CallingConventionSignal,
68 CallingConventionStdcall,
69 CallingConventionFastcall,
70 CallingConventionVectorcall,
71 CallingConventionThiscall,
72 CallingConventionAPCS,
73 CallingConventionAAPCS,
74 CallingConventionAAPCSVFP,
75};
76
6077// This one corresponds to the builtin.zig enum.
6178enum BuiltinPtrSize {
6279 BuiltinPtrSizeOne,
......@@ -398,6 +415,7 @@ struct LazyValueFnType {
398415 IrInstruction *align_inst; // can be null
399416 IrInstruction *return_type;
400417
418 CallingConvention cc;
401419 bool is_generic;
402420};
403421
......@@ -612,15 +630,6 @@ enum NodeType {
612630 NodeTypeVarFieldType,
613631};
614632
615enum CallingConvention {
616 CallingConventionUnspecified,
617 CallingConventionC,
618 CallingConventionCold,
619 CallingConventionNaked,
620 CallingConventionStdcall,
621 CallingConventionAsync,
622};
623
624633enum FnInline {
625634 FnInlineAuto,
626635 FnInlineAlways,
......@@ -639,10 +648,14 @@ struct AstNodeFnProto {
639648 AstNode *align_expr;
640649 // populated if the "section(S)" is present
641650 AstNode *section_expr;
651 // populated if the "callconv(S)" is present
652 AstNode *callconv_expr;
642653 Buf doc_comments;
643654
644655 FnInline fn_inline;
645 CallingConvention cc;
656 bool is_nakedcc;
657 bool is_stdcallcc;
658 bool is_async;
646659
647660 VisibMod visib_mod;
648661 bool auto_err_set;
......@@ -1597,6 +1610,7 @@ struct ZigFn {
15971610 Buf **param_names;
15981611 IrInstruction *err_code_spill;
15991612 AstNode *assumed_non_async;
1613 CallingConvention cc;
16001614
16011615 AstNode *fn_no_inline_set_node;
16021616 AstNode *fn_static_eval_set_node;
......@@ -3549,6 +3563,7 @@ struct IrInstructionFnProto {
35493563
35503564 IrInstruction **param_types;
35513565 IrInstruction *align_value;
3566 IrInstruction *callconv_value;
35523567 IrInstruction *return_type;
35533568 bool is_var_args;
35543569};
src/analyze.cpp+111-62
......@@ -919,24 +919,20 @@ ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry) {
919919
920920const char *calling_convention_name(CallingConvention cc) {
921921 switch (cc) {
922 case CallingConventionUnspecified: return "undefined";
923 case CallingConventionC: return "ccc";
924 case CallingConventionCold: return "coldcc";
925 case CallingConventionNaked: return "nakedcc";
926 case CallingConventionStdcall: return "stdcallcc";
927 case CallingConventionAsync: return "async";
928 }
929 zig_unreachable();
930}
931
932static const char *calling_convention_fn_type_str(CallingConvention cc) {
933 switch (cc) {
934 case CallingConventionUnspecified: return "";
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 ";
922 case CallingConventionUnspecified: return "Unspecified";
923 case CallingConventionC: return "C";
924 case CallingConventionCold: return "Cold";
925 case CallingConventionNaked: return "Naked";
926 case CallingConventionAsync: return "Async";
927 case CallingConventionInterrupt: return "Interrupt";
928 case CallingConventionSignal: return "Signal";
929 case CallingConventionStdcall: return "Stdcall";
930 case CallingConventionFastcall: return "Fastcall";
931 case CallingConventionVectorcall: return "Vectorcall";
932 case CallingConventionThiscall: return "Thiscall";
933 case CallingConventionAPCS: return "Apcs";
934 case CallingConventionAAPCS: return "Aapcs";
935 case CallingConventionAAPCSVFP: return "Aapcsvfp";
940936 }
941937 zig_unreachable();
942938}
......@@ -949,7 +945,15 @@ bool calling_convention_allows_zig_types(CallingConvention cc) {
949945 case CallingConventionC:
950946 case CallingConventionCold:
951947 case CallingConventionNaked:
948 case CallingConventionInterrupt:
949 case CallingConventionSignal:
952950 case CallingConventionStdcall:
951 case CallingConventionFastcall:
952 case CallingConventionVectorcall:
953 case CallingConventionThiscall:
954 case CallingConventionAPCS:
955 case CallingConventionAAPCS:
956 case CallingConventionAAPCSVFP:
953957 return false;
954958 }
955959 zig_unreachable();
......@@ -1006,8 +1010,8 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
10061010
10071011 // populate the name of the type
10081012 buf_resize(&fn_type->name, 0);
1009 const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc);
1010 buf_appendf(&fn_type->name, "%s", cc_str);
1013 if (fn_type->data.fn.fn_type_id.cc == CallingConventionC)
1014 buf_append_str(&fn_type->name, "extern ");
10111015 buf_appendf(&fn_type->name, "fn(");
10121016 for (size_t i = 0; i < fn_type_id->param_count; i += 1) {
10131017 FnTypeParamInfo *param_info = &fn_type_id->param_info[i];
......@@ -1026,6 +1030,9 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
10261030 if (fn_type_id->alignment != 0) {
10271031 buf_appendf(&fn_type->name, " align(%" PRIu32 ")", fn_type_id->alignment);
10281032 }
1033 if (fn_type_id->cc != CallingConventionUnspecified && fn_type_id->cc != CallingConventionC) {
1034 buf_appendf(&fn_type->name, " callconv(%s)", calling_convention_name(fn_type_id->cc));
1035 }
10291036 buf_appendf(&fn_type->name, " %s", buf_ptr(&fn_type_id->return_type->name));
10301037
10311038 // The fn_type is a pointer; not to be confused with the raw function type.
......@@ -1444,8 +1451,8 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
14441451ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
14451452 ZigType *fn_type = new_type_table_entry(ZigTypeIdFn);
14461453 buf_resize(&fn_type->name, 0);
1447 const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc);
1448 buf_appendf(&fn_type->name, "%s", cc_str);
1454 if (fn_type->data.fn.fn_type_id.cc == CallingConventionC)
1455 buf_append_str(&fn_type->name, "extern ");
14491456 buf_appendf(&fn_type->name, "fn(");
14501457 size_t i = 0;
14511458 for (; i < fn_type_id->next_param_index; i += 1) {
......@@ -1457,7 +1464,11 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
14571464 const char *comma_str = (i == 0) ? "" : ",";
14581465 buf_appendf(&fn_type->name, "%svar", comma_str);
14591466 }
1460 buf_appendf(&fn_type->name, ")var");
1467 buf_append_str(&fn_type->name, ")");
1468 if (fn_type_id->cc != CallingConventionUnspecified && fn_type_id->cc != CallingConventionC) {
1469 buf_appendf(&fn_type->name, " callconv(%s)", calling_convention_name(fn_type_id->cc));
1470 }
1471 buf_append_str(&fn_type->name, " var");
14611472
14621473 fn_type->data.fn.fn_type_id = *fn_type_id;
14631474 fn_type->data.fn.is_generic = true;
......@@ -1467,17 +1478,25 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
14671478 return fn_type;
14681479}
14691480
1470void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc) {
1481CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto) {
1482 if (fn_proto->is_nakedcc)
1483 return CallingConventionNaked;
1484 if (fn_proto->is_stdcallcc)
1485 return CallingConventionStdcall;
1486 if (fn_proto->is_async)
1487 return CallingConventionAsync;
1488 // Compatible with the C ABI
1489 if (fn_proto->is_extern || fn_proto->is_export)
1490 return CallingConventionC;
1491
1492 return CallingConventionUnspecified;
1493}
1494
1495void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, CallingConvention cc, size_t param_count_alloc) {
14711496 assert(proto_node->type == NodeTypeFnProto);
14721497 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
14731498
1474 if (fn_proto->cc == CallingConventionUnspecified) {
1475 bool extern_abi = fn_proto->is_extern || fn_proto->is_export;
1476 fn_type_id->cc = extern_abi ? CallingConventionC : CallingConventionUnspecified;
1477 } else {
1478 fn_type_id->cc = fn_proto->cc;
1479 }
1480
1499 fn_type_id->cc = cc;
14811500 fn_type_id->param_count = fn_proto->params.length;
14821501 fn_type_id->param_info = allocate<FnTypeParamInfo>(param_count_alloc);
14831502 fn_type_id->next_param_index = 0;
......@@ -1691,8 +1710,7 @@ Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result) {
16911710 case ZigTypeIdArray:
16921711 return type_allowed_in_extern(g, type_entry->data.array.child_type, result);
16931712 case ZigTypeIdFn:
1694 *result = type_entry->data.fn.fn_type_id.cc == CallingConventionC ||
1695 type_entry->data.fn.fn_type_id.cc == CallingConventionStdcall;
1713 *result = !calling_convention_allows_zig_types(type_entry->data.fn.fn_type_id.cc);
16961714 return ErrorNone;
16971715 case ZigTypeIdPointer:
16981716 if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
......@@ -1752,7 +1770,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
17521770 Error err;
17531771
17541772 FnTypeId fn_type_id = {0};
1755 init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length);
1773 init_fn_type_id(&fn_type_id, proto_node, fn_entry->cc, proto_node->data.fn_proto.params.length);
17561774
17571775 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) {
17581776 AstNode *param_node = fn_proto->params.at(fn_type_id.next_param_index);
......@@ -2164,7 +2182,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
21642182 ZigType *field_type = resolve_struct_field_type(g, field);
21652183 if (field_type == nullptr) {
21662184 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2167 return err;
2185 return ErrorSemanticAnalyzeFail;
21682186 }
21692187 if ((err = type_resolve(g, field->type_entry, ResolveStatusSizeKnown))) {
21702188 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
......@@ -2254,7 +2272,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
22542272 ZigType *field_type = resolve_struct_field_type(g, field);
22552273 if (field_type == nullptr) {
22562274 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2257 return err;
2275 return ErrorSemanticAnalyzeFail;
22582276 }
22592277
22602278 if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) {
......@@ -2324,7 +2342,7 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) {
23242342 &field->align))
23252343 {
23262344 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
2327 return err;
2345 return ErrorSemanticAnalyzeFail;
23282346 }
23292347 add_node_error(g, field->decl_node,
23302348 buf_create_from_str("TODO implement field alignment syntax for unions. https://github.com/ziglang/zig/issues/3125"));
......@@ -2451,6 +2469,7 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
24512469 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
24522470 return ErrorSemanticAnalyzeFail;
24532471 }
2472
24542473 if (is_packed) {
24552474 if ((err = emit_error_unless_type_allowed_in_packed_union(g, field_type, union_field->decl_node))) {
24562475 union_type->data.unionation.resolve_status = ResolveStatusInvalid;
......@@ -2909,7 +2928,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
29092928 &field->align))
29102929 {
29112930 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2912 return err;
2931 return ErrorSemanticAnalyzeFail;
29132932 }
29142933 } else if (packed) {
29152934 field->align = 1;
......@@ -3395,27 +3414,6 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
33953414 get_fully_qualified_decl_name(g, &fn_table_entry->symbol_name, &tld_fn->base, false);
33963415 }
33973416
3398 if (fn_proto->is_export) {
3399 switch (fn_proto->cc) {
3400 case CallingConventionAsync: {
3401 add_node_error(g, fn_def_node,
3402 buf_sprintf("exported function cannot be async"));
3403 } break;
3404 case CallingConventionC:
3405 case CallingConventionNaked:
3406 case CallingConventionCold:
3407 case CallingConventionStdcall:
3408 case CallingConventionUnspecified:
3409 // An exported function without a specific calling
3410 // convention defaults to C
3411 CallingConvention cc = (fn_proto->cc != CallingConventionUnspecified) ?
3412 fn_proto->cc : CallingConventionC;
3413 add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name),
3414 GlobalLinkageIdStrong, cc);
3415 break;
3416 }
3417 }
3418
34193417 if (!is_extern) {
34203418 fn_table_entry->fndef_scope = create_fndef_scope(g,
34213419 fn_table_entry->body_node, tld_fn->base.parent_scope, fn_table_entry);
......@@ -3434,19 +3432,70 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
34343432
34353433 Scope *child_scope = fn_table_entry->fndef_scope ? &fn_table_entry->fndef_scope->base : tld_fn->base.parent_scope;
34363434
3437 fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry);
3435 fn_table_entry->cc = cc_from_fn_proto(fn_proto);
3436 if (fn_proto->callconv_expr != nullptr) {
3437 ZigType *cc_enum_value = get_builtin_type(g, "CallingConvention");
3438
3439 ZigValue *result_val = analyze_const_value(g, child_scope, fn_proto->callconv_expr,
3440 cc_enum_value, nullptr, UndefBad);
3441 if (type_is_invalid(result_val->type)) {
3442 fn_table_entry->type_entry = g->builtin_types.entry_invalid;
3443 tld_fn->base.resolution = TldResolutionInvalid;
3444 return;
3445 }
3446
3447 fn_table_entry->cc = (CallingConvention)bigint_as_u32(&result_val->data.x_enum_tag);
3448 }
34383449
34393450 if (fn_proto->section_expr != nullptr) {
34403451 if (!analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name)) {
34413452 fn_table_entry->type_entry = g->builtin_types.entry_invalid;
3453 tld_fn->base.resolution = TldResolutionInvalid;
3454 return;
34423455 }
34433456 }
34443457
3445 if (fn_table_entry->type_entry->id == ZigTypeIdInvalid) {
3458 fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry);
3459
3460 if (type_is_invalid(fn_table_entry->type_entry)) {
34463461 tld_fn->base.resolution = TldResolutionInvalid;
34473462 return;
34483463 }
34493464
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 fn_table_entry->type_entry = g->builtin_types.entry_invalid;
3473 tld_fn->base.resolution = TldResolutionInvalid;
3474 return;
3475 case CallingConventionC:
3476 case CallingConventionCold:
3477 case CallingConventionNaked:
3478 case CallingConventionInterrupt:
3479 case CallingConventionSignal:
3480 case CallingConventionStdcall:
3481 case CallingConventionFastcall:
3482 case CallingConventionVectorcall:
3483 case CallingConventionThiscall:
3484 case CallingConventionAPCS:
3485 case CallingConventionAAPCS:
3486 case CallingConventionAAPCSVFP:
3487 add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name),
3488 GlobalLinkageIdStrong, fn_cc);
3489 break;
3490 case CallingConventionUnspecified:
3491 // An exported function without a specific calling
3492 // convention defaults to C
3493 add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name),
3494 GlobalLinkageIdStrong, CallingConventionC);
3495 break;
3496 }
3497 }
3498
34503499 if (!fn_table_entry->type_entry->data.fn.is_generic) {
34513500 if (fn_def_node)
34523501 g->fn_defs.append(fn_table_entry);
......@@ -3455,7 +3504,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
34553504 // if the calling convention implies that it cannot be async, we save that for later
34563505 // and leave the value to be nullptr to indicate that we have not emitted possible
34573506 // compile errors for improperly calling async functions.
3458 if (fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync) {
3507 if (fn_cc == CallingConventionAsync) {
34593508 fn_table_entry->inferred_async_node = fn_table_entry->proto_node;
34603509 }
34613510 } 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);
100100void append_namespace_qualification(CodeGen *g, Buf *buf, ZigType *container_type);
101101ZigFn *create_fn(CodeGen *g, AstNode *proto_node);
102102ZigFn *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);
104104AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index);
105105Error ATTRIBUTE_MUST_USE type_resolve(CodeGen *g, ZigType *type_entry, ResolveStatus status);
106106void complete_enum(CodeGen *g, ZigType *enum_type);
......@@ -259,6 +259,7 @@ ZigValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *
259259
260260void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);
261261bool fn_is_async(ZigFn *fn);
262CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto);
262263
263264Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *type_val, uint32_t *abi_align);
264265Error 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) {
488488 render_node_grouped(ar, node->data.fn_proto.section_expr);
489489 fprintf(ar->f, ")");
490490 }
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
492497 if (node->data.fn_proto.return_var_token != nullptr) {
493498 fprintf(ar->f, "var");
src/codegen.cpp+81-35
......@@ -263,36 +263,66 @@ static const char *get_mangled_name(CodeGen *g, const char *original_name, bool
263263 }
264264}
265265
266static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) {
266static ZigLLVM_CallingConv get_llvm_cc(CodeGen *g, CallingConvention cc) {
267267 switch (cc) {
268 case CallingConventionUnspecified: return LLVMFastCallConv;
269 case CallingConventionC: return LLVMCCallConv;
268 case CallingConventionUnspecified:
269 return ZigLLVM_Fast;
270 case CallingConventionC:
271 return ZigLLVM_C;
270272 case CallingConventionCold:
271 // cold calling convention only works on x86.
272 if (g->zig_target->arch == ZigLLVM_x86 ||
273 g->zig_target->arch == ZigLLVM_x86_64)
274 {
275 // cold calling convention is not supported on windows
276 if (g->zig_target->os == OsWindows) {
277 return LLVMCCallConv;
278 } else {
279 return LLVMColdCallConv;
280 }
281 } else {
282 return LLVMCCallConv;
283 }
284 break;
273 if ((g->zig_target->arch == ZigLLVM_x86 ||
274 g->zig_target->arch == ZigLLVM_x86_64) &&
275 g->zig_target->os != OsWindows)
276 return ZigLLVM_Cold;
277 return ZigLLVM_C;
285278 case CallingConventionNaked:
286279 zig_unreachable();
287280 case CallingConventionStdcall:
288 // stdcall calling convention only works on x86.
289 if (g->zig_target->arch == ZigLLVM_x86) {
290 return LLVMX86StdcallCallConv;
291 } else {
292 return LLVMCCallConv;
293 }
281 if (g->zig_target->arch == ZigLLVM_x86)
282 return ZigLLVM_X86_StdCall;
283 return ZigLLVM_C;
284 case CallingConventionFastcall:
285 if (g->zig_target->arch == ZigLLVM_x86)
286 return ZigLLVM_X86_FastCall;
287 return ZigLLVM_C;
288 case CallingConventionVectorcall:
289 if (g->zig_target->arch == ZigLLVM_x86)
290 return ZigLLVM_X86_VectorCall;
291 if (target_is_arm(g->zig_target) &&
292 target_arch_pointer_bit_width(g->zig_target->arch) == 64)
293 return ZigLLVM_AArch64_VectorCall;
294 return ZigLLVM_C;
295 case CallingConventionThiscall:
296 if (g->zig_target->arch == ZigLLVM_x86)
297 return ZigLLVM_X86_ThisCall;
298 return ZigLLVM_C;
294299 case CallingConventionAsync:
295 return LLVMFastCallConv;
300 return ZigLLVM_Fast;
301 case CallingConventionAPCS:
302 if (target_is_arm(g->zig_target))
303 return ZigLLVM_ARM_APCS;
304 return ZigLLVM_C;
305 case CallingConventionAAPCS:
306 if (target_is_arm(g->zig_target))
307 return ZigLLVM_ARM_AAPCS;
308 return ZigLLVM_C;
309 case CallingConventionAAPCSVFP:
310 if (target_is_arm(g->zig_target))
311 return ZigLLVM_ARM_AAPCS_VFP;
312 return ZigLLVM_C;
313 case CallingConventionInterrupt:
314 if (g->zig_target->arch == ZigLLVM_x86 ||
315 g->zig_target->arch == ZigLLVM_x86_64)
316 return ZigLLVM_X86_INTR;
317 if (g->zig_target->arch == ZigLLVM_avr)
318 return ZigLLVM_AVR_INTR;
319 if (g->zig_target->arch == ZigLLVM_msp430)
320 return ZigLLVM_MSP430_INTR;
321 return ZigLLVM_C;
322 case CallingConventionSignal:
323 if (g->zig_target->arch == ZigLLVM_avr)
324 return ZigLLVM_AVR_SIGNAL;
325 return ZigLLVM_C;
296326 }
297327 zig_unreachable();
298328}
......@@ -384,7 +414,15 @@ static bool cc_want_sret_attr(CallingConvention cc) {
384414 zig_unreachable();
385415 case CallingConventionC:
386416 case CallingConventionCold:
417 case CallingConventionInterrupt:
418 case CallingConventionSignal:
387419 case CallingConventionStdcall:
420 case CallingConventionFastcall:
421 case CallingConventionVectorcall:
422 case CallingConventionThiscall:
423 case CallingConventionAPCS:
424 case CallingConventionAAPCS:
425 case CallingConventionAAPCSVFP:
388426 return true;
389427 case CallingConventionAsync:
390428 case CallingConventionUnspecified:
......@@ -481,7 +519,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
481519 if (cc == CallingConventionNaked) {
482520 addLLVMFnAttr(llvm_fn, "naked");
483521 } else {
484 LLVMSetFunctionCallConv(llvm_fn, get_llvm_cc(g, fn_type->data.fn.fn_type_id.cc));
522 ZigLLVMFunctionSetCallingConv(llvm_fn, get_llvm_cc(g, fn_type->data.fn.fn_type_id.cc));
485523 }
486524
487525 bool want_cold = fn->is_cold || cc == CallingConventionCold;
......@@ -976,7 +1014,7 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace
9761014{
9771015 assert(g->panic_fn != nullptr);
9781016 LLVMValueRef fn_val = fn_llvm_value(g, g->panic_fn);
979 LLVMCallConv llvm_cc = get_llvm_cc(g, g->panic_fn->type_entry->data.fn.fn_type_id.cc);
1017 ZigLLVM_CallingConv llvm_cc = get_llvm_cc(g, g->panic_fn->type_entry->data.fn.fn_type_id.cc);
9801018 if (stack_trace_arg == nullptr) {
9811019 stack_trace_arg = LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type(g)));
9821020 }
......@@ -1087,7 +1125,7 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {
10871125 LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref);
10881126 addLLVMFnAttr(fn_val, "alwaysinline");
10891127 LLVMSetLinkage(fn_val, LLVMInternalLinkage);
1090 LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
1128 ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
10911129 addLLVMFnAttr(fn_val, "nounwind");
10921130 add_uwtable_attr(g, fn_val);
10931131 // Error return trace memory is in the stack, which is impossible to be at address 0
......@@ -1168,7 +1206,7 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
11681206 addLLVMFnAttr(fn_val, "noinline"); // so that we can look at return address
11691207 addLLVMFnAttr(fn_val, "cold");
11701208 LLVMSetLinkage(fn_val, LLVMInternalLinkage);
1171 LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
1209 ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
11721210 addLLVMFnAttr(fn_val, "nounwind");
11731211 add_uwtable_attr(g, fn_val);
11741212 if (codegen_have_frame_pointer(g)) {
......@@ -1252,7 +1290,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
12521290 addLLVMFnAttr(fn_val, "noreturn");
12531291 addLLVMFnAttr(fn_val, "cold");
12541292 LLVMSetLinkage(fn_val, LLVMInternalLinkage);
1255 LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
1293 ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
12561294 addLLVMFnAttr(fn_val, "nounwind");
12571295 add_uwtable_attr(g, fn_val);
12581296 if (codegen_have_frame_pointer(g)) {
......@@ -2148,7 +2186,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
21482186 const char *fn_name = get_mangled_name(g, "__zig_merge_error_return_traces", false);
21492187 LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref);
21502188 LLVMSetLinkage(fn_val, LLVMInternalLinkage);
2151 LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
2189 ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
21522190 addLLVMFnAttr(fn_val, "nounwind");
21532191 add_uwtable_attr(g, fn_val);
21542192 addLLVMArgAttr(fn_val, (unsigned)0, "noalias");
......@@ -2325,7 +2363,7 @@ static LLVMValueRef gen_resume(CodeGen *g, LLVMValueRef fn_val, LLVMValueRef tar
23252363 LLVMValueRef arg_val = LLVMConstSub(LLVMConstAllOnes(usize_type_ref),
23262364 LLVMConstInt(usize_type_ref, resume_id, false));
23272365 LLVMValueRef args[] = {target_frame_ptr, arg_val};
2328 return ZigLLVMBuildCall(g->builder, fn_val, args, 2, LLVMFastCallConv, ZigLLVM_CallAttrAuto, "");
2366 return ZigLLVMBuildCall(g->builder, fn_val, args, 2, ZigLLVM_Fast, ZigLLVM_CallAttrAuto, "");
23292367}
23302368
23312369static LLVMBasicBlockRef gen_suspend_begin(CodeGen *g, const char *name_hint) {
......@@ -4215,7 +4253,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
42154253 break;
42164254 }
42174255
4218 LLVMCallConv llvm_cc = get_llvm_cc(g, cc);
4256 ZigLLVM_CallingConv llvm_cc = get_llvm_cc(g, cc);
42194257 LLVMValueRef result;
42204258
42214259 if (callee_is_async) {
......@@ -4925,7 +4963,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {
49254963 buf_ptr(buf_sprintf("__zig_tag_name_%s", buf_ptr(&enum_type->name))), false);
49264964 LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref);
49274965 LLVMSetLinkage(fn_val, LLVMInternalLinkage);
4928 LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
4966 ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
49294967 addLLVMFnAttr(fn_val, "nounwind");
49304968 add_uwtable_attr(g, fn_val);
49314969 if (codegen_have_frame_pointer(g)) {
......@@ -8463,8 +8501,16 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
84638501 static_assert(CallingConventionC == 1, "");
84648502 static_assert(CallingConventionCold == 2, "");
84658503 static_assert(CallingConventionNaked == 3, "");
8466 static_assert(CallingConventionStdcall == 4, "");
8467 static_assert(CallingConventionAsync == 5, "");
8504 static_assert(CallingConventionAsync == 4, "");
8505 static_assert(CallingConventionInterrupt == 5, "");
8506 static_assert(CallingConventionSignal == 6, "");
8507 static_assert(CallingConventionStdcall == 7, "");
8508 static_assert(CallingConventionFastcall == 8, "");
8509 static_assert(CallingConventionVectorcall == 9, "");
8510 static_assert(CallingConventionThiscall == 10, "");
8511 static_assert(CallingConventionAPCS == 11, "");
8512 static_assert(CallingConventionAAPCS == 12, "");
8513 static_assert(CallingConventionAAPCSVFP == 13, "");
84688514
84698515 static_assert(FnInlineAuto == 0, "");
84708516 static_assert(FnInlineAlways == 1, "");
src/ir.cpp+46-12
......@@ -3248,12 +3248,13 @@ static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope,
32483248}
32493249
32503250static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *source_node,
3251 IrInstruction **param_types, IrInstruction *align_value, IrInstruction *return_type,
3252 bool is_var_args)
3251 IrInstruction **param_types, IrInstruction *align_value, IrInstruction *callconv_value,
3252 IrInstruction *return_type, bool is_var_args)
32533253{
32543254 IrInstructionFnProto *instruction = ir_build_instruction<IrInstructionFnProto>(irb, scope, source_node);
32553255 instruction->param_types = param_types;
32563256 instruction->align_value = align_value;
3257 instruction->callconv_value = callconv_value;
32573258 instruction->return_type = return_type;
32583259 instruction->is_var_args = is_var_args;
32593260
......@@ -3264,6 +3265,7 @@ static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *s
32643265 if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block);
32653266 }
32663267 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block);
3268 if (callconv_value != nullptr) ir_ref_instruction(callconv_value, irb->current_basic_block);
32673269 ir_ref_instruction(return_type, irb->current_basic_block);
32683270
32693271 return &instruction->base;
......@@ -8843,6 +8845,13 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
88438845 return irb->codegen->invalid_instruction;
88448846 }
88458847
8848 IrInstruction *callconv_value = nullptr;
8849 if (node->data.fn_proto.callconv_expr != nullptr) {
8850 callconv_value = ir_gen_node(irb, node->data.fn_proto.callconv_expr, parent_scope);
8851 if (callconv_value == irb->codegen->invalid_instruction)
8852 return irb->codegen->invalid_instruction;
8853 }
8854
88468855 IrInstruction *return_type;
88478856 if (node->data.fn_proto.return_var_token == nullptr) {
88488857 if (node->data.fn_proto.return_type == nullptr) {
......@@ -8859,7 +8868,7 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
88598868 //return_type = nullptr;
88608869 }
88618870
8862 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args);
8871 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, callconv_value, return_type, is_var_args);
88638872}
88648873
88658874static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) {
......@@ -16729,9 +16738,17 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
1672916738 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here"));
1673016739 } break;
1673116740 case CallingConventionC:
16732 case CallingConventionNaked:
1673316741 case CallingConventionCold:
16742 case CallingConventionNaked:
16743 case CallingConventionInterrupt:
16744 case CallingConventionSignal:
1673416745 case CallingConventionStdcall:
16746 case CallingConventionFastcall:
16747 case CallingConventionVectorcall:
16748 case CallingConventionThiscall:
16749 case CallingConventionAPCS:
16750 case CallingConventionAAPCS:
16751 case CallingConventionAAPCSVFP:
1673516752 add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, cc);
1673616753 break;
1673716754 }
......@@ -18094,7 +18111,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i
1809418111 return ira->codegen->invalid_instruction;
1809518112 }
1809618113
18097
1809818114 if (fn_type_id->is_var_args) {
1809918115 if (call_param_count < src_param_count) {
1810018116 ErrorMsg *msg = ir_add_error_node(ira, source_node,
......@@ -18247,8 +18263,9 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i
1824718263 buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name);
1824818264 impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn);
1824918265 impl_fn->child_scope = &impl_fn->fndef_scope->base;
18266 impl_fn->cc = fn_entry->cc;
1825018267 FnTypeId inst_fn_type_id = {0};
18251 init_fn_type_id(&inst_fn_type_id, fn_proto_node, new_fn_arg_count);
18268 init_fn_type_id(&inst_fn_type_id, fn_proto_node, fn_type_id->cc, new_fn_arg_count);
1825218269 inst_fn_type_id.param_count = 0;
1825318270 inst_fn_type_id.is_var_args = false;
1825418271
......@@ -22585,8 +22602,8 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
2258522602 // calling_convention: TypeInfo.CallingConvention
2258622603 ensure_field_index(fn_decl_val->type, "calling_convention", 2);
2258722604 fn_decl_fields[2]->special = ConstValSpecialStatic;
22588 fn_decl_fields[2]->type = ir_type_info_get_type(ira, "CallingConvention", nullptr);
22589 bigint_init_unsigned(&fn_decl_fields[2]->data.x_enum_tag, fn_node->cc);
22605 fn_decl_fields[2]->type = get_builtin_type(ira->codegen, "CallingConvention");
22606 bigint_init_unsigned(&fn_decl_fields[2]->data.x_enum_tag, fn_entry->cc);
2259022607 // is_var_args: bool
2259122608 ensure_field_index(fn_decl_val->type, "is_var_args", 3);
2259222609 bool is_varargs = fn_node->is_var_args;
......@@ -23273,7 +23290,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
2327323290 // calling_convention: TypeInfo.CallingConvention
2327423291 ensure_field_index(result->type, "calling_convention", 0);
2327523292 fields[0]->special = ConstValSpecialStatic;
23276 fields[0]->type = ir_type_info_get_type(ira, "CallingConvention", nullptr);
23293 fields[0]->type = get_builtin_type(ira->codegen, "CallingConvention");
2327723294 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc);
2327823295 // is_generic: bool
2327923296 ensure_field_index(result->type, "is_generic", 1);
......@@ -26185,6 +26202,21 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct
2618526202 return ira->codegen->invalid_instruction;
2618626203 }
2618726204
26205 lazy_fn_type->cc = cc_from_fn_proto(&proto_node->data.fn_proto);
26206 if (instruction->callconv_value != nullptr) {
26207 ZigType *cc_enum_type = get_builtin_type(ira->codegen, "CallingConvention");
26208
26209 IrInstruction *casted_value = ir_implicit_cast(ira, instruction->callconv_value, cc_enum_type);
26210 if (type_is_invalid(casted_value->value->type))
26211 return ira->codegen->invalid_instruction;
26212
26213 ZigValue *const_value = ir_resolve_const(ira, casted_value, UndefBad);
26214 if (const_value == nullptr)
26215 return ira->codegen->invalid_instruction;
26216
26217 lazy_fn_type->cc = (CallingConvention)bigint_as_u32(&const_value->data.x_enum_tag);
26218 }
26219
2618826220 size_t param_count = proto_node->data.fn_proto.params.length;
2618926221 lazy_fn_type->proto_node = proto_node;
2619026222 lazy_fn_type->param_types = allocate<IrInstruction *>(param_count);
......@@ -26195,9 +26227,11 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct
2619526227
2619626228 bool param_is_var_args = param_node->data.param_decl.is_var_args;
2619726229 if (param_is_var_args) {
26198 if (proto_node->data.fn_proto.cc == CallingConventionC) {
26230 const CallingConvention cc = lazy_fn_type->cc;
26231
26232 if (cc == CallingConventionC) {
2619926233 break;
26200 } else if (proto_node->data.fn_proto.cc == CallingConventionUnspecified) {
26234 } else if (cc == CallingConventionUnspecified) {
2620126235 lazy_fn_type->is_generic = true;
2620226236 return result;
2620326237 } else {
......@@ -29076,7 +29110,7 @@ static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, La
2907629110 AstNode *proto_node = lazy_fn_type->proto_node;
2907729111
2907829112 FnTypeId fn_type_id = {0};
29079 init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length);
29113 init_fn_type_id(&fn_type_id, proto_node, lazy_fn_type->cc, proto_node->data.fn_proto.params.length);
2908029114
2908129115 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) {
2908229116 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);
9292static AstNode *ast_parse_field_init(ParseContext *pc);
9393static AstNode *ast_parse_while_continue_expr(ParseContext *pc);
9494static AstNode *ast_parse_link_section(ParseContext *pc);
95static AstNode *ast_parse_callconv(ParseContext *pc);
9596static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc);
9697static AstNode *ast_parse_param_decl(ParseContext *pc);
9798static AstNode *ast_parse_param_type(ParseContext *pc);
......@@ -676,7 +677,9 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
676677 fn_proto->column = first->start_column;
677678 fn_proto->data.fn_proto.visib_mod = visib_mod;
678679 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;
680683 fn_proto->data.fn_proto.is_export = first->id == TokenIdKeywordExport;
681684 switch (first->id) {
682685 case TokenIdKeywordInline:
......@@ -761,7 +764,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
761764 // The extern keyword for fn CC is also used for container decls.
762765 // We therefore put it back, as allow container decl to consume it
763766 // later.
764 if (fn_cc.cc == CallingConventionC) {
767 if (fn_cc.is_extern) {
765768 fn = eat_token_if(pc, TokenIdKeywordFn);
766769 if (fn == nullptr) {
767770 put_back_token(pc);
......@@ -784,6 +787,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
784787
785788 AstNode *align_expr = ast_parse_byte_align(pc);
786789 AstNode *section_expr = ast_parse_link_section(pc);
790 AstNode *callconv_expr = ast_parse_callconv(pc);
787791 Token *var = eat_token_if(pc, TokenIdKeywordVar);
788792 Token *exmark = nullptr;
789793 AstNode *return_type = nullptr;
......@@ -798,6 +802,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
798802 res->data.fn_proto.params = params;
799803 res->data.fn_proto.align_expr = align_expr;
800804 res->data.fn_proto.section_expr = section_expr;
805 res->data.fn_proto.callconv_expr = callconv_expr;
801806 res->data.fn_proto.return_var_token = var;
802807 res->data.fn_proto.auto_err_set = exmark != nullptr;
803808 res->data.fn_proto.return_type = return_type;
......@@ -2099,6 +2104,18 @@ static AstNode *ast_parse_link_section(ParseContext *pc) {
20992104 return res;
21002105}
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
21022119// FnCC
21032120// <- KEYWORD_nakedcc
21042121// / KEYWORD_stdcallcc
......@@ -2107,19 +2124,19 @@ static AstNode *ast_parse_link_section(ParseContext *pc) {
21072124static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc) {
21082125 AstNodeFnProto res = {};
21092126 if (eat_token_if(pc, TokenIdKeywordNakedCC) != nullptr) {
2110 res.cc = CallingConventionNaked;
2127 res.is_nakedcc = true;
21112128 return Optional<AstNodeFnProto>::some(res);
21122129 }
21132130 if (eat_token_if(pc, TokenIdKeywordStdcallCC) != nullptr) {
2114 res.cc = CallingConventionStdcall;
2131 res.is_stdcallcc = true;
21152132 return Optional<AstNodeFnProto>::some(res);
21162133 }
2117 if (eat_token_if(pc, TokenIdKeywordExtern) != nullptr) {
2118 res.cc = CallingConventionC;
2134 if (eat_token_if(pc, TokenIdKeywordAsync) != nullptr) {
2135 res.is_async = true;
21192136 return Optional<AstNodeFnProto>::some(res);
21202137 }
2121 if (eat_token_if(pc, TokenIdKeywordAsync) != nullptr) {
2122 res.cc = CallingConventionAsync;
2138 if (eat_token_if(pc, TokenIdKeywordExtern) != nullptr) {
2139 res.is_extern = true;
21232140 return Optional<AstNodeFnProto>::some(res);
21242141 }
21252142
src/tokenizer.cpp+2
......@@ -110,6 +110,7 @@ static const struct ZigKeyword zig_keywords[] = {
110110 {"async", TokenIdKeywordAsync},
111111 {"await", TokenIdKeywordAwait},
112112 {"break", TokenIdKeywordBreak},
113 {"callconv", TokenIdKeywordCallconv},
113114 {"catch", TokenIdKeywordCatch},
114115 {"comptime", TokenIdKeywordCompTime},
115116 {"const", TokenIdKeywordConst},
......@@ -1545,6 +1546,7 @@ const char * token_name(TokenId id) {
15451546 case TokenIdKeywordAsm: return "asm";
15461547 case TokenIdKeywordBreak: return "break";
15471548 case TokenIdKeywordCatch: return "catch";
1549 case TokenIdKeywordCallconv: return "callconv";
15481550 case TokenIdKeywordCompTime: return "comptime";
15491551 case TokenIdKeywordConst: return "const";
15501552 case TokenIdKeywordContinue: return "continue";
src/tokenizer.hpp+1
......@@ -59,6 +59,7 @@ enum TokenId {
5959 TokenIdKeywordAwait,
6060 TokenIdKeywordBreak,
6161 TokenIdKeywordCatch,
62 TokenIdKeywordCallconv,
6263 TokenIdKeywordCompTime,
6364 TokenIdKeywordConst,
6465 TokenIdKeywordContinue,
src/zig_llvm.cpp+51-2
......@@ -273,10 +273,10 @@ ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref) {
273273}
274274
275275LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
276 unsigned NumArgs, unsigned CC, ZigLLVM_CallAttr attr, const char *Name)
276 unsigned NumArgs, ZigLLVM_CallingConv CC, ZigLLVM_CallAttr attr, const char *Name)
277277{
278278 CallInst *call_inst = CallInst::Create(unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Name);
279 call_inst->setCallingConv(CC);
279 call_inst->setCallingConv(static_cast<CallingConv::ID>(CC));
280280 switch (attr) {
281281 case ZigLLVM_CallAttrAuto:
282282 break;
......@@ -932,6 +932,9 @@ void ZigLLVMFunctionSetPrefixData(LLVMValueRef function, LLVMValueRef data) {
932932 unwrap<Function>(function)->setPrefixData(unwrap<Constant>(data));
933933}
934934
935void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, ZigLLVM_CallingConv cc) {
936 unwrap<Function>(function)->setCallingConv(static_cast<CallingConv::ID>(cc));
937}
935938
936939class MyOStream: public raw_ostream {
937940 public:
......@@ -1315,3 +1318,49 @@ static_assert((Triple::ObjectFormatType)ZigLLVM_ELF == Triple::ELF, "");
13151318static_assert((Triple::ObjectFormatType)ZigLLVM_MachO == Triple::MachO, "");
13161319static_assert((Triple::ObjectFormatType)ZigLLVM_Wasm == Triple::Wasm, "");
13171320static_assert((Triple::ObjectFormatType)ZigLLVM_XCOFF == Triple::XCOFF, "");
1321
1322static_assert((CallingConv::ID)ZigLLVM_C == llvm::CallingConv::C, "");
1323static_assert((CallingConv::ID)ZigLLVM_Fast == llvm::CallingConv::Fast, "");
1324static_assert((CallingConv::ID)ZigLLVM_Cold == llvm::CallingConv::Cold, "");
1325static_assert((CallingConv::ID)ZigLLVM_GHC == llvm::CallingConv::GHC, "");
1326static_assert((CallingConv::ID)ZigLLVM_HiPE == llvm::CallingConv::HiPE, "");
1327static_assert((CallingConv::ID)ZigLLVM_WebKit_JS == llvm::CallingConv::WebKit_JS, "");
1328static_assert((CallingConv::ID)ZigLLVM_AnyReg == llvm::CallingConv::AnyReg, "");
1329static_assert((CallingConv::ID)ZigLLVM_PreserveMost == llvm::CallingConv::PreserveMost, "");
1330static_assert((CallingConv::ID)ZigLLVM_PreserveAll == llvm::CallingConv::PreserveAll, "");
1331static_assert((CallingConv::ID)ZigLLVM_Swift == llvm::CallingConv::Swift, "");
1332static_assert((CallingConv::ID)ZigLLVM_CXX_FAST_TLS == llvm::CallingConv::CXX_FAST_TLS, "");
1333static_assert((CallingConv::ID)ZigLLVM_FirstTargetCC == llvm::CallingConv::FirstTargetCC, "");
1334static_assert((CallingConv::ID)ZigLLVM_X86_StdCall == llvm::CallingConv::X86_StdCall, "");
1335static_assert((CallingConv::ID)ZigLLVM_X86_FastCall == llvm::CallingConv::X86_FastCall, "");
1336static_assert((CallingConv::ID)ZigLLVM_ARM_APCS == llvm::CallingConv::ARM_APCS, "");
1337static_assert((CallingConv::ID)ZigLLVM_ARM_AAPCS == llvm::CallingConv::ARM_AAPCS, "");
1338static_assert((CallingConv::ID)ZigLLVM_ARM_AAPCS_VFP == llvm::CallingConv::ARM_AAPCS_VFP, "");
1339static_assert((CallingConv::ID)ZigLLVM_MSP430_INTR == llvm::CallingConv::MSP430_INTR, "");
1340static_assert((CallingConv::ID)ZigLLVM_X86_ThisCall == llvm::CallingConv::X86_ThisCall, "");
1341static_assert((CallingConv::ID)ZigLLVM_PTX_Kernel == llvm::CallingConv::PTX_Kernel, "");
1342static_assert((CallingConv::ID)ZigLLVM_PTX_Device == llvm::CallingConv::PTX_Device, "");
1343static_assert((CallingConv::ID)ZigLLVM_SPIR_FUNC == llvm::CallingConv::SPIR_FUNC, "");
1344static_assert((CallingConv::ID)ZigLLVM_SPIR_KERNEL == llvm::CallingConv::SPIR_KERNEL, "");
1345static_assert((CallingConv::ID)ZigLLVM_Intel_OCL_BI == llvm::CallingConv::Intel_OCL_BI, "");
1346static_assert((CallingConv::ID)ZigLLVM_X86_64_SysV == llvm::CallingConv::X86_64_SysV, "");
1347static_assert((CallingConv::ID)ZigLLVM_Win64 == llvm::CallingConv::Win64, "");
1348static_assert((CallingConv::ID)ZigLLVM_X86_VectorCall == llvm::CallingConv::X86_VectorCall, "");
1349static_assert((CallingConv::ID)ZigLLVM_HHVM == llvm::CallingConv::HHVM, "");
1350static_assert((CallingConv::ID)ZigLLVM_HHVM_C == llvm::CallingConv::HHVM_C, "");
1351static_assert((CallingConv::ID)ZigLLVM_X86_INTR == llvm::CallingConv::X86_INTR, "");
1352static_assert((CallingConv::ID)ZigLLVM_AVR_INTR == llvm::CallingConv::AVR_INTR, "");
1353static_assert((CallingConv::ID)ZigLLVM_AVR_SIGNAL == llvm::CallingConv::AVR_SIGNAL, "");
1354static_assert((CallingConv::ID)ZigLLVM_AVR_BUILTIN == llvm::CallingConv::AVR_BUILTIN, "");
1355static_assert((CallingConv::ID)ZigLLVM_AMDGPU_VS == llvm::CallingConv::AMDGPU_VS, "");
1356static_assert((CallingConv::ID)ZigLLVM_AMDGPU_GS == llvm::CallingConv::AMDGPU_GS, "");
1357static_assert((CallingConv::ID)ZigLLVM_AMDGPU_PS == llvm::CallingConv::AMDGPU_PS, "");
1358static_assert((CallingConv::ID)ZigLLVM_AMDGPU_CS == llvm::CallingConv::AMDGPU_CS, "");
1359static_assert((CallingConv::ID)ZigLLVM_AMDGPU_KERNEL == llvm::CallingConv::AMDGPU_KERNEL, "");
1360static_assert((CallingConv::ID)ZigLLVM_X86_RegCall == llvm::CallingConv::X86_RegCall, "");
1361static_assert((CallingConv::ID)ZigLLVM_AMDGPU_HS == llvm::CallingConv::AMDGPU_HS, "");
1362static_assert((CallingConv::ID)ZigLLVM_MSP430_BUILTIN == llvm::CallingConv::MSP430_BUILTIN, "");
1363static_assert((CallingConv::ID)ZigLLVM_AMDGPU_LS == llvm::CallingConv::AMDGPU_LS, "");
1364static_assert((CallingConv::ID)ZigLLVM_AMDGPU_ES == llvm::CallingConv::AMDGPU_ES, "");
1365static_assert((CallingConv::ID)ZigLLVM_AArch64_VectorCall == llvm::CallingConv::AArch64_VectorCall, "");
1366static_assert((CallingConv::ID)ZigLLVM_MaxID == llvm::CallingConv::MaxID, "");
src/zig_llvm.h+50-1
......@@ -64,6 +64,54 @@ ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, co
6464
6565ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref);
6666
67enum ZigLLVM_CallingConv {
68 ZigLLVM_C = 0,
69 ZigLLVM_Fast = 8,
70 ZigLLVM_Cold = 9,
71 ZigLLVM_GHC = 10,
72 ZigLLVM_HiPE = 11,
73 ZigLLVM_WebKit_JS = 12,
74 ZigLLVM_AnyReg = 13,
75 ZigLLVM_PreserveMost = 14,
76 ZigLLVM_PreserveAll = 15,
77 ZigLLVM_Swift = 16,
78 ZigLLVM_CXX_FAST_TLS = 17,
79 ZigLLVM_FirstTargetCC = 64,
80 ZigLLVM_X86_StdCall = 64,
81 ZigLLVM_X86_FastCall = 65,
82 ZigLLVM_ARM_APCS = 66,
83 ZigLLVM_ARM_AAPCS = 67,
84 ZigLLVM_ARM_AAPCS_VFP = 68,
85 ZigLLVM_MSP430_INTR = 69,
86 ZigLLVM_X86_ThisCall = 70,
87 ZigLLVM_PTX_Kernel = 71,
88 ZigLLVM_PTX_Device = 72,
89 ZigLLVM_SPIR_FUNC = 75,
90 ZigLLVM_SPIR_KERNEL = 76,
91 ZigLLVM_Intel_OCL_BI = 77,
92 ZigLLVM_X86_64_SysV = 78,
93 ZigLLVM_Win64 = 79,
94 ZigLLVM_X86_VectorCall = 80,
95 ZigLLVM_HHVM = 81,
96 ZigLLVM_HHVM_C = 82,
97 ZigLLVM_X86_INTR = 83,
98 ZigLLVM_AVR_INTR = 84,
99 ZigLLVM_AVR_SIGNAL = 85,
100 ZigLLVM_AVR_BUILTIN = 86,
101 ZigLLVM_AMDGPU_VS = 87,
102 ZigLLVM_AMDGPU_GS = 88,
103 ZigLLVM_AMDGPU_PS = 89,
104 ZigLLVM_AMDGPU_CS = 90,
105 ZigLLVM_AMDGPU_KERNEL = 91,
106 ZigLLVM_X86_RegCall = 92,
107 ZigLLVM_AMDGPU_HS = 93,
108 ZigLLVM_MSP430_BUILTIN = 94,
109 ZigLLVM_AMDGPU_LS = 95,
110 ZigLLVM_AMDGPU_ES = 96,
111 ZigLLVM_AArch64_VectorCall = 97,
112 ZigLLVM_MaxID = 1023,
113};
114
67115enum ZigLLVM_CallAttr {
68116 ZigLLVM_CallAttrAuto,
69117 ZigLLVM_CallAttrNeverTail,
......@@ -72,7 +120,7 @@ enum ZigLLVM_CallAttr {
72120 ZigLLVM_CallAttrAlwaysInline,
73121};
74122ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
75 unsigned NumArgs, unsigned CC, enum ZigLLVM_CallAttr attr, const char *Name);
123 unsigned NumArgs, enum ZigLLVM_CallingConv CC, enum ZigLLVM_CallAttr attr, const char *Name);
76124
77125ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign,
78126 LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size, bool isVolatile);
......@@ -215,6 +263,7 @@ ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigne
215263ZIG_EXTERN_C void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state);
216264ZIG_EXTERN_C void ZigLLVMSetTailCall(LLVMValueRef Call);
217265ZIG_EXTERN_C void ZigLLVMFunctionSetPrefixData(LLVMValueRef fn, LLVMValueRef data);
266ZIG_EXTERN_C void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, enum ZigLLVM_CallingConv cc);
218267
219268ZIG_EXTERN_C void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value);
220269ZIG_EXTERN_C void ZigLLVMAddByValAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val);
test/compile_errors.zig+15-15
......@@ -752,7 +752,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
752752 \\ _ = @frame();
753753 \\}
754754 , &[_][]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",
756756 "tmp.zig:5:9: note: @frame() causes function to be async",
757757 });
758758
......@@ -765,7 +765,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
765765 \\ suspend;
766766 \\}
767767 , &[_][]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",
769769 "tmp.zig:3:18: note: await here is a suspend point",
770770 });
771771
......@@ -843,7 +843,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
843843 \\ suspend;
844844 \\}
845845 , &[_][]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",
847847 "tmp.zig:2:8: note: async function call here",
848848 "tmp.zig:5:8: note: async function call here",
849849 "tmp.zig:8:5: note: suspends here",
......@@ -1140,7 +1140,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
11401140 \\ while (true) {}
11411141 \\}
11421142 , &[_][]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'",
11441144 "note: only one of the functions is generic",
11451145 });
11461146
......@@ -1362,7 +1362,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
13621362 \\ return 0;
13631363 \\}
13641364 , &[_][]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'",
13661366 });
13671367
13681368 cases.add("C pointer to c_void",
......@@ -2187,7 +2187,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
21872187 \\ f(g);
21882188 \\}
21892189 , &[_][]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",
21912191 });
21922192
21932193 cases.add("optional pointer to void in extern struct",
......@@ -2859,7 +2859,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
28592859 \\const Foo = enum { A, B, C };
28602860 \\export fn entry(foo: Foo) void { }
28612861 , &[_][]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'",
28632863 });
28642864
28652865 cases.add("function with non-extern non-packed struct parameter",
......@@ -2870,7 +2870,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
28702870 \\};
28712871 \\export fn entry(foo: Foo) void { }
28722872 , &[_][]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'",
28742874 });
28752875
28762876 cases.add("function with non-extern non-packed union parameter",
......@@ -2881,7 +2881,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
28812881 \\};
28822882 \\export fn entry(foo: Foo) void { }
28832883 , &[_][]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'",
28852885 });
28862886
28872887 cases.add("switch on enum with 1 field with no prongs",
......@@ -2977,8 +2977,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
29772977 \\ bar(&{});
29782978 \\}
29792979 , &[_][]const u8{
2980 "tmp.zig:1:30: 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 '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 'C'",
29822982 });
29832983
29842984 cases.add("implicit semicolon - block statement",
......@@ -4552,7 +4552,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
45524552 \\ return x + y;
45534553 \\}
45544554 , &[_][]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'",
45564556 });
45574557
45584558 cases.add("extern function with comptime parameter",
......@@ -4562,7 +4562,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
45624562 \\}
45634563 \\export fn entry() usize { return @sizeOf(@TypeOf(f)); }
45644564 , &[_][]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'",
45664566 });
45674567
45684568 cases.add("convert fixed size array to slice with invalid size",
......@@ -6303,7 +6303,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
63036303 \\ _ = @TypeOf(generic).ReturnType;
63046304 \\}
63056305 , &[_][]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",
63076307 });
63086308
63096309 cases.add("getting @ArgType of generic function",
......@@ -6312,7 +6312,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
63126312 \\ _ = @ArgType(@TypeOf(generic), 0);
63136313 \\}
63146314 , &[_][]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",
63166316 });
63176317
63186318 cases.add("unsupported modifier at start of asm output constraint",
test/src/translate_c.zig+14
......@@ -19,6 +19,7 @@ pub const TranslateCContext = struct {
1919 sources: ArrayList(SourceFile),
2020 expected_lines: ArrayList([]const u8),
2121 allow_warnings: bool,
22 target: std.Target = .Native,
2223
2324 const SourceFile = struct {
2425 filename: []const u8,
......@@ -71,6 +72,18 @@ pub const TranslateCContext = struct {
7172 self.addCase(tc);
7273 }
7374
75 pub fn addWithTarget(
76 self: *TranslateCContext,
77 name: []const u8,
78 target: std.Target,
79 source: []const u8,
80 expected_lines: []const []const u8,
81 ) void {
82 const tc = self.create(false, "source.h", name, source, expected_lines);
83 tc.target = target;
84 self.addCase(tc);
85 }
86
7487 pub fn addAllowWarnings(
7588 self: *TranslateCContext,
7689 name: []const u8,
......@@ -101,6 +114,7 @@ pub const TranslateCContext = struct {
101114 .basename = case.sources.toSliceConst()[0].filename,
102115 },
103116 });
117 translate_c.setTarget(case.target);
104118
105119 const check_file = translate_c.addCheckFile(case.expected_lines.toSliceConst());
106120
test/stage1/behavior/type_info.zig+2-2
......@@ -202,7 +202,7 @@ fn testUnion() void {
202202 expect(typeinfo_info.Union.fields[4].enum_field != null);
203203 expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
204204 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
207207 const TestNoTagUnion = union {
208208 Foo: void,
......@@ -266,7 +266,7 @@ test "type info: function type info" {
266266fn testFunction() void {
267267 const fn_info = @typeInfo(@TypeOf(foo));
268268 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);
270270 expect(fn_info.Fn.is_generic);
271271 expect(fn_info.Fn.args.len == 2);
272272 expect(fn_info.Fn.is_var_args);
test/translate_c.zig+41-7
......@@ -205,7 +205,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
205205 \\static void bar(void) {}
206206 , &[_][]const u8{
207207 \\pub export fn foo() void {}
208 \\pub fn bar() void {}
208 \\pub fn bar() callconv(.C) void {}
209209 });
210210
211211 cases.add("typedef void",
......@@ -957,6 +957,40 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
957957 \\pub const fn1 = ?extern fn (u8) void;
958958 });
959959
960 cases.addWithTarget("Calling convention", tests.Target{
961 .Cross = .{ .os = .linux, .arch = .i386, .abi = .none },
962 },
963 \\void __attribute__((fastcall)) foo1(float *a);
964 \\void __attribute__((stdcall)) foo2(float *a);
965 \\void __attribute__((vectorcall)) foo3(float *a);
966 \\void __attribute__((cdecl)) foo4(float *a);
967 \\void __attribute__((thiscall)) foo5(float *a);
968 , &[_][]const u8{
969 \\pub fn foo1(a: [*c]f32) callconv(.Fastcall) void;
970 \\pub fn foo2(a: [*c]f32) callconv(.Stdcall) void;
971 \\pub fn foo3(a: [*c]f32) callconv(.Vectorcall) void;
972 \\pub extern fn foo4(a: [*c]f32) void;
973 \\pub fn foo5(a: [*c]f32) callconv(.Thiscall) void;
974 });
975
976 cases.addWithTarget("Calling convention", tests.Target{
977 .Cross = .{ .os = .linux, .arch = .{ .arm = .v8_5a }, .abi = .none },
978 },
979 \\void __attribute__((pcs("aapcs"))) foo1(float *a);
980 \\void __attribute__((pcs("aapcs-vfp"))) foo2(float *a);
981 , &[_][]const u8{
982 \\pub fn foo1(a: [*c]f32) callconv(.AAPCS) void;
983 \\pub fn foo2(a: [*c]f32) callconv(.AAPCSVFP) void;
984 });
985
986 cases.addWithTarget("Calling convention", tests.Target{
987 .Cross = .{ .os = .linux, .arch = .{ .aarch64 = .v8_5a }, .abi = .none },
988 },
989 \\void __attribute__((aarch64_vector_pcs)) foo1(float *a);
990 , &[_][]const u8{
991 \\pub fn foo1(a: [*c]f32) callconv(.Vectorcall) void;
992 });
993
960994 cases.add("Parameterless function prototypes",
961995 \\void a() {}
962996 \\void b(void) {}
......@@ -985,7 +1019,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
9851019 \\ char *arr1[10] ={0};
9861020 \\}
9871021 , &[_][]const u8{
988 \\pub fn foo() void {
1022 \\pub fn foo() callconv(.C) void {
9891023 \\ var arr: [10]u8 = .{
9901024 \\ @bitCast(u8, @truncate(i8, @as(c_int, 1))),
9911025 \\ } ++ .{0} ** 9;
......@@ -2262,7 +2296,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
22622296 \\ baz();
22632297 \\}
22642298 , &[_][]const u8{
2265 \\pub fn bar() void {}
2299 \\pub fn bar() callconv(.C) void {}
22662300 \\pub export fn foo(arg_baz: ?extern fn () [*c]c_int) void {
22672301 \\ var baz = arg_baz;
22682302 \\ bar();
......@@ -2321,7 +2355,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
23212355 \\ do {} while (0);
23222356 \\}
23232357 , &[_][]const u8{
2324 \\pub fn foo() void {
2358 \\pub fn foo() callconv(.C) void {
23252359 \\ if (@as(c_int, 1) != 0) while (true) {
23262360 \\ if (!(@as(c_int, 0) != 0)) break;
23272361 \\ };
......@@ -2413,9 +2447,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
24132447 \\void c(void) {}
24142448 \\static void foo() {}
24152449 , &[_][]const u8{
2416 \\pub fn a() void {}
2417 \\pub fn b() void {}
2450 \\pub fn a() callconv(.C) void {}
2451 \\pub fn b() callconv(.C) void {}
24182452 \\pub export fn c() void {}
2419 \\pub fn foo() void {}
2453 \\pub fn foo() callconv(.C) void {}
24202454 });
24212455}