| author | |
| committer | |
| log | 343987cd057c5f2f0aad197518d7d573579d0d08 |
| tree | 733e506597f80f4aeb040dc7c931d77c2d0dbcaf |
| parent | ef83358eb6702e8541816817e98c3e7279033672 |
| signature | Commit is signed but in an unrecognized format. |
25 files changed, 372 insertions(+), 226 deletions(-)
doc/langref.html.in-21| ... | @@ -7492,27 +7492,6 @@ test "@hasDecl" { | ... | @@ -7492,27 +7492,6 @@ test "@hasDecl" { |
| 7492 | {#see_also|Compile Variables|@embedFile#} | 7492 | {#see_also|Compile Variables|@embedFile#} |
| 7493 | {#header_close#} | 7493 | {#header_close#} |
| 7494 | 7494 | ||
| 7495 | {#header_open|@inlineCall#} | ||
| 7496 | <pre>{#syntax#}@inlineCall(function: X, args: ...) Y{#endsyntax#}</pre> | ||
| 7497 | <p> | ||
| 7498 | This calls a function, in the same way that invoking an expression with parentheses does: | ||
| 7499 | </p> | ||
| 7500 | {#code_begin|test#} | ||
| 7501 | const assert = @import("std").debug.assert; | ||
| 7502 | |||
| 7503 | test "inline function call" { | ||
| 7504 | assert(@inlineCall(add, 3, 9) == 12); | ||
| 7505 | } | ||
| 7506 | |||
| 7507 | fn add(a: i32, b: i32) i32 { return a + b; } | ||
| 7508 | {#code_end#} | ||
| 7509 | <p> | ||
| 7510 | Unlike a normal function call, however, {#syntax#}@inlineCall{#endsyntax#} guarantees that the call | ||
| 7511 | will be inlined. If the call cannot be inlined, a compile error is emitted. | ||
| 7512 | </p> | ||
| 7513 | {#see_also|@call#} | ||
| 7514 | {#header_close#} | ||
| 7515 | |||
| 7516 | {#header_open|@intCast#} | 7495 | {#header_open|@intCast#} |
| 7517 | <pre>{#syntax#}@intCast(comptime DestType: type, int: var) DestType{#endsyntax#}</pre> | 7496 | <pre>{#syntax#}@intCast(comptime DestType: type, int: var) DestType{#endsyntax#}</pre> |
| 7518 | <p> | 7497 | <p> |
lib/std/hash/auto_hash.zig+2-2| ... | @@ -92,7 +92,7 @@ pub fn hash(hasher: var, key: var, comptime strat: HashStrategy) void { | ... | @@ -92,7 +92,7 @@ pub fn hash(hasher: var, key: var, comptime strat: HashStrategy) void { |
| 92 | 92 | ||
| 93 | // Help the optimizer see that hashing an int is easy by inlining! | 93 | // Help the optimizer see that hashing an int is easy by inlining! |
| 94 | // TODO Check if the situation is better after #561 is resolved. | 94 | // TODO Check if the situation is better after #561 is resolved. |
| 95 | .Int => @inlineCall(hasher.update, std.mem.asBytes(&key)), | 95 | .Int => @call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)}), |
| 96 | 96 | ||
| 97 | .Float => |info| hash(hasher, @bitCast(@IntType(false, info.bits), key), strat), | 97 | .Float => |info| hash(hasher, @bitCast(@IntType(false, info.bits), key), strat), |
| 98 | 98 | ||
| ... | @@ -101,7 +101,7 @@ pub fn hash(hasher: var, key: var, comptime strat: HashStrategy) void { | ... | @@ -101,7 +101,7 @@ pub fn hash(hasher: var, key: var, comptime strat: HashStrategy) void { |
| 101 | .ErrorSet => hash(hasher, @errorToInt(key), strat), | 101 | .ErrorSet => hash(hasher, @errorToInt(key), strat), |
| 102 | .AnyFrame, .Fn => hash(hasher, @ptrToInt(key), strat), | 102 | .AnyFrame, .Fn => hash(hasher, @ptrToInt(key), strat), |
| 103 | 103 | ||
| 104 | .Pointer => @inlineCall(hashPointer, hasher, key, strat), | 104 | .Pointer => @call(.{ .modifier = .always_inline }, hashPointer, .{ hasher, key, strat }), |
| 105 | 105 | ||
| 106 | .Optional => if (key) |k| hash(hasher, k, strat), | 106 | .Optional => if (key) |k| hash(hasher, k, strat), |
| 107 | 107 |
lib/std/hash/cityhash.zig+11-4| ... | @@ -197,7 +197,7 @@ pub const CityHash64 = struct { | ... | @@ -197,7 +197,7 @@ pub const CityHash64 = struct { |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | fn hashLen16(u: u64, v: u64) u64 { | 199 | fn hashLen16(u: u64, v: u64) u64 { |
| 200 | return @inlineCall(hash128To64, u, v); | 200 | return @call(.{ .modifier = .always_inline }, hash128To64, .{ u, v }); |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | fn hashLen16Mul(low: u64, high: u64, mul: u64) u64 { | 203 | fn hashLen16Mul(low: u64, high: u64, mul: u64) u64 { |
| ... | @@ -210,7 +210,7 @@ pub const CityHash64 = struct { | ... | @@ -210,7 +210,7 @@ pub const CityHash64 = struct { |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | fn hash128To64(low: u64, high: u64) u64 { | 212 | fn hash128To64(low: u64, high: u64) u64 { |
| 213 | return @inlineCall(hashLen16Mul, low, high, 0x9ddfea08eb382d69); | 213 | return @call(.{ .modifier = .always_inline }, hashLen16Mul, .{ low, high, 0x9ddfea08eb382d69 }); |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | fn hashLen0To16(str: []const u8) u64 { | 216 | fn hashLen0To16(str: []const u8) u64 { |
| ... | @@ -291,7 +291,14 @@ pub const CityHash64 = struct { | ... | @@ -291,7 +291,14 @@ pub const CityHash64 = struct { |
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | fn weakHashLen32WithSeeds(ptr: [*]const u8, a: u64, b: u64) WeakPair { | 293 | fn weakHashLen32WithSeeds(ptr: [*]const u8, a: u64, b: u64) WeakPair { |
| 294 | return @inlineCall(weakHashLen32WithSeedsHelper, fetch64(ptr), fetch64(ptr + 8), fetch64(ptr + 16), fetch64(ptr + 24), a, b); | 294 | return @call(.{ .modifier = .always_inline }, weakHashLen32WithSeedsHelper, .{ |
| 295 | fetch64(ptr), | ||
| 296 | fetch64(ptr + 8), | ||
| 297 | fetch64(ptr + 16), | ||
| 298 | fetch64(ptr + 24), | ||
| 299 | a, | ||
| 300 | b, | ||
| 301 | }); | ||
| 295 | } | 302 | } |
| 296 | 303 | ||
| 297 | pub fn hash(str: []const u8) u64 { | 304 | pub fn hash(str: []const u8) u64 { |
| ... | @@ -339,7 +346,7 @@ pub const CityHash64 = struct { | ... | @@ -339,7 +346,7 @@ pub const CityHash64 = struct { |
| 339 | } | 346 | } |
| 340 | 347 | ||
| 341 | pub fn hashWithSeed(str: []const u8, seed: u64) u64 { | 348 | pub fn hashWithSeed(str: []const u8, seed: u64) u64 { |
| 342 | return @inlineCall(Self.hashWithSeeds, str, k2, seed); | 349 | return @call(.{ .modifier = .always_inline }, Self.hashWithSeeds, .{ str, k2, seed }); |
| 343 | } | 350 | } |
| 344 | 351 | ||
| 345 | pub fn hashWithSeeds(str: []const u8, seed0: u64, seed1: u64) u64 { | 352 | pub fn hashWithSeeds(str: []const u8, seed0: u64, seed1: u64) u64 { |
lib/std/hash/murmur.zig+9-9| ... | @@ -8,7 +8,7 @@ pub const Murmur2_32 = struct { | ... | @@ -8,7 +8,7 @@ pub const Murmur2_32 = struct { |
| 8 | const Self = @This(); | 8 | const Self = @This(); |
| 9 | 9 | ||
| 10 | pub fn hash(str: []const u8) u32 { | 10 | pub fn hash(str: []const u8) u32 { |
| 11 | return @inlineCall(Self.hashWithSeed, str, default_seed); | 11 | return @call(.{ .modifier = .always_inline }, Self.hashWithSeed, .{ str, default_seed }); |
| 12 | } | 12 | } |
| 13 | 13 | ||
| 14 | pub fn hashWithSeed(str: []const u8, seed: u32) u32 { | 14 | pub fn hashWithSeed(str: []const u8, seed: u32) u32 { |
| ... | @@ -44,7 +44,7 @@ pub const Murmur2_32 = struct { | ... | @@ -44,7 +44,7 @@ pub const Murmur2_32 = struct { |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | pub fn hashUint32(v: u32) u32 { | 46 | pub fn hashUint32(v: u32) u32 { |
| 47 | return @inlineCall(Self.hashUint32WithSeed, v, default_seed); | 47 | return @call(.{ .modifier = .always_inline }, Self.hashUint32WithSeed, .{ v, default_seed }); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | pub fn hashUint32WithSeed(v: u32, seed: u32) u32 { | 50 | pub fn hashUint32WithSeed(v: u32, seed: u32) u32 { |
| ... | @@ -64,7 +64,7 @@ pub const Murmur2_32 = struct { | ... | @@ -64,7 +64,7 @@ pub const Murmur2_32 = struct { |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | pub fn hashUint64(v: u64) u32 { | 66 | pub fn hashUint64(v: u64) u32 { |
| 67 | return @inlineCall(Self.hashUint64WithSeed, v, default_seed); | 67 | return @call(.{ .modifier = .always_inline }, Self.hashUint64WithSeed, .{ v, default_seed }); |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | pub fn hashUint64WithSeed(v: u64, seed: u32) u32 { | 70 | pub fn hashUint64WithSeed(v: u64, seed: u32) u32 { |
| ... | @@ -93,7 +93,7 @@ pub const Murmur2_64 = struct { | ... | @@ -93,7 +93,7 @@ pub const Murmur2_64 = struct { |
| 93 | const Self = @This(); | 93 | const Self = @This(); |
| 94 | 94 | ||
| 95 | pub fn hash(str: []const u8) u64 { | 95 | pub fn hash(str: []const u8) u64 { |
| 96 | return @inlineCall(Self.hashWithSeed, str, default_seed); | 96 | return @call(.{ .modifier = .always_inline }, Self.hashWithSeed, .{ str, default_seed }); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | pub fn hashWithSeed(str: []const u8, seed: u64) u64 { | 99 | pub fn hashWithSeed(str: []const u8, seed: u64) u64 { |
| ... | @@ -127,7 +127,7 @@ pub const Murmur2_64 = struct { | ... | @@ -127,7 +127,7 @@ pub const Murmur2_64 = struct { |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | pub fn hashUint32(v: u32) u64 { | 129 | pub fn hashUint32(v: u32) u64 { |
| 130 | return @inlineCall(Self.hashUint32WithSeed, v, default_seed); | 130 | return @call(.{ .modifier = .always_inline }, Self.hashUint32WithSeed, .{ v, default_seed }); |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | pub fn hashUint32WithSeed(v: u32, seed: u32) u64 { | 133 | pub fn hashUint32WithSeed(v: u32, seed: u32) u64 { |
| ... | @@ -144,7 +144,7 @@ pub const Murmur2_64 = struct { | ... | @@ -144,7 +144,7 @@ pub const Murmur2_64 = struct { |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | pub fn hashUint64(v: u64) u64 { | 146 | pub fn hashUint64(v: u64) u64 { |
| 147 | return @inlineCall(Self.hashUint64WithSeed, v, default_seed); | 147 | return @call(.{ .modifier = .always_inline }, Self.hashUint64WithSeed, .{ v, default_seed }); |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | pub fn hashUint64WithSeed(v: u64, seed: u32) u64 { | 150 | pub fn hashUint64WithSeed(v: u64, seed: u32) u64 { |
| ... | @@ -172,7 +172,7 @@ pub const Murmur3_32 = struct { | ... | @@ -172,7 +172,7 @@ pub const Murmur3_32 = struct { |
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | pub fn hash(str: []const u8) u32 { | 174 | pub fn hash(str: []const u8) u32 { |
| 175 | return @inlineCall(Self.hashWithSeed, str, default_seed); | 175 | return @call(.{ .modifier = .always_inline }, Self.hashWithSeed, .{ str, default_seed }); |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | pub fn hashWithSeed(str: []const u8, seed: u32) u32 { | 178 | pub fn hashWithSeed(str: []const u8, seed: u32) u32 { |
| ... | @@ -220,7 +220,7 @@ pub const Murmur3_32 = struct { | ... | @@ -220,7 +220,7 @@ pub const Murmur3_32 = struct { |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | pub fn hashUint32(v: u32) u32 { | 222 | pub fn hashUint32(v: u32) u32 { |
| 223 | return @inlineCall(Self.hashUint32WithSeed, v, default_seed); | 223 | return @call(.{ .modifier = .always_inline }, Self.hashUint32WithSeed, .{ v, default_seed }); |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | pub fn hashUint32WithSeed(v: u32, seed: u32) u32 { | 226 | pub fn hashUint32WithSeed(v: u32, seed: u32) u32 { |
| ... | @@ -246,7 +246,7 @@ pub const Murmur3_32 = struct { | ... | @@ -246,7 +246,7 @@ pub const Murmur3_32 = struct { |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | pub fn hashUint64(v: u64) u32 { | 248 | pub fn hashUint64(v: u64) u32 { |
| 249 | return @inlineCall(Self.hashUint64WithSeed, v, default_seed); | 249 | return @call(.{ .modifier = .always_inline }, Self.hashUint64WithSeed, .{ v, default_seed }); |
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | pub fn hashUint64WithSeed(v: u64, seed: u32) u32 { | 252 | pub fn hashUint64WithSeed(v: u64, seed: u32) u32 { |
lib/std/hash/siphash.zig+12-7| ... | @@ -11,7 +11,7 @@ const testing = std.testing; | ... | @@ -11,7 +11,7 @@ const testing = std.testing; |
| 11 | const math = std.math; | 11 | const math = std.math; |
| 12 | const mem = std.mem; | 12 | const mem = std.mem; |
| 13 | 13 | ||
| 14 | const Endian = @import("builtin").Endian; | 14 | const Endian = std.builtin.Endian; |
| 15 | 15 | ||
| 16 | pub fn SipHash64(comptime c_rounds: usize, comptime d_rounds: usize) type { | 16 | pub fn SipHash64(comptime c_rounds: usize, comptime d_rounds: usize) type { |
| 17 | return SipHash(u64, c_rounds, d_rounds); | 17 | return SipHash(u64, c_rounds, d_rounds); |
| ... | @@ -62,7 +62,7 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round | ... | @@ -62,7 +62,7 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round |
| 62 | 62 | ||
| 63 | var off: usize = 0; | 63 | var off: usize = 0; |
| 64 | while (off < b.len) : (off += 8) { | 64 | while (off < b.len) : (off += 8) { |
| 65 | @inlineCall(self.round, b[off .. off + 8]); | 65 | @call(.{ .modifier = .always_inline }, self.round, .{b[off .. off + 8]}); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | self.msg_len +%= @truncate(u8, b.len); | 68 | self.msg_len +%= @truncate(u8, b.len); |
| ... | @@ -84,9 +84,12 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round | ... | @@ -84,9 +84,12 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round |
| 84 | self.v2 ^= 0xff; | 84 | self.v2 ^= 0xff; |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | // TODO this is a workaround, should be able to supply the value without a separate variable | ||
| 88 | const inl = std.builtin.CallOptions{ .modifier = .always_inline }; | ||
| 89 | |||
| 87 | comptime var i: usize = 0; | 90 | comptime var i: usize = 0; |
| 88 | inline while (i < d_rounds) : (i += 1) { | 91 | inline while (i < d_rounds) : (i += 1) { |
| 89 | @inlineCall(sipRound, self); | 92 | @call(inl, sipRound, .{self}); |
| 90 | } | 93 | } |
| 91 | 94 | ||
| 92 | const b1 = self.v0 ^ self.v1 ^ self.v2 ^ self.v3; | 95 | const b1 = self.v0 ^ self.v1 ^ self.v2 ^ self.v3; |
| ... | @@ -98,7 +101,7 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round | ... | @@ -98,7 +101,7 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round |
| 98 | 101 | ||
| 99 | comptime var j: usize = 0; | 102 | comptime var j: usize = 0; |
| 100 | inline while (j < d_rounds) : (j += 1) { | 103 | inline while (j < d_rounds) : (j += 1) { |
| 101 | @inlineCall(sipRound, self); | 104 | @call(inl, sipRound, .{self}); |
| 102 | } | 105 | } |
| 103 | 106 | ||
| 104 | const b2 = self.v0 ^ self.v1 ^ self.v2 ^ self.v3; | 107 | const b2 = self.v0 ^ self.v1 ^ self.v2 ^ self.v3; |
| ... | @@ -111,9 +114,11 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round | ... | @@ -111,9 +114,11 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round |
| 111 | const m = mem.readIntSliceLittle(u64, b[0..]); | 114 | const m = mem.readIntSliceLittle(u64, b[0..]); |
| 112 | self.v3 ^= m; | 115 | self.v3 ^= m; |
| 113 | 116 | ||
| 117 | // TODO this is a workaround, should be able to supply the value without a separate variable | ||
| 118 | const inl = std.builtin.CallOptions{ .modifier = .always_inline }; | ||
| 114 | comptime var i: usize = 0; | 119 | comptime var i: usize = 0; |
| 115 | inline while (i < c_rounds) : (i += 1) { | 120 | inline while (i < c_rounds) : (i += 1) { |
| 116 | @inlineCall(sipRound, self); | 121 | @call(inl, sipRound, .{self}); |
| 117 | } | 122 | } |
| 118 | 123 | ||
| 119 | self.v0 ^= m; | 124 | self.v0 ^= m; |
| ... | @@ -140,8 +145,8 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round | ... | @@ -140,8 +145,8 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round |
| 140 | const aligned_len = input.len - (input.len % 8); | 145 | const aligned_len = input.len - (input.len % 8); |
| 141 | 146 | ||
| 142 | var c = Self.init(key); | 147 | var c = Self.init(key); |
| 143 | @inlineCall(c.update, input[0..aligned_len]); | 148 | @call(.{ .modifier = .always_inline }, c.update, .{input[0..aligned_len]}); |
| 144 | return @inlineCall(c.final, input[aligned_len..]); | 149 | return @call(.{ .modifier = .always_inline }, c.final, .{input[aligned_len..]}); |
| 145 | } | 150 | } |
| 146 | }; | 151 | }; |
| 147 | } | 152 | } |
lib/std/hash/wyhash.zig+3-3| ... | @@ -65,7 +65,7 @@ const WyhashStateless = struct { | ... | @@ -65,7 +65,7 @@ const WyhashStateless = struct { |
| 65 | 65 | ||
| 66 | var off: usize = 0; | 66 | var off: usize = 0; |
| 67 | while (off < b.len) : (off += 32) { | 67 | while (off < b.len) : (off += 32) { |
| 68 | @inlineCall(self.round, b[off .. off + 32]); | 68 | @call(.{ .modifier = .always_inline }, self.round, .{b[off .. off + 32]}); |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | self.msg_len += b.len; | 71 | self.msg_len += b.len; |
| ... | @@ -121,8 +121,8 @@ const WyhashStateless = struct { | ... | @@ -121,8 +121,8 @@ const WyhashStateless = struct { |
| 121 | const aligned_len = input.len - (input.len % 32); | 121 | const aligned_len = input.len - (input.len % 32); |
| 122 | 122 | ||
| 123 | var c = WyhashStateless.init(seed); | 123 | var c = WyhashStateless.init(seed); |
| 124 | @inlineCall(c.update, input[0..aligned_len]); | 124 | @call(.{ .modifier = .always_inline }, c.update, .{input[0..aligned_len]}); |
| 125 | return @inlineCall(c.final, input[aligned_len..]); | 125 | return @call(.{ .modifier = .always_inline }, c.final, .{input[aligned_len..]}); |
| 126 | } | 126 | } |
| 127 | }; | 127 | }; |
| 128 | 128 |
lib/std/math/big/int.zig+11-3| ... | @@ -811,7 +811,7 @@ pub const Int = struct { | ... | @@ -811,7 +811,7 @@ pub const Int = struct { |
| 811 | 811 | ||
| 812 | var j: usize = 0; | 812 | var j: usize = 0; |
| 813 | while (j < a_lo.len) : (j += 1) { | 813 | while (j < a_lo.len) : (j += 1) { |
| 814 | a_lo[j] = @inlineCall(addMulLimbWithCarry, a_lo[j], y[j], xi, &carry); | 814 | a_lo[j] = @call(.{ .modifier = .always_inline }, addMulLimbWithCarry, .{ a_lo[j], y[j], xi, &carry }); |
| 815 | } | 815 | } |
| 816 | 816 | ||
| 817 | j = 0; | 817 | j = 0; |
| ... | @@ -1214,7 +1214,11 @@ pub const Int = struct { | ... | @@ -1214,7 +1214,11 @@ pub const Int = struct { |
| 1214 | const dst_i = src_i + limb_shift; | 1214 | const dst_i = src_i + limb_shift; |
| 1215 | 1215 | ||
| 1216 | const src_digit = a[src_i]; | 1216 | const src_digit = a[src_i]; |
| 1217 | r[dst_i] = carry | @inlineCall(math.shr, Limb, src_digit, Limb.bit_count - @intCast(Limb, interior_limb_shift)); | 1217 | r[dst_i] = carry | @call(.{ .modifier = .always_inline }, math.shr, .{ |
| 1218 | Limb, | ||
| 1219 | src_digit, | ||
| 1220 | Limb.bit_count - @intCast(Limb, interior_limb_shift), | ||
| 1221 | }); | ||
| 1218 | carry = (src_digit << interior_limb_shift); | 1222 | carry = (src_digit << interior_limb_shift); |
| 1219 | } | 1223 | } |
| 1220 | 1224 | ||
| ... | @@ -1254,7 +1258,11 @@ pub const Int = struct { | ... | @@ -1254,7 +1258,11 @@ pub const Int = struct { |
| 1254 | 1258 | ||
| 1255 | const src_digit = a[src_i]; | 1259 | const src_digit = a[src_i]; |
| 1256 | r[dst_i] = carry | (src_digit >> interior_limb_shift); | 1260 | r[dst_i] = carry | (src_digit >> interior_limb_shift); |
| 1257 | carry = @inlineCall(math.shl, Limb, src_digit, Limb.bit_count - @intCast(Limb, interior_limb_shift)); | 1261 | carry = @call(.{ .modifier = .always_inline }, math.shl, .{ |
| 1262 | Limb, | ||
| 1263 | src_digit, | ||
| 1264 | Limb.bit_count - @intCast(Limb, interior_limb_shift), | ||
| 1265 | }); | ||
| 1258 | } | 1266 | } |
| 1259 | } | 1267 | } |
| 1260 | 1268 |
lib/std/os/linux.zig+1-1| ... | @@ -94,7 +94,7 @@ pub fn fork() usize { | ... | @@ -94,7 +94,7 @@ pub fn fork() usize { |
| 94 | /// the compiler is not aware of how vfork affects control flow and you may | 94 | /// the compiler is not aware of how vfork affects control flow and you may |
| 95 | /// see different results in optimized builds. | 95 | /// see different results in optimized builds. |
| 96 | pub inline fn vfork() usize { | 96 | pub inline fn vfork() usize { |
| 97 | return @inlineCall(syscall0, SYS_vfork); | 97 | return @call(.{ .modifier = .always_inline }, syscall0, .{SYS_vfork}); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | pub fn futimens(fd: i32, times: *const [2]timespec) usize { | 100 | pub fn futimens(fd: i32, times: *const [2]timespec) usize { |
lib/std/special/compiler_rt/arm/aeabi_dcmp.zig+5-5| ... | @@ -14,31 +14,31 @@ const ConditionalOperator = enum { | ... | @@ -14,31 +14,31 @@ const ConditionalOperator = enum { |
| 14 | 14 | ||
| 15 | pub nakedcc fn __aeabi_dcmpeq() noreturn { | 15 | pub nakedcc fn __aeabi_dcmpeq() noreturn { |
| 16 | @setRuntimeSafety(false); | 16 | @setRuntimeSafety(false); |
| 17 | @inlineCall(aeabi_dcmp, .Eq); | 17 | @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Eq}); |
| 18 | unreachable; | 18 | unreachable; |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | pub nakedcc fn __aeabi_dcmplt() noreturn { | 21 | pub nakedcc fn __aeabi_dcmplt() noreturn { |
| 22 | @setRuntimeSafety(false); | 22 | @setRuntimeSafety(false); |
| 23 | @inlineCall(aeabi_dcmp, .Lt); | 23 | @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Lt}); |
| 24 | unreachable; | 24 | unreachable; |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | pub nakedcc fn __aeabi_dcmple() noreturn { | 27 | pub nakedcc fn __aeabi_dcmple() noreturn { |
| 28 | @setRuntimeSafety(false); | 28 | @setRuntimeSafety(false); |
| 29 | @inlineCall(aeabi_dcmp, .Le); | 29 | @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Le}); |
| 30 | unreachable; | 30 | unreachable; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | pub nakedcc fn __aeabi_dcmpge() noreturn { | 33 | pub nakedcc fn __aeabi_dcmpge() noreturn { |
| 34 | @setRuntimeSafety(false); | 34 | @setRuntimeSafety(false); |
| 35 | @inlineCall(aeabi_dcmp, .Ge); | 35 | @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Ge}); |
| 36 | unreachable; | 36 | unreachable; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | pub nakedcc fn __aeabi_dcmpgt() noreturn { | 39 | pub nakedcc fn __aeabi_dcmpgt() noreturn { |
| 40 | @setRuntimeSafety(false); | 40 | @setRuntimeSafety(false); |
| 41 | @inlineCall(aeabi_dcmp, .Gt); | 41 | @call(.{ .modifier = .always_inline }, aeabi_dcmp, .{.Gt}); |
| 42 | unreachable; | 42 | unreachable; |
| 43 | } | 43 | } |
| 44 | 44 |
lib/std/special/compiler_rt/arm/aeabi_fcmp.zig+5-5| ... | @@ -14,31 +14,31 @@ const ConditionalOperator = enum { | ... | @@ -14,31 +14,31 @@ const ConditionalOperator = enum { |
| 14 | 14 | ||
| 15 | pub nakedcc fn __aeabi_fcmpeq() noreturn { | 15 | pub nakedcc fn __aeabi_fcmpeq() noreturn { |
| 16 | @setRuntimeSafety(false); | 16 | @setRuntimeSafety(false); |
| 17 | @inlineCall(aeabi_fcmp, .Eq); | 17 | @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Eq}); |
| 18 | unreachable; | 18 | unreachable; |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | pub nakedcc fn __aeabi_fcmplt() noreturn { | 21 | pub nakedcc fn __aeabi_fcmplt() noreturn { |
| 22 | @setRuntimeSafety(false); | 22 | @setRuntimeSafety(false); |
| 23 | @inlineCall(aeabi_fcmp, .Lt); | 23 | @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Lt}); |
| 24 | unreachable; | 24 | unreachable; |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | pub nakedcc fn __aeabi_fcmple() noreturn { | 27 | pub nakedcc fn __aeabi_fcmple() noreturn { |
| 28 | @setRuntimeSafety(false); | 28 | @setRuntimeSafety(false); |
| 29 | @inlineCall(aeabi_fcmp, .Le); | 29 | @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Le}); |
| 30 | unreachable; | 30 | unreachable; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | pub nakedcc fn __aeabi_fcmpge() noreturn { | 33 | pub nakedcc fn __aeabi_fcmpge() noreturn { |
| 34 | @setRuntimeSafety(false); | 34 | @setRuntimeSafety(false); |
| 35 | @inlineCall(aeabi_fcmp, .Ge); | 35 | @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Ge}); |
| 36 | unreachable; | 36 | unreachable; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | pub nakedcc fn __aeabi_fcmpgt() noreturn { | 39 | pub nakedcc fn __aeabi_fcmpgt() noreturn { |
| 40 | @setRuntimeSafety(false); | 40 | @setRuntimeSafety(false); |
| 41 | @inlineCall(aeabi_fcmp, .Gt); | 41 | @call(.{ .modifier = .always_inline }, aeabi_fcmp, .{.Gt}); |
| 42 | unreachable; | 42 | unreachable; |
| 43 | } | 43 | } |
| 44 | 44 |
lib/std/special/compiler_rt/divti3.zig+4-1| ... | @@ -17,7 +17,10 @@ pub extern fn __divti3(a: i128, b: i128) i128 { | ... | @@ -17,7 +17,10 @@ pub extern fn __divti3(a: i128, b: i128) i128 { |
| 17 | 17 | ||
| 18 | const v128 = @Vector(2, u64); | 18 | const v128 = @Vector(2, u64); |
| 19 | pub extern fn __divti3_windows_x86_64(a: v128, b: v128) v128 { | 19 | pub extern fn __divti3_windows_x86_64(a: v128, b: v128) v128 { |
| 20 | return @bitCast(v128, @inlineCall(__divti3, @bitCast(i128, a), @bitCast(i128, b))); | 20 | return @bitCast(v128, @call(.{ .modifier = .always_inline }, __divti3, .{ |
| 21 | @bitCast(i128, a), | ||
| 22 | @bitCast(i128, b), | ||
| 23 | })); | ||
| 21 | } | 24 | } |
| 22 | 25 | ||
| 23 | test "import divti3" { | 26 | test "import divti3" { |
lib/std/special/compiler_rt/extendXfYf2.zig+4-4| ... | @@ -3,19 +3,19 @@ const builtin = @import("builtin"); | ... | @@ -3,19 +3,19 @@ const builtin = @import("builtin"); |
| 3 | const is_test = builtin.is_test; | 3 | const is_test = builtin.is_test; |
| 4 | 4 | ||
| 5 | pub extern fn __extendsfdf2(a: f32) f64 { | 5 | pub extern fn __extendsfdf2(a: f32) f64 { |
| 6 | return @inlineCall(extendXfYf2, f64, f32, @bitCast(u32, a)); | 6 | return @call(.{ .modifier = .always_inline }, extendXfYf2, .{ f64, f32, @bitCast(u32, a) }); |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | pub extern fn __extenddftf2(a: f64) f128 { | 9 | pub extern fn __extenddftf2(a: f64) f128 { |
| 10 | return @inlineCall(extendXfYf2, f128, f64, @bitCast(u64, a)); | 10 | return @call(.{ .modifier = .always_inline }, extendXfYf2, .{ f128, f64, @bitCast(u64, a) }); |
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | pub extern fn __extendsftf2(a: f32) f128 { | 13 | pub extern fn __extendsftf2(a: f32) f128 { |
| 14 | return @inlineCall(extendXfYf2, f128, f32, @bitCast(u32, a)); | 14 | return @call(.{ .modifier = .always_inline }, extendXfYf2, .{ f128, f32, @bitCast(u32, a) }); |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | pub extern fn __extendhfsf2(a: u16) f32 { | 17 | pub extern fn __extendhfsf2(a: u16) f32 { |
| 18 | return @inlineCall(extendXfYf2, f32, f16, a); | 18 | return @call(.{ .modifier = .always_inline }, extendXfYf2, .{ f32, f16, a }); |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | const CHAR_BIT = 8; | 21 | const CHAR_BIT = 8; |
lib/std/special/compiler_rt/floatsiXf.zig+3-3| ... | @@ -55,17 +55,17 @@ fn floatsiXf(comptime T: type, a: i32) T { | ... | @@ -55,17 +55,17 @@ fn floatsiXf(comptime T: type, a: i32) T { |
| 55 | 55 | ||
| 56 | pub extern fn __floatsisf(arg: i32) f32 { | 56 | pub extern fn __floatsisf(arg: i32) f32 { |
| 57 | @setRuntimeSafety(builtin.is_test); | 57 | @setRuntimeSafety(builtin.is_test); |
| 58 | return @inlineCall(floatsiXf, f32, arg); | 58 | return @call(.{ .modifier = .always_inline }, floatsiXf, .{ f32, arg }); |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | pub extern fn __floatsidf(arg: i32) f64 { | 61 | pub extern fn __floatsidf(arg: i32) f64 { |
| 62 | @setRuntimeSafety(builtin.is_test); | 62 | @setRuntimeSafety(builtin.is_test); |
| 63 | return @inlineCall(floatsiXf, f64, arg); | 63 | return @call(.{ .modifier = .always_inline }, floatsiXf, .{ f64, arg }); |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | pub extern fn __floatsitf(arg: i32) f128 { | 66 | pub extern fn __floatsitf(arg: i32) f128 { |
| 67 | @setRuntimeSafety(builtin.is_test); | 67 | @setRuntimeSafety(builtin.is_test); |
| 68 | return @inlineCall(floatsiXf, f128, arg); | 68 | return @call(.{ .modifier = .always_inline }, floatsiXf, .{ f128, arg }); |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | fn test_one_floatsitf(a: i32, expected: u128) void { | 71 | fn test_one_floatsitf(a: i32, expected: u128) void { |
lib/std/special/compiler_rt/modti3.zig+4-1| ... | @@ -22,7 +22,10 @@ pub extern fn __modti3(a: i128, b: i128) i128 { | ... | @@ -22,7 +22,10 @@ pub extern fn __modti3(a: i128, b: i128) i128 { |
| 22 | 22 | ||
| 23 | const v128 = @Vector(2, u64); | 23 | const v128 = @Vector(2, u64); |
| 24 | pub extern fn __modti3_windows_x86_64(a: v128, b: v128) v128 { | 24 | pub extern fn __modti3_windows_x86_64(a: v128, b: v128) v128 { |
| 25 | return @bitCast(v128, @inlineCall(__modti3, @bitCast(i128, a), @bitCast(i128, b))); | 25 | return @bitCast(v128, @call(.{ .modifier = .always_inline }, __modti3, .{ |
| 26 | @bitCast(i128, a), | ||
| 27 | @bitCast(i128, b), | ||
| 28 | })); | ||
| 26 | } | 29 | } |
| 27 | 30 | ||
| 28 | test "import modti3" { | 31 | test "import modti3" { |
lib/std/special/compiler_rt/multi3.zig+4-1| ... | @@ -16,7 +16,10 @@ pub extern fn __multi3(a: i128, b: i128) i128 { | ... | @@ -16,7 +16,10 @@ pub extern fn __multi3(a: i128, b: i128) i128 { |
| 16 | 16 | ||
| 17 | const v128 = @Vector(2, u64); | 17 | const v128 = @Vector(2, u64); |
| 18 | pub extern fn __multi3_windows_x86_64(a: v128, b: v128) v128 { | 18 | pub extern fn __multi3_windows_x86_64(a: v128, b: v128) v128 { |
| 19 | return @bitCast(v128, @inlineCall(__multi3, @bitCast(i128, a), @bitCast(i128, b))); | 19 | return @bitCast(v128, @call(.{ .modifier = .always_inline }, __multi3, .{ |
| 20 | @bitCast(i128, a), | ||
| 21 | @bitCast(i128, b), | ||
| 22 | })); | ||
| 20 | } | 23 | } |
| 21 | 24 | ||
| 22 | fn __mulddi3(a: u64, b: u64) i128 { | 25 | fn __mulddi3(a: u64, b: u64) i128 { |
lib/std/special/compiler_rt/stack_probe.zig+6-6| ... | @@ -182,25 +182,25 @@ fn win_probe_stack_adjust_sp() void { | ... | @@ -182,25 +182,25 @@ fn win_probe_stack_adjust_sp() void { |
| 182 | 182 | ||
| 183 | pub nakedcc fn _chkstk() void { | 183 | pub nakedcc fn _chkstk() void { |
| 184 | @setRuntimeSafety(false); | 184 | @setRuntimeSafety(false); |
| 185 | @inlineCall(win_probe_stack_adjust_sp); | 185 | @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}); |
| 186 | } | 186 | } |
| 187 | pub nakedcc fn __chkstk() void { | 187 | pub nakedcc fn __chkstk() void { |
| 188 | @setRuntimeSafety(false); | 188 | @setRuntimeSafety(false); |
| 189 | switch (builtin.arch) { | 189 | switch (builtin.arch) { |
| 190 | .i386 => @inlineCall(win_probe_stack_adjust_sp), | 190 | .i386 => @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}), |
| 191 | .x86_64 => @inlineCall(win_probe_stack_only), | 191 | .x86_64 => @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{}), |
| 192 | else => unreachable, | 192 | else => unreachable, |
| 193 | } | 193 | } |
| 194 | } | 194 | } |
| 195 | pub nakedcc fn ___chkstk() void { | 195 | pub nakedcc fn ___chkstk() void { |
| 196 | @setRuntimeSafety(false); | 196 | @setRuntimeSafety(false); |
| 197 | @inlineCall(win_probe_stack_adjust_sp); | 197 | @call(.{ .modifier = .always_inline }, win_probe_stack_adjust_sp, .{}); |
| 198 | } | 198 | } |
| 199 | pub nakedcc fn __chkstk_ms() void { | 199 | pub nakedcc fn __chkstk_ms() void { |
| 200 | @setRuntimeSafety(false); | 200 | @setRuntimeSafety(false); |
| 201 | @inlineCall(win_probe_stack_only); | 201 | @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{}); |
| 202 | } | 202 | } |
| 203 | pub nakedcc fn ___chkstk_ms() void { | 203 | pub nakedcc fn ___chkstk_ms() void { |
| 204 | @setRuntimeSafety(false); | 204 | @setRuntimeSafety(false); |
| 205 | @inlineCall(win_probe_stack_only); | 205 | @call(.{ .modifier = .always_inline }, win_probe_stack_only, .{}); |
| 206 | } | 206 | } |
lib/std/special/compiler_rt/umodti3.zig+4-1| ... | @@ -11,5 +11,8 @@ pub extern fn __umodti3(a: u128, b: u128) u128 { | ... | @@ -11,5 +11,8 @@ pub extern fn __umodti3(a: u128, b: u128) u128 { |
| 11 | 11 | ||
| 12 | const v128 = @Vector(2, u64); | 12 | const v128 = @Vector(2, u64); |
| 13 | pub extern fn __umodti3_windows_x86_64(a: v128, b: v128) v128 { | 13 | pub extern fn __umodti3_windows_x86_64(a: v128, b: v128) v128 { |
| 14 | return @bitCast(v128, @inlineCall(__umodti3, @bitCast(u128, a), @bitCast(u128, b))); | 14 | return @bitCast(v128, @call(.{ .modifier = .always_inline }, __umodti3, .{ |
| 15 | @bitCast(u128, a), | ||
| 16 | @bitCast(u128, b), | ||
| 17 | })); | ||
| 15 | } | 18 | } |
lib/std/special/start.zig+5-5| ... | @@ -59,7 +59,7 @@ stdcallcc fn _DllMainCRTStartup( | ... | @@ -59,7 +59,7 @@ stdcallcc fn _DllMainCRTStartup( |
| 59 | extern fn wasm_freestanding_start() void { | 59 | extern fn wasm_freestanding_start() void { |
| 60 | // This is marked inline because for some reason LLVM in release mode fails to inline it, | 60 | // This is marked inline because for some reason LLVM in release mode fails to inline it, |
| 61 | // and we want fewer call frames in stack traces. | 61 | // and we want fewer call frames in stack traces. |
| 62 | _ = @inlineCall(callMain); | 62 | _ = @call(.{ .modifier = .always_inline }, callMain, .{}); |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | extern fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) usize { | 65 | extern fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) usize { |
| ... | @@ -89,7 +89,7 @@ nakedcc fn _start() noreturn { | ... | @@ -89,7 +89,7 @@ nakedcc fn _start() noreturn { |
| 89 | if (builtin.os == builtin.Os.wasi) { | 89 | if (builtin.os == builtin.Os.wasi) { |
| 90 | // This is marked inline because for some reason LLVM in release mode fails to inline it, | 90 | // This is marked inline because for some reason LLVM in release mode fails to inline it, |
| 91 | // and we want fewer call frames in stack traces. | 91 | // and we want fewer call frames in stack traces. |
| 92 | std.os.wasi.proc_exit(@inlineCall(callMain)); | 92 | std.os.wasi.proc_exit(@call(.{ .modifier = .always_inline }, callMain, .{})); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | switch (builtin.arch) { | 95 | switch (builtin.arch) { |
| ... | @@ -187,7 +187,7 @@ fn posixCallMainAndExit() noreturn { | ... | @@ -187,7 +187,7 @@ fn posixCallMainAndExit() noreturn { |
| 187 | //std.os.exit(@newStackCall(new_stack, callMainWithArgs, argc, argv, envp)); | 187 | //std.os.exit(@newStackCall(new_stack, callMainWithArgs, argc, argv, envp)); |
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | std.os.exit(@inlineCall(callMainWithArgs, argc, argv, envp)); | 190 | std.os.exit(@call(.{ .modifier = .always_inline }, callMainWithArgs, .{ argc, argv, envp })); |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 { | 193 | fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 { |
| ... | @@ -203,7 +203,7 @@ extern fn main(c_argc: i32, c_argv: [*][*:0]u8, c_envp: [*:null]?[*:0]u8) i32 { | ... | @@ -203,7 +203,7 @@ extern fn main(c_argc: i32, c_argv: [*][*:0]u8, c_envp: [*:null]?[*:0]u8) i32 { |
| 203 | var env_count: usize = 0; | 203 | var env_count: usize = 0; |
| 204 | while (c_envp[env_count] != null) : (env_count += 1) {} | 204 | while (c_envp[env_count] != null) : (env_count += 1) {} |
| 205 | const envp = @ptrCast([*][*:0]u8, c_envp)[0..env_count]; | 205 | const envp = @ptrCast([*][*:0]u8, c_envp)[0..env_count]; |
| 206 | return @inlineCall(callMainWithArgs, @intCast(usize, c_argc), c_argv, envp); | 206 | return @call(.{ .modifier = .always_inline }, callMainWithArgs, .{ @intCast(usize, c_argc), c_argv, envp }); |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | // General error message for a malformed return type | 209 | // General error message for a malformed return type |
| ... | @@ -233,7 +233,7 @@ inline fn initEventLoopAndCallMain() u8 { | ... | @@ -233,7 +233,7 @@ inline fn initEventLoopAndCallMain() u8 { |
| 233 | 233 | ||
| 234 | // This is marked inline because for some reason LLVM in release mode fails to inline it, | 234 | // This is marked inline because for some reason LLVM in release mode fails to inline it, |
| 235 | // and we want fewer call frames in stack traces. | 235 | // and we want fewer call frames in stack traces. |
| 236 | return @inlineCall(callMain); | 236 | return @call(.{ .modifier = .always_inline }, callMain, .{}); |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | async fn callMainAsync(loop: *std.event.Loop) u8 { | 239 | async fn callMainAsync(loop: *std.event.Loop) u8 { |
src/all_types.hpp+16-3| ... | @@ -1700,7 +1700,6 @@ enum BuiltinFnId { | ... | @@ -1700,7 +1700,6 @@ enum BuiltinFnId { |
| 1700 | BuiltinFnIdFieldParentPtr, | 1700 | BuiltinFnIdFieldParentPtr, |
| 1701 | BuiltinFnIdByteOffsetOf, | 1701 | BuiltinFnIdByteOffsetOf, |
| 1702 | BuiltinFnIdBitOffsetOf, | 1702 | BuiltinFnIdBitOffsetOf, |
| 1703 | BuiltinFnIdInlineCall, | ||
| 1704 | BuiltinFnIdNewStackCall, | 1703 | BuiltinFnIdNewStackCall, |
| 1705 | BuiltinFnIdAsyncCall, | 1704 | BuiltinFnIdAsyncCall, |
| 1706 | BuiltinFnIdTypeId, | 1705 | BuiltinFnIdTypeId, |
| ... | @@ -2487,6 +2486,7 @@ enum IrInstructionId { | ... | @@ -2487,6 +2486,7 @@ enum IrInstructionId { |
| 2487 | IrInstructionIdVarPtr, | 2486 | IrInstructionIdVarPtr, |
| 2488 | IrInstructionIdReturnPtr, | 2487 | IrInstructionIdReturnPtr, |
| 2489 | IrInstructionIdCallSrc, | 2488 | IrInstructionIdCallSrc, |
| 2489 | IrInstructionIdCallSrcArgs, | ||
| 2490 | IrInstructionIdCallExtra, | 2490 | IrInstructionIdCallExtra, |
| 2491 | IrInstructionIdCallGen, | 2491 | IrInstructionIdCallGen, |
| 2492 | IrInstructionIdConst, | 2492 | IrInstructionIdConst, |
| ... | @@ -2904,8 +2904,21 @@ struct IrInstructionCallSrc { | ... | @@ -2904,8 +2904,21 @@ struct IrInstructionCallSrc { |
| 2904 | bool is_async_call_builtin; | 2904 | bool is_async_call_builtin; |
| 2905 | }; | 2905 | }; |
| 2906 | 2906 | ||
| 2907 | /// This is a pass1 instruction, used by @call. | 2907 | // This is a pass1 instruction, used by @call when the args node is |
| 2908 | /// `args` is expected to be either a struct or a tuple. | 2908 | // a tuple or struct literal. |
| 2909 | struct IrInstructionCallSrcArgs { | ||
| 2910 | IrInstruction base; | ||
| 2911 | |||
| 2912 | IrInstruction *options; | ||
| 2913 | IrInstruction *fn_ref; | ||
| 2914 | IrInstruction **args_ptr; | ||
| 2915 | size_t args_len; | ||
| 2916 | ResultLoc *result_loc; | ||
| 2917 | }; | ||
| 2918 | |||
| 2919 | // This is a pass1 instruction, used by @call, when the args node | ||
| 2920 | // is not a literal. | ||
| 2921 | // `args` is expected to be either a struct or a tuple. | ||
| 2909 | struct IrInstructionCallExtra { | 2922 | struct IrInstructionCallExtra { |
| 2910 | IrInstruction base; | 2923 | IrInstruction base; |
| 2911 | 2924 |
src/analyze.cpp+5-2| ... | @@ -594,8 +594,11 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con | ... | @@ -594,8 +594,11 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con |
| 594 | break; | 594 | break; |
| 595 | } | 595 | } |
| 596 | 596 | ||
| 597 | 597 | if (inferred_struct_field != nullptr) { | |
| 598 | if (type_is_resolved(child_type, ResolveStatusZeroBitsKnown)) { | 598 | entry->abi_size = g->builtin_types.entry_usize->abi_size; |
| 599 | entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits; | ||
| 600 | entry->abi_align = g->builtin_types.entry_usize->abi_align; | ||
| 601 | } else if (type_is_resolved(child_type, ResolveStatusZeroBitsKnown)) { | ||
| 599 | if (type_has_bits(child_type)) { | 602 | if (type_has_bits(child_type)) { |
| 600 | entry->abi_size = g->builtin_types.entry_usize->abi_size; | 603 | entry->abi_size = g->builtin_types.entry_usize->abi_size; |
| 601 | entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits; | 604 | entry->size_in_bits = g->builtin_types.entry_usize->size_in_bits; |
src/codegen.cpp+13-4| ... | @@ -3062,7 +3062,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, | ... | @@ -3062,7 +3062,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, |
| 3062 | ZigType *actual_type = cast_instruction->value->value->type; | 3062 | ZigType *actual_type = cast_instruction->value->value->type; |
| 3063 | ZigType *wanted_type = cast_instruction->base.value->type; | 3063 | ZigType *wanted_type = cast_instruction->base.value->type; |
| 3064 | LLVMValueRef expr_val = ir_llvm_value(g, cast_instruction->value); | 3064 | LLVMValueRef expr_val = ir_llvm_value(g, cast_instruction->value); |
| 3065 | assert(expr_val); | 3065 | ir_assert(expr_val, &cast_instruction->base); |
| 3066 | 3066 | ||
| 3067 | switch (cast_instruction->cast_op) { | 3067 | switch (cast_instruction->cast_op) { |
| 3068 | case CastOpNoCast: | 3068 | case CastOpNoCast: |
| ... | @@ -4330,8 +4330,17 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa | ... | @@ -4330,8 +4330,17 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa |
| 4330 | return struct_ptr; | 4330 | return struct_ptr; |
| 4331 | } | 4331 | } |
| 4332 | 4332 | ||
| 4333 | ZigType *struct_type = (struct_ptr_type->id == ZigTypeIdPointer) ? | 4333 | ZigType *struct_type; |
| 4334 | struct_ptr_type->data.pointer.child_type : struct_ptr_type; | 4334 | if (struct_ptr_type->id == ZigTypeIdPointer) { |
| 4335 | if (struct_ptr_type->data.pointer.inferred_struct_field != nullptr) { | ||
| 4336 | struct_type = struct_ptr_type->data.pointer.inferred_struct_field->inferred_struct_type; | ||
| 4337 | } else { | ||
| 4338 | struct_type = struct_ptr_type->data.pointer.child_type; | ||
| 4339 | } | ||
| 4340 | } else { | ||
| 4341 | struct_type = struct_ptr_type; | ||
| 4342 | } | ||
| 4343 | |||
| 4335 | if ((err = type_resolve(g, struct_type, ResolveStatusLLVMFull))) | 4344 | if ((err = type_resolve(g, struct_type, ResolveStatusLLVMFull))) |
| 4336 | codegen_report_errors_and_exit(g); | 4345 | codegen_report_errors_and_exit(g); |
| 4337 | 4346 | ||
| ... | @@ -6152,6 +6161,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -6152,6 +6161,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 6152 | case IrInstructionIdUndeclaredIdent: | 6161 | case IrInstructionIdUndeclaredIdent: |
| 6153 | case IrInstructionIdCallExtra: | 6162 | case IrInstructionIdCallExtra: |
| 6154 | case IrInstructionIdCallSrc: | 6163 | case IrInstructionIdCallSrc: |
| 6164 | case IrInstructionIdCallSrcArgs: | ||
| 6155 | case IrInstructionIdAllocaSrc: | 6165 | case IrInstructionIdAllocaSrc: |
| 6156 | case IrInstructionIdEndExpr: | 6166 | case IrInstructionIdEndExpr: |
| 6157 | case IrInstructionIdImplicitCast: | 6167 | case IrInstructionIdImplicitCast: |
| ... | @@ -8132,7 +8142,6 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -8132,7 +8142,6 @@ static void define_builtin_fns(CodeGen *g) { |
| 8132 | create_builtin_fn(g, BuiltinFnIdNearbyInt, "nearbyInt", 2); | 8142 | create_builtin_fn(g, BuiltinFnIdNearbyInt, "nearbyInt", 2); |
| 8133 | create_builtin_fn(g, BuiltinFnIdRound, "round", 2); | 8143 | create_builtin_fn(g, BuiltinFnIdRound, "round", 2); |
| 8134 | create_builtin_fn(g, BuiltinFnIdMulAdd, "mulAdd", 4); | 8144 | create_builtin_fn(g, BuiltinFnIdMulAdd, "mulAdd", 4); |
| 8135 | create_builtin_fn(g, BuiltinFnIdInlineCall, "inlineCall", SIZE_MAX); | ||
| 8136 | create_builtin_fn(g, BuiltinFnIdNewStackCall, "newStackCall", SIZE_MAX); | 8145 | create_builtin_fn(g, BuiltinFnIdNewStackCall, "newStackCall", SIZE_MAX); |
| 8137 | create_builtin_fn(g, BuiltinFnIdAsyncCall, "asyncCall", SIZE_MAX); | 8146 | create_builtin_fn(g, BuiltinFnIdAsyncCall, "asyncCall", SIZE_MAX); |
| 8138 | create_builtin_fn(g, BuiltinFnIdTypeId, "typeId", 1); | 8147 | create_builtin_fn(g, BuiltinFnIdTypeId, "typeId", 1); |
src/ir.cpp+210-124| ... | @@ -290,6 +290,8 @@ static void destroy_instruction(IrInstruction *inst) { | ... | @@ -290,6 +290,8 @@ static void destroy_instruction(IrInstruction *inst) { |
| 290 | return destroy(reinterpret_cast<IrInstructionCast *>(inst), name); | 290 | return destroy(reinterpret_cast<IrInstructionCast *>(inst), name); |
| 291 | case IrInstructionIdCallSrc: | 291 | case IrInstructionIdCallSrc: |
| 292 | return destroy(reinterpret_cast<IrInstructionCallSrc *>(inst), name); | 292 | return destroy(reinterpret_cast<IrInstructionCallSrc *>(inst), name); |
| 293 | case IrInstructionIdCallSrcArgs: | ||
| 294 | return destroy(reinterpret_cast<IrInstructionCallSrcArgs *>(inst), name); | ||
| 293 | case IrInstructionIdCallExtra: | 295 | case IrInstructionIdCallExtra: |
| 294 | return destroy(reinterpret_cast<IrInstructionCallExtra *>(inst), name); | 296 | return destroy(reinterpret_cast<IrInstructionCallExtra *>(inst), name); |
| 295 | case IrInstructionIdCallGen: | 297 | case IrInstructionIdCallGen: |
| ... | @@ -649,6 +651,15 @@ static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) { | ... | @@ -649,6 +651,15 @@ static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) { |
| 649 | assert(const_val->special == ConstValSpecialStatic); | 651 | assert(const_val->special == ConstValSpecialStatic); |
| 650 | ZigValue *result; | 652 | ZigValue *result; |
| 651 | 653 | ||
| 654 | InferredStructField *isf = const_val->type->data.pointer.inferred_struct_field; | ||
| 655 | if (isf != nullptr) { | ||
| 656 | TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name); | ||
| 657 | assert(field != nullptr); | ||
| 658 | assert(const_val->data.x_ptr.special == ConstPtrSpecialRef); | ||
| 659 | ZigValue *struct_val = const_val->data.x_ptr.data.ref.pointee; | ||
| 660 | return struct_val->data.x_struct.fields[field->src_index]; | ||
| 661 | } | ||
| 662 | |||
| 652 | switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) { | 663 | switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) { |
| 653 | case OnePossibleValueInvalid: | 664 | case OnePossibleValueInvalid: |
| 654 | zig_unreachable(); | 665 | zig_unreachable(); |
| ... | @@ -978,6 +989,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCallSrc *) { | ... | @@ -978,6 +989,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCallSrc *) { |
| 978 | return IrInstructionIdCallSrc; | 989 | return IrInstructionIdCallSrc; |
| 979 | } | 990 | } |
| 980 | 991 | ||
| 992 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCallSrcArgs *) { | ||
| 993 | return IrInstructionIdCallSrcArgs; | ||
| 994 | } | ||
| 995 | |||
| 981 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCallExtra *) { | 996 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCallExtra *) { |
| 982 | return IrInstructionIdCallExtra; | 997 | return IrInstructionIdCallExtra; |
| 983 | } | 998 | } |
| ... | @@ -1921,6 +1936,25 @@ static IrInstruction *ir_build_call_extra(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -1921,6 +1936,25 @@ static IrInstruction *ir_build_call_extra(IrBuilder *irb, Scope *scope, AstNode |
| 1921 | return &call_instruction->base; | 1936 | return &call_instruction->base; |
| 1922 | } | 1937 | } |
| 1923 | 1938 | ||
| 1939 | static IrInstruction *ir_build_call_src_args(IrBuilder *irb, Scope *scope, AstNode *source_node, | ||
| 1940 | IrInstruction *options, IrInstruction *fn_ref, IrInstruction **args_ptr, size_t args_len, | ||
| 1941 | ResultLoc *result_loc) | ||
| 1942 | { | ||
| 1943 | IrInstructionCallSrcArgs *call_instruction = ir_build_instruction<IrInstructionCallSrcArgs>(irb, scope, source_node); | ||
| 1944 | call_instruction->options = options; | ||
| 1945 | call_instruction->fn_ref = fn_ref; | ||
| 1946 | call_instruction->args_ptr = args_ptr; | ||
| 1947 | call_instruction->args_len = args_len; | ||
| 1948 | call_instruction->result_loc = result_loc; | ||
| 1949 | |||
| 1950 | ir_ref_instruction(options, irb->current_basic_block); | ||
| 1951 | ir_ref_instruction(fn_ref, irb->current_basic_block); | ||
| 1952 | for (size_t i = 0; i < args_len; i += 1) | ||
| 1953 | ir_ref_instruction(args_ptr[i], irb->current_basic_block); | ||
| 1954 | |||
| 1955 | return &call_instruction->base; | ||
| 1956 | } | ||
| 1957 | |||
| 1924 | static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *source_node, | 1958 | static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1925 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, | 1959 | ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, |
| 1926 | IrInstruction *ret_ptr, CallModifier modifier, bool is_async_call_builtin, | 1960 | IrInstruction *ret_ptr, CallModifier modifier, bool is_async_call_builtin, |
| ... | @@ -5095,6 +5129,43 @@ static IrInstruction *ir_gen_async_call(IrBuilder *irb, Scope *scope, AstNode *a | ... | @@ -5095,6 +5129,43 @@ static IrInstruction *ir_gen_async_call(IrBuilder *irb, Scope *scope, AstNode *a |
| 5095 | return ir_lval_wrap(irb, scope, call, lval, result_loc); | 5129 | return ir_lval_wrap(irb, scope, call, lval, result_loc); |
| 5096 | } | 5130 | } |
| 5097 | 5131 | ||
| 5132 | static IrInstruction *ir_gen_fn_call_with_args(IrBuilder *irb, Scope *scope, AstNode *source_node, | ||
| 5133 | AstNode *fn_ref_node, CallModifier modifier, IrInstruction *options, | ||
| 5134 | AstNode **args_ptr, size_t args_len, LVal lval, ResultLoc *result_loc) | ||
| 5135 | { | ||
| 5136 | IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); | ||
| 5137 | if (fn_ref == irb->codegen->invalid_instruction) | ||
| 5138 | return fn_ref; | ||
| 5139 | |||
| 5140 | IrInstruction *fn_type = ir_build_typeof(irb, scope, source_node, fn_ref); | ||
| 5141 | |||
| 5142 | IrInstruction **args = allocate<IrInstruction*>(args_len); | ||
| 5143 | for (size_t i = 0; i < args_len; i += 1) { | ||
| 5144 | AstNode *arg_node = args_ptr[i]; | ||
| 5145 | |||
| 5146 | IrInstruction *arg_index = ir_build_const_usize(irb, scope, arg_node, i); | ||
| 5147 | IrInstruction *arg_type = ir_build_arg_type(irb, scope, source_node, fn_type, arg_index, true); | ||
| 5148 | ResultLoc *no_result = no_result_loc(); | ||
| 5149 | ir_build_reset_result(irb, scope, source_node, no_result); | ||
| 5150 | ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result); | ||
| 5151 | |||
| 5152 | IrInstruction *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base); | ||
| 5153 | if (arg == irb->codegen->invalid_instruction) | ||
| 5154 | return arg; | ||
| 5155 | |||
| 5156 | args[i] = ir_build_implicit_cast(irb, scope, arg_node, arg, result_loc_cast); | ||
| 5157 | } | ||
| 5158 | |||
| 5159 | IrInstruction *fn_call; | ||
| 5160 | if (options != nullptr) { | ||
| 5161 | fn_call = ir_build_call_src_args(irb, scope, source_node, options, fn_ref, args, args_len, result_loc); | ||
| 5162 | } else { | ||
| 5163 | fn_call = ir_build_call_src(irb, scope, source_node, nullptr, fn_ref, args_len, args, nullptr, | ||
| 5164 | modifier, false, nullptr, result_loc); | ||
| 5165 | } | ||
| 5166 | return ir_lval_wrap(irb, scope, fn_call, lval, result_loc); | ||
| 5167 | } | ||
| 5168 | |||
| 5098 | static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, | 5169 | static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| 5099 | ResultLoc *result_loc) | 5170 | ResultLoc *result_loc) |
| 5100 | { | 5171 | { |
| ... | @@ -6013,32 +6084,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -6013,32 +6084,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 6013 | IrInstruction *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); | 6084 | IrInstruction *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); |
| 6014 | return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); | 6085 | return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); |
| 6015 | } | 6086 | } |
| 6016 | case BuiltinFnIdInlineCall: | ||
| 6017 | { | ||
| 6018 | if (node->data.fn_call_expr.params.length == 0) { | ||
| 6019 | add_node_error(irb->codegen, node, buf_sprintf("expected at least 1 argument, found 0")); | ||
| 6020 | return irb->codegen->invalid_instruction; | ||
| 6021 | } | ||
| 6022 | |||
| 6023 | AstNode *fn_ref_node = node->data.fn_call_expr.params.at(0); | ||
| 6024 | IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); | ||
| 6025 | if (fn_ref == irb->codegen->invalid_instruction) | ||
| 6026 | return fn_ref; | ||
| 6027 | |||
| 6028 | size_t arg_count = node->data.fn_call_expr.params.length - 1; | ||
| 6029 | |||
| 6030 | IrInstruction **args = allocate<IrInstruction*>(arg_count); | ||
| 6031 | for (size_t i = 0; i < arg_count; i += 1) { | ||
| 6032 | AstNode *arg_node = node->data.fn_call_expr.params.at(i + 1); | ||
| 6033 | args[i] = ir_gen_node(irb, arg_node, scope); | ||
| 6034 | if (args[i] == irb->codegen->invalid_instruction) | ||
| 6035 | return args[i]; | ||
| 6036 | } | ||
| 6037 | |||
| 6038 | IrInstruction *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, | ||
| 6039 | nullptr, CallModifierAlwaysInline, false, nullptr, result_loc); | ||
| 6040 | return ir_lval_wrap(irb, scope, call, lval, result_loc); | ||
| 6041 | } | ||
| 6042 | case BuiltinFnIdNewStackCall: | 6087 | case BuiltinFnIdNewStackCall: |
| 6043 | { | 6088 | { |
| 6044 | if (node->data.fn_call_expr.params.length < 2) { | 6089 | if (node->data.fn_call_expr.params.length < 2) { |
| ... | @@ -6086,17 +6131,33 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -6086,17 +6131,33 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 6086 | IrInstruction *options = ir_build_implicit_cast(irb, scope, options_node, options_inner, result_loc_cast); | 6131 | IrInstruction *options = ir_build_implicit_cast(irb, scope, options_node, options_inner, result_loc_cast); |
| 6087 | 6132 | ||
| 6088 | AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1); | 6133 | AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1); |
| 6089 | IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); | ||
| 6090 | if (fn_ref == irb->codegen->invalid_instruction) | ||
| 6091 | return fn_ref; | ||
| 6092 | |||
| 6093 | AstNode *args_node = node->data.fn_call_expr.params.at(2); | 6134 | AstNode *args_node = node->data.fn_call_expr.params.at(2); |
| 6094 | IrInstruction *args = ir_gen_node(irb, args_node, scope); | 6135 | if (args_node->type == NodeTypeContainerInitExpr) { |
| 6095 | if (args == irb->codegen->invalid_instruction) | 6136 | if (args_node->data.container_init_expr.kind == ContainerInitKindArray || |
| 6096 | return args; | 6137 | args_node->data.container_init_expr.entries.length == 0) |
| 6138 | { | ||
| 6139 | return ir_gen_fn_call_with_args(irb, scope, node, | ||
| 6140 | fn_ref_node, CallModifierNone, options, | ||
| 6141 | args_node->data.container_init_expr.entries.items, | ||
| 6142 | args_node->data.container_init_expr.entries.length, | ||
| 6143 | lval, result_loc); | ||
| 6144 | } else { | ||
| 6145 | exec_add_error_node(irb->codegen, irb->exec, args_node, | ||
| 6146 | buf_sprintf("TODO: @call with anon struct literal")); | ||
| 6147 | return irb->codegen->invalid_instruction; | ||
| 6148 | } | ||
| 6149 | } else { | ||
| 6150 | IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); | ||
| 6151 | if (fn_ref == irb->codegen->invalid_instruction) | ||
| 6152 | return fn_ref; | ||
| 6097 | 6153 | ||
| 6098 | IrInstruction *call = ir_build_call_extra(irb, scope, node, options, fn_ref, args, result_loc); | 6154 | IrInstruction *args = ir_gen_node(irb, args_node, scope); |
| 6099 | return ir_lval_wrap(irb, scope, call, lval, result_loc); | 6155 | if (args == irb->codegen->invalid_instruction) |
| 6156 | return args; | ||
| 6157 | |||
| 6158 | IrInstruction *call = ir_build_call_extra(irb, scope, node, options, fn_ref, args, result_loc); | ||
| 6159 | return ir_lval_wrap(irb, scope, call, lval, result_loc); | ||
| 6160 | } | ||
| 6100 | } | 6161 | } |
| 6101 | case BuiltinFnIdAsyncCall: | 6162 | case BuiltinFnIdAsyncCall: |
| 6102 | return ir_gen_async_call(irb, scope, nullptr, node, lval, result_loc); | 6163 | return ir_gen_async_call(irb, scope, nullptr, node, lval, result_loc); |
| ... | @@ -6415,33 +6476,8 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node | ... | @@ -6415,33 +6476,8 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node |
| 6415 | return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc); | 6476 | return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc); |
| 6416 | 6477 | ||
| 6417 | AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; | 6478 | AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; |
| 6418 | IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); | 6479 | return ir_gen_fn_call_with_args(irb, scope, node, fn_ref_node, node->data.fn_call_expr.modifier, |
| 6419 | if (fn_ref == irb->codegen->invalid_instruction) | 6480 | nullptr, node->data.fn_call_expr.params.items, node->data.fn_call_expr.params.length, lval, result_loc); |
| 6420 | return fn_ref; | ||
| 6421 | |||
| 6422 | IrInstruction *fn_type = ir_build_typeof(irb, scope, node, fn_ref); | ||
| 6423 | |||
| 6424 | size_t arg_count = node->data.fn_call_expr.params.length; | ||
| 6425 | IrInstruction **args = allocate<IrInstruction*>(arg_count); | ||
| 6426 | for (size_t i = 0; i < arg_count; i += 1) { | ||
| 6427 | AstNode *arg_node = node->data.fn_call_expr.params.at(i); | ||
| 6428 | |||
| 6429 | IrInstruction *arg_index = ir_build_const_usize(irb, scope, arg_node, i); | ||
| 6430 | IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, fn_type, arg_index, true); | ||
| 6431 | ResultLoc *no_result = no_result_loc(); | ||
| 6432 | ir_build_reset_result(irb, scope, node, no_result); | ||
| 6433 | ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result); | ||
| 6434 | |||
| 6435 | IrInstruction *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base); | ||
| 6436 | if (arg == irb->codegen->invalid_instruction) | ||
| 6437 | return arg; | ||
| 6438 | |||
| 6439 | args[i] = ir_build_implicit_cast(irb, scope, arg_node, arg, result_loc_cast); | ||
| 6440 | } | ||
| 6441 | |||
| 6442 | IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, nullptr, | ||
| 6443 | node->data.fn_call_expr.modifier, false, nullptr, result_loc); | ||
| 6444 | return ir_lval_wrap(irb, scope, fn_call, lval, result_loc); | ||
| 6445 | } | 6481 | } |
| 6446 | 6482 | ||
| 6447 | static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, | 6483 | static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, |
| ... | @@ -13955,6 +13991,20 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig | ... | @@ -13955,6 +13991,20 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Zig |
| 13955 | return ir_implicit_cast2(ira, value, value, expected_type); | 13991 | return ir_implicit_cast2(ira, value, value, expected_type); |
| 13956 | } | 13992 | } |
| 13957 | 13993 | ||
| 13994 | static ZigType *get_ptr_elem_type(CodeGen *g, IrInstruction *ptr) { | ||
| 13995 | ir_assert(ptr->value->type->id == ZigTypeIdPointer, ptr); | ||
| 13996 | ZigType *elem_type = ptr->value->type->data.pointer.child_type; | ||
| 13997 | if (elem_type != g->builtin_types.entry_var) | ||
| 13998 | return elem_type; | ||
| 13999 | |||
| 14000 | if (ir_resolve_lazy(g, ptr->source_node, ptr->value)) | ||
| 14001 | return g->builtin_types.entry_invalid; | ||
| 14002 | |||
| 14003 | assert(value_is_comptime(ptr->value)); | ||
| 14004 | ZigValue *pointee = const_ptr_pointee_unchecked(g, ptr->value); | ||
| 14005 | return pointee->type; | ||
| 14006 | } | ||
| 14007 | |||
| 13958 | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr, | 14008 | static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr, |
| 13959 | ResultLoc *result_loc) | 14009 | ResultLoc *result_loc) |
| 13960 | { | 14010 | { |
| ... | @@ -13971,6 +14021,8 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc | ... | @@ -13971,6 +14021,8 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc |
| 13971 | } | 14021 | } |
| 13972 | 14022 | ||
| 13973 | ZigType *child_type = ptr_type->data.pointer.child_type; | 14023 | ZigType *child_type = ptr_type->data.pointer.child_type; |
| 14024 | if (type_is_invalid(child_type)) | ||
| 14025 | return ira->codegen->invalid_instruction; | ||
| 13974 | // if the child type has one possible value, the deref is comptime | 14026 | // if the child type has one possible value, the deref is comptime |
| 13975 | switch (type_has_one_possible_value(ira->codegen, child_type)) { | 14027 | switch (type_has_one_possible_value(ira->codegen, child_type)) { |
| 13976 | case OnePossibleValueInvalid: | 14028 | case OnePossibleValueInvalid: |
| ... | @@ -17326,9 +17378,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source | ... | @@ -17326,9 +17378,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 17326 | copy_const_val(casted_ptr->value, ptr->value); | 17378 | copy_const_val(casted_ptr->value, ptr->value); |
| 17327 | casted_ptr->value->type = struct_ptr_type; | 17379 | casted_ptr->value->type = struct_ptr_type; |
| 17328 | } else { | 17380 | } else { |
| 17329 | casted_ptr = ir_build_cast(&ira->new_irb, source_instr->scope, | 17381 | casted_ptr = ptr; |
| 17330 | source_instr->source_node, struct_ptr_type, ptr, CastOpNoop); | ||
| 17331 | casted_ptr->value->type = struct_ptr_type; | ||
| 17332 | } | 17382 | } |
| 17333 | if (instr_is_comptime(casted_ptr)) { | 17383 | if (instr_is_comptime(casted_ptr)) { |
| 17334 | ZigValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad); | 17384 | ZigValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad); |
| ... | @@ -17409,6 +17459,12 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source | ... | @@ -17409,6 +17459,12 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 17409 | } | 17459 | } |
| 17410 | } | 17460 | } |
| 17411 | 17461 | ||
| 17462 | if (ptr->value->type->data.pointer.inferred_struct_field != nullptr && | ||
| 17463 | child_type == ira->codegen->builtin_types.entry_var) | ||
| 17464 | { | ||
| 17465 | child_type = ptr->value->type->data.pointer.inferred_struct_field->inferred_struct_type; | ||
| 17466 | } | ||
| 17467 | |||
| 17412 | switch (type_requires_comptime(ira->codegen, child_type)) { | 17468 | switch (type_requires_comptime(ira->codegen, child_type)) { |
| 17413 | case ReqCompTimeInvalid: | 17469 | case ReqCompTimeInvalid: |
| 17414 | return ira->codegen->invalid_instruction; | 17470 | return ira->codegen->invalid_instruction; |
| ... | @@ -18105,62 +18161,47 @@ static IrInstruction *ir_analyze_fn_call_src(IrAnalyze *ira, IrInstructionCallSr | ... | @@ -18105,62 +18161,47 @@ static IrInstruction *ir_analyze_fn_call_src(IrAnalyze *ira, IrInstructionCallSr |
| 18105 | return result; | 18161 | return result; |
| 18106 | } | 18162 | } |
| 18107 | 18163 | ||
| 18108 | static IrInstruction *ir_analyze_instruction_call_extra(IrAnalyze *ira, IrInstructionCallExtra *instruction) { | 18164 | static IrInstruction *ir_analyze_call_extra(IrAnalyze *ira, IrInstruction *source_instr, |
| 18109 | IrInstruction *options = instruction->options->child; | 18165 | IrInstruction *pass1_options, IrInstruction *pass1_fn_ref, IrInstruction **args_ptr, size_t args_len, |
| 18166 | ResultLoc *result_loc) | ||
| 18167 | { | ||
| 18168 | IrInstruction *options = pass1_options->child; | ||
| 18110 | if (type_is_invalid(options->value->type)) | 18169 | if (type_is_invalid(options->value->type)) |
| 18111 | return ira->codegen->invalid_instruction; | 18170 | return ira->codegen->invalid_instruction; |
| 18112 | 18171 | ||
| 18113 | IrInstruction *fn_ref = instruction->fn_ref->child; | 18172 | IrInstruction *fn_ref = pass1_fn_ref->child; |
| 18114 | if (type_is_invalid(fn_ref->value->type)) | 18173 | if (type_is_invalid(fn_ref->value->type)) |
| 18115 | return ira->codegen->invalid_instruction; | 18174 | return ira->codegen->invalid_instruction; |
| 18116 | ZigFn *fn = ir_resolve_fn(ira, fn_ref); | 18175 | IrInstruction *first_arg_ptr = nullptr; |
| 18117 | ZigType *fn_type = (fn != nullptr) ? fn->type_entry : fn_ref->value->type; | 18176 | ZigFn *fn = nullptr; |
| 18118 | 18177 | if (fn_ref->value->type->id == ZigTypeIdBoundFn) { | |
| 18119 | IrInstruction *args = instruction->args->child; | 18178 | assert(fn_ref->value->special == ConstValSpecialStatic); |
| 18120 | ZigType *args_type = args->value->type; | 18179 | fn = fn_ref->value->data.x_bound_fn.fn; |
| 18121 | if (type_is_invalid(args_type)) | 18180 | first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg; |
| 18122 | return ira->codegen->invalid_instruction; | 18181 | if (type_is_invalid(first_arg_ptr->value->type)) |
| 18123 | 18182 | return ira->codegen->invalid_instruction; | |
| 18124 | if (args_type->id != ZigTypeIdStruct) { | ||
| 18125 | ir_add_error(ira, args, | ||
| 18126 | buf_sprintf("expected tuple or struct, found '%s'", buf_ptr(&args_type->name))); | ||
| 18127 | return ira->codegen->invalid_instruction; | ||
| 18128 | } | ||
| 18129 | |||
| 18130 | IrInstruction **args_ptr = nullptr; | ||
| 18131 | size_t args_len = 0; | ||
| 18132 | |||
| 18133 | if (is_tuple(args_type)) { | ||
| 18134 | args_len = args_type->data.structure.src_field_count; | ||
| 18135 | args_ptr = allocate<IrInstruction *>(args_len, "IrInstruction *"); | ||
| 18136 | for (size_t i = 0; i < args_len; i += 1) { | ||
| 18137 | TypeStructField *arg_field = args_type->data.structure.fields[i]; | ||
| 18138 | args_ptr[i] = ir_analyze_struct_value_field_value(ira, &instruction->base, args, arg_field); | ||
| 18139 | if (type_is_invalid(args_ptr[i]->value->type)) | ||
| 18140 | return ira->codegen->invalid_instruction; | ||
| 18141 | } | ||
| 18142 | } else { | 18183 | } else { |
| 18143 | ir_add_error(ira, args, buf_sprintf("TODO: struct args")); | 18184 | fn = ir_resolve_fn(ira, fn_ref); |
| 18144 | return ira->codegen->invalid_instruction; | ||
| 18145 | } | 18185 | } |
| 18186 | ZigType *fn_type = (fn != nullptr) ? fn->type_entry : fn_ref->value->type; | ||
| 18146 | 18187 | ||
| 18147 | TypeStructField *modifier_field = find_struct_type_field(options->value->type, buf_create_from_str("modifier")); | 18188 | TypeStructField *modifier_field = find_struct_type_field(options->value->type, buf_create_from_str("modifier")); |
| 18148 | ir_assert(modifier_field != nullptr, &instruction->base); | 18189 | ir_assert(modifier_field != nullptr, source_instr); |
| 18149 | IrInstruction *modifier_inst = ir_analyze_struct_value_field_value(ira, &instruction->base, options, modifier_field); | 18190 | IrInstruction *modifier_inst = ir_analyze_struct_value_field_value(ira, source_instr, options, modifier_field); |
| 18150 | ZigValue *modifier_val = ir_resolve_const(ira, modifier_inst, UndefBad); | 18191 | ZigValue *modifier_val = ir_resolve_const(ira, modifier_inst, UndefBad); |
| 18151 | if (modifier_val == nullptr) | 18192 | if (modifier_val == nullptr) |
| 18152 | return ira->codegen->invalid_instruction; | 18193 | return ira->codegen->invalid_instruction; |
| 18153 | CallModifier modifier = (CallModifier)bigint_as_u32(&modifier_val->data.x_enum_tag); | 18194 | CallModifier modifier = (CallModifier)bigint_as_u32(&modifier_val->data.x_enum_tag); |
| 18154 | if (modifier == CallModifierAsync) { | 18195 | if (modifier == CallModifierAsync) { |
| 18155 | ir_add_error(ira, args, buf_sprintf("TODO: @call with async modifier")); | 18196 | ir_add_error(ira, source_instr, buf_sprintf("TODO: @call with async modifier")); |
| 18156 | return ira->codegen->invalid_instruction; | 18197 | return ira->codegen->invalid_instruction; |
| 18157 | } | 18198 | } |
| 18158 | if (ir_should_inline(ira->new_irb.exec, instruction->base.scope)) { | 18199 | if (ir_should_inline(ira->new_irb.exec, source_instr->scope)) { |
| 18159 | switch (modifier) { | 18200 | switch (modifier) { |
| 18160 | case CallModifierBuiltin: | 18201 | case CallModifierBuiltin: |
| 18161 | zig_unreachable(); | 18202 | zig_unreachable(); |
| 18162 | case CallModifierAsync: | 18203 | case CallModifierAsync: |
| 18163 | ir_add_error(ira, args, buf_sprintf("TODO: comptime @call with async modifier")); | 18204 | ir_add_error(ira, source_instr, buf_sprintf("TODO: comptime @call with async modifier")); |
| 18164 | return ira->codegen->invalid_instruction; | 18205 | return ira->codegen->invalid_instruction; |
| 18165 | case CallModifierCompileTime: | 18206 | case CallModifierCompileTime: |
| 18166 | case CallModifierNone: | 18207 | case CallModifierNone: |
| ... | @@ -18170,32 +18211,78 @@ static IrInstruction *ir_analyze_instruction_call_extra(IrAnalyze *ira, IrInstru | ... | @@ -18170,32 +18211,78 @@ static IrInstruction *ir_analyze_instruction_call_extra(IrAnalyze *ira, IrInstru |
| 18170 | modifier = CallModifierCompileTime; | 18211 | modifier = CallModifierCompileTime; |
| 18171 | break; | 18212 | break; |
| 18172 | case CallModifierNeverInline: | 18213 | case CallModifierNeverInline: |
| 18173 | ir_add_error(ira, args, | 18214 | ir_add_error(ira, source_instr, |
| 18174 | buf_sprintf("unable to perform 'never_inline' call at compile-time")); | 18215 | buf_sprintf("unable to perform 'never_inline' call at compile-time")); |
| 18175 | return ira->codegen->invalid_instruction; | 18216 | return ira->codegen->invalid_instruction; |
| 18176 | case CallModifierNeverTail: | 18217 | case CallModifierNeverTail: |
| 18177 | ir_add_error(ira, args, | 18218 | ir_add_error(ira, source_instr, |
| 18178 | buf_sprintf("unable to perform 'never_tail' call at compile-time")); | 18219 | buf_sprintf("unable to perform 'never_tail' call at compile-time")); |
| 18179 | return ira->codegen->invalid_instruction; | 18220 | return ira->codegen->invalid_instruction; |
| 18180 | } | 18221 | } |
| 18181 | } | 18222 | } |
| 18182 | 18223 | ||
| 18183 | TypeStructField *stack_field = find_struct_type_field(options->value->type, buf_create_from_str("stack")); | 18224 | TypeStructField *stack_field = find_struct_type_field(options->value->type, buf_create_from_str("stack")); |
| 18184 | ir_assert(stack_field != nullptr, &instruction->base); | 18225 | ir_assert(stack_field != nullptr, source_instr); |
| 18185 | IrInstruction *stack = ir_analyze_struct_value_field_value(ira, &instruction->base, options, stack_field); | 18226 | IrInstruction *stack = ir_analyze_struct_value_field_value(ira, source_instr, options, stack_field); |
| 18186 | IrInstruction *stack_is_non_null_inst = ir_analyze_test_non_null(ira, &instruction->base, stack); | 18227 | IrInstruction *stack_is_non_null_inst = ir_analyze_test_non_null(ira, source_instr, stack); |
| 18187 | bool stack_is_non_null; | 18228 | bool stack_is_non_null; |
| 18188 | if (!ir_resolve_bool(ira, stack_is_non_null_inst, &stack_is_non_null)) | 18229 | if (!ir_resolve_bool(ira, stack_is_non_null_inst, &stack_is_non_null)) |
| 18189 | return ira->codegen->invalid_instruction; | 18230 | return ira->codegen->invalid_instruction; |
| 18190 | if (!stack_is_non_null) | 18231 | if (!stack_is_non_null) |
| 18191 | stack = nullptr; | 18232 | stack = nullptr; |
| 18192 | 18233 | ||
| 18193 | IrInstruction *result = ir_analyze_fn_call(ira, &instruction->base, fn, fn_type, fn_ref, nullptr, | 18234 | return ir_analyze_fn_call(ira, source_instr, fn, fn_type, fn_ref, first_arg_ptr, |
| 18194 | modifier, stack, false, args_ptr, args_len, nullptr, instruction->result_loc); | 18235 | modifier, stack, false, args_ptr, args_len, nullptr, result_loc); |
| 18236 | } | ||
| 18237 | |||
| 18238 | static IrInstruction *ir_analyze_instruction_call_extra(IrAnalyze *ira, IrInstructionCallExtra *instruction) { | ||
| 18239 | IrInstruction *args = instruction->args->child; | ||
| 18240 | ZigType *args_type = args->value->type; | ||
| 18241 | if (type_is_invalid(args_type)) | ||
| 18242 | return ira->codegen->invalid_instruction; | ||
| 18243 | |||
| 18244 | if (args_type->id != ZigTypeIdStruct) { | ||
| 18245 | ir_add_error(ira, args, | ||
| 18246 | buf_sprintf("expected tuple or struct, found '%s'", buf_ptr(&args_type->name))); | ||
| 18247 | return ira->codegen->invalid_instruction; | ||
| 18248 | } | ||
| 18249 | |||
| 18250 | IrInstruction **args_ptr = nullptr; | ||
| 18251 | size_t args_len = 0; | ||
| 18252 | |||
| 18253 | if (is_tuple(args_type)) { | ||
| 18254 | args_len = args_type->data.structure.src_field_count; | ||
| 18255 | args_ptr = allocate<IrInstruction *>(args_len, "IrInstruction *"); | ||
| 18256 | for (size_t i = 0; i < args_len; i += 1) { | ||
| 18257 | TypeStructField *arg_field = args_type->data.structure.fields[i]; | ||
| 18258 | args_ptr[i] = ir_analyze_struct_value_field_value(ira, &instruction->base, args, arg_field); | ||
| 18259 | if (type_is_invalid(args_ptr[i]->value->type)) | ||
| 18260 | return ira->codegen->invalid_instruction; | ||
| 18261 | } | ||
| 18262 | } else { | ||
| 18263 | ir_add_error(ira, args, buf_sprintf("TODO: struct args")); | ||
| 18264 | return ira->codegen->invalid_instruction; | ||
| 18265 | } | ||
| 18266 | IrInstruction *result = ir_analyze_call_extra(ira, &instruction->base, instruction->options, | ||
| 18267 | instruction->fn_ref, args_ptr, args_len, instruction->result_loc); | ||
| 18195 | deallocate(args_ptr, args_len, "IrInstruction *"); | 18268 | deallocate(args_ptr, args_len, "IrInstruction *"); |
| 18196 | return result; | 18269 | return result; |
| 18197 | } | 18270 | } |
| 18198 | 18271 | ||
| 18272 | static IrInstruction *ir_analyze_instruction_call_args(IrAnalyze *ira, IrInstructionCallSrcArgs *instruction) { | ||
| 18273 | IrInstruction **args_ptr = allocate<IrInstruction *>(instruction->args_len, "IrInstruction *"); | ||
| 18274 | for (size_t i = 0; i < instruction->args_len; i += 1) { | ||
| 18275 | args_ptr[i] = instruction->args_ptr[i]->child; | ||
| 18276 | if (type_is_invalid(args_ptr[i]->value->type)) | ||
| 18277 | return ira->codegen->invalid_instruction; | ||
| 18278 | } | ||
| 18279 | |||
| 18280 | IrInstruction *result = ir_analyze_call_extra(ira, &instruction->base, instruction->options, | ||
| 18281 | instruction->fn_ref, args_ptr, instruction->args_len, instruction->result_loc); | ||
| 18282 | deallocate(args_ptr, instruction->args_len, "IrInstruction *"); | ||
| 18283 | return result; | ||
| 18284 | } | ||
| 18285 | |||
| 18199 | static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction) { | 18286 | static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction) { |
| 18200 | IrInstruction *fn_ref = call_instruction->fn_ref->child; | 18287 | IrInstruction *fn_ref = call_instruction->fn_ref->child; |
| 18201 | if (type_is_invalid(fn_ref->value->type)) | 18288 | if (type_is_invalid(fn_ref->value->type)) |
| ... | @@ -19513,8 +19600,18 @@ static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_n | ... | @@ -19513,8 +19600,18 @@ static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_n |
| 19513 | PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field, nullptr); | 19600 | PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field, nullptr); |
| 19514 | 19601 | ||
| 19515 | if (instr_is_comptime(container_ptr)) { | 19602 | if (instr_is_comptime(container_ptr)) { |
| 19516 | IrInstruction *result = ir_const(ira, source_instr, field_ptr_type); | 19603 | ZigValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); |
| 19517 | copy_const_val(result->value, container_ptr->value); | 19604 | if (ptr_val == nullptr) |
| 19605 | return ira->codegen->invalid_instruction; | ||
| 19606 | |||
| 19607 | IrInstruction *result; | ||
| 19608 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { | ||
| 19609 | result = ir_build_cast(&ira->new_irb, source_instr->scope, | ||
| 19610 | source_instr->source_node, container_ptr_type, container_ptr, CastOpNoop); | ||
| 19611 | } else { | ||
| 19612 | result = ir_const(ira, source_instr, field_ptr_type); | ||
| 19613 | } | ||
| 19614 | copy_const_val(result->value, ptr_val); | ||
| 19518 | result->value->type = field_ptr_type; | 19615 | result->value->type = field_ptr_type; |
| 19519 | return result; | 19616 | return result; |
| 19520 | } | 19617 | } |
| ... | @@ -20531,20 +20628,6 @@ static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrIns | ... | @@ -20531,20 +20628,6 @@ static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrIns |
| 20531 | return ir_analyze_test_non_null(ira, &instruction->base, value); | 20628 | return ir_analyze_test_non_null(ira, &instruction->base, value); |
| 20532 | } | 20629 | } |
| 20533 | 20630 | ||
| 20534 | static ZigType *get_ptr_elem_type(CodeGen *g, IrInstruction *ptr) { | ||
| 20535 | ir_assert(ptr->value->type->id == ZigTypeIdPointer, ptr); | ||
| 20536 | ZigType *elem_type = ptr->value->type->data.pointer.child_type; | ||
| 20537 | if (elem_type != g->builtin_types.entry_var) | ||
| 20538 | return elem_type; | ||
| 20539 | |||
| 20540 | if (ir_resolve_lazy(g, ptr->source_node, ptr->value)) | ||
| 20541 | return g->builtin_types.entry_invalid; | ||
| 20542 | |||
| 20543 | assert(value_is_comptime(ptr->value)); | ||
| 20544 | ZigValue *pointee = const_ptr_pointee_unchecked(g, ptr->value); | ||
| 20545 | return pointee->type; | ||
| 20546 | } | ||
| 20547 | |||
| 20548 | static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, | 20631 | static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 20549 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) | 20632 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| 20550 | { | 20633 | { |
| ... | @@ -27932,6 +28015,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction | ... | @@ -27932,6 +28015,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction |
| 27932 | return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); | 28015 | return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); |
| 27933 | case IrInstructionIdCallSrc: | 28016 | case IrInstructionIdCallSrc: |
| 27934 | return ir_analyze_instruction_call(ira, (IrInstructionCallSrc *)instruction); | 28017 | return ir_analyze_instruction_call(ira, (IrInstructionCallSrc *)instruction); |
| 28018 | case IrInstructionIdCallSrcArgs: | ||
| 28019 | return ir_analyze_instruction_call_args(ira, (IrInstructionCallSrcArgs *)instruction); | ||
| 27935 | case IrInstructionIdCallExtra: | 28020 | case IrInstructionIdCallExtra: |
| 27936 | return ir_analyze_instruction_call_extra(ira, (IrInstructionCallExtra *)instruction); | 28021 | return ir_analyze_instruction_call_extra(ira, (IrInstructionCallExtra *)instruction); |
| 27937 | case IrInstructionIdBr: | 28022 | case IrInstructionIdBr: |
| ... | @@ -28333,6 +28418,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -28333,6 +28418,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 28333 | case IrInstructionIdVectorStoreElem: | 28418 | case IrInstructionIdVectorStoreElem: |
| 28334 | case IrInstructionIdCallExtra: | 28419 | case IrInstructionIdCallExtra: |
| 28335 | case IrInstructionIdCallSrc: | 28420 | case IrInstructionIdCallSrc: |
| 28421 | case IrInstructionIdCallSrcArgs: | ||
| 28336 | case IrInstructionIdCallGen: | 28422 | case IrInstructionIdCallGen: |
| 28337 | case IrInstructionIdReturn: | 28423 | case IrInstructionIdReturn: |
| 28338 | case IrInstructionIdUnreachable: | 28424 | case IrInstructionIdUnreachable: |
src/ir_print.cpp+21| ... | @@ -96,6 +96,8 @@ const char* ir_instruction_type_str(IrInstructionId id) { | ... | @@ -96,6 +96,8 @@ const char* ir_instruction_type_str(IrInstructionId id) { |
| 96 | return "CallExtra"; | 96 | return "CallExtra"; |
| 97 | case IrInstructionIdCallSrc: | 97 | case IrInstructionIdCallSrc: |
| 98 | return "CallSrc"; | 98 | return "CallSrc"; |
| 99 | case IrInstructionIdCallSrcArgs: | ||
| 100 | return "CallSrcArgs"; | ||
| 99 | case IrInstructionIdCallGen: | 101 | case IrInstructionIdCallGen: |
| 100 | return "CallGen"; | 102 | return "CallGen"; |
| 101 | case IrInstructionIdConst: | 103 | case IrInstructionIdConst: |
| ... | @@ -649,6 +651,22 @@ static void ir_print_call_extra(IrPrint *irp, IrInstructionCallExtra *instructio | ... | @@ -649,6 +651,22 @@ static void ir_print_call_extra(IrPrint *irp, IrInstructionCallExtra *instructio |
| 649 | ir_print_result_loc(irp, instruction->result_loc); | 651 | ir_print_result_loc(irp, instruction->result_loc); |
| 650 | } | 652 | } |
| 651 | 653 | ||
| 654 | static void ir_print_call_src_args(IrPrint *irp, IrInstructionCallSrcArgs *instruction) { | ||
| 655 | fprintf(irp->f, "opts="); | ||
| 656 | ir_print_other_instruction(irp, instruction->options); | ||
| 657 | fprintf(irp->f, ", fn="); | ||
| 658 | ir_print_other_instruction(irp, instruction->fn_ref); | ||
| 659 | fprintf(irp->f, ", args=("); | ||
| 660 | for (size_t i = 0; i < instruction->args_len; i += 1) { | ||
| 661 | IrInstruction *arg = instruction->args_ptr[i]; | ||
| 662 | if (i != 0) | ||
| 663 | fprintf(irp->f, ", "); | ||
| 664 | ir_print_other_instruction(irp, arg); | ||
| 665 | } | ||
| 666 | fprintf(irp->f, "), result="); | ||
| 667 | ir_print_result_loc(irp, instruction->result_loc); | ||
| 668 | } | ||
| 669 | |||
| 652 | static void ir_print_call_src(IrPrint *irp, IrInstructionCallSrc *call_instruction) { | 670 | static void ir_print_call_src(IrPrint *irp, IrInstructionCallSrc *call_instruction) { |
| 653 | switch (call_instruction->modifier) { | 671 | switch (call_instruction->modifier) { |
| 654 | case CallModifierNone: | 672 | case CallModifierNone: |
| ... | @@ -2131,6 +2149,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool | ... | @@ -2131,6 +2149,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool |
| 2131 | case IrInstructionIdCallSrc: | 2149 | case IrInstructionIdCallSrc: |
| 2132 | ir_print_call_src(irp, (IrInstructionCallSrc *)instruction); | 2150 | ir_print_call_src(irp, (IrInstructionCallSrc *)instruction); |
| 2133 | break; | 2151 | break; |
| 2152 | case IrInstructionIdCallSrcArgs: | ||
| 2153 | ir_print_call_src_args(irp, (IrInstructionCallSrcArgs *)instruction); | ||
| 2154 | break; | ||
| 2134 | case IrInstructionIdCallGen: | 2155 | case IrInstructionIdCallGen: |
| 2135 | ir_print_call_gen(irp, (IrInstructionCallGen *)instruction); | 2156 | ir_print_call_gen(irp, (IrInstructionCallGen *)instruction); |
| 2136 | break; | 2157 | break; |
test/stage1/behavior/call.zig+13-2| ... | @@ -28,10 +28,21 @@ test "tuple parameters" { | ... | @@ -28,10 +28,21 @@ test "tuple parameters" { |
| 28 | return a + b; | 28 | return a + b; |
| 29 | } | 29 | } |
| 30 | }.add; | 30 | }.add; |
| 31 | var a: i32 = 12; | ||
| 32 | var b: i32 = 34; | ||
| 33 | expect(@call(.{}, add, .{ a, 34 }) == 46); | ||
| 34 | expect(@call(.{}, add, .{ 12, b }) == 46); | ||
| 35 | expect(@call(.{}, add, .{ a, b }) == 46); | ||
| 31 | expect(@call(.{}, add, .{ 12, 34 }) == 46); | 36 | expect(@call(.{}, add, .{ 12, 34 }) == 46); |
| 32 | comptime expect(@call(.{}, add, .{ 12, 34 }) == 46); | 37 | comptime expect(@call(.{}, add, .{ 12, 34 }) == 46); |
| 33 | { | 38 | { |
| 34 | const separate_args = .{ 12, 34 }; | 39 | const separate_args0 = .{ a, b }; |
| 35 | expect(@call(.{ .modifier = .always_inline }, add, separate_args) == 46); | 40 | //TODO const separate_args1 = .{ a, 34 }; |
| 41 | const separate_args2 = .{ 12, 34 }; | ||
| 42 | //TODO const separate_args3 = .{ 12, b }; | ||
| 43 | expect(@call(.{ .modifier = .always_inline }, add, separate_args0) == 46); | ||
| 44 | // TODO expect(@call(.{ .modifier = .always_inline }, add, separate_args1) == 46); | ||
| 45 | expect(@call(.{ .modifier = .always_inline }, add, separate_args2) == 46); | ||
| 46 | // TODO expect(@call(.{ .modifier = .always_inline }, add, separate_args3) == 46); | ||
| 36 | } | 47 | } |
| 37 | } | 48 | } |
test/stage1/behavior/fn.zig+1-9| ... | @@ -96,14 +96,6 @@ fn fn4() u32 { | ... | @@ -96,14 +96,6 @@ fn fn4() u32 { |
| 96 | return 8; | 96 | return 8; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | test "inline function call" { | ||
| 100 | expect(@inlineCall(add, 3, 9) == 12); | ||
| 101 | } | ||
| 102 | |||
| 103 | fn add(a: i32, b: i32) i32 { | ||
| 104 | return a + b; | ||
| 105 | } | ||
| 106 | |||
| 107 | test "number literal as an argument" { | 99 | test "number literal as an argument" { |
| 108 | numberLiteralArg(3); | 100 | numberLiteralArg(3); |
| 109 | comptime numberLiteralArg(3); | 101 | comptime numberLiteralArg(3); |
| ... | @@ -251,7 +243,7 @@ test "discard the result of a function that returns a struct" { | ... | @@ -251,7 +243,7 @@ test "discard the result of a function that returns a struct" { |
| 251 | test "function call with anon list literal" { | 243 | test "function call with anon list literal" { |
| 252 | const S = struct { | 244 | const S = struct { |
| 253 | fn doTheTest() void { | 245 | fn doTheTest() void { |
| 254 | consumeVec(.{9, 8, 7}); | 246 | consumeVec(.{ 9, 8, 7 }); |
| 255 | } | 247 | } |
| 256 | 248 | ||
| 257 | fn consumeVec(vec: [3]f32) void { | 249 | fn consumeVec(vec: [3]f32) void { |