| author | |
| committer | |
| log | 0a9daeb37e997ff75dcd16d1fc3b4cc143314e85 |
| tree | 05ca7f6b64b1e40fc16a595816f3a632a986617c |
| parent | c30106c90665079f525129e344cc1c13e4db162b |
| parent | d09bd3d86c4d36ad608a91b36c9a6eb6208c9626 |
| signature |
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 |
| 818 | 818 | .Keyword_resume, |
| 819 | 819 | .Keyword_return, |
| 820 | 820 | .Keyword_linksection, |
| 821 | .Keyword_callconv, | |
| 821 | 822 | .Keyword_stdcallcc, |
| 822 | 823 | .Keyword_struct, |
| 823 | 824 | .Keyword_suspend, |
doc/langref.html.in+1-1| ... | ... | @@ -2829,7 +2829,7 @@ test "@tagName" { |
| 2829 | 2829 | <p> |
| 2830 | 2830 | By default, enums are not guaranteed to be compatible with the C ABI: |
| 2831 | 2831 | </p> |
| 2832 | {#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'ccc'#} | |
| 2832 | {#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'C'#} | |
| 2833 | 2833 | const Foo = enum { A, B, C }; |
| 2834 | 2834 | export fn entry(foo: Foo) void { } |
| 2835 | 2835 | {#code_end#} |
lib/std/build/translate_c.zig+23-9| ... | ... | @@ -14,6 +14,7 @@ pub const TranslateCStep = struct { |
| 14 | 14 | source: build.FileSource, |
| 15 | 15 | output_dir: ?[]const u8, |
| 16 | 16 | out_basename: []const u8, |
| 17 | target: std.Target = .Native, | |
| 17 | 18 | |
| 18 | 19 | pub fn create(builder: *Builder, source: build.FileSource) *TranslateCStep { |
| 19 | 20 | const self = builder.allocator.create(TranslateCStep) catch unreachable; |
| ... | ... | @@ -38,6 +39,10 @@ pub const TranslateCStep = struct { |
| 38 | 39 | ) catch unreachable; |
| 39 | 40 | } |
| 40 | 41 | |
| 42 | pub fn setTarget(self: *TranslateCStep, target: std.Target) void { | |
| 43 | self.target = target; | |
| 44 | } | |
| 45 | ||
| 41 | 46 | /// Creates a step to build an executable from the translated source. |
| 42 | 47 | pub fn addExecutable(self: *TranslateCStep) *LibExeObjStep { |
| 43 | 48 | return self.builder.addExecutableSource("translated_c", @as(build.FileSource, .{ .translate_c = self })); |
| ... | ... | @@ -50,16 +55,25 @@ pub const TranslateCStep = struct { |
| 50 | 55 | fn make(step: *Step) !void { |
| 51 | 56 | const self = @fieldParentPtr(TranslateCStep, "step", step); |
| 52 | 57 | |
| 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)); | |
| 61 | 75 | |
| 62 | const output_path_nl = try self.builder.exec(&argv); | |
| 76 | const output_path_nl = try self.builder.exec(argv_list.toSliceConst()); | |
| 63 | 77 | const output_path = mem.trimRight(u8, output_path_nl, "\r\n"); |
| 64 | 78 | |
| 65 | 79 | self.out_basename = fs.path.basename(output_path); |
lib/std/builtin.zig+20-12| ... | ... | @@ -91,6 +91,25 @@ pub const Mode = enum { |
| 91 | 91 | ReleaseSmall, |
| 92 | 92 | }; |
| 93 | 93 | |
| 94 | /// This data structure is used by the Zig language code generation and | |
| 95 | /// therefore must be kept in sync with the compiler implementation. | |
| 96 | pub 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 | ||
| 94 | 113 | pub const TypeId = @TagType(TypeInfo); |
| 95 | 114 | |
| 96 | 115 | /// This data structure is used by the Zig language code generation and |
| ... | ... | @@ -253,17 +272,6 @@ pub const TypeInfo = union(enum) { |
| 253 | 272 | decls: []Declaration, |
| 254 | 273 | }; |
| 255 | 274 | |
| 256 | /// This data structure is used by the Zig language code generation and | |
| 257 | /// therefore must be kept in sync with the compiler implementation. | |
| 258 | pub const CallingConvention = enum { | |
| 259 | Unspecified, | |
| 260 | C, | |
| 261 | Cold, | |
| 262 | Naked, | |
| 263 | Stdcall, | |
| 264 | Async, | |
| 265 | }; | |
| 266 | ||
| 267 | 275 | /// This data structure is used by the Zig language code generation and |
| 268 | 276 | /// therefore must be kept in sync with the compiler implementation. |
| 269 | 277 | pub const FnArg = struct { |
| ... | ... | @@ -416,7 +424,7 @@ pub const CallOptions = struct { |
| 416 | 424 | /// therefore must be kept in sync with the compiler implementation. |
| 417 | 425 | pub const TestFn = struct { |
| 418 | 426 | name: []const u8, |
| 419 | func: fn()anyerror!void, | |
| 427 | func: fn () anyerror!void, | |
| 420 | 428 | }; |
| 421 | 429 | |
| 422 | 430 | /// This function type is used by the Zig language code generation and |
lib/std/debug.zig+1-1| ... | ... | @@ -2475,7 +2475,7 @@ extern fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *con |
| 2475 | 2475 | os.abort(); |
| 2476 | 2476 | } |
| 2477 | 2477 | |
| 2478 | stdcallcc fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) c_long { | |
| 2478 | fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) callconv(.Stdcall) c_long { | |
| 2479 | 2479 | const exception_address = @ptrToInt(info.ExceptionRecord.ExceptionAddress); |
| 2480 | 2480 | switch (info.ExceptionRecord.ExceptionCode) { |
| 2481 | 2481 | 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) |
| 73 | 73 | return self.tryAcquire() orelse @panic("deadlock detected"); |
| 74 | 74 | } |
| 75 | 75 | } |
| 76 | else if (builtin.os == .windows) | |
| 77 | // https://locklessinc.com/articles/keyed_events/ | |
| 76 | else if (builtin.os == .windows) | |
| 77 | // https://locklessinc.com/articles/keyed_events/ | |
| 78 | 78 | extern union { |
| 79 | 79 | locked: u8, |
| 80 | 80 | waiters: u32, |
| ... | ... | @@ -122,8 +122,8 @@ else if (builtin.os == .windows) |
| 122 | 122 | return Held{ .mutex = self }; |
| 123 | 123 | } |
| 124 | 124 | |
| 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. | |
| 127 | 127 | } else if (@cmpxchgWeak(u32, &self.waiters, waiters, (waiters + WAIT) | 1, .Monotonic, .Monotonic) == null) { |
| 128 | 128 | const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null); |
| 129 | 129 | assert(rc == 0); |
| ... | ... | @@ -143,7 +143,7 @@ else if (builtin.os == .windows) |
| 143 | 143 | |
| 144 | 144 | while (true) : (SpinLock.loopHint(1)) { |
| 145 | 145 | const waiters = @atomicLoad(u32, &self.mutex.waiters, .Monotonic); |
| 146 | ||
| 146 | ||
| 147 | 147 | // no one is waiting |
| 148 | 148 | if (waiters < WAIT) return; |
| 149 | 149 | // someone grabbed the lock and will do the wake instead |
| ... | ... | @@ -155,14 +155,14 @@ else if (builtin.os == .windows) |
| 155 | 155 | if (@cmpxchgWeak(u32, &self.mutex.waiters, waiters, waiters - WAIT + WAKE, .Release, .Monotonic) == null) { |
| 156 | 156 | const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null); |
| 157 | 157 | assert(rc == 0); |
| 158 | return; | |
| 158 | return; | |
| 159 | 159 | } |
| 160 | 160 | } |
| 161 | 161 | } |
| 162 | 162 | }; |
| 163 | 163 | } |
| 164 | 164 | else 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 | |
| 166 | 166 | struct { |
| 167 | 167 | state: usize, |
| 168 | 168 | |
| ... | ... | @@ -195,8 +195,8 @@ else if (builtin.link_libc or builtin.os == .linux) |
| 195 | 195 | |
| 196 | 196 | pub fn acquire(self: *Mutex) Held { |
| 197 | 197 | return self.tryAcquire() orelse { |
| 198 | self.acquireSlow(); | |
| 199 | return Held{ .mutex = self }; | |
| 198 | self.acquireSlow(); | |
| 199 | return Held{ .mutex = self }; | |
| 200 | 200 | }; |
| 201 | 201 | } |
| 202 | 202 | |
| ... | ... | @@ -265,7 +265,7 @@ else if (builtin.link_libc or builtin.os == .linux) |
| 265 | 265 | |
| 266 | 266 | fn releaseSlow(self: *Mutex) void { |
| 267 | 267 | @setCold(true); |
| 268 | ||
| 268 | ||
| 269 | 269 | // try and lock the LFIO queue to pop a node off, |
| 270 | 270 | // stopping altogether if its already locked or the queue is empty |
| 271 | 271 | var state = @atomicLoad(usize, &self.state, .Monotonic); |
| ... | ... | @@ -293,9 +293,10 @@ else if (builtin.link_libc or builtin.os == .linux) |
| 293 | 293 | } |
| 294 | 294 | } |
| 295 | 295 | |
| 296 | // for platforms without a known OS blocking | |
| 297 | // primitive, default to SpinLock for correctness | |
| 298 | else SpinLock; | |
| 296 | // for platforms without a known OS blocking | |
| 297 | // primitive, default to SpinLock for correctness | |
| 298 | else | |
| 299 | SpinLock; | |
| 299 | 300 | |
| 300 | 301 | const TestContext = struct { |
| 301 | 302 | mutex: *Mutex, |
lib/std/net.zig+1-5| ... | ... | @@ -451,11 +451,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !* |
| 451 | 451 | .next = null, |
| 452 | 452 | }; |
| 453 | 453 | 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)) { | |
| 459 | 455 | 0 => {}, |
| 460 | 456 | c.EAI_ADDRFAMILY => return error.HostLacksNetworkAddresses, |
| 461 | 457 | c.EAI_AGAIN => return error.TemporaryNameServerFailure, |
lib/std/os/linux/arm-eabi.zig+2-2| ... | ... | @@ -97,7 +97,7 @@ pub extern fn getThreadPointer() usize { |
| 97 | 97 | ); |
| 98 | 98 | } |
| 99 | 99 | |
| 100 | pub nakedcc fn restore() void { | |
| 100 | pub fn restore() callconv(.Naked) void { | |
| 101 | 101 | return asm volatile ("svc #0" |
| 102 | 102 | : |
| 103 | 103 | : [number] "{r7}" (@as(usize, SYS_sigreturn)) |
| ... | ... | @@ -105,7 +105,7 @@ pub nakedcc fn restore() void { |
| 105 | 105 | ); |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | pub nakedcc fn restore_rt() void { | |
| 108 | pub fn restore_rt() callconv(.Naked) void { | |
| 109 | 109 | return asm volatile ("svc #0" |
| 110 | 110 | : |
| 111 | 111 | : [number] "{r7}" (@as(usize, SYS_rt_sigreturn)) |
lib/std/os/linux/arm64.zig+1-1| ... | ... | @@ -90,7 +90,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, a |
| 90 | 90 | |
| 91 | 91 | pub const restore = restore_rt; |
| 92 | 92 | |
| 93 | pub nakedcc fn restore_rt() void { | |
| 93 | pub fn restore_rt() callconv(.Naked) void { | |
| 94 | 94 | return asm volatile ("svc #0" |
| 95 | 95 | : |
| 96 | 96 | : [number] "{x8}" (@as(usize, SYS_rt_sigreturn)) |
lib/std/os/linux/i386.zig+2-2| ... | ... | @@ -102,7 +102,7 @@ pub fn socketcall(call: usize, args: [*]usize) usize { |
| 102 | 102 | /// This matches the libc clone function. |
| 103 | 103 | pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; |
| 104 | 104 | |
| 105 | pub nakedcc fn restore() void { | |
| 105 | pub fn restore() callconv(.Naked) void { | |
| 106 | 106 | return asm volatile ("int $0x80" |
| 107 | 107 | : |
| 108 | 108 | : [number] "{eax}" (@as(usize, SYS_sigreturn)) |
| ... | ... | @@ -110,7 +110,7 @@ pub nakedcc fn restore() void { |
| 110 | 110 | ); |
| 111 | 111 | } |
| 112 | 112 | |
| 113 | pub nakedcc fn restore_rt() void { | |
| 113 | pub fn restore_rt() callconv(.Naked) void { | |
| 114 | 114 | return asm volatile ("int $0x80" |
| 115 | 115 | : |
| 116 | 116 | : [number] "{eax}" (@as(usize, SYS_rt_sigreturn)) |
lib/std/os/linux/mipsel.zig+2-2| ... | ... | @@ -144,7 +144,7 @@ pub fn syscall6( |
| 144 | 144 | /// This matches the libc clone function. |
| 145 | 145 | pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; |
| 146 | 146 | |
| 147 | pub nakedcc fn restore() void { | |
| 147 | pub fn restore() callconv(.Naked) void { | |
| 148 | 148 | return asm volatile ("syscall" |
| 149 | 149 | : |
| 150 | 150 | : [number] "{$2}" (@as(usize, SYS_sigreturn)) |
| ... | ... | @@ -152,7 +152,7 @@ pub nakedcc fn restore() void { |
| 152 | 152 | ); |
| 153 | 153 | } |
| 154 | 154 | |
| 155 | pub nakedcc fn restore_rt() void { | |
| 155 | pub fn restore_rt() callconv(.Naked) void { | |
| 156 | 156 | return asm volatile ("syscall" |
| 157 | 157 | : |
| 158 | 158 | : [number] "{$2}" (@as(usize, SYS_rt_sigreturn)) |
lib/std/os/linux/riscv64.zig+1-1| ... | ... | @@ -89,7 +89,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, a |
| 89 | 89 | |
| 90 | 90 | pub const restore = restore_rt; |
| 91 | 91 | |
| 92 | pub nakedcc fn restore_rt() void { | |
| 92 | pub fn restore_rt() callconv(.Naked) void { | |
| 93 | 93 | return asm volatile ("ecall" |
| 94 | 94 | : |
| 95 | 95 | : [number] "{x17}" (@as(usize, SYS_rt_sigreturn)) |
lib/std/os/linux/x86_64.zig+1-1| ... | ... | @@ -90,7 +90,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: usize, |
| 90 | 90 | |
| 91 | 91 | pub const restore = restore_rt; |
| 92 | 92 | |
| 93 | pub nakedcc fn restore_rt() void { | |
| 93 | pub fn restore_rt() callconv(.Naked) void { | |
| 94 | 94 | return asm volatile ("syscall" |
| 95 | 95 | : |
| 96 | 96 | : [number] "{rax}" (@as(usize, SYS_rt_sigreturn)) |
lib/std/os/test.zig+1-1| ... | ... | @@ -166,7 +166,7 @@ test "sigaltstack" { |
| 166 | 166 | // analyzed |
| 167 | 167 | const dl_phdr_info = if (@hasDecl(os, "dl_phdr_info")) os.dl_phdr_info else c_void; |
| 168 | 168 | |
| 169 | export fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) i32 { | |
| 169 | extern fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) i32 { | |
| 170 | 170 | if (builtin.os == .windows or builtin.os == .wasi or builtin.os == .macosx) |
| 171 | 171 | return 0; |
| 172 | 172 |
lib/std/os/uefi/protocols/simple_text_input_protocol.zig-1| ... | ... | @@ -27,4 +27,3 @@ pub const SimpleTextInputProtocol = extern struct { |
| 27 | 27 | .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b }, |
| 28 | 28 | }; |
| 29 | 29 | }; |
| 30 |
lib/std/os/windows/advapi32.zig+5-5| ... | ... | @@ -1,23 +1,23 @@ |
| 1 | 1 | usingnamespace @import("bits.zig"); |
| 2 | 2 | |
| 3 | pub extern "advapi32" stdcallcc fn RegOpenKeyExW( | |
| 3 | pub extern "advapi32" fn RegOpenKeyExW( | |
| 4 | 4 | hKey: HKEY, |
| 5 | 5 | lpSubKey: LPCWSTR, |
| 6 | 6 | ulOptions: DWORD, |
| 7 | 7 | samDesired: REGSAM, |
| 8 | 8 | phkResult: *HKEY, |
| 9 | ) LSTATUS; | |
| 9 | ) callconv(.Stdcall) LSTATUS; | |
| 10 | 10 | |
| 11 | pub extern "advapi32" stdcallcc fn RegQueryValueExW( | |
| 11 | pub extern "advapi32" fn RegQueryValueExW( | |
| 12 | 12 | hKey: HKEY, |
| 13 | 13 | lpValueName: LPCWSTR, |
| 14 | 14 | lpReserved: LPDWORD, |
| 15 | 15 | lpType: LPDWORD, |
| 16 | 16 | lpData: LPBYTE, |
| 17 | 17 | lpcbData: LPDWORD, |
| 18 | ) LSTATUS; | |
| 18 | ) callconv(.Stdcall) LSTATUS; | |
| 19 | 19 | |
| 20 | 20 | // RtlGenRandom is known as SystemFunction036 under advapi32 |
| 21 | 21 | // http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx */ |
| 22 | pub extern "advapi32" stdcallcc fn SystemFunction036(output: [*]u8, length: ULONG) BOOL; | |
| 22 | pub extern "advapi32" fn SystemFunction036(output: [*]u8, length: ULONG) callconv(.Stdcall) BOOL; | |
| 23 | 23 | pub const RtlGenRandom = SystemFunction036; |
lib/std/os/windows/bits.zig+1-1| ... | ... | @@ -892,7 +892,7 @@ pub const EXCEPTION_POINTERS = extern struct { |
| 892 | 892 | ContextRecord: *c_void, |
| 893 | 893 | }; |
| 894 | 894 | |
| 895 | pub const VECTORED_EXCEPTION_HANDLER = stdcallcc fn (ExceptionInfo: *EXCEPTION_POINTERS) c_long; | |
| 895 | pub const VECTORED_EXCEPTION_HANDLER = fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(.Stdcall) c_long; | |
| 896 | 896 | |
| 897 | 897 | pub const OBJECT_ATTRIBUTES = extern struct { |
| 898 | 898 | Length: ULONG, |
lib/std/os/windows/kernel32.zig+100-100| ... | ... | @@ -1,22 +1,22 @@ |
| 1 | 1 | usingnamespace @import("bits.zig"); |
| 2 | 2 | |
| 3 | pub extern "kernel32" stdcallcc fn AddVectoredExceptionHandler(First: c_ulong, Handler: ?VECTORED_EXCEPTION_HANDLER) ?*c_void; | |
| 4 | pub extern "kernel32" stdcallcc fn RemoveVectoredExceptionHandler(Handle: HANDLE) c_ulong; | |
| 3 | pub extern "kernel32" fn AddVectoredExceptionHandler(First: c_ulong, Handler: ?VECTORED_EXCEPTION_HANDLER) callconv(.Stdcall) ?*c_void; | |
| 4 | pub extern "kernel32" fn RemoveVectoredExceptionHandler(Handle: HANDLE) callconv(.Stdcall) c_ulong; | |
| 5 | 5 | |
| 6 | pub extern "kernel32" stdcallcc fn CancelIoEx(hFile: HANDLE, lpOverlapped: LPOVERLAPPED) BOOL; | |
| 6 | pub extern "kernel32" fn CancelIoEx(hFile: HANDLE, lpOverlapped: LPOVERLAPPED) callconv(.Stdcall) BOOL; | |
| 7 | 7 | |
| 8 | pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) BOOL; | |
| 8 | pub extern "kernel32" fn CloseHandle(hObject: HANDLE) callconv(.Stdcall) BOOL; | |
| 9 | 9 | |
| 10 | pub extern "kernel32" stdcallcc fn CreateDirectoryW(lpPathName: [*]const u16, lpSecurityAttributes: ?*SECURITY_ATTRIBUTES) BOOL; | |
| 10 | pub extern "kernel32" fn CreateDirectoryW(lpPathName: [*]const u16, lpSecurityAttributes: ?*SECURITY_ATTRIBUTES) callconv(.Stdcall) BOOL; | |
| 11 | 11 | |
| 12 | pub extern "kernel32" stdcallcc fn CreateEventExW( | |
| 12 | pub extern "kernel32" fn CreateEventExW( | |
| 13 | 13 | lpEventAttributes: ?*SECURITY_ATTRIBUTES, |
| 14 | 14 | lpName: [*:0]const u16, |
| 15 | 15 | dwFlags: DWORD, |
| 16 | 16 | dwDesiredAccess: DWORD, |
| 17 | ) ?HANDLE; | |
| 17 | ) callconv(.Stdcall) ?HANDLE; | |
| 18 | 18 | |
| 19 | pub extern "kernel32" stdcallcc fn CreateFileW( | |
| 19 | pub extern "kernel32" fn CreateFileW( | |
| 20 | 20 | lpFileName: [*]const u16, // TODO null terminated pointer type |
| 21 | 21 | dwDesiredAccess: DWORD, |
| 22 | 22 | dwShareMode: DWORD, |
| ... | ... | @@ -24,16 +24,16 @@ pub extern "kernel32" stdcallcc fn CreateFileW( |
| 24 | 24 | dwCreationDisposition: DWORD, |
| 25 | 25 | dwFlagsAndAttributes: DWORD, |
| 26 | 26 | hTemplateFile: ?HANDLE, |
| 27 | ) HANDLE; | |
| 27 | ) callconv(.Stdcall) HANDLE; | |
| 28 | 28 | |
| 29 | pub extern "kernel32" stdcallcc fn CreatePipe( | |
| 29 | pub extern "kernel32" fn CreatePipe( | |
| 30 | 30 | hReadPipe: *HANDLE, |
| 31 | 31 | hWritePipe: *HANDLE, |
| 32 | 32 | lpPipeAttributes: *const SECURITY_ATTRIBUTES, |
| 33 | 33 | nSize: DWORD, |
| 34 | ) BOOL; | |
| 34 | ) callconv(.Stdcall) BOOL; | |
| 35 | 35 | |
| 36 | pub extern "kernel32" stdcallcc fn CreateProcessW( | |
| 36 | pub extern "kernel32" fn CreateProcessW( | |
| 37 | 37 | lpApplicationName: ?LPWSTR, |
| 38 | 38 | lpCommandLine: LPWSTR, |
| 39 | 39 | lpProcessAttributes: ?*SECURITY_ATTRIBUTES, |
| ... | ... | @@ -44,15 +44,15 @@ pub extern "kernel32" stdcallcc fn CreateProcessW( |
| 44 | 44 | lpCurrentDirectory: ?LPWSTR, |
| 45 | 45 | lpStartupInfo: *STARTUPINFOW, |
| 46 | 46 | lpProcessInformation: *PROCESS_INFORMATION, |
| 47 | ) BOOL; | |
| 47 | ) callconv(.Stdcall) BOOL; | |
| 48 | 48 | |
| 49 | pub extern "kernel32" stdcallcc fn CreateSymbolicLinkW(lpSymlinkFileName: [*]const u16, lpTargetFileName: [*]const u16, dwFlags: DWORD) BOOLEAN; | |
| 49 | pub extern "kernel32" fn CreateSymbolicLinkW(lpSymlinkFileName: [*]const u16, lpTargetFileName: [*]const u16, dwFlags: DWORD) callconv(.Stdcall) BOOLEAN; | |
| 50 | 50 | |
| 51 | pub extern "kernel32" stdcallcc fn CreateIoCompletionPort(FileHandle: HANDLE, ExistingCompletionPort: ?HANDLE, CompletionKey: ULONG_PTR, NumberOfConcurrentThreads: DWORD) ?HANDLE; | |
| 51 | pub extern "kernel32" fn CreateIoCompletionPort(FileHandle: HANDLE, ExistingCompletionPort: ?HANDLE, CompletionKey: ULONG_PTR, NumberOfConcurrentThreads: DWORD) callconv(.Stdcall) ?HANDLE; | |
| 52 | 52 | |
| 53 | pub extern "kernel32" stdcallcc fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) ?HANDLE; | |
| 53 | pub extern "kernel32" fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) callconv(.Stdcall) ?HANDLE; | |
| 54 | 54 | |
| 55 | pub extern "kernel32" stdcallcc fn DeviceIoControl( | |
| 55 | pub extern "kernel32" fn DeviceIoControl( | |
| 56 | 56 | h: HANDLE, |
| 57 | 57 | dwIoControlCode: DWORD, |
| 58 | 58 | lpInBuffer: ?*const c_void, |
| ... | ... | @@ -61,107 +61,107 @@ pub extern "kernel32" stdcallcc fn DeviceIoControl( |
| 61 | 61 | nOutBufferSize: DWORD, |
| 62 | 62 | lpBytesReturned: ?*DWORD, |
| 63 | 63 | lpOverlapped: ?*OVERLAPPED, |
| 64 | ) BOOL; | |
| 64 | ) callconv(.Stdcall) BOOL; | |
| 65 | 65 | |
| 66 | pub extern "kernel32" stdcallcc fn DeleteFileW(lpFileName: [*]const u16) BOOL; | |
| 66 | pub extern "kernel32" fn DeleteFileW(lpFileName: [*]const u16) callconv(.Stdcall) BOOL; | |
| 67 | 67 | |
| 68 | pub extern "kernel32" stdcallcc fn DuplicateHandle(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE, hTargetProcessHandle: HANDLE, lpTargetHandle: *HANDLE, dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwOptions: DWORD) BOOL; | |
| 68 | pub extern "kernel32" fn DuplicateHandle(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE, hTargetProcessHandle: HANDLE, lpTargetHandle: *HANDLE, dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwOptions: DWORD) callconv(.Stdcall) BOOL; | |
| 69 | 69 | |
| 70 | pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: UINT) noreturn; | |
| 70 | pub extern "kernel32" fn ExitProcess(exit_code: UINT) callconv(.Stdcall) noreturn; | |
| 71 | 71 | |
| 72 | pub extern "kernel32" stdcallcc fn FindFirstFileW(lpFileName: [*]const u16, lpFindFileData: *WIN32_FIND_DATAW) HANDLE; | |
| 73 | pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL; | |
| 74 | pub extern "kernel32" stdcallcc fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) BOOL; | |
| 72 | pub extern "kernel32" fn FindFirstFileW(lpFileName: [*]const u16, lpFindFileData: *WIN32_FIND_DATAW) callconv(.Stdcall) HANDLE; | |
| 73 | pub extern "kernel32" fn FindClose(hFindFile: HANDLE) callconv(.Stdcall) BOOL; | |
| 74 | pub extern "kernel32" fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) callconv(.Stdcall) BOOL; | |
| 75 | 75 | |
| 76 | pub extern "kernel32" stdcallcc fn FormatMessageW(dwFlags: DWORD, lpSource: ?LPVOID, dwMessageId: DWORD, dwLanguageId: DWORD, lpBuffer: LPWSTR, nSize: DWORD, Arguments: ?*va_list) DWORD; | |
| 76 | pub extern "kernel32" fn FormatMessageW(dwFlags: DWORD, lpSource: ?LPVOID, dwMessageId: DWORD, dwLanguageId: DWORD, lpBuffer: LPWSTR, nSize: DWORD, Arguments: ?*va_list) callconv(.Stdcall) DWORD; | |
| 77 | 77 | |
| 78 | pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsW(penv: [*]u16) BOOL; | |
| 78 | pub extern "kernel32" fn FreeEnvironmentStringsW(penv: [*]u16) callconv(.Stdcall) BOOL; | |
| 79 | 79 | |
| 80 | pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR; | |
| 80 | pub extern "kernel32" fn GetCommandLineA() callconv(.Stdcall) LPSTR; | |
| 81 | 81 | |
| 82 | pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: *DWORD) BOOL; | |
| 82 | pub extern "kernel32" fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: *DWORD) callconv(.Stdcall) BOOL; | |
| 83 | 83 | |
| 84 | pub extern "kernel32" stdcallcc fn GetConsoleScreenBufferInfo(hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: *CONSOLE_SCREEN_BUFFER_INFO) BOOL; | |
| 84 | pub extern "kernel32" fn GetConsoleScreenBufferInfo(hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: *CONSOLE_SCREEN_BUFFER_INFO) callconv(.Stdcall) BOOL; | |
| 85 | 85 | |
| 86 | pub extern "kernel32" stdcallcc fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: ?[*]WCHAR) DWORD; | |
| 86 | pub extern "kernel32" fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: ?[*]WCHAR) callconv(.Stdcall) DWORD; | |
| 87 | 87 | |
| 88 | pub extern "kernel32" stdcallcc fn GetCurrentThread() HANDLE; | |
| 89 | pub extern "kernel32" stdcallcc fn GetCurrentThreadId() DWORD; | |
| 88 | pub extern "kernel32" fn GetCurrentThread() callconv(.Stdcall) HANDLE; | |
| 89 | pub extern "kernel32" fn GetCurrentThreadId() callconv(.Stdcall) DWORD; | |
| 90 | 90 | |
| 91 | pub extern "kernel32" stdcallcc fn GetEnvironmentStringsW() ?[*]u16; | |
| 91 | pub extern "kernel32" fn GetEnvironmentStringsW() callconv(.Stdcall) ?[*]u16; | |
| 92 | 92 | |
| 93 | pub extern "kernel32" stdcallcc fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) DWORD; | |
| 93 | pub extern "kernel32" fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) callconv(.Stdcall) DWORD; | |
| 94 | 94 | |
| 95 | pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: *DWORD) BOOL; | |
| 95 | pub extern "kernel32" fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: *DWORD) callconv(.Stdcall) BOOL; | |
| 96 | 96 | |
| 97 | pub extern "kernel32" stdcallcc fn GetFileSizeEx(hFile: HANDLE, lpFileSize: *LARGE_INTEGER) BOOL; | |
| 97 | pub extern "kernel32" fn GetFileSizeEx(hFile: HANDLE, lpFileSize: *LARGE_INTEGER) callconv(.Stdcall) BOOL; | |
| 98 | 98 | |
| 99 | pub extern "kernel32" stdcallcc fn GetFileAttributesW(lpFileName: [*]const WCHAR) DWORD; | |
| 99 | pub extern "kernel32" fn GetFileAttributesW(lpFileName: [*]const WCHAR) callconv(.Stdcall) DWORD; | |
| 100 | 100 | |
| 101 | pub extern "kernel32" stdcallcc fn GetModuleFileNameW(hModule: ?HMODULE, lpFilename: [*]u16, nSize: DWORD) DWORD; | |
| 101 | pub extern "kernel32" fn GetModuleFileNameW(hModule: ?HMODULE, lpFilename: [*]u16, nSize: DWORD) callconv(.Stdcall) DWORD; | |
| 102 | 102 | |
| 103 | pub extern "kernel32" stdcallcc fn GetModuleHandleW(lpModuleName: ?[*]const WCHAR) HMODULE; | |
| 103 | pub extern "kernel32" fn GetModuleHandleW(lpModuleName: ?[*]const WCHAR) callconv(.Stdcall) HMODULE; | |
| 104 | 104 | |
| 105 | pub extern "kernel32" stdcallcc fn GetLastError() DWORD; | |
| 105 | pub extern "kernel32" fn GetLastError() callconv(.Stdcall) DWORD; | |
| 106 | 106 | |
| 107 | pub extern "kernel32" stdcallcc fn GetFileInformationByHandle( | |
| 107 | pub extern "kernel32" fn GetFileInformationByHandle( | |
| 108 | 108 | hFile: HANDLE, |
| 109 | 109 | lpFileInformation: *BY_HANDLE_FILE_INFORMATION, |
| 110 | ) BOOL; | |
| 110 | ) callconv(.Stdcall) BOOL; | |
| 111 | 111 | |
| 112 | pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx( | |
| 112 | pub extern "kernel32" fn GetFileInformationByHandleEx( | |
| 113 | 113 | in_hFile: HANDLE, |
| 114 | 114 | in_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, |
| 115 | 115 | out_lpFileInformation: *c_void, |
| 116 | 116 | in_dwBufferSize: DWORD, |
| 117 | ) BOOL; | |
| 117 | ) callconv(.Stdcall) BOOL; | |
| 118 | 118 | |
| 119 | pub extern "kernel32" stdcallcc fn GetFinalPathNameByHandleW( | |
| 119 | pub extern "kernel32" fn GetFinalPathNameByHandleW( | |
| 120 | 120 | hFile: HANDLE, |
| 121 | 121 | lpszFilePath: [*]u16, |
| 122 | 122 | cchFilePath: DWORD, |
| 123 | 123 | dwFlags: DWORD, |
| 124 | ) DWORD; | |
| 124 | ) callconv(.Stdcall) DWORD; | |
| 125 | 125 | |
| 126 | pub extern "kernel32" stdcallcc fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERLAPPED, lpNumberOfBytesTransferred: *DWORD, bWait: BOOL) BOOL; | |
| 126 | pub extern "kernel32" fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERLAPPED, lpNumberOfBytesTransferred: *DWORD, bWait: BOOL) callconv(.Stdcall) BOOL; | |
| 127 | 127 | |
| 128 | pub extern "kernel32" stdcallcc fn GetProcessHeap() ?HANDLE; | |
| 129 | pub extern "kernel32" stdcallcc fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) BOOL; | |
| 128 | pub extern "kernel32" fn GetProcessHeap() callconv(.Stdcall) ?HANDLE; | |
| 129 | pub extern "kernel32" fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) callconv(.Stdcall) BOOL; | |
| 130 | 130 | |
| 131 | pub extern "kernel32" stdcallcc fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) void; | |
| 132 | pub extern "kernel32" stdcallcc fn GetSystemTimeAsFileTime(*FILETIME) void; | |
| 131 | pub extern "kernel32" fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) callconv(.Stdcall) void; | |
| 132 | pub extern "kernel32" fn GetSystemTimeAsFileTime(*FILETIME) callconv(.Stdcall) void; | |
| 133 | 133 | |
| 134 | pub extern "kernel32" stdcallcc fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) ?HANDLE; | |
| 135 | pub extern "kernel32" stdcallcc fn HeapDestroy(hHeap: HANDLE) BOOL; | |
| 136 | pub extern "kernel32" stdcallcc fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void, dwBytes: SIZE_T) ?*c_void; | |
| 137 | pub extern "kernel32" stdcallcc fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) SIZE_T; | |
| 138 | pub extern "kernel32" stdcallcc fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) SIZE_T; | |
| 139 | pub extern "kernel32" stdcallcc fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) BOOL; | |
| 134 | pub extern "kernel32" fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) callconv(.Stdcall) ?HANDLE; | |
| 135 | pub extern "kernel32" fn HeapDestroy(hHeap: HANDLE) callconv(.Stdcall) BOOL; | |
| 136 | pub extern "kernel32" fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void, dwBytes: SIZE_T) callconv(.Stdcall) ?*c_void; | |
| 137 | pub extern "kernel32" fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) callconv(.Stdcall) SIZE_T; | |
| 138 | pub extern "kernel32" fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) callconv(.Stdcall) SIZE_T; | |
| 139 | pub extern "kernel32" fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) callconv(.Stdcall) BOOL; | |
| 140 | 140 | |
| 141 | pub extern "kernel32" stdcallcc fn GetStdHandle(in_nStdHandle: DWORD) ?HANDLE; | |
| 141 | pub extern "kernel32" fn GetStdHandle(in_nStdHandle: DWORD) callconv(.Stdcall) ?HANDLE; | |
| 142 | 142 | |
| 143 | pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) ?*c_void; | |
| 143 | pub extern "kernel32" fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) callconv(.Stdcall) ?*c_void; | |
| 144 | 144 | |
| 145 | pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void) BOOL; | |
| 145 | pub extern "kernel32" fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void) callconv(.Stdcall) BOOL; | |
| 146 | 146 | |
| 147 | pub extern "kernel32" stdcallcc fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: ?*const c_void) BOOL; | |
| 147 | pub extern "kernel32" fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: ?*const c_void) callconv(.Stdcall) BOOL; | |
| 148 | 148 | |
| 149 | pub extern "kernel32" stdcallcc fn VirtualAlloc(lpAddress: ?LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD) ?LPVOID; | |
| 150 | pub extern "kernel32" stdcallcc fn VirtualFree(lpAddress: ?LPVOID, dwSize: SIZE_T, dwFreeType: DWORD) BOOL; | |
| 149 | pub extern "kernel32" fn VirtualAlloc(lpAddress: ?LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD) callconv(.Stdcall) ?LPVOID; | |
| 150 | pub extern "kernel32" fn VirtualFree(lpAddress: ?LPVOID, dwSize: SIZE_T, dwFreeType: DWORD) callconv(.Stdcall) BOOL; | |
| 151 | 151 | |
| 152 | pub extern "kernel32" stdcallcc fn MoveFileExW( | |
| 152 | pub extern "kernel32" fn MoveFileExW( | |
| 153 | 153 | lpExistingFileName: [*]const u16, |
| 154 | 154 | lpNewFileName: [*]const u16, |
| 155 | 155 | dwFlags: DWORD, |
| 156 | ) BOOL; | |
| 156 | ) callconv(.Stdcall) BOOL; | |
| 157 | 157 | |
| 158 | pub extern "kernel32" stdcallcc fn PostQueuedCompletionStatus(CompletionPort: HANDLE, dwNumberOfBytesTransferred: DWORD, dwCompletionKey: ULONG_PTR, lpOverlapped: ?*OVERLAPPED) BOOL; | |
| 158 | pub extern "kernel32" fn PostQueuedCompletionStatus(CompletionPort: HANDLE, dwNumberOfBytesTransferred: DWORD, dwCompletionKey: ULONG_PTR, lpOverlapped: ?*OVERLAPPED) callconv(.Stdcall) BOOL; | |
| 159 | 159 | |
| 160 | pub extern "kernel32" stdcallcc fn QueryPerformanceCounter(lpPerformanceCount: *LARGE_INTEGER) BOOL; | |
| 160 | pub extern "kernel32" fn QueryPerformanceCounter(lpPerformanceCount: *LARGE_INTEGER) callconv(.Stdcall) BOOL; | |
| 161 | 161 | |
| 162 | pub extern "kernel32" stdcallcc fn QueryPerformanceFrequency(lpFrequency: *LARGE_INTEGER) BOOL; | |
| 162 | pub extern "kernel32" fn QueryPerformanceFrequency(lpFrequency: *LARGE_INTEGER) callconv(.Stdcall) BOOL; | |
| 163 | 163 | |
| 164 | pub extern "kernel32" stdcallcc fn ReadDirectoryChangesW( | |
| 164 | pub extern "kernel32" fn ReadDirectoryChangesW( | |
| 165 | 165 | hDirectory: HANDLE, |
| 166 | 166 | lpBuffer: [*]align(@alignOf(FILE_NOTIFY_INFORMATION)) u8, |
| 167 | 167 | nBufferLength: DWORD, |
| ... | ... | @@ -170,79 +170,79 @@ pub extern "kernel32" stdcallcc fn ReadDirectoryChangesW( |
| 170 | 170 | lpBytesReturned: ?*DWORD, |
| 171 | 171 | lpOverlapped: ?*OVERLAPPED, |
| 172 | 172 | lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE, |
| 173 | ) BOOL; | |
| 173 | ) callconv(.Stdcall) BOOL; | |
| 174 | 174 | |
| 175 | pub extern "kernel32" stdcallcc fn ReadFile( | |
| 175 | pub extern "kernel32" fn ReadFile( | |
| 176 | 176 | in_hFile: HANDLE, |
| 177 | 177 | out_lpBuffer: [*]u8, |
| 178 | 178 | in_nNumberOfBytesToRead: DWORD, |
| 179 | 179 | out_lpNumberOfBytesRead: ?*DWORD, |
| 180 | 180 | in_out_lpOverlapped: ?*OVERLAPPED, |
| 181 | ) BOOL; | |
| 181 | ) callconv(.Stdcall) BOOL; | |
| 182 | 182 | |
| 183 | pub extern "kernel32" stdcallcc fn RemoveDirectoryW(lpPathName: [*]const u16) BOOL; | |
| 183 | pub extern "kernel32" fn RemoveDirectoryW(lpPathName: [*]const u16) callconv(.Stdcall) BOOL; | |
| 184 | 184 | |
| 185 | pub extern "kernel32" stdcallcc fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) BOOL; | |
| 185 | pub extern "kernel32" fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) callconv(.Stdcall) BOOL; | |
| 186 | 186 | |
| 187 | pub extern "kernel32" stdcallcc fn SetFilePointerEx( | |
| 187 | pub extern "kernel32" fn SetFilePointerEx( | |
| 188 | 188 | in_fFile: HANDLE, |
| 189 | 189 | in_liDistanceToMove: LARGE_INTEGER, |
| 190 | 190 | out_opt_ldNewFilePointer: ?*LARGE_INTEGER, |
| 191 | 191 | in_dwMoveMethod: DWORD, |
| 192 | ) BOOL; | |
| 192 | ) callconv(.Stdcall) BOOL; | |
| 193 | 193 | |
| 194 | pub extern "kernel32" stdcallcc fn SetFileTime( | |
| 194 | pub extern "kernel32" fn SetFileTime( | |
| 195 | 195 | hFile: HANDLE, |
| 196 | 196 | lpCreationTime: ?*const FILETIME, |
| 197 | 197 | lpLastAccessTime: ?*const FILETIME, |
| 198 | 198 | lpLastWriteTime: ?*const FILETIME, |
| 199 | ) BOOL; | |
| 199 | ) callconv(.Stdcall) BOOL; | |
| 200 | 200 | |
| 201 | pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) BOOL; | |
| 201 | pub extern "kernel32" fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) callconv(.Stdcall) BOOL; | |
| 202 | 202 | |
| 203 | pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD) void; | |
| 203 | pub extern "kernel32" fn Sleep(dwMilliseconds: DWORD) callconv(.Stdcall) void; | |
| 204 | 204 | |
| 205 | pub extern "kernel32" stdcallcc fn SwitchToThread() BOOL; | |
| 205 | pub extern "kernel32" fn SwitchToThread() callconv(.Stdcall) BOOL; | |
| 206 | 206 | |
| 207 | pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) BOOL; | |
| 207 | pub extern "kernel32" fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) callconv(.Stdcall) BOOL; | |
| 208 | 208 | |
| 209 | pub extern "kernel32" stdcallcc fn TlsAlloc() DWORD; | |
| 209 | pub extern "kernel32" fn TlsAlloc() callconv(.Stdcall) DWORD; | |
| 210 | 210 | |
| 211 | pub extern "kernel32" stdcallcc fn TlsFree(dwTlsIndex: DWORD) BOOL; | |
| 211 | pub extern "kernel32" fn TlsFree(dwTlsIndex: DWORD) callconv(.Stdcall) BOOL; | |
| 212 | 212 | |
| 213 | pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) DWORD; | |
| 213 | pub extern "kernel32" fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) callconv(.Stdcall) DWORD; | |
| 214 | 214 | |
| 215 | pub extern "kernel32" stdcallcc fn WaitForSingleObjectEx(hHandle: HANDLE, dwMilliseconds: DWORD, bAlertable: BOOL) DWORD; | |
| 215 | pub extern "kernel32" fn WaitForSingleObjectEx(hHandle: HANDLE, dwMilliseconds: DWORD, bAlertable: BOOL) callconv(.Stdcall) DWORD; | |
| 216 | 216 | |
| 217 | pub extern "kernel32" stdcallcc fn WaitForMultipleObjects(nCount: DWORD, lpHandle: [*]const HANDLE, bWaitAll: BOOL, dwMilliseconds: DWORD) DWORD; | |
| 217 | pub extern "kernel32" fn WaitForMultipleObjects(nCount: DWORD, lpHandle: [*]const HANDLE, bWaitAll: BOOL, dwMilliseconds: DWORD) callconv(.Stdcall) DWORD; | |
| 218 | 218 | |
| 219 | pub extern "kernel32" stdcallcc fn WaitForMultipleObjectsEx( | |
| 219 | pub extern "kernel32" fn WaitForMultipleObjectsEx( | |
| 220 | 220 | nCount: DWORD, |
| 221 | 221 | lpHandle: [*]const HANDLE, |
| 222 | 222 | bWaitAll: BOOL, |
| 223 | 223 | dwMilliseconds: DWORD, |
| 224 | 224 | bAlertable: BOOL, |
| 225 | ) DWORD; | |
| 225 | ) callconv(.Stdcall) DWORD; | |
| 226 | 226 | |
| 227 | pub extern "kernel32" stdcallcc fn WriteFile( | |
| 227 | pub extern "kernel32" fn WriteFile( | |
| 228 | 228 | in_hFile: HANDLE, |
| 229 | 229 | in_lpBuffer: [*]const u8, |
| 230 | 230 | in_nNumberOfBytesToWrite: DWORD, |
| 231 | 231 | out_lpNumberOfBytesWritten: ?*DWORD, |
| 232 | 232 | in_out_lpOverlapped: ?*OVERLAPPED, |
| 233 | ) BOOL; | |
| 233 | ) callconv(.Stdcall) BOOL; | |
| 234 | 234 | |
| 235 | pub extern "kernel32" stdcallcc fn WriteFileEx(hFile: HANDLE, lpBuffer: [*]const u8, nNumberOfBytesToWrite: DWORD, lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE) BOOL; | |
| 235 | pub extern "kernel32" fn WriteFileEx(hFile: HANDLE, lpBuffer: [*]const u8, nNumberOfBytesToWrite: DWORD, lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE) callconv(.Stdcall) BOOL; | |
| 236 | 236 | |
| 237 | pub extern "kernel32" stdcallcc fn LoadLibraryW(lpLibFileName: [*]const u16) ?HMODULE; | |
| 237 | pub extern "kernel32" fn LoadLibraryW(lpLibFileName: [*]const u16) callconv(.Stdcall) ?HMODULE; | |
| 238 | 238 | |
| 239 | pub extern "kernel32" stdcallcc fn GetProcAddress(hModule: HMODULE, lpProcName: [*]const u8) ?FARPROC; | |
| 239 | pub extern "kernel32" fn GetProcAddress(hModule: HMODULE, lpProcName: [*]const u8) callconv(.Stdcall) ?FARPROC; | |
| 240 | 240 | |
| 241 | pub extern "kernel32" stdcallcc fn FreeLibrary(hModule: HMODULE) BOOL; | |
| 241 | pub extern "kernel32" fn FreeLibrary(hModule: HMODULE) callconv(.Stdcall) BOOL; | |
| 242 | 242 | |
| 243 | pub extern "kernel32" stdcallcc fn InitializeCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void; | |
| 244 | pub extern "kernel32" stdcallcc fn EnterCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void; | |
| 245 | pub extern "kernel32" stdcallcc fn LeaveCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void; | |
| 246 | pub extern "kernel32" stdcallcc fn DeleteCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void; | |
| 243 | pub extern "kernel32" fn InitializeCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void; | |
| 244 | pub extern "kernel32" fn EnterCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void; | |
| 245 | pub extern "kernel32" fn LeaveCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void; | |
| 246 | pub extern "kernel32" fn DeleteCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void; | |
| 247 | 247 | |
| 248 | pub extern "kernel32" stdcallcc fn InitOnceExecuteOnce(InitOnce: *INIT_ONCE, InitFn: INIT_ONCE_FN, Parameter: ?*c_void, Context: ?*c_void) BOOL; | |
| 248 | pub extern "kernel32" fn InitOnceExecuteOnce(InitOnce: *INIT_ONCE, InitFn: INIT_ONCE_FN, Parameter: ?*c_void, Context: ?*c_void) callconv(.Stdcall) BOOL; |
lib/std/os/windows/ntdll.zig+19-19| ... | ... | @@ -1,14 +1,14 @@ |
| 1 | 1 | usingnamespace @import("bits.zig"); |
| 2 | 2 | |
| 3 | pub extern "NtDll" stdcallcc fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) WORD; | |
| 4 | pub extern "NtDll" stdcallcc fn NtQueryInformationFile( | |
| 3 | pub extern "NtDll" fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) callconv(.Stdcall) WORD; | |
| 4 | pub extern "NtDll" fn NtQueryInformationFile( | |
| 5 | 5 | FileHandle: HANDLE, |
| 6 | 6 | IoStatusBlock: *IO_STATUS_BLOCK, |
| 7 | 7 | FileInformation: *c_void, |
| 8 | 8 | Length: ULONG, |
| 9 | 9 | FileInformationClass: FILE_INFORMATION_CLASS, |
| 10 | ) NTSTATUS; | |
| 11 | pub extern "NtDll" stdcallcc fn NtCreateFile( | |
| 10 | ) callconv(.Stdcall) NTSTATUS; | |
| 11 | pub extern "NtDll" fn NtCreateFile( | |
| 12 | 12 | FileHandle: *HANDLE, |
| 13 | 13 | DesiredAccess: ACCESS_MASK, |
| 14 | 14 | ObjectAttributes: *OBJECT_ATTRIBUTES, |
| ... | ... | @@ -20,8 +20,8 @@ pub extern "NtDll" stdcallcc fn NtCreateFile( |
| 20 | 20 | CreateOptions: ULONG, |
| 21 | 21 | EaBuffer: ?*c_void, |
| 22 | 22 | EaLength: ULONG, |
| 23 | ) NTSTATUS; | |
| 24 | pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile( | |
| 23 | ) callconv(.Stdcall) NTSTATUS; | |
| 24 | pub extern "NtDll" fn NtDeviceIoControlFile( | |
| 25 | 25 | FileHandle: HANDLE, |
| 26 | 26 | Event: ?HANDLE, |
| 27 | 27 | ApcRoutine: ?IO_APC_ROUTINE, |
| ... | ... | @@ -32,17 +32,17 @@ pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile( |
| 32 | 32 | InputBufferLength: ULONG, |
| 33 | 33 | OutputBuffer: ?PVOID, |
| 34 | 34 | OutputBufferLength: ULONG, |
| 35 | ) NTSTATUS; | |
| 36 | pub extern "NtDll" stdcallcc fn NtClose(Handle: HANDLE) NTSTATUS; | |
| 37 | pub extern "NtDll" stdcallcc fn RtlDosPathNameToNtPathName_U( | |
| 35 | ) callconv(.Stdcall) NTSTATUS; | |
| 36 | pub extern "NtDll" fn NtClose(Handle: HANDLE) callconv(.Stdcall) NTSTATUS; | |
| 37 | pub extern "NtDll" fn RtlDosPathNameToNtPathName_U( | |
| 38 | 38 | DosPathName: [*]const u16, |
| 39 | 39 | NtPathName: *UNICODE_STRING, |
| 40 | 40 | NtFileNamePart: ?*?[*]const u16, |
| 41 | 41 | DirectoryInfo: ?*CURDIR, |
| 42 | ) BOOL; | |
| 43 | pub extern "NtDll" stdcallcc fn RtlFreeUnicodeString(UnicodeString: *UNICODE_STRING) void; | |
| 42 | ) callconv(.Stdcall) BOOL; | |
| 43 | pub extern "NtDll" fn RtlFreeUnicodeString(UnicodeString: *UNICODE_STRING) callconv(.Stdcall) void; | |
| 44 | 44 | |
| 45 | pub extern "NtDll" stdcallcc fn NtQueryDirectoryFile( | |
| 45 | pub extern "NtDll" fn NtQueryDirectoryFile( | |
| 46 | 46 | FileHandle: HANDLE, |
| 47 | 47 | Event: ?HANDLE, |
| 48 | 48 | ApcRoutine: ?IO_APC_ROUTINE, |
| ... | ... | @@ -54,22 +54,22 @@ pub extern "NtDll" stdcallcc fn NtQueryDirectoryFile( |
| 54 | 54 | ReturnSingleEntry: BOOLEAN, |
| 55 | 55 | FileName: ?*UNICODE_STRING, |
| 56 | 56 | RestartScan: BOOLEAN, |
| 57 | ) NTSTATUS; | |
| 58 | pub extern "NtDll" stdcallcc fn NtCreateKeyedEvent( | |
| 57 | ) callconv(.Stdcall) NTSTATUS; | |
| 58 | pub extern "NtDll" fn NtCreateKeyedEvent( | |
| 59 | 59 | KeyedEventHandle: *HANDLE, |
| 60 | 60 | DesiredAccess: ACCESS_MASK, |
| 61 | 61 | ObjectAttributes: ?PVOID, |
| 62 | 62 | Flags: ULONG, |
| 63 | ) NTSTATUS; | |
| 64 | pub extern "NtDll" stdcallcc fn NtReleaseKeyedEvent( | |
| 63 | ) callconv(.Stdcall) NTSTATUS; | |
| 64 | pub extern "NtDll" fn NtReleaseKeyedEvent( | |
| 65 | 65 | EventHandle: HANDLE, |
| 66 | 66 | Key: *const c_void, |
| 67 | 67 | Alertable: BOOLEAN, |
| 68 | 68 | Timeout: ?*LARGE_INTEGER, |
| 69 | ) NTSTATUS; | |
| 70 | pub extern "NtDll" stdcallcc fn NtWaitForKeyedEvent( | |
| 69 | ) callconv(.Stdcall) NTSTATUS; | |
| 70 | pub extern "NtDll" fn NtWaitForKeyedEvent( | |
| 71 | 71 | EventHandle: HANDLE, |
| 72 | 72 | Key: *const c_void, |
| 73 | 73 | Alertable: BOOLEAN, |
| 74 | 74 | Timeout: ?*LARGE_INTEGER, |
| 75 | ) NTSTATUS; | |
| 75 | ) callconv(.Stdcall) NTSTATUS; |
lib/std/os/windows/ole32.zig+4-4| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | usingnamespace @import("bits.zig"); |
| 2 | 2 | |
| 3 | pub extern "ole32" stdcallcc fn CoTaskMemFree(pv: LPVOID) void; | |
| 4 | pub extern "ole32" stdcallcc fn CoUninitialize() void; | |
| 5 | pub extern "ole32" stdcallcc fn CoGetCurrentProcess() DWORD; | |
| 6 | pub extern "ole32" stdcallcc fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) HRESULT; | |
| 3 | pub extern "ole32" fn CoTaskMemFree(pv: LPVOID) callconv(.Stdcall) void; | |
| 4 | pub extern "ole32" fn CoUninitialize() callconv(.Stdcall) void; | |
| 5 | pub extern "ole32" fn CoGetCurrentProcess() callconv(.Stdcall) DWORD; | |
| 6 | pub extern "ole32" fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) callconv(.Stdcall) HRESULT; |
lib/std/os/windows/shell32.zig+1-1| ... | ... | @@ -1,3 +1,3 @@ |
| 1 | 1 | usingnamespace @import("bits.zig"); |
| 2 | 2 | |
| 3 | pub extern "shell32" stdcallcc fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*]WCHAR) HRESULT; | |
| 3 | pub extern "shell32" fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*]WCHAR) callconv(.Stdcall) HRESULT; |
lib/std/os/windows/ws2_32.zig+23-23| ... | ... | @@ -315,30 +315,30 @@ const IOC_WS2 = 0x08000000; |
| 315 | 315 | |
| 316 | 316 | pub const SIO_BASE_HANDLE = IOC_OUT | IOC_WS2 | 34; |
| 317 | 317 | |
| 318 | pub extern "ws2_32" stdcallcc fn WSAStartup( | |
| 318 | pub extern "ws2_32" fn WSAStartup( | |
| 319 | 319 | wVersionRequired: WORD, |
| 320 | 320 | lpWSAData: *WSADATA, |
| 321 | ) c_int; | |
| 322 | pub extern "ws2_32" stdcallcc fn WSACleanup() c_int; | |
| 323 | pub extern "ws2_32" stdcallcc fn WSAGetLastError() c_int; | |
| 324 | pub extern "ws2_32" stdcallcc fn WSASocketA( | |
| 321 | ) callconv(.Stdcall) c_int; | |
| 322 | pub extern "ws2_32" fn WSACleanup() callconv(.Stdcall) c_int; | |
| 323 | pub extern "ws2_32" fn WSAGetLastError() callconv(.Stdcall) c_int; | |
| 324 | pub extern "ws2_32" fn WSASocketA( | |
| 325 | 325 | af: c_int, |
| 326 | 326 | type: c_int, |
| 327 | 327 | protocol: c_int, |
| 328 | 328 | lpProtocolInfo: ?*WSAPROTOCOL_INFOA, |
| 329 | 329 | g: GROUP, |
| 330 | 330 | dwFlags: DWORD, |
| 331 | ) SOCKET; | |
| 332 | pub extern "ws2_32" stdcallcc fn WSASocketW( | |
| 331 | ) callconv(.Stdcall) SOCKET; | |
| 332 | pub extern "ws2_32" fn WSASocketW( | |
| 333 | 333 | af: c_int, |
| 334 | 334 | type: c_int, |
| 335 | 335 | protocol: c_int, |
| 336 | 336 | lpProtocolInfo: ?*WSAPROTOCOL_INFOW, |
| 337 | 337 | g: GROUP, |
| 338 | 338 | dwFlags: DWORD, |
| 339 | ) SOCKET; | |
| 340 | pub extern "ws2_32" stdcallcc fn closesocket(s: SOCKET) c_int; | |
| 341 | pub extern "ws2_32" stdcallcc fn WSAIoctl( | |
| 339 | ) callconv(.Stdcall) SOCKET; | |
| 340 | pub extern "ws2_32" fn closesocket(s: SOCKET) callconv(.Stdcall) c_int; | |
| 341 | pub extern "ws2_32" fn WSAIoctl( | |
| 342 | 342 | s: SOCKET, |
| 343 | 343 | dwIoControlCode: DWORD, |
| 344 | 344 | lpvInBuffer: ?*const c_void, |
| ... | ... | @@ -348,18 +348,18 @@ pub extern "ws2_32" stdcallcc fn WSAIoctl( |
| 348 | 348 | lpcbBytesReturned: LPDWORD, |
| 349 | 349 | lpOverlapped: ?*WSAOVERLAPPED, |
| 350 | 350 | lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, |
| 351 | ) c_int; | |
| 352 | pub extern "ws2_32" stdcallcc fn accept( | |
| 351 | ) callconv(.Stdcall) c_int; | |
| 352 | pub extern "ws2_32" fn accept( | |
| 353 | 353 | s: SOCKET, |
| 354 | 354 | addr: ?*sockaddr, |
| 355 | 355 | addrlen: socklen_t, |
| 356 | ) SOCKET; | |
| 357 | pub extern "ws2_32" stdcallcc fn connect( | |
| 356 | ) callconv(.Stdcall) SOCKET; | |
| 357 | pub extern "ws2_32" fn connect( | |
| 358 | 358 | s: SOCKET, |
| 359 | 359 | name: *const sockaddr, |
| 360 | 360 | namelen: socklen_t, |
| 361 | ) c_int; | |
| 362 | pub extern "ws2_32" stdcallcc fn WSARecv( | |
| 361 | ) callconv(.Stdcall) c_int; | |
| 362 | pub extern "ws2_32" fn WSARecv( | |
| 363 | 363 | s: SOCKET, |
| 364 | 364 | lpBuffers: [*]const WSABUF, |
| 365 | 365 | dwBufferCount: DWORD, |
| ... | ... | @@ -367,8 +367,8 @@ pub extern "ws2_32" stdcallcc fn WSARecv( |
| 367 | 367 | lpFlags: *DWORD, |
| 368 | 368 | lpOverlapped: ?*WSAOVERLAPPED, |
| 369 | 369 | lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, |
| 370 | ) c_int; | |
| 371 | pub extern "ws2_32" stdcallcc fn WSARecvFrom( | |
| 370 | ) callconv(.Stdcall) c_int; | |
| 371 | pub extern "ws2_32" fn WSARecvFrom( | |
| 372 | 372 | s: SOCKET, |
| 373 | 373 | lpBuffers: [*]const WSABUF, |
| 374 | 374 | dwBufferCount: DWORD, |
| ... | ... | @@ -378,8 +378,8 @@ pub extern "ws2_32" stdcallcc fn WSARecvFrom( |
| 378 | 378 | lpFromlen: socklen_t, |
| 379 | 379 | lpOverlapped: ?*WSAOVERLAPPED, |
| 380 | 380 | lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, |
| 381 | ) c_int; | |
| 382 | pub extern "ws2_32" stdcallcc fn WSASend( | |
| 381 | ) callconv(.Stdcall) c_int; | |
| 382 | pub extern "ws2_32" fn WSASend( | |
| 383 | 383 | s: SOCKET, |
| 384 | 384 | lpBuffers: [*]WSABUF, |
| 385 | 385 | dwBufferCount: DWORD, |
| ... | ... | @@ -387,8 +387,8 @@ pub extern "ws2_32" stdcallcc fn WSASend( |
| 387 | 387 | dwFlags: DWORD, |
| 388 | 388 | lpOverlapped: ?*WSAOVERLAPPED, |
| 389 | 389 | lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, |
| 390 | ) c_int; | |
| 391 | pub extern "ws2_32" stdcallcc fn WSASendTo( | |
| 390 | ) callconv(.Stdcall) c_int; | |
| 391 | pub extern "ws2_32" fn WSASendTo( | |
| 392 | 392 | s: SOCKET, |
| 393 | 393 | lpBuffers: [*]WSABUF, |
| 394 | 394 | dwBufferCount: DWORD, |
| ... | ... | @@ -398,4 +398,4 @@ pub extern "ws2_32" stdcallcc fn WSASendTo( |
| 398 | 398 | iTolen: socklen_t, |
| 399 | 399 | lpOverlapped: ?*WSAOVERLAPPED, |
| 400 | 400 | lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, |
| 401 | ) c_int; | |
| 401 | ) callconv(.Stdcall) c_int; |
lib/std/reset_event.zig+12-14| ... | ... | @@ -14,13 +14,12 @@ const windows = os.windows; |
| 14 | 14 | pub const ResetEvent = struct { |
| 15 | 15 | os_event: OsEvent, |
| 16 | 16 | |
| 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; | |
| 24 | 23 | |
| 25 | 24 | pub fn init() ResetEvent { |
| 26 | 25 | return ResetEvent{ .os_event = OsEvent.init() }; |
| ... | ... | @@ -105,7 +104,7 @@ const PosixEvent = struct { |
| 105 | 104 | } |
| 106 | 105 | |
| 107 | 106 | fn deinit(self: *PosixEvent) void { |
| 108 | // on dragonfly, *destroy() functions can return EINVAL | |
| 107 | // on dragonfly, *destroy() functions can return EINVAL | |
| 109 | 108 | // for statically initialized pthread structures |
| 110 | 109 | const err = if (builtin.os == .dragonfly) os.EINVAL else 0; |
| 111 | 110 | |
| ... | ... | @@ -212,8 +211,7 @@ const AtomicEvent = struct { |
| 212 | 211 | fn wait(self: *AtomicEvent, timeout: ?u64) !void { |
| 213 | 212 | var waiters = @atomicLoad(u32, &self.waiters, .Acquire); |
| 214 | 213 | 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); | |
| 217 | 215 | } |
| 218 | 216 | } |
| 219 | 217 | |
| ... | ... | @@ -281,7 +279,7 @@ const AtomicEvent = struct { |
| 281 | 279 | pub fn wake(waiters: *u32, wake_count: u32) void { |
| 282 | 280 | const handle = getEventHandle() orelse return SpinFutex.wake(waiters, wake_count); |
| 283 | 281 | const key = @ptrCast(*const c_void, waiters); |
| 284 | ||
| 282 | ||
| 285 | 283 | var waiting = wake_count; |
| 286 | 284 | while (waiting != 0) : (waiting -= 1) { |
| 287 | 285 | const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null); |
| ... | ... | @@ -408,7 +406,7 @@ test "std.ResetEvent" { |
| 408 | 406 | // wait for receiver to update value and signal output |
| 409 | 407 | self.out.wait(); |
| 410 | 408 | testing.expect(self.value == 2); |
| 411 | ||
| 409 | ||
| 412 | 410 | // update value and signal final input |
| 413 | 411 | self.value = 3; |
| 414 | 412 | self.in.set(); |
| ... | ... | @@ -418,12 +416,12 @@ test "std.ResetEvent" { |
| 418 | 416 | // wait for sender to update value and signal input |
| 419 | 417 | self.in.wait(); |
| 420 | 418 | assert(self.value == 1); |
| 421 | ||
| 419 | ||
| 422 | 420 | // update value and signal output |
| 423 | 421 | self.in.reset(); |
| 424 | 422 | self.value = 2; |
| 425 | 423 | self.out.set(); |
| 426 | ||
| 424 | ||
| 427 | 425 | // wait for sender to update value and signal final input |
| 428 | 426 | self.in.wait(); |
| 429 | 427 | assert(self.value == 3); |
lib/std/special/c.zig+1-1| ... | ... | @@ -195,7 +195,7 @@ extern fn __stack_chk_fail() noreturn { |
| 195 | 195 | // TODO we should be able to put this directly in std/linux/x86_64.zig but |
| 196 | 196 | // it causes a segfault in release mode. this is a workaround of calling it |
| 197 | 197 | // across .o file boundaries. fix comptime @ptrCast of nakedcc functions. |
| 198 | nakedcc fn clone() void { | |
| 198 | fn clone() callconv(.Naked) void { | |
| 199 | 199 | switch (builtin.arch) { |
| 200 | 200 | .i386 => { |
| 201 | 201 | // __clone(func, stack, flags, arg, ptid, tls, ctid) |
lib/std/special/compiler_rt.zig+5-5| ... | ... | @@ -528,7 +528,7 @@ fn usesThumb1PreArmv6(arch: builtin.Arch) bool { |
| 528 | 528 | }; |
| 529 | 529 | } |
| 530 | 530 | |
| 531 | nakedcc fn __aeabi_memcpy() noreturn { | |
| 531 | fn __aeabi_memcpy() callconv(.Naked) noreturn { | |
| 532 | 532 | @setRuntimeSafety(false); |
| 533 | 533 | if (use_thumb_1) { |
| 534 | 534 | asm volatile ( |
| ... | ... | @@ -544,7 +544,7 @@ nakedcc fn __aeabi_memcpy() noreturn { |
| 544 | 544 | unreachable; |
| 545 | 545 | } |
| 546 | 546 | |
| 547 | nakedcc fn __aeabi_memmove() noreturn { | |
| 547 | fn __aeabi_memmove() callconv(.Naked) noreturn { | |
| 548 | 548 | @setRuntimeSafety(false); |
| 549 | 549 | if (use_thumb_1) { |
| 550 | 550 | asm volatile ( |
| ... | ... | @@ -560,7 +560,7 @@ nakedcc fn __aeabi_memmove() noreturn { |
| 560 | 560 | unreachable; |
| 561 | 561 | } |
| 562 | 562 | |
| 563 | nakedcc fn __aeabi_memset() noreturn { | |
| 563 | fn __aeabi_memset() callconv(.Naked) noreturn { | |
| 564 | 564 | @setRuntimeSafety(false); |
| 565 | 565 | if (use_thumb_1_pre_armv6) { |
| 566 | 566 | asm volatile ( |
| ... | ... | @@ -591,7 +591,7 @@ nakedcc fn __aeabi_memset() noreturn { |
| 591 | 591 | unreachable; |
| 592 | 592 | } |
| 593 | 593 | |
| 594 | nakedcc fn __aeabi_memclr() noreturn { | |
| 594 | fn __aeabi_memclr() callconv(.Naked) noreturn { | |
| 595 | 595 | @setRuntimeSafety(false); |
| 596 | 596 | if (use_thumb_1_pre_armv6) { |
| 597 | 597 | asm volatile ( |
| ... | ... | @@ -619,7 +619,7 @@ nakedcc fn __aeabi_memclr() noreturn { |
| 619 | 619 | unreachable; |
| 620 | 620 | } |
| 621 | 621 | |
| 622 | nakedcc fn __aeabi_memcmp() noreturn { | |
| 622 | fn __aeabi_memcmp() callconv(.Naked) noreturn { | |
| 623 | 623 | @setRuntimeSafety(false); |
| 624 | 624 | if (use_thumb_1) { |
| 625 | 625 | asm volatile ( |
lib/std/special/compiler_rt/arm/aeabi_dcmp.zig+5-5| ... | ... | @@ -12,31 +12,31 @@ const ConditionalOperator = enum { |
| 12 | 12 | Gt, |
| 13 | 13 | }; |
| 14 | 14 | |
| 15 | pub nakedcc fn __aeabi_dcmpeq() noreturn { | |
| 15 | pub fn __aeabi_dcmpeq() callconv(.Naked) noreturn { | |
| 16 | 16 | @setRuntimeSafety(false); |
| 17 | 17 | @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Eq}); |
| 18 | 18 | unreachable; |
| 19 | 19 | } |
| 20 | 20 | |
| 21 | pub nakedcc fn __aeabi_dcmplt() noreturn { | |
| 21 | pub fn __aeabi_dcmplt() callconv(.Naked) noreturn { | |
| 22 | 22 | @setRuntimeSafety(false); |
| 23 | 23 | @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Lt}); |
| 24 | 24 | unreachable; |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | pub nakedcc fn __aeabi_dcmple() noreturn { | |
| 27 | pub fn __aeabi_dcmple() callconv(.Naked) noreturn { | |
| 28 | 28 | @setRuntimeSafety(false); |
| 29 | 29 | @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Le}); |
| 30 | 30 | unreachable; |
| 31 | 31 | } |
| 32 | 32 | |
| 33 | pub nakedcc fn __aeabi_dcmpge() noreturn { | |
| 33 | pub fn __aeabi_dcmpge() callconv(.Naked) noreturn { | |
| 34 | 34 | @setRuntimeSafety(false); |
| 35 | 35 | @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Ge}); |
| 36 | 36 | unreachable; |
| 37 | 37 | } |
| 38 | 38 | |
| 39 | pub nakedcc fn __aeabi_dcmpgt() noreturn { | |
| 39 | pub fn __aeabi_dcmpgt() callconv(.Naked) noreturn { | |
| 40 | 40 | @setRuntimeSafety(false); |
| 41 | 41 | @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Gt}); |
| 42 | 42 | unreachable; |
lib/std/special/compiler_rt/arm/aeabi_fcmp.zig+5-5| ... | ... | @@ -12,31 +12,31 @@ const ConditionalOperator = enum { |
| 12 | 12 | Gt, |
| 13 | 13 | }; |
| 14 | 14 | |
| 15 | pub nakedcc fn __aeabi_fcmpeq() noreturn { | |
| 15 | pub fn __aeabi_fcmpeq() callconv(.Naked) noreturn { | |
| 16 | 16 | @setRuntimeSafety(false); |
| 17 | 17 | @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Eq}); |
| 18 | 18 | unreachable; |
| 19 | 19 | } |
| 20 | 20 | |
| 21 | pub nakedcc fn __aeabi_fcmplt() noreturn { | |
| 21 | pub fn __aeabi_fcmplt() callconv(.Naked) noreturn { | |
| 22 | 22 | @setRuntimeSafety(false); |
| 23 | 23 | @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Lt}); |
| 24 | 24 | unreachable; |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | pub nakedcc fn __aeabi_fcmple() noreturn { | |
| 27 | pub fn __aeabi_fcmple() callconv(.Naked) noreturn { | |
| 28 | 28 | @setRuntimeSafety(false); |
| 29 | 29 | @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Le}); |
| 30 | 30 | unreachable; |
| 31 | 31 | } |
| 32 | 32 | |
| 33 | pub nakedcc fn __aeabi_fcmpge() noreturn { | |
| 33 | pub fn __aeabi_fcmpge() callconv(.Naked) noreturn { | |
| 34 | 34 | @setRuntimeSafety(false); |
| 35 | 35 | @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Ge}); |
| 36 | 36 | unreachable; |
| 37 | 37 | } |
| 38 | 38 | |
| 39 | pub nakedcc fn __aeabi_fcmpgt() noreturn { | |
| 39 | pub fn __aeabi_fcmpgt() callconv(.Naked) noreturn { | |
| 40 | 40 | @setRuntimeSafety(false); |
| 41 | 41 | @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Gt}); |
| 42 | 42 | unreachable; |
lib/std/special/compiler_rt/aulldiv.zig+2-2| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const builtin = @import("builtin"); |
| 2 | 2 | |
| 3 | pub extern stdcallcc fn _alldiv(a: i64, b: i64) i64 { | |
| 3 | pub extern fn _alldiv(a: i64, b: i64) callconv(.Stdcall) i64 { | |
| 4 | 4 | @setRuntimeSafety(builtin.is_test); |
| 5 | 5 | const s_a = a >> (i64.bit_count - 1); |
| 6 | 6 | const s_b = b >> (i64.bit_count - 1); |
| ... | ... | @@ -13,7 +13,7 @@ pub extern stdcallcc fn _alldiv(a: i64, b: i64) i64 { |
| 13 | 13 | return (@bitCast(i64, r) ^ s) -% s; |
| 14 | 14 | } |
| 15 | 15 | |
| 16 | pub nakedcc fn _aulldiv() void { | |
| 16 | pub fn _aulldiv() callconv(.Naked) void { | |
| 17 | 17 | @setRuntimeSafety(false); |
| 18 | 18 | |
| 19 | 19 | // The stack layout is: |
lib/std/special/compiler_rt/aullrem.zig+2-2| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const builtin = @import("builtin"); |
| 2 | 2 | |
| 3 | pub extern stdcallcc fn _allrem(a: i64, b: i64) i64 { | |
| 3 | pub extern fn _allrem(a: i64, b: i64) callconv(.Stdcall) i64 { | |
| 4 | 4 | @setRuntimeSafety(builtin.is_test); |
| 5 | 5 | const s_a = a >> (i64.bit_count - 1); |
| 6 | 6 | const s_b = b >> (i64.bit_count - 1); |
| ... | ... | @@ -13,7 +13,7 @@ pub extern stdcallcc fn _allrem(a: i64, b: i64) i64 { |
| 13 | 13 | return (@bitCast(i64, r) ^ s) -% s; |
| 14 | 14 | } |
| 15 | 15 | |
| 16 | pub nakedcc fn _aullrem() void { | |
| 16 | pub fn _aullrem() callconv(.Naked) void { | |
| 17 | 17 | @setRuntimeSafety(false); |
| 18 | 18 | |
| 19 | 19 | // The stack layout is: |
lib/std/special/compiler_rt/stack_probe.zig+6-6| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | const builtin = @import("builtin"); |
| 2 | 2 | |
| 3 | 3 | // Zig's own stack-probe routine (available only on x86 and x86_64) |
| 4 | pub nakedcc fn zig_probe_stack() void { | |
| 4 | pub fn zig_probe_stack() callconv(.Naked) void { | |
| 5 | 5 | @setRuntimeSafety(false); |
| 6 | 6 | |
| 7 | 7 | // Versions of the Linux kernel before 5.1 treat any access below SP as |
| ... | ... | @@ -180,11 +180,11 @@ fn win_probe_stack_adjust_sp() void { |
| 180 | 180 | // ___chkstk (__alloca) | yes | yes | |
| 181 | 181 | // ___chkstk_ms | no | no | |
| 182 | 182 | |
| 183 | pub nakedcc fn _chkstk() void { | |
| 183 | pub fn _chkstk() callconv(.Naked) void { | |
| 184 | 184 | @setRuntimeSafety(false); |
| 185 | 185 | @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}); |
| 186 | 186 | } |
| 187 | pub nakedcc fn __chkstk() void { | |
| 187 | pub fn __chkstk() callconv(.Naked) void { | |
| 188 | 188 | @setRuntimeSafety(false); |
| 189 | 189 | switch (builtin.arch) { |
| 190 | 190 | .i386 => @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}), |
| ... | ... | @@ -192,15 +192,15 @@ pub nakedcc fn __chkstk() void { |
| 192 | 192 | else => unreachable, |
| 193 | 193 | } |
| 194 | 194 | } |
| 195 | pub nakedcc fn ___chkstk() void { | |
| 195 | pub fn ___chkstk() callconv(.Naked) void { | |
| 196 | 196 | @setRuntimeSafety(false); |
| 197 | 197 | @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}); |
| 198 | 198 | } |
| 199 | pub nakedcc fn __chkstk_ms() void { | |
| 199 | pub fn __chkstk_ms() callconv(.Naked) void { | |
| 200 | 200 | @setRuntimeSafety(false); |
| 201 | 201 | @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{}); |
| 202 | 202 | } |
| 203 | pub nakedcc fn ___chkstk_ms() void { | |
| 203 | pub fn ___chkstk_ms() callconv(.Naked) void { | |
| 204 | 204 | @setRuntimeSafety(false); |
| 205 | 205 | @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{}); |
| 206 | 206 | } |
lib/std/spinlock.zig+10-2| ... | ... | @@ -60,8 +60,16 @@ pub const SpinLock = struct { |
| 60 | 60 | switch (builtin.arch) { |
| 61 | 61 | // these instructions use a memory clobber as they |
| 62 | 62 | // 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 | ), | |
| 65 | 73 | else => std.os.sched_yield() catch {}, |
| 66 | 74 | } |
| 67 | 75 | } |
lib/std/start.zig+4-4| ... | ... | @@ -43,11 +43,11 @@ comptime { |
| 43 | 43 | } |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | stdcallcc fn _DllMainCRTStartup( | |
| 46 | fn _DllMainCRTStartup( | |
| 47 | 47 | hinstDLL: std.os.windows.HINSTANCE, |
| 48 | 48 | fdwReason: std.os.windows.DWORD, |
| 49 | 49 | lpReserved: std.os.windows.LPVOID, |
| 50 | ) std.os.windows.BOOL { | |
| 50 | ) callconv(.Stdcall) std.os.windows.BOOL { | |
| 51 | 51 | if (@hasDecl(root, "DllMain")) { |
| 52 | 52 | return root.DllMain(hinstDLL, fdwReason, lpReserved); |
| 53 | 53 | } |
| ... | ... | @@ -84,7 +84,7 @@ extern fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) u |
| 84 | 84 | } |
| 85 | 85 | } |
| 86 | 86 | |
| 87 | nakedcc fn _start() noreturn { | |
| 87 | fn _start() callconv(.Naked) noreturn { | |
| 88 | 88 | if (builtin.os == builtin.Os.wasi) { |
| 89 | 89 | // This is marked inline because for some reason LLVM in release mode fails to inline it, |
| 90 | 90 | // and we want fewer call frames in stack traces. |
| ... | ... | @@ -127,7 +127,7 @@ nakedcc fn _start() noreturn { |
| 127 | 127 | @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{}); |
| 128 | 128 | } |
| 129 | 129 | |
| 130 | stdcallcc fn WinMainCRTStartup() noreturn { | |
| 130 | fn WinMainCRTStartup() callconv(.Stdcall) noreturn { | |
| 131 | 131 | @setAlignStack(16); |
| 132 | 132 | if (!builtin.single_threaded) { |
| 133 | 133 | _ = @import("start_windows_tls.zig"); |
lib/std/zig/ast.zig+1| ... | ... | @@ -860,6 +860,7 @@ pub const Node = struct { |
| 860 | 860 | lib_name: ?*Node, // populated if this is an extern declaration |
| 861 | 861 | align_expr: ?*Node, // populated if align(A) is present |
| 862 | 862 | section_expr: ?*Node, // populated if linksection(A) is present |
| 863 | callconv_expr: ?*Node, // populated if callconv(A) is present | |
| 863 | 864 | |
| 864 | 865 | pub const ParamList = SegmentedList(*Node, 2); |
| 865 | 866 |
lib/std/zig/parse.zig+13| ... | ... | @@ -311,6 +311,7 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 311 | 311 | const rparen = try expectToken(it, tree, .RParen); |
| 312 | 312 | const align_expr = try parseByteAlign(arena, it, tree); |
| 313 | 313 | const section_expr = try parseLinkSection(arena, it, tree); |
| 314 | const callconv_expr = try parseCallconv(arena, it, tree); | |
| 314 | 315 | const exclamation_token = eatToken(it, .Bang); |
| 315 | 316 | |
| 316 | 317 | const return_type_expr = (try parseVarType(arena, it, tree)) orelse |
| ... | ... | @@ -347,6 +348,7 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { |
| 347 | 348 | .lib_name = null, |
| 348 | 349 | .align_expr = align_expr, |
| 349 | 350 | .section_expr = section_expr, |
| 351 | .callconv_expr = callconv_expr, | |
| 350 | 352 | }; |
| 351 | 353 | |
| 352 | 354 | if (cc) |kind| { |
| ... | ... | @@ -1678,6 +1680,17 @@ fn parseLinkSection(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node |
| 1678 | 1680 | return expr_node; |
| 1679 | 1681 | } |
| 1680 | 1682 | |
| 1683 | /// CallConv <- KEYWORD_callconv LPAREN Expr RPAREN | |
| 1684 | fn parseCallconv(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { | |
| 1685 | _ = eatToken(it, .Keyword_callconv) orelse return null; | |
| 1686 | _ = try expectToken(it, tree, .LParen); | |
| 1687 | const expr_node = try expectNode(arena, it, tree, parseExpr, AstError{ | |
| 1688 | .ExpectedExpr = AstError.ExpectedExpr{ .token = it.index }, | |
| 1689 | }); | |
| 1690 | _ = try expectToken(it, tree, .RParen); | |
| 1691 | return expr_node; | |
| 1692 | } | |
| 1693 | ||
| 1681 | 1694 | /// FnCC |
| 1682 | 1695 | /// <- KEYWORD_nakedcc |
| 1683 | 1696 | /// / KEYWORD_stdcallcc |
lib/std/zig/parser_test.zig+14-2| ... | ... | @@ -9,6 +9,18 @@ test "zig fmt: change @typeOf to @TypeOf" { |
| 9 | 9 | ); |
| 10 | 10 | } |
| 11 | 11 | |
| 12 | // TODO: Remove nakedcc/stdcallcc once zig 0.6.0 is released. See https://github.com/ziglang/zig/pull/3977 | |
| 13 | test "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 | ||
| 12 | 24 | test "zig fmt: comptime struct field" { |
| 13 | 25 | try testCanonical( |
| 14 | 26 | \\const Foo = struct { |
| ... | ... | @@ -234,7 +246,7 @@ test "zig fmt: threadlocal" { |
| 234 | 246 | test "zig fmt: linksection" { |
| 235 | 247 | try testCanonical( |
| 236 | 248 | \\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 {} | |
| 238 | 250 | \\ |
| 239 | 251 | ); |
| 240 | 252 | } |
| ... | ... | @@ -2326,7 +2338,7 @@ test "zig fmt: fn type" { |
| 2326 | 2338 | \\ |
| 2327 | 2339 | \\const a: fn (u8) u8 = undefined; |
| 2328 | 2340 | \\const b: extern fn (u8) u8 = undefined; |
| 2329 | \\const c: nakedcc fn (u8) u8 = undefined; | |
| 2341 | \\const c: fn (u8) callconv(.Naked) u8 = undefined; | |
| 2330 | 2342 | \\const ap: fn (u8) u8 = a; |
| 2331 | 2343 | \\ |
| 2332 | 2344 | ); |
lib/std/zig/render.zig+24-1| ... | ... | @@ -1319,8 +1319,16 @@ fn renderExpression( |
| 1319 | 1319 | try renderExpression(allocator, stream, tree, indent, start_col, lib_name, Space.Space); |
| 1320 | 1320 | } |
| 1321 | 1321 | |
| 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; | |
| 1322 | 1325 | 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 | |
| 1324 | 1332 | } |
| 1325 | 1333 | |
| 1326 | 1334 | const lparen = if (fn_proto.name_token) |name_token| blk: { |
| ... | ... | @@ -1392,6 +1400,21 @@ fn renderExpression( |
| 1392 | 1400 | try renderToken(tree, stream, section_rparen, indent, start_col, Space.Space); // ) |
| 1393 | 1401 | } |
| 1394 | 1402 | |
| 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 | ||
| 1395 | 1418 | switch (fn_proto.return_type) { |
| 1396 | 1419 | ast.Node.FnProto.ReturnType.Explicit => |node| { |
| 1397 | 1420 | return renderExpression(allocator, stream, tree, indent, start_col, node, space); |
lib/std/zig/tokenizer.zig+3| ... | ... | @@ -30,6 +30,7 @@ pub const Token = struct { |
| 30 | 30 | Keyword.init("async", .Keyword_async), |
| 31 | 31 | Keyword.init("await", .Keyword_await), |
| 32 | 32 | Keyword.init("break", .Keyword_break), |
| 33 | Keyword.init("callconv", .Keyword_callconv), | |
| 33 | 34 | Keyword.init("catch", .Keyword_catch), |
| 34 | 35 | Keyword.init("comptime", .Keyword_comptime), |
| 35 | 36 | Keyword.init("const", .Keyword_const), |
| ... | ... | @@ -162,6 +163,7 @@ pub const Token = struct { |
| 162 | 163 | Keyword_async, |
| 163 | 164 | Keyword_await, |
| 164 | 165 | Keyword_break, |
| 166 | Keyword_callconv, | |
| 165 | 167 | Keyword_catch, |
| 166 | 168 | Keyword_comptime, |
| 167 | 169 | Keyword_const, |
| ... | ... | @@ -286,6 +288,7 @@ pub const Token = struct { |
| 286 | 288 | .Keyword_async => "async", |
| 287 | 289 | .Keyword_await => "await", |
| 288 | 290 | .Keyword_break => "break", |
| 291 | .Keyword_callconv => "callconv", | |
| 289 | 292 | .Keyword_catch => "catch", |
| 290 | 293 | .Keyword_comptime => "comptime", |
| 291 | 294 | .Keyword_const => "const", |
src-self-hosted/translate_c.zig+18-3| ... | ... | @@ -11,7 +11,7 @@ const CToken = ctok.CToken; |
| 11 | 11 | const mem = std.mem; |
| 12 | 12 | const math = std.math; |
| 13 | 13 | |
| 14 | const CallingConvention = std.builtin.TypeInfo.CallingConvention; | |
| 14 | const CallingConvention = std.builtin.CallingConvention; | |
| 15 | 15 | |
| 16 | 16 | pub const ClangErrMsg = Stage2ErrorMsg; |
| 17 | 17 | |
| ... | ... | @@ -3690,6 +3690,7 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a |
| 3690 | 3690 | .lib_name = null, |
| 3691 | 3691 | .align_expr = null, |
| 3692 | 3692 | .section_expr = null, |
| 3693 | .callconv_expr = null, | |
| 3693 | 3694 | }; |
| 3694 | 3695 | |
| 3695 | 3696 | const block = try transCreateNodeBlock(c, null); |
| ... | ... | @@ -4141,6 +4142,11 @@ fn transCC( |
| 4141 | 4142 | switch (clang_cc) { |
| 4142 | 4143 | .C => return CallingConvention.C, |
| 4143 | 4144 | .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, | |
| 4144 | 4150 | else => return revertAndWarn( |
| 4145 | 4151 | rp, |
| 4146 | 4152 | error.UnsupportedType, |
| ... | ... | @@ -4196,7 +4202,6 @@ fn finishTransFnProto( |
| 4196 | 4202 | |
| 4197 | 4203 | // pub extern fn name(...) T |
| 4198 | 4204 | 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; | |
| 4200 | 4205 | const extern_export_inline_tok = if (is_export) |
| 4201 | 4206 | try appendToken(rp.c, .Keyword_export, "export") |
| 4202 | 4207 | else if (cc == .C and is_extern) |
| ... | ... | @@ -4303,6 +4308,14 @@ fn finishTransFnProto( |
| 4303 | 4308 | break :blk null; |
| 4304 | 4309 | }; |
| 4305 | 4310 | |
| 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 | ||
| 4306 | 4319 | const return_type_node = blk: { |
| 4307 | 4320 | if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) { |
| 4308 | 4321 | break :blk try transCreateNodeIdentifier(rp.c, "noreturn"); |
| ... | ... | @@ -4333,11 +4346,12 @@ fn finishTransFnProto( |
| 4333 | 4346 | .return_type = .{ .Explicit = return_type_node }, |
| 4334 | 4347 | .var_args_token = null, // TODO this field is broken in the AST data model |
| 4335 | 4348 | .extern_export_inline_token = extern_export_inline_tok, |
| 4336 | .cc_token = cc_tok, | |
| 4349 | .cc_token = null, | |
| 4337 | 4350 | .body_node = null, |
| 4338 | 4351 | .lib_name = null, |
| 4339 | 4352 | .align_expr = align_expr, |
| 4340 | 4353 | .section_expr = linksection_expr, |
| 4354 | .callconv_expr = callconv_expr, | |
| 4341 | 4355 | }; |
| 4342 | 4356 | return fn_proto; |
| 4343 | 4357 | } |
| ... | ... | @@ -4686,6 +4700,7 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u |
| 4686 | 4700 | .lib_name = null, |
| 4687 | 4701 | .align_expr = null, |
| 4688 | 4702 | .section_expr = null, |
| 4703 | .callconv_expr = null, | |
| 4689 | 4704 | }; |
| 4690 | 4705 | |
| 4691 | 4706 | const block = try transCreateNodeBlock(c, null); |
src-self-hosted/type.zig+2-1| ... | ... | @@ -337,7 +337,7 @@ pub const Type = struct { |
| 337 | 337 | } |
| 338 | 338 | }; |
| 339 | 339 | |
| 340 | const CallingConvention = builtin.TypeInfo.CallingConvention; | |
| 340 | const CallingConvention = builtin.CallingConvention; | |
| 341 | 341 | |
| 342 | 342 | pub const Param = struct { |
| 343 | 343 | is_noalias: bool, |
| ... | ... | @@ -352,6 +352,7 @@ pub const Type = struct { |
| 352 | 352 | .Naked => "nakedcc ", |
| 353 | 353 | .Stdcall => "stdcallcc ", |
| 354 | 354 | .Async => "async ", |
| 355 | else => unreachable, | |
| 355 | 356 | }; |
| 356 | 357 | } |
| 357 | 358 |
src/all_types.hpp+25-10| ... | ... | @@ -57,6 +57,23 @@ enum PtrLen { |
| 57 | 57 | PtrLenC, |
| 58 | 58 | }; |
| 59 | 59 | |
| 60 | enum 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 | ||
| 60 | 77 | // This one corresponds to the builtin.zig enum. |
| 61 | 78 | enum BuiltinPtrSize { |
| 62 | 79 | BuiltinPtrSizeOne, |
| ... | ... | @@ -398,6 +415,7 @@ struct LazyValueFnType { |
| 398 | 415 | IrInstruction *align_inst; // can be null |
| 399 | 416 | IrInstruction *return_type; |
| 400 | 417 | |
| 418 | CallingConvention cc; | |
| 401 | 419 | bool is_generic; |
| 402 | 420 | }; |
| 403 | 421 | |
| ... | ... | @@ -612,15 +630,6 @@ enum NodeType { |
| 612 | 630 | NodeTypeVarFieldType, |
| 613 | 631 | }; |
| 614 | 632 | |
| 615 | enum CallingConvention { | |
| 616 | CallingConventionUnspecified, | |
| 617 | CallingConventionC, | |
| 618 | CallingConventionCold, | |
| 619 | CallingConventionNaked, | |
| 620 | CallingConventionStdcall, | |
| 621 | CallingConventionAsync, | |
| 622 | }; | |
| 623 | ||
| 624 | 633 | enum FnInline { |
| 625 | 634 | FnInlineAuto, |
| 626 | 635 | FnInlineAlways, |
| ... | ... | @@ -639,10 +648,14 @@ struct AstNodeFnProto { |
| 639 | 648 | AstNode *align_expr; |
| 640 | 649 | // populated if the "section(S)" is present |
| 641 | 650 | AstNode *section_expr; |
| 651 | // populated if the "callconv(S)" is present | |
| 652 | AstNode *callconv_expr; | |
| 642 | 653 | Buf doc_comments; |
| 643 | 654 | |
| 644 | 655 | FnInline fn_inline; |
| 645 | CallingConvention cc; | |
| 656 | bool is_nakedcc; | |
| 657 | bool is_stdcallcc; | |
| 658 | bool is_async; | |
| 646 | 659 | |
| 647 | 660 | VisibMod visib_mod; |
| 648 | 661 | bool auto_err_set; |
| ... | ... | @@ -1597,6 +1610,7 @@ struct ZigFn { |
| 1597 | 1610 | Buf **param_names; |
| 1598 | 1611 | IrInstruction *err_code_spill; |
| 1599 | 1612 | AstNode *assumed_non_async; |
| 1613 | CallingConvention cc; | |
| 1600 | 1614 | |
| 1601 | 1615 | AstNode *fn_no_inline_set_node; |
| 1602 | 1616 | AstNode *fn_static_eval_set_node; |
| ... | ... | @@ -3549,6 +3563,7 @@ struct IrInstructionFnProto { |
| 3549 | 3563 | |
| 3550 | 3564 | IrInstruction **param_types; |
| 3551 | 3565 | IrInstruction *align_value; |
| 3566 | IrInstruction *callconv_value; | |
| 3552 | 3567 | IrInstruction *return_type; |
| 3553 | 3568 | bool is_var_args; |
| 3554 | 3569 | }; |
src/analyze.cpp+111-62| ... | ... | @@ -919,24 +919,20 @@ ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry) { |
| 919 | 919 | |
| 920 | 920 | const char *calling_convention_name(CallingConvention cc) { |
| 921 | 921 | 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 | ||
| 932 | static 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"; | |
| 940 | 936 | } |
| 941 | 937 | zig_unreachable(); |
| 942 | 938 | } |
| ... | ... | @@ -949,7 +945,15 @@ bool calling_convention_allows_zig_types(CallingConvention cc) { |
| 949 | 945 | case CallingConventionC: |
| 950 | 946 | case CallingConventionCold: |
| 951 | 947 | case CallingConventionNaked: |
| 948 | case CallingConventionInterrupt: | |
| 949 | case CallingConventionSignal: | |
| 952 | 950 | case CallingConventionStdcall: |
| 951 | case CallingConventionFastcall: | |
| 952 | case CallingConventionVectorcall: | |
| 953 | case CallingConventionThiscall: | |
| 954 | case CallingConventionAPCS: | |
| 955 | case CallingConventionAAPCS: | |
| 956 | case CallingConventionAAPCSVFP: | |
| 953 | 957 | return false; |
| 954 | 958 | } |
| 955 | 959 | zig_unreachable(); |
| ... | ... | @@ -1006,8 +1010,8 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { |
| 1006 | 1010 | |
| 1007 | 1011 | // populate the name of the type |
| 1008 | 1012 | 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 "); | |
| 1011 | 1015 | buf_appendf(&fn_type->name, "fn("); |
| 1012 | 1016 | for (size_t i = 0; i < fn_type_id->param_count; i += 1) { |
| 1013 | 1017 | FnTypeParamInfo *param_info = &fn_type_id->param_info[i]; |
| ... | ... | @@ -1026,6 +1030,9 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { |
| 1026 | 1030 | if (fn_type_id->alignment != 0) { |
| 1027 | 1031 | buf_appendf(&fn_type->name, " align(%" PRIu32 ")", fn_type_id->alignment); |
| 1028 | 1032 | } |
| 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 | } | |
| 1029 | 1036 | buf_appendf(&fn_type->name, " %s", buf_ptr(&fn_type_id->return_type->name)); |
| 1030 | 1037 | |
| 1031 | 1038 | // 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) { |
| 1444 | 1451 | ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) { |
| 1445 | 1452 | ZigType *fn_type = new_type_table_entry(ZigTypeIdFn); |
| 1446 | 1453 | 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 "); | |
| 1449 | 1456 | buf_appendf(&fn_type->name, "fn("); |
| 1450 | 1457 | size_t i = 0; |
| 1451 | 1458 | 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) { |
| 1457 | 1464 | const char *comma_str = (i == 0) ? "" : ","; |
| 1458 | 1465 | buf_appendf(&fn_type->name, "%svar", comma_str); |
| 1459 | 1466 | } |
| 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"); | |
| 1461 | 1472 | |
| 1462 | 1473 | fn_type->data.fn.fn_type_id = *fn_type_id; |
| 1463 | 1474 | fn_type->data.fn.is_generic = true; |
| ... | ... | @@ -1467,17 +1478,25 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) { |
| 1467 | 1478 | return fn_type; |
| 1468 | 1479 | } |
| 1469 | 1480 | |
| 1470 | void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc) { | |
| 1481 | CallingConvention 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 | ||
| 1495 | void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, CallingConvention cc, size_t param_count_alloc) { | |
| 1471 | 1496 | assert(proto_node->type == NodeTypeFnProto); |
| 1472 | 1497 | AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; |
| 1473 | 1498 | |
| 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; | |
| 1481 | 1500 | fn_type_id->param_count = fn_proto->params.length; |
| 1482 | 1501 | fn_type_id->param_info = allocate<FnTypeParamInfo>(param_count_alloc); |
| 1483 | 1502 | fn_type_id->next_param_index = 0; |
| ... | ... | @@ -1691,8 +1710,7 @@ Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result) { |
| 1691 | 1710 | case ZigTypeIdArray: |
| 1692 | 1711 | return type_allowed_in_extern(g, type_entry->data.array.child_type, result); |
| 1693 | 1712 | 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); | |
| 1696 | 1714 | return ErrorNone; |
| 1697 | 1715 | case ZigTypeIdPointer: |
| 1698 | 1716 | 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 |
| 1752 | 1770 | Error err; |
| 1753 | 1771 | |
| 1754 | 1772 | 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); | |
| 1756 | 1774 | |
| 1757 | 1775 | for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { |
| 1758 | 1776 | 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) { |
| 2164 | 2182 | ZigType *field_type = resolve_struct_field_type(g, field); |
| 2165 | 2183 | if (field_type == nullptr) { |
| 2166 | 2184 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2167 | return err; | |
| 2185 | return ErrorSemanticAnalyzeFail; | |
| 2168 | 2186 | } |
| 2169 | 2187 | if ((err = type_resolve(g, field->type_entry, ResolveStatusSizeKnown))) { |
| 2170 | 2188 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| ... | ... | @@ -2254,7 +2272,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { |
| 2254 | 2272 | ZigType *field_type = resolve_struct_field_type(g, field); |
| 2255 | 2273 | if (field_type == nullptr) { |
| 2256 | 2274 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2257 | return err; | |
| 2275 | return ErrorSemanticAnalyzeFail; | |
| 2258 | 2276 | } |
| 2259 | 2277 | |
| 2260 | 2278 | if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) { |
| ... | ... | @@ -2324,7 +2342,7 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { |
| 2324 | 2342 | &field->align)) |
| 2325 | 2343 | { |
| 2326 | 2344 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 2327 | return err; | |
| 2345 | return ErrorSemanticAnalyzeFail; | |
| 2328 | 2346 | } |
| 2329 | 2347 | add_node_error(g, field->decl_node, |
| 2330 | 2348 | 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) { |
| 2451 | 2469 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| 2452 | 2470 | return ErrorSemanticAnalyzeFail; |
| 2453 | 2471 | } |
| 2472 | ||
| 2454 | 2473 | if (is_packed) { |
| 2455 | 2474 | if ((err = emit_error_unless_type_allowed_in_packed_union(g, field_type, union_field->decl_node))) { |
| 2456 | 2475 | union_type->data.unionation.resolve_status = ResolveStatusInvalid; |
| ... | ... | @@ -2909,7 +2928,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { |
| 2909 | 2928 | &field->align)) |
| 2910 | 2929 | { |
| 2911 | 2930 | struct_type->data.structure.resolve_status = ResolveStatusInvalid; |
| 2912 | return err; | |
| 2931 | return ErrorSemanticAnalyzeFail; | |
| 2913 | 2932 | } |
| 2914 | 2933 | } else if (packed) { |
| 2915 | 2934 | field->align = 1; |
| ... | ... | @@ -3395,27 +3414,6 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 3395 | 3414 | get_fully_qualified_decl_name(g, &fn_table_entry->symbol_name, &tld_fn->base, false); |
| 3396 | 3415 | } |
| 3397 | 3416 | |
| 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 | ||
| 3419 | 3417 | if (!is_extern) { |
| 3420 | 3418 | fn_table_entry->fndef_scope = create_fndef_scope(g, |
| 3421 | 3419 | 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) { |
| 3434 | 3432 | |
| 3435 | 3433 | Scope *child_scope = fn_table_entry->fndef_scope ? &fn_table_entry->fndef_scope->base : tld_fn->base.parent_scope; |
| 3436 | 3434 | |
| 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 | } | |
| 3438 | 3449 | |
| 3439 | 3450 | if (fn_proto->section_expr != nullptr) { |
| 3440 | 3451 | if (!analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name)) { |
| 3441 | 3452 | fn_table_entry->type_entry = g->builtin_types.entry_invalid; |
| 3453 | tld_fn->base.resolution = TldResolutionInvalid; | |
| 3454 | return; | |
| 3442 | 3455 | } |
| 3443 | 3456 | } |
| 3444 | 3457 | |
| 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)) { | |
| 3446 | 3461 | tld_fn->base.resolution = TldResolutionInvalid; |
| 3447 | 3462 | return; |
| 3448 | 3463 | } |
| 3449 | 3464 | |
| 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 | ||
| 3450 | 3499 | if (!fn_table_entry->type_entry->data.fn.is_generic) { |
| 3451 | 3500 | if (fn_def_node) |
| 3452 | 3501 | g->fn_defs.append(fn_table_entry); |
| ... | ... | @@ -3455,7 +3504,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 3455 | 3504 | // if the calling convention implies that it cannot be async, we save that for later |
| 3456 | 3505 | // and leave the value to be nullptr to indicate that we have not emitted possible |
| 3457 | 3506 | // 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) { | |
| 3459 | 3508 | fn_table_entry->inferred_async_node = fn_table_entry->proto_node; |
| 3460 | 3509 | } |
| 3461 | 3510 | } else if (source_node->type == NodeTypeTestDecl) { |
src/analyze.hpp+2-1| ... | ... | @@ -100,7 +100,7 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node); |
| 100 | 100 | void append_namespace_qualification(CodeGen *g, Buf *buf, ZigType *container_type); |
| 101 | 101 | ZigFn *create_fn(CodeGen *g, AstNode *proto_node); |
| 102 | 102 | ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value); |
| 103 | void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc); | |
| 103 | void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, CallingConvention cc, size_t param_count_alloc); | |
| 104 | 104 | AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index); |
| 105 | 105 | Error ATTRIBUTE_MUST_USE type_resolve(CodeGen *g, ZigType *type_entry, ResolveStatus status); |
| 106 | 106 | void complete_enum(CodeGen *g, ZigType *enum_type); |
| ... | ... | @@ -259,6 +259,7 @@ ZigValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType * |
| 259 | 259 | |
| 260 | 260 | void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn); |
| 261 | 261 | bool fn_is_async(ZigFn *fn); |
| 262 | CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto); | |
| 262 | 263 | |
| 263 | 264 | Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *type_val, uint32_t *abi_align); |
| 264 | 265 | Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ZigValue *type_val, |
src/ast_render.cpp+5| ... | ... | @@ -488,6 +488,11 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { |
| 488 | 488 | render_node_grouped(ar, node->data.fn_proto.section_expr); |
| 489 | 489 | fprintf(ar->f, ")"); |
| 490 | 490 | } |
| 491 | if (node->data.fn_proto.callconv_expr) { | |
| 492 | fprintf(ar->f, " callconv("); | |
| 493 | render_node_grouped(ar, node->data.fn_proto.callconv_expr); | |
| 494 | fprintf(ar->f, ")"); | |
| 495 | } | |
| 491 | 496 | |
| 492 | 497 | if (node->data.fn_proto.return_var_token != nullptr) { |
| 493 | 498 | 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 |
| 263 | 263 | } |
| 264 | 264 | } |
| 265 | 265 | |
| 266 | static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) { | |
| 266 | static ZigLLVM_CallingConv get_llvm_cc(CodeGen *g, CallingConvention cc) { | |
| 267 | 267 | 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; | |
| 270 | 272 | 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; | |
| 285 | 278 | case CallingConventionNaked: |
| 286 | 279 | zig_unreachable(); |
| 287 | 280 | 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; | |
| 294 | 299 | 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; | |
| 296 | 326 | } |
| 297 | 327 | zig_unreachable(); |
| 298 | 328 | } |
| ... | ... | @@ -384,7 +414,15 @@ static bool cc_want_sret_attr(CallingConvention cc) { |
| 384 | 414 | zig_unreachable(); |
| 385 | 415 | case CallingConventionC: |
| 386 | 416 | case CallingConventionCold: |
| 417 | case CallingConventionInterrupt: | |
| 418 | case CallingConventionSignal: | |
| 387 | 419 | case CallingConventionStdcall: |
| 420 | case CallingConventionFastcall: | |
| 421 | case CallingConventionVectorcall: | |
| 422 | case CallingConventionThiscall: | |
| 423 | case CallingConventionAPCS: | |
| 424 | case CallingConventionAAPCS: | |
| 425 | case CallingConventionAAPCSVFP: | |
| 388 | 426 | return true; |
| 389 | 427 | case CallingConventionAsync: |
| 390 | 428 | case CallingConventionUnspecified: |
| ... | ... | @@ -481,7 +519,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { |
| 481 | 519 | if (cc == CallingConventionNaked) { |
| 482 | 520 | addLLVMFnAttr(llvm_fn, "naked"); |
| 483 | 521 | } 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)); | |
| 485 | 523 | } |
| 486 | 524 | |
| 487 | 525 | bool want_cold = fn->is_cold || cc == CallingConventionCold; |
| ... | ... | @@ -976,7 +1014,7 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace |
| 976 | 1014 | { |
| 977 | 1015 | assert(g->panic_fn != nullptr); |
| 978 | 1016 | 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); | |
| 980 | 1018 | if (stack_trace_arg == nullptr) { |
| 981 | 1019 | stack_trace_arg = LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type(g))); |
| 982 | 1020 | } |
| ... | ... | @@ -1087,7 +1125,7 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) { |
| 1087 | 1125 | LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref); |
| 1088 | 1126 | addLLVMFnAttr(fn_val, "alwaysinline"); |
| 1089 | 1127 | LLVMSetLinkage(fn_val, LLVMInternalLinkage); |
| 1090 | LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); | |
| 1128 | ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); | |
| 1091 | 1129 | addLLVMFnAttr(fn_val, "nounwind"); |
| 1092 | 1130 | add_uwtable_attr(g, fn_val); |
| 1093 | 1131 | // 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) { |
| 1168 | 1206 | addLLVMFnAttr(fn_val, "noinline"); // so that we can look at return address |
| 1169 | 1207 | addLLVMFnAttr(fn_val, "cold"); |
| 1170 | 1208 | LLVMSetLinkage(fn_val, LLVMInternalLinkage); |
| 1171 | LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); | |
| 1209 | ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); | |
| 1172 | 1210 | addLLVMFnAttr(fn_val, "nounwind"); |
| 1173 | 1211 | add_uwtable_attr(g, fn_val); |
| 1174 | 1212 | if (codegen_have_frame_pointer(g)) { |
| ... | ... | @@ -1252,7 +1290,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { |
| 1252 | 1290 | addLLVMFnAttr(fn_val, "noreturn"); |
| 1253 | 1291 | addLLVMFnAttr(fn_val, "cold"); |
| 1254 | 1292 | LLVMSetLinkage(fn_val, LLVMInternalLinkage); |
| 1255 | LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); | |
| 1293 | ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); | |
| 1256 | 1294 | addLLVMFnAttr(fn_val, "nounwind"); |
| 1257 | 1295 | add_uwtable_attr(g, fn_val); |
| 1258 | 1296 | if (codegen_have_frame_pointer(g)) { |
| ... | ... | @@ -2148,7 +2186,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) { |
| 2148 | 2186 | const char *fn_name = get_mangled_name(g, "__zig_merge_error_return_traces", false); |
| 2149 | 2187 | LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref); |
| 2150 | 2188 | LLVMSetLinkage(fn_val, LLVMInternalLinkage); |
| 2151 | LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); | |
| 2189 | ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); | |
| 2152 | 2190 | addLLVMFnAttr(fn_val, "nounwind"); |
| 2153 | 2191 | add_uwtable_attr(g, fn_val); |
| 2154 | 2192 | addLLVMArgAttr(fn_val, (unsigned)0, "noalias"); |
| ... | ... | @@ -2325,7 +2363,7 @@ static LLVMValueRef gen_resume(CodeGen *g, LLVMValueRef fn_val, LLVMValueRef tar |
| 2325 | 2363 | LLVMValueRef arg_val = LLVMConstSub(LLVMConstAllOnes(usize_type_ref), |
| 2326 | 2364 | LLVMConstInt(usize_type_ref, resume_id, false)); |
| 2327 | 2365 | 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, ""); | |
| 2329 | 2367 | } |
| 2330 | 2368 | |
| 2331 | 2369 | static LLVMBasicBlockRef gen_suspend_begin(CodeGen *g, const char *name_hint) { |
| ... | ... | @@ -4215,7 +4253,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 4215 | 4253 | break; |
| 4216 | 4254 | } |
| 4217 | 4255 | |
| 4218 | LLVMCallConv llvm_cc = get_llvm_cc(g, cc); | |
| 4256 | ZigLLVM_CallingConv llvm_cc = get_llvm_cc(g, cc); | |
| 4219 | 4257 | LLVMValueRef result; |
| 4220 | 4258 | |
| 4221 | 4259 | if (callee_is_async) { |
| ... | ... | @@ -4925,7 +4963,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) { |
| 4925 | 4963 | buf_ptr(buf_sprintf("__zig_tag_name_%s", buf_ptr(&enum_type->name))), false); |
| 4926 | 4964 | LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref); |
| 4927 | 4965 | LLVMSetLinkage(fn_val, LLVMInternalLinkage); |
| 4928 | LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); | |
| 4966 | ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); | |
| 4929 | 4967 | addLLVMFnAttr(fn_val, "nounwind"); |
| 4930 | 4968 | add_uwtable_attr(g, fn_val); |
| 4931 | 4969 | if (codegen_have_frame_pointer(g)) { |
| ... | ... | @@ -8463,8 +8501,16 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 8463 | 8501 | static_assert(CallingConventionC == 1, ""); |
| 8464 | 8502 | static_assert(CallingConventionCold == 2, ""); |
| 8465 | 8503 | 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, ""); | |
| 8468 | 8514 | |
| 8469 | 8515 | static_assert(FnInlineAuto == 0, ""); |
| 8470 | 8516 | static_assert(FnInlineAlways == 1, ""); |
src/ir.cpp+46-12| ... | ... | @@ -3248,12 +3248,13 @@ static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, |
| 3248 | 3248 | } |
| 3249 | 3249 | |
| 3250 | 3250 | static 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) | |
| 3253 | 3253 | { |
| 3254 | 3254 | IrInstructionFnProto *instruction = ir_build_instruction<IrInstructionFnProto>(irb, scope, source_node); |
| 3255 | 3255 | instruction->param_types = param_types; |
| 3256 | 3256 | instruction->align_value = align_value; |
| 3257 | instruction->callconv_value = callconv_value; | |
| 3257 | 3258 | instruction->return_type = return_type; |
| 3258 | 3259 | instruction->is_var_args = is_var_args; |
| 3259 | 3260 | |
| ... | ... | @@ -3264,6 +3265,7 @@ static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *s |
| 3264 | 3265 | if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block); |
| 3265 | 3266 | } |
| 3266 | 3267 | 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); | |
| 3267 | 3269 | ir_ref_instruction(return_type, irb->current_basic_block); |
| 3268 | 3270 | |
| 3269 | 3271 | return &instruction->base; |
| ... | ... | @@ -8843,6 +8845,13 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo |
| 8843 | 8845 | return irb->codegen->invalid_instruction; |
| 8844 | 8846 | } |
| 8845 | 8847 | |
| 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 | ||
| 8846 | 8855 | IrInstruction *return_type; |
| 8847 | 8856 | if (node->data.fn_proto.return_var_token == nullptr) { |
| 8848 | 8857 | if (node->data.fn_proto.return_type == nullptr) { |
| ... | ... | @@ -8859,7 +8868,7 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo |
| 8859 | 8868 | //return_type = nullptr; |
| 8860 | 8869 | } |
| 8861 | 8870 | |
| 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); | |
| 8863 | 8872 | } |
| 8864 | 8873 | |
| 8865 | 8874 | static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | ... | @@ -16729,9 +16738,17 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio |
| 16729 | 16738 | add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); |
| 16730 | 16739 | } break; |
| 16731 | 16740 | case CallingConventionC: |
| 16732 | case CallingConventionNaked: | |
| 16733 | 16741 | case CallingConventionCold: |
| 16742 | case CallingConventionNaked: | |
| 16743 | case CallingConventionInterrupt: | |
| 16744 | case CallingConventionSignal: | |
| 16734 | 16745 | case CallingConventionStdcall: |
| 16746 | case CallingConventionFastcall: | |
| 16747 | case CallingConventionVectorcall: | |
| 16748 | case CallingConventionThiscall: | |
| 16749 | case CallingConventionAPCS: | |
| 16750 | case CallingConventionAAPCS: | |
| 16751 | case CallingConventionAAPCSVFP: | |
| 16735 | 16752 | add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, cc); |
| 16736 | 16753 | break; |
| 16737 | 16754 | } |
| ... | ... | @@ -18094,7 +18111,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i |
| 18094 | 18111 | return ira->codegen->invalid_instruction; |
| 18095 | 18112 | } |
| 18096 | 18113 | |
| 18097 | ||
| 18098 | 18114 | if (fn_type_id->is_var_args) { |
| 18099 | 18115 | if (call_param_count < src_param_count) { |
| 18100 | 18116 | ErrorMsg *msg = ir_add_error_node(ira, source_node, |
| ... | ... | @@ -18247,8 +18263,9 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i |
| 18247 | 18263 | buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); |
| 18248 | 18264 | impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn); |
| 18249 | 18265 | impl_fn->child_scope = &impl_fn->fndef_scope->base; |
| 18266 | impl_fn->cc = fn_entry->cc; | |
| 18250 | 18267 | 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); | |
| 18252 | 18269 | inst_fn_type_id.param_count = 0; |
| 18253 | 18270 | inst_fn_type_id.is_var_args = false; |
| 18254 | 18271 | |
| ... | ... | @@ -22585,8 +22602,8 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr |
| 22585 | 22602 | // calling_convention: TypeInfo.CallingConvention |
| 22586 | 22603 | ensure_field_index(fn_decl_val->type, "calling_convention", 2); |
| 22587 | 22604 | 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); | |
| 22590 | 22607 | // is_var_args: bool |
| 22591 | 22608 | ensure_field_index(fn_decl_val->type, "is_var_args", 3); |
| 22592 | 22609 | bool is_varargs = fn_node->is_var_args; |
| ... | ... | @@ -23273,7 +23290,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 23273 | 23290 | // calling_convention: TypeInfo.CallingConvention |
| 23274 | 23291 | ensure_field_index(result->type, "calling_convention", 0); |
| 23275 | 23292 | 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"); | |
| 23277 | 23294 | bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); |
| 23278 | 23295 | // is_generic: bool |
| 23279 | 23296 | ensure_field_index(result->type, "is_generic", 1); |
| ... | ... | @@ -26185,6 +26202,21 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct |
| 26185 | 26202 | return ira->codegen->invalid_instruction; |
| 26186 | 26203 | } |
| 26187 | 26204 | |
| 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 | ||
| 26188 | 26220 | size_t param_count = proto_node->data.fn_proto.params.length; |
| 26189 | 26221 | lazy_fn_type->proto_node = proto_node; |
| 26190 | 26222 | lazy_fn_type->param_types = allocate<IrInstruction *>(param_count); |
| ... | ... | @@ -26195,9 +26227,11 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct |
| 26195 | 26227 | |
| 26196 | 26228 | bool param_is_var_args = param_node->data.param_decl.is_var_args; |
| 26197 | 26229 | 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) { | |
| 26199 | 26233 | break; |
| 26200 | } else if (proto_node->data.fn_proto.cc == CallingConventionUnspecified) { | |
| 26234 | } else if (cc == CallingConventionUnspecified) { | |
| 26201 | 26235 | lazy_fn_type->is_generic = true; |
| 26202 | 26236 | return result; |
| 26203 | 26237 | } else { |
| ... | ... | @@ -29076,7 +29110,7 @@ static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, La |
| 29076 | 29110 | AstNode *proto_node = lazy_fn_type->proto_node; |
| 29077 | 29111 | |
| 29078 | 29112 | 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); | |
| 29080 | 29114 | |
| 29081 | 29115 | for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { |
| 29082 | 29116 | AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); |
src/parser.cpp+25-8| ... | ... | @@ -92,6 +92,7 @@ static Token *ast_parse_block_label(ParseContext *pc); |
| 92 | 92 | static AstNode *ast_parse_field_init(ParseContext *pc); |
| 93 | 93 | static AstNode *ast_parse_while_continue_expr(ParseContext *pc); |
| 94 | 94 | static AstNode *ast_parse_link_section(ParseContext *pc); |
| 95 | static AstNode *ast_parse_callconv(ParseContext *pc); | |
| 95 | 96 | static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc); |
| 96 | 97 | static AstNode *ast_parse_param_decl(ParseContext *pc); |
| 97 | 98 | static AstNode *ast_parse_param_type(ParseContext *pc); |
| ... | ... | @@ -676,7 +677,9 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B |
| 676 | 677 | fn_proto->column = first->start_column; |
| 677 | 678 | fn_proto->data.fn_proto.visib_mod = visib_mod; |
| 678 | 679 | fn_proto->data.fn_proto.doc_comments = *doc_comments; |
| 679 | fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern; | |
| 680 | // ast_parse_fn_cc may set it | |
| 681 | if (!fn_proto->data.fn_proto.is_extern) | |
| 682 | fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern; | |
| 680 | 683 | fn_proto->data.fn_proto.is_export = first->id == TokenIdKeywordExport; |
| 681 | 684 | switch (first->id) { |
| 682 | 685 | case TokenIdKeywordInline: |
| ... | ... | @@ -761,7 +764,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) { |
| 761 | 764 | // The extern keyword for fn CC is also used for container decls. |
| 762 | 765 | // We therefore put it back, as allow container decl to consume it |
| 763 | 766 | // later. |
| 764 | if (fn_cc.cc == CallingConventionC) { | |
| 767 | if (fn_cc.is_extern) { | |
| 765 | 768 | fn = eat_token_if(pc, TokenIdKeywordFn); |
| 766 | 769 | if (fn == nullptr) { |
| 767 | 770 | put_back_token(pc); |
| ... | ... | @@ -784,6 +787,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) { |
| 784 | 787 | |
| 785 | 788 | AstNode *align_expr = ast_parse_byte_align(pc); |
| 786 | 789 | AstNode *section_expr = ast_parse_link_section(pc); |
| 790 | AstNode *callconv_expr = ast_parse_callconv(pc); | |
| 787 | 791 | Token *var = eat_token_if(pc, TokenIdKeywordVar); |
| 788 | 792 | Token *exmark = nullptr; |
| 789 | 793 | AstNode *return_type = nullptr; |
| ... | ... | @@ -798,6 +802,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) { |
| 798 | 802 | res->data.fn_proto.params = params; |
| 799 | 803 | res->data.fn_proto.align_expr = align_expr; |
| 800 | 804 | res->data.fn_proto.section_expr = section_expr; |
| 805 | res->data.fn_proto.callconv_expr = callconv_expr; | |
| 801 | 806 | res->data.fn_proto.return_var_token = var; |
| 802 | 807 | res->data.fn_proto.auto_err_set = exmark != nullptr; |
| 803 | 808 | res->data.fn_proto.return_type = return_type; |
| ... | ... | @@ -2099,6 +2104,18 @@ static AstNode *ast_parse_link_section(ParseContext *pc) { |
| 2099 | 2104 | return res; |
| 2100 | 2105 | } |
| 2101 | 2106 | |
| 2107 | // CallConv <- KEYWORD_callconv LPAREN Expr RPAREN | |
| 2108 | static AstNode *ast_parse_callconv(ParseContext *pc) { | |
| 2109 | Token *first = eat_token_if(pc, TokenIdKeywordCallconv); | |
| 2110 | if (first == nullptr) | |
| 2111 | return nullptr; | |
| 2112 | ||
| 2113 | expect_token(pc, TokenIdLParen); | |
| 2114 | AstNode *res = ast_expect(pc, ast_parse_expr); | |
| 2115 | expect_token(pc, TokenIdRParen); | |
| 2116 | return res; | |
| 2117 | } | |
| 2118 | ||
| 2102 | 2119 | // FnCC |
| 2103 | 2120 | // <- KEYWORD_nakedcc |
| 2104 | 2121 | // / KEYWORD_stdcallcc |
| ... | ... | @@ -2107,19 +2124,19 @@ static AstNode *ast_parse_link_section(ParseContext *pc) { |
| 2107 | 2124 | static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc) { |
| 2108 | 2125 | AstNodeFnProto res = {}; |
| 2109 | 2126 | if (eat_token_if(pc, TokenIdKeywordNakedCC) != nullptr) { |
| 2110 | res.cc = CallingConventionNaked; | |
| 2127 | res.is_nakedcc = true; | |
| 2111 | 2128 | return Optional<AstNodeFnProto>::some(res); |
| 2112 | 2129 | } |
| 2113 | 2130 | if (eat_token_if(pc, TokenIdKeywordStdcallCC) != nullptr) { |
| 2114 | res.cc = CallingConventionStdcall; | |
| 2131 | res.is_stdcallcc = true; | |
| 2115 | 2132 | return Optional<AstNodeFnProto>::some(res); |
| 2116 | 2133 | } |
| 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; | |
| 2119 | 2136 | return Optional<AstNodeFnProto>::some(res); |
| 2120 | 2137 | } |
| 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; | |
| 2123 | 2140 | return Optional<AstNodeFnProto>::some(res); |
| 2124 | 2141 | } |
| 2125 | 2142 |
src/tokenizer.cpp+2| ... | ... | @@ -110,6 +110,7 @@ static const struct ZigKeyword zig_keywords[] = { |
| 110 | 110 | {"async", TokenIdKeywordAsync}, |
| 111 | 111 | {"await", TokenIdKeywordAwait}, |
| 112 | 112 | {"break", TokenIdKeywordBreak}, |
| 113 | {"callconv", TokenIdKeywordCallconv}, | |
| 113 | 114 | {"catch", TokenIdKeywordCatch}, |
| 114 | 115 | {"comptime", TokenIdKeywordCompTime}, |
| 115 | 116 | {"const", TokenIdKeywordConst}, |
| ... | ... | @@ -1545,6 +1546,7 @@ const char * token_name(TokenId id) { |
| 1545 | 1546 | case TokenIdKeywordAsm: return "asm"; |
| 1546 | 1547 | case TokenIdKeywordBreak: return "break"; |
| 1547 | 1548 | case TokenIdKeywordCatch: return "catch"; |
| 1549 | case TokenIdKeywordCallconv: return "callconv"; | |
| 1548 | 1550 | case TokenIdKeywordCompTime: return "comptime"; |
| 1549 | 1551 | case TokenIdKeywordConst: return "const"; |
| 1550 | 1552 | case TokenIdKeywordContinue: return "continue"; |
src/tokenizer.hpp+1| ... | ... | @@ -59,6 +59,7 @@ enum TokenId { |
| 59 | 59 | TokenIdKeywordAwait, |
| 60 | 60 | TokenIdKeywordBreak, |
| 61 | 61 | TokenIdKeywordCatch, |
| 62 | TokenIdKeywordCallconv, | |
| 62 | 63 | TokenIdKeywordCompTime, |
| 63 | 64 | TokenIdKeywordConst, |
| 64 | 65 | TokenIdKeywordContinue, |
src/zig_llvm.cpp+51-2| ... | ... | @@ -273,10 +273,10 @@ ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref) { |
| 273 | 273 | } |
| 274 | 274 | |
| 275 | 275 | LLVMValueRef 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) | |
| 277 | 277 | { |
| 278 | 278 | 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)); | |
| 280 | 280 | switch (attr) { |
| 281 | 281 | case ZigLLVM_CallAttrAuto: |
| 282 | 282 | break; |
| ... | ... | @@ -932,6 +932,9 @@ void ZigLLVMFunctionSetPrefixData(LLVMValueRef function, LLVMValueRef data) { |
| 932 | 932 | unwrap<Function>(function)->setPrefixData(unwrap<Constant>(data)); |
| 933 | 933 | } |
| 934 | 934 | |
| 935 | void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, ZigLLVM_CallingConv cc) { | |
| 936 | unwrap<Function>(function)->setCallingConv(static_cast<CallingConv::ID>(cc)); | |
| 937 | } | |
| 935 | 938 | |
| 936 | 939 | class MyOStream: public raw_ostream { |
| 937 | 940 | public: |
| ... | ... | @@ -1315,3 +1318,49 @@ static_assert((Triple::ObjectFormatType)ZigLLVM_ELF == Triple::ELF, ""); |
| 1315 | 1318 | static_assert((Triple::ObjectFormatType)ZigLLVM_MachO == Triple::MachO, ""); |
| 1316 | 1319 | static_assert((Triple::ObjectFormatType)ZigLLVM_Wasm == Triple::Wasm, ""); |
| 1317 | 1320 | static_assert((Triple::ObjectFormatType)ZigLLVM_XCOFF == Triple::XCOFF, ""); |
| 1321 | ||
| 1322 | static_assert((CallingConv::ID)ZigLLVM_C == llvm::CallingConv::C, ""); | |
| 1323 | static_assert((CallingConv::ID)ZigLLVM_Fast == llvm::CallingConv::Fast, ""); | |
| 1324 | static_assert((CallingConv::ID)ZigLLVM_Cold == llvm::CallingConv::Cold, ""); | |
| 1325 | static_assert((CallingConv::ID)ZigLLVM_GHC == llvm::CallingConv::GHC, ""); | |
| 1326 | static_assert((CallingConv::ID)ZigLLVM_HiPE == llvm::CallingConv::HiPE, ""); | |
| 1327 | static_assert((CallingConv::ID)ZigLLVM_WebKit_JS == llvm::CallingConv::WebKit_JS, ""); | |
| 1328 | static_assert((CallingConv::ID)ZigLLVM_AnyReg == llvm::CallingConv::AnyReg, ""); | |
| 1329 | static_assert((CallingConv::ID)ZigLLVM_PreserveMost == llvm::CallingConv::PreserveMost, ""); | |
| 1330 | static_assert((CallingConv::ID)ZigLLVM_PreserveAll == llvm::CallingConv::PreserveAll, ""); | |
| 1331 | static_assert((CallingConv::ID)ZigLLVM_Swift == llvm::CallingConv::Swift, ""); | |
| 1332 | static_assert((CallingConv::ID)ZigLLVM_CXX_FAST_TLS == llvm::CallingConv::CXX_FAST_TLS, ""); | |
| 1333 | static_assert((CallingConv::ID)ZigLLVM_FirstTargetCC == llvm::CallingConv::FirstTargetCC, ""); | |
| 1334 | static_assert((CallingConv::ID)ZigLLVM_X86_StdCall == llvm::CallingConv::X86_StdCall, ""); | |
| 1335 | static_assert((CallingConv::ID)ZigLLVM_X86_FastCall == llvm::CallingConv::X86_FastCall, ""); | |
| 1336 | static_assert((CallingConv::ID)ZigLLVM_ARM_APCS == llvm::CallingConv::ARM_APCS, ""); | |
| 1337 | static_assert((CallingConv::ID)ZigLLVM_ARM_AAPCS == llvm::CallingConv::ARM_AAPCS, ""); | |
| 1338 | static_assert((CallingConv::ID)ZigLLVM_ARM_AAPCS_VFP == llvm::CallingConv::ARM_AAPCS_VFP, ""); | |
| 1339 | static_assert((CallingConv::ID)ZigLLVM_MSP430_INTR == llvm::CallingConv::MSP430_INTR, ""); | |
| 1340 | static_assert((CallingConv::ID)ZigLLVM_X86_ThisCall == llvm::CallingConv::X86_ThisCall, ""); | |
| 1341 | static_assert((CallingConv::ID)ZigLLVM_PTX_Kernel == llvm::CallingConv::PTX_Kernel, ""); | |
| 1342 | static_assert((CallingConv::ID)ZigLLVM_PTX_Device == llvm::CallingConv::PTX_Device, ""); | |
| 1343 | static_assert((CallingConv::ID)ZigLLVM_SPIR_FUNC == llvm::CallingConv::SPIR_FUNC, ""); | |
| 1344 | static_assert((CallingConv::ID)ZigLLVM_SPIR_KERNEL == llvm::CallingConv::SPIR_KERNEL, ""); | |
| 1345 | static_assert((CallingConv::ID)ZigLLVM_Intel_OCL_BI == llvm::CallingConv::Intel_OCL_BI, ""); | |
| 1346 | static_assert((CallingConv::ID)ZigLLVM_X86_64_SysV == llvm::CallingConv::X86_64_SysV, ""); | |
| 1347 | static_assert((CallingConv::ID)ZigLLVM_Win64 == llvm::CallingConv::Win64, ""); | |
| 1348 | static_assert((CallingConv::ID)ZigLLVM_X86_VectorCall == llvm::CallingConv::X86_VectorCall, ""); | |
| 1349 | static_assert((CallingConv::ID)ZigLLVM_HHVM == llvm::CallingConv::HHVM, ""); | |
| 1350 | static_assert((CallingConv::ID)ZigLLVM_HHVM_C == llvm::CallingConv::HHVM_C, ""); | |
| 1351 | static_assert((CallingConv::ID)ZigLLVM_X86_INTR == llvm::CallingConv::X86_INTR, ""); | |
| 1352 | static_assert((CallingConv::ID)ZigLLVM_AVR_INTR == llvm::CallingConv::AVR_INTR, ""); | |
| 1353 | static_assert((CallingConv::ID)ZigLLVM_AVR_SIGNAL == llvm::CallingConv::AVR_SIGNAL, ""); | |
| 1354 | static_assert((CallingConv::ID)ZigLLVM_AVR_BUILTIN == llvm::CallingConv::AVR_BUILTIN, ""); | |
| 1355 | static_assert((CallingConv::ID)ZigLLVM_AMDGPU_VS == llvm::CallingConv::AMDGPU_VS, ""); | |
| 1356 | static_assert((CallingConv::ID)ZigLLVM_AMDGPU_GS == llvm::CallingConv::AMDGPU_GS, ""); | |
| 1357 | static_assert((CallingConv::ID)ZigLLVM_AMDGPU_PS == llvm::CallingConv::AMDGPU_PS, ""); | |
| 1358 | static_assert((CallingConv::ID)ZigLLVM_AMDGPU_CS == llvm::CallingConv::AMDGPU_CS, ""); | |
| 1359 | static_assert((CallingConv::ID)ZigLLVM_AMDGPU_KERNEL == llvm::CallingConv::AMDGPU_KERNEL, ""); | |
| 1360 | static_assert((CallingConv::ID)ZigLLVM_X86_RegCall == llvm::CallingConv::X86_RegCall, ""); | |
| 1361 | static_assert((CallingConv::ID)ZigLLVM_AMDGPU_HS == llvm::CallingConv::AMDGPU_HS, ""); | |
| 1362 | static_assert((CallingConv::ID)ZigLLVM_MSP430_BUILTIN == llvm::CallingConv::MSP430_BUILTIN, ""); | |
| 1363 | static_assert((CallingConv::ID)ZigLLVM_AMDGPU_LS == llvm::CallingConv::AMDGPU_LS, ""); | |
| 1364 | static_assert((CallingConv::ID)ZigLLVM_AMDGPU_ES == llvm::CallingConv::AMDGPU_ES, ""); | |
| 1365 | static_assert((CallingConv::ID)ZigLLVM_AArch64_VectorCall == llvm::CallingConv::AArch64_VectorCall, ""); | |
| 1366 | static_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 |
| 64 | 64 | |
| 65 | 65 | ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref); |
| 66 | 66 | |
| 67 | enum 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 | ||
| 67 | 115 | enum ZigLLVM_CallAttr { |
| 68 | 116 | ZigLLVM_CallAttrAuto, |
| 69 | 117 | ZigLLVM_CallAttrNeverTail, |
| ... | ... | @@ -72,7 +120,7 @@ enum ZigLLVM_CallAttr { |
| 72 | 120 | ZigLLVM_CallAttrAlwaysInline, |
| 73 | 121 | }; |
| 74 | 122 | ZIG_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); | |
| 76 | 124 | |
| 77 | 125 | ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign, |
| 78 | 126 | LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size, bool isVolatile); |
| ... | ... | @@ -215,6 +263,7 @@ ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigne |
| 215 | 263 | ZIG_EXTERN_C void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state); |
| 216 | 264 | ZIG_EXTERN_C void ZigLLVMSetTailCall(LLVMValueRef Call); |
| 217 | 265 | ZIG_EXTERN_C void ZigLLVMFunctionSetPrefixData(LLVMValueRef fn, LLVMValueRef data); |
| 266 | ZIG_EXTERN_C void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, enum ZigLLVM_CallingConv cc); | |
| 218 | 267 | |
| 219 | 268 | ZIG_EXTERN_C void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value); |
| 220 | 269 | ZIG_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 { |
| 752 | 752 | \\ _ = @frame(); |
| 753 | 753 | \\} |
| 754 | 754 | , &[_][]const u8{ |
| 755 | "tmp.zig:1:1: error: function with calling convention 'ccc' cannot be async", | |
| 755 | "tmp.zig:1:1: error: function with calling convention 'C' cannot be async", | |
| 756 | 756 | "tmp.zig:5:9: note: @frame() causes function to be async", |
| 757 | 757 | }); |
| 758 | 758 | |
| ... | ... | @@ -765,7 +765,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 765 | 765 | \\ suspend; |
| 766 | 766 | \\} |
| 767 | 767 | , &[_][]const u8{ |
| 768 | "tmp.zig:1:1: error: function with calling convention 'ccc' cannot be async", | |
| 768 | "tmp.zig:1:1: error: function with calling convention 'C' cannot be async", | |
| 769 | 769 | "tmp.zig:3:18: note: await here is a suspend point", |
| 770 | 770 | }); |
| 771 | 771 | |
| ... | ... | @@ -843,7 +843,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 843 | 843 | \\ suspend; |
| 844 | 844 | \\} |
| 845 | 845 | , &[_][]const u8{ |
| 846 | "tmp.zig:1:1: error: function with calling convention 'ccc' cannot be async", | |
| 846 | "tmp.zig:1:1: error: function with calling convention 'C' cannot be async", | |
| 847 | 847 | "tmp.zig:2:8: note: async function call here", |
| 848 | 848 | "tmp.zig:5:8: note: async function call here", |
| 849 | 849 | "tmp.zig:8:5: note: suspends here", |
| ... | ... | @@ -1140,7 +1140,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1140 | 1140 | \\ while (true) {} |
| 1141 | 1141 | \\} |
| 1142 | 1142 | , &[_][]const u8{ |
| 1143 | "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn([]const u8,var)var'", | |
| 1143 | "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn([]const u8,var) var'", | |
| 1144 | 1144 | "note: only one of the functions is generic", |
| 1145 | 1145 | }); |
| 1146 | 1146 | |
| ... | ... | @@ -1362,7 +1362,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1362 | 1362 | \\ return 0; |
| 1363 | 1363 | \\} |
| 1364 | 1364 | , &[_][]const u8{ |
| 1365 | "tmp.zig:1:15: error: parameter of type 'var' not allowed in function with calling convention 'ccc'", | |
| 1365 | "tmp.zig:1:15: error: parameter of type 'var' not allowed in function with calling convention 'C'", | |
| 1366 | 1366 | }); |
| 1367 | 1367 | |
| 1368 | 1368 | cases.add("C pointer to c_void", |
| ... | ... | @@ -2187,7 +2187,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2187 | 2187 | \\ f(g); |
| 2188 | 2188 | \\} |
| 2189 | 2189 | , &[_][]const u8{ |
| 2190 | "tmp.zig:1:9: error: parameter of type 'fn(var)var' must be declared comptime", | |
| 2190 | "tmp.zig:1:9: error: parameter of type 'fn(var) var' must be declared comptime", | |
| 2191 | 2191 | }); |
| 2192 | 2192 | |
| 2193 | 2193 | cases.add("optional pointer to void in extern struct", |
| ... | ... | @@ -2859,7 +2859,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2859 | 2859 | \\const Foo = enum { A, B, C }; |
| 2860 | 2860 | \\export fn entry(foo: Foo) void { } |
| 2861 | 2861 | , &[_][]const u8{ |
| 2862 | "tmp.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'", | |
| 2862 | "tmp.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'", | |
| 2863 | 2863 | }); |
| 2864 | 2864 | |
| 2865 | 2865 | cases.add("function with non-extern non-packed struct parameter", |
| ... | ... | @@ -2870,7 +2870,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2870 | 2870 | \\}; |
| 2871 | 2871 | \\export fn entry(foo: Foo) void { } |
| 2872 | 2872 | , &[_][]const u8{ |
| 2873 | "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'", | |
| 2873 | "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'", | |
| 2874 | 2874 | }); |
| 2875 | 2875 | |
| 2876 | 2876 | cases.add("function with non-extern non-packed union parameter", |
| ... | ... | @@ -2881,7 +2881,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2881 | 2881 | \\}; |
| 2882 | 2882 | \\export fn entry(foo: Foo) void { } |
| 2883 | 2883 | , &[_][]const u8{ |
| 2884 | "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'", | |
| 2884 | "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'", | |
| 2885 | 2885 | }); |
| 2886 | 2886 | |
| 2887 | 2887 | cases.add("switch on enum with 1 field with no prongs", |
| ... | ... | @@ -2977,8 +2977,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2977 | 2977 | \\ bar(&{}); |
| 2978 | 2978 | \\} |
| 2979 | 2979 | , &[_][]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'", | |
| 2982 | 2982 | }); |
| 2983 | 2983 | |
| 2984 | 2984 | cases.add("implicit semicolon - block statement", |
| ... | ... | @@ -4552,7 +4552,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4552 | 4552 | \\ return x + y; |
| 4553 | 4553 | \\} |
| 4554 | 4554 | , &[_][]const u8{ |
| 4555 | "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'", | |
| 4555 | "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'", | |
| 4556 | 4556 | }); |
| 4557 | 4557 | |
| 4558 | 4558 | cases.add("extern function with comptime parameter", |
| ... | ... | @@ -4562,7 +4562,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4562 | 4562 | \\} |
| 4563 | 4563 | \\export fn entry() usize { return @sizeOf(@TypeOf(f)); } |
| 4564 | 4564 | , &[_][]const u8{ |
| 4565 | "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'", | |
| 4565 | "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'", | |
| 4566 | 4566 | }); |
| 4567 | 4567 | |
| 4568 | 4568 | cases.add("convert fixed size array to slice with invalid size", |
| ... | ... | @@ -6303,7 +6303,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 6303 | 6303 | \\ _ = @TypeOf(generic).ReturnType; |
| 6304 | 6304 | \\} |
| 6305 | 6305 | , &[_][]const u8{ |
| 6306 | "tmp.zig:3:25: error: ReturnType has not been resolved because 'fn(var)var' is generic", | |
| 6306 | "tmp.zig:3:25: error: ReturnType has not been resolved because 'fn(var) var' is generic", | |
| 6307 | 6307 | }); |
| 6308 | 6308 | |
| 6309 | 6309 | cases.add("getting @ArgType of generic function", |
| ... | ... | @@ -6312,7 +6312,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 6312 | 6312 | \\ _ = @ArgType(@TypeOf(generic), 0); |
| 6313 | 6313 | \\} |
| 6314 | 6314 | , &[_][]const u8{ |
| 6315 | "tmp.zig:3:36: error: @ArgType could not resolve the type of arg 0 because 'fn(var)var' is generic", | |
| 6315 | "tmp.zig:3:36: error: @ArgType could not resolve the type of arg 0 because 'fn(var) var' is generic", | |
| 6316 | 6316 | }); |
| 6317 | 6317 | |
| 6318 | 6318 | cases.add("unsupported modifier at start of asm output constraint", |
test/src/translate_c.zig+14| ... | ... | @@ -19,6 +19,7 @@ pub const TranslateCContext = struct { |
| 19 | 19 | sources: ArrayList(SourceFile), |
| 20 | 20 | expected_lines: ArrayList([]const u8), |
| 21 | 21 | allow_warnings: bool, |
| 22 | target: std.Target = .Native, | |
| 22 | 23 | |
| 23 | 24 | const SourceFile = struct { |
| 24 | 25 | filename: []const u8, |
| ... | ... | @@ -71,6 +72,18 @@ pub const TranslateCContext = struct { |
| 71 | 72 | self.addCase(tc); |
| 72 | 73 | } |
| 73 | 74 | |
| 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 | ||
| 74 | 87 | pub fn addAllowWarnings( |
| 75 | 88 | self: *TranslateCContext, |
| 76 | 89 | name: []const u8, |
| ... | ... | @@ -101,6 +114,7 @@ pub const TranslateCContext = struct { |
| 101 | 114 | .basename = case.sources.toSliceConst()[0].filename, |
| 102 | 115 | }, |
| 103 | 116 | }); |
| 117 | translate_c.setTarget(case.target); | |
| 104 | 118 | |
| 105 | 119 | const check_file = translate_c.addCheckFile(case.expected_lines.toSliceConst()); |
| 106 | 120 |
test/stage1/behavior/type_info.zig+2-2| ... | ... | @@ -202,7 +202,7 @@ fn testUnion() void { |
| 202 | 202 | expect(typeinfo_info.Union.fields[4].enum_field != null); |
| 203 | 203 | expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4); |
| 204 | 204 | expect(typeinfo_info.Union.fields[4].field_type == @TypeOf(@typeInfo(u8).Int)); |
| 205 | expect(typeinfo_info.Union.decls.len == 21); | |
| 205 | expect(typeinfo_info.Union.decls.len == 20); | |
| 206 | 206 | |
| 207 | 207 | const TestNoTagUnion = union { |
| 208 | 208 | Foo: void, |
| ... | ... | @@ -266,7 +266,7 @@ test "type info: function type info" { |
| 266 | 266 | fn testFunction() void { |
| 267 | 267 | const fn_info = @typeInfo(@TypeOf(foo)); |
| 268 | 268 | expect(@as(TypeId, fn_info) == TypeId.Fn); |
| 269 | expect(fn_info.Fn.calling_convention == TypeInfo.CallingConvention.Unspecified); | |
| 269 | expect(fn_info.Fn.calling_convention == .Unspecified); | |
| 270 | 270 | expect(fn_info.Fn.is_generic); |
| 271 | 271 | expect(fn_info.Fn.args.len == 2); |
| 272 | 272 | expect(fn_info.Fn.is_var_args); |
test/translate_c.zig+41-7| ... | ... | @@ -205,7 +205,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 205 | 205 | \\static void bar(void) {} |
| 206 | 206 | , &[_][]const u8{ |
| 207 | 207 | \\pub export fn foo() void {} |
| 208 | \\pub fn bar() void {} | |
| 208 | \\pub fn bar() callconv(.C) void {} | |
| 209 | 209 | }); |
| 210 | 210 | |
| 211 | 211 | cases.add("typedef void", |
| ... | ... | @@ -957,6 +957,40 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 957 | 957 | \\pub const fn1 = ?extern fn (u8) void; |
| 958 | 958 | }); |
| 959 | 959 | |
| 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 | ||
| 960 | 994 | cases.add("Parameterless function prototypes", |
| 961 | 995 | \\void a() {} |
| 962 | 996 | \\void b(void) {} |
| ... | ... | @@ -985,7 +1019,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 985 | 1019 | \\ char *arr1[10] ={0}; |
| 986 | 1020 | \\} |
| 987 | 1021 | , &[_][]const u8{ |
| 988 | \\pub fn foo() void { | |
| 1022 | \\pub fn foo() callconv(.C) void { | |
| 989 | 1023 | \\ var arr: [10]u8 = .{ |
| 990 | 1024 | \\ @bitCast(u8, @truncate(i8, @as(c_int, 1))), |
| 991 | 1025 | \\ } ++ .{0} ** 9; |
| ... | ... | @@ -2262,7 +2296,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 2262 | 2296 | \\ baz(); |
| 2263 | 2297 | \\} |
| 2264 | 2298 | , &[_][]const u8{ |
| 2265 | \\pub fn bar() void {} | |
| 2299 | \\pub fn bar() callconv(.C) void {} | |
| 2266 | 2300 | \\pub export fn foo(arg_baz: ?extern fn () [*c]c_int) void { |
| 2267 | 2301 | \\ var baz = arg_baz; |
| 2268 | 2302 | \\ bar(); |
| ... | ... | @@ -2321,7 +2355,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 2321 | 2355 | \\ do {} while (0); |
| 2322 | 2356 | \\} |
| 2323 | 2357 | , &[_][]const u8{ |
| 2324 | \\pub fn foo() void { | |
| 2358 | \\pub fn foo() callconv(.C) void { | |
| 2325 | 2359 | \\ if (@as(c_int, 1) != 0) while (true) { |
| 2326 | 2360 | \\ if (!(@as(c_int, 0) != 0)) break; |
| 2327 | 2361 | \\ }; |
| ... | ... | @@ -2413,9 +2447,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 2413 | 2447 | \\void c(void) {} |
| 2414 | 2448 | \\static void foo() {} |
| 2415 | 2449 | , &[_][]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 {} | |
| 2418 | 2452 | \\pub export fn c() void {} |
| 2419 | \\pub fn foo() void {} | |
| 2453 | \\pub fn foo() callconv(.C) void {} | |
| 2420 | 2454 | }); |
| 2421 | 2455 | } |