diff --git a/doc/docgen.zig b/doc/docgen.zig index 83855b3b50..0218f50419 100644 --- a/doc/docgen.zig +++ b/doc/docgen.zig @@ -818,6 +818,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok .Keyword_resume, .Keyword_return, .Keyword_linksection, + .Keyword_callconv, .Keyword_stdcallcc, .Keyword_struct, .Keyword_suspend, diff --git a/doc/langref.html.in b/doc/langref.html.in index e16a95295c..c39d15de9d 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -2829,7 +2829,7 @@ test "@tagName" {

By default, enums are not guaranteed to be compatible with the C ABI:

- {#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'ccc'#} + {#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'C'#} const Foo = enum { A, B, C }; export fn entry(foo: Foo) void { } {#code_end#} @@ -3974,7 +3974,7 @@ test "noreturn" {

Another use case for {#syntax#}noreturn{#endsyntax#} is the {#syntax#}exit{#endsyntax#} function:

{#code_begin|test#} {#target_windows#} -pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: c_uint) noreturn; +pub extern "kernel32" fn ExitProcess(exit_code: c_uint) callconv(.Stdcall) noreturn; test "foo" { const value = bar() catch ExitProcess(1); @@ -4008,8 +4008,8 @@ export fn sub(a: i8, b: i8) i8 { return a - b; } // The extern specifier is used to declare a function that will be resolved // at link time, when linking statically, or at runtime, when linking // dynamically. -// The stdcallcc specifier changes the calling convention of the function. -extern "kernel32" stdcallcc fn ExitProcess(exit_code: u32) noreturn; +// The callconv specifier changes the calling convention of the function. +extern "kernel32" fn ExitProcess(exit_code: u32) callconv(.Stdcall) noreturn; extern "c" fn atan2(a: f64, b: f64) f64; // The @setCold builtin tells the optimizer that a function is rarely called. @@ -4018,9 +4018,9 @@ fn abort() noreturn { while (true) {} } -// The nakedcc specifier makes a function not have any function prologue or epilogue. +// The naked calling convention makes a function not have any function prologue or epilogue. // This can be useful when integrating with assembly. -nakedcc fn _start() noreturn { +fn _start() callconv(.Naked) noreturn { abort(); } @@ -7735,7 +7735,7 @@ const Derp = @OpaqueType(); const Wat = @OpaqueType(); extern fn bar(d: *Derp) void; -export fn foo(w: *Wat) void { +fn foo(w: *Wat) callconv(.C) void { bar(w); } @@ -10382,9 +10382,7 @@ LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN # Fn specific FnCC - <- KEYWORD_nakedcc - / KEYWORD_stdcallcc - / KEYWORD_extern + <- KEYWORD_extern / KEYWORD_async ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType @@ -10648,7 +10646,6 @@ KEYWORD_fn <- 'fn' end_of_word KEYWORD_for <- 'for' end_of_word KEYWORD_if <- 'if' end_of_word KEYWORD_inline <- 'inline' end_of_word -KEYWORD_nakedcc <- 'nakedcc' end_of_word KEYWORD_noalias <- 'noalias' end_of_word KEYWORD_null <- 'null' end_of_word KEYWORD_or <- 'or' end_of_word @@ -10659,7 +10656,6 @@ KEYWORD_pub <- 'pub' end_of_word KEYWORD_resume <- 'resume' end_of_word KEYWORD_return <- 'return' end_of_word KEYWORD_linksection <- 'linksection' end_of_word -KEYWORD_stdcallcc <- 'stdcallcc' end_of_word KEYWORD_struct <- 'struct' end_of_word KEYWORD_suspend <- 'suspend' end_of_word KEYWORD_switch <- 'switch' end_of_word @@ -10681,10 +10677,10 @@ keyword <- KEYWORD_align / KEYWORD_and / KEYWORD_allowzero / KEYWORD_asm / KEYWORD_defer / KEYWORD_else / KEYWORD_enum / KEYWORD_errdefer / KEYWORD_error / KEYWORD_export / KEYWORD_extern / KEYWORD_false / KEYWORD_fn / KEYWORD_for / KEYWORD_if / KEYWORD_inline - / KEYWORD_nakedcc / KEYWORD_noalias / KEYWORD_null / KEYWORD_or + / KEYWORD_noalias / KEYWORD_null / KEYWORD_or / KEYWORD_orelse / KEYWORD_packed / KEYWORD_promise / KEYWORD_pub / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection - / KEYWORD_stdcallcc / KEYWORD_struct / KEYWORD_suspend + / KEYWORD_struct / KEYWORD_suspend / KEYWORD_switch / KEYWORD_test / KEYWORD_threadlocal / KEYWORD_true / KEYWORD_try / KEYWORD_undefined / KEYWORD_union / KEYWORD_unreachable / KEYWORD_usingnamespace / KEYWORD_var / KEYWORD_volatile / KEYWORD_while diff --git a/lib/std/build/translate_c.zig b/lib/std/build/translate_c.zig index 7574dbe331..010bb35abb 100644 --- a/lib/std/build/translate_c.zig +++ b/lib/std/build/translate_c.zig @@ -14,6 +14,7 @@ pub const TranslateCStep = struct { source: build.FileSource, output_dir: ?[]const u8, out_basename: []const u8, + target: std.Target = .Native, pub fn create(builder: *Builder, source: build.FileSource) *TranslateCStep { const self = builder.allocator.create(TranslateCStep) catch unreachable; @@ -38,6 +39,10 @@ pub const TranslateCStep = struct { ) catch unreachable; } + pub fn setTarget(self: *TranslateCStep, target: std.Target) void { + self.target = target; + } + /// Creates a step to build an executable from the translated source. pub fn addExecutable(self: *TranslateCStep) *LibExeObjStep { return self.builder.addExecutableSource("translated_c", @as(build.FileSource, .{ .translate_c = self })); @@ -50,16 +55,25 @@ pub const TranslateCStep = struct { fn make(step: *Step) !void { const self = @fieldParentPtr(TranslateCStep, "step", step); - const argv = [_][]const u8{ - self.builder.zig_exe, - "translate-c", - "-lc", - "--cache", - "on", - self.source.getPath(self.builder), - }; + var argv_list = std.ArrayList([]const u8).init(self.builder.allocator); + try argv_list.append(self.builder.zig_exe); + try argv_list.append("translate-c"); + try argv_list.append("-lc"); - const output_path_nl = try self.builder.exec(&argv); + try argv_list.append("--cache"); + try argv_list.append("on"); + + switch (self.target) { + .Native => {}, + .Cross => { + try argv_list.append("-target"); + try argv_list.append(try self.target.zigTriple(self.builder.allocator)); + }, + } + + try argv_list.append(self.source.getPath(self.builder)); + + const output_path_nl = try self.builder.exec(argv_list.toSliceConst()); const output_path = mem.trimRight(u8, output_path_nl, "\r\n"); self.out_basename = fs.path.basename(output_path); diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index 36767494e5..56414ee1b0 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -91,6 +91,25 @@ pub const Mode = enum { ReleaseSmall, }; +/// This data structure is used by the Zig language code generation and +/// therefore must be kept in sync with the compiler implementation. +pub const CallingConvention = enum { + Unspecified, + C, + Cold, + Naked, + Async, + Interrupt, + Signal, + Stdcall, + Fastcall, + Vectorcall, + Thiscall, + APCS, + AAPCS, + AAPCSVFP, +}; + pub const TypeId = @TagType(TypeInfo); /// This data structure is used by the Zig language code generation and @@ -253,17 +272,6 @@ pub const TypeInfo = union(enum) { decls: []Declaration, }; - /// This data structure is used by the Zig language code generation and - /// therefore must be kept in sync with the compiler implementation. - pub const CallingConvention = enum { - Unspecified, - C, - Cold, - Naked, - Stdcall, - Async, - }; - /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. pub const FnArg = struct { @@ -314,7 +322,6 @@ pub const TypeInfo = union(enum) { pub const FnDecl = struct { fn_type: type, inline_type: Inline, - calling_convention: CallingConvention, is_var_args: bool, is_extern: bool, is_export: bool, diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 76685666ad..94f81908da 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -2428,7 +2428,7 @@ fn resetSegfaultHandler() void { os.sigaction(os.SIGILL, &act, null); } -extern fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *const c_void) noreturn { +fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *const c_void) callconv(.C) noreturn { // Reset to the default handler so that if a segfault happens in this handler it will crash // the process. Also when this handler returns, the original instruction will be repeated // and the resulting segfault will crash the process rather than continually dump stack traces. @@ -2475,7 +2475,7 @@ extern fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *con os.abort(); } -stdcallcc fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) c_long { +fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) callconv(.Stdcall) c_long { const exception_address = @ptrToInt(info.ExceptionRecord.ExceptionAddress); switch (info.ExceptionRecord.ExceptionCode) { windows.EXCEPTION_DATATYPE_MISALIGNMENT => panicExtra(null, exception_address, "Unaligned Memory Access", .{}), diff --git a/lib/std/json/test.zig b/lib/std/json/test.zig index 2dc5b860ed..5cc069bda3 100644 --- a/lib/std/json/test.zig +++ b/lib/std/json/test.zig @@ -22,7 +22,7 @@ fn err(comptime s: []const u8) void { const allocator = &std.heap.FixedBufferAllocator.init(&mem_buffer).allocator; var p = std.json.Parser.init(allocator, false); - if(p.parse(s)) |_| { + if (p.parse(s)) |_| { unreachable; } else |_| {} } @@ -33,7 +33,7 @@ fn any(comptime s: []const u8) void { var mem_buffer: [1024 * 20]u8 = undefined; const allocator = &std.heap.FixedBufferAllocator.init(&mem_buffer).allocator; var p = std.json.Parser.init(allocator, false); - + _ = p.parse(s) catch {}; } @@ -44,7 +44,7 @@ fn anyStreamingErrNonStreaming(comptime s: []const u8) void { const allocator = &std.heap.FixedBufferAllocator.init(&mem_buffer).allocator; var p = std.json.Parser.init(allocator, false); - if(p.parse(s)) |_| { + if (p.parse(s)) |_| { unreachable; } else |_| {} } @@ -1742,9 +1742,9 @@ test "i_number_double_huge_neg_exp" { test "i_number_huge_exp" { return error.SkipZigTest; // FIXME Integer overflow in parseFloat -// any( -// \\[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006] -// ); + // any( + // \\[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006] + // ); } test "i_number_neg_int_huge_exp" { diff --git a/lib/std/math/sqrt.zig b/lib/std/math/sqrt.zig index 493e2cacf6..800a7574ae 100644 --- a/lib/std/math/sqrt.zig +++ b/lib/std/math/sqrt.zig @@ -70,4 +70,3 @@ pub fn Sqrt(comptime T: type) type { else => T, }; } - diff --git a/lib/std/mutex.zig b/lib/std/mutex.zig index d932205c5c..7fbe4fde18 100644 --- a/lib/std/mutex.zig +++ b/lib/std/mutex.zig @@ -17,7 +17,7 @@ const ResetEvent = std.ResetEvent; /// Example usage: /// var m = Mutex.init(); /// defer m.deinit(); -/// +/// /// const lock = m.acquire(); /// defer lock.release(); /// ... critical code @@ -73,8 +73,8 @@ pub const Mutex = if (builtin.single_threaded) return self.tryAcquire() orelse @panic("deadlock detected"); } } -else if (builtin.os == .windows) - // https://locklessinc.com/articles/keyed_events/ +else if (builtin.os == .windows) +// https://locklessinc.com/articles/keyed_events/ extern union { locked: u8, waiters: u32, @@ -122,8 +122,8 @@ else if (builtin.os == .windows) return Held{ .mutex = self }; } - // otherwise, try and update the waiting count. - // then unset the WAKE bit so that another unlocker can wake up a thread. + // otherwise, try and update the waiting count. + // then unset the WAKE bit so that another unlocker can wake up a thread. } else if (@cmpxchgWeak(u32, &self.waiters, waiters, (waiters + WAIT) | 1, .Monotonic, .Monotonic) == null) { const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null); assert(rc == 0); @@ -143,7 +143,7 @@ else if (builtin.os == .windows) while (true) : (SpinLock.loopHint(1)) { const waiters = @atomicLoad(u32, &self.mutex.waiters, .Monotonic); - + // no one is waiting if (waiters < WAIT) return; // someone grabbed the lock and will do the wake instead @@ -155,14 +155,14 @@ else if (builtin.os == .windows) if (@cmpxchgWeak(u32, &self.mutex.waiters, waiters, waiters - WAIT + WAKE, .Release, .Monotonic) == null) { const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null); assert(rc == 0); - return; + return; } } } }; } else if (builtin.link_libc or builtin.os == .linux) - // stack-based version of https://github.com/Amanieu/parking_lot/blob/master/core/src/word_lock.rs +// stack-based version of https://github.com/Amanieu/parking_lot/blob/master/core/src/word_lock.rs struct { state: usize, @@ -195,8 +195,8 @@ else if (builtin.link_libc or builtin.os == .linux) pub fn acquire(self: *Mutex) Held { return self.tryAcquire() orelse { - self.acquireSlow(); - return Held{ .mutex = self }; + self.acquireSlow(); + return Held{ .mutex = self }; }; } @@ -265,7 +265,7 @@ else if (builtin.link_libc or builtin.os == .linux) fn releaseSlow(self: *Mutex) void { @setCold(true); - + // try and lock the LFIO queue to pop a node off, // stopping altogether if its already locked or the queue is empty var state = @atomicLoad(usize, &self.state, .Monotonic); @@ -293,9 +293,10 @@ else if (builtin.link_libc or builtin.os == .linux) } } -// for platforms without a known OS blocking -// primitive, default to SpinLock for correctness -else SpinLock; + // for platforms without a known OS blocking + // primitive, default to SpinLock for correctness +else + SpinLock; const TestContext = struct { mutex: *Mutex, diff --git a/lib/std/net.zig b/lib/std/net.zig index d4e68b2e17..47ce95c99f 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -451,11 +451,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !* .next = null, }; var res: *os.addrinfo = undefined; - switch (os.system.getaddrinfo( - name_c.ptr, - @ptrCast([*:0]const u8, port_c.ptr), - &hints, - &res)) { + switch (os.system.getaddrinfo(name_c.ptr, @ptrCast([*:0]const u8, port_c.ptr), &hints, &res)) { 0 => {}, c.EAI_ADDRFAMILY => return error.HostLacksNetworkAddresses, c.EAI_AGAIN => return error.TemporaryNameServerFailure, diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index efba40bb8d..94fad4cfb7 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -512,7 +512,7 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) usize { return syscall2(SYS_clock_gettime, @bitCast(usize, @as(isize, clk_id)), @ptrToInt(tp)); } -extern fn init_vdso_clock_gettime(clk: i32, ts: *timespec) usize { +fn init_vdso_clock_gettime(clk: i32, ts: *timespec) callconv(.C) usize { const ptr = @intToPtr(?*const c_void, vdso.lookup(VDSO_CGT_VER, VDSO_CGT_SYM)); // Note that we may not have a VDSO at all, update the stub address anyway // so that clock_gettime will fall back on the good old (and slow) syscall diff --git a/lib/std/os/linux/arm-eabi.zig b/lib/std/os/linux/arm-eabi.zig index c457e10beb..2e55abd688 100644 --- a/lib/std/os/linux/arm-eabi.zig +++ b/lib/std/os/linux/arm-eabi.zig @@ -91,13 +91,13 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, a // LLVM calls this when the read-tp-hard feature is set to false. Currently, there is no way to pass // that to llvm via zig, see https://github.com/ziglang/zig/issues/2883. // LLVM expects libc to provide this function as __aeabi_read_tp, so it is exported if needed from special/c.zig. -pub extern fn getThreadPointer() usize { +pub fn getThreadPointer() callconv(.C) usize { return asm volatile ("mrc p15, 0, %[ret], c13, c0, 3" : [ret] "=r" (-> usize) ); } -pub nakedcc fn restore() void { +pub fn restore() callconv(.Naked) void { return asm volatile ("svc #0" : : [number] "{r7}" (@as(usize, SYS_sigreturn)) @@ -105,7 +105,7 @@ pub nakedcc fn restore() void { ); } -pub nakedcc fn restore_rt() void { +pub fn restore_rt() callconv(.Naked) void { return asm volatile ("svc #0" : : [number] "{r7}" (@as(usize, SYS_rt_sigreturn)) diff --git a/lib/std/os/linux/arm64.zig b/lib/std/os/linux/arm64.zig index ac2bb3bfdf..f565bea489 100644 --- a/lib/std/os/linux/arm64.zig +++ b/lib/std/os/linux/arm64.zig @@ -90,7 +90,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, a pub const restore = restore_rt; -pub nakedcc fn restore_rt() void { +pub fn restore_rt() callconv(.Naked) void { return asm volatile ("svc #0" : : [number] "{x8}" (@as(usize, SYS_rt_sigreturn)) diff --git a/lib/std/os/linux/i386.zig b/lib/std/os/linux/i386.zig index 3345f9904d..7652ece43e 100644 --- a/lib/std/os/linux/i386.zig +++ b/lib/std/os/linux/i386.zig @@ -102,7 +102,7 @@ pub fn socketcall(call: usize, args: [*]usize) usize { /// This matches the libc clone function. pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; -pub nakedcc fn restore() void { +pub fn restore() callconv(.Naked) void { return asm volatile ("int $0x80" : : [number] "{eax}" (@as(usize, SYS_sigreturn)) @@ -110,7 +110,7 @@ pub nakedcc fn restore() void { ); } -pub nakedcc fn restore_rt() void { +pub fn restore_rt() callconv(.Naked) void { return asm volatile ("int $0x80" : : [number] "{eax}" (@as(usize, SYS_rt_sigreturn)) diff --git a/lib/std/os/linux/mipsel.zig b/lib/std/os/linux/mipsel.zig index 60408c1e84..5193133f6c 100644 --- a/lib/std/os/linux/mipsel.zig +++ b/lib/std/os/linux/mipsel.zig @@ -144,7 +144,7 @@ pub fn syscall6( /// This matches the libc clone function. pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; -pub nakedcc fn restore() void { +pub fn restore() callconv(.Naked) void { return asm volatile ("syscall" : : [number] "{$2}" (@as(usize, SYS_sigreturn)) @@ -152,7 +152,7 @@ pub nakedcc fn restore() void { ); } -pub nakedcc fn restore_rt() void { +pub fn restore_rt() callconv(.Naked) void { return asm volatile ("syscall" : : [number] "{$2}" (@as(usize, SYS_rt_sigreturn)) diff --git a/lib/std/os/linux/riscv64.zig b/lib/std/os/linux/riscv64.zig index b7c59a9039..2259dad78e 100644 --- a/lib/std/os/linux/riscv64.zig +++ b/lib/std/os/linux/riscv64.zig @@ -89,7 +89,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, a pub const restore = restore_rt; -pub nakedcc fn restore_rt() void { +pub fn restore_rt() callconv(.Naked) void { return asm volatile ("ecall" : : [number] "{x17}" (@as(usize, SYS_rt_sigreturn)) diff --git a/lib/std/os/linux/x86_64.zig b/lib/std/os/linux/x86_64.zig index d037b3c6ae..d6067f9b18 100644 --- a/lib/std/os/linux/x86_64.zig +++ b/lib/std/os/linux/x86_64.zig @@ -90,7 +90,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: usize, pub const restore = restore_rt; -pub nakedcc fn restore_rt() void { +pub fn restore_rt() callconv(.Naked) void { return asm volatile ("syscall" : : [number] "{rax}" (@as(usize, SYS_rt_sigreturn)) diff --git a/lib/std/os/test.zig b/lib/std/os/test.zig index 09e8c24899..1e51dd6f82 100644 --- a/lib/std/os/test.zig +++ b/lib/std/os/test.zig @@ -166,7 +166,7 @@ test "sigaltstack" { // analyzed const dl_phdr_info = if (@hasDecl(os, "dl_phdr_info")) os.dl_phdr_info else c_void; -export fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) i32 { +fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) callconv(.C) i32 { if (builtin.os == .windows or builtin.os == .wasi or builtin.os == .macosx) return 0; diff --git a/lib/std/os/uefi/protocols/simple_text_input_protocol.zig b/lib/std/os/uefi/protocols/simple_text_input_protocol.zig index e1c5f6446f..b56ff728ef 100644 --- a/lib/std/os/uefi/protocols/simple_text_input_protocol.zig +++ b/lib/std/os/uefi/protocols/simple_text_input_protocol.zig @@ -27,4 +27,3 @@ pub const SimpleTextInputProtocol = extern struct { .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b }, }; }; - diff --git a/lib/std/os/windows/advapi32.zig b/lib/std/os/windows/advapi32.zig index 940f10994c..6364c5bddb 100644 --- a/lib/std/os/windows/advapi32.zig +++ b/lib/std/os/windows/advapi32.zig @@ -1,23 +1,23 @@ usingnamespace @import("bits.zig"); -pub extern "advapi32" stdcallcc fn RegOpenKeyExW( +pub extern "advapi32" fn RegOpenKeyExW( hKey: HKEY, lpSubKey: LPCWSTR, ulOptions: DWORD, samDesired: REGSAM, phkResult: *HKEY, -) LSTATUS; +) callconv(.Stdcall) LSTATUS; -pub extern "advapi32" stdcallcc fn RegQueryValueExW( +pub extern "advapi32" fn RegQueryValueExW( hKey: HKEY, lpValueName: LPCWSTR, lpReserved: LPDWORD, lpType: LPDWORD, lpData: LPBYTE, lpcbData: LPDWORD, -) LSTATUS; +) callconv(.Stdcall) LSTATUS; // RtlGenRandom is known as SystemFunction036 under advapi32 // http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx */ -pub extern "advapi32" stdcallcc fn SystemFunction036(output: [*]u8, length: ULONG) BOOL; +pub extern "advapi32" fn SystemFunction036(output: [*]u8, length: ULONG) callconv(.Stdcall) BOOL; pub const RtlGenRandom = SystemFunction036; diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig index def987bd23..7d87ae075a 100644 --- a/lib/std/os/windows/bits.zig +++ b/lib/std/os/windows/bits.zig @@ -892,7 +892,7 @@ pub const EXCEPTION_POINTERS = extern struct { ContextRecord: *c_void, }; -pub const VECTORED_EXCEPTION_HANDLER = stdcallcc fn (ExceptionInfo: *EXCEPTION_POINTERS) c_long; +pub const VECTORED_EXCEPTION_HANDLER = fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(.Stdcall) c_long; pub const OBJECT_ATTRIBUTES = extern struct { Length: ULONG, diff --git a/lib/std/os/windows/kernel32.zig b/lib/std/os/windows/kernel32.zig index 33e56abce1..1af68f4abd 100644 --- a/lib/std/os/windows/kernel32.zig +++ b/lib/std/os/windows/kernel32.zig @@ -1,22 +1,22 @@ usingnamespace @import("bits.zig"); -pub extern "kernel32" stdcallcc fn AddVectoredExceptionHandler(First: c_ulong, Handler: ?VECTORED_EXCEPTION_HANDLER) ?*c_void; -pub extern "kernel32" stdcallcc fn RemoveVectoredExceptionHandler(Handle: HANDLE) c_ulong; +pub extern "kernel32" fn AddVectoredExceptionHandler(First: c_ulong, Handler: ?VECTORED_EXCEPTION_HANDLER) callconv(.Stdcall) ?*c_void; +pub extern "kernel32" fn RemoveVectoredExceptionHandler(Handle: HANDLE) callconv(.Stdcall) c_ulong; -pub extern "kernel32" stdcallcc fn CancelIoEx(hFile: HANDLE, lpOverlapped: LPOVERLAPPED) BOOL; +pub extern "kernel32" fn CancelIoEx(hFile: HANDLE, lpOverlapped: LPOVERLAPPED) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) BOOL; +pub extern "kernel32" fn CloseHandle(hObject: HANDLE) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn CreateDirectoryW(lpPathName: [*]const u16, lpSecurityAttributes: ?*SECURITY_ATTRIBUTES) BOOL; +pub extern "kernel32" fn CreateDirectoryW(lpPathName: [*]const u16, lpSecurityAttributes: ?*SECURITY_ATTRIBUTES) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn CreateEventExW( +pub extern "kernel32" fn CreateEventExW( lpEventAttributes: ?*SECURITY_ATTRIBUTES, lpName: [*:0]const u16, dwFlags: DWORD, dwDesiredAccess: DWORD, -) ?HANDLE; +) callconv(.Stdcall) ?HANDLE; -pub extern "kernel32" stdcallcc fn CreateFileW( +pub extern "kernel32" fn CreateFileW( lpFileName: [*]const u16, // TODO null terminated pointer type dwDesiredAccess: DWORD, dwShareMode: DWORD, @@ -24,16 +24,16 @@ pub extern "kernel32" stdcallcc fn CreateFileW( dwCreationDisposition: DWORD, dwFlagsAndAttributes: DWORD, hTemplateFile: ?HANDLE, -) HANDLE; +) callconv(.Stdcall) HANDLE; -pub extern "kernel32" stdcallcc fn CreatePipe( +pub extern "kernel32" fn CreatePipe( hReadPipe: *HANDLE, hWritePipe: *HANDLE, lpPipeAttributes: *const SECURITY_ATTRIBUTES, nSize: DWORD, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn CreateProcessW( +pub extern "kernel32" fn CreateProcessW( lpApplicationName: ?LPWSTR, lpCommandLine: LPWSTR, lpProcessAttributes: ?*SECURITY_ATTRIBUTES, @@ -44,15 +44,15 @@ pub extern "kernel32" stdcallcc fn CreateProcessW( lpCurrentDirectory: ?LPWSTR, lpStartupInfo: *STARTUPINFOW, lpProcessInformation: *PROCESS_INFORMATION, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn CreateSymbolicLinkW(lpSymlinkFileName: [*]const u16, lpTargetFileName: [*]const u16, dwFlags: DWORD) BOOLEAN; +pub extern "kernel32" fn CreateSymbolicLinkW(lpSymlinkFileName: [*]const u16, lpTargetFileName: [*]const u16, dwFlags: DWORD) callconv(.Stdcall) BOOLEAN; -pub extern "kernel32" stdcallcc fn CreateIoCompletionPort(FileHandle: HANDLE, ExistingCompletionPort: ?HANDLE, CompletionKey: ULONG_PTR, NumberOfConcurrentThreads: DWORD) ?HANDLE; +pub extern "kernel32" fn CreateIoCompletionPort(FileHandle: HANDLE, ExistingCompletionPort: ?HANDLE, CompletionKey: ULONG_PTR, NumberOfConcurrentThreads: DWORD) callconv(.Stdcall) ?HANDLE; -pub extern "kernel32" stdcallcc fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) ?HANDLE; +pub extern "kernel32" fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) callconv(.Stdcall) ?HANDLE; -pub extern "kernel32" stdcallcc fn DeviceIoControl( +pub extern "kernel32" fn DeviceIoControl( h: HANDLE, dwIoControlCode: DWORD, lpInBuffer: ?*const c_void, @@ -61,107 +61,107 @@ pub extern "kernel32" stdcallcc fn DeviceIoControl( nOutBufferSize: DWORD, lpBytesReturned: ?*DWORD, lpOverlapped: ?*OVERLAPPED, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn DeleteFileW(lpFileName: [*]const u16) BOOL; +pub extern "kernel32" fn DeleteFileW(lpFileName: [*]const u16) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn DuplicateHandle(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE, hTargetProcessHandle: HANDLE, lpTargetHandle: *HANDLE, dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwOptions: DWORD) BOOL; +pub extern "kernel32" fn DuplicateHandle(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE, hTargetProcessHandle: HANDLE, lpTargetHandle: *HANDLE, dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwOptions: DWORD) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: UINT) noreturn; +pub extern "kernel32" fn ExitProcess(exit_code: UINT) callconv(.Stdcall) noreturn; -pub extern "kernel32" stdcallcc fn FindFirstFileW(lpFileName: [*]const u16, lpFindFileData: *WIN32_FIND_DATAW) HANDLE; -pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL; -pub extern "kernel32" stdcallcc fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) BOOL; +pub extern "kernel32" fn FindFirstFileW(lpFileName: [*]const u16, lpFindFileData: *WIN32_FIND_DATAW) callconv(.Stdcall) HANDLE; +pub extern "kernel32" fn FindClose(hFindFile: HANDLE) callconv(.Stdcall) BOOL; +pub extern "kernel32" fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn FormatMessageW(dwFlags: DWORD, lpSource: ?LPVOID, dwMessageId: DWORD, dwLanguageId: DWORD, lpBuffer: LPWSTR, nSize: DWORD, Arguments: ?*va_list) DWORD; +pub extern "kernel32" fn FormatMessageW(dwFlags: DWORD, lpSource: ?LPVOID, dwMessageId: DWORD, dwLanguageId: DWORD, lpBuffer: LPWSTR, nSize: DWORD, Arguments: ?*va_list) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsW(penv: [*]u16) BOOL; +pub extern "kernel32" fn FreeEnvironmentStringsW(penv: [*]u16) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR; +pub extern "kernel32" fn GetCommandLineA() callconv(.Stdcall) LPSTR; -pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: *DWORD) BOOL; +pub extern "kernel32" fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: *DWORD) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetConsoleScreenBufferInfo(hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: *CONSOLE_SCREEN_BUFFER_INFO) BOOL; +pub extern "kernel32" fn GetConsoleScreenBufferInfo(hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: *CONSOLE_SCREEN_BUFFER_INFO) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: ?[*]WCHAR) DWORD; +pub extern "kernel32" fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: ?[*]WCHAR) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn GetCurrentThread() HANDLE; -pub extern "kernel32" stdcallcc fn GetCurrentThreadId() DWORD; +pub extern "kernel32" fn GetCurrentThread() callconv(.Stdcall) HANDLE; +pub extern "kernel32" fn GetCurrentThreadId() callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn GetEnvironmentStringsW() ?[*]u16; +pub extern "kernel32" fn GetEnvironmentStringsW() callconv(.Stdcall) ?[*]u16; -pub extern "kernel32" stdcallcc fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) DWORD; +pub extern "kernel32" fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: *DWORD) BOOL; +pub extern "kernel32" fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: *DWORD) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetFileSizeEx(hFile: HANDLE, lpFileSize: *LARGE_INTEGER) BOOL; +pub extern "kernel32" fn GetFileSizeEx(hFile: HANDLE, lpFileSize: *LARGE_INTEGER) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetFileAttributesW(lpFileName: [*]const WCHAR) DWORD; +pub extern "kernel32" fn GetFileAttributesW(lpFileName: [*]const WCHAR) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn GetModuleFileNameW(hModule: ?HMODULE, lpFilename: [*]u16, nSize: DWORD) DWORD; +pub extern "kernel32" fn GetModuleFileNameW(hModule: ?HMODULE, lpFilename: [*]u16, nSize: DWORD) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn GetModuleHandleW(lpModuleName: ?[*]const WCHAR) HMODULE; +pub extern "kernel32" fn GetModuleHandleW(lpModuleName: ?[*]const WCHAR) callconv(.Stdcall) HMODULE; -pub extern "kernel32" stdcallcc fn GetLastError() DWORD; +pub extern "kernel32" fn GetLastError() callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn GetFileInformationByHandle( +pub extern "kernel32" fn GetFileInformationByHandle( hFile: HANDLE, lpFileInformation: *BY_HANDLE_FILE_INFORMATION, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx( +pub extern "kernel32" fn GetFileInformationByHandleEx( in_hFile: HANDLE, in_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, out_lpFileInformation: *c_void, in_dwBufferSize: DWORD, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetFinalPathNameByHandleW( +pub extern "kernel32" fn GetFinalPathNameByHandleW( hFile: HANDLE, lpszFilePath: [*]u16, cchFilePath: DWORD, dwFlags: DWORD, -) DWORD; +) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERLAPPED, lpNumberOfBytesTransferred: *DWORD, bWait: BOOL) BOOL; +pub extern "kernel32" fn GetOverlappedResult(hFile: HANDLE, lpOverlapped: *OVERLAPPED, lpNumberOfBytesTransferred: *DWORD, bWait: BOOL) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetProcessHeap() ?HANDLE; -pub extern "kernel32" stdcallcc fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) BOOL; +pub extern "kernel32" fn GetProcessHeap() callconv(.Stdcall) ?HANDLE; +pub extern "kernel32" fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) void; -pub extern "kernel32" stdcallcc fn GetSystemTimeAsFileTime(*FILETIME) void; +pub extern "kernel32" fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) callconv(.Stdcall) void; +pub extern "kernel32" fn GetSystemTimeAsFileTime(*FILETIME) callconv(.Stdcall) void; -pub extern "kernel32" stdcallcc fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) ?HANDLE; -pub extern "kernel32" stdcallcc fn HeapDestroy(hHeap: HANDLE) BOOL; -pub extern "kernel32" stdcallcc fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void, dwBytes: SIZE_T) ?*c_void; -pub extern "kernel32" stdcallcc fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) SIZE_T; -pub extern "kernel32" stdcallcc fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) SIZE_T; -pub extern "kernel32" stdcallcc fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) BOOL; +pub extern "kernel32" fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) callconv(.Stdcall) ?HANDLE; +pub extern "kernel32" fn HeapDestroy(hHeap: HANDLE) callconv(.Stdcall) BOOL; +pub extern "kernel32" fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void, dwBytes: SIZE_T) callconv(.Stdcall) ?*c_void; +pub extern "kernel32" fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) callconv(.Stdcall) SIZE_T; +pub extern "kernel32" fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) callconv(.Stdcall) SIZE_T; +pub extern "kernel32" fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn GetStdHandle(in_nStdHandle: DWORD) ?HANDLE; +pub extern "kernel32" fn GetStdHandle(in_nStdHandle: DWORD) callconv(.Stdcall) ?HANDLE; -pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) ?*c_void; +pub extern "kernel32" fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) callconv(.Stdcall) ?*c_void; -pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void) BOOL; +pub extern "kernel32" fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: ?*const c_void) BOOL; +pub extern "kernel32" fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: ?*const c_void) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn VirtualAlloc(lpAddress: ?LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD) ?LPVOID; -pub extern "kernel32" stdcallcc fn VirtualFree(lpAddress: ?LPVOID, dwSize: SIZE_T, dwFreeType: DWORD) BOOL; +pub extern "kernel32" fn VirtualAlloc(lpAddress: ?LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD) callconv(.Stdcall) ?LPVOID; +pub extern "kernel32" fn VirtualFree(lpAddress: ?LPVOID, dwSize: SIZE_T, dwFreeType: DWORD) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn MoveFileExW( +pub extern "kernel32" fn MoveFileExW( lpExistingFileName: [*]const u16, lpNewFileName: [*]const u16, dwFlags: DWORD, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn PostQueuedCompletionStatus(CompletionPort: HANDLE, dwNumberOfBytesTransferred: DWORD, dwCompletionKey: ULONG_PTR, lpOverlapped: ?*OVERLAPPED) BOOL; +pub extern "kernel32" fn PostQueuedCompletionStatus(CompletionPort: HANDLE, dwNumberOfBytesTransferred: DWORD, dwCompletionKey: ULONG_PTR, lpOverlapped: ?*OVERLAPPED) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn QueryPerformanceCounter(lpPerformanceCount: *LARGE_INTEGER) BOOL; +pub extern "kernel32" fn QueryPerformanceCounter(lpPerformanceCount: *LARGE_INTEGER) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn QueryPerformanceFrequency(lpFrequency: *LARGE_INTEGER) BOOL; +pub extern "kernel32" fn QueryPerformanceFrequency(lpFrequency: *LARGE_INTEGER) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn ReadDirectoryChangesW( +pub extern "kernel32" fn ReadDirectoryChangesW( hDirectory: HANDLE, lpBuffer: [*]align(@alignOf(FILE_NOTIFY_INFORMATION)) u8, nBufferLength: DWORD, @@ -170,79 +170,79 @@ pub extern "kernel32" stdcallcc fn ReadDirectoryChangesW( lpBytesReturned: ?*DWORD, lpOverlapped: ?*OVERLAPPED, lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn ReadFile( +pub extern "kernel32" fn ReadFile( in_hFile: HANDLE, out_lpBuffer: [*]u8, in_nNumberOfBytesToRead: DWORD, out_lpNumberOfBytesRead: ?*DWORD, in_out_lpOverlapped: ?*OVERLAPPED, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn RemoveDirectoryW(lpPathName: [*]const u16) BOOL; +pub extern "kernel32" fn RemoveDirectoryW(lpPathName: [*]const u16) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) BOOL; +pub extern "kernel32" fn SetConsoleTextAttribute(hConsoleOutput: HANDLE, wAttributes: WORD) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn SetFilePointerEx( +pub extern "kernel32" fn SetFilePointerEx( in_fFile: HANDLE, in_liDistanceToMove: LARGE_INTEGER, out_opt_ldNewFilePointer: ?*LARGE_INTEGER, in_dwMoveMethod: DWORD, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn SetFileTime( +pub extern "kernel32" fn SetFileTime( hFile: HANDLE, lpCreationTime: ?*const FILETIME, lpLastAccessTime: ?*const FILETIME, lpLastWriteTime: ?*const FILETIME, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) BOOL; +pub extern "kernel32" fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD) void; +pub extern "kernel32" fn Sleep(dwMilliseconds: DWORD) callconv(.Stdcall) void; -pub extern "kernel32" stdcallcc fn SwitchToThread() BOOL; +pub extern "kernel32" fn SwitchToThread() callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) BOOL; +pub extern "kernel32" fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn TlsAlloc() DWORD; +pub extern "kernel32" fn TlsAlloc() callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn TlsFree(dwTlsIndex: DWORD) BOOL; +pub extern "kernel32" fn TlsFree(dwTlsIndex: DWORD) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) DWORD; +pub extern "kernel32" fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn WaitForSingleObjectEx(hHandle: HANDLE, dwMilliseconds: DWORD, bAlertable: BOOL) DWORD; +pub extern "kernel32" fn WaitForSingleObjectEx(hHandle: HANDLE, dwMilliseconds: DWORD, bAlertable: BOOL) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn WaitForMultipleObjects(nCount: DWORD, lpHandle: [*]const HANDLE, bWaitAll: BOOL, dwMilliseconds: DWORD) DWORD; +pub extern "kernel32" fn WaitForMultipleObjects(nCount: DWORD, lpHandle: [*]const HANDLE, bWaitAll: BOOL, dwMilliseconds: DWORD) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn WaitForMultipleObjectsEx( +pub extern "kernel32" fn WaitForMultipleObjectsEx( nCount: DWORD, lpHandle: [*]const HANDLE, bWaitAll: BOOL, dwMilliseconds: DWORD, bAlertable: BOOL, -) DWORD; +) callconv(.Stdcall) DWORD; -pub extern "kernel32" stdcallcc fn WriteFile( +pub extern "kernel32" fn WriteFile( in_hFile: HANDLE, in_lpBuffer: [*]const u8, in_nNumberOfBytesToWrite: DWORD, out_lpNumberOfBytesWritten: ?*DWORD, in_out_lpOverlapped: ?*OVERLAPPED, -) BOOL; +) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn WriteFileEx(hFile: HANDLE, lpBuffer: [*]const u8, nNumberOfBytesToWrite: DWORD, lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE) BOOL; +pub extern "kernel32" fn WriteFileEx(hFile: HANDLE, lpBuffer: [*]const u8, nNumberOfBytesToWrite: DWORD, lpOverlapped: LPOVERLAPPED, lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn LoadLibraryW(lpLibFileName: [*]const u16) ?HMODULE; +pub extern "kernel32" fn LoadLibraryW(lpLibFileName: [*]const u16) callconv(.Stdcall) ?HMODULE; -pub extern "kernel32" stdcallcc fn GetProcAddress(hModule: HMODULE, lpProcName: [*]const u8) ?FARPROC; +pub extern "kernel32" fn GetProcAddress(hModule: HMODULE, lpProcName: [*]const u8) callconv(.Stdcall) ?FARPROC; -pub extern "kernel32" stdcallcc fn FreeLibrary(hModule: HMODULE) BOOL; +pub extern "kernel32" fn FreeLibrary(hModule: HMODULE) callconv(.Stdcall) BOOL; -pub extern "kernel32" stdcallcc fn InitializeCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void; -pub extern "kernel32" stdcallcc fn EnterCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void; -pub extern "kernel32" stdcallcc fn LeaveCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void; -pub extern "kernel32" stdcallcc fn DeleteCriticalSection(lpCriticalSection: *CRITICAL_SECTION) void; +pub extern "kernel32" fn InitializeCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void; +pub extern "kernel32" fn EnterCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void; +pub extern "kernel32" fn LeaveCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void; +pub extern "kernel32" fn DeleteCriticalSection(lpCriticalSection: *CRITICAL_SECTION) callconv(.Stdcall) void; -pub extern "kernel32" stdcallcc fn InitOnceExecuteOnce(InitOnce: *INIT_ONCE, InitFn: INIT_ONCE_FN, Parameter: ?*c_void, Context: ?*c_void) BOOL; +pub extern "kernel32" fn InitOnceExecuteOnce(InitOnce: *INIT_ONCE, InitFn: INIT_ONCE_FN, Parameter: ?*c_void, Context: ?*c_void) callconv(.Stdcall) BOOL; diff --git a/lib/std/os/windows/ntdll.zig b/lib/std/os/windows/ntdll.zig index 84de0ca946..695cd77274 100644 --- a/lib/std/os/windows/ntdll.zig +++ b/lib/std/os/windows/ntdll.zig @@ -1,14 +1,14 @@ usingnamespace @import("bits.zig"); -pub extern "NtDll" stdcallcc fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) WORD; -pub extern "NtDll" stdcallcc fn NtQueryInformationFile( +pub extern "NtDll" fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) callconv(.Stdcall) WORD; +pub extern "NtDll" fn NtQueryInformationFile( FileHandle: HANDLE, IoStatusBlock: *IO_STATUS_BLOCK, FileInformation: *c_void, Length: ULONG, FileInformationClass: FILE_INFORMATION_CLASS, -) NTSTATUS; -pub extern "NtDll" stdcallcc fn NtCreateFile( +) callconv(.Stdcall) NTSTATUS; +pub extern "NtDll" fn NtCreateFile( FileHandle: *HANDLE, DesiredAccess: ACCESS_MASK, ObjectAttributes: *OBJECT_ATTRIBUTES, @@ -20,8 +20,8 @@ pub extern "NtDll" stdcallcc fn NtCreateFile( CreateOptions: ULONG, EaBuffer: ?*c_void, EaLength: ULONG, -) NTSTATUS; -pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile( +) callconv(.Stdcall) NTSTATUS; +pub extern "NtDll" fn NtDeviceIoControlFile( FileHandle: HANDLE, Event: ?HANDLE, ApcRoutine: ?IO_APC_ROUTINE, @@ -32,17 +32,17 @@ pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile( InputBufferLength: ULONG, OutputBuffer: ?PVOID, OutputBufferLength: ULONG, -) NTSTATUS; -pub extern "NtDll" stdcallcc fn NtClose(Handle: HANDLE) NTSTATUS; -pub extern "NtDll" stdcallcc fn RtlDosPathNameToNtPathName_U( +) callconv(.Stdcall) NTSTATUS; +pub extern "NtDll" fn NtClose(Handle: HANDLE) callconv(.Stdcall) NTSTATUS; +pub extern "NtDll" fn RtlDosPathNameToNtPathName_U( DosPathName: [*]const u16, NtPathName: *UNICODE_STRING, NtFileNamePart: ?*?[*]const u16, DirectoryInfo: ?*CURDIR, -) BOOL; -pub extern "NtDll" stdcallcc fn RtlFreeUnicodeString(UnicodeString: *UNICODE_STRING) void; +) callconv(.Stdcall) BOOL; +pub extern "NtDll" fn RtlFreeUnicodeString(UnicodeString: *UNICODE_STRING) callconv(.Stdcall) void; -pub extern "NtDll" stdcallcc fn NtQueryDirectoryFile( +pub extern "NtDll" fn NtQueryDirectoryFile( FileHandle: HANDLE, Event: ?HANDLE, ApcRoutine: ?IO_APC_ROUTINE, @@ -54,22 +54,22 @@ pub extern "NtDll" stdcallcc fn NtQueryDirectoryFile( ReturnSingleEntry: BOOLEAN, FileName: ?*UNICODE_STRING, RestartScan: BOOLEAN, -) NTSTATUS; -pub extern "NtDll" stdcallcc fn NtCreateKeyedEvent( +) callconv(.Stdcall) NTSTATUS; +pub extern "NtDll" fn NtCreateKeyedEvent( KeyedEventHandle: *HANDLE, DesiredAccess: ACCESS_MASK, ObjectAttributes: ?PVOID, Flags: ULONG, -) NTSTATUS; -pub extern "NtDll" stdcallcc fn NtReleaseKeyedEvent( +) callconv(.Stdcall) NTSTATUS; +pub extern "NtDll" fn NtReleaseKeyedEvent( EventHandle: HANDLE, Key: *const c_void, Alertable: BOOLEAN, Timeout: ?*LARGE_INTEGER, -) NTSTATUS; -pub extern "NtDll" stdcallcc fn NtWaitForKeyedEvent( +) callconv(.Stdcall) NTSTATUS; +pub extern "NtDll" fn NtWaitForKeyedEvent( EventHandle: HANDLE, Key: *const c_void, Alertable: BOOLEAN, Timeout: ?*LARGE_INTEGER, -) NTSTATUS; +) callconv(.Stdcall) NTSTATUS; diff --git a/lib/std/os/windows/ole32.zig b/lib/std/os/windows/ole32.zig index 39c12d074c..a472089078 100644 --- a/lib/std/os/windows/ole32.zig +++ b/lib/std/os/windows/ole32.zig @@ -1,6 +1,6 @@ usingnamespace @import("bits.zig"); -pub extern "ole32" stdcallcc fn CoTaskMemFree(pv: LPVOID) void; -pub extern "ole32" stdcallcc fn CoUninitialize() void; -pub extern "ole32" stdcallcc fn CoGetCurrentProcess() DWORD; -pub extern "ole32" stdcallcc fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) HRESULT; +pub extern "ole32" fn CoTaskMemFree(pv: LPVOID) callconv(.Stdcall) void; +pub extern "ole32" fn CoUninitialize() callconv(.Stdcall) void; +pub extern "ole32" fn CoGetCurrentProcess() callconv(.Stdcall) DWORD; +pub extern "ole32" fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) callconv(.Stdcall) HRESULT; diff --git a/lib/std/os/windows/shell32.zig b/lib/std/os/windows/shell32.zig index c178997aad..aa1667d01d 100644 --- a/lib/std/os/windows/shell32.zig +++ b/lib/std/os/windows/shell32.zig @@ -1,3 +1,3 @@ usingnamespace @import("bits.zig"); -pub extern "shell32" stdcallcc fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*]WCHAR) HRESULT; +pub extern "shell32" fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*]WCHAR) callconv(.Stdcall) HRESULT; diff --git a/lib/std/os/windows/ws2_32.zig b/lib/std/os/windows/ws2_32.zig index c3dece2909..70cb62ac51 100644 --- a/lib/std/os/windows/ws2_32.zig +++ b/lib/std/os/windows/ws2_32.zig @@ -315,30 +315,30 @@ const IOC_WS2 = 0x08000000; pub const SIO_BASE_HANDLE = IOC_OUT | IOC_WS2 | 34; -pub extern "ws2_32" stdcallcc fn WSAStartup( +pub extern "ws2_32" fn WSAStartup( wVersionRequired: WORD, lpWSAData: *WSADATA, -) c_int; -pub extern "ws2_32" stdcallcc fn WSACleanup() c_int; -pub extern "ws2_32" stdcallcc fn WSAGetLastError() c_int; -pub extern "ws2_32" stdcallcc fn WSASocketA( +) callconv(.Stdcall) c_int; +pub extern "ws2_32" fn WSACleanup() callconv(.Stdcall) c_int; +pub extern "ws2_32" fn WSAGetLastError() callconv(.Stdcall) c_int; +pub extern "ws2_32" fn WSASocketA( af: c_int, type: c_int, protocol: c_int, lpProtocolInfo: ?*WSAPROTOCOL_INFOA, g: GROUP, dwFlags: DWORD, -) SOCKET; -pub extern "ws2_32" stdcallcc fn WSASocketW( +) callconv(.Stdcall) SOCKET; +pub extern "ws2_32" fn WSASocketW( af: c_int, type: c_int, protocol: c_int, lpProtocolInfo: ?*WSAPROTOCOL_INFOW, g: GROUP, dwFlags: DWORD, -) SOCKET; -pub extern "ws2_32" stdcallcc fn closesocket(s: SOCKET) c_int; -pub extern "ws2_32" stdcallcc fn WSAIoctl( +) callconv(.Stdcall) SOCKET; +pub extern "ws2_32" fn closesocket(s: SOCKET) callconv(.Stdcall) c_int; +pub extern "ws2_32" fn WSAIoctl( s: SOCKET, dwIoControlCode: DWORD, lpvInBuffer: ?*const c_void, @@ -348,18 +348,18 @@ pub extern "ws2_32" stdcallcc fn WSAIoctl( lpcbBytesReturned: LPDWORD, lpOverlapped: ?*WSAOVERLAPPED, lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, -) c_int; -pub extern "ws2_32" stdcallcc fn accept( +) callconv(.Stdcall) c_int; +pub extern "ws2_32" fn accept( s: SOCKET, addr: ?*sockaddr, addrlen: socklen_t, -) SOCKET; -pub extern "ws2_32" stdcallcc fn connect( +) callconv(.Stdcall) SOCKET; +pub extern "ws2_32" fn connect( s: SOCKET, name: *const sockaddr, namelen: socklen_t, -) c_int; -pub extern "ws2_32" stdcallcc fn WSARecv( +) callconv(.Stdcall) c_int; +pub extern "ws2_32" fn WSARecv( s: SOCKET, lpBuffers: [*]const WSABUF, dwBufferCount: DWORD, @@ -367,8 +367,8 @@ pub extern "ws2_32" stdcallcc fn WSARecv( lpFlags: *DWORD, lpOverlapped: ?*WSAOVERLAPPED, lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, -) c_int; -pub extern "ws2_32" stdcallcc fn WSARecvFrom( +) callconv(.Stdcall) c_int; +pub extern "ws2_32" fn WSARecvFrom( s: SOCKET, lpBuffers: [*]const WSABUF, dwBufferCount: DWORD, @@ -378,8 +378,8 @@ pub extern "ws2_32" stdcallcc fn WSARecvFrom( lpFromlen: socklen_t, lpOverlapped: ?*WSAOVERLAPPED, lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, -) c_int; -pub extern "ws2_32" stdcallcc fn WSASend( +) callconv(.Stdcall) c_int; +pub extern "ws2_32" fn WSASend( s: SOCKET, lpBuffers: [*]WSABUF, dwBufferCount: DWORD, @@ -387,8 +387,8 @@ pub extern "ws2_32" stdcallcc fn WSASend( dwFlags: DWORD, lpOverlapped: ?*WSAOVERLAPPED, lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, -) c_int; -pub extern "ws2_32" stdcallcc fn WSASendTo( +) callconv(.Stdcall) c_int; +pub extern "ws2_32" fn WSASendTo( s: SOCKET, lpBuffers: [*]WSABUF, dwBufferCount: DWORD, @@ -398,4 +398,4 @@ pub extern "ws2_32" stdcallcc fn WSASendTo( iTolen: socklen_t, lpOverlapped: ?*WSAOVERLAPPED, lpCompletionRoutine: ?WSAOVERLAPPED_COMPLETION_ROUTINE, -) c_int; +) callconv(.Stdcall) c_int; diff --git a/lib/std/reset_event.zig b/lib/std/reset_event.zig index 86bc5ba5aa..b9d9517c6d 100644 --- a/lib/std/reset_event.zig +++ b/lib/std/reset_event.zig @@ -14,13 +14,12 @@ const windows = os.windows; pub const ResetEvent = struct { os_event: OsEvent, - pub const OsEvent = - if (builtin.single_threaded) - DebugEvent - else if (builtin.link_libc and builtin.os != .windows and builtin.os != .linux) - PosixEvent - else - AtomicEvent; + pub const OsEvent = if (builtin.single_threaded) + DebugEvent + else if (builtin.link_libc and builtin.os != .windows and builtin.os != .linux) + PosixEvent + else + AtomicEvent; pub fn init() ResetEvent { return ResetEvent{ .os_event = OsEvent.init() }; @@ -105,7 +104,7 @@ const PosixEvent = struct { } fn deinit(self: *PosixEvent) void { - // on dragonfly, *destroy() functions can return EINVAL + // on dragonfly, *destroy() functions can return EINVAL // for statically initialized pthread structures const err = if (builtin.os == .dragonfly) os.EINVAL else 0; @@ -212,8 +211,7 @@ const AtomicEvent = struct { fn wait(self: *AtomicEvent, timeout: ?u64) !void { var waiters = @atomicLoad(u32, &self.waiters, .Acquire); while (waiters != WAKE) { - waiters = @cmpxchgWeak(u32, &self.waiters, waiters, waiters + WAIT, .Acquire, .Acquire) - orelse return Futex.wait(&self.waiters, timeout); + waiters = @cmpxchgWeak(u32, &self.waiters, waiters, waiters + WAIT, .Acquire, .Acquire) orelse return Futex.wait(&self.waiters, timeout); } } @@ -281,7 +279,7 @@ const AtomicEvent = struct { pub fn wake(waiters: *u32, wake_count: u32) void { const handle = getEventHandle() orelse return SpinFutex.wake(waiters, wake_count); const key = @ptrCast(*const c_void, waiters); - + var waiting = wake_count; while (waiting != 0) : (waiting -= 1) { const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null); @@ -408,7 +406,7 @@ test "std.ResetEvent" { // wait for receiver to update value and signal output self.out.wait(); testing.expect(self.value == 2); - + // update value and signal final input self.value = 3; self.in.set(); @@ -418,12 +416,12 @@ test "std.ResetEvent" { // wait for sender to update value and signal input self.in.wait(); assert(self.value == 1); - + // update value and signal output self.in.reset(); self.value = 2; self.out.set(); - + // wait for sender to update value and signal final input self.in.wait(); assert(self.value == 3); diff --git a/lib/std/special/c.zig b/lib/std/special/c.zig index 08c59337c5..604bfd277a 100644 --- a/lib/std/special/c.zig +++ b/lib/std/special/c.zig @@ -40,19 +40,19 @@ comptime { extern var _fltused: c_int = 1; extern fn main(argc: c_int, argv: [*:null]?[*:0]u8) c_int; -extern fn wasm_start() void { +fn wasm_start() callconv(.C) void { _ = main(0, undefined); } -extern fn strcmp(s1: [*:0]const u8, s2: [*:0]const u8) c_int { +fn strcmp(s1: [*:0]const u8, s2: [*:0]const u8) callconv(.C) c_int { return std.cstr.cmp(s1, s2); } -extern fn strlen(s: [*:0]const u8) usize { +fn strlen(s: [*:0]const u8) callconv(.C) usize { return std.mem.len(u8, s); } -extern fn strncmp(_l: [*:0]const u8, _r: [*:0]const u8, _n: usize) c_int { +fn strncmp(_l: [*:0]const u8, _r: [*:0]const u8, _n: usize) callconv(.C) c_int { if (_n == 0) return 0; var l = _l; var r = _r; @@ -65,7 +65,7 @@ extern fn strncmp(_l: [*:0]const u8, _r: [*:0]const u8, _n: usize) c_int { return @as(c_int, l[0]) - @as(c_int, r[0]); } -extern fn strerror(errnum: c_int) [*:0]const u8 { +fn strerror(errnum: c_int) callconv(.C) [*:0]const u8 { return "TODO strerror implementation"; } @@ -188,14 +188,14 @@ comptime { @export("clone", clone, builtin.GlobalLinkage.Strong); } } -extern fn __stack_chk_fail() noreturn { +fn __stack_chk_fail() callconv(.C) noreturn { @panic("stack smashing detected"); } // TODO we should be able to put this directly in std/linux/x86_64.zig but // it causes a segfault in release mode. this is a workaround of calling it // across .o file boundaries. fix comptime @ptrCast of nakedcc functions. -nakedcc fn clone() void { +fn clone() callconv(.Naked) void { switch (builtin.arch) { .i386 => { // __clone(func, stack, flags, arg, ptid, tls, ctid) @@ -750,7 +750,6 @@ test "sqrt special" { std.testing.expect(std.math.isNan(sqrt(std.math.nan(f64)))); } - export fn sqrtf(x: f32) f32 { const tiny: f32 = 1.0e-30; const sign: i32 = @bitCast(i32, @as(u32, 0x80000000)); @@ -848,4 +847,3 @@ test "sqrtf special" { std.testing.expect(std.math.isNan(sqrtf(-1.0))); std.testing.expect(std.math.isNan(sqrtf(std.math.nan(f32)))); } - diff --git a/lib/std/special/compiler_rt.zig b/lib/std/special/compiler_rt.zig index 0426f72417..3a6e9c97e2 100644 --- a/lib/std/special/compiler_rt.zig +++ b/lib/std/special/compiler_rt.zig @@ -309,7 +309,7 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn } } -extern fn __stack_chk_fail() noreturn { +fn __stack_chk_fail() callconv(.C) noreturn { @panic("stack smashing detected"); } @@ -320,17 +320,17 @@ extern var __stack_chk_guard: usize = blk: { break :blk @bitCast(usize, buf); }; -extern fn __aeabi_unwind_cpp_pr0() void { +fn __aeabi_unwind_cpp_pr0() callconv(.C) void { unreachable; } -extern fn __aeabi_unwind_cpp_pr1() void { +fn __aeabi_unwind_cpp_pr1() callconv(.C) void { unreachable; } -extern fn __aeabi_unwind_cpp_pr2() void { +fn __aeabi_unwind_cpp_pr2() callconv(.C) void { unreachable; } -extern fn __divmoddi4(a: i64, b: i64, rem: *i64) i64 { +fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.C) i64 { @setRuntimeSafety(is_test); const d = __divdi3(a, b); @@ -338,7 +338,7 @@ extern fn __divmoddi4(a: i64, b: i64, rem: *i64) i64 { return d; } -extern fn __divdi3(a: i64, b: i64) i64 { +fn __divdi3(a: i64, b: i64) callconv(.C) i64 { @setRuntimeSafety(is_test); // Set aside the sign of the quotient. @@ -352,7 +352,7 @@ extern fn __divdi3(a: i64, b: i64) i64 { return @bitCast(i64, (res ^ sign) -% sign); } -extern fn __moddi3(a: i64, b: i64) i64 { +fn __moddi3(a: i64, b: i64) callconv(.C) i64 { @setRuntimeSafety(is_test); // Take absolute value of a and b via abs(x) = (x^(x >> 63)) - (x >> 63). @@ -365,12 +365,12 @@ extern fn __moddi3(a: i64, b: i64) i64 { return (@bitCast(i64, r) ^ (a >> 63)) -% (a >> 63); } -extern fn __udivdi3(a: u64, b: u64) u64 { +fn __udivdi3(a: u64, b: u64) callconv(.C) u64 { @setRuntimeSafety(is_test); return __udivmoddi4(a, b, null); } -extern fn __umoddi3(a: u64, b: u64) u64 { +fn __umoddi3(a: u64, b: u64) callconv(.C) u64 { @setRuntimeSafety(is_test); var r: u64 = undefined; @@ -378,7 +378,7 @@ extern fn __umoddi3(a: u64, b: u64) u64 { return r; } -extern fn __aeabi_uidivmod(n: u32, d: u32) extern struct { +fn __aeabi_uidivmod(n: u32, d: u32) callconv(.C) extern struct { q: u32, r: u32, } { @@ -389,7 +389,7 @@ extern fn __aeabi_uidivmod(n: u32, d: u32) extern struct { return result; } -extern fn __aeabi_uldivmod(n: u64, d: u64) extern struct { +fn __aeabi_uldivmod(n: u64, d: u64) callconv(.C) extern struct { q: u64, r: u64, } { @@ -400,7 +400,7 @@ extern fn __aeabi_uldivmod(n: u64, d: u64) extern struct { return result; } -extern fn __aeabi_idivmod(n: i32, d: i32) extern struct { +fn __aeabi_idivmod(n: i32, d: i32) callconv(.C) extern struct { q: i32, r: i32, } { @@ -411,7 +411,7 @@ extern fn __aeabi_idivmod(n: i32, d: i32) extern struct { return result; } -extern fn __aeabi_ldivmod(n: i64, d: i64) extern struct { +fn __aeabi_ldivmod(n: i64, d: i64) callconv(.C) extern struct { q: i64, r: i64, } { @@ -528,7 +528,7 @@ fn usesThumb1PreArmv6(arch: builtin.Arch) bool { }; } -nakedcc fn __aeabi_memcpy() noreturn { +fn __aeabi_memcpy() callconv(.Naked) noreturn { @setRuntimeSafety(false); if (use_thumb_1) { asm volatile ( @@ -544,7 +544,7 @@ nakedcc fn __aeabi_memcpy() noreturn { unreachable; } -nakedcc fn __aeabi_memmove() noreturn { +fn __aeabi_memmove() callconv(.Naked) noreturn { @setRuntimeSafety(false); if (use_thumb_1) { asm volatile ( @@ -560,7 +560,7 @@ nakedcc fn __aeabi_memmove() noreturn { unreachable; } -nakedcc fn __aeabi_memset() noreturn { +fn __aeabi_memset() callconv(.Naked) noreturn { @setRuntimeSafety(false); if (use_thumb_1_pre_armv6) { asm volatile ( @@ -591,7 +591,7 @@ nakedcc fn __aeabi_memset() noreturn { unreachable; } -nakedcc fn __aeabi_memclr() noreturn { +fn __aeabi_memclr() callconv(.Naked) noreturn { @setRuntimeSafety(false); if (use_thumb_1_pre_armv6) { asm volatile ( @@ -619,7 +619,7 @@ nakedcc fn __aeabi_memclr() noreturn { unreachable; } -nakedcc fn __aeabi_memcmp() noreturn { +fn __aeabi_memcmp() callconv(.Naked) noreturn { @setRuntimeSafety(false); if (use_thumb_1) { asm volatile ( @@ -635,7 +635,7 @@ nakedcc fn __aeabi_memcmp() noreturn { unreachable; } -extern fn __divmodsi4(a: i32, b: i32, rem: *i32) i32 { +fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.C) i32 { @setRuntimeSafety(is_test); const d = __divsi3(a, b); @@ -643,7 +643,7 @@ extern fn __divmodsi4(a: i32, b: i32, rem: *i32) i32 { return d; } -extern fn __udivmodsi4(a: u32, b: u32, rem: *u32) u32 { +fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.C) u32 { @setRuntimeSafety(is_test); const d = __udivsi3(a, b); @@ -651,7 +651,7 @@ extern fn __udivmodsi4(a: u32, b: u32, rem: *u32) u32 { return d; } -extern fn __divsi3(n: i32, d: i32) i32 { +fn __divsi3(n: i32, d: i32) callconv(.C) i32 { @setRuntimeSafety(is_test); // Set aside the sign of the quotient. @@ -665,7 +665,7 @@ extern fn __divsi3(n: i32, d: i32) i32 { return @bitCast(i32, (res ^ sign) -% sign); } -extern fn __udivsi3(n: u32, d: u32) u32 { +fn __udivsi3(n: u32, d: u32) callconv(.C) u32 { @setRuntimeSafety(is_test); const n_uword_bits: c_uint = u32.bit_count; @@ -706,13 +706,13 @@ extern fn __udivsi3(n: u32, d: u32) u32 { return q; } -extern fn __modsi3(n: i32, d: i32) i32 { +fn __modsi3(n: i32, d: i32) callconv(.C) i32 { @setRuntimeSafety(is_test); return n -% __divsi3(n, d) *% d; } -extern fn __umodsi3(n: u32, d: u32) u32 { +fn __umodsi3(n: u32, d: u32) callconv(.C) u32 { @setRuntimeSafety(is_test); return n -% __udivsi3(n, d) *% d; diff --git a/lib/std/special/compiler_rt/addXf3.zig b/lib/std/special/compiler_rt/addXf3.zig index e3dd1819c3..ac38e1c8cd 100644 --- a/lib/std/special/compiler_rt/addXf3.zig +++ b/lib/std/special/compiler_rt/addXf3.zig @@ -6,29 +6,29 @@ const std = @import("std"); const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); -pub extern fn __addsf3(a: f32, b: f32) f32 { +pub fn __addsf3(a: f32, b: f32) callconv(.C) f32 { return addXf3(f32, a, b); } -pub extern fn __adddf3(a: f64, b: f64) f64 { +pub fn __adddf3(a: f64, b: f64) callconv(.C) f64 { return addXf3(f64, a, b); } -pub extern fn __addtf3(a: f128, b: f128) f128 { +pub fn __addtf3(a: f128, b: f128) callconv(.C) f128 { return addXf3(f128, a, b); } -pub extern fn __subsf3(a: f32, b: f32) f32 { +pub fn __subsf3(a: f32, b: f32) callconv(.C) f32 { const neg_b = @bitCast(f32, @bitCast(u32, b) ^ (@as(u32, 1) << 31)); return addXf3(f32, a, neg_b); } -pub extern fn __subdf3(a: f64, b: f64) f64 { +pub fn __subdf3(a: f64, b: f64) callconv(.C) f64 { const neg_b = @bitCast(f64, @bitCast(u64, b) ^ (@as(u64, 1) << 63)); return addXf3(f64, a, neg_b); } -pub extern fn __subtf3(a: f128, b: f128) f128 { +pub fn __subtf3(a: f128, b: f128) callconv(.C) f128 { const neg_b = @bitCast(f128, @bitCast(u128, b) ^ (@as(u128, 1) << 127)); return addXf3(f128, a, neg_b); } diff --git a/lib/std/special/compiler_rt/arm/aeabi_dcmp.zig b/lib/std/special/compiler_rt/arm/aeabi_dcmp.zig index 7463c49931..d75c343fbb 100644 --- a/lib/std/special/compiler_rt/arm/aeabi_dcmp.zig +++ b/lib/std/special/compiler_rt/arm/aeabi_dcmp.zig @@ -12,31 +12,31 @@ const ConditionalOperator = enum { Gt, }; -pub nakedcc fn __aeabi_dcmpeq() noreturn { +pub fn __aeabi_dcmpeq() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Eq}); unreachable; } -pub nakedcc fn __aeabi_dcmplt() noreturn { +pub fn __aeabi_dcmplt() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Lt}); unreachable; } -pub nakedcc fn __aeabi_dcmple() noreturn { +pub fn __aeabi_dcmple() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Le}); unreachable; } -pub nakedcc fn __aeabi_dcmpge() noreturn { +pub fn __aeabi_dcmpge() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Ge}); unreachable; } -pub nakedcc fn __aeabi_dcmpgt() noreturn { +pub fn __aeabi_dcmpgt() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Gt}); unreachable; diff --git a/lib/std/special/compiler_rt/arm/aeabi_fcmp.zig b/lib/std/special/compiler_rt/arm/aeabi_fcmp.zig index 9a24641d9a..bf36e78ad2 100644 --- a/lib/std/special/compiler_rt/arm/aeabi_fcmp.zig +++ b/lib/std/special/compiler_rt/arm/aeabi_fcmp.zig @@ -12,31 +12,31 @@ const ConditionalOperator = enum { Gt, }; -pub nakedcc fn __aeabi_fcmpeq() noreturn { +pub fn __aeabi_fcmpeq() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Eq}); unreachable; } -pub nakedcc fn __aeabi_fcmplt() noreturn { +pub fn __aeabi_fcmplt() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Lt}); unreachable; } -pub nakedcc fn __aeabi_fcmple() noreturn { +pub fn __aeabi_fcmple() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Le}); unreachable; } -pub nakedcc fn __aeabi_fcmpge() noreturn { +pub fn __aeabi_fcmpge() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Ge}); unreachable; } -pub nakedcc fn __aeabi_fcmpgt() noreturn { +pub fn __aeabi_fcmpgt() callconv(.Naked) noreturn { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Gt}); unreachable; diff --git a/lib/std/special/compiler_rt/ashlti3.zig b/lib/std/special/compiler_rt/ashlti3.zig index 65b23f22e5..211515f9dd 100644 --- a/lib/std/special/compiler_rt/ashlti3.zig +++ b/lib/std/special/compiler_rt/ashlti3.zig @@ -1,7 +1,7 @@ const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); -pub extern fn __ashlti3(a: i128, b: i32) i128 { +pub fn __ashlti3(a: i128, b: i32) callconv(.C) i128 { var input = twords{ .all = a }; var result: twords = undefined; diff --git a/lib/std/special/compiler_rt/ashrti3.zig b/lib/std/special/compiler_rt/ashrti3.zig index 40ee89c3c4..1bcd40d2e4 100644 --- a/lib/std/special/compiler_rt/ashrti3.zig +++ b/lib/std/special/compiler_rt/ashrti3.zig @@ -1,7 +1,7 @@ const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); -pub extern fn __ashrti3(a: i128, b: i32) i128 { +pub fn __ashrti3(a: i128, b: i32) callconv(.C) i128 { var input = twords{ .all = a }; var result: twords = undefined; diff --git a/lib/std/special/compiler_rt/aulldiv.zig b/lib/std/special/compiler_rt/aulldiv.zig index dfca4f4c43..2e2dd364d5 100644 --- a/lib/std/special/compiler_rt/aulldiv.zig +++ b/lib/std/special/compiler_rt/aulldiv.zig @@ -1,6 +1,6 @@ const builtin = @import("builtin"); -pub extern stdcallcc fn _alldiv(a: i64, b: i64) i64 { +pub fn _alldiv(a: i64, b: i64) callconv(.Stdcall) i64 { @setRuntimeSafety(builtin.is_test); const s_a = a >> (i64.bit_count - 1); const s_b = b >> (i64.bit_count - 1); @@ -13,7 +13,7 @@ pub extern stdcallcc fn _alldiv(a: i64, b: i64) i64 { return (@bitCast(i64, r) ^ s) -% s; } -pub nakedcc fn _aulldiv() void { +pub fn _aulldiv() callconv(.Naked) void { @setRuntimeSafety(false); // The stack layout is: diff --git a/lib/std/special/compiler_rt/aullrem.zig b/lib/std/special/compiler_rt/aullrem.zig index c1fee72032..4244f1bb80 100644 --- a/lib/std/special/compiler_rt/aullrem.zig +++ b/lib/std/special/compiler_rt/aullrem.zig @@ -1,6 +1,6 @@ const builtin = @import("builtin"); -pub extern stdcallcc fn _allrem(a: i64, b: i64) i64 { +pub fn _allrem(a: i64, b: i64) callconv(.Stdcall) i64 { @setRuntimeSafety(builtin.is_test); const s_a = a >> (i64.bit_count - 1); const s_b = b >> (i64.bit_count - 1); @@ -13,7 +13,7 @@ pub extern stdcallcc fn _allrem(a: i64, b: i64) i64 { return (@bitCast(i64, r) ^ s) -% s; } -pub nakedcc fn _aullrem() void { +pub fn _aullrem() callconv(.Naked) void { @setRuntimeSafety(false); // The stack layout is: diff --git a/lib/std/special/compiler_rt/comparedf2.zig b/lib/std/special/compiler_rt/comparedf2.zig index 95dc878630..b6e08c49f4 100644 --- a/lib/std/special/compiler_rt/comparedf2.zig +++ b/lib/std/special/compiler_rt/comparedf2.zig @@ -27,7 +27,7 @@ const LE_EQUAL = @as(c_int, 0); const LE_GREATER = @as(c_int, 1); const LE_UNORDERED = @as(c_int, 1); -pub extern fn __ledf2(a: fp_t, b: fp_t) c_int { +pub fn __ledf2(a: fp_t, b: fp_t) callconv(.C) c_int { @setRuntimeSafety(is_test); const aInt: srep_t = @bitCast(srep_t, a); const bInt: srep_t = @bitCast(srep_t, b); @@ -70,7 +70,7 @@ const GE_EQUAL = @as(c_int, 0); const GE_GREATER = @as(c_int, 1); const GE_UNORDERED = @as(c_int, -1); // Note: different from LE_UNORDERED -pub extern fn __gedf2(a: fp_t, b: fp_t) c_int { +pub fn __gedf2(a: fp_t, b: fp_t) callconv(.C) c_int { @setRuntimeSafety(is_test); const aInt: srep_t = @bitCast(srep_t, a); const bInt: srep_t = @bitCast(srep_t, b); @@ -94,26 +94,26 @@ pub extern fn __gedf2(a: fp_t, b: fp_t) c_int { } } -pub extern fn __unorddf2(a: fp_t, b: fp_t) c_int { +pub fn __unorddf2(a: fp_t, b: fp_t) callconv(.C) c_int { @setRuntimeSafety(is_test); const aAbs: rep_t = @bitCast(rep_t, a) & absMask; const bAbs: rep_t = @bitCast(rep_t, b) & absMask; return @boolToInt(aAbs > infRep or bAbs > infRep); } -pub extern fn __eqdf2(a: fp_t, b: fp_t) c_int { +pub fn __eqdf2(a: fp_t, b: fp_t) callconv(.C) c_int { return __ledf2(a, b); } -pub extern fn __ltdf2(a: fp_t, b: fp_t) c_int { +pub fn __ltdf2(a: fp_t, b: fp_t) callconv(.C) c_int { return __ledf2(a, b); } -pub extern fn __nedf2(a: fp_t, b: fp_t) c_int { +pub fn __nedf2(a: fp_t, b: fp_t) callconv(.C) c_int { return __ledf2(a, b); } -pub extern fn __gtdf2(a: fp_t, b: fp_t) c_int { +pub fn __gtdf2(a: fp_t, b: fp_t) callconv(.C) c_int { return __gedf2(a, b); } diff --git a/lib/std/special/compiler_rt/comparesf2.zig b/lib/std/special/compiler_rt/comparesf2.zig index 4468da4fbe..fdb5737ad3 100644 --- a/lib/std/special/compiler_rt/comparesf2.zig +++ b/lib/std/special/compiler_rt/comparesf2.zig @@ -27,7 +27,7 @@ const LE_EQUAL = @as(c_int, 0); const LE_GREATER = @as(c_int, 1); const LE_UNORDERED = @as(c_int, 1); -pub extern fn __lesf2(a: fp_t, b: fp_t) c_int { +pub fn __lesf2(a: fp_t, b: fp_t) callconv(.C) c_int { @setRuntimeSafety(is_test); const aInt: srep_t = @bitCast(srep_t, a); const bInt: srep_t = @bitCast(srep_t, b); @@ -70,7 +70,7 @@ const GE_EQUAL = @as(c_int, 0); const GE_GREATER = @as(c_int, 1); const GE_UNORDERED = @as(c_int, -1); // Note: different from LE_UNORDERED -pub extern fn __gesf2(a: fp_t, b: fp_t) c_int { +pub fn __gesf2(a: fp_t, b: fp_t) callconv(.C) c_int { @setRuntimeSafety(is_test); const aInt: srep_t = @bitCast(srep_t, a); const bInt: srep_t = @bitCast(srep_t, b); @@ -94,26 +94,26 @@ pub extern fn __gesf2(a: fp_t, b: fp_t) c_int { } } -pub extern fn __unordsf2(a: fp_t, b: fp_t) c_int { +pub fn __unordsf2(a: fp_t, b: fp_t) callconv(.C) c_int { @setRuntimeSafety(is_test); const aAbs: rep_t = @bitCast(rep_t, a) & absMask; const bAbs: rep_t = @bitCast(rep_t, b) & absMask; return @boolToInt(aAbs > infRep or bAbs > infRep); } -pub extern fn __eqsf2(a: fp_t, b: fp_t) c_int { +pub fn __eqsf2(a: fp_t, b: fp_t) callconv(.C) c_int { return __lesf2(a, b); } -pub extern fn __ltsf2(a: fp_t, b: fp_t) c_int { +pub fn __ltsf2(a: fp_t, b: fp_t) callconv(.C) c_int { return __lesf2(a, b); } -pub extern fn __nesf2(a: fp_t, b: fp_t) c_int { +pub fn __nesf2(a: fp_t, b: fp_t) callconv(.C) c_int { return __lesf2(a, b); } -pub extern fn __gtsf2(a: fp_t, b: fp_t) c_int { +pub fn __gtsf2(a: fp_t, b: fp_t) callconv(.C) c_int { return __gesf2(a, b); } diff --git a/lib/std/special/compiler_rt/comparetf2.zig b/lib/std/special/compiler_rt/comparetf2.zig index e973018455..f2969f2112 100644 --- a/lib/std/special/compiler_rt/comparetf2.zig +++ b/lib/std/special/compiler_rt/comparetf2.zig @@ -21,7 +21,7 @@ const infRep = exponentMask; const builtin = @import("builtin"); const is_test = builtin.is_test; -pub extern fn __letf2(a: f128, b: f128) c_int { +pub fn __letf2(a: f128, b: f128) callconv(.C) c_int { @setRuntimeSafety(is_test); const aInt = @bitCast(rep_t, a); @@ -65,7 +65,7 @@ const GE_EQUAL = @as(c_int, 0); const GE_GREATER = @as(c_int, 1); const GE_UNORDERED = @as(c_int, -1); // Note: different from LE_UNORDERED -pub extern fn __getf2(a: f128, b: f128) c_int { +pub fn __getf2(a: f128, b: f128) callconv(.C) c_int { @setRuntimeSafety(is_test); const aInt = @bitCast(srep_t, a); @@ -90,7 +90,7 @@ pub extern fn __getf2(a: f128, b: f128) c_int { GE_GREATER; } -pub extern fn __unordtf2(a: f128, b: f128) c_int { +pub fn __unordtf2(a: f128, b: f128) callconv(.C) c_int { @setRuntimeSafety(is_test); const aAbs = @bitCast(rep_t, a) & absMask; diff --git a/lib/std/special/compiler_rt/divdf3.zig b/lib/std/special/compiler_rt/divdf3.zig index 9937b09497..a8afd4a3a6 100644 --- a/lib/std/special/compiler_rt/divdf3.zig +++ b/lib/std/special/compiler_rt/divdf3.zig @@ -5,7 +5,7 @@ const std = @import("std"); const builtin = @import("builtin"); -pub extern fn __divdf3(a: f64, b: f64) f64 { +pub fn __divdf3(a: f64, b: f64) callconv(.C) f64 { @setRuntimeSafety(builtin.is_test); const Z = @IntType(false, f64.bit_count); const SignedZ = @IntType(true, f64.bit_count); diff --git a/lib/std/special/compiler_rt/divsf3.zig b/lib/std/special/compiler_rt/divsf3.zig index 4ee2eed36c..ea882b4927 100644 --- a/lib/std/special/compiler_rt/divsf3.zig +++ b/lib/std/special/compiler_rt/divsf3.zig @@ -5,7 +5,7 @@ const std = @import("std"); const builtin = @import("builtin"); -pub extern fn __divsf3(a: f32, b: f32) f32 { +pub fn __divsf3(a: f32, b: f32) callconv(.C) f32 { @setRuntimeSafety(builtin.is_test); const Z = @IntType(false, f32.bit_count); diff --git a/lib/std/special/compiler_rt/divti3.zig b/lib/std/special/compiler_rt/divti3.zig index fcb23a50d9..2b878f5269 100644 --- a/lib/std/special/compiler_rt/divti3.zig +++ b/lib/std/special/compiler_rt/divti3.zig @@ -1,7 +1,7 @@ const udivmod = @import("udivmod.zig").udivmod; const builtin = @import("builtin"); -pub extern fn __divti3(a: i128, b: i128) i128 { +pub fn __divti3(a: i128, b: i128) callconv(.C) i128 { @setRuntimeSafety(builtin.is_test); const s_a = a >> (i128.bit_count - 1); @@ -16,7 +16,7 @@ pub extern fn __divti3(a: i128, b: i128) i128 { } const v128 = @Vector(2, u64); -pub extern fn __divti3_windows_x86_64(a: v128, b: v128) v128 { +pub fn __divti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 { return @bitCast(v128, @call(.{ .modifier = .always_inline }, __divti3, .{ @bitCast(i128, a), @bitCast(i128, b), diff --git a/lib/std/special/compiler_rt/extendXfYf2.zig b/lib/std/special/compiler_rt/extendXfYf2.zig index 427bd4ec24..10227043aa 100644 --- a/lib/std/special/compiler_rt/extendXfYf2.zig +++ b/lib/std/special/compiler_rt/extendXfYf2.zig @@ -2,19 +2,19 @@ const std = @import("std"); const builtin = @import("builtin"); const is_test = builtin.is_test; -pub extern fn __extendsfdf2(a: f32) f64 { +pub fn __extendsfdf2(a: f32) callconv(.C) f64 { return @call(.{ .modifier = .always_inline }, extendXfYf2, .{ f64, f32, @bitCast(u32, a) }); } -pub extern fn __extenddftf2(a: f64) f128 { +pub fn __extenddftf2(a: f64) callconv(.C) f128 { return @call(.{ .modifier = .always_inline }, extendXfYf2, .{ f128, f64, @bitCast(u64, a) }); } -pub extern fn __extendsftf2(a: f32) f128 { +pub fn __extendsftf2(a: f32) callconv(.C) f128 { return @call(.{ .modifier = .always_inline }, extendXfYf2, .{ f128, f32, @bitCast(u32, a) }); } -pub extern fn __extendhfsf2(a: u16) f32 { +pub fn __extendhfsf2(a: u16) callconv(.C) f32 { return @call(.{ .modifier = .always_inline }, extendXfYf2, .{ f32, f16, a }); } diff --git a/lib/std/special/compiler_rt/fixdfdi.zig b/lib/std/special/compiler_rt/fixdfdi.zig index c108fd15aa..fb3b31d6e8 100644 --- a/lib/std/special/compiler_rt/fixdfdi.zig +++ b/lib/std/special/compiler_rt/fixdfdi.zig @@ -1,7 +1,7 @@ const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); -pub extern fn __fixdfdi(a: f64) i64 { +pub fn __fixdfdi(a: f64) callconv(.C) i64 { @setRuntimeSafety(builtin.is_test); return fixint(f64, i64, a); } diff --git a/lib/std/special/compiler_rt/fixdfsi.zig b/lib/std/special/compiler_rt/fixdfsi.zig index 83a17b2b0d..de21c86e43 100644 --- a/lib/std/special/compiler_rt/fixdfsi.zig +++ b/lib/std/special/compiler_rt/fixdfsi.zig @@ -1,7 +1,7 @@ const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); -pub extern fn __fixdfsi(a: f64) i32 { +pub fn __fixdfsi(a: f64) callconv(.C) i32 { @setRuntimeSafety(builtin.is_test); return fixint(f64, i32, a); } diff --git a/lib/std/special/compiler_rt/fixdfti.zig b/lib/std/special/compiler_rt/fixdfti.zig index e30f885cf6..0e21f0ba19 100644 --- a/lib/std/special/compiler_rt/fixdfti.zig +++ b/lib/std/special/compiler_rt/fixdfti.zig @@ -1,7 +1,7 @@ const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); -pub extern fn __fixdfti(a: f64) i128 { +pub fn __fixdfti(a: f64) callconv(.C) i128 { @setRuntimeSafety(builtin.is_test); return fixint(f64, i128, a); } diff --git a/lib/std/special/compiler_rt/fixsfdi.zig b/lib/std/special/compiler_rt/fixsfdi.zig index ffa81d13ab..d3aaf9d470 100644 --- a/lib/std/special/compiler_rt/fixsfdi.zig +++ b/lib/std/special/compiler_rt/fixsfdi.zig @@ -1,7 +1,7 @@ const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); -pub extern fn __fixsfdi(a: f32) i64 { +pub fn __fixsfdi(a: f32) callconv(.C) i64 { @setRuntimeSafety(builtin.is_test); return fixint(f32, i64, a); } diff --git a/lib/std/special/compiler_rt/fixsfsi.zig b/lib/std/special/compiler_rt/fixsfsi.zig index 9a94b4395b..81aa01dfa1 100644 --- a/lib/std/special/compiler_rt/fixsfsi.zig +++ b/lib/std/special/compiler_rt/fixsfsi.zig @@ -1,7 +1,7 @@ const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); -pub extern fn __fixsfsi(a: f32) i32 { +pub fn __fixsfsi(a: f32) callconv(.C) i32 { @setRuntimeSafety(builtin.is_test); return fixint(f32, i32, a); } diff --git a/lib/std/special/compiler_rt/fixsfti.zig b/lib/std/special/compiler_rt/fixsfti.zig index 806a1678aa..d7ce4b3a60 100644 --- a/lib/std/special/compiler_rt/fixsfti.zig +++ b/lib/std/special/compiler_rt/fixsfti.zig @@ -1,7 +1,7 @@ const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); -pub extern fn __fixsfti(a: f32) i128 { +pub fn __fixsfti(a: f32) callconv(.C) i128 { @setRuntimeSafety(builtin.is_test); return fixint(f32, i128, a); } diff --git a/lib/std/special/compiler_rt/fixtfdi.zig b/lib/std/special/compiler_rt/fixtfdi.zig index 8d99231b74..0ef3aa2259 100644 --- a/lib/std/special/compiler_rt/fixtfdi.zig +++ b/lib/std/special/compiler_rt/fixtfdi.zig @@ -1,7 +1,7 @@ const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); -pub extern fn __fixtfdi(a: f128) i64 { +pub fn __fixtfdi(a: f128) callconv(.C) i64 { @setRuntimeSafety(builtin.is_test); return fixint(f128, i64, a); } diff --git a/lib/std/special/compiler_rt/fixtfsi.zig b/lib/std/special/compiler_rt/fixtfsi.zig index f3f83634b2..15e89a11b0 100644 --- a/lib/std/special/compiler_rt/fixtfsi.zig +++ b/lib/std/special/compiler_rt/fixtfsi.zig @@ -1,7 +1,7 @@ const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); -pub extern fn __fixtfsi(a: f128) i32 { +pub fn __fixtfsi(a: f128) callconv(.C) i32 { @setRuntimeSafety(builtin.is_test); return fixint(f128, i32, a); } diff --git a/lib/std/special/compiler_rt/fixtfti.zig b/lib/std/special/compiler_rt/fixtfti.zig index 07d38f2c3b..733fa1eed1 100644 --- a/lib/std/special/compiler_rt/fixtfti.zig +++ b/lib/std/special/compiler_rt/fixtfti.zig @@ -1,7 +1,7 @@ const fixint = @import("fixint.zig").fixint; const builtin = @import("builtin"); -pub extern fn __fixtfti(a: f128) i128 { +pub fn __fixtfti(a: f128) callconv(.C) i128 { @setRuntimeSafety(builtin.is_test); return fixint(f128, i128, a); } diff --git a/lib/std/special/compiler_rt/fixunsdfdi.zig b/lib/std/special/compiler_rt/fixunsdfdi.zig index 1fa7ed758e..9d41d4b740 100644 --- a/lib/std/special/compiler_rt/fixunsdfdi.zig +++ b/lib/std/special/compiler_rt/fixunsdfdi.zig @@ -1,7 +1,7 @@ const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); -pub extern fn __fixunsdfdi(a: f64) u64 { +pub fn __fixunsdfdi(a: f64) callconv(.C) u64 { @setRuntimeSafety(builtin.is_test); return fixuint(f64, u64, a); } diff --git a/lib/std/special/compiler_rt/fixunsdfsi.zig b/lib/std/special/compiler_rt/fixunsdfsi.zig index a77cb8df89..044523512c 100644 --- a/lib/std/special/compiler_rt/fixunsdfsi.zig +++ b/lib/std/special/compiler_rt/fixunsdfsi.zig @@ -1,7 +1,7 @@ const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); -pub extern fn __fixunsdfsi(a: f64) u32 { +pub fn __fixunsdfsi(a: f64) callconv(.C) u32 { @setRuntimeSafety(builtin.is_test); return fixuint(f64, u32, a); } diff --git a/lib/std/special/compiler_rt/fixunsdfti.zig b/lib/std/special/compiler_rt/fixunsdfti.zig index 6e1ded46e5..3dcec6bf89 100644 --- a/lib/std/special/compiler_rt/fixunsdfti.zig +++ b/lib/std/special/compiler_rt/fixunsdfti.zig @@ -1,7 +1,7 @@ const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); -pub extern fn __fixunsdfti(a: f64) u128 { +pub fn __fixunsdfti(a: f64) callconv(.C) u128 { @setRuntimeSafety(builtin.is_test); return fixuint(f64, u128, a); } diff --git a/lib/std/special/compiler_rt/fixunssfdi.zig b/lib/std/special/compiler_rt/fixunssfdi.zig index 36d4acc28c..a42121aeec 100644 --- a/lib/std/special/compiler_rt/fixunssfdi.zig +++ b/lib/std/special/compiler_rt/fixunssfdi.zig @@ -1,7 +1,7 @@ const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); -pub extern fn __fixunssfdi(a: f32) u64 { +pub fn __fixunssfdi(a: f32) callconv(.C) u64 { @setRuntimeSafety(builtin.is_test); return fixuint(f32, u64, a); } diff --git a/lib/std/special/compiler_rt/fixunssfsi.zig b/lib/std/special/compiler_rt/fixunssfsi.zig index 53130286a1..00f7c8ad22 100644 --- a/lib/std/special/compiler_rt/fixunssfsi.zig +++ b/lib/std/special/compiler_rt/fixunssfsi.zig @@ -1,7 +1,7 @@ const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); -pub extern fn __fixunssfsi(a: f32) u32 { +pub fn __fixunssfsi(a: f32) callconv(.C) u32 { @setRuntimeSafety(builtin.is_test); return fixuint(f32, u32, a); } diff --git a/lib/std/special/compiler_rt/fixunssfti.zig b/lib/std/special/compiler_rt/fixunssfti.zig index f0cd788d2e..dff9eb7498 100644 --- a/lib/std/special/compiler_rt/fixunssfti.zig +++ b/lib/std/special/compiler_rt/fixunssfti.zig @@ -1,7 +1,7 @@ const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); -pub extern fn __fixunssfti(a: f32) u128 { +pub fn __fixunssfti(a: f32) callconv(.C) u128 { @setRuntimeSafety(builtin.is_test); return fixuint(f32, u128, a); } diff --git a/lib/std/special/compiler_rt/fixunstfdi.zig b/lib/std/special/compiler_rt/fixunstfdi.zig index e352044708..907116c165 100644 --- a/lib/std/special/compiler_rt/fixunstfdi.zig +++ b/lib/std/special/compiler_rt/fixunstfdi.zig @@ -1,7 +1,7 @@ const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); -pub extern fn __fixunstfdi(a: f128) u64 { +pub fn __fixunstfdi(a: f128) callconv(.C) u64 { @setRuntimeSafety(builtin.is_test); return fixuint(f128, u64, a); } diff --git a/lib/std/special/compiler_rt/fixunstfsi.zig b/lib/std/special/compiler_rt/fixunstfsi.zig index 579c559790..c66a3f18b4 100644 --- a/lib/std/special/compiler_rt/fixunstfsi.zig +++ b/lib/std/special/compiler_rt/fixunstfsi.zig @@ -1,7 +1,7 @@ const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); -pub extern fn __fixunstfsi(a: f128) u32 { +pub fn __fixunstfsi(a: f128) callconv(.C) u32 { @setRuntimeSafety(builtin.is_test); return fixuint(f128, u32, a); } diff --git a/lib/std/special/compiler_rt/fixunstfti.zig b/lib/std/special/compiler_rt/fixunstfti.zig index cd6178164a..1867c69234 100644 --- a/lib/std/special/compiler_rt/fixunstfti.zig +++ b/lib/std/special/compiler_rt/fixunstfti.zig @@ -1,7 +1,7 @@ const fixuint = @import("fixuint.zig").fixuint; const builtin = @import("builtin"); -pub extern fn __fixunstfti(a: f128) u128 { +pub fn __fixunstfti(a: f128) callconv(.C) u128 { @setRuntimeSafety(builtin.is_test); return fixuint(f128, u128, a); } diff --git a/lib/std/special/compiler_rt/floatdidf.zig b/lib/std/special/compiler_rt/floatdidf.zig index 1610136413..93bd0c8a3e 100644 --- a/lib/std/special/compiler_rt/floatdidf.zig +++ b/lib/std/special/compiler_rt/floatdidf.zig @@ -4,7 +4,7 @@ const std = @import("std"); const twop52: f64 = 0x1.0p52; const twop32: f64 = 0x1.0p32; -pub extern fn __floatdidf(a: i64) f64 { +pub fn __floatdidf(a: i64) callconv(.C) f64 { @setRuntimeSafety(builtin.is_test); if (a == 0) return 0; diff --git a/lib/std/special/compiler_rt/floatsiXf.zig b/lib/std/special/compiler_rt/floatsiXf.zig index 917dfb47fc..30a09de90c 100644 --- a/lib/std/special/compiler_rt/floatsiXf.zig +++ b/lib/std/special/compiler_rt/floatsiXf.zig @@ -53,17 +53,17 @@ fn floatsiXf(comptime T: type, a: i32) T { return @bitCast(T, result); } -pub extern fn __floatsisf(arg: i32) f32 { +pub fn __floatsisf(arg: i32) callconv(.C) f32 { @setRuntimeSafety(builtin.is_test); return @call(.{ .modifier = .always_inline }, floatsiXf, .{ f32, arg }); } -pub extern fn __floatsidf(arg: i32) f64 { +pub fn __floatsidf(arg: i32) callconv(.C) f64 { @setRuntimeSafety(builtin.is_test); return @call(.{ .modifier = .always_inline }, floatsiXf, .{ f64, arg }); } -pub extern fn __floatsitf(arg: i32) f128 { +pub fn __floatsitf(arg: i32) callconv(.C) f128 { @setRuntimeSafety(builtin.is_test); return @call(.{ .modifier = .always_inline }, floatsiXf, .{ f128, arg }); } diff --git a/lib/std/special/compiler_rt/floattidf.zig b/lib/std/special/compiler_rt/floattidf.zig index 1e83674598..6b5013287b 100644 --- a/lib/std/special/compiler_rt/floattidf.zig +++ b/lib/std/special/compiler_rt/floattidf.zig @@ -5,7 +5,7 @@ const maxInt = std.math.maxInt; const DBL_MANT_DIG = 53; -pub extern fn __floattidf(arg: i128) f64 { +pub fn __floattidf(arg: i128) callconv(.C) f64 { @setRuntimeSafety(is_test); if (arg == 0) diff --git a/lib/std/special/compiler_rt/floattisf.zig b/lib/std/special/compiler_rt/floattisf.zig index 0c02bfff1f..3f020dadd8 100644 --- a/lib/std/special/compiler_rt/floattisf.zig +++ b/lib/std/special/compiler_rt/floattisf.zig @@ -5,7 +5,7 @@ const maxInt = std.math.maxInt; const FLT_MANT_DIG = 24; -pub extern fn __floattisf(arg: i128) f32 { +pub fn __floattisf(arg: i128) callconv(.C) f32 { @setRuntimeSafety(is_test); if (arg == 0) diff --git a/lib/std/special/compiler_rt/floattitf.zig b/lib/std/special/compiler_rt/floattitf.zig index aac22e36d0..90bc241306 100644 --- a/lib/std/special/compiler_rt/floattitf.zig +++ b/lib/std/special/compiler_rt/floattitf.zig @@ -5,7 +5,7 @@ const maxInt = std.math.maxInt; const LDBL_MANT_DIG = 113; -pub extern fn __floattitf(arg: i128) f128 { +pub fn __floattitf(arg: i128) callconv(.C) f128 { @setRuntimeSafety(is_test); if (arg == 0) diff --git a/lib/std/special/compiler_rt/floatundidf.zig b/lib/std/special/compiler_rt/floatundidf.zig index 68759a2acd..c8803b4c6c 100644 --- a/lib/std/special/compiler_rt/floatundidf.zig +++ b/lib/std/special/compiler_rt/floatundidf.zig @@ -5,7 +5,7 @@ const twop52: f64 = 0x1.0p52; const twop84: f64 = 0x1.0p84; const twop84_plus_twop52: f64 = 0x1.00000001p84; -pub extern fn __floatundidf(a: u64) f64 { +pub fn __floatundidf(a: u64) callconv(.C) f64 { @setRuntimeSafety(builtin.is_test); if (a == 0) return 0; diff --git a/lib/std/special/compiler_rt/floatunditf.zig b/lib/std/special/compiler_rt/floatunditf.zig index 9af83a2b5d..b574d21bd8 100644 --- a/lib/std/special/compiler_rt/floatunditf.zig +++ b/lib/std/special/compiler_rt/floatunditf.zig @@ -2,7 +2,7 @@ const builtin = @import("builtin"); const is_test = builtin.is_test; const std = @import("std"); -pub extern fn __floatunditf(a: u128) f128 { +pub fn __floatunditf(a: u128) callconv(.C) f128 { @setRuntimeSafety(is_test); if (a == 0) { diff --git a/lib/std/special/compiler_rt/floatunsidf.zig b/lib/std/special/compiler_rt/floatunsidf.zig index d744009aea..92a7870806 100644 --- a/lib/std/special/compiler_rt/floatunsidf.zig +++ b/lib/std/special/compiler_rt/floatunsidf.zig @@ -4,7 +4,7 @@ const maxInt = std.math.maxInt; const implicitBit = @as(u64, 1) << 52; -pub extern fn __floatunsidf(arg: u32) f64 { +pub fn __floatunsidf(arg: u32) callconv(.C) f64 { @setRuntimeSafety(builtin.is_test); if (arg == 0) return 0.0; diff --git a/lib/std/special/compiler_rt/floatunsitf.zig b/lib/std/special/compiler_rt/floatunsitf.zig index 18397f8ad0..a10ff6b703 100644 --- a/lib/std/special/compiler_rt/floatunsitf.zig +++ b/lib/std/special/compiler_rt/floatunsitf.zig @@ -2,7 +2,7 @@ const builtin = @import("builtin"); const is_test = builtin.is_test; const std = @import("std"); -pub extern fn __floatunsitf(a: u64) f128 { +pub fn __floatunsitf(a: u64) callconv(.C) f128 { @setRuntimeSafety(is_test); if (a == 0) { diff --git a/lib/std/special/compiler_rt/floatuntidf.zig b/lib/std/special/compiler_rt/floatuntidf.zig index 5d3a201058..5b5adc0491 100644 --- a/lib/std/special/compiler_rt/floatuntidf.zig +++ b/lib/std/special/compiler_rt/floatuntidf.zig @@ -5,7 +5,7 @@ const maxInt = std.math.maxInt; const DBL_MANT_DIG = 53; -pub extern fn __floatuntidf(arg: u128) f64 { +pub fn __floatuntidf(arg: u128) callconv(.C) f64 { @setRuntimeSafety(is_test); if (arg == 0) diff --git a/lib/std/special/compiler_rt/floatuntisf.zig b/lib/std/special/compiler_rt/floatuntisf.zig index e450ad9a48..33e6e41a84 100644 --- a/lib/std/special/compiler_rt/floatuntisf.zig +++ b/lib/std/special/compiler_rt/floatuntisf.zig @@ -5,7 +5,7 @@ const maxInt = std.math.maxInt; const FLT_MANT_DIG = 24; -pub extern fn __floatuntisf(arg: u128) f32 { +pub fn __floatuntisf(arg: u128) callconv(.C) f32 { @setRuntimeSafety(is_test); if (arg == 0) diff --git a/lib/std/special/compiler_rt/floatuntitf.zig b/lib/std/special/compiler_rt/floatuntitf.zig index f92942e034..0b96076206 100644 --- a/lib/std/special/compiler_rt/floatuntitf.zig +++ b/lib/std/special/compiler_rt/floatuntitf.zig @@ -5,7 +5,7 @@ const maxInt = std.math.maxInt; const LDBL_MANT_DIG = 113; -pub extern fn __floatuntitf(arg: u128) f128 { +pub fn __floatuntitf(arg: u128) callconv(.C) f128 { @setRuntimeSafety(is_test); if (arg == 0) diff --git a/lib/std/special/compiler_rt/lshrti3.zig b/lib/std/special/compiler_rt/lshrti3.zig index 329968ae40..043be5e2a2 100644 --- a/lib/std/special/compiler_rt/lshrti3.zig +++ b/lib/std/special/compiler_rt/lshrti3.zig @@ -1,7 +1,7 @@ const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); -pub extern fn __lshrti3(a: i128, b: i32) i128 { +pub fn __lshrti3(a: i128, b: i32) callconv(.C) i128 { var input = twords{ .all = a }; var result: twords = undefined; diff --git a/lib/std/special/compiler_rt/modti3.zig b/lib/std/special/compiler_rt/modti3.zig index d983ecba5f..a9d1f48468 100644 --- a/lib/std/special/compiler_rt/modti3.zig +++ b/lib/std/special/compiler_rt/modti3.zig @@ -6,7 +6,7 @@ const udivmod = @import("udivmod.zig").udivmod; const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); -pub extern fn __modti3(a: i128, b: i128) i128 { +pub fn __modti3(a: i128, b: i128) callconv(.C) i128 { @setRuntimeSafety(builtin.is_test); const s_a = a >> (i128.bit_count - 1); // s = a < 0 ? -1 : 0 @@ -21,7 +21,7 @@ pub extern fn __modti3(a: i128, b: i128) i128 { } const v128 = @Vector(2, u64); -pub extern fn __modti3_windows_x86_64(a: v128, b: v128) v128 { +pub fn __modti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 { return @bitCast(v128, @call(.{ .modifier = .always_inline }, __modti3, .{ @bitCast(i128, a), @bitCast(i128, b), diff --git a/lib/std/special/compiler_rt/mulXf3.zig b/lib/std/special/compiler_rt/mulXf3.zig index 11ee0b49a4..9457bfb86e 100644 --- a/lib/std/special/compiler_rt/mulXf3.zig +++ b/lib/std/special/compiler_rt/mulXf3.zig @@ -6,13 +6,13 @@ const std = @import("std"); const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); -pub extern fn __multf3(a: f128, b: f128) f128 { +pub fn __multf3(a: f128, b: f128) callconv(.C) f128 { return mulXf3(f128, a, b); } -pub extern fn __muldf3(a: f64, b: f64) f64 { +pub fn __muldf3(a: f64, b: f64) callconv(.C) f64 { return mulXf3(f64, a, b); } -pub extern fn __mulsf3(a: f32, b: f32) f32 { +pub fn __mulsf3(a: f32, b: f32) callconv(.C) f32 { return mulXf3(f32, a, b); } diff --git a/lib/std/special/compiler_rt/muldi3.zig b/lib/std/special/compiler_rt/muldi3.zig index 3efc5a9ac6..4f605d441c 100644 --- a/lib/std/special/compiler_rt/muldi3.zig +++ b/lib/std/special/compiler_rt/muldi3.zig @@ -39,7 +39,7 @@ fn __muldsi3(a: u32, b: u32) i64 { return r.all; } -pub extern fn __muldi3(a: i64, b: i64) i64 { +pub fn __muldi3(a: i64, b: i64) callconv(.C) i64 { @setRuntimeSafety(builtin.is_test); const x = dwords{ .all = a }; diff --git a/lib/std/special/compiler_rt/mulodi4.zig b/lib/std/special/compiler_rt/mulodi4.zig index 21c7fd1f97..b70d1657e7 100644 --- a/lib/std/special/compiler_rt/mulodi4.zig +++ b/lib/std/special/compiler_rt/mulodi4.zig @@ -3,7 +3,7 @@ const compiler_rt = @import("../compiler_rt.zig"); const maxInt = std.math.maxInt; const minInt = std.math.minInt; -pub extern fn __mulodi4(a: i64, b: i64, overflow: *c_int) i64 { +pub fn __mulodi4(a: i64, b: i64, overflow: *c_int) callconv(.C) i64 { @setRuntimeSafety(builtin.is_test); const min = @bitCast(i64, @as(u64, 1 << (i64.bit_count - 1))); diff --git a/lib/std/special/compiler_rt/muloti4.zig b/lib/std/special/compiler_rt/muloti4.zig index ad6ad43808..190959b801 100644 --- a/lib/std/special/compiler_rt/muloti4.zig +++ b/lib/std/special/compiler_rt/muloti4.zig @@ -1,7 +1,7 @@ const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); -pub extern fn __muloti4(a: i128, b: i128, overflow: *c_int) i128 { +pub fn __muloti4(a: i128, b: i128, overflow: *c_int) callconv(.C) i128 { @setRuntimeSafety(builtin.is_test); const min = @bitCast(i128, @as(u128, 1 << (i128.bit_count - 1))); diff --git a/lib/std/special/compiler_rt/multi3.zig b/lib/std/special/compiler_rt/multi3.zig index 56ff56cbb2..f46bd55421 100644 --- a/lib/std/special/compiler_rt/multi3.zig +++ b/lib/std/special/compiler_rt/multi3.zig @@ -5,7 +5,7 @@ const compiler_rt = @import("../compiler_rt.zig"); // ae684fad6d34858c014c94da69c15e7774a633c3 // 2018-08-13 -pub extern fn __multi3(a: i128, b: i128) i128 { +pub fn __multi3(a: i128, b: i128) callconv(.C) i128 { @setRuntimeSafety(builtin.is_test); const x = twords{ .all = a }; const y = twords{ .all = b }; @@ -15,7 +15,7 @@ pub extern fn __multi3(a: i128, b: i128) i128 { } const v128 = @Vector(2, u64); -pub extern fn __multi3_windows_x86_64(a: v128, b: v128) v128 { +pub fn __multi3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 { return @bitCast(v128, @call(.{ .modifier = .always_inline }, __multi3, .{ @bitCast(i128, a), @bitCast(i128, b), diff --git a/lib/std/special/compiler_rt/negXf2.zig b/lib/std/special/compiler_rt/negXf2.zig index c4be085d62..e21e36b955 100644 --- a/lib/std/special/compiler_rt/negXf2.zig +++ b/lib/std/special/compiler_rt/negXf2.zig @@ -1,10 +1,10 @@ const std = @import("std"); -pub extern fn __negsf2(a: f32) f32 { +pub fn __negsf2(a: f32) callconv(.C) f32 { return negXf2(f32, a); } -pub extern fn __negdf2(a: f64) f64 { +pub fn __negdf2(a: f64) callconv(.C) f64 { return negXf2(f64, a); } diff --git a/lib/std/special/compiler_rt/popcountdi2.zig b/lib/std/special/compiler_rt/popcountdi2.zig index ea36b0ec44..b7e7220c7b 100644 --- a/lib/std/special/compiler_rt/popcountdi2.zig +++ b/lib/std/special/compiler_rt/popcountdi2.zig @@ -2,7 +2,7 @@ const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); // ported from llvm compiler-rt 8.0.0rc3 95e1c294cb0415a377a7b1d6c7c7d4f89e1c04e4 -pub extern fn __popcountdi2(a: i64) i32 { +pub fn __popcountdi2(a: i64) callconv(.C) i32 { var x2 = @bitCast(u64, a); x2 = x2 - ((x2 >> 1) & 0x5555555555555555); // Every 2 bits holds the sum of every pair of bits (32) diff --git a/lib/std/special/compiler_rt/stack_probe.zig b/lib/std/special/compiler_rt/stack_probe.zig index 6406f3977a..dd441b2f32 100644 --- a/lib/std/special/compiler_rt/stack_probe.zig +++ b/lib/std/special/compiler_rt/stack_probe.zig @@ -1,7 +1,7 @@ const builtin = @import("builtin"); // Zig's own stack-probe routine (available only on x86 and x86_64) -pub nakedcc fn zig_probe_stack() void { +pub fn zig_probe_stack() callconv(.Naked) void { @setRuntimeSafety(false); // Versions of the Linux kernel before 5.1 treat any access below SP as @@ -180,11 +180,11 @@ fn win_probe_stack_adjust_sp() void { // ___chkstk (__alloca) | yes | yes | // ___chkstk_ms | no | no | -pub nakedcc fn _chkstk() void { +pub fn _chkstk() callconv(.Naked) void { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}); } -pub nakedcc fn __chkstk() void { +pub fn __chkstk() callconv(.Naked) void { @setRuntimeSafety(false); switch (builtin.arch) { .i386 => @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}), @@ -192,15 +192,15 @@ pub nakedcc fn __chkstk() void { else => unreachable, } } -pub nakedcc fn ___chkstk() void { +pub fn ___chkstk() callconv(.Naked) void { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}); } -pub nakedcc fn __chkstk_ms() void { +pub fn __chkstk_ms() callconv(.Naked) void { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{}); } -pub nakedcc fn ___chkstk_ms() void { +pub fn ___chkstk_ms() callconv(.Naked) void { @setRuntimeSafety(false); @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{}); } diff --git a/lib/std/special/compiler_rt/truncXfYf2.zig b/lib/std/special/compiler_rt/truncXfYf2.zig index d231c0d416..10b097e777 100644 --- a/lib/std/special/compiler_rt/truncXfYf2.zig +++ b/lib/std/special/compiler_rt/truncXfYf2.zig @@ -1,22 +1,22 @@ const std = @import("std"); -pub extern fn __truncsfhf2(a: f32) u16 { +pub fn __truncsfhf2(a: f32) callconv(.C) u16 { return @bitCast(u16, truncXfYf2(f16, f32, a)); } -pub extern fn __truncdfhf2(a: f64) u16 { +pub fn __truncdfhf2(a: f64) callconv(.C) u16 { return @bitCast(u16, truncXfYf2(f16, f64, a)); } -pub extern fn __trunctfsf2(a: f128) f32 { +pub fn __trunctfsf2(a: f128) callconv(.C) f32 { return truncXfYf2(f32, f128, a); } -pub extern fn __trunctfdf2(a: f128) f64 { +pub fn __trunctfdf2(a: f128) callconv(.C) f64 { return truncXfYf2(f64, f128, a); } -pub extern fn __truncdfsf2(a: f64) f32 { +pub fn __truncdfsf2(a: f64) callconv(.C) f32 { return truncXfYf2(f32, f64, a); } diff --git a/lib/std/special/compiler_rt/udivmoddi4.zig b/lib/std/special/compiler_rt/udivmoddi4.zig index de86c845e5..79f0f39986 100644 --- a/lib/std/special/compiler_rt/udivmoddi4.zig +++ b/lib/std/special/compiler_rt/udivmoddi4.zig @@ -1,7 +1,7 @@ const udivmod = @import("udivmod.zig").udivmod; const builtin = @import("builtin"); -pub extern fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) u64 { +pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.C) u64 { @setRuntimeSafety(builtin.is_test); return udivmod(u64, a, b, maybe_rem); } diff --git a/lib/std/special/compiler_rt/udivmodti4.zig b/lib/std/special/compiler_rt/udivmodti4.zig index c74dff512d..7a3405c3e2 100644 --- a/lib/std/special/compiler_rt/udivmodti4.zig +++ b/lib/std/special/compiler_rt/udivmodti4.zig @@ -2,13 +2,13 @@ const udivmod = @import("udivmod.zig").udivmod; const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); -pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?*u128) u128 { +pub fn __udivmodti4(a: u128, b: u128, maybe_rem: ?*u128) callconv(.C) u128 { @setRuntimeSafety(builtin.is_test); return udivmod(u128, a, b, maybe_rem); } const v128 = @Vector(2, u64); -pub extern fn __udivmodti4_windows_x86_64(a: v128, b: v128, maybe_rem: ?*u128) v128 { +pub fn __udivmodti4_windows_x86_64(a: v128, b: v128, maybe_rem: ?*u128) callconv(.C) v128 { @setRuntimeSafety(builtin.is_test); return @bitCast(v128, udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), maybe_rem)); } diff --git a/lib/std/special/compiler_rt/udivti3.zig b/lib/std/special/compiler_rt/udivti3.zig index ab451859bf..6283285e01 100644 --- a/lib/std/special/compiler_rt/udivti3.zig +++ b/lib/std/special/compiler_rt/udivti3.zig @@ -1,13 +1,13 @@ const udivmodti4 = @import("udivmodti4.zig"); const builtin = @import("builtin"); -pub extern fn __udivti3(a: u128, b: u128) u128 { +pub fn __udivti3(a: u128, b: u128) callconv(.C) u128 { @setRuntimeSafety(builtin.is_test); return udivmodti4.__udivmodti4(a, b, null); } const v128 = @Vector(2, u64); -pub extern fn __udivti3_windows_x86_64(a: v128, b: v128) v128 { +pub fn __udivti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 { @setRuntimeSafety(builtin.is_test); return udivmodti4.__udivmodti4_windows_x86_64(a, b, null); } diff --git a/lib/std/special/compiler_rt/umodti3.zig b/lib/std/special/compiler_rt/umodti3.zig index 9d4a42147c..4f9890f512 100644 --- a/lib/std/special/compiler_rt/umodti3.zig +++ b/lib/std/special/compiler_rt/umodti3.zig @@ -2,7 +2,7 @@ const udivmodti4 = @import("udivmodti4.zig"); const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); -pub extern fn __umodti3(a: u128, b: u128) u128 { +pub fn __umodti3(a: u128, b: u128) callconv(.C) u128 { @setRuntimeSafety(builtin.is_test); var r: u128 = undefined; _ = udivmodti4.__udivmodti4(a, b, &r); @@ -10,7 +10,7 @@ pub extern fn __umodti3(a: u128, b: u128) u128 { } const v128 = @Vector(2, u64); -pub extern fn __umodti3_windows_x86_64(a: v128, b: v128) v128 { +pub fn __umodti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 { return @bitCast(v128, @call(.{ .modifier = .always_inline }, __umodti3, .{ @bitCast(u128, a), @bitCast(u128, b), diff --git a/lib/std/spinlock.zig b/lib/std/spinlock.zig index 4efd244367..1a3239a95c 100644 --- a/lib/std/spinlock.zig +++ b/lib/std/spinlock.zig @@ -60,8 +60,16 @@ pub const SpinLock = struct { switch (builtin.arch) { // these instructions use a memory clobber as they // flush the pipeline of any speculated reads/writes. - .i386, .x86_64 => asm volatile ("pause" ::: "memory"), - .arm, .aarch64 => asm volatile ("yield" ::: "memory"), + .i386, .x86_64 => asm volatile ("pause" + : + : + : "memory" + ), + .arm, .aarch64 => asm volatile ("yield" + : + : + : "memory" + ), else => std.os.sched_yield() catch {}, } } diff --git a/lib/std/start.zig b/lib/std/start.zig index 3c46449949..7c1353e18b 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -43,11 +43,7 @@ comptime { } } -stdcallcc fn _DllMainCRTStartup( - hinstDLL: std.os.windows.HINSTANCE, - fdwReason: std.os.windows.DWORD, - lpReserved: std.os.windows.LPVOID, -) std.os.windows.BOOL { +fn _DllMainCRTStartup(hinstDLL: std.os.windows.HINSTANCE, fdwReason: std.os.windows.DWORD, lpReserved: std.os.windows.LPVOID) callconv(.Stdcall) std.os.windows.BOOL { if (@hasDecl(root, "DllMain")) { return root.DllMain(hinstDLL, fdwReason, lpReserved); } @@ -55,13 +51,13 @@ stdcallcc fn _DllMainCRTStartup( return std.os.windows.TRUE; } -extern fn wasm_freestanding_start() void { +fn wasm_freestanding_start() callconv(.C) void { // This is marked inline because for some reason LLVM in release mode fails to inline it, // and we want fewer call frames in stack traces. _ = @call(.{ .modifier = .always_inline }, callMain, .{}); } -extern fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) usize { +fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) callconv(.C) usize { const bad_efi_main_ret = "expected return type of main to be 'void', 'noreturn', or 'usize'"; uefi.handle = handle; uefi.system_table = system_table; @@ -84,7 +80,7 @@ extern fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) u } } -nakedcc fn _start() noreturn { +fn _start() callconv(.Naked) noreturn { if (builtin.os == builtin.Os.wasi) { // This is marked inline because for some reason LLVM in release mode fails to inline it, // and we want fewer call frames in stack traces. @@ -127,7 +123,7 @@ nakedcc fn _start() noreturn { @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{}); } -stdcallcc fn WinMainCRTStartup() noreturn { +fn WinMainCRTStartup() callconv(.Stdcall) noreturn { @setAlignStack(16); if (!builtin.single_threaded) { _ = @import("start_windows_tls.zig"); @@ -198,7 +194,7 @@ fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 { return initEventLoopAndCallMain(); } -extern fn main(c_argc: i32, c_argv: [*][*:0]u8, c_envp: [*:null]?[*:0]u8) i32 { +fn main(c_argc: i32, c_argv: [*][*:0]u8, c_envp: [*:null]?[*:0]u8) callconv(.C) i32 { var env_count: usize = 0; while (c_envp[env_count] != null) : (env_count += 1) {} const envp = @ptrCast([*][*:0]u8, c_envp)[0..env_count]; diff --git a/lib/std/thread.zig b/lib/std/thread.zig index dcc762f30e..c482405c44 100644 --- a/lib/std/thread.zig +++ b/lib/std/thread.zig @@ -156,7 +156,7 @@ pub const Thread = struct { thread: Thread, inner: Context, }; - extern fn threadMain(raw_arg: windows.LPVOID) windows.DWORD { + fn threadMain(raw_arg: windows.LPVOID) callconv(.C) windows.DWORD { const arg = if (@sizeOf(Context) == 0) {} else @ptrCast(*Context, @alignCast(@alignOf(Context), raw_arg)).*; switch (@typeId(@TypeOf(startFn).ReturnType)) { .Int => { @@ -198,7 +198,7 @@ pub const Thread = struct { } const MainFuncs = struct { - extern fn linuxThreadMain(ctx_addr: usize) u8 { + fn linuxThreadMain(ctx_addr: usize) callconv(.C) u8 { const arg = if (@sizeOf(Context) == 0) {} else @intToPtr(*const Context, ctx_addr).*; switch (@typeId(@TypeOf(startFn).ReturnType)) { @@ -212,7 +212,7 @@ pub const Thread = struct { else => @compileError("expected return type of startFn to be 'u8', 'noreturn', 'void', or '!void'"), } } - extern fn posixThreadMain(ctx: ?*c_void) ?*c_void { + fn posixThreadMain(ctx: ?*c_void) callconv(.C) ?*c_void { if (@sizeOf(Context) == 0) { _ = startFn({}); return null; diff --git a/lib/std/unicode/throughput_test.zig b/lib/std/unicode/throughput_test.zig index 922c25ebc6..7265361b31 100644 --- a/lib/std/unicode/throughput_test.zig +++ b/lib/std/unicode/throughput_test.zig @@ -22,7 +22,7 @@ pub fn main() !void { const elapsed_ns_orig = timer.lap(); @fence(.SeqCst); - var buffer2: [32767] u16 align(4096) = undefined; + var buffer2: [32767]u16 align(4096) = undefined; _ = try std.unicode.utf8ToUtf16Le_better(&buffer2, args[1]); @fence(.SeqCst); diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig index adbcef165e..b921213f0c 100644 --- a/lib/std/zig/ast.zig +++ b/lib/std/zig/ast.zig @@ -860,6 +860,7 @@ pub const Node = struct { lib_name: ?*Node, // populated if this is an extern declaration align_expr: ?*Node, // populated if align(A) is present section_expr: ?*Node, // populated if linksection(A) is present + callconv_expr: ?*Node, // populated if callconv(A) is present pub const ParamList = SegmentedList(*Node, 2); diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index 14d5a0a400..c9c9956159 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -311,6 +311,7 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { const rparen = try expectToken(it, tree, .RParen); const align_expr = try parseByteAlign(arena, it, tree); const section_expr = try parseLinkSection(arena, it, tree); + const callconv_expr = try parseCallconv(arena, it, tree); const exclamation_token = eatToken(it, .Bang); const return_type_expr = (try parseVarType(arena, it, tree)) orelse @@ -347,6 +348,7 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { .lib_name = null, .align_expr = align_expr, .section_expr = section_expr, + .callconv_expr = callconv_expr, }; if (cc) |kind| { @@ -1678,6 +1680,17 @@ fn parseLinkSection(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node return expr_node; } +/// CallConv <- KEYWORD_callconv LPAREN Expr RPAREN +fn parseCallconv(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { + _ = eatToken(it, .Keyword_callconv) orelse return null; + _ = try expectToken(it, tree, .LParen); + const expr_node = try expectNode(arena, it, tree, parseExpr, AstError{ + .ExpectedExpr = AstError.ExpectedExpr{ .token = it.index }, + }); + _ = try expectToken(it, tree, .RParen); + return expr_node; +} + /// FnCC /// <- KEYWORD_nakedcc /// / KEYWORD_stdcallcc diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 2e7a376684..97df2dff15 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -9,6 +9,20 @@ test "zig fmt: change @typeOf to @TypeOf" { ); } +// TODO: Remove nakedcc/stdcallcc once zig 0.6.0 is released. See https://github.com/ziglang/zig/pull/3977 +test "zig fmt: convert extern/nakedcc/stdcallcc into callconv(...)" { + try testTransform( + \\nakedcc fn foo1() void {} + \\stdcallcc fn foo2() void {} + \\extern fn foo3() void {} + , + \\fn foo1() callconv(.Naked) void {} + \\fn foo2() callconv(.Stdcall) void {} + \\fn foo3() callconv(.C) void {} + \\ + ); +} + test "zig fmt: comptime struct field" { try testCanonical( \\const Foo = struct { @@ -234,7 +248,7 @@ test "zig fmt: threadlocal" { test "zig fmt: linksection" { try testCanonical( \\export var aoeu: u64 linksection(".text.derp") = 1234; - \\export nakedcc fn _start() linksection(".text.boot") noreturn {} + \\export fn _start() linksection(".text.boot") callconv(.Naked) noreturn {} \\ ); } @@ -2326,7 +2340,7 @@ test "zig fmt: fn type" { \\ \\const a: fn (u8) u8 = undefined; \\const b: extern fn (u8) u8 = undefined; - \\const c: nakedcc fn (u8) u8 = undefined; + \\const c: fn (u8) callconv(.Naked) u8 = undefined; \\const ap: fn (u8) u8 = a; \\ ); diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index d3553bb0bd..2b1a739186 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -1311,8 +1311,16 @@ fn renderExpression( try renderToken(tree, stream, visib_token_index, indent, start_col, Space.Space); // pub } + // Some extra machinery is needed to rewrite the old-style cc + // notation to the new callconv one + var cc_rewrite_str: ?[*:0]const u8 = null; if (fn_proto.extern_export_inline_token) |extern_export_inline_token| { - try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export + const tok = tree.tokens.at(extern_export_inline_token); + if (tok.id != .Keyword_extern or fn_proto.body_node == null) { + try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export + } else { + cc_rewrite_str = ".C"; + } } if (fn_proto.lib_name) |lib_name| { @@ -1320,7 +1328,12 @@ fn renderExpression( } if (fn_proto.cc_token) |cc_token| { - try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc + var str = tree.tokenSlicePtr(tree.tokens.at(cc_token)); + if (mem.eql(u8, str, "stdcallcc")) { + cc_rewrite_str = ".Stdcall"; + } else if (mem.eql(u8, str, "nakedcc")) { + cc_rewrite_str = ".Naked"; + } else try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc } const lparen = if (fn_proto.name_token) |name_token| blk: { @@ -1392,6 +1405,21 @@ fn renderExpression( try renderToken(tree, stream, section_rparen, indent, start_col, Space.Space); // ) } + if (fn_proto.callconv_expr) |callconv_expr| { + const callconv_rparen = tree.nextToken(callconv_expr.lastToken()); + const callconv_lparen = tree.prevToken(callconv_expr.firstToken()); + const callconv_kw = tree.prevToken(callconv_lparen); + + try renderToken(tree, stream, callconv_kw, indent, start_col, Space.None); // callconv + try renderToken(tree, stream, callconv_lparen, indent, start_col, Space.None); // ( + try renderExpression(allocator, stream, tree, indent, start_col, callconv_expr, Space.None); + try renderToken(tree, stream, callconv_rparen, indent, start_col, Space.Space); // ) + } else if (cc_rewrite_str) |str| { + try stream.write("callconv("); + try stream.write(mem.toSliceConst(u8, str)); + try stream.write(") "); + } + switch (fn_proto.return_type) { ast.Node.FnProto.ReturnType.Explicit => |node| { return renderExpression(allocator, stream, tree, indent, start_col, node, space); diff --git a/lib/std/zig/tokenizer.zig b/lib/std/zig/tokenizer.zig index d95fb47d41..327700f591 100644 --- a/lib/std/zig/tokenizer.zig +++ b/lib/std/zig/tokenizer.zig @@ -30,6 +30,7 @@ pub const Token = struct { Keyword.init("async", .Keyword_async), Keyword.init("await", .Keyword_await), Keyword.init("break", .Keyword_break), + Keyword.init("callconv", .Keyword_callconv), Keyword.init("catch", .Keyword_catch), Keyword.init("comptime", .Keyword_comptime), Keyword.init("const", .Keyword_const), @@ -162,6 +163,7 @@ pub const Token = struct { Keyword_async, Keyword_await, Keyword_break, + Keyword_callconv, Keyword_catch, Keyword_comptime, Keyword_const, @@ -286,6 +288,7 @@ pub const Token = struct { .Keyword_async => "async", .Keyword_await => "await", .Keyword_break => "break", + .Keyword_callconv => "callconv", .Keyword_catch => "catch", .Keyword_comptime => "comptime", .Keyword_const => "const", diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 730c93e037..4ff3f1ece2 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -11,7 +11,7 @@ const CToken = ctok.CToken; const mem = std.mem; const math = std.math; -const CallingConvention = std.builtin.TypeInfo.CallingConvention; +const CallingConvention = std.builtin.CallingConvention; pub const ClangErrMsg = Stage2ErrorMsg; @@ -3690,6 +3690,7 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a .lib_name = null, .align_expr = null, .section_expr = null, + .callconv_expr = null, }; const block = try transCreateNodeBlock(c, null); @@ -4141,6 +4142,11 @@ fn transCC( switch (clang_cc) { .C => return CallingConvention.C, .X86StdCall => return CallingConvention.Stdcall, + .X86FastCall => return CallingConvention.Fastcall, + .X86VectorCall, .AArch64VectorCall => return CallingConvention.Vectorcall, + .X86ThisCall => return CallingConvention.Thiscall, + .AAPCS => return CallingConvention.AAPCS, + .AAPCS_VFP => return CallingConvention.AAPCSVFP, else => return revertAndWarn( rp, error.UnsupportedType, @@ -4189,14 +4195,13 @@ fn finishTransFnProto( is_pub: bool, ) !*ast.Node.FnProto { const is_export = if (fn_decl_context) |ctx| ctx.is_export else false; - const is_extern = if (fn_decl_context) |ctx| !ctx.has_body else true; + const is_extern = if (fn_decl_context) |ctx| !ctx.has_body else false; // TODO check for always_inline attribute // TODO check for align attribute // pub extern fn name(...) T const pub_tok = if (is_pub) try appendToken(rp.c, .Keyword_pub, "pub") else null; - const cc_tok = if (cc == .Stdcall) try appendToken(rp.c, .Keyword_stdcallcc, "stdcallcc") else null; const extern_export_inline_tok = if (is_export) try appendToken(rp.c, .Keyword_export, "export") else if (cc == .C and is_extern) @@ -4303,6 +4308,14 @@ fn finishTransFnProto( break :blk null; }; + const callconv_expr = if ((is_export or is_extern) and cc == .C) null else blk: { + _ = try appendToken(rp.c, .Keyword_callconv, "callconv"); + _ = try appendToken(rp.c, .LParen, "("); + const expr = try transCreateNodeEnumLiteral(rp.c, @tagName(cc)); + _ = try appendToken(rp.c, .RParen, ")"); + break :blk expr; + }; + const return_type_node = blk: { if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) { break :blk try transCreateNodeIdentifier(rp.c, "noreturn"); @@ -4333,11 +4346,12 @@ fn finishTransFnProto( .return_type = .{ .Explicit = return_type_node }, .var_args_token = null, // TODO this field is broken in the AST data model .extern_export_inline_token = extern_export_inline_tok, - .cc_token = cc_tok, + .cc_token = null, .body_node = null, .lib_name = null, .align_expr = align_expr, .section_expr = linksection_expr, + .callconv_expr = callconv_expr, }; return fn_proto; } @@ -4686,6 +4700,7 @@ fn transMacroFnDefine(c: *Context, it: *ctok.TokenList.Iterator, name: []const u .lib_name = null, .align_expr = null, .section_expr = null, + .callconv_expr = null, }; const block = try transCreateNodeBlock(c, null); diff --git a/src-self-hosted/type.zig b/src-self-hosted/type.zig index d3f3ba746a..d4ffc355c0 100644 --- a/src-self-hosted/type.zig +++ b/src-self-hosted/type.zig @@ -337,7 +337,7 @@ pub const Type = struct { } }; - const CallingConvention = builtin.TypeInfo.CallingConvention; + const CallingConvention = builtin.CallingConvention; pub const Param = struct { is_noalias: bool, @@ -352,6 +352,7 @@ pub const Type = struct { .Naked => "nakedcc ", .Stdcall => "stdcallcc ", .Async => "async ", + else => unreachable, }; } diff --git a/src/all_types.hpp b/src/all_types.hpp index dd2b918fc6..fe77d3db3b 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -57,6 +57,23 @@ enum PtrLen { PtrLenC, }; +enum CallingConvention { + CallingConventionUnspecified, + CallingConventionC, + CallingConventionCold, + CallingConventionNaked, + CallingConventionAsync, + CallingConventionInterrupt, + CallingConventionSignal, + CallingConventionStdcall, + CallingConventionFastcall, + CallingConventionVectorcall, + CallingConventionThiscall, + CallingConventionAPCS, + CallingConventionAAPCS, + CallingConventionAAPCSVFP, +}; + // This one corresponds to the builtin.zig enum. enum BuiltinPtrSize { BuiltinPtrSizeOne, @@ -398,6 +415,7 @@ struct LazyValueFnType { IrInstruction *align_inst; // can be null IrInstruction *return_type; + CallingConvention cc; bool is_generic; }; @@ -612,15 +630,6 @@ enum NodeType { NodeTypeVarFieldType, }; -enum CallingConvention { - CallingConventionUnspecified, - CallingConventionC, - CallingConventionCold, - CallingConventionNaked, - CallingConventionStdcall, - CallingConventionAsync, -}; - enum FnInline { FnInlineAuto, FnInlineAlways, @@ -639,10 +648,12 @@ struct AstNodeFnProto { AstNode *align_expr; // populated if the "section(S)" is present AstNode *section_expr; + // populated if the "callconv(S)" is present + AstNode *callconv_expr; Buf doc_comments; FnInline fn_inline; - CallingConvention cc; + bool is_async; VisibMod visib_mod; bool auto_err_set; @@ -3549,6 +3560,7 @@ struct IrInstructionFnProto { IrInstruction **param_types; IrInstruction *align_value; + IrInstruction *callconv_value; IrInstruction *return_type; bool is_var_args; }; diff --git a/src/analyze.cpp b/src/analyze.cpp index aeef6cf35b..b15d986558 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -919,24 +919,20 @@ ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry) { const char *calling_convention_name(CallingConvention cc) { switch (cc) { - case CallingConventionUnspecified: return "undefined"; - case CallingConventionC: return "ccc"; - case CallingConventionCold: return "coldcc"; - case CallingConventionNaked: return "nakedcc"; - case CallingConventionStdcall: return "stdcallcc"; - case CallingConventionAsync: return "async"; - } - zig_unreachable(); -} - -static const char *calling_convention_fn_type_str(CallingConvention cc) { - switch (cc) { - case CallingConventionUnspecified: return ""; - case CallingConventionC: return "extern "; - case CallingConventionCold: return "coldcc "; - case CallingConventionNaked: return "nakedcc "; - case CallingConventionStdcall: return "stdcallcc "; - case CallingConventionAsync: return "async "; + case CallingConventionUnspecified: return "Unspecified"; + case CallingConventionC: return "C"; + case CallingConventionCold: return "Cold"; + case CallingConventionNaked: return "Naked"; + case CallingConventionAsync: return "Async"; + case CallingConventionInterrupt: return "Interrupt"; + case CallingConventionSignal: return "Signal"; + case CallingConventionStdcall: return "Stdcall"; + case CallingConventionFastcall: return "Fastcall"; + case CallingConventionVectorcall: return "Vectorcall"; + case CallingConventionThiscall: return "Thiscall"; + case CallingConventionAPCS: return "Apcs"; + case CallingConventionAAPCS: return "Aapcs"; + case CallingConventionAAPCSVFP: return "Aapcsvfp"; } zig_unreachable(); } @@ -949,7 +945,15 @@ bool calling_convention_allows_zig_types(CallingConvention cc) { case CallingConventionC: case CallingConventionCold: case CallingConventionNaked: + case CallingConventionInterrupt: + case CallingConventionSignal: case CallingConventionStdcall: + case CallingConventionFastcall: + case CallingConventionVectorcall: + case CallingConventionThiscall: + case CallingConventionAPCS: + case CallingConventionAAPCS: + case CallingConventionAAPCSVFP: return false; } zig_unreachable(); @@ -1006,8 +1010,6 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { // populate the name of the type buf_resize(&fn_type->name, 0); - const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc); - buf_appendf(&fn_type->name, "%s", cc_str); buf_appendf(&fn_type->name, "fn("); for (size_t i = 0; i < fn_type_id->param_count; i += 1) { FnTypeParamInfo *param_info = &fn_type_id->param_info[i]; @@ -1026,6 +1028,9 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { if (fn_type_id->alignment != 0) { buf_appendf(&fn_type->name, " align(%" PRIu32 ")", fn_type_id->alignment); } + if (fn_type_id->cc != CallingConventionUnspecified) { + buf_appendf(&fn_type->name, " callconv(.%s)", calling_convention_name(fn_type_id->cc)); + } buf_appendf(&fn_type->name, " %s", buf_ptr(&fn_type_id->return_type->name)); // The fn_type is a pointer; not to be confused with the raw function type. @@ -1444,8 +1449,6 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) { ZigType *fn_type = new_type_table_entry(ZigTypeIdFn); buf_resize(&fn_type->name, 0); - const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc); - buf_appendf(&fn_type->name, "%s", cc_str); buf_appendf(&fn_type->name, "fn("); size_t i = 0; for (; i < fn_type_id->next_param_index; i += 1) { @@ -1457,7 +1460,11 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) { const char *comma_str = (i == 0) ? "" : ","; buf_appendf(&fn_type->name, "%svar", comma_str); } - buf_appendf(&fn_type->name, ")var"); + buf_append_str(&fn_type->name, ")"); + if (fn_type_id->cc != CallingConventionUnspecified) { + buf_appendf(&fn_type->name, " callconv(.%s)", calling_convention_name(fn_type_id->cc)); + } + buf_append_str(&fn_type->name, " var"); fn_type->data.fn.fn_type_id = *fn_type_id; fn_type->data.fn.is_generic = true; @@ -1467,17 +1474,21 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) { return fn_type; } -void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc) { +CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto) { + if (fn_proto->is_async) + return CallingConventionAsync; + // Compatible with the C ABI + if (fn_proto->is_extern || fn_proto->is_export) + return CallingConventionC; + + return CallingConventionUnspecified; +} + +void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, CallingConvention cc, size_t param_count_alloc) { assert(proto_node->type == NodeTypeFnProto); AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; - if (fn_proto->cc == CallingConventionUnspecified) { - bool extern_abi = fn_proto->is_extern || fn_proto->is_export; - fn_type_id->cc = extern_abi ? CallingConventionC : CallingConventionUnspecified; - } else { - fn_type_id->cc = fn_proto->cc; - } - + fn_type_id->cc = cc; fn_type_id->param_count = fn_proto->params.length; fn_type_id->param_info = allocate(param_count_alloc); fn_type_id->next_param_index = 0; @@ -1691,8 +1702,7 @@ Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result) { case ZigTypeIdArray: return type_allowed_in_extern(g, type_entry->data.array.child_type, result); case ZigTypeIdFn: - *result = type_entry->data.fn.fn_type_id.cc == CallingConventionC || - type_entry->data.fn.fn_type_id.cc == CallingConventionStdcall; + *result = !calling_convention_allows_zig_types(type_entry->data.fn.fn_type_id.cc); return ErrorNone; case ZigTypeIdPointer: if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown))) @@ -1746,13 +1756,15 @@ ZigType *get_auto_err_set_type(CodeGen *g, ZigFn *fn_entry) { return err_set_type; } -static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope, ZigFn *fn_entry) { +static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope, ZigFn *fn_entry, + CallingConvention cc) +{ assert(proto_node->type == NodeTypeFnProto); AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; Error err; FnTypeId fn_type_id = {0}; - init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); + init_fn_type_id(&fn_type_id, proto_node, cc, proto_node->data.fn_proto.params.length); for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { AstNode *param_node = fn_proto->params.at(fn_type_id.next_param_index); @@ -2164,7 +2176,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { ZigType *field_type = resolve_struct_field_type(g, field); if (field_type == nullptr) { struct_type->data.structure.resolve_status = ResolveStatusInvalid; - return err; + return ErrorSemanticAnalyzeFail; } if ((err = type_resolve(g, field->type_entry, ResolveStatusSizeKnown))) { struct_type->data.structure.resolve_status = ResolveStatusInvalid; @@ -2254,7 +2266,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { ZigType *field_type = resolve_struct_field_type(g, field); if (field_type == nullptr) { struct_type->data.structure.resolve_status = ResolveStatusInvalid; - return err; + return ErrorSemanticAnalyzeFail; } if ((err = type_resolve(g, field_type, ResolveStatusSizeKnown))) { @@ -2324,7 +2336,7 @@ static Error resolve_union_alignment(CodeGen *g, ZigType *union_type) { &field->align)) { union_type->data.unionation.resolve_status = ResolveStatusInvalid; - return err; + return ErrorSemanticAnalyzeFail; } add_node_error(g, field->decl_node, buf_create_from_str("TODO implement field alignment syntax for unions. https://github.com/ziglang/zig/issues/3125")); @@ -2451,6 +2463,7 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) { union_type->data.unionation.resolve_status = ResolveStatusInvalid; return ErrorSemanticAnalyzeFail; } + if (is_packed) { if ((err = emit_error_unless_type_allowed_in_packed_union(g, field_type, union_field->decl_node))) { union_type->data.unionation.resolve_status = ResolveStatusInvalid; @@ -2909,7 +2922,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { &field->align)) { struct_type->data.structure.resolve_status = ResolveStatusInvalid; - return err; + return ErrorSemanticAnalyzeFail; } } else if (packed) { field->align = 1; @@ -3395,27 +3408,6 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { get_fully_qualified_decl_name(g, &fn_table_entry->symbol_name, &tld_fn->base, false); } - if (fn_proto->is_export) { - switch (fn_proto->cc) { - case CallingConventionAsync: { - add_node_error(g, fn_def_node, - buf_sprintf("exported function cannot be async")); - } break; - case CallingConventionC: - case CallingConventionNaked: - case CallingConventionCold: - case CallingConventionStdcall: - case CallingConventionUnspecified: - // An exported function without a specific calling - // convention defaults to C - CallingConvention cc = (fn_proto->cc != CallingConventionUnspecified) ? - fn_proto->cc : CallingConventionC; - add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name), - GlobalLinkageIdStrong, cc); - break; - } - } - if (!is_extern) { fn_table_entry->fndef_scope = create_fndef_scope(g, fn_table_entry->body_node, tld_fn->base.parent_scope, fn_table_entry); @@ -3434,19 +3426,72 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { Scope *child_scope = fn_table_entry->fndef_scope ? &fn_table_entry->fndef_scope->base : tld_fn->base.parent_scope; - fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry); + CallingConvention cc; + if (fn_proto->callconv_expr != nullptr) { + ZigType *cc_enum_value = get_builtin_type(g, "CallingConvention"); + + ZigValue *result_val = analyze_const_value(g, child_scope, fn_proto->callconv_expr, + cc_enum_value, nullptr, UndefBad); + if (type_is_invalid(result_val->type)) { + fn_table_entry->type_entry = g->builtin_types.entry_invalid; + tld_fn->base.resolution = TldResolutionInvalid; + return; + } + + cc = (CallingConvention)bigint_as_u32(&result_val->data.x_enum_tag); + } else { + cc = cc_from_fn_proto(fn_proto); + } if (fn_proto->section_expr != nullptr) { if (!analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name)) { fn_table_entry->type_entry = g->builtin_types.entry_invalid; + tld_fn->base.resolution = TldResolutionInvalid; + return; } } - if (fn_table_entry->type_entry->id == ZigTypeIdInvalid) { + fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry, cc); + + if (type_is_invalid(fn_table_entry->type_entry)) { tld_fn->base.resolution = TldResolutionInvalid; return; } + const CallingConvention fn_cc = fn_table_entry->type_entry->data.fn.fn_type_id.cc; + + if (fn_proto->is_export) { + switch (fn_cc) { + case CallingConventionAsync: + add_node_error(g, fn_def_node, + buf_sprintf("exported function cannot be async")); + fn_table_entry->type_entry = g->builtin_types.entry_invalid; + tld_fn->base.resolution = TldResolutionInvalid; + return; + case CallingConventionC: + case CallingConventionCold: + case CallingConventionNaked: + case CallingConventionInterrupt: + case CallingConventionSignal: + case CallingConventionStdcall: + case CallingConventionFastcall: + case CallingConventionVectorcall: + case CallingConventionThiscall: + case CallingConventionAPCS: + case CallingConventionAAPCS: + case CallingConventionAAPCSVFP: + add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name), + GlobalLinkageIdStrong, fn_cc); + break; + case CallingConventionUnspecified: + // An exported function without a specific calling + // convention defaults to C + add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name), + GlobalLinkageIdStrong, CallingConventionC); + break; + } + } + if (!fn_table_entry->type_entry->data.fn.is_generic) { if (fn_def_node) g->fn_defs.append(fn_table_entry); @@ -3455,7 +3500,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { // if the calling convention implies that it cannot be async, we save that for later // and leave the value to be nullptr to indicate that we have not emitted possible // compile errors for improperly calling async functions. - if (fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync) { + if (fn_cc == CallingConventionAsync) { fn_table_entry->inferred_async_node = fn_table_entry->proto_node; } } else if (source_node->type == NodeTypeTestDecl) { @@ -4338,7 +4383,7 @@ uint32_t get_ptr_align(CodeGen *g, ZigType *type) { } else if (ptr_type->id == ZigTypeIdFn) { // I tried making this use LLVMABIAlignmentOfType but it trips this assertion in LLVM: // "Cannot getTypeInfo() on a type that is unsized!" - // when getting the alignment of `?extern fn() void`. + // when getting the alignment of `?fn() callconv(.C) void`. // See http://lists.llvm.org/pipermail/llvm-dev/2018-September/126142.html return (ptr_type->data.fn.fn_type_id.alignment == 0) ? 1 : ptr_type->data.fn.fn_type_id.alignment; } else if (ptr_type->id == ZigTypeIdAnyFrame) { diff --git a/src/analyze.hpp b/src/analyze.hpp index f823e642f8..f79dbbda44 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -100,7 +100,7 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node); void append_namespace_qualification(CodeGen *g, Buf *buf, ZigType *container_type); ZigFn *create_fn(CodeGen *g, AstNode *proto_node); ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value); -void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc); +void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, CallingConvention cc, size_t param_count_alloc); AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index); Error ATTRIBUTE_MUST_USE type_resolve(CodeGen *g, ZigType *type_entry, ResolveStatus status); void complete_enum(CodeGen *g, ZigType *enum_type); @@ -259,6 +259,7 @@ ZigValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType * void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn); bool fn_is_async(ZigFn *fn); +CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto); Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *type_val, uint32_t *abi_align); Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ZigValue *type_val, diff --git a/src/ast_render.cpp b/src/ast_render.cpp index 2be932ac8e..d8d0d6c0e2 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -488,6 +488,11 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { render_node_grouped(ar, node->data.fn_proto.section_expr); fprintf(ar->f, ")"); } + if (node->data.fn_proto.callconv_expr) { + fprintf(ar->f, " callconv("); + render_node_grouped(ar, node->data.fn_proto.callconv_expr); + fprintf(ar->f, ")"); + } if (node->data.fn_proto.return_var_token != nullptr) { fprintf(ar->f, "var"); diff --git a/src/codegen.cpp b/src/codegen.cpp index 95263e167f..59f69539bc 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -263,36 +263,66 @@ static const char *get_mangled_name(CodeGen *g, const char *original_name, bool } } -static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) { +static ZigLLVM_CallingConv get_llvm_cc(CodeGen *g, CallingConvention cc) { switch (cc) { - case CallingConventionUnspecified: return LLVMFastCallConv; - case CallingConventionC: return LLVMCCallConv; + case CallingConventionUnspecified: + return ZigLLVM_Fast; + case CallingConventionC: + return ZigLLVM_C; case CallingConventionCold: - // cold calling convention only works on x86. - if (g->zig_target->arch == ZigLLVM_x86 || - g->zig_target->arch == ZigLLVM_x86_64) - { - // cold calling convention is not supported on windows - if (g->zig_target->os == OsWindows) { - return LLVMCCallConv; - } else { - return LLVMColdCallConv; - } - } else { - return LLVMCCallConv; - } - break; + if ((g->zig_target->arch == ZigLLVM_x86 || + g->zig_target->arch == ZigLLVM_x86_64) && + g->zig_target->os != OsWindows) + return ZigLLVM_Cold; + return ZigLLVM_C; case CallingConventionNaked: zig_unreachable(); case CallingConventionStdcall: - // stdcall calling convention only works on x86. - if (g->zig_target->arch == ZigLLVM_x86) { - return LLVMX86StdcallCallConv; - } else { - return LLVMCCallConv; - } + if (g->zig_target->arch == ZigLLVM_x86) + return ZigLLVM_X86_StdCall; + return ZigLLVM_C; + case CallingConventionFastcall: + if (g->zig_target->arch == ZigLLVM_x86) + return ZigLLVM_X86_FastCall; + return ZigLLVM_C; + case CallingConventionVectorcall: + if (g->zig_target->arch == ZigLLVM_x86) + return ZigLLVM_X86_VectorCall; + if (target_is_arm(g->zig_target) && + target_arch_pointer_bit_width(g->zig_target->arch) == 64) + return ZigLLVM_AArch64_VectorCall; + return ZigLLVM_C; + case CallingConventionThiscall: + if (g->zig_target->arch == ZigLLVM_x86) + return ZigLLVM_X86_ThisCall; + return ZigLLVM_C; case CallingConventionAsync: - return LLVMFastCallConv; + return ZigLLVM_Fast; + case CallingConventionAPCS: + if (target_is_arm(g->zig_target)) + return ZigLLVM_ARM_APCS; + return ZigLLVM_C; + case CallingConventionAAPCS: + if (target_is_arm(g->zig_target)) + return ZigLLVM_ARM_AAPCS; + return ZigLLVM_C; + case CallingConventionAAPCSVFP: + if (target_is_arm(g->zig_target)) + return ZigLLVM_ARM_AAPCS_VFP; + return ZigLLVM_C; + case CallingConventionInterrupt: + if (g->zig_target->arch == ZigLLVM_x86 || + g->zig_target->arch == ZigLLVM_x86_64) + return ZigLLVM_X86_INTR; + if (g->zig_target->arch == ZigLLVM_avr) + return ZigLLVM_AVR_INTR; + if (g->zig_target->arch == ZigLLVM_msp430) + return ZigLLVM_MSP430_INTR; + return ZigLLVM_C; + case CallingConventionSignal: + if (g->zig_target->arch == ZigLLVM_avr) + return ZigLLVM_AVR_SIGNAL; + return ZigLLVM_C; } zig_unreachable(); } @@ -384,7 +414,15 @@ static bool cc_want_sret_attr(CallingConvention cc) { zig_unreachable(); case CallingConventionC: case CallingConventionCold: + case CallingConventionInterrupt: + case CallingConventionSignal: case CallingConventionStdcall: + case CallingConventionFastcall: + case CallingConventionVectorcall: + case CallingConventionThiscall: + case CallingConventionAPCS: + case CallingConventionAAPCS: + case CallingConventionAAPCSVFP: return true; case CallingConventionAsync: case CallingConventionUnspecified: @@ -481,7 +519,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { if (cc == CallingConventionNaked) { addLLVMFnAttr(llvm_fn, "naked"); } else { - LLVMSetFunctionCallConv(llvm_fn, get_llvm_cc(g, fn_type->data.fn.fn_type_id.cc)); + ZigLLVMFunctionSetCallingConv(llvm_fn, get_llvm_cc(g, cc)); } bool want_cold = fn->is_cold || cc == CallingConventionCold; @@ -976,7 +1014,7 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace { assert(g->panic_fn != nullptr); LLVMValueRef fn_val = fn_llvm_value(g, g->panic_fn); - LLVMCallConv llvm_cc = get_llvm_cc(g, g->panic_fn->type_entry->data.fn.fn_type_id.cc); + ZigLLVM_CallingConv llvm_cc = get_llvm_cc(g, g->panic_fn->type_entry->data.fn.fn_type_id.cc); if (stack_trace_arg == nullptr) { stack_trace_arg = LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type(g))); } @@ -1087,7 +1125,7 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) { LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref); addLLVMFnAttr(fn_val, "alwaysinline"); LLVMSetLinkage(fn_val, LLVMInternalLinkage); - LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); + ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); addLLVMFnAttr(fn_val, "nounwind"); add_uwtable_attr(g, fn_val); // 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) { addLLVMFnAttr(fn_val, "noinline"); // so that we can look at return address addLLVMFnAttr(fn_val, "cold"); LLVMSetLinkage(fn_val, LLVMInternalLinkage); - LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); + ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); addLLVMFnAttr(fn_val, "nounwind"); add_uwtable_attr(g, fn_val); if (codegen_have_frame_pointer(g)) { @@ -1252,7 +1290,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { addLLVMFnAttr(fn_val, "noreturn"); addLLVMFnAttr(fn_val, "cold"); LLVMSetLinkage(fn_val, LLVMInternalLinkage); - LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); + ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); addLLVMFnAttr(fn_val, "nounwind"); add_uwtable_attr(g, fn_val); if (codegen_have_frame_pointer(g)) { @@ -2148,7 +2186,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) { const char *fn_name = get_mangled_name(g, "__zig_merge_error_return_traces", false); LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref); LLVMSetLinkage(fn_val, LLVMInternalLinkage); - LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); + ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); addLLVMFnAttr(fn_val, "nounwind"); add_uwtable_attr(g, fn_val); addLLVMArgAttr(fn_val, (unsigned)0, "noalias"); @@ -2325,7 +2363,7 @@ static LLVMValueRef gen_resume(CodeGen *g, LLVMValueRef fn_val, LLVMValueRef tar LLVMValueRef arg_val = LLVMConstSub(LLVMConstAllOnes(usize_type_ref), LLVMConstInt(usize_type_ref, resume_id, false)); LLVMValueRef args[] = {target_frame_ptr, arg_val}; - return ZigLLVMBuildCall(g->builder, fn_val, args, 2, LLVMFastCallConv, ZigLLVM_CallAttrAuto, ""); + return ZigLLVMBuildCall(g->builder, fn_val, args, 2, ZigLLVM_Fast, ZigLLVM_CallAttrAuto, ""); } 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 break; } - LLVMCallConv llvm_cc = get_llvm_cc(g, cc); + ZigLLVM_CallingConv llvm_cc = get_llvm_cc(g, cc); LLVMValueRef result; if (callee_is_async) { @@ -4925,7 +4963,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) { buf_ptr(buf_sprintf("__zig_tag_name_%s", buf_ptr(&enum_type->name))), false); LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref); LLVMSetLinkage(fn_val, LLVMInternalLinkage); - LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); + ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); addLLVMFnAttr(fn_val, "nounwind"); add_uwtable_attr(g, fn_val); if (codegen_have_frame_pointer(g)) { @@ -8463,8 +8501,16 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { static_assert(CallingConventionC == 1, ""); static_assert(CallingConventionCold == 2, ""); static_assert(CallingConventionNaked == 3, ""); - static_assert(CallingConventionStdcall == 4, ""); - static_assert(CallingConventionAsync == 5, ""); + static_assert(CallingConventionAsync == 4, ""); + static_assert(CallingConventionInterrupt == 5, ""); + static_assert(CallingConventionSignal == 6, ""); + static_assert(CallingConventionStdcall == 7, ""); + static_assert(CallingConventionFastcall == 8, ""); + static_assert(CallingConventionVectorcall == 9, ""); + static_assert(CallingConventionThiscall == 10, ""); + static_assert(CallingConventionAPCS == 11, ""); + static_assert(CallingConventionAAPCS == 12, ""); + static_assert(CallingConventionAAPCSVFP == 13, ""); static_assert(FnInlineAuto == 0, ""); static_assert(FnInlineAlways == 1, ""); diff --git a/src/ir.cpp b/src/ir.cpp index 762e97e257..8332cbd2d6 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3248,12 +3248,13 @@ static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, } static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction **param_types, IrInstruction *align_value, IrInstruction *return_type, - bool is_var_args) + IrInstruction **param_types, IrInstruction *align_value, IrInstruction *callconv_value, + IrInstruction *return_type, bool is_var_args) { IrInstructionFnProto *instruction = ir_build_instruction(irb, scope, source_node); instruction->param_types = param_types; instruction->align_value = align_value; + instruction->callconv_value = callconv_value; instruction->return_type = return_type; instruction->is_var_args = is_var_args; @@ -3264,6 +3265,7 @@ static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *s if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block); } if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); + if (callconv_value != nullptr) ir_ref_instruction(callconv_value, irb->current_basic_block); ir_ref_instruction(return_type, irb->current_basic_block); return &instruction->base; @@ -8843,6 +8845,13 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo return irb->codegen->invalid_instruction; } + IrInstruction *callconv_value = nullptr; + if (node->data.fn_proto.callconv_expr != nullptr) { + callconv_value = ir_gen_node(irb, node->data.fn_proto.callconv_expr, parent_scope); + if (callconv_value == irb->codegen->invalid_instruction) + return irb->codegen->invalid_instruction; + } + IrInstruction *return_type; if (node->data.fn_proto.return_var_token == nullptr) { if (node->data.fn_proto.return_type == nullptr) { @@ -8859,7 +8868,7 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo //return_type = nullptr; } - return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args); + return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, callconv_value, return_type, is_var_args); } static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) { @@ -16729,9 +16738,17 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); } break; case CallingConventionC: - case CallingConventionNaked: case CallingConventionCold: + case CallingConventionNaked: + case CallingConventionInterrupt: + case CallingConventionSignal: case CallingConventionStdcall: + case CallingConventionFastcall: + case CallingConventionVectorcall: + case CallingConventionThiscall: + case CallingConventionAPCS: + case CallingConventionAAPCS: + case CallingConventionAAPCSVFP: add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, cc); break; } @@ -18094,7 +18111,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i return ira->codegen->invalid_instruction; } - if (fn_type_id->is_var_args) { if (call_param_count < src_param_count) { ErrorMsg *msg = ir_add_error_node(ira, source_node, @@ -18248,7 +18264,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn); impl_fn->child_scope = &impl_fn->fndef_scope->base; FnTypeId inst_fn_type_id = {0}; - init_fn_type_id(&inst_fn_type_id, fn_proto_node, new_fn_arg_count); + init_fn_type_id(&inst_fn_type_id, fn_proto_node, fn_type_id->cc, new_fn_arg_count); inst_fn_type_id.param_count = 0; inst_fn_type_id.is_var_args = false; @@ -22582,50 +22598,45 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr fn_decl_fields[1]->special = ConstValSpecialStatic; fn_decl_fields[1]->type = type_info_fn_decl_inline_type; bigint_init_unsigned(&fn_decl_fields[1]->data.x_enum_tag, fn_entry->fn_inline); - // calling_convention: TypeInfo.CallingConvention - ensure_field_index(fn_decl_val->type, "calling_convention", 2); - fn_decl_fields[2]->special = ConstValSpecialStatic; - fn_decl_fields[2]->type = ir_type_info_get_type(ira, "CallingConvention", nullptr); - bigint_init_unsigned(&fn_decl_fields[2]->data.x_enum_tag, fn_node->cc); // is_var_args: bool - ensure_field_index(fn_decl_val->type, "is_var_args", 3); + ensure_field_index(fn_decl_val->type, "is_var_args", 2); bool is_varargs = fn_node->is_var_args; + fn_decl_fields[2]->special = ConstValSpecialStatic; + fn_decl_fields[2]->type = ira->codegen->builtin_types.entry_bool; + fn_decl_fields[2]->data.x_bool = is_varargs; + // is_extern: bool + ensure_field_index(fn_decl_val->type, "is_extern", 3); fn_decl_fields[3]->special = ConstValSpecialStatic; fn_decl_fields[3]->type = ira->codegen->builtin_types.entry_bool; - fn_decl_fields[3]->data.x_bool = is_varargs; - // is_extern: bool - ensure_field_index(fn_decl_val->type, "is_extern", 4); + fn_decl_fields[3]->data.x_bool = fn_node->is_extern; + // is_export: bool + ensure_field_index(fn_decl_val->type, "is_export", 4); fn_decl_fields[4]->special = ConstValSpecialStatic; fn_decl_fields[4]->type = ira->codegen->builtin_types.entry_bool; - fn_decl_fields[4]->data.x_bool = fn_node->is_extern; - // is_export: bool - ensure_field_index(fn_decl_val->type, "is_export", 5); - fn_decl_fields[5]->special = ConstValSpecialStatic; - fn_decl_fields[5]->type = ira->codegen->builtin_types.entry_bool; - fn_decl_fields[5]->data.x_bool = fn_node->is_export; + fn_decl_fields[4]->data.x_bool = fn_node->is_export; // lib_name: ?[]const u8 - ensure_field_index(fn_decl_val->type, "lib_name", 6); - fn_decl_fields[6]->special = ConstValSpecialStatic; + ensure_field_index(fn_decl_val->type, "lib_name", 5); + fn_decl_fields[5]->special = ConstValSpecialStatic; ZigType *u8_ptr = get_pointer_to_type_extra( ira->codegen, ira->codegen->builtin_types.entry_u8, true, false, PtrLenUnknown, 0, 0, 0, false); - fn_decl_fields[6]->type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr)); + fn_decl_fields[5]->type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr)); if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) { - fn_decl_fields[6]->data.x_optional = create_const_vals(1); + fn_decl_fields[5]->data.x_optional = create_const_vals(1); ZigValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name)->data.x_ptr.data.ref.pointee; - init_const_slice(ira->codegen, fn_decl_fields[6]->data.x_optional, lib_name, 0, + init_const_slice(ira->codegen, fn_decl_fields[5]->data.x_optional, lib_name, 0, buf_len(fn_node->lib_name), true); } else { - fn_decl_fields[6]->data.x_optional = nullptr; + fn_decl_fields[5]->data.x_optional = nullptr; } // return_type: type - ensure_field_index(fn_decl_val->type, "return_type", 7); - fn_decl_fields[7]->special = ConstValSpecialStatic; - fn_decl_fields[7]->type = ira->codegen->builtin_types.entry_type; - fn_decl_fields[7]->data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; + ensure_field_index(fn_decl_val->type, "return_type", 6); + fn_decl_fields[6]->special = ConstValSpecialStatic; + fn_decl_fields[6]->type = ira->codegen->builtin_types.entry_type; + fn_decl_fields[6]->data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; // arg_names: [][] const u8 - ensure_field_index(fn_decl_val->type, "arg_names", 8); + ensure_field_index(fn_decl_val->type, "arg_names", 7); size_t fn_arg_count = fn_entry->variable_list.length; ZigValue *fn_arg_name_array = create_const_vals(1); fn_arg_name_array->special = ConstValSpecialStatic; @@ -22634,7 +22645,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); - init_const_slice(ira->codegen, fn_decl_fields[8], fn_arg_name_array, 0, fn_arg_count, false); + init_const_slice(ira->codegen, fn_decl_fields[7], fn_arg_name_array, 0, fn_arg_count, false); for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index); @@ -23273,7 +23284,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr // calling_convention: TypeInfo.CallingConvention ensure_field_index(result->type, "calling_convention", 0); fields[0]->special = ConstValSpecialStatic; - fields[0]->type = ir_type_info_get_type(ira, "CallingConvention", nullptr); + fields[0]->type = get_builtin_type(ira->codegen, "CallingConvention"); bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); // is_generic: bool ensure_field_index(result->type, "is_generic", 1); @@ -26185,6 +26196,21 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct return ira->codegen->invalid_instruction; } + lazy_fn_type->cc = cc_from_fn_proto(&proto_node->data.fn_proto); + if (instruction->callconv_value != nullptr) { + ZigType *cc_enum_type = get_builtin_type(ira->codegen, "CallingConvention"); + + IrInstruction *casted_value = ir_implicit_cast(ira, instruction->callconv_value, cc_enum_type); + if (type_is_invalid(casted_value->value->type)) + return ira->codegen->invalid_instruction; + + ZigValue *const_value = ir_resolve_const(ira, casted_value, UndefBad); + if (const_value == nullptr) + return ira->codegen->invalid_instruction; + + lazy_fn_type->cc = (CallingConvention)bigint_as_u32(&const_value->data.x_enum_tag); + } + size_t param_count = proto_node->data.fn_proto.params.length; lazy_fn_type->proto_node = proto_node; lazy_fn_type->param_types = allocate(param_count); @@ -26195,9 +26221,11 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct bool param_is_var_args = param_node->data.param_decl.is_var_args; if (param_is_var_args) { - if (proto_node->data.fn_proto.cc == CallingConventionC) { + const CallingConvention cc = lazy_fn_type->cc; + + if (cc == CallingConventionC) { break; - } else if (proto_node->data.fn_proto.cc == CallingConventionUnspecified) { + } else if (cc == CallingConventionUnspecified) { lazy_fn_type->is_generic = true; return result; } else { @@ -29076,7 +29104,7 @@ static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, La AstNode *proto_node = lazy_fn_type->proto_node; FnTypeId fn_type_id = {0}; - init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); + init_fn_type_id(&fn_type_id, proto_node, lazy_fn_type->cc, proto_node->data.fn_proto.params.length); for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); diff --git a/src/parser.cpp b/src/parser.cpp index a0c5cf794b..f6f5811e63 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -92,6 +92,7 @@ static Token *ast_parse_block_label(ParseContext *pc); static AstNode *ast_parse_field_init(ParseContext *pc); static AstNode *ast_parse_while_continue_expr(ParseContext *pc); static AstNode *ast_parse_link_section(ParseContext *pc); +static AstNode *ast_parse_callconv(ParseContext *pc); static Optional ast_parse_fn_cc(ParseContext *pc); static AstNode *ast_parse_param_decl(ParseContext *pc); 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 fn_proto->column = first->start_column; fn_proto->data.fn_proto.visib_mod = visib_mod; fn_proto->data.fn_proto.doc_comments = *doc_comments; - fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern; + // ast_parse_fn_cc may set it + if (!fn_proto->data.fn_proto.is_extern) + fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern; fn_proto->data.fn_proto.is_export = first->id == TokenIdKeywordExport; switch (first->id) { case TokenIdKeywordInline: @@ -761,7 +764,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) { // The extern keyword for fn CC is also used for container decls. // We therefore put it back, as allow container decl to consume it // later. - if (fn_cc.cc == CallingConventionC) { + if (fn_cc.is_extern) { fn = eat_token_if(pc, TokenIdKeywordFn); if (fn == nullptr) { put_back_token(pc); @@ -784,6 +787,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) { AstNode *align_expr = ast_parse_byte_align(pc); AstNode *section_expr = ast_parse_link_section(pc); + AstNode *callconv_expr = ast_parse_callconv(pc); Token *var = eat_token_if(pc, TokenIdKeywordVar); Token *exmark = nullptr; AstNode *return_type = nullptr; @@ -798,6 +802,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) { res->data.fn_proto.params = params; res->data.fn_proto.align_expr = align_expr; res->data.fn_proto.section_expr = section_expr; + res->data.fn_proto.callconv_expr = callconv_expr; res->data.fn_proto.return_var_token = var; res->data.fn_proto.auto_err_set = exmark != nullptr; res->data.fn_proto.return_type = return_type; @@ -2099,27 +2104,29 @@ static AstNode *ast_parse_link_section(ParseContext *pc) { return res; } +// CallConv <- KEYWORD_callconv LPAREN Expr RPAREN +static AstNode *ast_parse_callconv(ParseContext *pc) { + Token *first = eat_token_if(pc, TokenIdKeywordCallconv); + if (first == nullptr) + return nullptr; + + expect_token(pc, TokenIdLParen); + AstNode *res = ast_expect(pc, ast_parse_expr); + expect_token(pc, TokenIdRParen); + return res; +} + // FnCC -// <- KEYWORD_nakedcc -// / KEYWORD_stdcallcc -// / KEYWORD_extern +// <- KEYWORD_extern // / KEYWORD_async static Optional ast_parse_fn_cc(ParseContext *pc) { AstNodeFnProto res = {}; - if (eat_token_if(pc, TokenIdKeywordNakedCC) != nullptr) { - res.cc = CallingConventionNaked; - return Optional::some(res); - } - if (eat_token_if(pc, TokenIdKeywordStdcallCC) != nullptr) { - res.cc = CallingConventionStdcall; + if (eat_token_if(pc, TokenIdKeywordAsync) != nullptr) { + res.is_async = true; return Optional::some(res); } if (eat_token_if(pc, TokenIdKeywordExtern) != nullptr) { - res.cc = CallingConventionC; - return Optional::some(res); - } - if (eat_token_if(pc, TokenIdKeywordAsync) != nullptr) { - res.cc = CallingConventionAsync; + res.is_extern = true; return Optional::some(res); } diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index f8b5059bf1..9182c5227a 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -110,6 +110,7 @@ static const struct ZigKeyword zig_keywords[] = { {"async", TokenIdKeywordAsync}, {"await", TokenIdKeywordAwait}, {"break", TokenIdKeywordBreak}, + {"callconv", TokenIdKeywordCallconv}, {"catch", TokenIdKeywordCatch}, {"comptime", TokenIdKeywordCompTime}, {"const", TokenIdKeywordConst}, @@ -126,7 +127,6 @@ static const struct ZigKeyword zig_keywords[] = { {"for", TokenIdKeywordFor}, {"if", TokenIdKeywordIf}, {"inline", TokenIdKeywordInline}, - {"nakedcc", TokenIdKeywordNakedCC}, {"noalias", TokenIdKeywordNoAlias}, {"noasync", TokenIdKeywordNoAsync}, {"noinline", TokenIdKeywordNoInline}, @@ -138,7 +138,6 @@ static const struct ZigKeyword zig_keywords[] = { {"resume", TokenIdKeywordResume}, {"return", TokenIdKeywordReturn}, {"linksection", TokenIdKeywordLinkSection}, - {"stdcallcc", TokenIdKeywordStdcallCC}, {"struct", TokenIdKeywordStruct}, {"suspend", TokenIdKeywordSuspend}, {"switch", TokenIdKeywordSwitch}, @@ -1545,6 +1544,7 @@ const char * token_name(TokenId id) { case TokenIdKeywordAsm: return "asm"; case TokenIdKeywordBreak: return "break"; case TokenIdKeywordCatch: return "catch"; + case TokenIdKeywordCallconv: return "callconv"; case TokenIdKeywordCompTime: return "comptime"; case TokenIdKeywordConst: return "const"; case TokenIdKeywordContinue: return "continue"; @@ -1560,7 +1560,6 @@ const char * token_name(TokenId id) { case TokenIdKeywordFor: return "for"; case TokenIdKeywordIf: return "if"; case TokenIdKeywordInline: return "inline"; - case TokenIdKeywordNakedCC: return "nakedcc"; case TokenIdKeywordNoAlias: return "noalias"; case TokenIdKeywordNoAsync: return "noasync"; case TokenIdKeywordNoInline: return "noinline"; @@ -1571,7 +1570,6 @@ const char * token_name(TokenId id) { case TokenIdKeywordPub: return "pub"; case TokenIdKeywordReturn: return "return"; case TokenIdKeywordLinkSection: return "linksection"; - case TokenIdKeywordStdcallCC: return "stdcallcc"; case TokenIdKeywordStruct: return "struct"; case TokenIdKeywordSwitch: return "switch"; case TokenIdKeywordTest: return "test"; diff --git a/src/tokenizer.hpp b/src/tokenizer.hpp index 084512a576..a893cc2373 100644 --- a/src/tokenizer.hpp +++ b/src/tokenizer.hpp @@ -59,6 +59,7 @@ enum TokenId { TokenIdKeywordAwait, TokenIdKeywordBreak, TokenIdKeywordCatch, + TokenIdKeywordCallconv, TokenIdKeywordCompTime, TokenIdKeywordConst, TokenIdKeywordContinue, @@ -76,7 +77,6 @@ enum TokenId { TokenIdKeywordInline, TokenIdKeywordNoInline, TokenIdKeywordLinkSection, - TokenIdKeywordNakedCC, TokenIdKeywordNoAlias, TokenIdKeywordNoAsync, TokenIdKeywordNull, @@ -86,7 +86,6 @@ enum TokenId { TokenIdKeywordPub, TokenIdKeywordResume, TokenIdKeywordReturn, - TokenIdKeywordStdcallCC, TokenIdKeywordStruct, TokenIdKeywordSuspend, TokenIdKeywordSwitch, diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 7ecb717047..b5c43b632b 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -273,10 +273,10 @@ ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref) { } LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args, - unsigned NumArgs, unsigned CC, ZigLLVM_CallAttr attr, const char *Name) + unsigned NumArgs, ZigLLVM_CallingConv CC, ZigLLVM_CallAttr attr, const char *Name) { CallInst *call_inst = CallInst::Create(unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Name); - call_inst->setCallingConv(CC); + call_inst->setCallingConv(static_cast(CC)); switch (attr) { case ZigLLVM_CallAttrAuto: break; @@ -932,6 +932,9 @@ void ZigLLVMFunctionSetPrefixData(LLVMValueRef function, LLVMValueRef data) { unwrap(function)->setPrefixData(unwrap(data)); } +void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, ZigLLVM_CallingConv cc) { + unwrap(function)->setCallingConv(static_cast(cc)); +} class MyOStream: public raw_ostream { public: @@ -1315,3 +1318,49 @@ static_assert((Triple::ObjectFormatType)ZigLLVM_ELF == Triple::ELF, ""); static_assert((Triple::ObjectFormatType)ZigLLVM_MachO == Triple::MachO, ""); static_assert((Triple::ObjectFormatType)ZigLLVM_Wasm == Triple::Wasm, ""); static_assert((Triple::ObjectFormatType)ZigLLVM_XCOFF == Triple::XCOFF, ""); + +static_assert((CallingConv::ID)ZigLLVM_C == llvm::CallingConv::C, ""); +static_assert((CallingConv::ID)ZigLLVM_Fast == llvm::CallingConv::Fast, ""); +static_assert((CallingConv::ID)ZigLLVM_Cold == llvm::CallingConv::Cold, ""); +static_assert((CallingConv::ID)ZigLLVM_GHC == llvm::CallingConv::GHC, ""); +static_assert((CallingConv::ID)ZigLLVM_HiPE == llvm::CallingConv::HiPE, ""); +static_assert((CallingConv::ID)ZigLLVM_WebKit_JS == llvm::CallingConv::WebKit_JS, ""); +static_assert((CallingConv::ID)ZigLLVM_AnyReg == llvm::CallingConv::AnyReg, ""); +static_assert((CallingConv::ID)ZigLLVM_PreserveMost == llvm::CallingConv::PreserveMost, ""); +static_assert((CallingConv::ID)ZigLLVM_PreserveAll == llvm::CallingConv::PreserveAll, ""); +static_assert((CallingConv::ID)ZigLLVM_Swift == llvm::CallingConv::Swift, ""); +static_assert((CallingConv::ID)ZigLLVM_CXX_FAST_TLS == llvm::CallingConv::CXX_FAST_TLS, ""); +static_assert((CallingConv::ID)ZigLLVM_FirstTargetCC == llvm::CallingConv::FirstTargetCC, ""); +static_assert((CallingConv::ID)ZigLLVM_X86_StdCall == llvm::CallingConv::X86_StdCall, ""); +static_assert((CallingConv::ID)ZigLLVM_X86_FastCall == llvm::CallingConv::X86_FastCall, ""); +static_assert((CallingConv::ID)ZigLLVM_ARM_APCS == llvm::CallingConv::ARM_APCS, ""); +static_assert((CallingConv::ID)ZigLLVM_ARM_AAPCS == llvm::CallingConv::ARM_AAPCS, ""); +static_assert((CallingConv::ID)ZigLLVM_ARM_AAPCS_VFP == llvm::CallingConv::ARM_AAPCS_VFP, ""); +static_assert((CallingConv::ID)ZigLLVM_MSP430_INTR == llvm::CallingConv::MSP430_INTR, ""); +static_assert((CallingConv::ID)ZigLLVM_X86_ThisCall == llvm::CallingConv::X86_ThisCall, ""); +static_assert((CallingConv::ID)ZigLLVM_PTX_Kernel == llvm::CallingConv::PTX_Kernel, ""); +static_assert((CallingConv::ID)ZigLLVM_PTX_Device == llvm::CallingConv::PTX_Device, ""); +static_assert((CallingConv::ID)ZigLLVM_SPIR_FUNC == llvm::CallingConv::SPIR_FUNC, ""); +static_assert((CallingConv::ID)ZigLLVM_SPIR_KERNEL == llvm::CallingConv::SPIR_KERNEL, ""); +static_assert((CallingConv::ID)ZigLLVM_Intel_OCL_BI == llvm::CallingConv::Intel_OCL_BI, ""); +static_assert((CallingConv::ID)ZigLLVM_X86_64_SysV == llvm::CallingConv::X86_64_SysV, ""); +static_assert((CallingConv::ID)ZigLLVM_Win64 == llvm::CallingConv::Win64, ""); +static_assert((CallingConv::ID)ZigLLVM_X86_VectorCall == llvm::CallingConv::X86_VectorCall, ""); +static_assert((CallingConv::ID)ZigLLVM_HHVM == llvm::CallingConv::HHVM, ""); +static_assert((CallingConv::ID)ZigLLVM_HHVM_C == llvm::CallingConv::HHVM_C, ""); +static_assert((CallingConv::ID)ZigLLVM_X86_INTR == llvm::CallingConv::X86_INTR, ""); +static_assert((CallingConv::ID)ZigLLVM_AVR_INTR == llvm::CallingConv::AVR_INTR, ""); +static_assert((CallingConv::ID)ZigLLVM_AVR_SIGNAL == llvm::CallingConv::AVR_SIGNAL, ""); +static_assert((CallingConv::ID)ZigLLVM_AVR_BUILTIN == llvm::CallingConv::AVR_BUILTIN, ""); +static_assert((CallingConv::ID)ZigLLVM_AMDGPU_VS == llvm::CallingConv::AMDGPU_VS, ""); +static_assert((CallingConv::ID)ZigLLVM_AMDGPU_GS == llvm::CallingConv::AMDGPU_GS, ""); +static_assert((CallingConv::ID)ZigLLVM_AMDGPU_PS == llvm::CallingConv::AMDGPU_PS, ""); +static_assert((CallingConv::ID)ZigLLVM_AMDGPU_CS == llvm::CallingConv::AMDGPU_CS, ""); +static_assert((CallingConv::ID)ZigLLVM_AMDGPU_KERNEL == llvm::CallingConv::AMDGPU_KERNEL, ""); +static_assert((CallingConv::ID)ZigLLVM_X86_RegCall == llvm::CallingConv::X86_RegCall, ""); +static_assert((CallingConv::ID)ZigLLVM_AMDGPU_HS == llvm::CallingConv::AMDGPU_HS, ""); +static_assert((CallingConv::ID)ZigLLVM_MSP430_BUILTIN == llvm::CallingConv::MSP430_BUILTIN, ""); +static_assert((CallingConv::ID)ZigLLVM_AMDGPU_LS == llvm::CallingConv::AMDGPU_LS, ""); +static_assert((CallingConv::ID)ZigLLVM_AMDGPU_ES == llvm::CallingConv::AMDGPU_ES, ""); +static_assert((CallingConv::ID)ZigLLVM_AArch64_VectorCall == llvm::CallingConv::AArch64_VectorCall, ""); +static_assert((CallingConv::ID)ZigLLVM_MaxID == llvm::CallingConv::MaxID, ""); diff --git a/src/zig_llvm.h b/src/zig_llvm.h index 4d8a3fa927..ba9816b4f8 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -64,6 +64,54 @@ ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, co ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref); +enum ZigLLVM_CallingConv { + ZigLLVM_C = 0, + ZigLLVM_Fast = 8, + ZigLLVM_Cold = 9, + ZigLLVM_GHC = 10, + ZigLLVM_HiPE = 11, + ZigLLVM_WebKit_JS = 12, + ZigLLVM_AnyReg = 13, + ZigLLVM_PreserveMost = 14, + ZigLLVM_PreserveAll = 15, + ZigLLVM_Swift = 16, + ZigLLVM_CXX_FAST_TLS = 17, + ZigLLVM_FirstTargetCC = 64, + ZigLLVM_X86_StdCall = 64, + ZigLLVM_X86_FastCall = 65, + ZigLLVM_ARM_APCS = 66, + ZigLLVM_ARM_AAPCS = 67, + ZigLLVM_ARM_AAPCS_VFP = 68, + ZigLLVM_MSP430_INTR = 69, + ZigLLVM_X86_ThisCall = 70, + ZigLLVM_PTX_Kernel = 71, + ZigLLVM_PTX_Device = 72, + ZigLLVM_SPIR_FUNC = 75, + ZigLLVM_SPIR_KERNEL = 76, + ZigLLVM_Intel_OCL_BI = 77, + ZigLLVM_X86_64_SysV = 78, + ZigLLVM_Win64 = 79, + ZigLLVM_X86_VectorCall = 80, + ZigLLVM_HHVM = 81, + ZigLLVM_HHVM_C = 82, + ZigLLVM_X86_INTR = 83, + ZigLLVM_AVR_INTR = 84, + ZigLLVM_AVR_SIGNAL = 85, + ZigLLVM_AVR_BUILTIN = 86, + ZigLLVM_AMDGPU_VS = 87, + ZigLLVM_AMDGPU_GS = 88, + ZigLLVM_AMDGPU_PS = 89, + ZigLLVM_AMDGPU_CS = 90, + ZigLLVM_AMDGPU_KERNEL = 91, + ZigLLVM_X86_RegCall = 92, + ZigLLVM_AMDGPU_HS = 93, + ZigLLVM_MSP430_BUILTIN = 94, + ZigLLVM_AMDGPU_LS = 95, + ZigLLVM_AMDGPU_ES = 96, + ZigLLVM_AArch64_VectorCall = 97, + ZigLLVM_MaxID = 1023, +}; + enum ZigLLVM_CallAttr { ZigLLVM_CallAttrAuto, ZigLLVM_CallAttrNeverTail, @@ -72,7 +120,7 @@ enum ZigLLVM_CallAttr { ZigLLVM_CallAttrAlwaysInline, }; ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args, - unsigned NumArgs, unsigned CC, enum ZigLLVM_CallAttr attr, const char *Name); + unsigned NumArgs, enum ZigLLVM_CallingConv CC, enum ZigLLVM_CallAttr attr, const char *Name); ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign, LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size, bool isVolatile); @@ -215,6 +263,7 @@ ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigne ZIG_EXTERN_C void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state); ZIG_EXTERN_C void ZigLLVMSetTailCall(LLVMValueRef Call); ZIG_EXTERN_C void ZigLLVMFunctionSetPrefixData(LLVMValueRef fn, LLVMValueRef data); +ZIG_EXTERN_C void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, enum ZigLLVM_CallingConv cc); ZIG_EXTERN_C void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value); ZIG_EXTERN_C void ZigLLVMAddByValAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val); diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 75e88ac918..fb1cf88e74 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -752,7 +752,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ _ = @frame(); \\} , &[_][]const u8{ - "tmp.zig:1:1: error: function with calling convention 'ccc' cannot be async", + "tmp.zig:1:1: error: function with calling convention 'C' cannot be async", "tmp.zig:5:9: note: @frame() causes function to be async", }); @@ -765,7 +765,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ suspend; \\} , &[_][]const u8{ - "tmp.zig:1:1: error: function with calling convention 'ccc' cannot be async", + "tmp.zig:1:1: error: function with calling convention 'C' cannot be async", "tmp.zig:3:18: note: await here is a suspend point", }); @@ -843,7 +843,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ suspend; \\} , &[_][]const u8{ - "tmp.zig:1:1: error: function with calling convention 'ccc' cannot be async", + "tmp.zig:1:1: error: function with calling convention 'C' cannot be async", "tmp.zig:2:8: note: async function call here", "tmp.zig:5:8: note: async function call here", "tmp.zig:8:5: note: suspends here", @@ -1140,7 +1140,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ while (true) {} \\} , &[_][]const u8{ - "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn([]const u8,var)var'", + "error: expected type 'fn([]const u8, ?*std.builtin.StackTrace) noreturn', found 'fn([]const u8,var) var'", "note: only one of the functions is generic", }); @@ -1362,7 +1362,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ return 0; \\} , &[_][]const u8{ - "tmp.zig:1:15: error: parameter of type 'var' not allowed in function with calling convention 'ccc'", + "tmp.zig:1:15: error: parameter of type 'var' not allowed in function with calling convention 'C'", }); cases.add("C pointer to c_void", @@ -2187,7 +2187,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ f(g); \\} , &[_][]const u8{ - "tmp.zig:1:9: error: parameter of type 'fn(var)var' must be declared comptime", + "tmp.zig:1:9: error: parameter of type 'fn(var) var' must be declared comptime", }); cases.add("optional pointer to void in extern struct", @@ -2843,7 +2843,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\export fn entry() void { \\ foo(); \\} - \\nakedcc fn foo() void { } + \\fn foo() callconv(.Naked) void { } , &[_][]const u8{ "tmp.zig:2:5: error: unable to call function with naked calling convention", "tmp.zig:4:1: note: declared here", @@ -2859,7 +2859,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\const Foo = enum { A, B, C }; \\export fn entry(foo: Foo) void { } , &[_][]const u8{ - "tmp.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'", + "tmp.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'", }); cases.add("function with non-extern non-packed struct parameter", @@ -2870,7 +2870,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\}; \\export fn entry(foo: Foo) void { } , &[_][]const u8{ - "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'", + "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'", }); cases.add("function with non-extern non-packed union parameter", @@ -2881,7 +2881,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\}; \\export fn entry(foo: Foo) void { } , &[_][]const u8{ - "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'", + "tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C'", }); cases.add("switch on enum with 1 field with no prongs", @@ -2972,13 +2972,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ foo(bar); \\} \\ - \\extern fn bar(x: *void) void { } + \\fn bar(x: *void) callconv(.C) void { } \\export fn entry2() void { \\ bar(&{}); \\} , &[_][]const u8{ - "tmp.zig:1:30: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'ccc'", - "tmp.zig:7:18: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'ccc'", + "tmp.zig:1:30: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'", + "tmp.zig:7:11: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'", }); cases.add("implicit semicolon - block statement", @@ -3871,7 +3871,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ \\export fn entry() usize { return @sizeOf(@TypeOf(fns)); } , &[_][]const u8{ - "tmp.zig:1:37: error: expected type 'fn(i32) i32', found 'extern fn(i32) i32'", + "tmp.zig:1:37: error: expected type 'fn(i32) i32', found 'fn(i32) callconv(.C) i32'", }); cases.add("colliding invalid top level functions", @@ -4552,7 +4552,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ return x + y; \\} , &[_][]const u8{ - "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'", + "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'", }); cases.add("extern function with comptime parameter", @@ -4562,7 +4562,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\} \\export fn entry() usize { return @sizeOf(@TypeOf(f)); } , &[_][]const u8{ - "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'", + "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'", }); cases.add("convert fixed size array to slice with invalid size", @@ -5618,7 +5618,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { }); cases.add("wrong types given to @export", - \\extern fn entry() void { } + \\fn entry() callconv(.C) void { } \\comptime { \\ @export("entry", entry, @as(u32, 1234)); \\} @@ -5663,7 +5663,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { }); cases.add("@setAlignStack in naked function", - \\export nakedcc fn entry() void { + \\export fn entry() callconv(.Naked) void { \\ @setAlignStack(16); \\} , &[_][]const u8{ @@ -6303,7 +6303,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ _ = @TypeOf(generic).ReturnType; \\} , &[_][]const u8{ - "tmp.zig:3:25: error: ReturnType has not been resolved because 'fn(var)var' is generic", + "tmp.zig:3:25: error: ReturnType has not been resolved because 'fn(var) var' is generic", }); cases.add("getting @ArgType of generic function", @@ -6312,7 +6312,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ _ = @ArgType(@TypeOf(generic), 0); \\} , &[_][]const u8{ - "tmp.zig:3:36: error: @ArgType could not resolve the type of arg 0 because 'fn(var)var' is generic", + "tmp.zig:3:36: error: @ArgType could not resolve the type of arg 0 because 'fn(var) var' is generic", }); cases.add("unsupported modifier at start of asm output constraint", diff --git a/test/src/translate_c.zig b/test/src/translate_c.zig index 6db1e6f181..ad820dcec6 100644 --- a/test/src/translate_c.zig +++ b/test/src/translate_c.zig @@ -19,6 +19,7 @@ pub const TranslateCContext = struct { sources: ArrayList(SourceFile), expected_lines: ArrayList([]const u8), allow_warnings: bool, + target: std.Target = .Native, const SourceFile = struct { filename: []const u8, @@ -71,6 +72,18 @@ pub const TranslateCContext = struct { self.addCase(tc); } + pub fn addWithTarget( + self: *TranslateCContext, + name: []const u8, + target: std.Target, + source: []const u8, + expected_lines: []const []const u8, + ) void { + const tc = self.create(false, "source.h", name, source, expected_lines); + tc.target = target; + self.addCase(tc); + } + pub fn addAllowWarnings( self: *TranslateCContext, name: []const u8, @@ -101,6 +114,7 @@ pub const TranslateCContext = struct { .basename = case.sources.toSliceConst()[0].filename, }, }); + translate_c.setTarget(case.target); const check_file = translate_c.addCheckFile(case.expected_lines.toSliceConst()); diff --git a/test/stage1/behavior/align.zig b/test/stage1/behavior/align.zig index 1812394f2e..c83d2379b4 100644 --- a/test/stage1/behavior/align.zig +++ b/test/stage1/behavior/align.zig @@ -221,14 +221,14 @@ test "alignment of structs" { }) == @alignOf(usize)); } -test "alignment of extern() void" { +test "alignment of function with c calling convention" { var runtime_nothing = nothing; const casted1 = @ptrCast(*const u8, runtime_nothing); - const casted2 = @ptrCast(extern fn () void, casted1); + const casted2 = @ptrCast(fn () callconv(.C) void, casted1); casted2(); } -extern fn nothing() void {} +fn nothing() callconv(.C) void {} test "return error union with 128-bit integer" { expect(3 == try give()); diff --git a/test/stage1/behavior/bugs/1310.zig b/test/stage1/behavior/bugs/1310.zig index f0f696e4bc..788cba5756 100644 --- a/test/stage1/behavior/bugs/1310.zig +++ b/test/stage1/behavior/bugs/1310.zig @@ -3,7 +3,7 @@ const expect = std.testing.expect; pub const VM = ?[*]const struct_InvocationTable_; pub const struct_InvocationTable_ = extern struct { - GetVM: ?extern fn (?[*]VM) c_int, + GetVM: ?fn (?[*]VM) callconv(.C) c_int, }; pub const struct_VM_ = extern struct { @@ -15,7 +15,7 @@ pub const struct_VM_ = extern struct { pub const InvocationTable_ = struct_InvocationTable_; pub const VM_ = struct_VM_; -extern fn agent_callback(_vm: [*]VM, options: [*]u8) i32 { +fn agent_callback(_vm: [*]VM, options: [*]u8) callconv(.C) i32 { return 11; } diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig index aca8c6fc34..ae2530af61 100644 --- a/test/stage1/behavior/cast.zig +++ b/test/stage1/behavior/cast.zig @@ -477,7 +477,7 @@ test "compile time int to ptr of function" { } pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize)); -pub const PFN_void = extern fn (*c_void) void; +pub const PFN_void = fn (*c_void) callconv(.C) void; fn foobar(func: PFN_void) void { std.testing.expect(@ptrToInt(func) == maxInt(usize)); @@ -587,7 +587,7 @@ test "peer cast *[0]T to []const T" { var global_array: [4]u8 = undefined; test "cast from array reference to fn" { - const f = @ptrCast(extern fn () void, &global_array); + const f = @ptrCast(fn () callconv(.C) void, &global_array); expect(@ptrToInt(f) == @ptrToInt(&global_array)); } diff --git a/test/stage1/behavior/fn.zig b/test/stage1/behavior/fn.zig index 654405df44..13859b92ca 100644 --- a/test/stage1/behavior/fn.zig +++ b/test/stage1/behavior/fn.zig @@ -186,9 +186,9 @@ test "return inner function which references comptime variable of outer function test "extern struct with stdcallcc fn pointer" { const S = extern struct { - ptr: stdcallcc fn () i32, + ptr: fn () callconv(.Stdcall) i32, - stdcallcc fn foo() i32 { + fn foo() callconv(.Stdcall) i32 { return 1234; } }; diff --git a/test/stage1/behavior/misc.zig b/test/stage1/behavior/misc.zig index 0b29189cde..9b9771a24c 100644 --- a/test/stage1/behavior/misc.zig +++ b/test/stage1/behavior/misc.zig @@ -19,7 +19,7 @@ comptime { @export("disabledExternFn", disabledExternFn, builtin.GlobalLinkage.Internal); } -extern fn disabledExternFn() void {} +fn disabledExternFn() callconv(.C) void {} test "call disabled extern fn" { disabledExternFn(); diff --git a/test/stage1/behavior/struct.zig b/test/stage1/behavior/struct.zig index 2d51498a85..8e5ab29db3 100644 --- a/test/stage1/behavior/struct.zig +++ b/test/stage1/behavior/struct.zig @@ -580,7 +580,7 @@ test "default struct initialization fields" { expectEqual(1239, x.a + x.b); } -test "extern fn returns struct by value" { +test "fn with C calling convention returns struct by value" { const S = struct { fn entry() void { var x = makeBar(10); @@ -591,7 +591,7 @@ test "extern fn returns struct by value" { handle: i32, }; - extern fn makeBar(t: i32) ExternBar { + fn makeBar(t: i32) callconv(.C) ExternBar { return ExternBar{ .handle = t, }; diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig index a9d4a1c924..d35cc8831f 100644 --- a/test/stage1/behavior/type_info.zig +++ b/test/stage1/behavior/type_info.zig @@ -202,7 +202,7 @@ fn testUnion() void { expect(typeinfo_info.Union.fields[4].enum_field != null); expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4); expect(typeinfo_info.Union.fields[4].field_type == @TypeOf(@typeInfo(u8).Int)); - expect(typeinfo_info.Union.decls.len == 21); + expect(typeinfo_info.Union.decls.len == 20); const TestNoTagUnion = union { Foo: void, @@ -266,7 +266,7 @@ test "type info: function type info" { fn testFunction() void { const fn_info = @typeInfo(@TypeOf(foo)); expect(@as(TypeId, fn_info) == TypeId.Fn); - expect(fn_info.Fn.calling_convention == TypeInfo.CallingConvention.Unspecified); + expect(fn_info.Fn.calling_convention == .Unspecified); expect(fn_info.Fn.is_generic); expect(fn_info.Fn.args.len == 2); expect(fn_info.Fn.is_var_args); diff --git a/test/standalone/load_dynamic_library/main.zig b/test/standalone/load_dynamic_library/main.zig index d1cba72db5..197e3ca47c 100644 --- a/test/standalone/load_dynamic_library/main.zig +++ b/test/standalone/load_dynamic_library/main.zig @@ -9,7 +9,7 @@ pub fn main() !void { var lib = try std.DynLib.open(dynlib_name); defer lib.close(); - const addFn = lib.lookup(extern fn (i32, i32) i32, "add") orelse return error.SymbolNotFound; + const addFn = lib.lookup(fn (i32, i32) callconv(.C) i32, "add") orelse return error.SymbolNotFound; const result = addFn(12, 34); std.debug.assert(result == 46); diff --git a/test/translate_c.zig b/test/translate_c.zig index 7049173d80..3714d370eb 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -205,7 +205,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\static void bar(void) {} , &[_][]const u8{ \\pub export fn foo() void {} - \\pub fn bar() void {} + \\pub fn bar() callconv(.C) void {} }); cases.add("typedef void", @@ -238,7 +238,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub extern fn foo() void; \\pub export fn bar() void { \\ var func_ptr: ?*c_void = @ptrCast(?*c_void, foo); - \\ var typed_func_ptr: ?extern fn () void = @intToPtr(?extern fn () void, @intCast(c_ulong, @ptrToInt(func_ptr))); + \\ var typed_func_ptr: ?fn () callconv(.C) void = @intToPtr(?fn () callconv(.C) void, @intCast(c_ulong, @ptrToInt(func_ptr))); \\} }); @@ -295,9 +295,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ lws_callback_function *callback_http; \\}; , &[_][]const u8{ - \\pub const lws_callback_function = extern fn () void; + \\pub const lws_callback_function = fn () callconv(.C) void; \\pub const struct_Foo = extern struct { - \\ func: ?extern fn () void, + \\ func: ?fn () callconv(.C) void, \\ callback_http: ?lws_callback_function, \\}; }); @@ -377,7 +377,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\}; , &[_][]const u8{ \\pub const struct_Foo = extern struct { - \\ derp: ?extern fn ([*c]struct_Foo) void, + \\ derp: ?fn ([*c]struct_Foo) callconv(.C) void, \\}; , \\pub const Foo = struct_Foo; @@ -611,7 +611,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { cases.add("__cdecl doesn't mess up function pointers", \\void foo(void (__cdecl *fn_ptr)(void)); , &[_][]const u8{ - \\pub extern fn foo(fn_ptr: ?extern fn () void) void; + \\pub extern fn foo(fn_ptr: ?fn () callconv(.C) void) void; }); cases.add("void cast", @@ -953,8 +953,42 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\typedef void (*fn0)(); \\typedef void (*fn1)(char); , &[_][]const u8{ - \\pub const fn0 = ?extern fn (...) void; - \\pub const fn1 = ?extern fn (u8) void; + \\pub const fn0 = ?fn (...) callconv(.C) void; + \\pub const fn1 = ?fn (u8) callconv(.C) void; + }); + + cases.addWithTarget("Calling convention", tests.Target{ + .Cross = .{ .os = .linux, .arch = .i386, .abi = .none }, + }, + \\void __attribute__((fastcall)) foo1(float *a); + \\void __attribute__((stdcall)) foo2(float *a); + \\void __attribute__((vectorcall)) foo3(float *a); + \\void __attribute__((cdecl)) foo4(float *a); + \\void __attribute__((thiscall)) foo5(float *a); + , &[_][]const u8{ + \\pub fn foo1(a: [*c]f32) callconv(.Fastcall) void; + \\pub fn foo2(a: [*c]f32) callconv(.Stdcall) void; + \\pub fn foo3(a: [*c]f32) callconv(.Vectorcall) void; + \\pub extern fn foo4(a: [*c]f32) void; + \\pub fn foo5(a: [*c]f32) callconv(.Thiscall) void; + }); + + cases.addWithTarget("Calling convention", tests.Target{ + .Cross = .{ .os = .linux, .arch = .{ .arm = .v8_5a }, .abi = .none }, + }, + \\void __attribute__((pcs("aapcs"))) foo1(float *a); + \\void __attribute__((pcs("aapcs-vfp"))) foo2(float *a); + , &[_][]const u8{ + \\pub fn foo1(a: [*c]f32) callconv(.AAPCS) void; + \\pub fn foo2(a: [*c]f32) callconv(.AAPCSVFP) void; + }); + + cases.addWithTarget("Calling convention", tests.Target{ + .Cross = .{ .os = .linux, .arch = .{ .aarch64 = .v8_5a }, .abi = .none }, + }, + \\void __attribute__((aarch64_vector_pcs)) foo1(float *a); + , &[_][]const u8{ + \\pub fn foo1(a: [*c]f32) callconv(.Vectorcall) void; }); cases.add("Parameterless function prototypes", @@ -985,7 +1019,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ char *arr1[10] ={0}; \\} , &[_][]const u8{ - \\pub fn foo() void { + \\pub fn foo() callconv(.C) void { \\ var arr: [10]u8 = .{ \\ @bitCast(u8, @truncate(i8, @as(c_int, 1))), \\ } ++ .{0} ** 9; @@ -1123,13 +1157,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\extern char (*fn_ptr2)(int, float); \\#define bar fn_ptr2 , &[_][]const u8{ - \\pub extern var fn_ptr: ?extern fn () void; + \\pub extern var fn_ptr: ?fn () callconv(.C) void; , \\pub inline fn foo() void { \\ return fn_ptr.?(); \\} , - \\pub extern var fn_ptr2: ?extern fn (c_int, f32) u8; + \\pub extern var fn_ptr2: ?fn (c_int, f32) callconv(.C) u8; , \\pub inline fn bar(arg_1: c_int, arg_2: f32) u8 { \\ return fn_ptr2.?(arg_1, arg_2); @@ -1151,8 +1185,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\#define glClearPFN PFNGLCLEARPROC , &[_][]const u8{ \\pub const GLbitfield = c_uint; - \\pub const PFNGLCLEARPROC = ?extern fn (GLbitfield) void; - \\pub const OpenGLProc = ?extern fn () void; + \\pub const PFNGLCLEARPROC = ?fn (GLbitfield) callconv(.C) void; + \\pub const OpenGLProc = ?fn () callconv(.C) void; \\const struct_unnamed_1 = extern struct { \\ Clear: PFNGLCLEARPROC, \\}; @@ -1942,8 +1976,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ return 0; \\} \\pub export fn bar() void { - \\ var f: ?extern fn () void = foo; - \\ var b: ?extern fn () c_int = baz; + \\ var f: ?fn () callconv(.C) void = foo; + \\ var b: ?fn () callconv(.C) c_int = baz; \\ f.?(); \\ (f).?(); \\ foo(); @@ -2262,8 +2296,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ baz(); \\} , &[_][]const u8{ - \\pub fn bar() void {} - \\pub export fn foo(arg_baz: ?extern fn () [*c]c_int) void { + \\pub fn bar() callconv(.C) void {} + \\pub export fn foo(arg_baz: ?fn () callconv(.C) [*c]c_int) void { \\ var baz = arg_baz; \\ bar(); \\ _ = baz.?(); @@ -2321,7 +2355,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ do {} while (0); \\} , &[_][]const u8{ - \\pub fn foo() void { + \\pub fn foo() callconv(.C) void { \\ if (@as(c_int, 1) != 0) while (true) { \\ if (!(@as(c_int, 0) != 0)) break; \\ }; @@ -2413,9 +2447,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\void c(void) {} \\static void foo() {} , &[_][]const u8{ - \\pub fn a() void {} - \\pub fn b() void {} + \\pub fn a() callconv(.C) void {} + \\pub fn b() callconv(.C) void {} \\pub export fn c() void {} - \\pub fn foo() void {} + \\pub fn foo() callconv(.C) void {} }); }