authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-02-22 20:10:16-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-02-22 20:10:16-05:00
log6769806213ab28ed629221085325d8f143e515b0
treee621eb6aa4ab49bb72018d33c373b258f55922df
parentb6a1fdd3fa167878f75b4f12ac170d1a10e4e9a2
parenteb3c7f570601a6e00cbf03f0a026b3493887a534
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #21727 from 87flowers/fmt-render2

std/zig/render: Rewrite indentation

44 files changed, 1725 insertions(+), 1499 deletions(-)

lib/compiler/aro/aro/Parser.zig+1-1
...@@ -979,7 +979,7 @@ fn decl(p: *Parser) Error!bool {...@@ -979,7 +979,7 @@ fn decl(p: *Parser) Error!bool {
979 _ = try p.expectToken(.semicolon);979 _ = try p.expectToken(.semicolon);
980 if (decl_spec.ty.is(.@"enum") or980 if (decl_spec.ty.is(.@"enum") or
981 (decl_spec.ty.isRecord() and !decl_spec.ty.isAnonymousRecord(p.comp) and981 (decl_spec.ty.isRecord() and !decl_spec.ty.isAnonymousRecord(p.comp) and
982 !decl_spec.ty.isTypeof())) // we follow GCC and clang's behavior here982 !decl_spec.ty.isTypeof())) // we follow GCC and clang's behavior here
983 {983 {
984 const specifier = decl_spec.ty.canonicalize(.standard).specifier;984 const specifier = decl_spec.ty.canonicalize(.standard).specifier;
985 const attrs = p.attr_buf.items(.attr)[attr_buf_top..];985 const attrs = p.attr_buf.items(.attr)[attr_buf_top..];
lib/compiler/aro/aro/pragmas/gcc.zig+3-3
...@@ -114,9 +114,9 @@ fn preprocessorHandler(pragma: *Pragma, pp: *Preprocessor, start_idx: TokenIndex...@@ -114,9 +114,9 @@ fn preprocessorHandler(pragma: *Pragma, pp: *Preprocessor, start_idx: TokenIndex
114114
115 const gcc_pragma = std.meta.stringToEnum(Directive, pp.expandedSlice(directive_tok)) orelse115 const gcc_pragma = std.meta.stringToEnum(Directive, pp.expandedSlice(directive_tok)) orelse
116 return pp.comp.addDiagnostic(.{116 return pp.comp.addDiagnostic(.{
117 .tag = .unknown_gcc_pragma,117 .tag = .unknown_gcc_pragma,
118 .loc = directive_tok.loc,118 .loc = directive_tok.loc,
119 }, pp.expansionSlice(start_idx + 1));119 }, pp.expansionSlice(start_idx + 1));
120120
121 switch (gcc_pragma) {121 switch (gcc_pragma) {
122 .warning, .@"error" => {122 .warning, .@"error" => {
lib/compiler/resinator/lang.zig+1-1
...@@ -255,7 +255,7 @@ pub fn parse(lang_tag: []const u8) error{InvalidLanguageTag}!Parsed {...@@ -255,7 +255,7 @@ pub fn parse(lang_tag: []const u8) error{InvalidLanguageTag}!Parsed {
255 // Special case for qps-ploca and qps-plocm255 // Special case for qps-ploca and qps-plocm
256 else if (std.ascii.eqlIgnoreCase(lang_code, "qps") and256 else if (std.ascii.eqlIgnoreCase(lang_code, "qps") and
257 (std.ascii.eqlIgnoreCase(part_str, "ploca") or257 (std.ascii.eqlIgnoreCase(part_str, "ploca") or
258 std.ascii.eqlIgnoreCase(part_str, "plocm")))258 std.ascii.eqlIgnoreCase(part_str, "plocm")))
259 {259 {
260 parsed.suffix = part_str;260 parsed.suffix = part_str;
261 } else {261 } else {
lib/compiler_rt/count0bits.zig+1-1
...@@ -143,7 +143,7 @@ pub const __clzsi2 = switch (builtin.cpu.arch) {...@@ -143,7 +143,7 @@ pub const __clzsi2 = switch (builtin.cpu.arch) {
143 .arm, .armeb, .thumb, .thumbeb => impl: {143 .arm, .armeb, .thumb, .thumbeb => impl: {
144 const use_thumb1 =144 const use_thumb1 =
145 (builtin.cpu.arch.isThumb() or145 (builtin.cpu.arch.isThumb() or
146 std.Target.arm.featureSetHas(builtin.cpu.features, .noarm)) and146 std.Target.arm.featureSetHas(builtin.cpu.features, .noarm)) and
147 !std.Target.arm.featureSetHas(builtin.cpu.features, .thumb2);147 !std.Target.arm.featureSetHas(builtin.cpu.features, .thumb2);
148148
149 if (use_thumb1) {149 if (use_thumb1) {
lib/compiler_rt/int.zig+26-26
...@@ -81,19 +81,19 @@ fn test_one_divmoddi4(a: i64, b: i64, expected_q: i64, expected_r: i64) !void {...@@ -81,19 +81,19 @@ fn test_one_divmoddi4(a: i64, b: i64, expected_q: i64, expected_r: i64) !void {
8181
82const cases__divmoddi4 =82const cases__divmoddi4 =
83 [_][4]i64{83 [_][4]i64{
84 [_]i64{ 0, 1, 0, 0 },84 [_]i64{ 0, 1, 0, 0 },
85 [_]i64{ 0, -1, 0, 0 },85 [_]i64{ 0, -1, 0, 0 },
86 [_]i64{ 2, 1, 2, 0 },86 [_]i64{ 2, 1, 2, 0 },
87 [_]i64{ 2, -1, -2, 0 },87 [_]i64{ 2, -1, -2, 0 },
88 [_]i64{ -2, 1, -2, 0 },88 [_]i64{ -2, 1, -2, 0 },
89 [_]i64{ -2, -1, 2, 0 },89 [_]i64{ -2, -1, 2, 0 },
90 [_]i64{ 7, 5, 1, 2 },90 [_]i64{ 7, 5, 1, 2 },
91 [_]i64{ -7, 5, -1, -2 },91 [_]i64{ -7, 5, -1, -2 },
92 [_]i64{ 19, 5, 3, 4 },92 [_]i64{ 19, 5, 3, 4 },
93 [_]i64{ 19, -5, -3, 4 },93 [_]i64{ 19, -5, -3, 4 },
94 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 },94 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 },
95 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 },95 [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 },
96};96 };
9797
98test "test_divmoddi4" {98test "test_divmoddi4" {
99 for (cases__divmoddi4) |case| {99 for (cases__divmoddi4) |case| {
...@@ -215,19 +215,19 @@ pub fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.C) i32 {...@@ -215,19 +215,19 @@ pub fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.C) i32 {
215215
216const cases__divmodsi4 =216const cases__divmodsi4 =
217 [_][4]i32{217 [_][4]i32{
218 [_]i32{ 0, 1, 0, 0 },218 [_]i32{ 0, 1, 0, 0 },
219 [_]i32{ 0, -1, 0, 0 },219 [_]i32{ 0, -1, 0, 0 },
220 [_]i32{ 2, 1, 2, 0 },220 [_]i32{ 2, 1, 2, 0 },
221 [_]i32{ 2, -1, -2, 0 },221 [_]i32{ 2, -1, -2, 0 },
222 [_]i32{ -2, 1, -2, 0 },222 [_]i32{ -2, 1, -2, 0 },
223 [_]i32{ -2, -1, 2, 0 },223 [_]i32{ -2, -1, 2, 0 },
224 [_]i32{ 7, 5, 1, 2 },224 [_]i32{ 7, 5, 1, 2 },
225 [_]i32{ -7, 5, -1, -2 },225 [_]i32{ -7, 5, -1, -2 },
226 [_]i32{ 19, 5, 3, 4 },226 [_]i32{ 19, 5, 3, 4 },
227 [_]i32{ 19, -5, -3, 4 },227 [_]i32{ 19, -5, -3, 4 },
228 [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 },228 [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 },
229 [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 },229 [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 },
230};230 };
231231
232fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) !void {232fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) !void {
233 var r: i32 = undefined;233 var r: i32 = undefined;
lib/compiler_rt/popcount.zig+1-1
...@@ -40,7 +40,7 @@ inline fn popcountXi2(comptime ST: type, a: ST) i32 {...@@ -40,7 +40,7 @@ inline fn popcountXi2(comptime ST: type, a: ST) i32 {
40 var x: UT = @bitCast(a);40 var x: UT = @bitCast(a);
41 x -= (x >> 1) & (~@as(UT, 0) / 3); // 0x55...55, aggregate duos41 x -= (x >> 1) & (~@as(UT, 0) / 3); // 0x55...55, aggregate duos
42 x = ((x >> 2) & (~@as(UT, 0) / 5)) // 0x33...33, aggregate nibbles42 x = ((x >> 2) & (~@as(UT, 0) / 5)) // 0x33...33, aggregate nibbles
43 + (x & (~@as(UT, 0) / 5));43 + (x & (~@as(UT, 0) / 5));
44 x += x >> 4;44 x += x >> 4;
45 x &= ~@as(UT, 0) / 17; // 0x0F...0F, aggregate bytes45 x &= ~@as(UT, 0) / 17; // 0x0F...0F, aggregate bytes
46 // 8 most significant bits of x + (x<<8) + (x<<16) + ..46 // 8 most significant bits of x + (x<<8) + (x<<16) + ..
lib/docs/wasm/markdown/Parser.zig+1-1
...@@ -374,7 +374,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void {...@@ -374,7 +374,7 @@ fn appendBlockStart(p: *Parser, block_start: BlockStart) !void {
374 // or not of the same marker type.374 // or not of the same marker type.
375 const should_close_list = last_pending_block.tag == .list and375 const should_close_list = last_pending_block.tag == .list and
376 (block_start.tag != .list_item or376 (block_start.tag != .list_item or
377 block_start.data.list_item.marker != last_pending_block.data.list.marker);377 block_start.data.list_item.marker != last_pending_block.data.list.marker);
378 // The last block should also be closed if the new block is not a table378 // The last block should also be closed if the new block is not a table
379 // row, which is the only allowed child of a table.379 // row, which is the only allowed child of a table.
380 const should_close_table = last_pending_block.tag == .table and380 const should_close_table = last_pending_block.tag == .table and
lib/std/Target.zig+1-1
...@@ -299,7 +299,7 @@ pub const Os = struct {...@@ -299,7 +299,7 @@ pub const Os = struct {
299 pub fn parse(str: []const u8) !WindowsVersion {299 pub fn parse(str: []const u8) !WindowsVersion {
300 return std.meta.stringToEnum(WindowsVersion, str) orelse300 return std.meta.stringToEnum(WindowsVersion, str) orelse
301 @enumFromInt(std.fmt.parseInt(u32, str, 0) catch301 @enumFromInt(std.fmt.parseInt(u32, str, 0) catch
302 return error.InvalidOperatingSystemVersion);302 return error.InvalidOperatingSystemVersion);
303 }303 }
304304
305 /// This function is defined to serialize a Zig source code representation of this305 /// This function is defined to serialize a Zig source code representation of this
lib/std/c.zig+4-4
...@@ -9879,10 +9879,10 @@ pub extern "c" fn setlocale(category: LC, locale: ?[*:0]const u8) ?[*:0]const u8...@@ -9879,10 +9879,10 @@ pub extern "c" fn setlocale(category: LC, locale: ?[*:0]const u8) ?[*:0]const u8
98799879
9880pub const getcontext = if (builtin.target.abi.isAndroid() or builtin.target.os.tag == .openbsd)9880pub const getcontext = if (builtin.target.abi.isAndroid() or builtin.target.os.tag == .openbsd)
9881{} // android bionic and openbsd libc does not implement getcontext9881{} // android bionic and openbsd libc does not implement getcontext
9882else if (native_os == .linux and builtin.target.abi.isMusl())9882 else if (native_os == .linux and builtin.target.abi.isMusl())
9883 linux.getcontext9883 linux.getcontext
9884else9884 else
9885 private.getcontext;9885 private.getcontext;
98869886
9887pub const max_align_t = if (native_abi == .msvc or native_abi == .itanium)9887pub const max_align_t = if (native_abi == .msvc or native_abi == .itanium)
9888 f649888 f64
lib/std/crypto/tls/Client.zig+7-7
...@@ -692,7 +692,7 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client...@@ -692,7 +692,7 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client
692 const client_key_exchange_msg = .{@intFromEnum(tls.ContentType.handshake)} ++692 const client_key_exchange_msg = .{@intFromEnum(tls.ContentType.handshake)} ++
693 int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++693 int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++
694 array(u16, u8, .{@intFromEnum(tls.HandshakeType.client_key_exchange)} ++694 array(u16, u8, .{@intFromEnum(tls.HandshakeType.client_key_exchange)} ++
695 array(u24, u8, array(u8, u8, key_share.secp256r1_kp.public_key.toUncompressedSec1())));695 array(u24, u8, array(u8, u8, key_share.secp256r1_kp.public_key.toUncompressedSec1())));
696 const client_change_cipher_spec_msg = .{@intFromEnum(tls.ContentType.change_cipher_spec)} ++696 const client_change_cipher_spec_msg = .{@intFromEnum(tls.ContentType.change_cipher_spec)} ++
697 int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++697 int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++
698 array(u16, tls.ChangeCipherSpecType, .{.change_cipher_spec});698 array(u16, tls.ChangeCipherSpecType, .{.change_cipher_spec});
...@@ -720,11 +720,11 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client...@@ -720,11 +720,11 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client
720 );720 );
721 const client_verify_cleartext = .{@intFromEnum(tls.HandshakeType.finished)} ++721 const client_verify_cleartext = .{@intFromEnum(tls.HandshakeType.finished)} ++
722 array(u24, u8, hmacExpandLabel(722 array(u24, u8, hmacExpandLabel(
723 P.Hmac,723 P.Hmac,
724 &master_secret,724 &master_secret,
725 &.{ "client finished", &p.transcript_hash.peek() },725 &.{ "client finished", &p.transcript_hash.peek() },
726 P.verify_data_length,726 P.verify_data_length,
727 ));727 ));
728 p.transcript_hash.update(&client_verify_cleartext);728 p.transcript_hash.update(&client_verify_cleartext);
729 p.version = .{ .tls_1_2 = .{729 p.version = .{ .tls_1_2 = .{
730 .expected_server_verify_data = hmacExpandLabel(730 .expected_server_verify_data = hmacExpandLabel(
...@@ -745,7 +745,7 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client...@@ -745,7 +745,7 @@ pub fn init(stream: anytype, options: Options) InitError(@TypeOf(stream))!Client
745 var client_verify_msg = .{@intFromEnum(tls.ContentType.handshake)} ++745 var client_verify_msg = .{@intFromEnum(tls.ContentType.handshake)} ++
746 int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++746 int(u16, @intFromEnum(tls.ProtocolVersion.tls_1_2)) ++
747 array(u16, u8, nonce[P.fixed_iv_length..].* ++747 array(u16, u8, nonce[P.fixed_iv_length..].* ++
748 @as([client_verify_cleartext.len + P.mac_length]u8, undefined));748 @as([client_verify_cleartext.len + P.mac_length]u8, undefined));
749 P.AEAD.encrypt(749 P.AEAD.encrypt(
750 client_verify_msg[client_verify_msg.len - P.mac_length -750 client_verify_msg[client_verify_msg.len - P.mac_length -
751 client_verify_cleartext.len ..][0..client_verify_cleartext.len],751 client_verify_cleartext.len ..][0..client_verify_cleartext.len],
lib/std/debug/SelfInfo.zig+9-9
...@@ -689,15 +689,15 @@ pub const Module = switch (native_os) {...@@ -689,15 +689,15 @@ pub const Module = switch (native_os) {
689 const o_file_path = mem.sliceTo(self.strings[symbol.ofile..], 0);689 const o_file_path = mem.sliceTo(self.strings[symbol.ofile..], 0);
690 const o_file_info = self.ofiles.getPtr(o_file_path) orelse690 const o_file_info = self.ofiles.getPtr(o_file_path) orelse
691 (self.loadOFile(allocator, o_file_path) catch |err| switch (err) {691 (self.loadOFile(allocator, o_file_path) catch |err| switch (err) {
692 error.FileNotFound,692 error.FileNotFound,
693 error.MissingDebugInfo,693 error.MissingDebugInfo,
694 error.InvalidDebugInfo,694 error.InvalidDebugInfo,
695 => return .{695 => return .{
696 .relocated_address = relocated_address,696 .relocated_address = relocated_address,
697 .symbol = symbol,697 .symbol = symbol,
698 },698 },
699 else => return err,699 else => return err,
700 });700 });
701701
702 return .{702 return .{
703 .relocated_address = relocated_address,703 .relocated_address = relocated_address,
lib/std/http/Client.zig+14-14
...@@ -959,14 +959,14 @@ pub const Request = struct {...@@ -959,14 +959,14 @@ pub const Request = struct {
959959
960 pub const WaitError = RequestError || SendError || TransferReadError ||960 pub const WaitError = RequestError || SendError || TransferReadError ||
961 proto.HeadersParser.CheckCompleteHeadError || Response.ParseError ||961 proto.HeadersParser.CheckCompleteHeadError || Response.ParseError ||
962 error{ // TODO: file zig fmt issue for this bad indentation962 error{
963 TooManyHttpRedirects,963 TooManyHttpRedirects,
964 RedirectRequiresResend,964 RedirectRequiresResend,
965 HttpRedirectLocationMissing,965 HttpRedirectLocationMissing,
966 HttpRedirectLocationInvalid,966 HttpRedirectLocationInvalid,
967 CompressionInitializationFailed,967 CompressionInitializationFailed,
968 CompressionUnsupported,968 CompressionUnsupported,
969 };969 };
970970
971 /// Waits for a response from the server and parses any headers that are sent.971 /// Waits for a response from the server and parses any headers that are sent.
972 /// This function will block until the final response is received.972 /// This function will block until the final response is received.
...@@ -1539,13 +1539,13 @@ pub fn connect(...@@ -1539,13 +1539,13 @@ pub fn connect(
15391539
1540pub const RequestError = ConnectTcpError || ConnectErrorPartial || Request.SendError ||1540pub const RequestError = ConnectTcpError || ConnectErrorPartial || Request.SendError ||
1541 std.fmt.ParseIntError || Connection.WriteError ||1541 std.fmt.ParseIntError || Connection.WriteError ||
1542 error{ // TODO: file a zig fmt issue for this bad indentation1542 error{
1543 UnsupportedUriScheme,1543 UnsupportedUriScheme,
1544 UriMissingHost,1544 UriMissingHost,
15451545
1546 CertificateBundleLoadFailure,1546 CertificateBundleLoadFailure,
1547 UnsupportedTransferEncoding,1547 UnsupportedTransferEncoding,
1548};1548 };
15491549
1550pub const RequestOptions = struct {1550pub const RequestOptions = struct {
1551 version: http.Version = .@"HTTP/1.1",1551 version: http.Version = .@"HTTP/1.1",
lib/std/posix.zig+6-6
...@@ -2851,12 +2851,12 @@ pub fn renameatW(...@@ -2851,12 +2851,12 @@ pub fn renameatW(
28512851
2852 rc =2852 rc =
2853 windows.ntdll.NtSetInformationFile(2853 windows.ntdll.NtSetInformationFile(
2854 src_fd,2854 src_fd,
2855 &io_status_block,2855 &io_status_block,
2856 rename_info,2856 rename_info,
2857 @intCast(struct_len), // already checked for error.NameTooLong2857 @intCast(struct_len), // already checked for error.NameTooLong
2858 .FileRenameInformation,2858 .FileRenameInformation,
2859 );2859 );
2860 }2860 }
28612861
2862 switch (rc) {2862 switch (rc) {
lib/std/zig.zig+12-12
...@@ -535,16 +535,12 @@ test isUnderscore {...@@ -535,16 +535,12 @@ test isUnderscore {
535 try std.testing.expect(!isUnderscore("\\x5f"));535 try std.testing.expect(!isUnderscore("\\x5f"));
536}536}
537537
538pub fn readSourceFileToEndAlloc(538pub fn readSourceFileToEndAlloc(gpa: Allocator, input: std.fs.File, size_hint: ?usize) ![:0]u8 {
539 allocator: Allocator,
540 input: std.fs.File,
541 size_hint: ?usize,
542) ![:0]u8 {
543 const source_code = input.readToEndAllocOptions(539 const source_code = input.readToEndAllocOptions(
544 allocator,540 gpa,
545 max_src_size,541 max_src_size,
546 size_hint,542 size_hint,
547 @alignOf(u16),543 @alignOf(u8),
548 0,544 0,
549 ) catch |err| switch (err) {545 ) catch |err| switch (err) {
550 error.ConnectionResetByPeer => unreachable,546 error.ConnectionResetByPeer => unreachable,
...@@ -552,7 +548,7 @@ pub fn readSourceFileToEndAlloc(...@@ -552,7 +548,7 @@ pub fn readSourceFileToEndAlloc(
552 error.NotOpenForReading => unreachable,548 error.NotOpenForReading => unreachable,
553 else => |e| return e,549 else => |e| return e,
554 };550 };
555 errdefer allocator.free(source_code);551 errdefer gpa.free(source_code);
556552
557 // Detect unsupported file types with their Byte Order Mark553 // Detect unsupported file types with their Byte Order Mark
558 const unsupported_boms = [_][]const u8{554 const unsupported_boms = [_][]const u8{
...@@ -568,15 +564,19 @@ pub fn readSourceFileToEndAlloc(...@@ -568,15 +564,19 @@ pub fn readSourceFileToEndAlloc(
568564
569 // If the file starts with a UTF-16 little endian BOM, translate it to UTF-8565 // If the file starts with a UTF-16 little endian BOM, translate it to UTF-8
570 if (std.mem.startsWith(u8, source_code, "\xff\xfe")) {566 if (std.mem.startsWith(u8, source_code, "\xff\xfe")) {
571 const source_code_utf16_le = std.mem.bytesAsSlice(u16, source_code);567 if (source_code.len % 2 != 0) return error.InvalidEncoding;
572 const source_code_utf8 = std.unicode.utf16LeToUtf8AllocZ(allocator, source_code_utf16_le) catch |err| switch (err) {568 // TODO: after wrangle-writer-buffering branch is merged,
569 // avoid this unnecessary allocation
570 const aligned_copy = try gpa.alloc(u16, source_code.len / 2);
571 defer gpa.free(aligned_copy);
572 @memcpy(std.mem.sliceAsBytes(aligned_copy), source_code);
573 const source_code_utf8 = std.unicode.utf16LeToUtf8AllocZ(gpa, aligned_copy) catch |err| switch (err) {
573 error.DanglingSurrogateHalf => error.UnsupportedEncoding,574 error.DanglingSurrogateHalf => error.UnsupportedEncoding,
574 error.ExpectedSecondSurrogateHalf => error.UnsupportedEncoding,575 error.ExpectedSecondSurrogateHalf => error.UnsupportedEncoding,
575 error.UnexpectedSecondSurrogateHalf => error.UnsupportedEncoding,576 error.UnexpectedSecondSurrogateHalf => error.UnsupportedEncoding,
576 else => |e| return e,577 else => |e| return e,
577 };578 };
578579 gpa.free(source_code);
579 allocator.free(source_code);
580 return source_code_utf8;580 return source_code_utf8;
581 }581 }
582582
lib/std/zig/parser_test.zig+165-20
...@@ -1776,7 +1776,7 @@ test "zig fmt: if nested" {...@@ -1776,7 +1776,7 @@ test "zig fmt: if nested" {
1776 \\ GE_EQUAL1776 \\ GE_EQUAL
1777 \\ else1777 \\ else
1778 \\ GE_GREATER1778 \\ GE_GREATER
1779 \\ // comment1779 \\ // comment
1780 \\ else if (aInt > bInt)1780 \\ else if (aInt > bInt)
1781 \\ GE_LESS1781 \\ GE_LESS
1782 \\ else if (aInt == bInt)1782 \\ else if (aInt == bInt)
...@@ -4670,7 +4670,7 @@ test "zig fmt: test comments in field access chain" {...@@ -4670,7 +4670,7 @@ test "zig fmt: test comments in field access chain" {
4670 \\ .more() //4670 \\ .more() //
4671 \\ .more().more() //4671 \\ .more().more() //
4672 \\ .more() //4672 \\ .more() //
4673 \\ // .more() //4673 \\ // .more() //
4674 \\ .more() //4674 \\ .more() //
4675 \\ .more();4675 \\ .more();
4676 \\ data: Data,4676 \\ data: Data,
...@@ -4679,9 +4679,9 @@ test "zig fmt: test comments in field access chain" {...@@ -4679,9 +4679,9 @@ test "zig fmt: test comments in field access chain" {
4679 \\pub const str = struct {4679 \\pub const str = struct {
4680 \\ pub const Thing = more.more //4680 \\ pub const Thing = more.more //
4681 \\ .more() //4681 \\ .more() //
4682 \\ // .more() //4682 \\ // .more() //
4683 \\ // .more() //4683 \\ // .more() //
4684 \\ // .more() //4684 \\ // .more() //
4685 \\ .more() //4685 \\ .more() //
4686 \\ .more();4686 \\ .more();
4687 \\ data: Data,4687 \\ data: Data,
...@@ -4706,7 +4706,7 @@ test "zig fmt: allow line break before field access" {...@@ -4706,7 +4706,7 @@ test "zig fmt: allow line break before field access" {
4706 \\ const x = foo4706 \\ const x = foo
4707 \\ .bar()4707 \\ .bar()
4708 \\ . // comment4708 \\ . // comment
4709 \\ // comment4709 \\ // comment
4710 \\ swooop().zippy(zag)4710 \\ swooop().zippy(zag)
4711 \\ .iguessthisisok();4711 \\ .iguessthisisok();
4712 \\4712 \\
...@@ -4716,7 +4716,7 @@ test "zig fmt: allow line break before field access" {...@@ -4716,7 +4716,7 @@ test "zig fmt: allow line break before field access" {
4716 \\ .input_manager //4716 \\ .input_manager //
4717 \\ .default_seat4717 \\ .default_seat
4718 \\ . // comment4718 \\ . // comment
4719 \\ // another comment4719 \\ // another comment
4720 \\ wlr_seat.name;4720 \\ wlr_seat.name;
4721 \\}4721 \\}
4722 \\4722 \\
...@@ -4955,19 +4955,19 @@ test "zig fmt: use of comments and multiline string literals may force the param...@@ -4955,19 +4955,19 @@ test "zig fmt: use of comments and multiline string literals may force the param
4955 \\4955 \\
4956 \\// This looks like garbage don't do this4956 \\// This looks like garbage don't do this
4957 \\const rparen = tree.prevToken(4957 \\const rparen = tree.prevToken(
4958 \\// the first token for the annotation expressions is the left4958 \\ // the first token for the annotation expressions is the left
4959 \\// parenthesis, hence the need for two prevToken4959 \\ // parenthesis, hence the need for two prevToken
4960 \\if (fn_proto.getAlignExpr()) |align_expr|4960 \\ if (fn_proto.getAlignExpr()) |align_expr|
4961 \\ tree.prevToken(tree.prevToken(align_expr.firstToken()))4961 \\ tree.prevToken(tree.prevToken(align_expr.firstToken()))
4962 \\else if (fn_proto.getSectionExpr()) |section_expr|4962 \\ else if (fn_proto.getSectionExpr()) |section_expr|
4963 \\ tree.prevToken(tree.prevToken(section_expr.firstToken()))4963 \\ tree.prevToken(tree.prevToken(section_expr.firstToken()))
4964 \\else if (fn_proto.getCallconvExpr()) |callconv_expr|4964 \\ else if (fn_proto.getCallconvExpr()) |callconv_expr|
4965 \\ tree.prevToken(tree.prevToken(callconv_expr.firstToken()))4965 \\ tree.prevToken(tree.prevToken(callconv_expr.firstToken()))
4966 \\else switch (fn_proto.return_type) {4966 \\ else switch (fn_proto.return_type) {
4967 \\ .Explicit => |node| node.firstToken(),4967 \\ .Explicit => |node| node.firstToken(),
4968 \\ .InferErrorSet => |node| tree.prevToken(node.firstToken()),4968 \\ .InferErrorSet => |node| tree.prevToken(node.firstToken()),
4969 \\ .Invalid => unreachable,4969 \\ .Invalid => unreachable,
4970 \\});4970 \\ });
4971 \\4971 \\
4972 );4972 );
4973}4973}
...@@ -5962,6 +5962,151 @@ test "zig fmt: pointer type syntax to index" {...@@ -5962,6 +5962,151 @@ test "zig fmt: pointer type syntax to index" {
5962 );5962 );
5963}5963}
59645964
5965test "zig fmt: binop indentation in if statement" {
5966 try testCanonical(
5967 \\test {
5968 \\ if (first_param_type.isGenericPoison() or
5969 \\ (first_param_type.zigTypeTag(zcu) == .pointer and
5970 \\ (first_param_type.ptrSize(zcu) == .One or
5971 \\ first_param_type.ptrSize(zcu) == .C) and
5972 \\ first_param_type.childType(zcu).eql(concrete_ty, zcu)))
5973 \\ {
5974 \\ f(x);
5975 \\ }
5976 \\}
5977 \\
5978 );
5979}
5980
5981test "zig fmt: test indentation after equals sign" {
5982 try testCanonical(
5983 \\test {
5984 \\ const foo =
5985 \\ if (1 == 2)
5986 \\ 1
5987 \\ else if (3 > 4)
5988 \\ 2
5989 \\ else
5990 \\ 0;
5991 \\
5992 \\ const foo, const bar =
5993 \\ if (1 == 2)
5994 \\ .{ 0, 0 }
5995 \\ else if (3 > 4)
5996 \\ .{ 1, 1 }
5997 \\ else
5998 \\ .{ 2, 2 };
5999 \\
6000 \\ while (foo) if (bar)
6001 \\ f(x);
6002 \\
6003 \\ foobar =
6004 \\ if (true)
6005 \\ 1
6006 \\ else
6007 \\ 0;
6008 \\
6009 \\ const foo = if (1 == 2)
6010 \\ 1
6011 \\ else if (3 > 4)
6012 \\ 2
6013 \\ else
6014 \\ 0;
6015 \\
6016 \\ const foo, const bar = if (1 == 2)
6017 \\ .{ 0, 0 }
6018 \\ else if (3 > 4)
6019 \\ .{ 1, 1 }
6020 \\ else
6021 \\ .{ 2, 2 };
6022 \\
6023 \\ foobar = if (true)
6024 \\ 1
6025 \\ else
6026 \\ 0;
6027 \\
6028 \\ const is_alphanum =
6029 \\ (ch >= 'a' and ch <= 'z') or
6030 \\ (ch >= 'A' and ch <= 'Z') or
6031 \\ (ch >= '0' and ch <= '9');
6032 \\
6033 \\ const bar = 100 + calculate(
6034 \\ 200,
6035 \\ 300,
6036 \\ );
6037 \\
6038 \\ const gcc_pragma = std.meta.stringToEnum(Directive, pp.expandedSlice(directive_tok)) orelse
6039 \\ return pp.comp.addDiagnostic(.{
6040 \\ .tag = .unknown_gcc_pragma,
6041 \\ .loc = directive_tok.loc,
6042 \\ }, pp.expansionSlice(start_idx + 1));
6043 \\
6044 \\ const vec4s =
6045 \\ [_][4]i32{
6046 \\ [_]i32{ 0, 1, 0, 0 },
6047 \\ [_]i32{ 0, -1, 0, 0 },
6048 \\ [_]i32{ 2, 1, 2, 0 },
6049 \\ };
6050 \\}
6051 \\
6052 );
6053}
6054
6055test "zig fmt: test indentation of if expressions" {
6056 try testCanonical(
6057 \\test {
6058 \\ const foo = 1 +
6059 \\ if (1 == 2)
6060 \\ 2
6061 \\ else
6062 \\ 0;
6063 \\
6064 \\ const foo = 1 + if (1 == 2)
6065 \\ 2
6066 \\ else
6067 \\ 0;
6068 \\
6069 \\ errval catch |e|
6070 \\ if (e == error.Meow)
6071 \\ return 0x1F408
6072 \\ else
6073 \\ unreachable;
6074 \\
6075 \\ errval catch |e| if (e == error.Meow)
6076 \\ return 0x1F408
6077 \\ else
6078 \\ unreachable;
6079 \\
6080 \\ return if (1 == 2)
6081 \\ 1
6082 \\ else if (3 > 4)
6083 \\ 2
6084 \\ else
6085 \\ 0;
6086 \\}
6087 \\
6088 );
6089}
6090
6091test "zig fmt: indentation of comments within catch, else, orelse" {
6092 try testCanonical(
6093 \\comptime {
6094 \\ _ = foo() catch
6095 \\ //
6096 \\ bar();
6097 \\
6098 \\ _ = if (foo) bar() else
6099 \\ //
6100 \\ qux();
6101 \\
6102 \\ _ = foo() orelse
6103 \\ //
6104 \\ qux();
6105 \\}
6106 \\
6107 );
6108}
6109
5965test "recovery: top level" {6110test "recovery: top level" {
5966 try testError(6111 try testError(
5967 \\test "" {inline}6112 \\test "" {inline}
lib/std/zig/render.zig+299-215
...@@ -81,10 +81,8 @@ const Render = struct {...@@ -81,10 +81,8 @@ const Render = struct {
8181
82pub fn renderTree(buffer: *std.ArrayList(u8), tree: Ast, fixups: Fixups) Error!void {82pub fn renderTree(buffer: *std.ArrayList(u8), tree: Ast, fixups: Fixups) Error!void {
83 assert(tree.errors.len == 0); // Cannot render an invalid tree.83 assert(tree.errors.len == 0); // Cannot render an invalid tree.
84 var auto_indenting_stream = Ais{84 var auto_indenting_stream = Ais.init(buffer, indent_delta);
85 .indent_delta = indent_delta,85 defer auto_indenting_stream.deinit();
86 .underlying_writer = buffer.writer(),
87 };
88 var r: Render = .{86 var r: Render = .{
89 .gpa = buffer.allocator,87 .gpa = buffer.allocator,
90 .ais = &auto_indenting_stream,88 .ais = &auto_indenting_stream,
...@@ -198,7 +196,7 @@ fn renderMember(...@@ -198,7 +196,7 @@ fn renderMember(
198 try renderExpression(r, fn_proto, .space);196 try renderExpression(r, fn_proto, .space);
199 const body_node = datas[decl].rhs;197 const body_node = datas[decl].rhs;
200 if (r.fixups.gut_functions.contains(decl)) {198 if (r.fixups.gut_functions.contains(decl)) {
201 ais.pushIndent();199 try ais.pushIndent(.normal);
202 const lbrace = tree.nodes.items(.main_token)[body_node];200 const lbrace = tree.nodes.items(.main_token)[body_node];
203 try renderToken(r, lbrace, .newline);201 try renderToken(r, lbrace, .newline);
204 try discardAllParams(r, fn_proto);202 try discardAllParams(r, fn_proto);
...@@ -207,7 +205,7 @@ fn renderMember(...@@ -207,7 +205,7 @@ fn renderMember(
207 try ais.insertNewline();205 try ais.insertNewline();
208 try renderToken(r, tree.lastToken(body_node), space); // rbrace206 try renderToken(r, tree.lastToken(body_node), space); // rbrace
209 } else if (r.fixups.unused_var_decls.count() != 0) {207 } else if (r.fixups.unused_var_decls.count() != 0) {
210 ais.pushIndentNextLine();208 try ais.pushIndent(.normal);
211 const lbrace = tree.nodes.items(.main_token)[body_node];209 const lbrace = tree.nodes.items(.main_token)[body_node];
212 try renderToken(r, lbrace, .newline);210 try renderToken(r, lbrace, .newline);
213211
...@@ -297,7 +295,11 @@ fn renderMember(...@@ -297,7 +295,11 @@ fn renderMember(
297 .local_var_decl,295 .local_var_decl,
298 .simple_var_decl,296 .simple_var_decl,
299 .aligned_var_decl,297 .aligned_var_decl,
300 => return renderVarDecl(r, tree.fullVarDecl(decl).?, false, .semicolon),298 => {
299 try ais.pushSpace(.semicolon);
300 try renderVarDecl(r, tree.fullVarDecl(decl).?, false, .semicolon);
301 ais.popSpace();
302 },
301303
302 .test_decl => {304 .test_decl => {
303 const test_token = main_tokens[decl];305 const test_token = main_tokens[decl];
...@@ -361,18 +363,25 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {...@@ -361,18 +363,25 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {
361 => return renderToken(r, main_tokens[node], space),363 => return renderToken(r, main_tokens[node], space),
362364
363 .multiline_string_literal => {365 .multiline_string_literal => {
364 var locked_indents = ais.lockOneShotIndent();
365 try ais.maybeInsertNewline();366 try ais.maybeInsertNewline();
366367
367 var i = datas[node].lhs;368 var i = datas[node].lhs;
368 while (i <= datas[node].rhs) : (i += 1) try renderToken(r, i, .newline);369 while (i <= datas[node].rhs) : (i += 1) try renderToken(r, i, .newline);
369370
370 while (locked_indents > 0) : (locked_indents -= 1) ais.popIndent();371 // dedent the next thing that comes after a multiline string literal
372 if (!ais.indentStackEmpty() and
373 token_tags[i] != .colon and
374 ((token_tags[i] != .semicolon and token_tags[i] != .comma) or
375 ais.lastSpaceModeIndent() < ais.currentIndent()))
376 {
377 ais.popIndent();
378 try ais.pushIndent(.normal);
379 }
371380
372 switch (space) {381 switch (space) {
373 .none, .space, .newline, .skip => {},382 .none, .space, .newline, .skip => {},
374 .semicolon => if (token_tags[i] == .semicolon) try renderToken(r, i, .newline),383 .semicolon => if (token_tags[i] == .semicolon) try renderTokenOverrideSpaceMode(r, i, .newline, .semicolon),
375 .comma => if (token_tags[i] == .comma) try renderToken(r, i, .newline),384 .comma => if (token_tags[i] == .comma) try renderTokenOverrideSpaceMode(r, i, .newline, .comma),
376 .comma_space => if (token_tags[i] == .comma) try renderToken(r, i, .space),385 .comma_space => if (token_tags[i] == .comma) try renderToken(r, i, .space),
377 }386 }
378 },387 },
...@@ -445,6 +454,7 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {...@@ -445,6 +454,7 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {
445454
446 try renderExpression(r, datas[node].lhs, .space); // target455 try renderExpression(r, datas[node].lhs, .space); // target
447456
457 try ais.pushIndent(.normal);
448 if (token_tags[fallback_first - 1] == .pipe) {458 if (token_tags[fallback_first - 1] == .pipe) {
449 try renderToken(r, main_token, .space); // catch keyword459 try renderToken(r, main_token, .space); // catch keyword
450 try renderToken(r, main_token + 1, .none); // pipe460 try renderToken(r, main_token + 1, .none); // pipe
...@@ -454,38 +464,27 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {...@@ -454,38 +464,27 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {
454 assert(token_tags[fallback_first - 1] == .keyword_catch);464 assert(token_tags[fallback_first - 1] == .keyword_catch);
455 try renderToken(r, main_token, after_op_space); // catch keyword465 try renderToken(r, main_token, after_op_space); // catch keyword
456 }466 }
457
458 ais.pushIndentOneShot();
459 try renderExpression(r, datas[node].rhs, space); // fallback467 try renderExpression(r, datas[node].rhs, space); // fallback
468 ais.popIndent();
460 },469 },
461470
462 .field_access => {471 .field_access => {
463 const main_token = main_tokens[node];472 const main_token = main_tokens[node];
464 const field_access = datas[node];473 const field_access = datas[node];
465474
475 try ais.pushIndent(.field_access);
466 try renderExpression(r, field_access.lhs, .none);476 try renderExpression(r, field_access.lhs, .none);
467477
468 // Allow a line break between the lhs and the dot if the lhs and rhs478 // Allow a line break between the lhs and the dot if the lhs and rhs
469 // are on different lines.479 // are on different lines.
470 const lhs_last_token = tree.lastToken(field_access.lhs);480 const lhs_last_token = tree.lastToken(field_access.lhs);
471 const same_line = tree.tokensOnSameLine(lhs_last_token, main_token + 1);481 const same_line = tree.tokensOnSameLine(lhs_last_token, main_token + 1);
472 if (!same_line) {482 if (!same_line and !hasComment(tree, lhs_last_token, main_token)) try ais.insertNewline();
473 if (!hasComment(tree, lhs_last_token, main_token)) try ais.insertNewline();
474 ais.pushIndentOneShot();
475 }
476483
477 try renderToken(r, main_token, .none); // .484 try renderToken(r, main_token, .none); // .
478485
479 // This check ensures that zag() is indented in the following example:486 try renderIdentifier(r, field_access.rhs, space, .eagerly_unquote); // field
480 // const x = foo487 ais.popIndent();
481 // .bar()
482 // . // comment
483 // zag();
484 if (!same_line and hasComment(tree, main_token, main_token + 1)) {
485 ais.pushIndentOneShot();
486 }
487
488 return renderIdentifier(r, field_access.rhs, space, .eagerly_unquote); // field
489 },488 },
490489
491 .error_union,490 .error_union,
...@@ -507,11 +506,6 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {...@@ -507,11 +506,6 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {
507 }506 }
508 },507 },
509508
510 .add,
511 .add_wrap,
512 .add_sat,
513 .array_cat,
514 .array_mult,
515 .assign,509 .assign,
516 .assign_bit_and,510 .assign_bit_and,
517 .assign_bit_or,511 .assign_bit_or,
...@@ -530,6 +524,25 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {...@@ -530,6 +524,25 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {
530 .assign_mul,524 .assign_mul,
531 .assign_mul_wrap,525 .assign_mul_wrap,
532 .assign_mul_sat,526 .assign_mul_sat,
527 => {
528 const infix = datas[node];
529 try renderExpression(r, infix.lhs, .space);
530 const op_token = main_tokens[node];
531 try ais.pushIndent(.after_equals);
532 if (tree.tokensOnSameLine(op_token, op_token + 1)) {
533 try renderToken(r, op_token, .space);
534 } else {
535 try renderToken(r, op_token, .newline);
536 }
537 try renderExpression(r, infix.rhs, space);
538 ais.popIndent();
539 },
540
541 .add,
542 .add_wrap,
543 .add_sat,
544 .array_cat,
545 .array_mult,
533 .bang_equal,546 .bang_equal,
534 .bit_and,547 .bit_and,
535 .bit_or,548 .bit_or,
...@@ -558,15 +571,14 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {...@@ -558,15 +571,14 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {
558 const infix = datas[node];571 const infix = datas[node];
559 try renderExpression(r, infix.lhs, .space);572 try renderExpression(r, infix.lhs, .space);
560 const op_token = main_tokens[node];573 const op_token = main_tokens[node];
574 try ais.pushIndent(.binop);
561 if (tree.tokensOnSameLine(op_token, op_token + 1)) {575 if (tree.tokensOnSameLine(op_token, op_token + 1)) {
562 try renderToken(r, op_token, .space);576 try renderToken(r, op_token, .space);
563 } else {577 } else {
564 ais.pushIndent();
565 try renderToken(r, op_token, .newline);578 try renderToken(r, op_token, .newline);
566 ais.popIndent();
567 }579 }
568 ais.pushIndentOneShot();580 try renderExpression(r, infix.rhs, space);
569 return renderExpression(r, infix.rhs, space);581 ais.popIndent();
570 },582 },
571583
572 .assign_destructure => {584 .assign_destructure => {
...@@ -588,15 +600,14 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {...@@ -588,15 +600,14 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {
588 else => try renderExpression(r, variable_node, variable_space),600 else => try renderExpression(r, variable_node, variable_space),
589 }601 }
590 }602 }
603 try ais.pushIndent(.after_equals);
591 if (tree.tokensOnSameLine(full.ast.equal_token, full.ast.equal_token + 1)) {604 if (tree.tokensOnSameLine(full.ast.equal_token, full.ast.equal_token + 1)) {
592 try renderToken(r, full.ast.equal_token, .space);605 try renderToken(r, full.ast.equal_token, .space);
593 } else {606 } else {
594 ais.pushIndent();
595 try renderToken(r, full.ast.equal_token, .newline);607 try renderToken(r, full.ast.equal_token, .newline);
596 ais.popIndent();
597 }608 }
598 ais.pushIndentOneShot();609 try renderExpression(r, full.ast.value_expr, space);
599 return renderExpression(r, full.ast.value_expr, space);610 ais.popIndent();
600 },611 },
601612
602 .bit_not,613 .bit_not,
...@@ -674,7 +685,7 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {...@@ -674,7 +685,7 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {
674 const one_line = tree.tokensOnSameLine(lbracket, rbracket);685 const one_line = tree.tokensOnSameLine(lbracket, rbracket);
675 const inner_space = if (one_line) Space.none else Space.newline;686 const inner_space = if (one_line) Space.none else Space.newline;
676 try renderExpression(r, suffix.lhs, .none);687 try renderExpression(r, suffix.lhs, .none);
677 ais.pushIndentNextLine();688 try ais.pushIndent(.normal);
678 try renderToken(r, lbracket, inner_space); // [689 try renderToken(r, lbracket, inner_space); // [
679 try renderExpression(r, suffix.rhs, inner_space);690 try renderExpression(r, suffix.rhs, inner_space);
680 ais.popIndent();691 ais.popIndent();
...@@ -725,9 +736,10 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {...@@ -725,9 +736,10 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {
725 },736 },
726737
727 .grouped_expression => {738 .grouped_expression => {
739 try ais.pushIndent(.normal);
728 try renderToken(r, main_tokens[node], .none); // lparen740 try renderToken(r, main_tokens[node], .none); // lparen
729 ais.pushIndentOneShot();
730 try renderExpression(r, datas[node].lhs, .none);741 try renderExpression(r, datas[node].lhs, .none);
742 ais.popIndent();
731 return renderToken(r, datas[node].rhs, space); // rparen743 return renderToken(r, datas[node].rhs, space); // rparen
732 },744 },
733745
...@@ -767,14 +779,18 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {...@@ -767,14 +779,18 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {
767 return renderToken(r, rbrace, space);779 return renderToken(r, rbrace, space);
768 } else if (token_tags[rbrace - 1] == .comma) {780 } else if (token_tags[rbrace - 1] == .comma) {
769 // There is a trailing comma so render each member on a new line.781 // There is a trailing comma so render each member on a new line.
770 ais.pushIndentNextLine();782 try ais.pushIndent(.normal);
771 try renderToken(r, lbrace, .newline);783 try renderToken(r, lbrace, .newline);
772 var i = lbrace + 1;784 var i = lbrace + 1;
773 while (i < rbrace) : (i += 1) {785 while (i < rbrace) : (i += 1) {
774 if (i > lbrace + 1) try renderExtraNewlineToken(r, i);786 if (i > lbrace + 1) try renderExtraNewlineToken(r, i);
775 switch (token_tags[i]) {787 switch (token_tags[i]) {
776 .doc_comment => try renderToken(r, i, .newline),788 .doc_comment => try renderToken(r, i, .newline),
777 .identifier => try renderIdentifier(r, i, .comma, .eagerly_unquote),789 .identifier => {
790 try ais.pushSpace(.comma);
791 try renderIdentifier(r, i, .comma, .eagerly_unquote);
792 ais.popSpace();
793 },
778 .comma => {},794 .comma => {},
779 else => unreachable,795 else => unreachable,
780 }796 }
...@@ -848,12 +864,14 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {...@@ -848,12 +864,14 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {
848 try renderExpression(r, full.ast.condition, .none); // condition expression864 try renderExpression(r, full.ast.condition, .none); // condition expression
849 try renderToken(r, rparen, .space); // )865 try renderToken(r, rparen, .space); // )
850866
851 ais.pushIndentNextLine();867 try ais.pushIndent(.normal);
852 if (full.ast.cases.len == 0) {868 if (full.ast.cases.len == 0) {
853 try renderToken(r, rparen + 1, .none); // {869 try renderToken(r, rparen + 1, .none); // {
854 } else {870 } else {
855 try renderToken(r, rparen + 1, .newline); // {871 try renderToken(r, rparen + 1, .newline); // {
872 try ais.pushSpace(.comma);
856 try renderExpressions(r, full.ast.cases, .comma);873 try renderExpressions(r, full.ast.cases, .comma);
874 ais.popSpace();
857 }875 }
858 ais.popIndent();876 ais.popIndent();
859 return renderToken(r, tree.lastToken(node), space); // }877 return renderToken(r, tree.lastToken(node), space); // }
...@@ -923,7 +941,7 @@ fn renderArrayType(...@@ -923,7 +941,7 @@ fn renderArrayType(
923 const rbracket = tree.firstToken(array_type.ast.elem_type) - 1;941 const rbracket = tree.firstToken(array_type.ast.elem_type) - 1;
924 const one_line = tree.tokensOnSameLine(array_type.ast.lbracket, rbracket);942 const one_line = tree.tokensOnSameLine(array_type.ast.lbracket, rbracket);
925 const inner_space = if (one_line) Space.none else Space.newline;943 const inner_space = if (one_line) Space.none else Space.newline;
926 ais.pushIndentNextLine();944 try ais.pushIndent(.normal);
927 try renderToken(r, array_type.ast.lbracket, inner_space); // lbracket945 try renderToken(r, array_type.ast.lbracket, inner_space); // lbracket
928 try renderExpression(r, array_type.ast.elem_count, inner_space);946 try renderExpression(r, array_type.ast.elem_count, inner_space);
929 if (array_type.ast.sentinel != 0) {947 if (array_type.ast.sentinel != 0) {
...@@ -1167,9 +1185,9 @@ fn renderVarDeclWithoutFixups(...@@ -1167,9 +1185,9 @@ fn renderVarDeclWithoutFixups(
1167 {1185 {
1168 const name_space = if (var_decl.ast.type_node == 0 and1186 const name_space = if (var_decl.ast.type_node == 0 and
1169 (var_decl.ast.align_node != 0 or1187 (var_decl.ast.align_node != 0 or
1170 var_decl.ast.addrspace_node != 0 or1188 var_decl.ast.addrspace_node != 0 or
1171 var_decl.ast.section_node != 0 or1189 var_decl.ast.section_node != 0 or
1172 var_decl.ast.init_node != 0))1190 var_decl.ast.init_node != 0))
1173 Space.space1191 Space.space
1174 else1192 else
1175 Space.none;1193 Space.none;
...@@ -1239,13 +1257,10 @@ fn renderVarDeclWithoutFixups(...@@ -1239,13 +1257,10 @@ fn renderVarDeclWithoutFixups(
12391257
1240 const eq_token = tree.firstToken(var_decl.ast.init_node) - 1;1258 const eq_token = tree.firstToken(var_decl.ast.init_node) - 1;
1241 const eq_space: Space = if (tree.tokensOnSameLine(eq_token, eq_token + 1)) .space else .newline;1259 const eq_space: Space = if (tree.tokensOnSameLine(eq_token, eq_token + 1)) .space else .newline;
1242 {1260 try ais.pushIndent(.after_equals);
1243 ais.pushIndent();1261 try renderToken(r, eq_token, eq_space); // =
1244 try renderToken(r, eq_token, eq_space); // =1262 try renderExpression(r, var_decl.ast.init_node, space); // ;
1245 ais.popIndent();1263 ais.popIndent();
1246 }
1247 ais.pushIndentOneShot();
1248 return renderExpression(r, var_decl.ast.init_node, space); // ;
1249}1264}
12501265
1251fn renderIf(r: *Render, if_node: Ast.full.If, space: Space) Error!void {1266fn renderIf(r: *Render, if_node: Ast.full.If, space: Space) Error!void {
...@@ -1345,23 +1360,28 @@ fn renderThenElse(...@@ -1345,23 +1360,28 @@ fn renderThenElse(
1345 const then_expr_is_block = nodeIsBlock(node_tags[then_expr]);1360 const then_expr_is_block = nodeIsBlock(node_tags[then_expr]);
1346 const indent_then_expr = !then_expr_is_block and1361 const indent_then_expr = !then_expr_is_block and
1347 !tree.tokensOnSameLine(last_prefix_token, tree.firstToken(then_expr));1362 !tree.tokensOnSameLine(last_prefix_token, tree.firstToken(then_expr));
1348 if (indent_then_expr or (then_expr_is_block and ais.isLineOverIndented())) {1363
1349 ais.pushIndentNextLine();1364 if (indent_then_expr) try ais.pushIndent(.normal);
1365
1366 if (then_expr_is_block and ais.isLineOverIndented()) {
1367 ais.disableIndentCommitting();
1368 try renderToken(r, last_prefix_token, .newline);
1369 ais.enableIndentCommitting();
1370 } else if (indent_then_expr) {
1350 try renderToken(r, last_prefix_token, .newline);1371 try renderToken(r, last_prefix_token, .newline);
1351 ais.popIndent();
1352 } else {1372 } else {
1353 try renderToken(r, last_prefix_token, .space);1373 try renderToken(r, last_prefix_token, .space);
1354 }1374 }
13551375
1356 if (else_expr != 0) {1376 if (else_expr != 0) {
1357 if (indent_then_expr) {1377 if (indent_then_expr) {
1358 ais.pushIndent();
1359 try renderExpression(r, then_expr, .newline);1378 try renderExpression(r, then_expr, .newline);
1360 ais.popIndent();
1361 } else {1379 } else {
1362 try renderExpression(r, then_expr, .space);1380 try renderExpression(r, then_expr, .space);
1363 }1381 }
13641382
1383 if (indent_then_expr) ais.popIndent();
1384
1365 var last_else_token = else_token;1385 var last_else_token = else_token;
13661386
1367 if (maybe_error_token) |error_token| {1387 if (maybe_error_token) |error_token| {
...@@ -1375,20 +1395,17 @@ fn renderThenElse(...@@ -1375,20 +1395,17 @@ fn renderThenElse(
1375 !nodeIsBlock(node_tags[else_expr]) and1395 !nodeIsBlock(node_tags[else_expr]) and
1376 !nodeIsIfForWhileSwitch(node_tags[else_expr]);1396 !nodeIsIfForWhileSwitch(node_tags[else_expr]);
1377 if (indent_else_expr) {1397 if (indent_else_expr) {
1378 ais.pushIndentNextLine();1398 try ais.pushIndent(.normal);
1379 try renderToken(r, last_else_token, .newline);1399 try renderToken(r, last_else_token, .newline);
1400 try renderExpression(r, else_expr, space);
1380 ais.popIndent();1401 ais.popIndent();
1381 try renderExpressionIndented(r, else_expr, space);
1382 } else {1402 } else {
1383 try renderToken(r, last_else_token, .space);1403 try renderToken(r, last_else_token, .space);
1384 try renderExpression(r, else_expr, space);1404 try renderExpression(r, else_expr, space);
1385 }1405 }
1386 } else {1406 } else {
1387 if (indent_then_expr) {1407 try renderExpression(r, then_expr, space);
1388 try renderExpressionIndented(r, then_expr, space);1408 if (indent_then_expr) ais.popIndent();
1389 } else {
1390 try renderExpression(r, then_expr, space);
1391 }
1392 }1409 }
1393}1410}
13941411
...@@ -1414,7 +1431,7 @@ fn renderFor(r: *Render, for_node: Ast.full.For, space: Space) Error!void {...@@ -1414,7 +1431,7 @@ fn renderFor(r: *Render, for_node: Ast.full.For, space: Space) Error!void {
1414 var cur = for_node.payload_token;1431 var cur = for_node.payload_token;
1415 const pipe = std.mem.indexOfScalarPos(std.zig.Token.Tag, token_tags, cur, .pipe).?;1432 const pipe = std.mem.indexOfScalarPos(std.zig.Token.Tag, token_tags, cur, .pipe).?;
1416 if (token_tags[pipe - 1] == .comma) {1433 if (token_tags[pipe - 1] == .comma) {
1417 ais.pushIndentNextLine();1434 try ais.pushIndent(.normal);
1418 try renderToken(r, cur - 1, .newline); // |1435 try renderToken(r, cur - 1, .newline); // |
1419 while (true) {1436 while (true) {
1420 if (token_tags[cur] == .asterisk) {1437 if (token_tags[cur] == .asterisk) {
...@@ -1542,25 +1559,24 @@ fn renderContainerField(...@@ -1542,25 +1559,24 @@ fn renderContainerField(
1542 }1559 }
1543 const eq_token = tree.firstToken(field.ast.value_expr) - 1;1560 const eq_token = tree.firstToken(field.ast.value_expr) - 1;
1544 const eq_space: Space = if (tree.tokensOnSameLine(eq_token, eq_token + 1)) .space else .newline;1561 const eq_space: Space = if (tree.tokensOnSameLine(eq_token, eq_token + 1)) .space else .newline;
1545 {1562
1546 ais.pushIndent();1563 try ais.pushIndent(.after_equals);
1547 try renderToken(r, eq_token, eq_space); // =1564 try renderToken(r, eq_token, eq_space); // =
1565
1566 if (eq_space == .space) {
1548 ais.popIndent();1567 ais.popIndent();
1568 try renderExpressionComma(r, field.ast.value_expr, space); // value
1569 return;
1549 }1570 }
15501571
1551 if (eq_space == .space)
1552 return renderExpressionComma(r, field.ast.value_expr, space); // value
1553
1554 const token_tags = tree.tokens.items(.tag);1572 const token_tags = tree.tokens.items(.tag);
1555 const maybe_comma = tree.lastToken(field.ast.value_expr) + 1;1573 const maybe_comma = tree.lastToken(field.ast.value_expr) + 1;
15561574
1557 if (token_tags[maybe_comma] == .comma) {1575 if (token_tags[maybe_comma] == .comma) {
1558 ais.pushIndent();
1559 try renderExpression(r, field.ast.value_expr, .none); // value1576 try renderExpression(r, field.ast.value_expr, .none); // value
1560 ais.popIndent();1577 ais.popIndent();
1561 try renderToken(r, maybe_comma, .newline);1578 try renderToken(r, maybe_comma, .newline);
1562 } else {1579 } else {
1563 ais.pushIndent();
1564 try renderExpression(r, field.ast.value_expr, space); // value1580 try renderExpression(r, field.ast.value_expr, space); // value
1565 ais.popIndent();1581 ais.popIndent();
1566 }1582 }
...@@ -1617,9 +1633,12 @@ fn renderBuiltinCall(...@@ -1617,9 +1633,12 @@ fn renderBuiltinCall(
1617 if (token_tags[first_param_token] == .multiline_string_literal_line or1633 if (token_tags[first_param_token] == .multiline_string_literal_line or
1618 hasSameLineComment(tree, first_param_token - 1))1634 hasSameLineComment(tree, first_param_token - 1))
1619 {1635 {
1620 ais.pushIndentOneShot();1636 try ais.pushIndent(.normal);
1637 try renderExpression(r, param_node, .none);
1638 ais.popIndent();
1639 } else {
1640 try renderExpression(r, param_node, .none);
1621 }1641 }
1622 try renderExpression(r, param_node, .none);
16231642
1624 if (i + 1 < params.len) {1643 if (i + 1 < params.len) {
1625 const comma_token = tree.lastToken(param_node) + 1;1644 const comma_token = tree.lastToken(param_node) + 1;
...@@ -1629,11 +1648,13 @@ fn renderBuiltinCall(...@@ -1629,11 +1648,13 @@ fn renderBuiltinCall(
1629 return renderToken(r, after_last_param_token, space); // )1648 return renderToken(r, after_last_param_token, space); // )
1630 } else {1649 } else {
1631 // Render one param per line.1650 // Render one param per line.
1632 ais.pushIndent();1651 try ais.pushIndent(.normal);
1633 try renderToken(r, builtin_token + 1, Space.newline); // (1652 try renderToken(r, builtin_token + 1, Space.newline); // (
16341653
1635 for (params) |param_node| {1654 for (params) |param_node| {
1655 try ais.pushSpace(.comma);
1636 try renderExpression(r, param_node, .comma);1656 try renderExpression(r, param_node, .comma);
1657 ais.popSpace();
1637 }1658 }
1638 ais.popIndent();1659 ais.popIndent();
16391660
...@@ -1755,7 +1776,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi...@@ -1755,7 +1776,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi
1755 }1776 }
1756 } else {1777 } else {
1757 // One param per line.1778 // One param per line.
1758 ais.pushIndent();1779 try ais.pushIndent(.normal);
1759 try renderToken(r, lparen, .newline); // (1780 try renderToken(r, lparen, .newline); // (
17601781
1761 var param_i: usize = 0;1782 var param_i: usize = 0;
...@@ -1801,7 +1822,9 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi...@@ -1801,7 +1822,9 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi
1801 }1822 }
1802 const param = fn_proto.ast.params[param_i];1823 const param = fn_proto.ast.params[param_i];
1803 param_i += 1;1824 param_i += 1;
1825 try ais.pushSpace(.comma);
1804 try renderExpression(r, param, .comma);1826 try renderExpression(r, param, .comma);
1827 ais.popSpace();
1805 last_param_token = tree.lastToken(param);1828 last_param_token = tree.lastToken(param);
1806 if (token_tags[last_param_token + 1] == .comma) last_param_token += 1;1829 if (token_tags[last_param_token + 1] == .comma) last_param_token += 1;
1807 }1830 }
...@@ -1864,6 +1887,7 @@ fn renderSwitchCase(...@@ -1864,6 +1887,7 @@ fn renderSwitchCase(
1864 switch_case: Ast.full.SwitchCase,1887 switch_case: Ast.full.SwitchCase,
1865 space: Space,1888 space: Space,
1866) Error!void {1889) Error!void {
1890 const ais = r.ais;
1867 const tree = r.tree;1891 const tree = r.tree;
1868 const node_tags = tree.nodes.items(.tag);1892 const node_tags = tree.nodes.items(.tag);
1869 const token_tags = tree.tokens.items(.tag);1893 const token_tags = tree.tokens.items(.tag);
...@@ -1883,7 +1907,9 @@ fn renderSwitchCase(...@@ -1883,7 +1907,9 @@ fn renderSwitchCase(
1883 try renderToken(r, switch_case.ast.arrow_token - 1, .space); // else keyword1907 try renderToken(r, switch_case.ast.arrow_token - 1, .space); // else keyword
1884 } else if (trailing_comma or has_comment_before_arrow) {1908 } else if (trailing_comma or has_comment_before_arrow) {
1885 // Render each value on a new line1909 // Render each value on a new line
1910 try ais.pushSpace(.comma);
1886 try renderExpressions(r, switch_case.ast.values, .comma);1911 try renderExpressions(r, switch_case.ast.values, .comma);
1912 ais.popSpace();
1887 } else {1913 } else {
1888 // Render on one line1914 // Render on one line
1889 for (switch_case.ast.values) |value_expr| {1915 for (switch_case.ast.values) |value_expr| {
...@@ -1936,7 +1962,7 @@ fn renderBlock(...@@ -1936,7 +1962,7 @@ fn renderBlock(
1936 try renderIdentifier(r, lbrace - 2, .none, .eagerly_unquote); // identifier1962 try renderIdentifier(r, lbrace - 2, .none, .eagerly_unquote); // identifier
1937 try renderToken(r, lbrace - 1, .space); // :1963 try renderToken(r, lbrace - 1, .space); // :
1938 }1964 }
1939 ais.pushIndentNextLine();1965 try ais.pushIndent(.normal);
1940 if (statements.len == 0) {1966 if (statements.len == 0) {
1941 try renderToken(r, lbrace, .none);1967 try renderToken(r, lbrace, .none);
1942 ais.popIndent();1968 ais.popIndent();
...@@ -1959,6 +1985,7 @@ fn finishRenderBlock(...@@ -1959,6 +1985,7 @@ fn finishRenderBlock(
1959 for (statements, 0..) |stmt, i| {1985 for (statements, 0..) |stmt, i| {
1960 if (i != 0) try renderExtraNewline(r, stmt);1986 if (i != 0) try renderExtraNewline(r, stmt);
1961 if (r.fixups.omit_nodes.contains(stmt)) continue;1987 if (r.fixups.omit_nodes.contains(stmt)) continue;
1988 try ais.pushSpace(.semicolon);
1962 switch (node_tags[stmt]) {1989 switch (node_tags[stmt]) {
1963 .global_var_decl,1990 .global_var_decl,
1964 .local_var_decl,1991 .local_var_decl,
...@@ -1968,6 +1995,7 @@ fn finishRenderBlock(...@@ -1968,6 +1995,7 @@ fn finishRenderBlock(
19681995
1969 else => try renderExpression(r, stmt, .semicolon),1996 else => try renderExpression(r, stmt, .semicolon),
1970 }1997 }
1998 ais.popSpace();
1971 }1999 }
1972 ais.popIndent();2000 ais.popIndent();
19732001
...@@ -1989,7 +2017,7 @@ fn renderStructInit(...@@ -1989,7 +2017,7 @@ fn renderStructInit(
1989 try renderExpression(r, struct_init.ast.type_expr, .none); // T2017 try renderExpression(r, struct_init.ast.type_expr, .none); // T
1990 }2018 }
1991 if (struct_init.ast.fields.len == 0) {2019 if (struct_init.ast.fields.len == 0) {
1992 ais.pushIndentNextLine();2020 try ais.pushIndent(.normal);
1993 try renderToken(r, struct_init.ast.lbrace, .none); // lbrace2021 try renderToken(r, struct_init.ast.lbrace, .none); // lbrace
1994 ais.popIndent();2022 ais.popIndent();
1995 return renderToken(r, struct_init.ast.lbrace + 1, space); // rbrace2023 return renderToken(r, struct_init.ast.lbrace + 1, space); // rbrace
...@@ -1999,7 +2027,7 @@ fn renderStructInit(...@@ -1999,7 +2027,7 @@ fn renderStructInit(
1999 const trailing_comma = token_tags[rbrace - 1] == .comma;2027 const trailing_comma = token_tags[rbrace - 1] == .comma;
2000 if (trailing_comma or hasComment(tree, struct_init.ast.lbrace, rbrace)) {2028 if (trailing_comma or hasComment(tree, struct_init.ast.lbrace, rbrace)) {
2001 // Render one field init per line.2029 // Render one field init per line.
2002 ais.pushIndentNextLine();2030 try ais.pushIndent(.normal);
2003 try renderToken(r, struct_init.ast.lbrace, .newline);2031 try renderToken(r, struct_init.ast.lbrace, .newline);
20042032
2005 try renderToken(r, struct_init.ast.lbrace + 1, .none); // .2033 try renderToken(r, struct_init.ast.lbrace + 1, .none); // .
...@@ -2011,7 +2039,10 @@ fn renderStructInit(...@@ -2011,7 +2039,10 @@ fn renderStructInit(
2011 const expr = nodes[field_node];2039 const expr = nodes[field_node];
2012 var space_after_equal: Space = if (expr == .multiline_string_literal) .none else .space;2040 var space_after_equal: Space = if (expr == .multiline_string_literal) .none else .space;
2013 try renderToken(r, struct_init.ast.lbrace + 3, space_after_equal); // =2041 try renderToken(r, struct_init.ast.lbrace + 3, space_after_equal); // =
2042
2043 try ais.pushSpace(.comma);
2014 try renderExpressionFixup(r, field_node, .comma);2044 try renderExpressionFixup(r, field_node, .comma);
2045 ais.popSpace();
20152046
2016 for (struct_init.ast.fields[1..]) |field_init| {2047 for (struct_init.ast.fields[1..]) |field_init| {
2017 const init_token = tree.firstToken(field_init);2048 const init_token = tree.firstToken(field_init);
...@@ -2020,7 +2051,10 @@ fn renderStructInit(...@@ -2020,7 +2051,10 @@ fn renderStructInit(
2020 try renderIdentifier(r, init_token - 2, .space, .eagerly_unquote); // name2051 try renderIdentifier(r, init_token - 2, .space, .eagerly_unquote); // name
2021 space_after_equal = if (nodes[field_init] == .multiline_string_literal) .none else .space;2052 space_after_equal = if (nodes[field_init] == .multiline_string_literal) .none else .space;
2022 try renderToken(r, init_token - 1, space_after_equal); // =2053 try renderToken(r, init_token - 1, space_after_equal); // =
2054
2055 try ais.pushSpace(.comma);
2023 try renderExpressionFixup(r, field_init, .comma);2056 try renderExpressionFixup(r, field_init, .comma);
2057 ais.popSpace();
2024 }2058 }
20252059
2026 ais.popIndent();2060 ais.popIndent();
...@@ -2057,7 +2091,7 @@ fn renderArrayInit(...@@ -2057,7 +2091,7 @@ fn renderArrayInit(
2057 }2091 }
20582092
2059 if (array_init.ast.elements.len == 0) {2093 if (array_init.ast.elements.len == 0) {
2060 ais.pushIndentNextLine();2094 try ais.pushIndent(.normal);
2061 try renderToken(r, array_init.ast.lbrace, .none); // lbrace2095 try renderToken(r, array_init.ast.lbrace, .none); // lbrace
2062 ais.popIndent();2096 ais.popIndent();
2063 return renderToken(r, array_init.ast.lbrace + 1, space); // rbrace2097 return renderToken(r, array_init.ast.lbrace + 1, space); // rbrace
...@@ -2099,7 +2133,7 @@ fn renderArrayInit(...@@ -2099,7 +2133,7 @@ fn renderArrayInit(
2099 return renderToken(r, last_elem_token + 1, space); // rbrace2133 return renderToken(r, last_elem_token + 1, space); // rbrace
2100 }2134 }
21012135
2102 ais.pushIndentNextLine();2136 try ais.pushIndent(.normal);
2103 try renderToken(r, array_init.ast.lbrace, .newline);2137 try renderToken(r, array_init.ast.lbrace, .newline);
21042138
2105 var expr_index: usize = 0;2139 var expr_index: usize = 0;
...@@ -2152,10 +2186,8 @@ fn renderArrayInit(...@@ -2152,10 +2186,8 @@ fn renderArrayInit(
2152 const sub_expr_buffer_starts = try gpa.alloc(usize, section_exprs.len + 1);2186 const sub_expr_buffer_starts = try gpa.alloc(usize, section_exprs.len + 1);
2153 defer gpa.free(sub_expr_buffer_starts);2187 defer gpa.free(sub_expr_buffer_starts);
21542188
2155 var auto_indenting_stream = Ais{2189 var auto_indenting_stream = Ais.init(&sub_expr_buffer, indent_delta);
2156 .indent_delta = indent_delta,2190 defer auto_indenting_stream.deinit();
2157 .underlying_writer = sub_expr_buffer.writer(),
2158 };
2159 var sub_render: Render = .{2191 var sub_render: Render = .{
2160 .gpa = r.gpa,2192 .gpa = r.gpa,
2161 .ais = &auto_indenting_stream,2193 .ais = &auto_indenting_stream,
...@@ -2192,7 +2224,10 @@ fn renderArrayInit(...@@ -2192,7 +2224,10 @@ fn renderArrayInit(
2192 column_counter = 0;2224 column_counter = 0;
2193 }2225 }
2194 } else {2226 } else {
2227 try ais.pushSpace(.comma);
2195 try renderExpression(&sub_render, expr, .comma);2228 try renderExpression(&sub_render, expr, .comma);
2229 ais.popSpace();
2230
2196 const width = sub_expr_buffer.items.len - start - 2;2231 const width = sub_expr_buffer.items.len - start - 2;
2197 const this_contains_newline = mem.indexOfScalar(u8, sub_expr_buffer.items[start .. sub_expr_buffer.items.len - 1], '\n') != null;2232 const this_contains_newline = mem.indexOfScalar(u8, sub_expr_buffer.items[start .. sub_expr_buffer.items.len - 1], '\n') != null;
2198 contains_newline = contains_newline or this_contains_newline;2233 contains_newline = contains_newline or this_contains_newline;
...@@ -2318,7 +2353,7 @@ fn renderContainerDecl(...@@ -2318,7 +2353,7 @@ fn renderContainerDecl(
23182353
2319 const rbrace = tree.lastToken(container_decl_node);2354 const rbrace = tree.lastToken(container_decl_node);
2320 if (container_decl.ast.members.len == 0) {2355 if (container_decl.ast.members.len == 0) {
2321 ais.pushIndentNextLine();2356 try ais.pushIndent(.normal);
2322 if (token_tags[lbrace + 1] == .container_doc_comment) {2357 if (token_tags[lbrace + 1] == .container_doc_comment) {
2323 try renderToken(r, lbrace, .newline); // lbrace2358 try renderToken(r, lbrace, .newline); // lbrace
2324 try renderContainerDocComments(r, lbrace + 1);2359 try renderContainerDocComments(r, lbrace + 1);
...@@ -2360,7 +2395,7 @@ fn renderContainerDecl(...@@ -2360,7 +2395,7 @@ fn renderContainerDecl(
2360 }2395 }
23612396
2362 // One member per line.2397 // One member per line.
2363 ais.pushIndentNextLine();2398 try ais.pushIndent(.normal);
2364 try renderToken(r, lbrace, .newline); // lbrace2399 try renderToken(r, lbrace, .newline); // lbrace
2365 if (token_tags[lbrace + 1] == .container_doc_comment) {2400 if (token_tags[lbrace + 1] == .container_doc_comment) {
2366 try renderContainerDocComments(r, lbrace + 1);2401 try renderContainerDocComments(r, lbrace + 1);
...@@ -2372,7 +2407,11 @@ fn renderContainerDecl(...@@ -2372,7 +2407,11 @@ fn renderContainerDecl(
2372 .container_field_init,2407 .container_field_init,
2373 .container_field_align,2408 .container_field_align,
2374 .container_field,2409 .container_field,
2375 => try renderMember(r, container, member, .comma),2410 => {
2411 try ais.pushSpace(.comma);
2412 try renderMember(r, container, member, .comma);
2413 ais.popSpace();
2414 },
23762415
2377 else => try renderMember(r, container, member, .newline),2416 else => try renderMember(r, container, member, .newline),
2378 }2417 }
...@@ -2401,7 +2440,7 @@ fn renderAsm(...@@ -2401,7 +2440,7 @@ fn renderAsm(
2401 }2440 }
24022441
2403 if (asm_node.ast.items.len == 0) {2442 if (asm_node.ast.items.len == 0) {
2404 ais.pushIndent();2443 try ais.forcePushIndent(.normal);
2405 if (asm_node.first_clobber) |first_clobber| {2444 if (asm_node.first_clobber) |first_clobber| {
2406 // asm ("foo" ::: "a", "b")2445 // asm ("foo" ::: "a", "b")
2407 // asm ("foo" ::: "a", "b",)2446 // asm ("foo" ::: "a", "b",)
...@@ -2439,7 +2478,7 @@ fn renderAsm(...@@ -2439,7 +2478,7 @@ fn renderAsm(
2439 }2478 }
2440 }2479 }
24412480
2442 ais.pushIndent();2481 try ais.forcePushIndent(.normal);
2443 try renderExpression(r, asm_node.ast.template, .newline);2482 try renderExpression(r, asm_node.ast.template, .newline);
2444 ais.setIndentDelta(asm_indent_delta);2483 ais.setIndentDelta(asm_indent_delta);
2445 const colon1 = tree.lastToken(asm_node.ast.template) + 1;2484 const colon1 = tree.lastToken(asm_node.ast.template) + 1;
...@@ -2450,7 +2489,7 @@ fn renderAsm(...@@ -2450,7 +2489,7 @@ fn renderAsm(
2450 } else colon2: {2489 } else colon2: {
2451 try renderToken(r, colon1, .space); // :2490 try renderToken(r, colon1, .space); // :
24522491
2453 ais.pushIndent();2492 try ais.forcePushIndent(.normal);
2454 for (asm_node.outputs, 0..) |asm_output, i| {2493 for (asm_node.outputs, 0..) |asm_output, i| {
2455 if (i + 1 < asm_node.outputs.len) {2494 if (i + 1 < asm_node.outputs.len) {
2456 const next_asm_output = asm_node.outputs[i + 1];2495 const next_asm_output = asm_node.outputs[i + 1];
...@@ -2460,13 +2499,17 @@ fn renderAsm(...@@ -2460,13 +2499,17 @@ fn renderAsm(
2460 try renderToken(r, comma, .newline); // ,2499 try renderToken(r, comma, .newline); // ,
2461 try renderExtraNewlineToken(r, tree.firstToken(next_asm_output));2500 try renderExtraNewlineToken(r, tree.firstToken(next_asm_output));
2462 } else if (asm_node.inputs.len == 0 and asm_node.first_clobber == null) {2501 } else if (asm_node.inputs.len == 0 and asm_node.first_clobber == null) {
2502 try ais.pushSpace(.comma);
2463 try renderAsmOutput(r, asm_output, .comma);2503 try renderAsmOutput(r, asm_output, .comma);
2504 ais.popSpace();
2464 ais.popIndent();2505 ais.popIndent();
2465 ais.setIndentDelta(indent_delta);2506 ais.setIndentDelta(indent_delta);
2466 ais.popIndent();2507 ais.popIndent();
2467 return renderToken(r, asm_node.ast.rparen, space); // rparen2508 return renderToken(r, asm_node.ast.rparen, space); // rparen
2468 } else {2509 } else {
2510 try ais.pushSpace(.comma);
2469 try renderAsmOutput(r, asm_output, .comma);2511 try renderAsmOutput(r, asm_output, .comma);
2512 ais.popSpace();
2470 const comma_or_colon = tree.lastToken(asm_output) + 1;2513 const comma_or_colon = tree.lastToken(asm_output) + 1;
2471 ais.popIndent();2514 ais.popIndent();
2472 break :colon2 switch (token_tags[comma_or_colon]) {2515 break :colon2 switch (token_tags[comma_or_colon]) {
...@@ -2482,7 +2525,7 @@ fn renderAsm(...@@ -2482,7 +2525,7 @@ fn renderAsm(
2482 break :colon3 colon2 + 1;2525 break :colon3 colon2 + 1;
2483 } else colon3: {2526 } else colon3: {
2484 try renderToken(r, colon2, .space); // :2527 try renderToken(r, colon2, .space); // :
2485 ais.pushIndent();2528 try ais.forcePushIndent(.normal);
2486 for (asm_node.inputs, 0..) |asm_input, i| {2529 for (asm_node.inputs, 0..) |asm_input, i| {
2487 if (i + 1 < asm_node.inputs.len) {2530 if (i + 1 < asm_node.inputs.len) {
2488 const next_asm_input = asm_node.inputs[i + 1];2531 const next_asm_input = asm_node.inputs[i + 1];
...@@ -2492,13 +2535,17 @@ fn renderAsm(...@@ -2492,13 +2535,17 @@ fn renderAsm(
2492 try renderToken(r, first_token - 1, .newline); // ,2535 try renderToken(r, first_token - 1, .newline); // ,
2493 try renderExtraNewlineToken(r, first_token);2536 try renderExtraNewlineToken(r, first_token);
2494 } else if (asm_node.first_clobber == null) {2537 } else if (asm_node.first_clobber == null) {
2538 try ais.pushSpace(.comma);
2495 try renderAsmInput(r, asm_input, .comma);2539 try renderAsmInput(r, asm_input, .comma);
2540 ais.popSpace();
2496 ais.popIndent();2541 ais.popIndent();
2497 ais.setIndentDelta(indent_delta);2542 ais.setIndentDelta(indent_delta);
2498 ais.popIndent();2543 ais.popIndent();
2499 return renderToken(r, asm_node.ast.rparen, space); // rparen2544 return renderToken(r, asm_node.ast.rparen, space); // rparen
2500 } else {2545 } else {
2546 try ais.pushSpace(.comma);
2501 try renderAsmInput(r, asm_input, .comma);2547 try renderAsmInput(r, asm_input, .comma);
2548 ais.popSpace();
2502 const comma_or_colon = tree.lastToken(asm_input) + 1;2549 const comma_or_colon = tree.lastToken(asm_input) + 1;
2503 ais.popIndent();2550 ais.popIndent();
2504 break :colon3 switch (token_tags[comma_or_colon]) {2551 break :colon3 switch (token_tags[comma_or_colon]) {
...@@ -2517,16 +2564,16 @@ fn renderAsm(...@@ -2517,16 +2564,16 @@ fn renderAsm(
2517 switch (token_tags[tok_i + 1]) {2564 switch (token_tags[tok_i + 1]) {
2518 .r_paren => {2565 .r_paren => {
2519 ais.setIndentDelta(indent_delta);2566 ais.setIndentDelta(indent_delta);
2520 ais.popIndent();
2521 try renderToken(r, tok_i, .newline);2567 try renderToken(r, tok_i, .newline);
2568 ais.popIndent();
2522 return renderToken(r, tok_i + 1, space);2569 return renderToken(r, tok_i + 1, space);
2523 },2570 },
2524 .comma => {2571 .comma => {
2525 switch (token_tags[tok_i + 2]) {2572 switch (token_tags[tok_i + 2]) {
2526 .r_paren => {2573 .r_paren => {
2527 ais.setIndentDelta(indent_delta);2574 ais.setIndentDelta(indent_delta);
2528 ais.popIndent();
2529 try renderToken(r, tok_i, .newline);2575 try renderToken(r, tok_i, .newline);
2576 ais.popIndent();
2530 return renderToken(r, tok_i + 2, space);2577 return renderToken(r, tok_i + 2, space);
2531 },2578 },
2532 else => {2579 else => {
...@@ -2564,7 +2611,7 @@ fn renderParamList(...@@ -2564,7 +2611,7 @@ fn renderParamList(
2564 const token_tags = tree.tokens.items(.tag);2611 const token_tags = tree.tokens.items(.tag);
25652612
2566 if (params.len == 0) {2613 if (params.len == 0) {
2567 ais.pushIndentNextLine();2614 try ais.pushIndent(.normal);
2568 try renderToken(r, lparen, .none);2615 try renderToken(r, lparen, .none);
2569 ais.popIndent();2616 ais.popIndent();
2570 return renderToken(r, lparen + 1, space); // )2617 return renderToken(r, lparen + 1, space); // )
...@@ -2573,40 +2620,29 @@ fn renderParamList(...@@ -2573,40 +2620,29 @@ fn renderParamList(
2573 const last_param = params[params.len - 1];2620 const last_param = params[params.len - 1];
2574 const after_last_param_tok = tree.lastToken(last_param) + 1;2621 const after_last_param_tok = tree.lastToken(last_param) + 1;
2575 if (token_tags[after_last_param_tok] == .comma) {2622 if (token_tags[after_last_param_tok] == .comma) {
2576 ais.pushIndentNextLine();2623 try ais.pushIndent(.normal);
2577 try renderToken(r, lparen, .newline); // (2624 try renderToken(r, lparen, .newline); // (
2578 for (params, 0..) |param_node, i| {2625 for (params, 0..) |param_node, i| {
2579 if (i + 1 < params.len) {2626 if (i + 1 < params.len) {
2580 try renderExpression(r, param_node, .none);2627 try renderExpression(r, param_node, .none);
25812628
2582 // Unindent the comma for multiline string literals.
2583 const is_multiline_string =
2584 token_tags[tree.firstToken(param_node)] == .multiline_string_literal_line;
2585 if (is_multiline_string) ais.popIndent();
2586
2587 const comma = tree.lastToken(param_node) + 1;2629 const comma = tree.lastToken(param_node) + 1;
2588 try renderToken(r, comma, .newline); // ,2630 try renderToken(r, comma, .newline); // ,
25892631
2590 if (is_multiline_string) ais.pushIndent();
2591
2592 try renderExtraNewline(r, params[i + 1]);2632 try renderExtraNewline(r, params[i + 1]);
2593 } else {2633 } else {
2634 try ais.pushSpace(.comma);
2594 try renderExpression(r, param_node, .comma);2635 try renderExpression(r, param_node, .comma);
2636 ais.popSpace();
2595 }2637 }
2596 }2638 }
2597 ais.popIndent();2639 ais.popIndent();
2598 return renderToken(r, after_last_param_tok + 1, space); // )2640 return renderToken(r, after_last_param_tok + 1, space); // )
2599 }2641 }
26002642
2643 try ais.pushIndent(.normal);
2601 try renderToken(r, lparen, .none); // (2644 try renderToken(r, lparen, .none); // (
2602
2603 for (params, 0..) |param_node, i| {2645 for (params, 0..) |param_node, i| {
2604 const first_param_token = tree.firstToken(param_node);
2605 if (token_tags[first_param_token] == .multiline_string_literal_line or
2606 hasSameLineComment(tree, first_param_token - 1))
2607 {
2608 ais.pushIndentOneShot();
2609 }
2610 try renderExpression(r, param_node, .none);2646 try renderExpression(r, param_node, .none);
26112647
2612 if (i + 1 < params.len) {2648 if (i + 1 < params.len) {
...@@ -2617,68 +2653,8 @@ fn renderParamList(...@@ -2617,68 +2653,8 @@ fn renderParamList(
2617 try renderToken(r, comma, comma_space);2653 try renderToken(r, comma, comma_space);
2618 }2654 }
2619 }2655 }
2620
2621 return renderToken(r, after_last_param_tok, space); // )
2622}
2623
2624/// Renders the given expression indented, popping the indent before rendering
2625/// any following line comments
2626fn renderExpressionIndented(r: *Render, node: Ast.Node.Index, space: Space) Error!void {
2627 const tree = r.tree;
2628 const ais = r.ais;
2629 const token_starts = tree.tokens.items(.start);
2630 const token_tags = tree.tokens.items(.tag);
2631
2632 ais.pushIndent();
2633
2634 var last_token = tree.lastToken(node);
2635 const punctuation = switch (space) {
2636 .none, .space, .newline, .skip => false,
2637 .comma => true,
2638 .comma_space => token_tags[last_token + 1] == .comma,
2639 .semicolon => token_tags[last_token + 1] == .semicolon,
2640 };
2641
2642 try renderExpression(r, node, if (punctuation) .none else .skip);
2643
2644 switch (space) {
2645 .none, .space, .newline, .skip => {},
2646 .comma => {
2647 if (token_tags[last_token + 1] == .comma) {
2648 try renderToken(r, last_token + 1, .skip);
2649 last_token += 1;
2650 } else {
2651 try ais.writer().writeByte(',');
2652 }
2653 },
2654 .comma_space => if (token_tags[last_token + 1] == .comma) {
2655 try renderToken(r, last_token + 1, .skip);
2656 last_token += 1;
2657 },
2658 .semicolon => if (token_tags[last_token + 1] == .semicolon) {
2659 try renderToken(r, last_token + 1, .skip);
2660 last_token += 1;
2661 },
2662 }
2663
2664 ais.popIndent();2656 ais.popIndent();
26652657 return renderToken(r, after_last_param_tok, space); // )
2666 if (space == .skip) return;
2667
2668 const comment_start = token_starts[last_token] + tokenSliceForRender(tree, last_token).len;
2669 const comment = try renderComments(r, comment_start, token_starts[last_token + 1]);
2670
2671 if (!comment) switch (space) {
2672 .none => {},
2673 .space,
2674 .comma_space,
2675 => try ais.writer().writeByte(' '),
2676 .newline,
2677 .comma,
2678 .semicolon,
2679 => try ais.insertNewline(),
2680 .skip => unreachable,
2681 };
2682}2658}
26832659
2684/// Render an expression, and the comma that follows it, if it is present in the source.2660/// Render an expression, and the comma that follows it, if it is present in the source.
...@@ -2752,6 +2728,16 @@ fn renderToken(r: *Render, token_index: Ast.TokenIndex, space: Space) Error!void...@@ -2752,6 +2728,16 @@ fn renderToken(r: *Render, token_index: Ast.TokenIndex, space: Space) Error!void
2752 try renderSpace(r, token_index, lexeme.len, space);2728 try renderSpace(r, token_index, lexeme.len, space);
2753}2729}
27542730
2731fn renderTokenOverrideSpaceMode(r: *Render, token_index: Ast.TokenIndex, space: Space, override_space: Space) Error!void {
2732 const tree = r.tree;
2733 const ais = r.ais;
2734 const lexeme = tokenSliceForRender(tree, token_index);
2735 try ais.writer().writeAll(lexeme);
2736 ais.enableSpaceMode(override_space);
2737 defer ais.disableSpaceMode();
2738 try renderSpace(r, token_index, lexeme.len, space);
2739}
2740
2755fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space: Space) Error!void {2741fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space: Space) Error!void {
2756 const tree = r.tree;2742 const tree = r.tree;
2757 const ais = r.ais;2743 const ais = r.ais;
...@@ -2765,7 +2751,8 @@ fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space...@@ -2765,7 +2751,8 @@ fn renderSpace(r: *Render, token_index: Ast.TokenIndex, lexeme_len: usize, space
2765 if (space == .comma and token_tags[token_index + 1] != .comma) {2751 if (space == .comma and token_tags[token_index + 1] != .comma) {
2766 try ais.writer().writeByte(',');2752 try ais.writer().writeByte(',');
2767 }2753 }
27682754 if (space == .semicolon or space == .comma) ais.enableSpaceMode(space);
2755 defer ais.disableSpaceMode();
2769 const comment = try renderComments(r, token_start + lexeme_len, token_starts[token_index + 1]);2756 const comment = try renderComments(r, token_start + lexeme_len, token_starts[token_index + 1]);
2770 switch (space) {2757 switch (space) {
2771 .none => {},2758 .none => {},
...@@ -3315,12 +3302,47 @@ fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usi...@@ -3315,12 +3302,47 @@ fn rowSize(tree: Ast, exprs: []const Ast.Node.Index, rtoken: Ast.TokenIndex) usi
33153302
3316/// Automatically inserts indentation of written data by keeping3303/// Automatically inserts indentation of written data by keeping
3317/// track of the current indentation level3304/// track of the current indentation level
3305///
3306/// We introduce a new indentation scope with pushIndent/popIndent whenever
3307/// we potentially want to introduce an indent after the next newline.
3308///
3309/// Indentation should only ever increment by one from one line to the next,
3310/// no matter how many new indentation scopes are introduced. This is done by
3311/// only realizing the indentation from the most recent scope. As an example:
3312///
3313/// while (foo) if (bar)
3314/// f(x);
3315///
3316/// The body of `while` introduces a new indentation scope and the body of
3317/// `if` also introduces a new indentation scope. When the newline is seen,
3318/// only the indentation scope of the `if` is realized, and the `while` is
3319/// not.
3320///
3321/// As comments are rendered during space rendering, we need to keep track
3322/// of the appropriate indentation level for them with pushSpace/popSpace.
3323/// This should be done whenever a scope that ends in a .semicolon or a
3324/// .comma is introduced.
3318fn AutoIndentingStream(comptime UnderlyingWriter: type) type {3325fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
3319 return struct {3326 return struct {
3320 const Self = @This();3327 const Self = @This();
3321 pub const WriteError = UnderlyingWriter.Error;3328 pub const WriteError = UnderlyingWriter.Error;
3322 pub const Writer = std.io.Writer(*Self, WriteError, write);3329 pub const Writer = std.io.Writer(*Self, WriteError, write);
33233330
3331 pub const IndentType = enum {
3332 normal,
3333 after_equals,
3334 binop,
3335 field_access,
3336 };
3337 const StackElem = struct {
3338 indent_type: IndentType,
3339 realized: bool,
3340 };
3341 const SpaceElem = struct {
3342 space: Space,
3343 indent_count: usize,
3344 };
3345
3324 underlying_writer: UnderlyingWriter,3346 underlying_writer: UnderlyingWriter,
33253347
3326 /// Offset into the source at which formatting has been disabled with3348 /// Offset into the source at which formatting has been disabled with
...@@ -3333,13 +3355,27 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {...@@ -3333,13 +3355,27 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
33333355
3334 indent_count: usize = 0,3356 indent_count: usize = 0,
3335 indent_delta: usize,3357 indent_delta: usize,
3358 indent_stack: std.ArrayList(StackElem),
3359 space_stack: std.ArrayList(SpaceElem),
3360 space_mode: ?usize = null,
3361 disable_indent_committing: usize = 0,
3336 current_line_empty: bool = true,3362 current_line_empty: bool = true,
3337 /// automatically popped when applied
3338 indent_one_shot_count: usize = 0,
3339 /// the most recently applied indent3363 /// the most recently applied indent
3340 applied_indent: usize = 0,3364 applied_indent: usize = 0,
3341 /// not used until the next line3365
3342 indent_next_line: usize = 0,3366 pub fn init(buffer: *std.ArrayList(u8), indent_delta_: usize) Self {
3367 return .{
3368 .underlying_writer = buffer.writer(),
3369 .indent_delta = indent_delta_,
3370 .indent_stack = std.ArrayList(StackElem).init(buffer.allocator),
3371 .space_stack = std.ArrayList(SpaceElem).init(buffer.allocator),
3372 };
3373 }
3374
3375 pub fn deinit(self: *Self) void {
3376 self.indent_stack.deinit();
3377 self.space_stack.deinit();
3378 }
33433379
3344 pub fn writer(self: *Self) Writer {3380 pub fn writer(self: *Self) Writer {
3345 return .{ .context = self };3381 return .{ .context = self };
...@@ -3384,7 +3420,73 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {...@@ -3384,7 +3420,73 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
33843420
3385 fn resetLine(self: *Self) void {3421 fn resetLine(self: *Self) void {
3386 self.current_line_empty = true;3422 self.current_line_empty = true;
3387 self.indent_next_line = 0;3423
3424 if (self.disable_indent_committing > 0) return;
3425
3426 if (self.indent_stack.items.len > 0) {
3427 // By default, we realize the most recent indentation scope.
3428 var to_realize = self.indent_stack.items.len - 1;
3429
3430 if (self.indent_stack.items.len >= 2 and
3431 self.indent_stack.items[to_realize - 1].indent_type == .after_equals and
3432 self.indent_stack.items[to_realize - 1].realized and
3433 self.indent_stack.items[to_realize].indent_type == .binop)
3434 {
3435 // If we are in a .binop scope and our direct parent is .after_equals, don't indent.
3436 // This ensures correct indentation in the below example:
3437 //
3438 // const foo =
3439 // (x >= 'a' and x <= 'z') or //<-- we are here
3440 // (x >= 'A' and x <= 'Z');
3441 //
3442 return;
3443 }
3444
3445 if (self.indent_stack.items[to_realize].indent_type == .field_access) {
3446 // Only realize the top-most field_access in a chain.
3447 while (to_realize > 0 and self.indent_stack.items[to_realize - 1].indent_type == .field_access)
3448 to_realize -= 1;
3449 }
3450
3451 if (self.indent_stack.items[to_realize].realized) return;
3452 self.indent_stack.items[to_realize].realized = true;
3453 self.indent_count += 1;
3454 }
3455 }
3456
3457 /// Disables indentation level changes during the next newlines until re-enabled.
3458 pub fn disableIndentCommitting(self: *Self) void {
3459 self.disable_indent_committing += 1;
3460 }
3461
3462 pub fn enableIndentCommitting(self: *Self) void {
3463 assert(self.disable_indent_committing > 0);
3464 self.disable_indent_committing -= 1;
3465 }
3466
3467 pub fn pushSpace(self: *Self, space: Space) !void {
3468 try self.space_stack.append(.{ .space = space, .indent_count = self.indent_count });
3469 }
3470
3471 pub fn popSpace(self: *Self) void {
3472 _ = self.space_stack.pop();
3473 }
3474
3475 /// Sets current indentation level to be the same as that of the last pushSpace.
3476 pub fn enableSpaceMode(self: *Self, space: Space) void {
3477 if (self.space_stack.items.len == 0) return;
3478 const curr = self.space_stack.getLast();
3479 if (curr.space != space) return;
3480 self.space_mode = curr.indent_count;
3481 }
3482
3483 pub fn disableSpaceMode(self: *Self) void {
3484 self.space_mode = null;
3485 }
3486
3487 pub fn lastSpaceModeIndent(self: *Self) usize {
3488 if (self.space_stack.items.len == 0) return 0;
3489 return self.space_stack.getLast().indent_count * self.indent_delta;
3388 }3490 }
33893491
3390 /// Insert a newline unless the current line is blank3492 /// Insert a newline unless the current line is blank
...@@ -3396,36 +3498,25 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {...@@ -3396,36 +3498,25 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
3396 /// Push default indentation3498 /// Push default indentation
3397 /// Doesn't actually write any indentation.3499 /// Doesn't actually write any indentation.
3398 /// Just primes the stream to be able to write the correct indentation if it needs to.3500 /// Just primes the stream to be able to write the correct indentation if it needs to.
3399 pub fn pushIndent(self: *Self) void {3501 pub fn pushIndent(self: *Self, indent_type: IndentType) !void {
3400 self.indent_count += 1;3502 try self.indent_stack.append(.{ .indent_type = indent_type, .realized = false });
3401 }3503 }
34023504
3403 /// Push an indent that is automatically popped after being applied3505 /// Forces an indentation level to be realized.
3404 pub fn pushIndentOneShot(self: *Self) void {3506 pub fn forcePushIndent(self: *Self, indent_type: IndentType) !void {
3405 self.indent_one_shot_count += 1;3507 try self.indent_stack.append(.{ .indent_type = indent_type, .realized = true });
3406 self.pushIndent();3508 self.indent_count += 1;
3407 }
3408
3409 /// Turns all one-shot indents into regular indents
3410 /// Returns number of indents that must now be manually popped
3411 pub fn lockOneShotIndent(self: *Self) usize {
3412 const locked_count = self.indent_one_shot_count;
3413 self.indent_one_shot_count = 0;
3414 return locked_count;
3415 }
3416
3417 /// Push an indent that should not take effect until the next line
3418 pub fn pushIndentNextLine(self: *Self) void {
3419 self.indent_next_line += 1;
3420 self.pushIndent();
3421 }3509 }
34223510
3423 pub fn popIndent(self: *Self) void {3511 pub fn popIndent(self: *Self) void {
3424 assert(self.indent_count != 0);3512 if (self.indent_stack.pop().?.realized) {
3425 self.indent_count -= 1;3513 assert(self.indent_count > 0);
3514 self.indent_count -= 1;
3515 }
3516 }
34263517
3427 if (self.indent_next_line > 0)3518 pub fn indentStackEmpty(self: *Self) bool {
3428 self.indent_next_line -= 1;3519 return self.indent_stack.items.len == 0;
3429 }3520 }
34303521
3431 /// Writes ' ' bytes if the current line is empty3522 /// Writes ' ' bytes if the current line is empty
...@@ -3437,9 +3528,6 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {...@@ -3437,9 +3528,6 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
3437 }3528 }
3438 self.applied_indent = current_indent;3529 self.applied_indent = current_indent;
3439 }3530 }
3440
3441 self.indent_count -= self.indent_one_shot_count;
3442 self.indent_one_shot_count = 0;
3443 self.current_line_empty = false;3531 self.current_line_empty = false;
3444 }3532 }
34453533
...@@ -3450,12 +3538,8 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {...@@ -3450,12 +3538,8 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
3450 }3538 }
34513539
3452 fn currentIndent(self: *Self) usize {3540 fn currentIndent(self: *Self) usize {
3453 var indent_current: usize = 0;3541 const indent_count = self.space_mode orelse self.indent_count;
3454 if (self.indent_count > 0) {3542 return indent_count * self.indent_delta;
3455 const indent_count = self.indent_count - self.indent_next_line;
3456 indent_current = indent_count * self.indent_delta;
3457 }
3458 return indent_current;
3459 }3543 }
3460 };3544 };
3461}3545}
src/Sema.zig+11-11
...@@ -23443,7 +23443,7 @@ fn ptrCastFull(...@@ -23443,7 +23443,7 @@ fn ptrCastFull(
23443 errdefer msg.destroy(sema.gpa);23443 errdefer msg.destroy(sema.gpa);
23444 if (dest_info.flags.size == .many and23444 if (dest_info.flags.size == .many and
23445 (src_info.flags.size == .slice or23445 (src_info.flags.size == .slice or
23446 (src_info.flags.size == .one and Type.fromInterned(src_info.child).zigTypeTag(zcu) == .array)))23446 (src_info.flags.size == .one and Type.fromInterned(src_info.child).zigTypeTag(zcu) == .array)))
23447 {23447 {
23448 try sema.errNote(src, msg, "use 'ptr' field to convert slice to many pointer", .{});23448 try sema.errNote(src, msg, "use 'ptr' field to convert slice to many pointer", .{});
23449 } else {23449 } else {
...@@ -28136,9 +28136,9 @@ fn fieldCallBind(...@@ -28136,9 +28136,9 @@ fn fieldCallBind(
28136 const first_param_type = Type.fromInterned(func_type.param_types.get(ip)[0]);28136 const first_param_type = Type.fromInterned(func_type.param_types.get(ip)[0]);
28137 if (first_param_type.isGenericPoison() or28137 if (first_param_type.isGenericPoison() or
28138 (first_param_type.zigTypeTag(zcu) == .pointer and28138 (first_param_type.zigTypeTag(zcu) == .pointer and
28139 (first_param_type.ptrSize(zcu) == .one or28139 (first_param_type.ptrSize(zcu) == .one or
28140 first_param_type.ptrSize(zcu) == .c) and28140 first_param_type.ptrSize(zcu) == .c) and
28141 first_param_type.childType(zcu).eql(concrete_ty, zcu)))28141 first_param_type.childType(zcu).eql(concrete_ty, zcu)))
28142 {28142 {
28143 // Note that if the param type is generic poison, we know that it must28143 // Note that if the param type is generic poison, we know that it must
28144 // specifically be `anytype` since it's the first parameter, meaning we28144 // specifically be `anytype` since it's the first parameter, meaning we
...@@ -29652,7 +29652,7 @@ fn coerceExtra(...@@ -29652,7 +29652,7 @@ fn coerceExtra(
2965229652
29653 if (dest_info.sentinel == .none or inst_info.sentinel == .none or29653 if (dest_info.sentinel == .none or inst_info.sentinel == .none or
29654 Air.internedToRef(dest_info.sentinel) !=29654 Air.internedToRef(dest_info.sentinel) !=
29655 try sema.coerceInMemory(Value.fromInterned(inst_info.sentinel), Type.fromInterned(dest_info.child)))29655 try sema.coerceInMemory(Value.fromInterned(inst_info.sentinel), Type.fromInterned(dest_info.child)))
29656 break :p;29656 break :p;
2965729657
29658 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);29658 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
...@@ -30492,12 +30492,12 @@ pub fn coerceInMemoryAllowed(...@@ -30492,12 +30492,12 @@ pub fn coerceInMemoryAllowed(
30492 }30492 }
30493 const ok_sent = (dest_info.sentinel == null and src_info.sentinel == null) or30493 const ok_sent = (dest_info.sentinel == null and src_info.sentinel == null) or
30494 (src_info.sentinel != null and30494 (src_info.sentinel != null and
30495 dest_info.sentinel != null and30495 dest_info.sentinel != null and
30496 dest_info.sentinel.?.eql(30496 dest_info.sentinel.?.eql(
30497 try pt.getCoerced(src_info.sentinel.?, dest_info.elem_type),30497 try pt.getCoerced(src_info.sentinel.?, dest_info.elem_type),
30498 dest_info.elem_type,30498 dest_info.elem_type,
30499 zcu,30499 zcu,
30500 ));30500 ));
30501 if (!ok_sent) {30501 if (!ok_sent) {
30502 return .{ .array_sentinel = .{30502 return .{ .array_sentinel = .{
30503 .actual = src_info.sentinel orelse Value.@"unreachable",30503 .actual = src_info.sentinel orelse Value.@"unreachable",
src/Type.zig+6-5
...@@ -610,11 +610,12 @@ pub fn hasRuntimeBitsInner(...@@ -610,11 +610,12 @@ pub fn hasRuntimeBitsInner(
610 // in which case we want control flow to continue down below.610 // in which case we want control flow to continue down below.
611 if (tag_ty != .none and611 if (tag_ty != .none and
612 try Type.fromInterned(tag_ty).hasRuntimeBitsInner(612 try Type.fromInterned(tag_ty).hasRuntimeBitsInner(
613 ignore_comptime_only,613 ignore_comptime_only,
614 strat,614 strat,
615 zcu,615 zcu,
616 tid,616 tid,
617 )) {617 ))
618 {
618 return true;619 return true;
619 }620 }
620 },621 },
src/Zcu.zig+4-4
...@@ -1496,8 +1496,8 @@ pub const SrcLoc = struct {...@@ -1496,8 +1496,8 @@ pub const SrcLoc = struct {
1496 const case = tree.fullSwitchCase(case_node).?;1496 const case = tree.fullSwitchCase(case_node).?;
1497 const is_special = (case.ast.values.len == 0) or1497 const is_special = (case.ast.values.len == 0) or
1498 (case.ast.values.len == 1 and1498 (case.ast.values.len == 1 and
1499 node_tags[case.ast.values[0]] == .identifier and1499 node_tags[case.ast.values[0]] == .identifier and
1500 mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_"));1500 mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_"));
1501 if (!is_special) continue;1501 if (!is_special) continue;
15021502
1503 return tree.nodeToSpan(case_node);1503 return tree.nodeToSpan(case_node);
...@@ -1516,8 +1516,8 @@ pub const SrcLoc = struct {...@@ -1516,8 +1516,8 @@ pub const SrcLoc = struct {
1516 const case = tree.fullSwitchCase(case_node).?;1516 const case = tree.fullSwitchCase(case_node).?;
1517 const is_special = (case.ast.values.len == 0) or1517 const is_special = (case.ast.values.len == 0) or
1518 (case.ast.values.len == 1 and1518 (case.ast.values.len == 1 and
1519 node_tags[case.ast.values[0]] == .identifier and1519 node_tags[case.ast.values[0]] == .identifier and
1520 mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_"));1520 mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_"));
1521 if (is_special) continue;1521 if (is_special) continue;
15221522
1523 for (case.ast.values) |item_node| {1523 for (case.ast.values) |item_node| {
src/arch/riscv64/CodeGen.zig+10-11
...@@ -685,8 +685,7 @@ fn restoreState(func: *Func, state: State, deaths: []const Air.Inst.Index, compt...@@ -685,8 +685,7 @@ fn restoreState(func: *Func, state: State, deaths: []const Air.Inst.Index, compt
685685
686 const ExpectedContents = [@typeInfo(RegisterManager.TrackedRegisters).array.len]RegisterLock;686 const ExpectedContents = [@typeInfo(RegisterManager.TrackedRegisters).array.len]RegisterLock;
687 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =687 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =
688 if (opts.update_tracking)688 if (opts.update_tracking) {} else std.heap.stackFallback(@sizeOf(ExpectedContents), func.gpa);
689 {} else std.heap.stackFallback(@sizeOf(ExpectedContents), func.gpa);
690689
691 var reg_locks = if (opts.update_tracking) {} else try std.ArrayList(RegisterLock).initCapacity(690 var reg_locks = if (opts.update_tracking) {} else try std.ArrayList(RegisterLock).initCapacity(
692 stack.get(),691 stack.get(),
...@@ -2260,7 +2259,7 @@ fn airIntCast(func: *Func, inst: Air.Inst.Index) !void {...@@ -2260,7 +2259,7 @@ fn airIntCast(func: *Func, inst: Air.Inst.Index) !void {
22602259
2261 const dst_mcv = if (dst_int_info.bits <= src_storage_bits and2260 const dst_mcv = if (dst_int_info.bits <= src_storage_bits and
2262 math.divCeil(u16, dst_int_info.bits, 64) catch unreachable ==2261 math.divCeil(u16, dst_int_info.bits, 64) catch unreachable ==
2263 math.divCeil(u32, src_storage_bits, 64) catch unreachable and2262 math.divCeil(u32, src_storage_bits, 64) catch unreachable and
2264 func.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: {2263 func.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: {
2265 const dst_mcv = try func.allocRegOrMem(dst_ty, inst, true);2264 const dst_mcv = try func.allocRegOrMem(dst_ty, inst, true);
2266 try func.genCopy(min_ty, dst_mcv, src_mcv);2265 try func.genCopy(min_ty, dst_mcv, src_mcv);
...@@ -2311,9 +2310,9 @@ fn airNot(func: *Func, inst: Air.Inst.Index) !void {...@@ -2311,9 +2310,9 @@ fn airNot(func: *Func, inst: Air.Inst.Index) !void {
23112310
2312 const dst_reg: Register =2311 const dst_reg: Register =
2313 if (func.reuseOperand(inst, ty_op.operand, 0, operand) and operand == .register)2312 if (func.reuseOperand(inst, ty_op.operand, 0, operand) and operand == .register)
2314 operand.register2313 operand.register
2315 else2314 else
2316 (try func.allocRegOrMem(func.typeOfIndex(inst), inst, true)).register;2315 (try func.allocRegOrMem(func.typeOfIndex(inst), inst, true)).register;
23172316
2318 switch (ty.zigTypeTag(zcu)) {2317 switch (ty.zigTypeTag(zcu)) {
2319 .bool => {2318 .bool => {
...@@ -6222,11 +6221,11 @@ fn airAsm(func: *Func, inst: Air.Inst.Index) !void {...@@ -6222,11 +6221,11 @@ fn airAsm(func: *Func, inst: Air.Inst.Index) !void {
62226221
6223 const instruction: union(enum) { mnem: Mnemonic, pseudo: Pseudo } =6222 const instruction: union(enum) { mnem: Mnemonic, pseudo: Pseudo } =
6224 if (std.meta.stringToEnum(Mnemonic, mnem_str)) |mnem|6223 if (std.meta.stringToEnum(Mnemonic, mnem_str)) |mnem|
6225 .{ .mnem = mnem }6224 .{ .mnem = mnem }
6226 else if (std.meta.stringToEnum(Pseudo, mnem_str)) |pseudo|6225 else if (std.meta.stringToEnum(Pseudo, mnem_str)) |pseudo|
6227 .{ .pseudo = pseudo }6226 .{ .pseudo = pseudo }
6228 else6227 else
6229 return func.fail("invalid mnem str '{s}'", .{mnem_str});6228 return func.fail("invalid mnem str '{s}'", .{mnem_str});
62306229
6231 const Operand = union(enum) {6230 const Operand = union(enum) {
6232 none,6231 none,
src/arch/sparc64/CodeGen.zig+6-6
...@@ -4394,12 +4394,12 @@ fn processDeath(self: *Self, inst: Air.Inst.Index) void {...@@ -4394,12 +4394,12 @@ fn processDeath(self: *Self, inst: Air.Inst.Index) void {
43944394
4395/// Turns stack_offset MCV into a real SPARCv9 stack offset usable for asm.4395/// Turns stack_offset MCV into a real SPARCv9 stack offset usable for asm.
4396fn realStackOffset(off: u32) u32 {4396fn realStackOffset(off: u32) u32 {
4397 return off4397 return off +
4398 // SPARCv9 %sp points away from the stack by some amount.4398 // SPARCv9 %sp points away from the stack by some amount.
4399 + abi.stack_bias4399 abi.stack_bias +
4400 // The first couple bytes of each stack frame is reserved4400 // The first couple bytes of each stack frame is reserved
4401 // for ABI and hardware purposes.4401 // for ABI and hardware purposes.
4402 + abi.stack_reserved_area;4402 abi.stack_reserved_area;
4403 // Only after that we have the usable stack frame portion.4403 // Only after that we have the usable stack frame portion.
4404}4404}
44054405
src/arch/x86_64/CodeGen.zig+41-42
...@@ -82655,8 +82655,7 @@ fn restoreState(self: *CodeGen, state: State, deaths: []const Air.Inst.Index, co...@@ -82655,8 +82655,7 @@ fn restoreState(self: *CodeGen, state: State, deaths: []const Air.Inst.Index, co
8265582655
82656 const ExpectedContents = [@typeInfo(RegisterManager.TrackedRegisters).array.len]RegisterLock;82656 const ExpectedContents = [@typeInfo(RegisterManager.TrackedRegisters).array.len]RegisterLock;
82657 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =82657 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =
82658 if (opts.update_tracking)82658 if (opts.update_tracking) {} else std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
82659 {} else std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
8266082659
82661 var reg_locks = if (opts.update_tracking) {} else try std.ArrayList(RegisterLock).initCapacity(82660 var reg_locks = if (opts.update_tracking) {} else try std.ArrayList(RegisterLock).initCapacity(
82662 stack.get(),82661 stack.get(),
...@@ -83216,7 +83215,7 @@ fn airIntCast(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -83216,7 +83215,7 @@ fn airIntCast(self: *CodeGen, inst: Air.Inst.Index) !void {
83216 const dst_mcv = if ((if (src_mcv.getReg()) |src_reg| src_reg.class() == .general_purpose else src_abi_size > 8) and83215 const dst_mcv = if ((if (src_mcv.getReg()) |src_reg| src_reg.class() == .general_purpose else src_abi_size > 8) and
83217 dst_int_info.bits <= src_storage_bits and83216 dst_int_info.bits <= src_storage_bits and
83218 std.math.divCeil(u16, dst_int_info.bits, 64) catch unreachable ==83217 std.math.divCeil(u16, dst_int_info.bits, 64) catch unreachable ==
83219 std.math.divCeil(u32, src_storage_bits, 64) catch unreachable and83218 std.math.divCeil(u32, src_storage_bits, 64) catch unreachable and
83220 self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: {83219 self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: {
83221 const dst_mcv = try self.allocRegOrMem(inst, true);83220 const dst_mcv = try self.allocRegOrMem(inst, true);
83222 try self.genCopy(min_ty, dst_mcv, src_mcv, .{});83221 try self.genCopy(min_ty, dst_mcv, src_mcv, .{});
...@@ -84695,10 +84694,10 @@ fn genIntMulDivOpMir(self: *CodeGen, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCVa...@@ -84695,10 +84694,10 @@ fn genIntMulDivOpMir(self: *CodeGen, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCVa
84695 ._ => {84694 ._ => {
84696 const hi_reg: Register =84695 const hi_reg: Register =
84697 switch (bit_size) {84696 switch (bit_size) {
84698 8 => .ah,84697 8 => .ah,
84699 16, 32, 64 => .edx,84698 16, 32, 64 => .edx,
84700 else => unreachable,84699 else => unreachable,
84701 };84700 };
84702 try self.asmRegisterRegister(.{ ._, .xor }, hi_reg, hi_reg);84701 try self.asmRegisterRegister(.{ ._, .xor }, hi_reg, hi_reg);
84703 },84702 },
84704 .i_ => try self.asmOpOnly(.{ ._, switch (bit_size) {84703 .i_ => try self.asmOpOnly(.{ ._, switch (bit_size) {
...@@ -89019,9 +89018,9 @@ fn genShiftBinOpMir(...@@ -89019,9 +89018,9 @@ fn genShiftBinOpMir(
89019 .size = .fromSize(abi_size),89018 .size = .fromSize(abi_size),
89020 .disp = std.math.cast(i32, @as(i64, @bitCast(addr))) orelse89019 .disp = std.math.cast(i32, @as(i64, @bitCast(addr))) orelse
89021 return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{89020 return self.fail("TODO genShiftBinOpMir between {s} and {s}", .{
89022 @tagName(lhs_mcv),89021 @tagName(lhs_mcv),
89023 @tagName(shift_mcv),89022 @tagName(shift_mcv),
89024 }),89023 }),
89025 } },89024 } },
89026 },89025 },
89027 .indirect => |reg_off| .{89026 .indirect => |reg_off| .{
...@@ -89761,17 +89760,17 @@ fn genBinOp(...@@ -89761,17 +89760,17 @@ fn genBinOp(
8976189760
89762 const ordered_air: [2]Air.Inst.Ref = if (lhs_ty.isVector(zcu) and89761 const ordered_air: [2]Air.Inst.Ref = if (lhs_ty.isVector(zcu) and
89763 switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) {89762 switch (lhs_ty.childType(zcu).zigTypeTag(zcu)) {
89764 .bool => false,89763 .bool => false,
89765 .int => switch (air_tag) {89764 .int => switch (air_tag) {
89766 .cmp_lt, .cmp_gte => true,89765 .cmp_lt, .cmp_gte => true,
89767 else => false,89766 else => false,
89768 },89767 },
89769 .float => switch (air_tag) {89768 .float => switch (air_tag) {
89770 .cmp_gte, .cmp_gt => true,89769 .cmp_gte, .cmp_gt => true,
89771 else => false,89770 else => false,
89772 },89771 },
89773 else => unreachable,89772 else => unreachable,
89774 }) .{ rhs_air, lhs_air } else .{ lhs_air, rhs_air };89773 }) .{ rhs_air, lhs_air } else .{ lhs_air, rhs_air };
8977589774
89776 if (lhs_ty.isAbiInt(zcu)) for (ordered_air) |op_air| {89775 if (lhs_ty.isAbiInt(zcu)) for (ordered_air) |op_air| {
89777 switch (try self.resolveInst(op_air)) {89776 switch (try self.resolveInst(op_air)) {
...@@ -91776,13 +91775,13 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv...@@ -91776,13 +91775,13 @@ fn genIntMulComplexOpMir(self: *CodeGen, dst_ty: Type, dst_mcv: MCValue, src_mcv
91776 .size = .fromSize(abi_size),91775 .size = .fromSize(abi_size),
91777 .disp = std.math.cast(i32, @as(i64, @bitCast(addr))) orelse91776 .disp = std.math.cast(i32, @as(i64, @bitCast(addr))) orelse
91778 return self.asmRegisterRegister(91777 return self.asmRegisterRegister(
91779 .{ .i_, .mul },91778 .{ .i_, .mul },
91780 dst_alias,91779 dst_alias,
91781 registerAlias(91780 registerAlias(
91782 try self.copyToTmpRegister(dst_ty, resolved_src_mcv),91781 try self.copyToTmpRegister(dst_ty, resolved_src_mcv),
91783 abi_size,91782 abi_size,
91783 ),
91784 ),91784 ),
91785 ),
91786 } },91785 } },
91787 },91786 },
91788 .indirect => |reg_off| .{91787 .indirect => |reg_off| .{
...@@ -94101,9 +94100,9 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -94101,9 +94100,9 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
94101 std.mem.eql(u8, rest, "r,m") or std.mem.eql(u8, rest, "m,r"))94100 std.mem.eql(u8, rest, "r,m") or std.mem.eql(u8, rest, "m,r"))
94102 self.register_manager.tryAllocReg(maybe_inst, abi.RegisterClass.gp) orelse94101 self.register_manager.tryAllocReg(maybe_inst, abi.RegisterClass.gp) orelse
94103 if (output != .none)94102 if (output != .none)
94104 null94103 null
94105 else94104 else
94106 return self.fail("ran out of registers lowering inline asm", .{})94105 return self.fail("ran out of registers lowering inline asm", .{})
94107 else if (std.mem.startsWith(u8, rest, "{") and std.mem.endsWith(u8, rest, "}"))94106 else if (std.mem.startsWith(u8, rest, "{") and std.mem.endsWith(u8, rest, "}"))
94108 parseRegName(rest["{".len .. rest.len - "}".len]) orelse94107 parseRegName(rest["{".len .. rest.len - "}".len]) orelse
94109 return self.fail("invalid register constraint: '{s}'", .{constraint})94108 return self.fail("invalid register constraint: '{s}'", .{constraint})
...@@ -96965,9 +96964,9 @@ fn airAtomicLoad(self: *CodeGen, inst: Air.Inst.Index) !void {...@@ -96965,9 +96964,9 @@ fn airAtomicLoad(self: *CodeGen, inst: Air.Inst.Index) !void {
9696596964
96966 const dst_mcv =96965 const dst_mcv =
96967 if (self.reuseOperand(inst, atomic_load.ptr, 0, ptr_mcv))96966 if (self.reuseOperand(inst, atomic_load.ptr, 0, ptr_mcv))
96968 ptr_mcv96967 ptr_mcv
96969 else96968 else
96970 try self.allocRegOrMem(inst, true);96969 try self.allocRegOrMem(inst, true);
9697196970
96972 try self.load(dst_mcv, ptr_ty, ptr_mcv);96971 try self.load(dst_mcv, ptr_ty, ptr_mcv);
96973 return self.finishAir(inst, dst_mcv, .{ atomic_load.ptr, .none, .none });96972 return self.finishAir(inst, dst_mcv, .{ atomic_load.ptr, .none, .none });
...@@ -103712,9 +103711,9 @@ const Select = struct {...@@ -103712,9 +103711,9 @@ const Select = struct {
103712 if (cg.intInfo(ty.childType(zcu))) |int_info| int_info.signedness == .signed else false,103711 if (cg.intInfo(ty.childType(zcu))) |int_info| int_info.signedness == .signed else false,
103713 .signed_int_or_full_vec => |size| ty.isVector(zcu) and @divExact(size.bitSize(cg.target), 8) >= ty.abiSize(zcu) and103712 .signed_int_or_full_vec => |size| ty.isVector(zcu) and @divExact(size.bitSize(cg.target), 8) >= ty.abiSize(zcu) and
103714 if (cg.intInfo(ty.childType(zcu))) |int_info| switch (int_info.signedness) {103713 if (cg.intInfo(ty.childType(zcu))) |int_info| switch (int_info.signedness) {
103715 .signed => true,103714 .signed => true,
103716 .unsigned => int_info.bits >= 8 and std.math.isPowerOfTwo(int_info.bits),103715 .unsigned => int_info.bits >= 8 and std.math.isPowerOfTwo(int_info.bits),
103717 } else false,103716 } else false,
103718 .unsigned_int_vec => |size| ty.isVector(zcu) and @divExact(size.bitSize(cg.target), 8) >= ty.abiSize(zcu) and103717 .unsigned_int_vec => |size| ty.isVector(zcu) and @divExact(size.bitSize(cg.target), 8) >= ty.abiSize(zcu) and
103719 if (cg.intInfo(ty.childType(zcu))) |int_info| int_info.signedness == .unsigned else false,103718 if (cg.intInfo(ty.childType(zcu))) |int_info| int_info.signedness == .unsigned else false,
103720 .size => |size| @divExact(size.bitSize(cg.target), 8) >= ty.abiSize(zcu),103719 .size => |size| @divExact(size.bitSize(cg.target), 8) >= ty.abiSize(zcu),
...@@ -103736,26 +103735,26 @@ const Select = struct {...@@ -103736,26 +103735,26 @@ const Select = struct {
103736 if (cg.intInfo(ty.scalarType(zcu))) |int_info| of_is.is.bitSize(cg.target) >= int_info.bits else false,103735 if (cg.intInfo(ty.scalarType(zcu))) |int_info| of_is.is.bitSize(cg.target) >= int_info.bits else false,
103737 .scalar_signed_int => |of_is| @divExact(of_is.of.bitSize(cg.target), 8) >= cg.unalignedSize(ty) and103736 .scalar_signed_int => |of_is| @divExact(of_is.of.bitSize(cg.target), 8) >= cg.unalignedSize(ty) and
103738 if (cg.intInfo(ty.scalarType(zcu))) |int_info| int_info.signedness == .signed and103737 if (cg.intInfo(ty.scalarType(zcu))) |int_info| int_info.signedness == .signed and
103739 of_is.is.bitSize(cg.target) >= int_info.bits else false,103738 of_is.is.bitSize(cg.target) >= int_info.bits else false,
103740 .scalar_unsigned_int => |of_is| @divExact(of_is.of.bitSize(cg.target), 8) >= cg.unalignedSize(ty) and103739 .scalar_unsigned_int => |of_is| @divExact(of_is.of.bitSize(cg.target), 8) >= cg.unalignedSize(ty) and
103741 if (cg.intInfo(ty.scalarType(zcu))) |int_info| int_info.signedness == .unsigned and103740 if (cg.intInfo(ty.scalarType(zcu))) |int_info| int_info.signedness == .unsigned and
103742 of_is.is.bitSize(cg.target) >= int_info.bits else false,103741 of_is.is.bitSize(cg.target) >= int_info.bits else false,
103743 .multiple_scalar_int => |of_is| ty.abiSize(zcu) % @divExact(of_is.of.bitSize(cg.target), 8) == 0 and103742 .multiple_scalar_int => |of_is| ty.abiSize(zcu) % @divExact(of_is.of.bitSize(cg.target), 8) == 0 and
103744 if (cg.intInfo(ty.scalarType(zcu))) |int_info| of_is.is.bitSize(cg.target) >= int_info.bits else false,103743 if (cg.intInfo(ty.scalarType(zcu))) |int_info| of_is.is.bitSize(cg.target) >= int_info.bits else false,
103745 .multiple_scalar_signed_int => |of_is| ty.abiSize(zcu) % @divExact(of_is.of.bitSize(cg.target), 8) == 0 and103744 .multiple_scalar_signed_int => |of_is| ty.abiSize(zcu) % @divExact(of_is.of.bitSize(cg.target), 8) == 0 and
103746 if (cg.intInfo(ty.scalarType(zcu))) |int_info| int_info.signedness == .signed and103745 if (cg.intInfo(ty.scalarType(zcu))) |int_info| int_info.signedness == .signed and
103747 of_is.is.bitSize(cg.target) >= int_info.bits else false,103746 of_is.is.bitSize(cg.target) >= int_info.bits else false,
103748 .multiple_scalar_unsigned_int => |of_is| ty.abiSize(zcu) % @divExact(of_is.of.bitSize(cg.target), 8) == 0 and103747 .multiple_scalar_unsigned_int => |of_is| ty.abiSize(zcu) % @divExact(of_is.of.bitSize(cg.target), 8) == 0 and
103749 if (cg.intInfo(ty.scalarType(zcu))) |int_info| int_info.signedness == .unsigned and103748 if (cg.intInfo(ty.scalarType(zcu))) |int_info| int_info.signedness == .unsigned and
103750 of_is.is.bitSize(cg.target) >= int_info.bits else false,103749 of_is.is.bitSize(cg.target) >= int_info.bits else false,
103751 .multiple_scalar_exact_int => |of_is| ty.abiSize(zcu) % @divExact(of_is.of.bitSize(cg.target), 8) == 0 and103750 .multiple_scalar_exact_int => |of_is| ty.abiSize(zcu) % @divExact(of_is.of.bitSize(cg.target), 8) == 0 and
103752 if (cg.intInfo(ty.scalarType(zcu))) |int_info| of_is.is == int_info.bits else false,103751 if (cg.intInfo(ty.scalarType(zcu))) |int_info| of_is.is == int_info.bits else false,
103753 .multiple_scalar_exact_signed_int => |of_is| ty.abiSize(zcu) % @divExact(of_is.of.bitSize(cg.target), 8) == 0 and103752 .multiple_scalar_exact_signed_int => |of_is| ty.abiSize(zcu) % @divExact(of_is.of.bitSize(cg.target), 8) == 0 and
103754 if (cg.intInfo(ty.scalarType(zcu))) |int_info| int_info.signedness == .signed and103753 if (cg.intInfo(ty.scalarType(zcu))) |int_info| int_info.signedness == .signed and
103755 of_is.is == int_info.bits else false,103754 of_is.is == int_info.bits else false,
103756 .multiple_scalar_exact_unsigned_int => |of_is| ty.abiSize(zcu) % @divExact(of_is.of.bitSize(cg.target), 8) == 0 and103755 .multiple_scalar_exact_unsigned_int => |of_is| ty.abiSize(zcu) % @divExact(of_is.of.bitSize(cg.target), 8) == 0 and
103757 if (cg.intInfo(ty.scalarType(zcu))) |int_info| int_info.signedness == .unsigned and103756 if (cg.intInfo(ty.scalarType(zcu))) |int_info| int_info.signedness == .unsigned and
103758 of_is.is == int_info.bits else false,103757 of_is.is == int_info.bits else false,
103759 .scalar_remainder_int => |of_is| if (cg.intInfo(ty.scalarType(zcu))) |int_info|103758 .scalar_remainder_int => |of_is| if (cg.intInfo(ty.scalarType(zcu))) |int_info|
103760 of_is.is.bitSize(cg.target) >= (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1103759 of_is.is.bitSize(cg.target) >= (int_info.bits - 1) % of_is.of.bitSize(cg.target) + 1
103761 else103760 else
src/codegen.zig+1-1
...@@ -423,7 +423,7 @@ pub fn generateSymbol(...@@ -423,7 +423,7 @@ pub fn generateSymbol(
423423
424 const padding = abi_size -424 const padding = abi_size -
425 (math.cast(usize, Type.fromInterned(vector_type.child).abiSize(zcu) * vector_type.len) orelse425 (math.cast(usize, Type.fromInterned(vector_type.child).abiSize(zcu) * vector_type.len) orelse
426 return error.Overflow);426 return error.Overflow);
427 if (padding > 0) try code.appendNTimes(gpa, 0, padding);427 if (padding > 0) try code.appendNTimes(gpa, 0, padding);
428 }428 }
429 },429 },
src/codegen/c.zig+3-3
...@@ -1990,7 +1990,7 @@ pub const DeclGen = struct {...@@ -1990,7 +1990,7 @@ pub const DeclGen = struct {
1990 if (dest_bits <= 64 and src_bits <= 64) {1990 if (dest_bits <= 64 and src_bits <= 64) {
1991 const needs_cast = src_int_info == null or1991 const needs_cast = src_int_info == null or
1992 (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or1992 (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or
1993 dest_int_info.signedness != src_int_info.?.signedness);1993 dest_int_info.signedness != src_int_info.?.signedness);
1994 return !needs_cast and !src_is_ptr;1994 return !needs_cast and !src_is_ptr;
1995 } else return false;1995 } else return false;
1996 }1996 }
...@@ -2031,7 +2031,7 @@ pub const DeclGen = struct {...@@ -2031,7 +2031,7 @@ pub const DeclGen = struct {
2031 if (dest_bits <= 64 and src_bits <= 64) {2031 if (dest_bits <= 64 and src_bits <= 64) {
2032 const needs_cast = src_int_info == null or2032 const needs_cast = src_int_info == null or
2033 (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or2033 (toCIntBits(dest_int_info.bits) != toCIntBits(src_int_info.?.bits) or
2034 dest_int_info.signedness != src_int_info.?.signedness);2034 dest_int_info.signedness != src_int_info.?.signedness);
20352035
2036 if (needs_cast) {2036 if (needs_cast) {
2037 try w.writeByte('(');2037 try w.writeByte('(');
...@@ -4348,7 +4348,7 @@ fn airEquality(...@@ -4348,7 +4348,7 @@ fn airEquality(
4348 .aligned, .array, .vector, .fwd_decl, .function => unreachable,4348 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
4349 .aggregate => |aggregate| if (aggregate.fields.len == 2 and4349 .aggregate => |aggregate| if (aggregate.fields.len == 2 and
4350 (aggregate.fields.at(0, ctype_pool).name.index == .is_null or4350 (aggregate.fields.at(0, ctype_pool).name.index == .is_null or
4351 aggregate.fields.at(1, ctype_pool).name.index == .is_null))4351 aggregate.fields.at(1, ctype_pool).name.index == .is_null))
4352 {4352 {
4353 try f.writeCValueMember(writer, lhs, .{ .identifier = "is_null" });4353 try f.writeCValueMember(writer, lhs, .{ .identifier = "is_null" });
4354 try writer.writeAll(" || ");4354 try writer.writeAll(" || ");
src/codegen/c/Type.zig+34-35
...@@ -758,12 +758,12 @@ pub const Info = union(enum) {...@@ -758,12 +758,12 @@ pub const Info = union(enum) {
758 fn tag(pointer_info: Pointer) Pool.Tag {758 fn tag(pointer_info: Pointer) Pool.Tag {
759 return @enumFromInt(@intFromEnum(Pool.Tag.pointer) +759 return @enumFromInt(@intFromEnum(Pool.Tag.pointer) +
760 @as(u2, @bitCast(packed struct(u2) {760 @as(u2, @bitCast(packed struct(u2) {
761 @"const": bool,761 @"const": bool,
762 @"volatile": bool,762 @"volatile": bool,
763 }{763 }{
764 .@"const" = pointer_info.@"const",764 .@"const" = pointer_info.@"const",
765 .@"volatile" = pointer_info.@"volatile",765 .@"volatile" = pointer_info.@"volatile",
766 })));766 })));
767 }767 }
768 };768 };
769769
...@@ -887,24 +887,24 @@ pub const Info = union(enum) {...@@ -887,24 +887,24 @@ pub const Info = union(enum) {
887 pool_adapter.eql(lhs_vector_info.elem_ctype, rhs_info.vector.elem_ctype),887 pool_adapter.eql(lhs_vector_info.elem_ctype, rhs_info.vector.elem_ctype),
888 .fwd_decl => |lhs_fwd_decl_info| lhs_fwd_decl_info.tag == rhs_info.fwd_decl.tag and888 .fwd_decl => |lhs_fwd_decl_info| lhs_fwd_decl_info.tag == rhs_info.fwd_decl.tag and
889 switch (lhs_fwd_decl_info.name) {889 switch (lhs_fwd_decl_info.name) {
890 .anon => |lhs_anon| rhs_info.fwd_decl.name == .anon and lhs_anon.eqlAdapted(890 .anon => |lhs_anon| rhs_info.fwd_decl.name == .anon and lhs_anon.eqlAdapted(
891 lhs_pool,891 lhs_pool,
892 rhs_info.fwd_decl.name.anon,892 rhs_info.fwd_decl.name.anon,
893 rhs_pool,893 rhs_pool,
894 pool_adapter,894 pool_adapter,
895 ),895 ),
896 .index => |lhs_index| rhs_info.fwd_decl.name == .index and896 .index => |lhs_index| rhs_info.fwd_decl.name == .index and
897 lhs_index == rhs_info.fwd_decl.name.index,897 lhs_index == rhs_info.fwd_decl.name.index,
898 },898 },
899 .aggregate => |lhs_aggregate_info| lhs_aggregate_info.tag == rhs_info.aggregate.tag and899 .aggregate => |lhs_aggregate_info| lhs_aggregate_info.tag == rhs_info.aggregate.tag and
900 lhs_aggregate_info.@"packed" == rhs_info.aggregate.@"packed" and900 lhs_aggregate_info.@"packed" == rhs_info.aggregate.@"packed" and
901 switch (lhs_aggregate_info.name) {901 switch (lhs_aggregate_info.name) {
902 .anon => |lhs_anon| rhs_info.aggregate.name == .anon and902 .anon => |lhs_anon| rhs_info.aggregate.name == .anon and
903 lhs_anon.index == rhs_info.aggregate.name.anon.index and903 lhs_anon.index == rhs_info.aggregate.name.anon.index and
904 lhs_anon.id == rhs_info.aggregate.name.anon.id,904 lhs_anon.id == rhs_info.aggregate.name.anon.id,
905 .fwd_decl => |lhs_fwd_decl| rhs_info.aggregate.name == .fwd_decl and905 .fwd_decl => |lhs_fwd_decl| rhs_info.aggregate.name == .fwd_decl and
906 pool_adapter.eql(lhs_fwd_decl, rhs_info.aggregate.name.fwd_decl),906 pool_adapter.eql(lhs_fwd_decl, rhs_info.aggregate.name.fwd_decl),
907 } and lhs_aggregate_info.fields.eqlAdapted(907 } and lhs_aggregate_info.fields.eqlAdapted(
908 lhs_pool,908 lhs_pool,
909 rhs_info.aggregate.fields,909 rhs_info.aggregate.fields,
910 rhs_pool,910 rhs_pool,
...@@ -913,13 +913,12 @@ pub const Info = union(enum) {...@@ -913,13 +913,12 @@ pub const Info = union(enum) {
913 .function => |lhs_function_info| lhs_function_info.param_ctypes.len ==913 .function => |lhs_function_info| lhs_function_info.param_ctypes.len ==
914 rhs_info.function.param_ctypes.len and914 rhs_info.function.param_ctypes.len and
915 pool_adapter.eql(lhs_function_info.return_ctype, rhs_info.function.return_ctype) and915 pool_adapter.eql(lhs_function_info.return_ctype, rhs_info.function.return_ctype) and
916 for (0..lhs_function_info.param_ctypes.len) |param_index|916 for (0..lhs_function_info.param_ctypes.len) |param_index| {
917 {917 if (!pool_adapter.eql(
918 if (!pool_adapter.eql(918 lhs_function_info.param_ctypes.at(param_index, lhs_pool),
919 lhs_function_info.param_ctypes.at(param_index, lhs_pool),919 rhs_info.function.param_ctypes.at(param_index, rhs_pool),
920 rhs_info.function.param_ctypes.at(param_index, rhs_pool),920 )) break false;
921 )) break false;921 } else true,
922 } else true,
923 };922 };
924 }923 }
925};924};
...@@ -2301,13 +2300,13 @@ pub const Pool = struct {...@@ -2301,13 +2300,13 @@ pub const Pool = struct {
2301 const return_type = Type.fromInterned(func_info.return_type);2300 const return_type = Type.fromInterned(func_info.return_type);
2302 const return_ctype: CType =2301 const return_ctype: CType =
2303 if (!ip.isNoReturn(func_info.return_type)) try pool.fromType(2302 if (!ip.isNoReturn(func_info.return_type)) try pool.fromType(
2304 allocator,2303 allocator,
2305 scratch,2304 scratch,
2306 return_type,2305 return_type,
2307 pt,2306 pt,
2308 mod,2307 mod,
2309 kind.asParameter(),2308 kind.asParameter(),
2310 ) else .void;2309 ) else .void;
2311 for (0..func_info.param_types.len) |param_index| {2310 for (0..func_info.param_types.len) |param_index| {
2312 const param_type = Type.fromInterned(2311 const param_type = Type.fromInterned(
2313 func_info.param_types.get(ip)[param_index],2312 func_info.param_types.get(ip)[param_index],
src/codegen/llvm.zig+55-56
...@@ -388,7 +388,7 @@ const DataLayoutBuilder = struct {...@@ -388,7 +388,7 @@ const DataLayoutBuilder = struct {
388 self.target.cpu.arch != .riscv64 and388 self.target.cpu.arch != .riscv64 and
389 self.target.cpu.arch != .loongarch64 and389 self.target.cpu.arch != .loongarch64 and
390 !(self.target.cpu.arch == .aarch64 and390 !(self.target.cpu.arch == .aarch64 and
391 (self.target.os.tag == .uefi or self.target.os.tag == .windows)) and391 (self.target.os.tag == .uefi or self.target.os.tag == .windows)) and
392 self.target.cpu.arch != .bpfeb and self.target.cpu.arch != .bpfel) continue;392 self.target.cpu.arch != .bpfeb and self.target.cpu.arch != .bpfel) continue;
393 try writer.writeAll("-p");393 try writer.writeAll("-p");
394 if (info.llvm != .default) try writer.print("{d}", .{@intFromEnum(info.llvm)});394 if (info.llvm != .default) try writer.print("{d}", .{@intFromEnum(info.llvm)});
...@@ -859,55 +859,54 @@ pub const Object = struct {...@@ -859,55 +859,54 @@ pub const Object = struct {
859 builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = target }});859 builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = target }});
860860
861 const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref =861 const debug_compile_unit, const debug_enums_fwd_ref, const debug_globals_fwd_ref =
862 if (!builder.strip)862 if (!builder.strip) debug_info: {
863 debug_info: {863 // We fully resolve all paths at this point to avoid lack of
864 // We fully resolve all paths at this point to avoid lack of864 // source line info in stack traces or lack of debugging
865 // source line info in stack traces or lack of debugging865 // information which, if relative paths were used, would be
866 // information which, if relative paths were used, would be866 // very location dependent.
867 // very location dependent.867 // TODO: the only concern I have with this is WASI as either host or target, should
868 // TODO: the only concern I have with this is WASI as either host or target, should868 // we leave the paths as relative then?
869 // we leave the paths as relative then?869 // TODO: This is totally wrong. In dwarf, paths are encoded as relative to
870 // TODO: This is totally wrong. In dwarf, paths are encoded as relative to870 // a particular directory, and then the directory path is specified elsewhere.
871 // a particular directory, and then the directory path is specified elsewhere.871 // In the compiler frontend we have it stored correctly in this
872 // In the compiler frontend we have it stored correctly in this872 // way already, but here we throw all that sweet information
873 // way already, but here we throw all that sweet information873 // into the garbage can by converting into absolute paths. What
874 // into the garbage can by converting into absolute paths. What874 // a terrible tragedy.
875 // a terrible tragedy.875 const compile_unit_dir = blk: {
876 const compile_unit_dir = blk: {876 if (comp.zcu) |zcu| m: {
877 if (comp.zcu) |zcu| m: {877 const d = try zcu.main_mod.root.joinString(arena, "");
878 const d = try zcu.main_mod.root.joinString(arena, "");878 if (d.len == 0) break :m;
879 if (d.len == 0) break :m;879 if (std.fs.path.isAbsolute(d)) break :blk d;
880 if (std.fs.path.isAbsolute(d)) break :blk d;880 break :blk std.fs.realpathAlloc(arena, d) catch break :blk d;
881 break :blk std.fs.realpathAlloc(arena, d) catch break :blk d;881 }
882 }882 break :blk try std.process.getCwdAlloc(arena);
883 break :blk try std.process.getCwdAlloc(arena);883 };
884 };
885884
886 const debug_file = try builder.debugFile(885 const debug_file = try builder.debugFile(
887 try builder.metadataString(comp.root_name),886 try builder.metadataString(comp.root_name),
888 try builder.metadataString(compile_unit_dir),887 try builder.metadataString(compile_unit_dir),
889 );888 );
890889
891 const debug_enums_fwd_ref = try builder.debugForwardReference();890 const debug_enums_fwd_ref = try builder.debugForwardReference();
892 const debug_globals_fwd_ref = try builder.debugForwardReference();891 const debug_globals_fwd_ref = try builder.debugForwardReference();
893892
894 const debug_compile_unit = try builder.debugCompileUnit(893 const debug_compile_unit = try builder.debugCompileUnit(
895 debug_file,894 debug_file,
896 // Don't use the version string here; LLVM misparses it when it895 // Don't use the version string here; LLVM misparses it when it
897 // includes the git revision.896 // includes the git revision.
898 try builder.metadataStringFmt("zig {d}.{d}.{d}", .{897 try builder.metadataStringFmt("zig {d}.{d}.{d}", .{
899 build_options.semver.major,898 build_options.semver.major,
900 build_options.semver.minor,899 build_options.semver.minor,
901 build_options.semver.patch,900 build_options.semver.patch,
902 }),901 }),
903 debug_enums_fwd_ref,902 debug_enums_fwd_ref,
904 debug_globals_fwd_ref,903 debug_globals_fwd_ref,
905 .{ .optimized = comp.root_mod.optimize_mode != .Debug },904 .{ .optimized = comp.root_mod.optimize_mode != .Debug },
906 );905 );
907906
908 try builder.metadataNamed(try builder.metadataString("llvm.dbg.cu"), &.{debug_compile_unit});907 try builder.metadataNamed(try builder.metadataString("llvm.dbg.cu"), &.{debug_compile_unit});
909 break :debug_info .{ debug_compile_unit, debug_enums_fwd_ref, debug_globals_fwd_ref };908 break :debug_info .{ debug_compile_unit, debug_enums_fwd_ref, debug_globals_fwd_ref };
910 } else .{.none} ** 3;909 } else .{.none} ** 3;
911910
912 const obj = try arena.create(Object);911 const obj = try arena.create(Object);
913 obj.* = .{912 obj.* = .{
...@@ -2759,9 +2758,9 @@ pub const Object = struct {...@@ -2759,9 +2758,9 @@ pub const Object = struct {
27592758
2760 const full_fields: [2]Builder.Metadata =2759 const full_fields: [2]Builder.Metadata =
2761 if (layout.tag_align.compare(.gte, layout.payload_align))2760 if (layout.tag_align.compare(.gte, layout.payload_align))
2762 .{ debug_tag_type, debug_payload_type }2761 .{ debug_tag_type, debug_payload_type }
2763 else2762 else
2764 .{ debug_payload_type, debug_tag_type };2763 .{ debug_payload_type, debug_tag_type };
27652764
2766 const debug_tagged_union_type = try o.builder.debugStructType(2765 const debug_tagged_union_type = try o.builder.debugStructType(
2767 try o.builder.metadataString(name),2766 try o.builder.metadataString(name),
...@@ -4551,11 +4550,11 @@ pub const Object = struct {...@@ -4551,11 +4550,11 @@ pub const Object = struct {
4551 // instruction is followed by a `wrap_optional`, it will return this value4550 // instruction is followed by a `wrap_optional`, it will return this value
4552 // verbatim, and the result should test as non-null.4551 // verbatim, and the result should test as non-null.
4553 switch (zcu.getTarget().ptrBitWidth()) {4552 switch (zcu.getTarget().ptrBitWidth()) {
4554 16 => 0xaaaa,4553 16 => 0xaaaa,
4555 32 => 0xaaaaaaaa,4554 32 => 0xaaaaaaaa,
4556 64 => 0xaaaaaaaa_aaaaaaaa,4555 64 => 0xaaaaaaaa_aaaaaaaa,
4557 else => unreachable,4556 else => unreachable,
4558 };4557 };
4559 const llvm_usize = try o.lowerType(Type.usize);4558 const llvm_usize = try o.lowerType(Type.usize);
4560 const llvm_ptr_ty = try o.lowerType(ptr_ty);4559 const llvm_ptr_ty = try o.lowerType(ptr_ty);
4561 return o.builder.castConst(.inttoptr, try o.builder.intConst(llvm_usize, int), llvm_ptr_ty);4560 return o.builder.castConst(.inttoptr, try o.builder.intConst(llvm_usize, int), llvm_ptr_ty);
...@@ -9544,7 +9543,7 @@ pub const FuncGen = struct {...@@ -9544,7 +9543,7 @@ pub const FuncGen = struct {
95449543
9545 if (llvm_dest_ty.isStruct(&o.builder) or9544 if (llvm_dest_ty.isStruct(&o.builder) or
9546 ((operand_ty.zigTypeTag(zcu) == .vector or inst_ty.zigTypeTag(zcu) == .vector) and9545 ((operand_ty.zigTypeTag(zcu) == .vector or inst_ty.zigTypeTag(zcu) == .vector) and
9547 operand_ty.bitSize(zcu) != inst_ty.bitSize(zcu)))9546 operand_ty.bitSize(zcu) != inst_ty.bitSize(zcu)))
9548 {9547 {
9549 // Both our operand and our result are values, not pointers,9548 // Both our operand and our result are values, not pointers,
9550 // but LLVM won't let us bitcast struct values or vectors with padding bits.9549 // but LLVM won't let us bitcast struct values or vectors with padding bits.
src/fmt.zig+1
...@@ -214,6 +214,7 @@ const FmtError = error{...@@ -214,6 +214,7 @@ const FmtError = error{
214 Unseekable,214 Unseekable,
215 NotOpenForWriting,215 NotOpenForWriting,
216 UnsupportedEncoding,216 UnsupportedEncoding,
217 InvalidEncoding,
217 ConnectionResetByPeer,218 ConnectionResetByPeer,
218 SocketNotConnected,219 SocketNotConnected,
219 LockViolation,220 LockViolation,
src/link/Coff.zig+35-35
...@@ -3821,38 +3821,38 @@ const msdos_stub: [120]u8 = .{...@@ -3821,38 +3821,38 @@ const msdos_stub: [120]u8 = .{
3821 0x40, 0x00, // Absolute offset to relocation table. 64 matches the header size (all bytes before the MS-DOS stub program).3821 0x40, 0x00, // Absolute offset to relocation table. 64 matches the header size (all bytes before the MS-DOS stub program).
3822 0x00, 0x00, // Overlay number. Zero means this is the main executable.3822 0x00, 0x00, // Overlay number. Zero means this is the main executable.
3823}3823}
3824// Reserved words.3824 // Reserved words.
3825++ .{ 0x00, 0x00 } ** 43825 ++ .{ 0x00, 0x00 } ** 4
3826// OEM-related fields.3826 // OEM-related fields.
3827++ .{3827 ++ .{
3828 0x00, 0x00, // OEM identifier.3828 0x00, 0x00, // OEM identifier.
3829 0x00, 0x00, // OEM information.3829 0x00, 0x00, // OEM information.
3830}3830 }
3831// Reserved words.3831 // Reserved words.
3832++ .{ 0x00, 0x00 } ** 103832 ++ .{ 0x00, 0x00 } ** 10
3833// Address of the PE header (a long). This matches the size of this entire MS-DOS stub, so that's the address of what's after this MS-DOS stub.3833 // Address of the PE header (a long). This matches the size of this entire MS-DOS stub, so that's the address of what's after this MS-DOS stub.
3834++ .{ 0x78, 0x00, 0x00, 0x00 }3834 ++ .{ 0x78, 0x00, 0x00, 0x00 }
3835// What follows is a 16-bit x86 MS-DOS program of 7 instructions that prints the bytes after these instructions and then exits.3835 // What follows is a 16-bit x86 MS-DOS program of 7 instructions that prints the bytes after these instructions and then exits.
3836++ .{3836 ++ .{
3837 // Set the value of the data segment to the same value as the code segment.3837 // Set the value of the data segment to the same value as the code segment.
3838 0x0e, // push cs3838 0x0e, // push cs
3839 0x1f, // pop ds3839 0x1f, // pop ds
3840 // Set the DX register to the address of the message.3840 // Set the DX register to the address of the message.
3841 // If you count all bytes of these 7 instructions you get 14, so that's the address of what's after these instructions.3841 // If you count all bytes of these 7 instructions you get 14, so that's the address of what's after these instructions.
3842 0xba, 14, 0x00, // mov dx, 143842 0xba, 14, 0x00, // mov dx, 14
3843 // Set AH to the system call code for printing a message.3843 // Set AH to the system call code for printing a message.
3844 0xb4, 0x09, // mov ah, 0x093844 0xb4, 0x09, // mov ah, 0x09
3845 // Perform the system call to print the message.3845 // Perform the system call to print the message.
3846 0xcd, 0x21, // int 0x213846 0xcd, 0x21, // int 0x21
3847 // Set AH to 0x4c which is the system call code for exiting, and set AL to 0x01 which is the exit code.3847 // Set AH to 0x4c which is the system call code for exiting, and set AL to 0x01 which is the exit code.
3848 0xb8, 0x01, 0x4c, // mov ax, 0x4c013848 0xb8, 0x01, 0x4c, // mov ax, 0x4c01
3849 // Peform the system call to exit the program with exit code 1.3849 // Peform the system call to exit the program with exit code 1.
3850 0xcd, 0x21, // int 0x213850 0xcd, 0x21, // int 0x21
3851}3851 }
3852// Message to print.3852 // Message to print.
3853++ "This program cannot be run in DOS mode.".*3853 ++ "This program cannot be run in DOS mode.".*
3854// Message terminators.3854 // Message terminators.
3855++ .{3855 ++ .{
3856 '$', // We do not pass a length to the print system call; the string is terminated by this character.3856 '$', // We do not pass a length to the print system call; the string is terminated by this character.
3857 0x00, 0x00, // Terminating zero bytes.3857 0x00, 0x00, // Terminating zero bytes.
3858};3858 };
src/link/Dwarf.zig+24-24
...@@ -1995,30 +1995,30 @@ pub const WipNav = struct {...@@ -1995,30 +1995,30 @@ pub const WipNav = struct {
1995 errdefer _ = if (!decl_gop.found_existing) dwarf.decls.pop();1995 errdefer _ = if (!decl_gop.found_existing) dwarf.decls.pop();
1996 const was_generic_decl = decl_gop.found_existing and1996 const was_generic_decl = decl_gop.found_existing and
1997 switch (try dwarf.debug_info.declAbbrevCode(wip_nav.unit, decl_gop.value_ptr.*)) {1997 switch (try dwarf.debug_info.declAbbrevCode(wip_nav.unit, decl_gop.value_ptr.*)) {
1998 .null,1998 .null,
1999 .decl_alias,1999 .decl_alias,
2000 .decl_empty_enum,2000 .decl_empty_enum,
2001 .decl_enum,2001 .decl_enum,
2002 .decl_namespace_struct,2002 .decl_namespace_struct,
2003 .decl_struct,2003 .decl_struct,
2004 .decl_packed_struct,2004 .decl_packed_struct,
2005 .decl_union,2005 .decl_union,
2006 .decl_var,2006 .decl_var,
2007 .decl_const,2007 .decl_const,
2008 .decl_const_runtime_bits,2008 .decl_const_runtime_bits,
2009 .decl_const_comptime_state,2009 .decl_const_comptime_state,
2010 .decl_const_runtime_bits_comptime_state,2010 .decl_const_runtime_bits_comptime_state,
2011 .decl_empty_func,2011 .decl_empty_func,
2012 .decl_func,2012 .decl_func,
2013 .decl_empty_func_generic,2013 .decl_empty_func_generic,
2014 .decl_func_generic,2014 .decl_func_generic,
2015 => false,2015 => false,
2016 .generic_decl_var,2016 .generic_decl_var,
2017 .generic_decl_const,2017 .generic_decl_const,
2018 .generic_decl_func,2018 .generic_decl_func,
2019 => true,2019 => true,
2020 else => unreachable,2020 else => unreachable,
2021 };2021 };
2022 if (parent_type.getCaptures(zcu).len == 0) {2022 if (parent_type.getCaptures(zcu).len == 0) {
2023 if (was_generic_decl) try dwarf.freeCommonEntry(wip_nav.unit, decl_gop.value_ptr.*);2023 if (was_generic_decl) try dwarf.freeCommonEntry(wip_nav.unit, decl_gop.value_ptr.*);
2024 decl_gop.value_ptr.* = orig_entry;2024 decl_gop.value_ptr.* = orig_entry;
src/link/Elf/Object.zig+5-5
...@@ -236,11 +236,11 @@ pub fn validateEFlags(...@@ -236,11 +236,11 @@ pub fn validateEFlags(
236236
237 const fabi: riscv.Eflags.FloatAbi =237 const fabi: riscv.Eflags.FloatAbi =
238 if (std.Target.riscv.featureSetHas(features, .d))238 if (std.Target.riscv.featureSetHas(features, .d))
239 .double239 .double
240 else if (std.Target.riscv.featureSetHas(features, .f))240 else if (std.Target.riscv.featureSetHas(features, .f))
241 .single241 .single
242 else242 else
243 .soft;243 .soft;
244244
245 if (flags.fabi != fabi) {245 if (flags.fabi != fabi) {
246 any_errors = true;246 any_errors = true;
src/link/Elf/relocatable.zig+11-11
...@@ -217,20 +217,20 @@ fn initSections(elf_file: *Elf) !void {...@@ -217,20 +217,20 @@ fn initSections(elf_file: *Elf) !void {
217 if (elf_file.section_indexes.eh_frame == null) {217 if (elf_file.section_indexes.eh_frame == null) {
218 elf_file.section_indexes.eh_frame = elf_file.sectionByName(".eh_frame") orelse218 elf_file.section_indexes.eh_frame = elf_file.sectionByName(".eh_frame") orelse
219 try elf_file.addSection(.{219 try elf_file.addSection(.{
220 .name = try elf_file.insertShString(".eh_frame"),220 .name = try elf_file.insertShString(".eh_frame"),
221 .type = if (elf_file.getTarget().cpu.arch == .x86_64)221 .type = if (elf_file.getTarget().cpu.arch == .x86_64)
222 elf.SHT_X86_64_UNWIND222 elf.SHT_X86_64_UNWIND
223 else223 else
224 elf.SHT_PROGBITS,224 elf.SHT_PROGBITS,
225 .flags = elf.SHF_ALLOC,225 .flags = elf.SHF_ALLOC,
226 .addralign = elf_file.ptrWidthBytes(),226 .addralign = elf_file.ptrWidthBytes(),
227 });227 });
228 }228 }
229 elf_file.section_indexes.eh_frame_rela = elf_file.sectionByName(".rela.eh_frame") orelse229 elf_file.section_indexes.eh_frame_rela = elf_file.sectionByName(".rela.eh_frame") orelse
230 try elf_file.addRelaShdr(230 try elf_file.addRelaShdr(
231 try elf_file.insertShString(".rela.eh_frame"),231 try elf_file.insertShString(".rela.eh_frame"),
232 elf_file.section_indexes.eh_frame.?,232 elf_file.section_indexes.eh_frame.?,
233 );233 );
234 }234 }
235235
236 try initComdatGroups(elf_file);236 try initComdatGroups(elf_file);
src/link/Elf/synthetic_sections.zig+1-1
...@@ -551,7 +551,7 @@ pub const GotSection = struct {...@@ -551,7 +551,7 @@ pub const GotSection = struct {
551 switch (entry.tag) {551 switch (entry.tag) {
552 .got => if (symbol.?.flags.import or symbol.?.isIFunc(elf_file) or552 .got => if (symbol.?.flags.import or symbol.?.isIFunc(elf_file) or
553 ((elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) and553 ((elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) and
554 !symbol.?.isAbs(elf_file)))554 !symbol.?.isAbs(elf_file)))
555 {555 {
556 num += 1;556 num += 1;
557 },557 },
src/link/MachO.zig+8-8
...@@ -1617,14 +1617,14 @@ fn initOutputSections(self: *MachO) !void {...@@ -1617,14 +1617,14 @@ fn initOutputSections(self: *MachO) !void {
1617 }1617 }
1618 self.text_sect_index = self.getSectionByName("__TEXT", "__text") orelse1618 self.text_sect_index = self.getSectionByName("__TEXT", "__text") orelse
1619 try self.addSection("__TEXT", "__text", .{1619 try self.addSection("__TEXT", "__text", .{
1620 .alignment = switch (self.getTarget().cpu.arch) {1620 .alignment = switch (self.getTarget().cpu.arch) {
1621 .x86_64 => 0,1621 .x86_64 => 0,
1622 .aarch64 => 2,1622 .aarch64 => 2,
1623 else => unreachable,1623 else => unreachable,
1624 },1624 },
1625 .flags = macho.S_REGULAR |1625 .flags = macho.S_REGULAR |
1626 macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,1626 macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
1627 });1627 });
1628 self.data_sect_index = self.getSectionByName("__DATA", "__data") orelse1628 self.data_sect_index = self.getSectionByName("__DATA", "__data") orelse
1629 try self.addSection("__DATA", "__data", .{});1629 try self.addSection("__DATA", "__data", .{});
1630}1630}
src/link/MachO/Atom.zig+4-4
...@@ -149,10 +149,10 @@ pub fn initOutputSection(sect: macho.section_64, macho_file: *MachO) !u8 {...@@ -149,10 +149,10 @@ pub fn initOutputSection(sect: macho.section_64, macho_file: *MachO) !u8 {
149 if (macho_file.base.isRelocatable()) {149 if (macho_file.base.isRelocatable()) {
150 const osec = macho_file.getSectionByName(sect.segName(), sect.sectName()) orelse150 const osec = macho_file.getSectionByName(sect.segName(), sect.sectName()) orelse
151 try macho_file.addSection(151 try macho_file.addSection(
152 sect.segName(),152 sect.segName(),
153 sect.sectName(),153 sect.sectName(),
154 .{ .flags = sect.flags },154 .{ .flags = sect.flags },
155 );155 );
156 return osec;156 return osec;
157 }157 }
158158
src/link/MachO/ZigObject.zig+2-2
...@@ -1104,8 +1104,8 @@ fn createTlvDescriptor(...@@ -1104,8 +1104,8 @@ fn createTlvDescriptor(
11041104
1105 const sect_index = macho_file.getSectionByName("__DATA", "__thread_vars") orelse1105 const sect_index = macho_file.getSectionByName("__DATA", "__thread_vars") orelse
1106 try macho_file.addSection("__DATA", "__thread_vars", .{1106 try macho_file.addSection("__DATA", "__thread_vars", .{
1107 .flags = macho.S_THREAD_LOCAL_VARIABLES,1107 .flags = macho.S_THREAD_LOCAL_VARIABLES,
1108 });1108 });
1109 sym.out_n_sect = sect_index;1109 sym.out_n_sect = sect_index;
1110 atom.out_n_sect = sect_index;1110 atom.out_n_sect = sect_index;
11111111
src/link/MachO/dead_strip.zig+2-2
...@@ -102,8 +102,8 @@ fn mark(roots: []*Atom, objects: []const File.Index, macho_file: *MachO) void {...@@ -102,8 +102,8 @@ fn mark(roots: []*Atom, objects: []const File.Index, macho_file: *MachO) void {
102 const isec = atom.getInputSection(macho_file);102 const isec = atom.getInputSection(macho_file);
103 if (isec.isDontDeadStripIfReferencesLive() and103 if (isec.isDontDeadStripIfReferencesLive() and
104 !(mem.eql(u8, isec.sectName(), "__eh_frame") or104 !(mem.eql(u8, isec.sectName(), "__eh_frame") or
105 mem.eql(u8, isec.sectName(), "__compact_unwind") or105 mem.eql(u8, isec.sectName(), "__compact_unwind") or
106 isec.attrs() & macho.S_ATTR_DEBUG != 0) and106 isec.attrs() & macho.S_ATTR_DEBUG != 0) and
107 !atom.isAlive() and refersLive(atom, macho_file))107 !atom.isAlive() and refersLive(atom, macho_file))
108 {108 {
109 markLive(atom, macho_file);109 markLive(atom, macho_file);
src/main.zig+4-4
...@@ -5919,8 +5919,8 @@ pub const ClangArgIterator = struct {...@@ -5919,8 +5919,8 @@ pub const ClangArgIterator = struct {
59195919
5920 self.arg_iterator_response_file =5920 self.arg_iterator_response_file =
5921 initArgIteratorResponseFile(arena, resp_file_path) catch |err| {5921 initArgIteratorResponseFile(arena, resp_file_path) catch |err| {
5922 fatal("unable to read response file '{s}': {s}", .{ resp_file_path, @errorName(err) });5922 fatal("unable to read response file '{s}': {s}", .{ resp_file_path, @errorName(err) });
5923 };5923 };
5924 // NOTE: The ArgIteratorResponseFile returns tokens from next() that are slices of an5924 // NOTE: The ArgIteratorResponseFile returns tokens from next() that are slices of an
5925 // internal buffer. This internal buffer is arena allocated, so it is not cleaned up here.5925 // internal buffer. This internal buffer is arena allocated, so it is not cleaned up here.
59265926
...@@ -6233,8 +6233,8 @@ fn cmdAstCheck(...@@ -6233,8 +6233,8 @@ fn cmdAstCheck(
6233 file.tree.?.tokens.len * (@sizeOf(std.zig.Token.Tag) + @sizeOf(Ast.ByteOffset));6233 file.tree.?.tokens.len * (@sizeOf(std.zig.Token.Tag) + @sizeOf(Ast.ByteOffset));
6234 const tree_bytes = @sizeOf(Ast) + file.tree.?.nodes.len *6234 const tree_bytes = @sizeOf(Ast) + file.tree.?.nodes.len *
6235 (@sizeOf(Ast.Node.Tag) +6235 (@sizeOf(Ast.Node.Tag) +
6236 @sizeOf(Ast.Node.Data) +6236 @sizeOf(Ast.Node.Data) +
6237 @sizeOf(Ast.TokenIndex));6237 @sizeOf(Ast.TokenIndex));
6238 const instruction_bytes = file.zir.?.instructions.len *6238 const instruction_bytes = file.zir.?.instructions.len *
6239 // Here we don't use @sizeOf(Zir.Inst.Data) because it would include6239 // Here we don't use @sizeOf(Zir.Inst.Data) because it would include
6240 // the debug safety tag but we want to measure release size.6240 // the debug safety tag but we want to measure release size.
src/translate_c.zig+14-15
...@@ -2570,9 +2570,9 @@ fn transInitListExprRecord(...@@ -2570,9 +2570,9 @@ fn transInitListExprRecord(
2570 // Unions and Structs are both represented as RecordDecl2570 // Unions and Structs are both represented as RecordDecl
2571 const record_ty = ty.getAsRecordType() orelse2571 const record_ty = ty.getAsRecordType() orelse
2572 blk: {2572 blk: {
2573 is_union_type = true;2573 is_union_type = true;
2574 break :blk ty.getAsUnionType();2574 break :blk ty.getAsUnionType();
2575 } orelse unreachable;2575 } orelse unreachable;
2576 const record_decl = record_ty.getDecl();2576 const record_decl = record_ty.getDecl();
2577 const record_def = record_decl.getDefinition() orelse2577 const record_def = record_decl.getDefinition() orelse
2578 unreachable;2578 unreachable;
...@@ -4006,7 +4006,7 @@ fn transCPtrCast(...@@ -4006,7 +4006,7 @@ fn transCPtrCast(
4006 if (!src_ty.isArrayType() and ((src_child_type.isConstQualified() and4006 if (!src_ty.isArrayType() and ((src_child_type.isConstQualified() and
4007 !child_type.isConstQualified()) or4007 !child_type.isConstQualified()) or
4008 (src_child_type.isVolatileQualified() and4008 (src_child_type.isVolatileQualified() and
4009 !child_type.isVolatileQualified())))4009 !child_type.isVolatileQualified())))
4010 {4010 {
4011 return removeCVQualifiers(c, dst_type_node, expr);4011 return removeCVQualifiers(c, dst_type_node, expr);
4012 } else {4012 } else {
...@@ -4092,8 +4092,8 @@ fn transFloatingLiteralQuad(c: *Context, expr: *const clang.FloatingLiteral, use...@@ -4092,8 +4092,8 @@ fn transFloatingLiteralQuad(c: *Context, expr: *const clang.FloatingLiteral, use
4092 false;4092 false;
4093 break :fmt_decimal if (could_roundtrip) try c.arena.dupe(u8, temp_str) else null;4093 break :fmt_decimal if (could_roundtrip) try c.arena.dupe(u8, temp_str) else null;
4094 }4094 }
4095 // otherwise, fall back to the hexadecimal format4095 // otherwise, fall back to the hexadecimal format
4096 orelse try std.fmt.allocPrint(c.arena, "{x}", .{quad});4096 orelse try std.fmt.allocPrint(c.arena, "{x}", .{quad});
40974097
4098 var node = try Tag.float_literal.create(c.arena, str);4098 var node = try Tag.float_literal.create(c.arena, str);
4099 if (is_negative) node = try Tag.negate.create(c.arena, node);4099 if (is_negative) node = try Tag.negate.create(c.arena, node);
...@@ -5080,15 +5080,14 @@ fn finishTransFnProto(...@@ -5080,15 +5080,14 @@ fn finishTransFnProto(
5080 const is_noalias = param_qt.isRestrictQualified();5080 const is_noalias = param_qt.isRestrictQualified();
50815081
5082 const param_name: ?[]const u8 =5082 const param_name: ?[]const u8 =
5083 if (fn_decl) |decl|5083 if (fn_decl) |decl| blk: {
5084 blk: {5084 const param = decl.getParamDecl(@as(c_uint, @intCast(i)));
5085 const param = decl.getParamDecl(@as(c_uint, @intCast(i)));5085 const param_name: []const u8 = try c.str(@as(*const clang.NamedDecl, @ptrCast(param)).getName_bytes_begin());
5086 const param_name: []const u8 = try c.str(@as(*const clang.NamedDecl, @ptrCast(param)).getName_bytes_begin());5086 if (param_name.len < 1)
5087 if (param_name.len < 1)5087 break :blk null;
5088 break :blk null;5088
50895089 break :blk param_name;
5090 break :blk param_name;5090 } else null;
5091 } else null;
5092 const type_node = try transQualType(c, scope, param_qt, source_loc);5091 const type_node = try transQualType(c, scope, param_qt, source_loc);
50935092
5094 fn_params.addOneAssumeCapacity().* = .{5093 fn_params.addOneAssumeCapacity().* = .{
test/behavior/export_builtin.zig+2-2
...@@ -59,8 +59,8 @@ test "exporting comptime-known value" {...@@ -59,8 +59,8 @@ test "exporting comptime-known value" {
59 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;59 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
60 if (builtin.zig_backend == .stage2_x86_64 and60 if (builtin.zig_backend == .stage2_x86_64 and
61 (builtin.target.ofmt != .elf and61 (builtin.target.ofmt != .elf and
62 builtin.target.ofmt != .macho and62 builtin.target.ofmt != .macho and
63 builtin.target.ofmt != .coff)) return error.SkipZigTest;63 builtin.target.ofmt != .coff)) return error.SkipZigTest;
64 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;64 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
65 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;65 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
66 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;66 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
test/link/elf.zig+70-70
...@@ -475,7 +475,7 @@ fn testCommentString(b: *Build, opts: Options) *Step {...@@ -475,7 +475,7 @@ fn testCommentString(b: *Build, opts: Options) *Step {
475 const test_step = addTestStep(b, "comment-string", opts);475 const test_step = addTestStep(b, "comment-string", opts);
476476
477 const exe = addExecutable(b, opts, .{ .name = "main", .zig_source_bytes = 477 const exe = addExecutable(b, opts, .{ .name = "main", .zig_source_bytes =
478 \\pub fn main() void {}478 \\pub fn main() void {}
479 });479 });
480480
481 const check = exe.checkObject();481 const check = exe.checkObject();
...@@ -490,7 +490,7 @@ fn testCommentStringStaticLib(b: *Build, opts: Options) *Step {...@@ -490,7 +490,7 @@ fn testCommentStringStaticLib(b: *Build, opts: Options) *Step {
490 const test_step = addTestStep(b, "comment-string-static-lib", opts);490 const test_step = addTestStep(b, "comment-string-static-lib", opts);
491491
492 const lib = addStaticLibrary(b, opts, .{ .name = "lib", .zig_source_bytes = 492 const lib = addStaticLibrary(b, opts, .{ .name = "lib", .zig_source_bytes =
493 \\export fn foo() void {}493 \\export fn foo() void {}
494 });494 });
495495
496 const check = lib.checkObject();496 const check = lib.checkObject();
...@@ -861,23 +861,23 @@ fn testEmitRelocatable(b: *Build, opts: Options) *Step {...@@ -861,23 +861,23 @@ fn testEmitRelocatable(b: *Build, opts: Options) *Step {
861 const test_step = addTestStep(b, "emit-relocatable", opts);861 const test_step = addTestStep(b, "emit-relocatable", opts);
862862
863 const a_o = addObject(b, opts, .{ .name = "a", .zig_source_bytes = 863 const a_o = addObject(b, opts, .{ .name = "a", .zig_source_bytes =
864 \\const std = @import("std");864 \\const std = @import("std");
865 \\extern var bar: i32;865 \\extern var bar: i32;
866 \\export fn foo() i32 {866 \\export fn foo() i32 {
867 \\ return bar;867 \\ return bar;
868 \\}868 \\}
869 \\export fn printFoo() void {869 \\export fn printFoo() void {
870 \\ std.debug.print("foo={d}\n", .{foo()});870 \\ std.debug.print("foo={d}\n", .{foo()});
871 \\}871 \\}
872 });872 });
873 a_o.linkLibC();873 a_o.linkLibC();
874874
875 const b_o = addObject(b, opts, .{ .name = "b", .c_source_bytes = 875 const b_o = addObject(b, opts, .{ .name = "b", .c_source_bytes =
876 \\#include <stdio.h>876 \\#include <stdio.h>
877 \\int bar = 42;877 \\int bar = 42;
878 \\void printBar() {878 \\void printBar() {
879 \\ fprintf(stderr, "bar=%d\n", bar);879 \\ fprintf(stderr, "bar=%d\n", bar);
880 \\}880 \\}
881 });881 });
882 b_o.linkLibC();882 b_o.linkLibC();
883883
...@@ -886,13 +886,13 @@ fn testEmitRelocatable(b: *Build, opts: Options) *Step {...@@ -886,13 +886,13 @@ fn testEmitRelocatable(b: *Build, opts: Options) *Step {
886 c_o.addObject(b_o);886 c_o.addObject(b_o);
887887
888 const exe = addExecutable(b, opts, .{ .name = "test", .zig_source_bytes = 888 const exe = addExecutable(b, opts, .{ .name = "test", .zig_source_bytes =
889 \\const std = @import("std");889 \\const std = @import("std");
890 \\extern fn printFoo() void;890 \\extern fn printFoo() void;
891 \\extern fn printBar() void;891 \\extern fn printBar() void;
892 \\pub fn main() void {892 \\pub fn main() void {
893 \\ printFoo();893 \\ printFoo();
894 \\ printBar();894 \\ printBar();
895 \\}895 \\}
896 });896 });
897 exe.addObject(c_o);897 exe.addObject(c_o);
898 exe.linkLibC();898 exe.linkLibC();
...@@ -1920,8 +1920,8 @@ fn testInitArrayOrder(b: *Build, opts: Options) *Step {...@@ -1920,8 +1920,8 @@ fn testInitArrayOrder(b: *Build, opts: Options) *Step {
1920 g_o.linkLibC();1920 g_o.linkLibC();
19211921
1922 const h_o = addObject(b, opts, .{ .name = "h", .c_source_bytes = 1922 const h_o = addObject(b, opts, .{ .name = "h", .c_source_bytes =
1923 \\#include <stdio.h>1923 \\#include <stdio.h>
1924 \\__attribute__((destructor)) void fini2() { printf("8"); }1924 \\__attribute__((destructor)) void fini2() { printf("8"); }
1925 });1925 });
1926 h_o.linkLibC();1926 h_o.linkLibC();
19271927
...@@ -2495,23 +2495,23 @@ fn testMergeStrings2(b: *Build, opts: Options) *Step {...@@ -2495,23 +2495,23 @@ fn testMergeStrings2(b: *Build, opts: Options) *Step {
2495 const test_step = addTestStep(b, "merge-strings2", opts);2495 const test_step = addTestStep(b, "merge-strings2", opts);
24962496
2497 const obj1 = addObject(b, opts, .{ .name = "a", .zig_source_bytes = 2497 const obj1 = addObject(b, opts, .{ .name = "a", .zig_source_bytes =
2498 \\const std = @import("std");2498 \\const std = @import("std");
2499 \\export fn foo() void {2499 \\export fn foo() void {
2500 \\ var arr: [5:0]u16 = [_:0]u16{ 1, 2, 3, 4, 5 };2500 \\ var arr: [5:0]u16 = [_:0]u16{ 1, 2, 3, 4, 5 };
2501 \\ const slice = std.mem.sliceTo(&arr, 3);2501 \\ const slice = std.mem.sliceTo(&arr, 3);
2502 \\ std.testing.expectEqualSlices(u16, arr[0..2], slice) catch unreachable;2502 \\ std.testing.expectEqualSlices(u16, arr[0..2], slice) catch unreachable;
2503 \\}2503 \\}
2504 });2504 });
25052505
2506 const obj2 = addObject(b, opts, .{ .name = "b", .zig_source_bytes = 2506 const obj2 = addObject(b, opts, .{ .name = "b", .zig_source_bytes =
2507 \\const std = @import("std");2507 \\const std = @import("std");
2508 \\extern fn foo() void;2508 \\extern fn foo() void;
2509 \\pub fn main() void {2509 \\pub fn main() void {
2510 \\ foo();2510 \\ foo();
2511 \\ var arr: [5:0]u16 = [_:0]u16{ 5, 4, 3, 2, 1 };2511 \\ var arr: [5:0]u16 = [_:0]u16{ 5, 4, 3, 2, 1 };
2512 \\ const slice = std.mem.sliceTo(&arr, 3);2512 \\ const slice = std.mem.sliceTo(&arr, 3);
2513 \\ std.testing.expectEqualSlices(u16, arr[0..2], slice) catch unreachable;2513 \\ std.testing.expectEqualSlices(u16, arr[0..2], slice) catch unreachable;
2514 \\}2514 \\}
2515 });2515 });
25162516
2517 {2517 {
...@@ -2752,17 +2752,17 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step {...@@ -2752,17 +2752,17 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step {
2752 });2752 });
2753 obj2.linkLibCpp();2753 obj2.linkLibCpp();
2754 const obj3 = addObject(b, opts, .{ .name = "obj3", .cpp_source_bytes = 2754 const obj3 = addObject(b, opts, .{ .name = "obj3", .cpp_source_bytes =
2755 \\#include <iostream>2755 \\#include <iostream>
2756 \\#include <stdexcept>2756 \\#include <stdexcept>
2757 \\extern int try_again();2757 \\extern int try_again();
2758 \\int main() {2758 \\int main() {
2759 \\ try {2759 \\ try {
2760 \\ try_again();2760 \\ try_again();
2761 \\ } catch (const std::exception &e) {2761 \\ } catch (const std::exception &e) {
2762 \\ std::cout << "exception=" << e.what();2762 \\ std::cout << "exception=" << e.what();
2763 \\ }2763 \\ }
2764 \\ return 0;2764 \\ return 0;
2765 \\}2765 \\}
2766 });2766 });
2767 obj3.linkLibCpp();2767 obj3.linkLibCpp();
27682768
...@@ -2864,15 +2864,15 @@ fn testRelocatableMergeStrings(b: *Build, opts: Options) *Step {...@@ -2864,15 +2864,15 @@ fn testRelocatableMergeStrings(b: *Build, opts: Options) *Step {
2864 const test_step = addTestStep(b, "relocatable-merge-strings", opts);2864 const test_step = addTestStep(b, "relocatable-merge-strings", opts);
28652865
2866 const obj1 = addObject(b, opts, .{ .name = "a", .asm_source_bytes = 2866 const obj1 = addObject(b, opts, .{ .name = "a", .asm_source_bytes =
2867 \\.section .rodata.str1.1,"aMS",@progbits,12867 \\.section .rodata.str1.1,"aMS",@progbits,1
2868 \\val1:2868 \\val1:
2869 \\.ascii "Hello \0"2869 \\.ascii "Hello \0"
2870 \\.section .rodata.str1.1,"aMS",@progbits,12870 \\.section .rodata.str1.1,"aMS",@progbits,1
2871 \\val5:2871 \\val5:
2872 \\.ascii "World \0"2872 \\.ascii "World \0"
2873 \\.section .rodata.str1.1,"aMS",@progbits,12873 \\.section .rodata.str1.1,"aMS",@progbits,1
2874 \\val7:2874 \\val7:
2875 \\.ascii "Hello \0"2875 \\.ascii "Hello \0"
2876 });2876 });
28772877
2878 const obj2 = addObject(b, opts, .{ .name = "b" });2878 const obj2 = addObject(b, opts, .{ .name = "b" });
...@@ -3030,18 +3030,18 @@ fn testThunks(b: *Build, opts: Options) *Step {...@@ -3030,18 +3030,18 @@ fn testThunks(b: *Build, opts: Options) *Step {
3030 const test_step = addTestStep(b, "thunks", opts);3030 const test_step = addTestStep(b, "thunks", opts);
30313031
3032 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 3032 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
3033 \\void foo();3033 \\void foo();
3034 \\__attribute__((section(".bar"))) void bar() {3034 \\__attribute__((section(".bar"))) void bar() {
3035 \\ return foo();3035 \\ return foo();
3036 \\}3036 \\}
3037 \\__attribute__((section(".foo"))) void foo() {3037 \\__attribute__((section(".foo"))) void foo() {
3038 \\ return bar();3038 \\ return bar();
3039 \\}3039 \\}
3040 \\int main() {3040 \\int main() {
3041 \\ foo();3041 \\ foo();
3042 \\ bar();3042 \\ bar();
3043 \\ return 0;3043 \\ return 0;
3044 \\}3044 \\}
3045 });3045 });
30463046
3047 const check = exe.checkObject();3047 const check = exe.checkObject();
test/link/macho.zig+816-816
...@@ -109,20 +109,20 @@ fn testDeadStrip(b: *Build, opts: Options) *Step {...@@ -109,20 +109,20 @@ fn testDeadStrip(b: *Build, opts: Options) *Step {
109 const test_step = addTestStep(b, "dead-strip", opts);109 const test_step = addTestStep(b, "dead-strip", opts);
110110
111 const obj = addObject(b, opts, .{ .name = "a", .cpp_source_bytes = 111 const obj = addObject(b, opts, .{ .name = "a", .cpp_source_bytes =
112 \\#include <stdio.h>112 \\#include <stdio.h>
113 \\int two() { return 2; }113 \\int two() { return 2; }
114 \\int live_var1 = 1;114 \\int live_var1 = 1;
115 \\int live_var2 = two();115 \\int live_var2 = two();
116 \\int dead_var1 = 3;116 \\int dead_var1 = 3;
117 \\int dead_var2 = 4;117 \\int dead_var2 = 4;
118 \\void live_fn1() {}118 \\void live_fn1() {}
119 \\void live_fn2() { live_fn1(); }119 \\void live_fn2() { live_fn1(); }
120 \\void dead_fn1() {}120 \\void dead_fn1() {}
121 \\void dead_fn2() { dead_fn1(); }121 \\void dead_fn2() { dead_fn1(); }
122 \\int main() {122 \\int main() {
123 \\ printf("%d %d\n", live_var1, live_var2);123 \\ printf("%d %d\n", live_var1, live_var2);
124 \\ live_fn2();124 \\ live_fn2();
125 \\}125 \\}
126 });126 });
127127
128 {128 {
...@@ -190,21 +190,21 @@ fn testDuplicateDefinitions(b: *Build, opts: Options) *Step {...@@ -190,21 +190,21 @@ fn testDuplicateDefinitions(b: *Build, opts: Options) *Step {
190 const test_step = addTestStep(b, "duplicate-definitions", opts);190 const test_step = addTestStep(b, "duplicate-definitions", opts);
191191
192 const obj = addObject(b, opts, .{ .name = "a", .zig_source_bytes = 192 const obj = addObject(b, opts, .{ .name = "a", .zig_source_bytes =
193 \\var x: usize = 1;193 \\var x: usize = 1;
194 \\export fn strong() void { x += 1; }194 \\export fn strong() void { x += 1; }
195 \\export fn weak() void { x += 1; }195 \\export fn weak() void { x += 1; }
196 });196 });
197197
198 const exe = addExecutable(b, opts, .{ .name = "main", .zig_source_bytes = 198 const exe = addExecutable(b, opts, .{ .name = "main", .zig_source_bytes =
199 \\var x: usize = 1;199 \\var x: usize = 1;
200 \\export fn strong() void { x += 1; }200 \\export fn strong() void { x += 1; }
201 \\comptime { @export(&weakImpl, .{ .name = "weak", .linkage = .weak }); }201 \\comptime { @export(&weakImpl, .{ .name = "weak", .linkage = .weak }); }
202 \\fn weakImpl() callconv(.C) void { x += 1; }202 \\fn weakImpl() callconv(.C) void { x += 1; }
203 \\extern fn weak() void;203 \\extern fn weak() void;
204 \\pub fn main() void {204 \\pub fn main() void {
205 \\ weak();205 \\ weak();
206 \\ strong();206 \\ strong();
207 \\}207 \\}
208 });208 });
209 exe.addObject(obj);209 exe.addObject(obj);
210210
...@@ -221,16 +221,16 @@ fn testDeadStripDylibs(b: *Build, opts: Options) *Step {...@@ -221,16 +221,16 @@ fn testDeadStripDylibs(b: *Build, opts: Options) *Step {
221 const test_step = addTestStep(b, "dead-strip-dylibs", opts);221 const test_step = addTestStep(b, "dead-strip-dylibs", opts);
222222
223 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes = 223 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes =
224 \\#include <objc/runtime.h>224 \\#include <objc/runtime.h>
225 \\int main() {225 \\int main() {
226 \\ if (objc_getClass("NSObject") == 0) {226 \\ if (objc_getClass("NSObject") == 0) {
227 \\ return -1;227 \\ return -1;
228 \\ }228 \\ }
229 \\ if (objc_getClass("NSApplication") == 0) {229 \\ if (objc_getClass("NSApplication") == 0) {
230 \\ return -2;230 \\ return -2;
231 \\ }231 \\ }
232 \\ return 0;232 \\ return 0;
233 \\}233 \\}
234 });234 });
235235
236 {236 {
...@@ -270,11 +270,11 @@ fn testDylib(b: *Build, opts: Options) *Step {...@@ -270,11 +270,11 @@ fn testDylib(b: *Build, opts: Options) *Step {
270 const test_step = addTestStep(b, "dylib", opts);270 const test_step = addTestStep(b, "dylib", opts);
271271
272 const dylib = addSharedLibrary(b, opts, .{ .name = "a", .c_source_bytes = 272 const dylib = addSharedLibrary(b, opts, .{ .name = "a", .c_source_bytes =
273 \\#include<stdio.h>273 \\#include<stdio.h>
274 \\char world[] = "world";274 \\char world[] = "world";
275 \\char* hello() {275 \\char* hello() {
276 \\ return "Hello";276 \\ return "Hello";
277 \\}277 \\}
278 });278 });
279279
280 const check = dylib.checkObject();280 const check = dylib.checkObject();
...@@ -284,13 +284,13 @@ fn testDylib(b: *Build, opts: Options) *Step {...@@ -284,13 +284,13 @@ fn testDylib(b: *Build, opts: Options) *Step {
284 test_step.dependOn(&check.step);284 test_step.dependOn(&check.step);
285285
286 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 286 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
287 \\#include<stdio.h>287 \\#include<stdio.h>
288 \\char* hello();288 \\char* hello();
289 \\extern char world[];289 \\extern char world[];
290 \\int main() {290 \\int main() {
291 \\ printf("%s %s", hello(), world);291 \\ printf("%s %s", hello(), world);
292 \\ return 0;292 \\ return 0;
293 \\}293 \\}
294 });294 });
295 exe.root_module.linkSystemLibrary("a", .{});295 exe.root_module.linkSystemLibrary("a", .{});
296 exe.root_module.addLibraryPath(dylib.getEmittedBinDirectory());296 exe.root_module.addLibraryPath(dylib.getEmittedBinDirectory());
...@@ -345,10 +345,10 @@ fn testEmptyObject(b: *Build, opts: Options) *Step {...@@ -345,10 +345,10 @@ fn testEmptyObject(b: *Build, opts: Options) *Step {
345 const empty = addObject(b, opts, .{ .name = "empty", .c_source_bytes = "" });345 const empty = addObject(b, opts, .{ .name = "empty", .c_source_bytes = "" });
346346
347 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 347 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
348 \\#include <stdio.h>348 \\#include <stdio.h>
349 \\int main() {349 \\int main() {
350 \\ printf("Hello world!");350 \\ printf("Hello world!");
351 \\}351 \\}
352 });352 });
353 exe.addObject(empty);353 exe.addObject(empty);
354354
...@@ -375,11 +375,11 @@ fn testEntryPoint(b: *Build, opts: Options) *Step {...@@ -375,11 +375,11 @@ fn testEntryPoint(b: *Build, opts: Options) *Step {
375 const test_step = addTestStep(b, "entry-point", opts);375 const test_step = addTestStep(b, "entry-point", opts);
376376
377 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 377 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
378 \\#include<stdio.h>378 \\#include<stdio.h>
379 \\int non_main() {379 \\int non_main() {
380 \\ printf("%d", 42);380 \\ printf("%d", 42);
381 \\ return 0;381 \\ return 0;
382 \\}382 \\}
383 });383 });
384 exe.entry = .{ .symbol_name = "_non_main" };384 exe.entry = .{ .symbol_name = "_non_main" };
385385
...@@ -597,10 +597,10 @@ fn testHeaderWeakFlags(b: *Build, opts: Options) *Step {...@@ -597,10 +597,10 @@ fn testHeaderWeakFlags(b: *Build, opts: Options) *Step {
597 const test_step = addTestStep(b, "header-weak-flags", opts);597 const test_step = addTestStep(b, "header-weak-flags", opts);
598598
599 const obj1 = addObject(b, opts, .{ .name = "a", .asm_source_bytes = 599 const obj1 = addObject(b, opts, .{ .name = "a", .asm_source_bytes =
600 \\.globl _x600 \\.globl _x
601 \\.weak_definition _x601 \\.weak_definition _x
602 \\_x:602 \\_x:
603 \\ ret603 \\ ret
604 });604 });
605605
606 const lib = addSharedLibrary(b, opts, .{ .name = "a" });606 const lib = addSharedLibrary(b, opts, .{ .name = "a" });
...@@ -659,11 +659,11 @@ fn testHeaderWeakFlags(b: *Build, opts: Options) *Step {...@@ -659,11 +659,11 @@ fn testHeaderWeakFlags(b: *Build, opts: Options) *Step {
659659
660 {660 {
661 const exe = addExecutable(b, opts, .{ .name = "main3", .asm_source_bytes = 661 const exe = addExecutable(b, opts, .{ .name = "main3", .asm_source_bytes =
662 \\.globl _main, _x662 \\.globl _main, _x
663 \\_x:663 \\_x:
664 \\664 \\
665 \\_main:665 \\_main:
666 \\ ret666 \\ ret
667 });667 });
668 exe.linkLibrary(lib);668 exe.linkLibrary(lib);
669669
...@@ -684,11 +684,11 @@ fn testHelloC(b: *Build, opts: Options) *Step {...@@ -684,11 +684,11 @@ fn testHelloC(b: *Build, opts: Options) *Step {
684 const test_step = addTestStep(b, "hello-c", opts);684 const test_step = addTestStep(b, "hello-c", opts);
685685
686 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 686 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
687 \\#include <stdio.h>687 \\#include <stdio.h>
688 \\int main() { 688 \\int main() {
689 \\ printf("Hello world!\n");689 \\ printf("Hello world!\n");
690 \\ return 0;690 \\ return 0;
691 \\}691 \\}
692 });692 });
693693
694 const run = addRunArtifact(exe);694 const run = addRunArtifact(exe);
...@@ -708,10 +708,10 @@ fn testHelloZig(b: *Build, opts: Options) *Step {...@@ -708,10 +708,10 @@ fn testHelloZig(b: *Build, opts: Options) *Step {
708 const test_step = addTestStep(b, "hello-zig", opts);708 const test_step = addTestStep(b, "hello-zig", opts);
709709
710 const exe = addExecutable(b, opts, .{ .name = "main", .zig_source_bytes = 710 const exe = addExecutable(b, opts, .{ .name = "main", .zig_source_bytes =
711 \\const std = @import("std");711 \\const std = @import("std");
712 \\pub fn main() void {712 \\pub fn main() void {
713 \\ std.io.getStdOut().writer().print("Hello world!\n", .{}) catch unreachable;713 \\ std.io.getStdOut().writer().print("Hello world!\n", .{}) catch unreachable;
714 \\}714 \\}
715 });715 });
716716
717 const run = addRunArtifact(exe);717 const run = addRunArtifact(exe);
...@@ -729,10 +729,10 @@ fn testLargeBss(b: *Build, opts: Options) *Step {...@@ -729,10 +729,10 @@ fn testLargeBss(b: *Build, opts: Options) *Step {
729 // maybe S_GB_ZEROFILL section is an answer to this but it doesn't seem supported by dyld729 // maybe S_GB_ZEROFILL section is an answer to this but it doesn't seem supported by dyld
730 // anymore. When I get some free time I will re-investigate this.730 // anymore. When I get some free time I will re-investigate this.
731 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 731 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
732 \\char arr[0x1000000];732 \\char arr[0x1000000];
733 \\int main() {733 \\int main() {
734 \\ return arr[2000];734 \\ return arr[2000];
735 \\}735 \\}
736 });736 });
737737
738 const run = addRunArtifact(exe);738 const run = addRunArtifact(exe);
...@@ -746,11 +746,11 @@ fn testLayout(b: *Build, opts: Options) *Step {...@@ -746,11 +746,11 @@ fn testLayout(b: *Build, opts: Options) *Step {
746 const test_step = addTestStep(b, "layout", opts);746 const test_step = addTestStep(b, "layout", opts);
747747
748 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 748 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
749 \\#include <stdio.h>749 \\#include <stdio.h>
750 \\int main() {750 \\int main() {
751 \\ printf("Hello world!");751 \\ printf("Hello world!");
752 \\ return 0;752 \\ return 0;
753 \\}753 \\}
754 });754 });
755755
756 const check = exe.checkObject();756 const check = exe.checkObject();
...@@ -936,15 +936,15 @@ fn testLinksection(b: *Build, opts: Options) *Step {...@@ -936,15 +936,15 @@ fn testLinksection(b: *Build, opts: Options) *Step {
936 const test_step = addTestStep(b, "linksection", opts);936 const test_step = addTestStep(b, "linksection", opts);
937937
938 const obj = addObject(b, opts, .{ .name = "main", .zig_source_bytes = 938 const obj = addObject(b, opts, .{ .name = "main", .zig_source_bytes =
939 \\export var test_global: u32 linksection("__DATA,__TestGlobal") = undefined;939 \\export var test_global: u32 linksection("__DATA,__TestGlobal") = undefined;
940 \\export fn testFn() linksection("__TEXT,__TestFn") callconv(.C) void {940 \\export fn testFn() linksection("__TEXT,__TestFn") callconv(.C) void {
941 \\ TestGenericFn("A").f();941 \\ TestGenericFn("A").f();
942 \\}942 \\}
943 \\fn TestGenericFn(comptime suffix: []const u8) type {943 \\fn TestGenericFn(comptime suffix: []const u8) type {
944 \\ return struct {944 \\ return struct {
945 \\ fn f() linksection("__TEXT,__TestGenFn" ++ suffix) void {}945 \\ fn f() linksection("__TEXT,__TestGenFn" ++ suffix) void {}
946 \\ };946 \\ };
947 \\}947 \\}
948 });948 });
949949
950 const check = obj.checkObject();950 const check = obj.checkObject();
...@@ -967,71 +967,71 @@ fn testMergeLiteralsX64(b: *Build, opts: Options) *Step {...@@ -967,71 +967,71 @@ fn testMergeLiteralsX64(b: *Build, opts: Options) *Step {
967 const test_step = addTestStep(b, "merge-literals-x64", opts);967 const test_step = addTestStep(b, "merge-literals-x64", opts);
968968
969 const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes = 969 const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes =
970 \\.globl _q1970 \\.globl _q1
971 \\.globl _s1971 \\.globl _s1
972 \\972 \\
973 \\.align 4973 \\.align 4
974 \\_q1:974 \\_q1:
975 \\ lea L._q1(%rip), %rax975 \\ lea L._q1(%rip), %rax
976 \\ mov (%rax), %xmm0976 \\ mov (%rax), %xmm0
977 \\ ret977 \\ ret
978 \\ 978 \\
979 \\.section __TEXT,__cstring,cstring_literals979 \\.section __TEXT,__cstring,cstring_literals
980 \\l._s1:980 \\l._s1:
981 \\ .asciz "hello"981 \\ .asciz "hello"
982 \\982 \\
983 \\.section __TEXT,__literal8,8byte_literals983 \\.section __TEXT,__literal8,8byte_literals
984 \\.align 8984 \\.align 8
985 \\L._q1:985 \\L._q1:
986 \\ .double 1.2345986 \\ .double 1.2345
987 \\987 \\
988 \\.section __DATA,__data988 \\.section __DATA,__data
989 \\.align 8989 \\.align 8
990 \\_s1:990 \\_s1:
991 \\ .quad l._s1991 \\ .quad l._s1
992 });992 });
993993
994 const b_o = addObject(b, opts, .{ .name = "b", .asm_source_bytes = 994 const b_o = addObject(b, opts, .{ .name = "b", .asm_source_bytes =
995 \\.globl _q2995 \\.globl _q2
996 \\.globl _s2996 \\.globl _s2
997 \\.globl _s3997 \\.globl _s3
998 \\998 \\
999 \\.align 4999 \\.align 4
1000 \\_q2:1000 \\_q2:
1001 \\ lea L._q2(%rip), %rax1001 \\ lea L._q2(%rip), %rax
1002 \\ mov (%rax), %xmm01002 \\ mov (%rax), %xmm0
1003 \\ ret1003 \\ ret
1004 \\ 1004 \\
1005 \\.section __TEXT,__cstring,cstring_literals1005 \\.section __TEXT,__cstring,cstring_literals
1006 \\l._s2:1006 \\l._s2:
1007 \\ .asciz "hello"1007 \\ .asciz "hello"
1008 \\l._s3:1008 \\l._s3:
1009 \\ .asciz "world"1009 \\ .asciz "world"
1010 \\1010 \\
1011 \\.section __TEXT,__literal8,8byte_literals1011 \\.section __TEXT,__literal8,8byte_literals
1012 \\.align 81012 \\.align 8
1013 \\L._q2:1013 \\L._q2:
1014 \\ .double 1.23451014 \\ .double 1.2345
1015 \\1015 \\
1016 \\.section __DATA,__data1016 \\.section __DATA,__data
1017 \\.align 81017 \\.align 8
1018 \\_s2:1018 \\_s2:
1019 \\ .quad l._s21019 \\ .quad l._s2
1020 \\_s3:1020 \\_s3:
1021 \\ .quad l._s31021 \\ .quad l._s3
1022 });1022 });
10231023
1024 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes = 1024 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes =
1025 \\#include <stdio.h>1025 \\#include <stdio.h>
1026 \\extern double q1();1026 \\extern double q1();
1027 \\extern double q2();1027 \\extern double q2();
1028 \\extern const char* s1;1028 \\extern const char* s1;
1029 \\extern const char* s2;1029 \\extern const char* s2;
1030 \\extern const char* s3;1030 \\extern const char* s3;
1031 \\int main() {1031 \\int main() {
1032 \\ printf("%s, %s, %s, %f, %f", s1, s2, s3, q1(), q2());1032 \\ printf("%s, %s, %s, %f, %f", s1, s2, s3, q1(), q2());
1033 \\ return 0;1033 \\ return 0;
1034 \\}1034 \\}
1035 });1035 });
10361036
1037 const runWithChecks = struct {1037 const runWithChecks = struct {
...@@ -1083,71 +1083,71 @@ fn testMergeLiteralsArm64(b: *Build, opts: Options) *Step {...@@ -1083,71 +1083,71 @@ fn testMergeLiteralsArm64(b: *Build, opts: Options) *Step {
1083 const test_step = addTestStep(b, "merge-literals-arm64", opts);1083 const test_step = addTestStep(b, "merge-literals-arm64", opts);
10841084
1085 const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes = 1085 const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes =
1086 \\.globl _q11086 \\.globl _q1
1087 \\.globl _s11087 \\.globl _s1
1088 \\1088 \\
1089 \\.align 41089 \\.align 4
1090 \\_q1:1090 \\_q1:
1091 \\ adrp x8, L._q1@PAGE1091 \\ adrp x8, L._q1@PAGE
1092 \\ ldr d0, [x8, L._q1@PAGEOFF]1092 \\ ldr d0, [x8, L._q1@PAGEOFF]
1093 \\ ret1093 \\ ret
1094 \\ 1094 \\
1095 \\.section __TEXT,__cstring,cstring_literals1095 \\.section __TEXT,__cstring,cstring_literals
1096 \\l._s1:1096 \\l._s1:
1097 \\ .asciz "hello"1097 \\ .asciz "hello"
1098 \\1098 \\
1099 \\.section __TEXT,__literal8,8byte_literals1099 \\.section __TEXT,__literal8,8byte_literals
1100 \\.align 81100 \\.align 8
1101 \\L._q1:1101 \\L._q1:
1102 \\ .double 1.23451102 \\ .double 1.2345
1103 \\1103 \\
1104 \\.section __DATA,__data1104 \\.section __DATA,__data
1105 \\.align 81105 \\.align 8
1106 \\_s1:1106 \\_s1:
1107 \\ .quad l._s11107 \\ .quad l._s1
1108 });1108 });
11091109
1110 const b_o = addObject(b, opts, .{ .name = "b", .asm_source_bytes = 1110 const b_o = addObject(b, opts, .{ .name = "b", .asm_source_bytes =
1111 \\.globl _q21111 \\.globl _q2
1112 \\.globl _s21112 \\.globl _s2
1113 \\.globl _s31113 \\.globl _s3
1114 \\1114 \\
1115 \\.align 41115 \\.align 4
1116 \\_q2:1116 \\_q2:
1117 \\ adrp x8, L._q2@PAGE1117 \\ adrp x8, L._q2@PAGE
1118 \\ ldr d0, [x8, L._q2@PAGEOFF]1118 \\ ldr d0, [x8, L._q2@PAGEOFF]
1119 \\ ret1119 \\ ret
1120 \\ 1120 \\
1121 \\.section __TEXT,__cstring,cstring_literals1121 \\.section __TEXT,__cstring,cstring_literals
1122 \\l._s2:1122 \\l._s2:
1123 \\ .asciz "hello"1123 \\ .asciz "hello"
1124 \\l._s3:1124 \\l._s3:
1125 \\ .asciz "world"1125 \\ .asciz "world"
1126 \\1126 \\
1127 \\.section __TEXT,__literal8,8byte_literals1127 \\.section __TEXT,__literal8,8byte_literals
1128 \\.align 81128 \\.align 8
1129 \\L._q2:1129 \\L._q2:
1130 \\ .double 1.23451130 \\ .double 1.2345
1131 \\1131 \\
1132 \\.section __DATA,__data1132 \\.section __DATA,__data
1133 \\.align 81133 \\.align 8
1134 \\_s2:1134 \\_s2:
1135 \\ .quad l._s21135 \\ .quad l._s2
1136 \\_s3:1136 \\_s3:
1137 \\ .quad l._s31137 \\ .quad l._s3
1138 });1138 });
11391139
1140 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes = 1140 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes =
1141 \\#include <stdio.h>1141 \\#include <stdio.h>
1142 \\extern double q1();1142 \\extern double q1();
1143 \\extern double q2();1143 \\extern double q2();
1144 \\extern const char* s1;1144 \\extern const char* s1;
1145 \\extern const char* s2;1145 \\extern const char* s2;
1146 \\extern const char* s3;1146 \\extern const char* s3;
1147 \\int main() {1147 \\int main() {
1148 \\ printf("%s, %s, %s, %f, %f", s1, s2, s3, q1(), q2());1148 \\ printf("%s, %s, %s, %f, %f", s1, s2, s3, q1(), q2());
1149 \\ return 0;1149 \\ return 0;
1150 \\}1150 \\}
1151 });1151 });
11521152
1153 const runWithChecks = struct {1153 const runWithChecks = struct {
...@@ -1203,59 +1203,59 @@ fn testMergeLiteralsArm642(b: *Build, opts: Options) *Step {...@@ -1203,59 +1203,59 @@ fn testMergeLiteralsArm642(b: *Build, opts: Options) *Step {
1203 const test_step = addTestStep(b, "merge-literals-arm64-2", opts);1203 const test_step = addTestStep(b, "merge-literals-arm64-2", opts);
12041204
1205 const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes = 1205 const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes =
1206 \\.globl _q11206 \\.globl _q1
1207 \\.globl _s11207 \\.globl _s1
1208 \\1208 \\
1209 \\.align 41209 \\.align 4
1210 \\_q1:1210 \\_q1:
1211 \\ adrp x0, L._q1@PAGE1211 \\ adrp x0, L._q1@PAGE
1212 \\ ldr x0, [x0, L._q1@PAGEOFF]1212 \\ ldr x0, [x0, L._q1@PAGEOFF]
1213 \\ ret1213 \\ ret
1214 \\ 1214 \\
1215 \\.section __TEXT,__cstring,cstring_literals1215 \\.section __TEXT,__cstring,cstring_literals
1216 \\_s1:1216 \\_s1:
1217 \\ .asciz "hello"1217 \\ .asciz "hello"
1218 \\1218 \\
1219 \\.section __TEXT,__literal8,8byte_literals1219 \\.section __TEXT,__literal8,8byte_literals
1220 \\.align 81220 \\.align 8
1221 \\L._q1:1221 \\L._q1:
1222 \\ .double 1.23451222 \\ .double 1.2345
1223 });1223 });
12241224
1225 const b_o = addObject(b, opts, .{ .name = "b", .asm_source_bytes = 1225 const b_o = addObject(b, opts, .{ .name = "b", .asm_source_bytes =
1226 \\.globl _q21226 \\.globl _q2
1227 \\.globl _s21227 \\.globl _s2
1228 \\.globl _s31228 \\.globl _s3
1229 \\1229 \\
1230 \\.align 41230 \\.align 4
1231 \\_q2:1231 \\_q2:
1232 \\ adrp x0, L._q2@PAGE1232 \\ adrp x0, L._q2@PAGE
1233 \\ ldr x0, [x0, L._q2@PAGEOFF]1233 \\ ldr x0, [x0, L._q2@PAGEOFF]
1234 \\ ret1234 \\ ret
1235 \\ 1235 \\
1236 \\.section __TEXT,__cstring,cstring_literals1236 \\.section __TEXT,__cstring,cstring_literals
1237 \\_s2:1237 \\_s2:
1238 \\ .asciz "hello"1238 \\ .asciz "hello"
1239 \\_s3:1239 \\_s3:
1240 \\ .asciz "world"1240 \\ .asciz "world"
1241 \\1241 \\
1242 \\.section __TEXT,__literal8,8byte_literals1242 \\.section __TEXT,__literal8,8byte_literals
1243 \\.align 81243 \\.align 8
1244 \\L._q2:1244 \\L._q2:
1245 \\ .double 1.23451245 \\ .double 1.2345
1246 });1246 });
12471247
1248 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes = 1248 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes =
1249 \\#include <stdio.h>1249 \\#include <stdio.h>
1250 \\extern double q1();1250 \\extern double q1();
1251 \\extern double q2();1251 \\extern double q2();
1252 \\extern const char* s1;1252 \\extern const char* s1;
1253 \\extern const char* s2;1253 \\extern const char* s2;
1254 \\extern const char* s3;1254 \\extern const char* s3;
1255 \\int main() {1255 \\int main() {
1256 \\ printf("%s, %s, %s, %f, %f", s1, s2, s3, q1(), q2());1256 \\ printf("%s, %s, %s, %f, %f", s1, s2, s3, q1(), q2());
1257 \\ return 0;1257 \\ return 0;
1258 \\}1258 \\}
1259 });1259 });
12601260
1261 const exe = addExecutable(b, opts, .{ .name = "main1" });1261 const exe = addExecutable(b, opts, .{ .name = "main1" });
...@@ -1277,43 +1277,43 @@ fn testMergeLiteralsAlignment(b: *Build, opts: Options) *Step {...@@ -1277,43 +1277,43 @@ fn testMergeLiteralsAlignment(b: *Build, opts: Options) *Step {
1277 const test_step = addTestStep(b, "merge-literals-alignment", opts);1277 const test_step = addTestStep(b, "merge-literals-alignment", opts);
12781278
1279 const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes = 1279 const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes =
1280 \\.globl _s11280 \\.globl _s1
1281 \\.globl _s21281 \\.globl _s2
1282 \\1282 \\
1283 \\.section __TEXT,__cstring,cstring_literals1283 \\.section __TEXT,__cstring,cstring_literals
1284 \\.align 31284 \\.align 3
1285 \\_s1:1285 \\_s1:
1286 \\ .asciz "str1"1286 \\ .asciz "str1"
1287 \\_s2:1287 \\_s2:
1288 \\ .asciz "str2"1288 \\ .asciz "str2"
1289 });1289 });
12901290
1291 const b_o = addObject(b, opts, .{ .name = "b", .asm_source_bytes = 1291 const b_o = addObject(b, opts, .{ .name = "b", .asm_source_bytes =
1292 \\.globl _s31292 \\.globl _s3
1293 \\.globl _s41293 \\.globl _s4
1294 \\1294 \\
1295 \\.section __TEXT,__cstring,cstring_literals1295 \\.section __TEXT,__cstring,cstring_literals
1296 \\.align 21296 \\.align 2
1297 \\_s3:1297 \\_s3:
1298 \\ .asciz "str1"1298 \\ .asciz "str1"
1299 \\_s4:1299 \\_s4:
1300 \\ .asciz "str2"1300 \\ .asciz "str2"
1301 });1301 });
13021302
1303 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes = 1303 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes =
1304 \\#include <assert.h>1304 \\#include <assert.h>
1305 \\#include <stdint.h>1305 \\#include <stdint.h>
1306 \\#include <stdio.h>1306 \\#include <stdio.h>
1307 \\extern const char* s1;1307 \\extern const char* s1;
1308 \\extern const char* s2;1308 \\extern const char* s2;
1309 \\extern const char* s3;1309 \\extern const char* s3;
1310 \\extern const char* s4;1310 \\extern const char* s4;
1311 \\int main() {1311 \\int main() {
1312 \\ assert((uintptr_t)(&s1) % 8 == 0 && s1 == s3);1312 \\ assert((uintptr_t)(&s1) % 8 == 0 && s1 == s3);
1313 \\ assert((uintptr_t)(&s2) % 8 == 0 && s2 == s4);1313 \\ assert((uintptr_t)(&s2) % 8 == 0 && s2 == s4);
1314 \\ printf("%s%s%s%s", &s1, &s2, &s3, &s4);1314 \\ printf("%s%s%s%s", &s1, &s2, &s3, &s4);
1315 \\ return 0;1315 \\ return 0;
1316 \\}1316 \\}
1317 , .c_source_flags = &.{"-Wno-format"} });1317 , .c_source_flags = &.{"-Wno-format"} });
13181318
1319 const runWithChecks = struct {1319 const runWithChecks = struct {
...@@ -1356,39 +1356,39 @@ fn testMergeLiteralsObjc(b: *Build, opts: Options) *Step {...@@ -1356,39 +1356,39 @@ fn testMergeLiteralsObjc(b: *Build, opts: Options) *Step {
1356 const test_step = addTestStep(b, "merge-literals-objc", opts);1356 const test_step = addTestStep(b, "merge-literals-objc", opts);
13571357
1358 const main_o = addObject(b, opts, .{ .name = "main", .objc_source_bytes = 1358 const main_o = addObject(b, opts, .{ .name = "main", .objc_source_bytes =
1359 \\#import <Foundation/Foundation.h>;1359 \\#import <Foundation/Foundation.h>;
1360 \\1360 \\
1361 \\extern void foo();1361 \\extern void foo();
1362 \\1362 \\
1363 \\int main() {1363 \\int main() {
1364 \\ NSString *thing = @"aaa";1364 \\ NSString *thing = @"aaa";
1365 \\1365 \\
1366 \\ SEL sel = @selector(lowercaseString);1366 \\ SEL sel = @selector(lowercaseString);
1367 \\ NSString *lower = (([thing respondsToSelector:sel]) ? @"YES" : @"NO");1367 \\ NSString *lower = (([thing respondsToSelector:sel]) ? @"YES" : @"NO");
1368 \\ NSLog (@"Responds to lowercaseString: %@", lower);1368 \\ NSLog (@"Responds to lowercaseString: %@", lower);
1369 \\ if ([thing respondsToSelector:sel]) //(lower == @"YES")1369 \\ if ([thing respondsToSelector:sel]) //(lower == @"YES")
1370 \\ NSLog(@"lowercaseString is: %@", [thing lowercaseString]);1370 \\ NSLog(@"lowercaseString is: %@", [thing lowercaseString]);
1371 \\1371 \\
1372 \\ foo();1372 \\ foo();
1373 \\}1373 \\}
1374 });1374 });
13751375
1376 const a_o = addObject(b, opts, .{ .name = "a", .objc_source_bytes = 1376 const a_o = addObject(b, opts, .{ .name = "a", .objc_source_bytes =
1377 \\#import <Foundation/Foundation.h>;1377 \\#import <Foundation/Foundation.h>;
1378 \\1378 \\
1379 \\void foo() {1379 \\void foo() {
1380 \\ NSString *thing = @"aaa";1380 \\ NSString *thing = @"aaa";
1381 \\ SEL sel = @selector(lowercaseString);1381 \\ SEL sel = @selector(lowercaseString);
1382 \\ NSString *lower = (([thing respondsToSelector:sel]) ? @"YES" : @"NO");1382 \\ NSString *lower = (([thing respondsToSelector:sel]) ? @"YES" : @"NO");
1383 \\ NSLog (@"Responds to lowercaseString in foo(): %@", lower);1383 \\ NSLog (@"Responds to lowercaseString in foo(): %@", lower);
1384 \\ if ([thing respondsToSelector:sel]) //(lower == @"YES")1384 \\ if ([thing respondsToSelector:sel]) //(lower == @"YES")
1385 \\ NSLog(@"lowercaseString in foo() is: %@", [thing lowercaseString]);1385 \\ NSLog(@"lowercaseString in foo() is: %@", [thing lowercaseString]);
1386 \\ SEL sel2 = @selector(uppercaseString);1386 \\ SEL sel2 = @selector(uppercaseString);
1387 \\ NSString *upper = (([thing respondsToSelector:sel2]) ? @"YES" : @"NO");1387 \\ NSString *upper = (([thing respondsToSelector:sel2]) ? @"YES" : @"NO");
1388 \\ NSLog (@"Responds to uppercaseString in foo(): %@", upper);1388 \\ NSLog (@"Responds to uppercaseString in foo(): %@", upper);
1389 \\ if ([thing respondsToSelector:sel2]) //(upper == @"YES")1389 \\ if ([thing respondsToSelector:sel2]) //(upper == @"YES")
1390 \\ NSLog(@"uppercaseString in foo() is: %@", [thing uppercaseString]);1390 \\ NSLog(@"uppercaseString in foo() is: %@", [thing uppercaseString]);
1391 \\}1391 \\}
1392 });1392 });
13931393
1394 const runWithChecks = struct {1394 const runWithChecks = struct {
...@@ -1459,12 +1459,12 @@ fn testNoDeadStrip(b: *Build, opts: Options) *Step {...@@ -1459,12 +1459,12 @@ fn testNoDeadStrip(b: *Build, opts: Options) *Step {
1459 const test_step = addTestStep(b, "no-dead-strip", opts);1459 const test_step = addTestStep(b, "no-dead-strip", opts);
14601460
1461 const exe = addExecutable(b, opts, .{ .name = "name", .c_source_bytes = 1461 const exe = addExecutable(b, opts, .{ .name = "name", .c_source_bytes =
1462 \\__attribute__((used)) int bogus1 = 0;1462 \\__attribute__((used)) int bogus1 = 0;
1463 \\int bogus2 = 0;1463 \\int bogus2 = 0;
1464 \\int foo = 42;1464 \\int foo = 42;
1465 \\int main() {1465 \\int main() {
1466 \\ return foo - 42;1466 \\ return foo - 42;
1467 \\}1467 \\}
1468 });1468 });
1469 exe.link_gc_sections = true;1469 exe.link_gc_sections = true;
14701470
...@@ -1543,11 +1543,11 @@ fn testObjc(b: *Build, opts: Options) *Step {...@@ -1543,11 +1543,11 @@ fn testObjc(b: *Build, opts: Options) *Step {
1543 const test_step = addTestStep(b, "objc", opts);1543 const test_step = addTestStep(b, "objc", opts);
15441544
1545 const lib = addStaticLibrary(b, opts, .{ .name = "a", .objc_source_bytes = 1545 const lib = addStaticLibrary(b, opts, .{ .name = "a", .objc_source_bytes =
1546 \\#import <Foundation/Foundation.h>1546 \\#import <Foundation/Foundation.h>
1547 \\@interface Foo : NSObject1547 \\@interface Foo : NSObject
1548 \\@end1548 \\@end
1549 \\@implementation Foo1549 \\@implementation Foo
1550 \\@end1550 \\@end
1551 });1551 });
15521552
1553 {1553 {
...@@ -1600,32 +1600,32 @@ fn testObjcpp(b: *Build, opts: Options) *Step {...@@ -1600,32 +1600,32 @@ fn testObjcpp(b: *Build, opts: Options) *Step {
1600 };1600 };
16011601
1602 const foo_o = addObject(b, opts, .{ .name = "foo", .objcpp_source_bytes = 1602 const foo_o = addObject(b, opts, .{ .name = "foo", .objcpp_source_bytes =
1603 \\#import "Foo.h"1603 \\#import "Foo.h"
1604 \\@implementation Foo1604 \\@implementation Foo
1605 \\- (NSString *)name1605 \\- (NSString *)name
1606 \\{1606 \\{
1607 \\ NSString *str = [[NSString alloc] initWithFormat:@"Zig"];1607 \\ NSString *str = [[NSString alloc] initWithFormat:@"Zig"];
1608 \\ return str;1608 \\ return str;
1609 \\}1609 \\}
1610 \\@end1610 \\@end
1611 });1611 });
1612 foo_o.root_module.addIncludePath(foo_h.dirname());1612 foo_o.root_module.addIncludePath(foo_h.dirname());
1613 foo_o.linkLibCpp();1613 foo_o.linkLibCpp();
16141614
1615 const exe = addExecutable(b, opts, .{ .name = "main", .objcpp_source_bytes = 1615 const exe = addExecutable(b, opts, .{ .name = "main", .objcpp_source_bytes =
1616 \\#import "Foo.h"1616 \\#import "Foo.h"
1617 \\#import <assert.h>1617 \\#import <assert.h>
1618 \\#include <iostream>1618 \\#include <iostream>
1619 \\int main(int argc, char *argv[])1619 \\int main(int argc, char *argv[])
1620 \\{1620 \\{
1621 \\ @autoreleasepool {1621 \\ @autoreleasepool {
1622 \\ Foo *foo = [[Foo alloc] init];1622 \\ Foo *foo = [[Foo alloc] init];
1623 \\ NSString *result = [foo name];1623 \\ NSString *result = [foo name];
1624 \\ std::cout << "Hello from C++ and " << [result UTF8String];1624 \\ std::cout << "Hello from C++ and " << [result UTF8String];
1625 \\ assert([result isEqualToString:@"Zig"]);1625 \\ assert([result isEqualToString:@"Zig"]);
1626 \\ return 0;1626 \\ return 0;
1627 \\ }1627 \\ }
1628 \\}1628 \\}
1629 });1629 });
1630 exe.root_module.addIncludePath(foo_h.dirname());1630 exe.root_module.addIncludePath(foo_h.dirname());
1631 exe.addObject(foo_o);1631 exe.addObject(foo_o);
...@@ -1677,21 +1677,21 @@ fn testReexportsZig(b: *Build, opts: Options) *Step {...@@ -1677,21 +1677,21 @@ fn testReexportsZig(b: *Build, opts: Options) *Step {
1677 const test_step = addTestStep(b, "reexports-zig", opts);1677 const test_step = addTestStep(b, "reexports-zig", opts);
16781678
1679 const lib = addStaticLibrary(b, opts, .{ .name = "a", .zig_source_bytes = 1679 const lib = addStaticLibrary(b, opts, .{ .name = "a", .zig_source_bytes =
1680 \\const x: i32 = 42;1680 \\const x: i32 = 42;
1681 \\export fn foo() i32 {1681 \\export fn foo() i32 {
1682 \\ return x;1682 \\ return x;
1683 \\}1683 \\}
1684 \\comptime {1684 \\comptime {
1685 \\ @export(&foo, .{ .name = "bar", .linkage = .strong });1685 \\ @export(&foo, .{ .name = "bar", .linkage = .strong });
1686 \\}1686 \\}
1687 });1687 });
16881688
1689 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 1689 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
1690 \\extern int foo();1690 \\extern int foo();
1691 \\extern int bar();1691 \\extern int bar();
1692 \\int main() {1692 \\int main() {
1693 \\ return bar() - foo();1693 \\ return bar() - foo();
1694 \\}1694 \\}
1695 });1695 });
1696 exe.linkLibrary(lib);1696 exe.linkLibrary(lib);
16971697
...@@ -1706,32 +1706,32 @@ fn testRelocatable(b: *Build, opts: Options) *Step {...@@ -1706,32 +1706,32 @@ fn testRelocatable(b: *Build, opts: Options) *Step {
1706 const test_step = addTestStep(b, "relocatable", opts);1706 const test_step = addTestStep(b, "relocatable", opts);
17071707
1708 const a_o = addObject(b, opts, .{ .name = "a", .cpp_source_bytes = 1708 const a_o = addObject(b, opts, .{ .name = "a", .cpp_source_bytes =
1709 \\#include <stdexcept>1709 \\#include <stdexcept>
1710 \\int try_me() {1710 \\int try_me() {
1711 \\ throw std::runtime_error("Oh no!");1711 \\ throw std::runtime_error("Oh no!");
1712 \\}1712 \\}
1713 });1713 });
1714 a_o.linkLibCpp();1714 a_o.linkLibCpp();
17151715
1716 const b_o = addObject(b, opts, .{ .name = "b", .cpp_source_bytes = 1716 const b_o = addObject(b, opts, .{ .name = "b", .cpp_source_bytes =
1717 \\extern int try_me();1717 \\extern int try_me();
1718 \\int try_again() {1718 \\int try_again() {
1719 \\ return try_me();1719 \\ return try_me();
1720 \\}1720 \\}
1721 });1721 });
17221722
1723 const main_o = addObject(b, opts, .{ .name = "main", .cpp_source_bytes = 1723 const main_o = addObject(b, opts, .{ .name = "main", .cpp_source_bytes =
1724 \\#include <iostream>1724 \\#include <iostream>
1725 \\#include <stdexcept>1725 \\#include <stdexcept>
1726 \\extern int try_again();1726 \\extern int try_again();
1727 \\int main() {1727 \\int main() {
1728 \\ try {1728 \\ try {
1729 \\ try_again();1729 \\ try_again();
1730 \\ } catch (const std::exception &e) {1730 \\ } catch (const std::exception &e) {
1731 \\ std::cout << "exception=" << e.what();1731 \\ std::cout << "exception=" << e.what();
1732 \\ }1732 \\ }
1733 \\ return 0;1733 \\ return 0;
1734 \\}1734 \\}
1735 });1735 });
1736 main_o.linkLibCpp();1736 main_o.linkLibCpp();
17371737
...@@ -1774,34 +1774,34 @@ fn testRelocatableZig(b: *Build, opts: Options) *Step {...@@ -1774,34 +1774,34 @@ fn testRelocatableZig(b: *Build, opts: Options) *Step {
1774 const test_step = addTestStep(b, "relocatable-zig", opts);1774 const test_step = addTestStep(b, "relocatable-zig", opts);
17751775
1776 const a_o = addObject(b, opts, .{ .name = "a", .zig_source_bytes = 1776 const a_o = addObject(b, opts, .{ .name = "a", .zig_source_bytes =
1777 \\const std = @import("std");1777 \\const std = @import("std");
1778 \\export var foo: i32 = 0;1778 \\export var foo: i32 = 0;
1779 \\export fn incrFoo() void {1779 \\export fn incrFoo() void {
1780 \\ foo += 1;1780 \\ foo += 1;
1781 \\ std.debug.print("incrFoo={d}\n", .{foo});1781 \\ std.debug.print("incrFoo={d}\n", .{foo});
1782 \\}1782 \\}
1783 });1783 });
17841784
1785 const b_o = addObject(b, opts, .{ .name = "b", .zig_source_bytes = 1785 const b_o = addObject(b, opts, .{ .name = "b", .zig_source_bytes =
1786 \\const std = @import("std");1786 \\const std = @import("std");
1787 \\extern var foo: i32;1787 \\extern var foo: i32;
1788 \\export fn decrFoo() void {1788 \\export fn decrFoo() void {
1789 \\ foo -= 1;1789 \\ foo -= 1;
1790 \\ std.debug.print("decrFoo={d}\n", .{foo});1790 \\ std.debug.print("decrFoo={d}\n", .{foo});
1791 \\}1791 \\}
1792 });1792 });
17931793
1794 const main_o = addObject(b, opts, .{ .name = "main", .zig_source_bytes = 1794 const main_o = addObject(b, opts, .{ .name = "main", .zig_source_bytes =
1795 \\const std = @import("std");1795 \\const std = @import("std");
1796 \\extern var foo: i32;1796 \\extern var foo: i32;
1797 \\extern fn incrFoo() void;1797 \\extern fn incrFoo() void;
1798 \\extern fn decrFoo() void;1798 \\extern fn decrFoo() void;
1799 \\pub fn main() void {1799 \\pub fn main() void {
1800 \\ const init = foo;1800 \\ const init = foo;
1801 \\ incrFoo();1801 \\ incrFoo();
1802 \\ decrFoo();1802 \\ decrFoo();
1803 \\ if (init == foo) @panic("Oh no!");1803 \\ if (init == foo) @panic("Oh no!");
1804 \\}1804 \\}
1805 });1805 });
18061806
1807 const c_o = addObject(b, opts, .{ .name = "c" });1807 const c_o = addObject(b, opts, .{ .name = "c" });
...@@ -1825,11 +1825,11 @@ fn testSearchStrategy(b: *Build, opts: Options) *Step {...@@ -1825,11 +1825,11 @@ fn testSearchStrategy(b: *Build, opts: Options) *Step {
1825 const test_step = addTestStep(b, "search-strategy", opts);1825 const test_step = addTestStep(b, "search-strategy", opts);
18261826
1827 const obj = addObject(b, opts, .{ .name = "a", .c_source_bytes = 1827 const obj = addObject(b, opts, .{ .name = "a", .c_source_bytes =
1828 \\#include<stdio.h>1828 \\#include<stdio.h>
1829 \\char world[] = "world";1829 \\char world[] = "world";
1830 \\char* hello() {1830 \\char* hello() {
1831 \\ return "Hello";1831 \\ return "Hello";
1832 \\}1832 \\}
1833 });1833 });
18341834
1835 const liba = addStaticLibrary(b, opts, .{ .name = "a" });1835 const liba = addStaticLibrary(b, opts, .{ .name = "a" });
...@@ -1839,13 +1839,13 @@ fn testSearchStrategy(b: *Build, opts: Options) *Step {...@@ -1839,13 +1839,13 @@ fn testSearchStrategy(b: *Build, opts: Options) *Step {
1839 dylib.addObject(obj);1839 dylib.addObject(obj);
18401840
1841 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes = 1841 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes =
1842 \\#include<stdio.h>1842 \\#include<stdio.h>
1843 \\char* hello();1843 \\char* hello();
1844 \\extern char world[];1844 \\extern char world[];
1845 \\int main() {1845 \\int main() {
1846 \\ printf("%s %s", hello(), world);1846 \\ printf("%s %s", hello(), world);
1847 \\ return 0;1847 \\ return 0;
1848 \\}1848 \\}
1849 });1849 });
18501850
1851 {1851 {
...@@ -1973,23 +1973,23 @@ fn testSectionBoundarySymbols2(b: *Build, opts: Options) *Step {...@@ -1973,23 +1973,23 @@ fn testSectionBoundarySymbols2(b: *Build, opts: Options) *Step {
1973 const test_step = addTestStep(b, "section-boundary-symbols-2", opts);1973 const test_step = addTestStep(b, "section-boundary-symbols-2", opts);
19741974
1975 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 1975 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
1976 \\#include <stdio.h>1976 \\#include <stdio.h>
1977 \\struct pair { int a; int b; };1977 \\struct pair { int a; int b; };
1978 \\struct pair first __attribute__((section("__DATA,__pairs"))) = { 1, 2 };1978 \\struct pair first __attribute__((section("__DATA,__pairs"))) = { 1, 2 };
1979 \\struct pair second __attribute__((section("__DATA,__pairs"))) = { 3, 4 };1979 \\struct pair second __attribute__((section("__DATA,__pairs"))) = { 3, 4 };
1980 \\extern struct pair pairs_start __asm("section$start$__DATA$__pairs");1980 \\extern struct pair pairs_start __asm("section$start$__DATA$__pairs");
1981 \\extern struct pair pairs_end __asm("section$end$__DATA$__pairs");1981 \\extern struct pair pairs_end __asm("section$end$__DATA$__pairs");
1982 \\int main() {1982 \\int main() {
1983 \\ printf("%d,%d\n", first.a, first.b);1983 \\ printf("%d,%d\n", first.a, first.b);
1984 \\ printf("%d,%d\n", second.a, second.b);1984 \\ printf("%d,%d\n", second.a, second.b);
1985 \\ struct pair* p;1985 \\ struct pair* p;
1986 \\ for (p = &pairs_start; p < &pairs_end; p++) {1986 \\ for (p = &pairs_start; p < &pairs_end; p++) {
1987 \\ p->a = 0;1987 \\ p->a = 0;
1988 \\ }1988 \\ }
1989 \\ printf("%d,%d\n", first.a, first.b);1989 \\ printf("%d,%d\n", first.a, first.b);
1990 \\ printf("%d,%d\n", second.a, second.b);1990 \\ printf("%d,%d\n", second.a, second.b);
1991 \\ return 0;1991 \\ return 0;
1992 \\}1992 \\}
1993 });1993 });
19941994
1995 const run = b.addRunArtifact(exe);1995 const run = b.addRunArtifact(exe);
...@@ -2010,24 +2010,24 @@ fn testSegmentBoundarySymbols(b: *Build, opts: Options) *Step {...@@ -2010,24 +2010,24 @@ fn testSegmentBoundarySymbols(b: *Build, opts: Options) *Step {
2010 const test_step = addTestStep(b, "segment-boundary-symbols", opts);2010 const test_step = addTestStep(b, "segment-boundary-symbols", opts);
20112011
2012 const obj1 = addObject(b, opts, .{ .name = "a", .cpp_source_bytes = 2012 const obj1 = addObject(b, opts, .{ .name = "a", .cpp_source_bytes =
2013 \\constexpr const char* MESSAGE __attribute__((used, section("__DATA_CONST_1,__message_ptr"))) = "codebase";2013 \\constexpr const char* MESSAGE __attribute__((used, section("__DATA_CONST_1,__message_ptr"))) = "codebase";
2014 });2014 });
20152015
2016 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes = 2016 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes =
2017 \\#include <stdio.h>2017 \\#include <stdio.h>
2018 \\const char* interop();2018 \\const char* interop();
2019 \\int main() {2019 \\int main() {
2020 \\ printf("All your %s are belong to us.\n", interop());2020 \\ printf("All your %s are belong to us.\n", interop());
2021 \\ return 0;2021 \\ return 0;
2022 \\}2022 \\}
2023 });2023 });
20242024
2025 {2025 {
2026 const obj2 = addObject(b, opts, .{ .name = "b", .cpp_source_bytes = 2026 const obj2 = addObject(b, opts, .{ .name = "b", .cpp_source_bytes =
2027 \\extern const char* message_pointer __asm("segment$start$__DATA_CONST_1");2027 \\extern const char* message_pointer __asm("segment$start$__DATA_CONST_1");
2028 \\extern "C" const char* interop() {2028 \\extern "C" const char* interop() {
2029 \\ return message_pointer;2029 \\ return message_pointer;
2030 \\}2030 \\}
2031 });2031 });
20322032
2033 const exe = addExecutable(b, opts, .{ .name = "main" });2033 const exe = addExecutable(b, opts, .{ .name = "main" });
...@@ -2047,10 +2047,10 @@ fn testSegmentBoundarySymbols(b: *Build, opts: Options) *Step {...@@ -2047,10 +2047,10 @@ fn testSegmentBoundarySymbols(b: *Build, opts: Options) *Step {
20472047
2048 {2048 {
2049 const obj2 = addObject(b, opts, .{ .name = "c", .cpp_source_bytes = 2049 const obj2 = addObject(b, opts, .{ .name = "c", .cpp_source_bytes =
2050 \\extern const char* message_pointer __asm("segment$start$__DATA_1");2050 \\extern const char* message_pointer __asm("segment$start$__DATA_1");
2051 \\extern "C" const char* interop() {2051 \\extern "C" const char* interop() {
2052 \\ return message_pointer;2052 \\ return message_pointer;
2053 \\}2053 \\}
2054 });2054 });
20552055
2056 const exe = addExecutable(b, opts, .{ .name = "main2" });2056 const exe = addExecutable(b, opts, .{ .name = "main2" });
...@@ -2078,27 +2078,27 @@ fn testSymbolStabs(b: *Build, opts: Options) *Step {...@@ -2078,27 +2078,27 @@ fn testSymbolStabs(b: *Build, opts: Options) *Step {
2078 const test_step = addTestStep(b, "symbol-stabs", opts);2078 const test_step = addTestStep(b, "symbol-stabs", opts);
20792079
2080 const a_o = addObject(b, opts, .{ .name = "a", .c_source_bytes = 2080 const a_o = addObject(b, opts, .{ .name = "a", .c_source_bytes =
2081 \\int foo = 42;2081 \\int foo = 42;
2082 \\int getFoo() {2082 \\int getFoo() {
2083 \\ return foo;2083 \\ return foo;
2084 \\}2084 \\}
2085 });2085 });
20862086
2087 const b_o = addObject(b, opts, .{ .name = "b", .c_source_bytes = 2087 const b_o = addObject(b, opts, .{ .name = "b", .c_source_bytes =
2088 \\int bar = 24;2088 \\int bar = 24;
2089 \\int getBar() {2089 \\int getBar() {
2090 \\ return bar;2090 \\ return bar;
2091 \\}2091 \\}
2092 });2092 });
20932093
2094 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes = 2094 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes =
2095 \\#include <stdio.h>2095 \\#include <stdio.h>
2096 \\extern int getFoo();2096 \\extern int getFoo();
2097 \\extern int getBar();2097 \\extern int getBar();
2098 \\int main() {2098 \\int main() {
2099 \\ printf("foo=%d,bar=%d", getFoo(), getBar());2099 \\ printf("foo=%d,bar=%d", getFoo(), getBar());
2100 \\ return 0;2100 \\ return 0;
2101 \\}2101 \\}
2102 });2102 });
21032103
2104 const exe = addExecutable(b, opts, .{ .name = "main" });2104 const exe = addExecutable(b, opts, .{ .name = "main" });
...@@ -2162,11 +2162,11 @@ fn testTbdv3(b: *Build, opts: Options) *Step {...@@ -2162,11 +2162,11 @@ fn testTbdv3(b: *Build, opts: Options) *Step {
2162 };2162 };
21632163
2164 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 2164 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
2165 \\#include <stdio.h>2165 \\#include <stdio.h>
2166 \\int getFoo();2166 \\int getFoo();
2167 \\int main() {2167 \\int main() {
2168 \\ return getFoo() - 42;2168 \\ return getFoo() - 42;
2169 \\}2169 \\}
2170 });2170 });
2171 exe.root_module.linkSystemLibrary("a", .{});2171 exe.root_module.linkSystemLibrary("a", .{});
2172 exe.root_module.addLibraryPath(tbd.dirname());2172 exe.root_module.addLibraryPath(tbd.dirname());
...@@ -2209,18 +2209,18 @@ fn testThunks(b: *Build, opts: Options) *Step {...@@ -2209,18 +2209,18 @@ fn testThunks(b: *Build, opts: Options) *Step {
2209 const test_step = addTestStep(b, "thunks", opts);2209 const test_step = addTestStep(b, "thunks", opts);
22102210
2211 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 2211 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
2212 \\#include <stdio.h>2212 \\#include <stdio.h>
2213 \\void bar() {2213 \\void bar() {
2214 \\ printf("bar");2214 \\ printf("bar");
2215 \\}2215 \\}
2216 \\void foo() {2216 \\void foo() {
2217 \\ fprintf(stdout, "foo");2217 \\ fprintf(stdout, "foo");
2218 \\}2218 \\}
2219 \\int main() {2219 \\int main() {
2220 \\ foo();2220 \\ foo();
2221 \\ bar();2221 \\ bar();
2222 \\ return 0;2222 \\ return 0;
2223 \\}2223 \\}
2224 });2224 });
22252225
2226 const check = exe.checkObject();2226 const check = exe.checkObject();
...@@ -2241,24 +2241,24 @@ fn testTls(b: *Build, opts: Options) *Step {...@@ -2241,24 +2241,24 @@ fn testTls(b: *Build, opts: Options) *Step {
2241 const test_step = addTestStep(b, "tls", opts);2241 const test_step = addTestStep(b, "tls", opts);
22422242
2243 const dylib = addSharedLibrary(b, opts, .{ .name = "a", .c_source_bytes = 2243 const dylib = addSharedLibrary(b, opts, .{ .name = "a", .c_source_bytes =
2244 \\_Thread_local int a;2244 \\_Thread_local int a;
2245 \\int getA() {2245 \\int getA() {
2246 \\ return a;2246 \\ return a;
2247 \\}2247 \\}
2248 });2248 });
22492249
2250 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 2250 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
2251 \\#include<stdio.h>2251 \\#include<stdio.h>
2252 \\extern _Thread_local int a;2252 \\extern _Thread_local int a;
2253 \\extern int getA();2253 \\extern int getA();
2254 \\int getA2() {2254 \\int getA2() {
2255 \\ return a;2255 \\ return a;
2256 \\}2256 \\}
2257 \\int main() {2257 \\int main() {
2258 \\ a = 2;2258 \\ a = 2;
2259 \\ printf("%d %d %d", a, getA(), getA2());2259 \\ printf("%d %d %d", a, getA(), getA2());
2260 \\ return 0;2260 \\ return 0;
2261 \\}2261 \\}
2262 });2262 });
2263 exe.root_module.linkSystemLibrary("a", .{});2263 exe.root_module.linkSystemLibrary("a", .{});
2264 exe.root_module.addLibraryPath(dylib.getEmittedBinDirectory());2264 exe.root_module.addLibraryPath(dylib.getEmittedBinDirectory());
...@@ -2292,33 +2292,33 @@ fn testTlsPointers(b: *Build, opts: Options) *Step {...@@ -2292,33 +2292,33 @@ fn testTlsPointers(b: *Build, opts: Options) *Step {
2292 };2292 };
22932293
2294 const bar_o = addObject(b, opts, .{ .name = "bar", .cpp_source_bytes = 2294 const bar_o = addObject(b, opts, .{ .name = "bar", .cpp_source_bytes =
2295 \\#include "foo.h"2295 \\#include "foo.h"
2296 \\int bar() {2296 \\int bar() {
2297 \\ int v1 = Foo<int>::getVar();2297 \\ int v1 = Foo<int>::getVar();
2298 \\ return v1;2298 \\ return v1;
2299 \\}2299 \\}
2300 });2300 });
2301 bar_o.root_module.addIncludePath(foo_h.dirname());2301 bar_o.root_module.addIncludePath(foo_h.dirname());
2302 bar_o.linkLibCpp();2302 bar_o.linkLibCpp();
23032303
2304 const baz_o = addObject(b, opts, .{ .name = "baz", .cpp_source_bytes = 2304 const baz_o = addObject(b, opts, .{ .name = "baz", .cpp_source_bytes =
2305 \\#include "foo.h"2305 \\#include "foo.h"
2306 \\int baz() {2306 \\int baz() {
2307 \\ int v1 = Foo<unsigned>::getVar();2307 \\ int v1 = Foo<unsigned>::getVar();
2308 \\ return v1;2308 \\ return v1;
2309 \\}2309 \\}
2310 });2310 });
2311 baz_o.root_module.addIncludePath(foo_h.dirname());2311 baz_o.root_module.addIncludePath(foo_h.dirname());
2312 baz_o.linkLibCpp();2312 baz_o.linkLibCpp();
23132313
2314 const main_o = addObject(b, opts, .{ .name = "main", .cpp_source_bytes = 2314 const main_o = addObject(b, opts, .{ .name = "main", .cpp_source_bytes =
2315 \\extern int bar();2315 \\extern int bar();
2316 \\extern int baz();2316 \\extern int baz();
2317 \\int main() {2317 \\int main() {
2318 \\ int v1 = bar();2318 \\ int v1 = bar();
2319 \\ int v2 = baz();2319 \\ int v2 = baz();
2320 \\ return v1 != v2;2320 \\ return v1 != v2;
2321 \\}2321 \\}
2322 });2322 });
2323 main_o.root_module.addIncludePath(foo_h.dirname());2323 main_o.root_module.addIncludePath(foo_h.dirname());
2324 main_o.linkLibCpp();2324 main_o.linkLibCpp();
...@@ -2340,14 +2340,14 @@ fn testTlsLargeTbss(b: *Build, opts: Options) *Step {...@@ -2340,14 +2340,14 @@ fn testTlsLargeTbss(b: *Build, opts: Options) *Step {
2340 const test_step = addTestStep(b, "tls-large-tbss", opts);2340 const test_step = addTestStep(b, "tls-large-tbss", opts);
23412341
2342 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 2342 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
2343 \\#include <stdio.h>2343 \\#include <stdio.h>
2344 \\_Thread_local int x[0x8000];2344 \\_Thread_local int x[0x8000];
2345 \\_Thread_local int y[0x8000];2345 \\_Thread_local int y[0x8000];
2346 \\int main() {2346 \\int main() {
2347 \\ x[0] = 3;2347 \\ x[0] = 3;
2348 \\ x[0x7fff] = 5;2348 \\ x[0x7fff] = 5;
2349 \\ printf("%d %d %d %d %d %d\n", x[0], x[1], x[0x7fff], y[0], y[1], y[0x7fff]);2349 \\ printf("%d %d %d %d %d %d\n", x[0], x[1], x[0x7fff], y[0], y[1], y[0x7fff]);
2350 \\}2350 \\}
2351 });2351 });
23522352
2353 const run = addRunArtifact(exe);2353 const run = addRunArtifact(exe);
...@@ -2361,15 +2361,15 @@ fn testTlsZig(b: *Build, opts: Options) *Step {...@@ -2361,15 +2361,15 @@ fn testTlsZig(b: *Build, opts: Options) *Step {
2361 const test_step = addTestStep(b, "tls-zig", opts);2361 const test_step = addTestStep(b, "tls-zig", opts);
23622362
2363 const exe = addExecutable(b, opts, .{ .name = "main", .zig_source_bytes = 2363 const exe = addExecutable(b, opts, .{ .name = "main", .zig_source_bytes =
2364 \\const std = @import("std");2364 \\const std = @import("std");
2365 \\threadlocal var x: i32 = 0;2365 \\threadlocal var x: i32 = 0;
2366 \\threadlocal var y: i32 = -1;2366 \\threadlocal var y: i32 = -1;
2367 \\pub fn main() void {2367 \\pub fn main() void {
2368 \\ std.io.getStdOut().writer().print("{d} {d}\n", .{x, y}) catch unreachable;2368 \\ std.io.getStdOut().writer().print("{d} {d}\n", .{x, y}) catch unreachable;
2369 \\ x -= 1;2369 \\ x -= 1;
2370 \\ y += 1;2370 \\ y += 1;
2371 \\ std.io.getStdOut().writer().print("{d} {d}\n", .{x, y}) catch unreachable;2371 \\ std.io.getStdOut().writer().print("{d} {d}\n", .{x, y}) catch unreachable;
2372 \\}2372 \\}
2373 });2373 });
23742374
2375 const run = addRunArtifact(exe);2375 const run = addRunArtifact(exe);
...@@ -2387,15 +2387,15 @@ fn testTwoLevelNamespace(b: *Build, opts: Options) *Step {...@@ -2387,15 +2387,15 @@ fn testTwoLevelNamespace(b: *Build, opts: Options) *Step {
2387 const test_step = addTestStep(b, "two-level-namespace", opts);2387 const test_step = addTestStep(b, "two-level-namespace", opts);
23882388
2389 const liba = addSharedLibrary(b, opts, .{ .name = "a", .c_source_bytes = 2389 const liba = addSharedLibrary(b, opts, .{ .name = "a", .c_source_bytes =
2390 \\#include <stdio.h>2390 \\#include <stdio.h>
2391 \\int foo = 1;2391 \\int foo = 1;
2392 \\int* ptr_to_foo = &foo;2392 \\int* ptr_to_foo = &foo;
2393 \\int getFoo() {2393 \\int getFoo() {
2394 \\ return foo;2394 \\ return foo;
2395 \\}2395 \\}
2396 \\void printInA() {2396 \\void printInA() {
2397 \\ printf("liba: getFoo()=%d, ptr_to_foo=%d\n", getFoo(), *ptr_to_foo);2397 \\ printf("liba: getFoo()=%d, ptr_to_foo=%d\n", getFoo(), *ptr_to_foo);
2398 \\}2398 \\}
2399 });2399 });
24002400
2401 {2401 {
...@@ -2408,15 +2408,15 @@ fn testTwoLevelNamespace(b: *Build, opts: Options) *Step {...@@ -2408,15 +2408,15 @@ fn testTwoLevelNamespace(b: *Build, opts: Options) *Step {
2408 }2408 }
24092409
2410 const libb = addSharedLibrary(b, opts, .{ .name = "b", .c_source_bytes = 2410 const libb = addSharedLibrary(b, opts, .{ .name = "b", .c_source_bytes =
2411 \\#include <stdio.h>2411 \\#include <stdio.h>
2412 \\int foo = 2;2412 \\int foo = 2;
2413 \\int* ptr_to_foo = &foo;2413 \\int* ptr_to_foo = &foo;
2414 \\int getFoo() {2414 \\int getFoo() {
2415 \\ return foo;2415 \\ return foo;
2416 \\}2416 \\}
2417 \\void printInB() {2417 \\void printInB() {
2418 \\ printf("libb: getFoo()=%d, ptr_to_foo=%d\n", getFoo(), *ptr_to_foo);2418 \\ printf("libb: getFoo()=%d, ptr_to_foo=%d\n", getFoo(), *ptr_to_foo);
2419 \\}2419 \\}
2420 });2420 });
24212421
2422 {2422 {
...@@ -2429,17 +2429,17 @@ fn testTwoLevelNamespace(b: *Build, opts: Options) *Step {...@@ -2429,17 +2429,17 @@ fn testTwoLevelNamespace(b: *Build, opts: Options) *Step {
2429 }2429 }
24302430
2431 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes = 2431 const main_o = addObject(b, opts, .{ .name = "main", .c_source_bytes =
2432 \\#include <stdio.h>2432 \\#include <stdio.h>
2433 \\int getFoo();2433 \\int getFoo();
2434 \\extern int* ptr_to_foo;2434 \\extern int* ptr_to_foo;
2435 \\void printInA();2435 \\void printInA();
2436 \\void printInB();2436 \\void printInB();
2437 \\int main() {2437 \\int main() {
2438 \\ printf("main: getFoo()=%d, ptr_to_foo=%d\n", getFoo(), *ptr_to_foo);2438 \\ printf("main: getFoo()=%d, ptr_to_foo=%d\n", getFoo(), *ptr_to_foo);
2439 \\ printInA();2439 \\ printInA();
2440 \\ printInB();2440 \\ printInB();
2441 \\ return 0;2441 \\ return 0;
2442 \\}2442 \\}
2443 });2443 });
24442444
2445 {2445 {
...@@ -2629,17 +2629,17 @@ fn testUnresolvedError(b: *Build, opts: Options) *Step {...@@ -2629,17 +2629,17 @@ fn testUnresolvedError(b: *Build, opts: Options) *Step {
2629 const test_step = addTestStep(b, "unresolved-error", opts);2629 const test_step = addTestStep(b, "unresolved-error", opts);
26302630
2631 const obj = addObject(b, opts, .{ .name = "a", .zig_source_bytes = 2631 const obj = addObject(b, opts, .{ .name = "a", .zig_source_bytes =
2632 \\extern fn foo() i32;2632 \\extern fn foo() i32;
2633 \\export fn bar() i32 { return foo() + 1; }2633 \\export fn bar() i32 { return foo() + 1; }
2634 });2634 });
26352635
2636 const exe = addExecutable(b, opts, .{ .name = "main", .zig_source_bytes = 2636 const exe = addExecutable(b, opts, .{ .name = "main", .zig_source_bytes =
2637 \\const std = @import("std");2637 \\const std = @import("std");
2638 \\extern fn foo() i32;2638 \\extern fn foo() i32;
2639 \\extern fn bar() i32;2639 \\extern fn bar() i32;
2640 \\pub fn main() void {2640 \\pub fn main() void {
2641 \\ std.debug.print("foo() + bar() = {d}", .{foo() + bar()});2641 \\ std.debug.print("foo() + bar() = {d}", .{foo() + bar()});
2642 \\}2642 \\}
2643 });2643 });
2644 exe.addObject(obj);2644 exe.addObject(obj);
26452645
...@@ -2665,17 +2665,17 @@ fn testUnresolvedError2(b: *Build, opts: Options) *Step {...@@ -2665,17 +2665,17 @@ fn testUnresolvedError2(b: *Build, opts: Options) *Step {
2665 const test_step = addTestStep(b, "unresolved-error-2", opts);2665 const test_step = addTestStep(b, "unresolved-error-2", opts);
26662666
2667 const exe = addExecutable(b, opts, .{ .name = "main", .zig_source_bytes = 2667 const exe = addExecutable(b, opts, .{ .name = "main", .zig_source_bytes =
2668 \\pub fn main() !void {2668 \\pub fn main() !void {
2669 \\ const msg_send_fn = @extern(2669 \\ const msg_send_fn = @extern(
2670 \\ *const fn () callconv(.C) usize,2670 \\ *const fn () callconv(.C) usize,
2671 \\ .{ .name = "objc_msgSend$initWithContentRect:styleMask:backing:defer:screen:" },2671 \\ .{ .name = "objc_msgSend$initWithContentRect:styleMask:backing:defer:screen:" },
2672 \\ );2672 \\ );
2673 \\ _ = @call(2673 \\ _ = @call(
2674 \\ .auto,2674 \\ .auto,
2675 \\ msg_send_fn,2675 \\ msg_send_fn,
2676 \\ .{},2676 \\ .{},
2677 \\ );2677 \\ );
2678 \\}2678 \\}
2679 });2679 });
26802680
2681 expectLinkErrors(exe, test_step, .{ .exact = &.{2681 expectLinkErrors(exe, test_step, .{ .exact = &.{
...@@ -2737,82 +2737,82 @@ fn testUnwindInfo(b: *Build, opts: Options) *Step {...@@ -2737,82 +2737,82 @@ fn testUnwindInfo(b: *Build, opts: Options) *Step {
2737 };2737 };
27382738
2739 const main_o = addObject(b, opts, .{ .name = "main", .cpp_source_bytes = 2739 const main_o = addObject(b, opts, .{ .name = "main", .cpp_source_bytes =
2740 \\#include "all.h"2740 \\#include "all.h"
2741 \\#include <cstdio>2741 \\#include <cstdio>
2742 \\2742 \\
2743 \\void fn_c() {2743 \\void fn_c() {
2744 \\ SimpleStringOwner c{ "cccccccccc" };2744 \\ SimpleStringOwner c{ "cccccccccc" };
2745 \\}2745 \\}
2746 \\2746 \\
2747 \\void fn_b() {2747 \\void fn_b() {
2748 \\ SimpleStringOwner b{ "b" };2748 \\ SimpleStringOwner b{ "b" };
2749 \\ fn_c();2749 \\ fn_c();
2750 \\}2750 \\}
2751 \\2751 \\
2752 \\int main() {2752 \\int main() {
2753 \\ try {2753 \\ try {
2754 \\ SimpleStringOwner a{ "a" };2754 \\ SimpleStringOwner a{ "a" };
2755 \\ fn_b();2755 \\ fn_b();
2756 \\ SimpleStringOwner d{ "d" };2756 \\ SimpleStringOwner d{ "d" };
2757 \\ } catch (const Error& e) {2757 \\ } catch (const Error& e) {
2758 \\ printf("Error: %s\n", e.what());2758 \\ printf("Error: %s\n", e.what());
2759 \\ } catch(const std::exception& e) {2759 \\ } catch(const std::exception& e) {
2760 \\ printf("Exception: %s\n", e.what());2760 \\ printf("Exception: %s\n", e.what());
2761 \\ }2761 \\ }
2762 \\ return 0;2762 \\ return 0;
2763 \\}2763 \\}
2764 });2764 });
2765 main_o.root_module.addIncludePath(all_h.dirname());2765 main_o.root_module.addIncludePath(all_h.dirname());
2766 main_o.linkLibCpp();2766 main_o.linkLibCpp();
27672767
2768 const simple_string_o = addObject(b, opts, .{ .name = "simple_string", .cpp_source_bytes = 2768 const simple_string_o = addObject(b, opts, .{ .name = "simple_string", .cpp_source_bytes =
2769 \\#include "all.h"2769 \\#include "all.h"
2770 \\#include <cstdio>2770 \\#include <cstdio>
2771 \\#include <cstring>2771 \\#include <cstring>
2772 \\2772 \\
2773 \\SimpleString::SimpleString(size_t max_size)2773 \\SimpleString::SimpleString(size_t max_size)
2774 \\: max_size{ max_size }, length{} {2774 \\: max_size{ max_size }, length{} {
2775 \\ if (max_size == 0) {2775 \\ if (max_size == 0) {
2776 \\ throw Error{ "Max size must be at least 1." };2776 \\ throw Error{ "Max size must be at least 1." };
2777 \\ }2777 \\ }
2778 \\ buffer = new char[max_size];2778 \\ buffer = new char[max_size];
2779 \\ buffer[0] = 0;2779 \\ buffer[0] = 0;
2780 \\}2780 \\}
2781 \\2781 \\
2782 \\SimpleString::~SimpleString() {2782 \\SimpleString::~SimpleString() {
2783 \\ delete[] buffer;2783 \\ delete[] buffer;
2784 \\}2784 \\}
2785 \\2785 \\
2786 \\void SimpleString::print(const char* tag) const {2786 \\void SimpleString::print(const char* tag) const {
2787 \\ printf("%s: %s", tag, buffer);2787 \\ printf("%s: %s", tag, buffer);
2788 \\}2788 \\}
2789 \\2789 \\
2790 \\bool SimpleString::append_line(const char* x) {2790 \\bool SimpleString::append_line(const char* x) {
2791 \\ const auto x_len = strlen(x);2791 \\ const auto x_len = strlen(x);
2792 \\ if (x_len + length + 2 > max_size) return false;2792 \\ if (x_len + length + 2 > max_size) return false;
2793 \\ std::strncpy(buffer + length, x, max_size - length);2793 \\ std::strncpy(buffer + length, x, max_size - length);
2794 \\ length += x_len;2794 \\ length += x_len;
2795 \\ buffer[length++] = '\n';2795 \\ buffer[length++] = '\n';
2796 \\ buffer[length] = 0;2796 \\ buffer[length] = 0;
2797 \\ return true;2797 \\ return true;
2798 \\}2798 \\}
2799 });2799 });
2800 simple_string_o.root_module.addIncludePath(all_h.dirname());2800 simple_string_o.root_module.addIncludePath(all_h.dirname());
2801 simple_string_o.linkLibCpp();2801 simple_string_o.linkLibCpp();
28022802
2803 const simple_string_owner_o = addObject(b, opts, .{ .name = "simple_string_owner", .cpp_source_bytes = 2803 const simple_string_owner_o = addObject(b, opts, .{ .name = "simple_string_owner", .cpp_source_bytes =
2804 \\#include "all.h"2804 \\#include "all.h"
2805 \\2805 \\
2806 \\SimpleStringOwner::SimpleStringOwner(const char* x) : string{ 10 } {2806 \\SimpleStringOwner::SimpleStringOwner(const char* x) : string{ 10 } {
2807 \\ if (!string.append_line(x)) {2807 \\ if (!string.append_line(x)) {
2808 \\ throw Error{ "Not enough memory!" };2808 \\ throw Error{ "Not enough memory!" };
2809 \\ }2809 \\ }
2810 \\ string.print("Constructed");2810 \\ string.print("Constructed");
2811 \\}2811 \\}
2812 \\2812 \\
2813 \\SimpleStringOwner::~SimpleStringOwner() {2813 \\SimpleStringOwner::~SimpleStringOwner() {
2814 \\ string.print("About to destroy");2814 \\ string.print("About to destroy");
2815 \\}2815 \\}
2816 });2816 });
2817 simple_string_owner_o.root_module.addIncludePath(all_h.dirname());2817 simple_string_owner_o.root_module.addIncludePath(all_h.dirname());
2818 simple_string_owner_o.linkLibCpp();2818 simple_string_owner_o.linkLibCpp();
...@@ -2848,52 +2848,52 @@ fn testUnwindInfoNoSubsectionsArm64(b: *Build, opts: Options) *Step {...@@ -2848,52 +2848,52 @@ fn testUnwindInfoNoSubsectionsArm64(b: *Build, opts: Options) *Step {
2848 const test_step = addTestStep(b, "unwind-info-no-subsections-arm64", opts);2848 const test_step = addTestStep(b, "unwind-info-no-subsections-arm64", opts);
28492849
2850 const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes = 2850 const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes =
2851 \\.globl _foo2851 \\.globl _foo
2852 \\.align 42852 \\.align 4
2853 \\_foo:2853 \\_foo:
2854 \\ .cfi_startproc2854 \\ .cfi_startproc
2855 \\ stp x29, x30, [sp, #-32]!2855 \\ stp x29, x30, [sp, #-32]!
2856 \\ .cfi_def_cfa_offset 322856 \\ .cfi_def_cfa_offset 32
2857 \\ .cfi_offset w30, -242857 \\ .cfi_offset w30, -24
2858 \\ .cfi_offset w29, -322858 \\ .cfi_offset w29, -32
2859 \\ mov x29, sp2859 \\ mov x29, sp
2860 \\ .cfi_def_cfa w29, 322860 \\ .cfi_def_cfa w29, 32
2861 \\ bl _bar2861 \\ bl _bar
2862 \\ ldp x29, x30, [sp], #322862 \\ ldp x29, x30, [sp], #32
2863 \\ .cfi_restore w292863 \\ .cfi_restore w29
2864 \\ .cfi_restore w302864 \\ .cfi_restore w30
2865 \\ .cfi_def_cfa_offset 02865 \\ .cfi_def_cfa_offset 0
2866 \\ ret2866 \\ ret
2867 \\ .cfi_endproc2867 \\ .cfi_endproc
2868 \\2868 \\
2869 \\.globl _bar2869 \\.globl _bar
2870 \\.align 42870 \\.align 4
2871 \\_bar:2871 \\_bar:
2872 \\ .cfi_startproc2872 \\ .cfi_startproc
2873 \\ sub sp, sp, #322873 \\ sub sp, sp, #32
2874 \\ .cfi_def_cfa_offset -322874 \\ .cfi_def_cfa_offset -32
2875 \\ stp x29, x30, [sp, #16]2875 \\ stp x29, x30, [sp, #16]
2876 \\ .cfi_offset w30, -242876 \\ .cfi_offset w30, -24
2877 \\ .cfi_offset w29, -322877 \\ .cfi_offset w29, -32
2878 \\ mov x29, sp2878 \\ mov x29, sp
2879 \\ .cfi_def_cfa w29, 322879 \\ .cfi_def_cfa w29, 32
2880 \\ mov w0, #42880 \\ mov w0, #4
2881 \\ ldp x29, x30, [sp, #16]2881 \\ ldp x29, x30, [sp, #16]
2882 \\ .cfi_restore w292882 \\ .cfi_restore w29
2883 \\ .cfi_restore w302883 \\ .cfi_restore w30
2884 \\ add sp, sp, #322884 \\ add sp, sp, #32
2885 \\ .cfi_def_cfa_offset 02885 \\ .cfi_def_cfa_offset 0
2886 \\ ret2886 \\ ret
2887 \\ .cfi_endproc2887 \\ .cfi_endproc
2888 });2888 });
28892889
2890 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 2890 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
2891 \\#include <stdio.h>2891 \\#include <stdio.h>
2892 \\int foo();2892 \\int foo();
2893 \\int main() {2893 \\int main() {
2894 \\ printf("%d\n", foo());2894 \\ printf("%d\n", foo());
2895 \\ return 0;2895 \\ return 0;
2896 \\}2896 \\}
2897 });2897 });
2898 exe.addObject(a_o);2898 exe.addObject(a_o);
28992899
...@@ -2908,44 +2908,44 @@ fn testUnwindInfoNoSubsectionsX64(b: *Build, opts: Options) *Step {...@@ -2908,44 +2908,44 @@ fn testUnwindInfoNoSubsectionsX64(b: *Build, opts: Options) *Step {
2908 const test_step = addTestStep(b, "unwind-info-no-subsections-x64", opts);2908 const test_step = addTestStep(b, "unwind-info-no-subsections-x64", opts);
29092909
2910 const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes = 2910 const a_o = addObject(b, opts, .{ .name = "a", .asm_source_bytes =
2911 \\.globl _foo2911 \\.globl _foo
2912 \\_foo:2912 \\_foo:
2913 \\ .cfi_startproc2913 \\ .cfi_startproc
2914 \\ push %rbp2914 \\ push %rbp
2915 \\ .cfi_def_cfa_offset 82915 \\ .cfi_def_cfa_offset 8
2916 \\ .cfi_offset %rbp, -82916 \\ .cfi_offset %rbp, -8
2917 \\ mov %rsp, %rbp2917 \\ mov %rsp, %rbp
2918 \\ .cfi_def_cfa_register %rbp2918 \\ .cfi_def_cfa_register %rbp
2919 \\ call _bar2919 \\ call _bar
2920 \\ pop %rbp2920 \\ pop %rbp
2921 \\ .cfi_restore %rbp2921 \\ .cfi_restore %rbp
2922 \\ .cfi_def_cfa_offset 02922 \\ .cfi_def_cfa_offset 0
2923 \\ ret2923 \\ ret
2924 \\ .cfi_endproc2924 \\ .cfi_endproc
2925 \\2925 \\
2926 \\.globl _bar2926 \\.globl _bar
2927 \\_bar:2927 \\_bar:
2928 \\ .cfi_startproc2928 \\ .cfi_startproc
2929 \\ push %rbp2929 \\ push %rbp
2930 \\ .cfi_def_cfa_offset 82930 \\ .cfi_def_cfa_offset 8
2931 \\ .cfi_offset %rbp, -82931 \\ .cfi_offset %rbp, -8
2932 \\ mov %rsp, %rbp2932 \\ mov %rsp, %rbp
2933 \\ .cfi_def_cfa_register %rbp2933 \\ .cfi_def_cfa_register %rbp
2934 \\ mov $4, %rax2934 \\ mov $4, %rax
2935 \\ pop %rbp2935 \\ pop %rbp
2936 \\ .cfi_restore %rbp2936 \\ .cfi_restore %rbp
2937 \\ .cfi_def_cfa_offset 02937 \\ .cfi_def_cfa_offset 0
2938 \\ ret2938 \\ ret
2939 \\ .cfi_endproc2939 \\ .cfi_endproc
2940 });2940 });
29412941
2942 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 2942 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
2943 \\#include <stdio.h>2943 \\#include <stdio.h>
2944 \\int foo();2944 \\int foo();
2945 \\int main() {2945 \\int main() {
2946 \\ printf("%d\n", foo());2946 \\ printf("%d\n", foo());
2947 \\ return 0;2947 \\ return 0;
2948 \\}2948 \\}
2949 });2949 });
2950 exe.addObject(a_o);2950 exe.addObject(a_o);
29512951
...@@ -2961,27 +2961,27 @@ fn testWeakBind(b: *Build, opts: Options) *Step {...@@ -2961,27 +2961,27 @@ fn testWeakBind(b: *Build, opts: Options) *Step {
2961 const test_step = addTestStep(b, "weak-bind", opts);2961 const test_step = addTestStep(b, "weak-bind", opts);
29622962
2963 const lib = addSharedLibrary(b, opts, .{ .name = "foo", .asm_source_bytes = 2963 const lib = addSharedLibrary(b, opts, .{ .name = "foo", .asm_source_bytes =
2964 \\.globl _weak_dysym2964 \\.globl _weak_dysym
2965 \\.weak_definition _weak_dysym2965 \\.weak_definition _weak_dysym
2966 \\_weak_dysym:2966 \\_weak_dysym:
2967 \\ .quad 0x12342967 \\ .quad 0x1234
2968 \\2968 \\
2969 \\.globl _weak_dysym_for_gotpcrel2969 \\.globl _weak_dysym_for_gotpcrel
2970 \\.weak_definition _weak_dysym_for_gotpcrel2970 \\.weak_definition _weak_dysym_for_gotpcrel
2971 \\_weak_dysym_for_gotpcrel:2971 \\_weak_dysym_for_gotpcrel:
2972 \\ .quad 0x12342972 \\ .quad 0x1234
2973 \\2973 \\
2974 \\.globl _weak_dysym_fn2974 \\.globl _weak_dysym_fn
2975 \\.weak_definition _weak_dysym_fn2975 \\.weak_definition _weak_dysym_fn
2976 \\_weak_dysym_fn:2976 \\_weak_dysym_fn:
2977 \\ ret2977 \\ ret
2978 \\2978 \\
2979 \\.section __DATA,__thread_vars,thread_local_variables2979 \\.section __DATA,__thread_vars,thread_local_variables
2980 \\2980 \\
2981 \\.globl _weak_dysym_tlv2981 \\.globl _weak_dysym_tlv
2982 \\.weak_definition _weak_dysym_tlv2982 \\.weak_definition _weak_dysym_tlv
2983 \\_weak_dysym_tlv:2983 \\_weak_dysym_tlv:
2984 \\ .quad 0x12342984 \\ .quad 0x1234
2985 });2985 });
29862986
2987 {2987 {
...@@ -2995,61 +2995,61 @@ fn testWeakBind(b: *Build, opts: Options) *Step {...@@ -2995,61 +2995,61 @@ fn testWeakBind(b: *Build, opts: Options) *Step {
2995 }2995 }
29962996
2997 const exe = addExecutable(b, opts, .{ .name = "main", .asm_source_bytes = 2997 const exe = addExecutable(b, opts, .{ .name = "main", .asm_source_bytes =
2998 \\.globl _main, _weak_external, _weak_external_for_gotpcrel, _weak_external_fn2998 \\.globl _main, _weak_external, _weak_external_for_gotpcrel, _weak_external_fn
2999 \\.weak_definition _weak_external, _weak_external_for_gotpcrel, _weak_external_fn, _weak_internal, _weak_internal_for_gotpcrel, _weak_internal_fn2999 \\.weak_definition _weak_external, _weak_external_for_gotpcrel, _weak_external_fn, _weak_internal, _weak_internal_for_gotpcrel, _weak_internal_fn
3000 \\3000 \\
3001 \\_main:3001 \\_main:
3002 \\ mov _weak_dysym_for_gotpcrel@GOTPCREL(%rip), %rax3002 \\ mov _weak_dysym_for_gotpcrel@GOTPCREL(%rip), %rax
3003 \\ mov _weak_external_for_gotpcrel@GOTPCREL(%rip), %rax3003 \\ mov _weak_external_for_gotpcrel@GOTPCREL(%rip), %rax
3004 \\ mov _weak_internal_for_gotpcrel@GOTPCREL(%rip), %rax3004 \\ mov _weak_internal_for_gotpcrel@GOTPCREL(%rip), %rax
3005 \\ mov _weak_tlv@TLVP(%rip), %rax3005 \\ mov _weak_tlv@TLVP(%rip), %rax
3006 \\ mov _weak_dysym_tlv@TLVP(%rip), %rax3006 \\ mov _weak_dysym_tlv@TLVP(%rip), %rax
3007 \\ mov _weak_internal_tlv@TLVP(%rip), %rax3007 \\ mov _weak_internal_tlv@TLVP(%rip), %rax
3008 \\ callq _weak_dysym_fn3008 \\ callq _weak_dysym_fn
3009 \\ callq _weak_external_fn3009 \\ callq _weak_external_fn
3010 \\ callq _weak_internal_fn3010 \\ callq _weak_internal_fn
3011 \\ mov $0, %rax3011 \\ mov $0, %rax
3012 \\ ret3012 \\ ret
3013 \\3013 \\
3014 \\_weak_external:3014 \\_weak_external:
3015 \\ .quad 0x12343015 \\ .quad 0x1234
3016 \\3016 \\
3017 \\_weak_external_for_gotpcrel:3017 \\_weak_external_for_gotpcrel:
3018 \\ .quad 0x12343018 \\ .quad 0x1234
3019 \\3019 \\
3020 \\_weak_external_fn:3020 \\_weak_external_fn:
3021 \\ ret3021 \\ ret
3022 \\3022 \\
3023 \\_weak_internal:3023 \\_weak_internal:
3024 \\ .quad 0x12343024 \\ .quad 0x1234
3025 \\3025 \\
3026 \\_weak_internal_for_gotpcrel:3026 \\_weak_internal_for_gotpcrel:
3027 \\ .quad 0x12343027 \\ .quad 0x1234
3028 \\3028 \\
3029 \\_weak_internal_fn:3029 \\_weak_internal_fn:
3030 \\ ret3030 \\ ret
3031 \\3031 \\
3032 \\.data3032 \\.data
3033 \\ .quad _weak_dysym3033 \\ .quad _weak_dysym
3034 \\ .quad _weak_external + 23034 \\ .quad _weak_external + 2
3035 \\ .quad _weak_internal3035 \\ .quad _weak_internal
3036 \\3036 \\
3037 \\.tbss _weak_tlv$tlv$init, 4, 23037 \\.tbss _weak_tlv$tlv$init, 4, 2
3038 \\.tbss _weak_internal_tlv$tlv$init, 4, 23038 \\.tbss _weak_internal_tlv$tlv$init, 4, 2
3039 \\3039 \\
3040 \\.section __DATA,__thread_vars,thread_local_variables3040 \\.section __DATA,__thread_vars,thread_local_variables
3041 \\.globl _weak_tlv3041 \\.globl _weak_tlv
3042 \\.weak_definition _weak_tlv, _weak_internal_tlv3042 \\.weak_definition _weak_tlv, _weak_internal_tlv
3043 \\3043 \\
3044 \\_weak_tlv:3044 \\_weak_tlv:
3045 \\ .quad __tlv_bootstrap3045 \\ .quad __tlv_bootstrap
3046 \\ .quad 03046 \\ .quad 0
3047 \\ .quad _weak_tlv$tlv$init3047 \\ .quad _weak_tlv$tlv$init
3048 \\3048 \\
3049 \\_weak_internal_tlv:3049 \\_weak_internal_tlv:
3050 \\ .quad __tlv_bootstrap3050 \\ .quad __tlv_bootstrap
3051 \\ .quad 03051 \\ .quad 0
3052 \\ .quad _weak_internal_tlv$tlv$init3052 \\ .quad _weak_internal_tlv$tlv$init
3053 });3053 });
3054 exe.linkLibrary(lib);3054 exe.linkLibrary(lib);
30553055
...@@ -3111,23 +3111,23 @@ fn testWeakLibrary(b: *Build, opts: Options) *Step {...@@ -3111,23 +3111,23 @@ fn testWeakLibrary(b: *Build, opts: Options) *Step {
3111 const test_step = addTestStep(b, "weak-library", opts);3111 const test_step = addTestStep(b, "weak-library", opts);
31123112
3113 const dylib = addSharedLibrary(b, opts, .{ .name = "a", .c_source_bytes = 3113 const dylib = addSharedLibrary(b, opts, .{ .name = "a", .c_source_bytes =
3114 \\#include<stdio.h>3114 \\#include<stdio.h>
3115 \\int a = 42;3115 \\int a = 42;
3116 \\const char* asStr() {3116 \\const char* asStr() {
3117 \\ static char str[3];3117 \\ static char str[3];
3118 \\ sprintf(str, "%d", 42);3118 \\ sprintf(str, "%d", 42);
3119 \\ return str;3119 \\ return str;
3120 \\}3120 \\}
3121 });3121 });
31223122
3123 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 3123 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
3124 \\#include<stdio.h>3124 \\#include<stdio.h>
3125 \\extern int a;3125 \\extern int a;
3126 \\extern const char* asStr();3126 \\extern const char* asStr();
3127 \\int main() {3127 \\int main() {
3128 \\ printf("%d %s", a, asStr());3128 \\ printf("%d %s", a, asStr());
3129 \\ return 0;3129 \\ return 0;
3130 \\}3130 \\}
3131 });3131 });
3132 exe.root_module.linkSystemLibrary("a", .{ .weak = true });3132 exe.root_module.linkSystemLibrary("a", .{ .weak = true });
3133 exe.root_module.addLibraryPath(dylib.getEmittedBinDirectory());3133 exe.root_module.addLibraryPath(dylib.getEmittedBinDirectory());
...@@ -3154,11 +3154,11 @@ fn testWeakRef(b: *Build, opts: Options) *Step {...@@ -3154,11 +3154,11 @@ fn testWeakRef(b: *Build, opts: Options) *Step {
3154 const test_step = addTestStep(b, "weak-ref", opts);3154 const test_step = addTestStep(b, "weak-ref", opts);
31553155
3156 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 3156 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
3157 \\#include <stdio.h>3157 \\#include <stdio.h>
3158 \\#include <sys/_types/_fd_def.h>3158 \\#include <sys/_types/_fd_def.h>
3159 \\int main(int argc, char** argv) {3159 \\int main(int argc, char** argv) {
3160 \\ printf("__darwin_check_fd_set_overflow: %p\n", __darwin_check_fd_set_overflow);3160 \\ printf("__darwin_check_fd_set_overflow: %p\n", __darwin_check_fd_set_overflow);
3161 \\}3161 \\}
3162 });3162 });
31633163
3164 const check = exe.checkObject();3164 const check = exe.checkObject();
tools/doctest.zig+1-1
...@@ -203,7 +203,7 @@ fn printOutput(...@@ -203,7 +203,7 @@ fn printOutput(
203 if (mem.startsWith(u8, triple, "wasm32") or203 if (mem.startsWith(u8, triple, "wasm32") or
204 mem.startsWith(u8, triple, "riscv64-linux") or204 mem.startsWith(u8, triple, "riscv64-linux") or
205 (mem.startsWith(u8, triple, "x86_64-linux") and205 (mem.startsWith(u8, triple, "x86_64-linux") and
206 builtin.os.tag != .linux or builtin.cpu.arch != .x86_64))206 builtin.os.tag != .linux or builtin.cpu.arch != .x86_64))
207 {207 {
208 // skip execution208 // skip execution
209 break :code_block;209 break :code_block;
tools/fetch_them_macos_headers.zig+2-2
...@@ -99,8 +99,8 @@ pub fn main() anyerror!void {...@@ -99,8 +99,8 @@ pub fn main() anyerror!void {
9999
100 const version = Version.parse(parsed_json.value.DefaultProperties.MACOSX_DEPLOYMENT_TARGET) orelse100 const version = Version.parse(parsed_json.value.DefaultProperties.MACOSX_DEPLOYMENT_TARGET) orelse
101 fatal("don't know how to parse SDK version: {s}", .{101 fatal("don't know how to parse SDK version: {s}", .{
102 parsed_json.value.DefaultProperties.MACOSX_DEPLOYMENT_TARGET,102 parsed_json.value.DefaultProperties.MACOSX_DEPLOYMENT_TARGET,
103 });103 });
104 const os_ver: OsVer = switch (version.major) {104 const os_ver: OsVer = switch (version.major) {
105 10 => .catalina,105 10 => .catalina,
106 11 => .big_sur,106 11 => .big_sur,
tools/update_clang_options.zig+1-1
...@@ -761,7 +761,7 @@ pub fn main() anyerror!void {...@@ -761,7 +761,7 @@ pub fn main() anyerror!void {
761 if ((std.mem.startsWith(u8, name, "mno-") and761 if ((std.mem.startsWith(u8, name, "mno-") and
762 llvm_to_zig_cpu_features.contains(name["mno-".len..])) or762 llvm_to_zig_cpu_features.contains(name["mno-".len..])) or
763 (std.mem.startsWith(u8, name, "m") and763 (std.mem.startsWith(u8, name, "m") and
764 llvm_to_zig_cpu_features.contains(name["m".len..])))764 llvm_to_zig_cpu_features.contains(name["m".len..])))
765 {765 {
766 try stdout.print("m(\"{s}\"),\n", .{name});766 try stdout.print("m(\"{s}\"),\n", .{name});
767 } else {767 } else {