| author | |
| committer | |
| log | 3cfde183f3700999eac0b84b54cae0a7d63743a9 |
| tree | 57665cd311d115c3fac2b69dfff58939b6ff8592 |
| parent | 6317da8da400e40a947f6333d1afc289ec349102 |
| parent | aa3c3f66da630cddc12931e7845f4e71acbc4860 |
| signature |
progress towards stage2 behavior tests for all targets passing with the LLVM backend19 files changed, 190 insertions(+), 111 deletions(-)
lib/std/os/windows.zig+40-10| ... | ... | @@ -2693,7 +2693,10 @@ pub const MEM_RESERVE_PLACEHOLDERS = 0x2; |
| 2693 | 2693 | pub const MEM_DECOMMIT = 0x4000; |
| 2694 | 2694 | pub const MEM_RELEASE = 0x8000; |
| 2695 | 2695 | |
| 2696 | pub const PTHREAD_START_ROUTINE = fn (LPVOID) callconv(.C) DWORD; | |
| 2696 | pub const PTHREAD_START_ROUTINE = switch (builtin.zig_backend) { | |
| 2697 | .stage1 => fn (LPVOID) callconv(.C) DWORD, | |
| 2698 | else => *const fn (LPVOID) callconv(.C) DWORD, | |
| 2699 | }; | |
| 2697 | 2700 | pub const LPTHREAD_START_ROUTINE = PTHREAD_START_ROUTINE; |
| 2698 | 2701 | |
| 2699 | 2702 | pub const WIN32_FIND_DATAW = extern struct { |
| ... | ... | @@ -2866,7 +2869,10 @@ pub const IMAGE_TLS_DIRECTORY = extern struct { |
| 2866 | 2869 | pub const IMAGE_TLS_DIRECTORY64 = IMAGE_TLS_DIRECTORY; |
| 2867 | 2870 | pub const IMAGE_TLS_DIRECTORY32 = IMAGE_TLS_DIRECTORY; |
| 2868 | 2871 | |
| 2869 | pub const PIMAGE_TLS_CALLBACK = ?fn (PVOID, DWORD, PVOID) callconv(.C) void; | |
| 2872 | pub const PIMAGE_TLS_CALLBACK = switch (builtin.zig_backend) { | |
| 2873 | .stage1 => ?fn (PVOID, DWORD, PVOID) callconv(.C) void, | |
| 2874 | else => ?*const fn (PVOID, DWORD, PVOID) callconv(.C) void, | |
| 2875 | }; | |
| 2870 | 2876 | |
| 2871 | 2877 | pub const PROV_RSA_FULL = 1; |
| 2872 | 2878 | |
| ... | ... | @@ -2892,7 +2898,10 @@ pub const FILE_ACTION_MODIFIED = 0x00000003; |
| 2892 | 2898 | pub const FILE_ACTION_RENAMED_OLD_NAME = 0x00000004; |
| 2893 | 2899 | pub const FILE_ACTION_RENAMED_NEW_NAME = 0x00000005; |
| 2894 | 2900 | |
| 2895 | pub const LPOVERLAPPED_COMPLETION_ROUTINE = ?fn (DWORD, DWORD, *OVERLAPPED) callconv(.C) void; | |
| 2901 | pub const LPOVERLAPPED_COMPLETION_ROUTINE = switch (builtin.zig_backend) { | |
| 2902 | .stage1 => ?fn (DWORD, DWORD, *OVERLAPPED) callconv(.C) void, | |
| 2903 | else => ?*const fn (DWORD, DWORD, *OVERLAPPED) callconv(.C) void, | |
| 2904 | }; | |
| 2896 | 2905 | |
| 2897 | 2906 | pub const FILE_NOTIFY_CHANGE_CREATION = 64; |
| 2898 | 2907 | pub const FILE_NOTIFY_CHANGE_SIZE = 8; |
| ... | ... | @@ -2945,7 +2954,10 @@ pub const RTL_CRITICAL_SECTION = extern struct { |
| 2945 | 2954 | pub const CRITICAL_SECTION = RTL_CRITICAL_SECTION; |
| 2946 | 2955 | pub const INIT_ONCE = RTL_RUN_ONCE; |
| 2947 | 2956 | pub const INIT_ONCE_STATIC_INIT = RTL_RUN_ONCE_INIT; |
| 2948 | pub const INIT_ONCE_FN = fn (InitOnce: *INIT_ONCE, Parameter: ?*anyopaque, Context: ?*anyopaque) callconv(.C) BOOL; | |
| 2957 | pub const INIT_ONCE_FN = switch (builtin.zig_backend) { | |
| 2958 | .stage1 => fn (InitOnce: *INIT_ONCE, Parameter: ?*anyopaque, Context: ?*anyopaque) callconv(.C) BOOL, | |
| 2959 | else => *const fn (InitOnce: *INIT_ONCE, Parameter: ?*anyopaque, Context: ?*anyopaque) callconv(.C) BOOL, | |
| 2960 | }; | |
| 2949 | 2961 | |
| 2950 | 2962 | pub const RTL_RUN_ONCE = extern struct { |
| 2951 | 2963 | Ptr: ?*anyopaque, |
| ... | ... | @@ -3230,7 +3242,10 @@ pub const EXCEPTION_POINTERS = extern struct { |
| 3230 | 3242 | ContextRecord: *std.os.windows.CONTEXT, |
| 3231 | 3243 | }; |
| 3232 | 3244 | |
| 3233 | pub const VECTORED_EXCEPTION_HANDLER = fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(WINAPI) c_long; | |
| 3245 | pub const VECTORED_EXCEPTION_HANDLER = switch (builtin.zig_backend) { | |
| 3246 | .stage1 => fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(WINAPI) c_long, | |
| 3247 | else => *const fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(WINAPI) c_long, | |
| 3248 | }; | |
| 3234 | 3249 | |
| 3235 | 3250 | pub const OBJECT_ATTRIBUTES = extern struct { |
| 3236 | 3251 | Length: ULONG, |
| ... | ... | @@ -3506,7 +3521,10 @@ pub const RTL_DRIVE_LETTER_CURDIR = extern struct { |
| 3506 | 3521 | DosPath: UNICODE_STRING, |
| 3507 | 3522 | }; |
| 3508 | 3523 | |
| 3509 | pub const PPS_POST_PROCESS_INIT_ROUTINE = ?fn () callconv(.C) void; | |
| 3524 | pub const PPS_POST_PROCESS_INIT_ROUTINE = switch (builtin.zig_backend) { | |
| 3525 | .stage1 => ?fn () callconv(.C) void, | |
| 3526 | else => ?*const fn () callconv(.C) void, | |
| 3527 | }; | |
| 3510 | 3528 | |
| 3511 | 3529 | pub const FILE_BOTH_DIR_INFORMATION = extern struct { |
| 3512 | 3530 | NextEntryOffset: ULONG, |
| ... | ... | @@ -3526,7 +3544,10 @@ pub const FILE_BOTH_DIR_INFORMATION = extern struct { |
| 3526 | 3544 | }; |
| 3527 | 3545 | pub const FILE_BOTH_DIRECTORY_INFORMATION = FILE_BOTH_DIR_INFORMATION; |
| 3528 | 3546 | |
| 3529 | pub const IO_APC_ROUTINE = fn (PVOID, *IO_STATUS_BLOCK, ULONG) callconv(.C) void; | |
| 3547 | pub const IO_APC_ROUTINE = switch (builtin.zig_backend) { | |
| 3548 | .stage1 => fn (PVOID, *IO_STATUS_BLOCK, ULONG) callconv(.C) void, | |
| 3549 | else => *const fn (PVOID, *IO_STATUS_BLOCK, ULONG) callconv(.C) void, | |
| 3550 | }; | |
| 3530 | 3551 | |
| 3531 | 3552 | pub const CURDIR = extern struct { |
| 3532 | 3553 | DosPath: UNICODE_STRING, |
| ... | ... | @@ -3598,8 +3619,14 @@ pub const ENUM_PAGE_FILE_INFORMATION = extern struct { |
| 3598 | 3619 | PeakUsage: SIZE_T, |
| 3599 | 3620 | }; |
| 3600 | 3621 | |
| 3601 | pub const PENUM_PAGE_FILE_CALLBACKW = ?fn (?LPVOID, *ENUM_PAGE_FILE_INFORMATION, LPCWSTR) callconv(.C) BOOL; | |
| 3602 | pub const PENUM_PAGE_FILE_CALLBACKA = ?fn (?LPVOID, *ENUM_PAGE_FILE_INFORMATION, LPCSTR) callconv(.C) BOOL; | |
| 3622 | pub const PENUM_PAGE_FILE_CALLBACKW = switch (builtin.zig_backend) { | |
| 3623 | .stage1 => ?fn (?LPVOID, *ENUM_PAGE_FILE_INFORMATION, LPCWSTR) callconv(.C) BOOL, | |
| 3624 | else => ?*const fn (?LPVOID, *ENUM_PAGE_FILE_INFORMATION, LPCWSTR) callconv(.C) BOOL, | |
| 3625 | }; | |
| 3626 | pub const PENUM_PAGE_FILE_CALLBACKA = switch (builtin.zig_backend) { | |
| 3627 | .stage1 => ?fn (?LPVOID, *ENUM_PAGE_FILE_INFORMATION, LPCSTR) callconv(.C) BOOL, | |
| 3628 | else => ?*const fn (?LPVOID, *ENUM_PAGE_FILE_INFORMATION, LPCSTR) callconv(.C) BOOL, | |
| 3629 | }; | |
| 3603 | 3630 | |
| 3604 | 3631 | pub const PSAPI_WS_WATCH_INFORMATION_EX = extern struct { |
| 3605 | 3632 | BasicInfo: PSAPI_WS_WATCH_INFORMATION, |
| ... | ... | @@ -3699,4 +3726,7 @@ pub const CTRL_CLOSE_EVENT: DWORD = 2; |
| 3699 | 3726 | pub const CTRL_LOGOFF_EVENT: DWORD = 5; |
| 3700 | 3727 | pub const CTRL_SHUTDOWN_EVENT: DWORD = 6; |
| 3701 | 3728 | |
| 3702 | pub const HANDLER_ROUTINE = fn (dwCtrlType: DWORD) callconv(.C) BOOL; | |
| 3729 | pub const HANDLER_ROUTINE = switch (builtin.zig_backend) { | |
| 3730 | .stage1 => fn (dwCtrlType: DWORD) callconv(.C) BOOL, | |
| 3731 | else => *const fn (dwCtrlType: DWORD) callconv(.C) BOOL, | |
| 3732 | }; |
lib/std/pdb.zig+25-25| ... | ... | @@ -14,7 +14,7 @@ const ArrayList = std.ArrayList; |
| 14 | 14 | // documentation and/or contributors. |
| 15 | 15 | |
| 16 | 16 | // https://llvm.org/docs/PDB/DbiStream.html#stream-header |
| 17 | pub const DbiStreamHeader = packed struct { | |
| 17 | pub const DbiStreamHeader = extern struct { | |
| 18 | 18 | VersionSignature: i32, |
| 19 | 19 | VersionHeader: u32, |
| 20 | 20 | Age: u32, |
| ... | ... | @@ -37,7 +37,7 @@ pub const DbiStreamHeader = packed struct { |
| 37 | 37 | Padding: u32, |
| 38 | 38 | }; |
| 39 | 39 | |
| 40 | pub const SectionContribEntry = packed struct { | |
| 40 | pub const SectionContribEntry = extern struct { | |
| 41 | 41 | /// COFF Section index, 1-based |
| 42 | 42 | Section: u16, |
| 43 | 43 | Padding1: [2]u8, |
| ... | ... | @@ -50,7 +50,7 @@ pub const SectionContribEntry = packed struct { |
| 50 | 50 | RelocCrc: u32, |
| 51 | 51 | }; |
| 52 | 52 | |
| 53 | pub const ModInfo = packed struct { | |
| 53 | pub const ModInfo = extern struct { | |
| 54 | 54 | Unused1: u32, |
| 55 | 55 | SectionContr: SectionContribEntry, |
| 56 | 56 | Flags: u16, |
| ... | ... | @@ -68,7 +68,7 @@ pub const ModInfo = packed struct { |
| 68 | 68 | //ObjFileName: char[], |
| 69 | 69 | }; |
| 70 | 70 | |
| 71 | pub const SectionMapHeader = packed struct { | |
| 71 | pub const SectionMapHeader = extern struct { | |
| 72 | 72 | /// Number of segment descriptors |
| 73 | 73 | Count: u16, |
| 74 | 74 | |
| ... | ... | @@ -76,7 +76,7 @@ pub const SectionMapHeader = packed struct { |
| 76 | 76 | LogCount: u16, |
| 77 | 77 | }; |
| 78 | 78 | |
| 79 | pub const SectionMapEntry = packed struct { | |
| 79 | pub const SectionMapEntry = extern struct { | |
| 80 | 80 | /// See the SectionMapEntryFlags enum below. |
| 81 | 81 | Flags: u16, |
| 82 | 82 | |
| ... | ... | @@ -310,7 +310,7 @@ pub const SymbolKind = enum(u16) { |
| 310 | 310 | |
| 311 | 311 | pub const TypeIndex = u32; |
| 312 | 312 | |
| 313 | pub const ProcSym = packed struct { | |
| 313 | pub const ProcSym = extern struct { | |
| 314 | 314 | Parent: u32, |
| 315 | 315 | End: u32, |
| 316 | 316 | Next: u32, |
| ... | ... | @@ -342,7 +342,7 @@ pub const SectionContrSubstreamVersion = enum(u32) { |
| 342 | 342 | _, |
| 343 | 343 | }; |
| 344 | 344 | |
| 345 | pub const RecordPrefix = packed struct { | |
| 345 | pub const RecordPrefix = extern struct { | |
| 346 | 346 | /// Record length, starting from &RecordKind. |
| 347 | 347 | RecordLen: u16, |
| 348 | 348 | |
| ... | ... | @@ -354,7 +354,7 @@ pub const RecordPrefix = packed struct { |
| 354 | 354 | /// The structure definition follows. |
| 355 | 355 | /// LineBlockFragmentHeader Blocks[] |
| 356 | 356 | /// Each `LineBlockFragmentHeader` as specified below. |
| 357 | pub const LineFragmentHeader = packed struct { | |
| 357 | pub const LineFragmentHeader = extern struct { | |
| 358 | 358 | /// Code offset of line contribution. |
| 359 | 359 | RelocOffset: u32, |
| 360 | 360 | |
| ... | ... | @@ -376,7 +376,7 @@ pub const LineFlags = packed struct { |
| 376 | 376 | /// header. The structure definitions follow. |
| 377 | 377 | /// LineNumberEntry Lines[NumLines]; |
| 378 | 378 | /// ColumnNumberEntry Columns[NumLines]; |
| 379 | pub const LineBlockFragmentHeader = packed struct { | |
| 379 | pub const LineBlockFragmentHeader = extern struct { | |
| 380 | 380 | /// Offset of FileChecksum entry in File |
| 381 | 381 | /// checksums buffer. The checksum entry then |
| 382 | 382 | /// contains another offset into the string |
| ... | ... | @@ -388,7 +388,7 @@ pub const LineBlockFragmentHeader = packed struct { |
| 388 | 388 | BlockSize: u32, |
| 389 | 389 | }; |
| 390 | 390 | |
| 391 | pub const LineNumberEntry = packed struct { | |
| 391 | pub const LineNumberEntry = extern struct { | |
| 392 | 392 | /// Offset to start of code bytes for line number |
| 393 | 393 | Offset: u32, |
| 394 | 394 | Flags: u32, |
| ... | ... | @@ -404,13 +404,13 @@ pub const LineNumberEntry = packed struct { |
| 404 | 404 | }; |
| 405 | 405 | }; |
| 406 | 406 | |
| 407 | pub const ColumnNumberEntry = packed struct { | |
| 407 | pub const ColumnNumberEntry = extern struct { | |
| 408 | 408 | StartColumn: u16, |
| 409 | 409 | EndColumn: u16, |
| 410 | 410 | }; |
| 411 | 411 | |
| 412 | 412 | /// Checksum bytes follow. |
| 413 | pub const FileChecksumEntryHeader = packed struct { | |
| 413 | pub const FileChecksumEntryHeader = extern struct { | |
| 414 | 414 | /// Byte offset of filename in global string table. |
| 415 | 415 | FileNameOffset: u32, |
| 416 | 416 | |
| ... | ... | @@ -441,7 +441,7 @@ pub const DebugSubsectionKind = enum(u32) { |
| 441 | 441 | CoffSymbolRVA = 0xfd, |
| 442 | 442 | }; |
| 443 | 443 | |
| 444 | pub const DebugSubsectionHeader = packed struct { | |
| 444 | pub const DebugSubsectionHeader = extern struct { | |
| 445 | 445 | /// codeview::DebugSubsectionKind enum |
| 446 | 446 | Kind: DebugSubsectionKind, |
| 447 | 447 | |
| ... | ... | @@ -449,7 +449,7 @@ pub const DebugSubsectionHeader = packed struct { |
| 449 | 449 | Length: u32, |
| 450 | 450 | }; |
| 451 | 451 | |
| 452 | pub const PDBStringTableHeader = packed struct { | |
| 452 | pub const PDBStringTableHeader = extern struct { | |
| 453 | 453 | /// PDBStringTableSignature |
| 454 | 454 | Signature: u32, |
| 455 | 455 | |
| ... | ... | @@ -686,12 +686,12 @@ pub const Pdb = struct { |
| 686 | 686 | |
| 687 | 687 | var symbol_i: usize = 0; |
| 688 | 688 | while (symbol_i != module.symbols.len) { |
| 689 | const prefix = @ptrCast(*RecordPrefix, &module.symbols[symbol_i]); | |
| 689 | const prefix = @ptrCast(*align(1) RecordPrefix, &module.symbols[symbol_i]); | |
| 690 | 690 | if (prefix.RecordLen < 2) |
| 691 | 691 | return null; |
| 692 | 692 | switch (prefix.RecordKind) { |
| 693 | 693 | .S_LPROC32, .S_GPROC32 => { |
| 694 | const proc_sym = @ptrCast(*ProcSym, &module.symbols[symbol_i + @sizeOf(RecordPrefix)]); | |
| 694 | const proc_sym = @ptrCast(*align(1) ProcSym, &module.symbols[symbol_i + @sizeOf(RecordPrefix)]); | |
| 695 | 695 | if (address >= proc_sym.CodeOffset and address < proc_sym.CodeOffset + proc_sym.CodeSize) { |
| 696 | 696 | return mem.sliceTo(@ptrCast([*:0]u8, proc_sym) + @sizeOf(ProcSym), 0); |
| 697 | 697 | } |
| ... | ... | @@ -712,7 +712,7 @@ pub const Pdb = struct { |
| 712 | 712 | var skip_len: usize = undefined; |
| 713 | 713 | const checksum_offset = module.checksum_offset orelse return error.MissingDebugInfo; |
| 714 | 714 | while (sect_offset != subsect_info.len) : (sect_offset += skip_len) { |
| 715 | const subsect_hdr = @ptrCast(*DebugSubsectionHeader, &subsect_info[sect_offset]); | |
| 715 | const subsect_hdr = @ptrCast(*align(1) DebugSubsectionHeader, &subsect_info[sect_offset]); | |
| 716 | 716 | skip_len = subsect_hdr.Length; |
| 717 | 717 | sect_offset += @sizeOf(DebugSubsectionHeader); |
| 718 | 718 | |
| ... | ... | @@ -720,7 +720,7 @@ pub const Pdb = struct { |
| 720 | 720 | .Lines => { |
| 721 | 721 | var line_index = sect_offset; |
| 722 | 722 | |
| 723 | const line_hdr = @ptrCast(*LineFragmentHeader, &subsect_info[line_index]); | |
| 723 | const line_hdr = @ptrCast(*align(1) LineFragmentHeader, &subsect_info[line_index]); | |
| 724 | 724 | if (line_hdr.RelocSegment == 0) |
| 725 | 725 | return error.MissingDebugInfo; |
| 726 | 726 | line_index += @sizeOf(LineFragmentHeader); |
| ... | ... | @@ -734,7 +734,7 @@ pub const Pdb = struct { |
| 734 | 734 | const subsection_end_index = sect_offset + subsect_hdr.Length; |
| 735 | 735 | |
| 736 | 736 | while (line_index < subsection_end_index) { |
| 737 | const block_hdr = @ptrCast(*LineBlockFragmentHeader, &subsect_info[line_index]); | |
| 737 | const block_hdr = @ptrCast(*align(1) LineBlockFragmentHeader, &subsect_info[line_index]); | |
| 738 | 738 | line_index += @sizeOf(LineBlockFragmentHeader); |
| 739 | 739 | const start_line_index = line_index; |
| 740 | 740 | |
| ... | ... | @@ -746,7 +746,7 @@ pub const Pdb = struct { |
| 746 | 746 | // This is done with a simple linear search. |
| 747 | 747 | var line_i: u32 = 0; |
| 748 | 748 | while (line_i < block_hdr.NumLines) : (line_i += 1) { |
| 749 | const line_num_entry = @ptrCast(*LineNumberEntry, &subsect_info[line_index]); | |
| 749 | const line_num_entry = @ptrCast(*align(1) LineNumberEntry, &subsect_info[line_index]); | |
| 750 | 750 | line_index += @sizeOf(LineNumberEntry); |
| 751 | 751 | |
| 752 | 752 | const vaddr_start = frag_vaddr_start + line_num_entry.Offset; |
| ... | ... | @@ -758,7 +758,7 @@ pub const Pdb = struct { |
| 758 | 758 | // line_i == 0 would mean that no matching LineNumberEntry was found. |
| 759 | 759 | if (line_i > 0) { |
| 760 | 760 | const subsect_index = checksum_offset + block_hdr.NameIndex; |
| 761 | const chksum_hdr = @ptrCast(*FileChecksumEntryHeader, &module.subsect_info[subsect_index]); | |
| 761 | const chksum_hdr = @ptrCast(*align(1) FileChecksumEntryHeader, &module.subsect_info[subsect_index]); | |
| 762 | 762 | const strtab_offset = @sizeOf(PDBStringTableHeader) + chksum_hdr.FileNameOffset; |
| 763 | 763 | try self.string_table.?.seekTo(strtab_offset); |
| 764 | 764 | const source_file_name = try self.string_table.?.reader().readUntilDelimiterAlloc(self.allocator, 0, 1024); |
| ... | ... | @@ -768,12 +768,12 @@ pub const Pdb = struct { |
| 768 | 768 | const column = if (has_column) blk: { |
| 769 | 769 | const start_col_index = start_line_index + @sizeOf(LineNumberEntry) * block_hdr.NumLines; |
| 770 | 770 | const col_index = start_col_index + @sizeOf(ColumnNumberEntry) * line_entry_idx; |
| 771 | const col_num_entry = @ptrCast(*ColumnNumberEntry, &subsect_info[col_index]); | |
| 771 | const col_num_entry = @ptrCast(*align(1) ColumnNumberEntry, &subsect_info[col_index]); | |
| 772 | 772 | break :blk col_num_entry.StartColumn; |
| 773 | 773 | } else 0; |
| 774 | 774 | |
| 775 | 775 | const found_line_index = start_line_index + line_entry_idx * @sizeOf(LineNumberEntry); |
| 776 | const line_num_entry = @ptrCast(*LineNumberEntry, &subsect_info[found_line_index]); | |
| 776 | const line_num_entry = @ptrCast(*align(1) LineNumberEntry, &subsect_info[found_line_index]); | |
| 777 | 777 | const flags = @ptrCast(*LineNumberEntry.Flags, &line_num_entry.Flags); |
| 778 | 778 | |
| 779 | 779 | return debug.LineInfo{ |
| ... | ... | @@ -833,7 +833,7 @@ pub const Pdb = struct { |
| 833 | 833 | var sect_offset: usize = 0; |
| 834 | 834 | var skip_len: usize = undefined; |
| 835 | 835 | while (sect_offset != mod.subsect_info.len) : (sect_offset += skip_len) { |
| 836 | const subsect_hdr = @ptrCast(*DebugSubsectionHeader, &mod.subsect_info[sect_offset]); | |
| 836 | const subsect_hdr = @ptrCast(*align(1) DebugSubsectionHeader, &mod.subsect_info[sect_offset]); | |
| 837 | 837 | skip_len = subsect_hdr.Length; |
| 838 | 838 | sect_offset += @sizeOf(DebugSubsectionHeader); |
| 839 | 839 | |
| ... | ... | @@ -969,7 +969,7 @@ fn blockCountFromSize(size: u32, block_size: u32) u32 { |
| 969 | 969 | } |
| 970 | 970 | |
| 971 | 971 | // https://llvm.org/docs/PDB/MsfFile.html#the-superblock |
| 972 | const SuperBlock = packed struct { | |
| 972 | const SuperBlock = extern struct { | |
| 973 | 973 | /// The LLVM docs list a space between C / C++ but empirically this is not the case. |
| 974 | 974 | const file_magic = "Microsoft C/C++ MSF 7.00\r\n\x1a\x44\x53\x00\x00\x00"; |
| 975 | 975 |
lib/std/special/test_runner.zig+1-1| ... | ... | @@ -28,7 +28,7 @@ pub fn main() void { |
| 28 | 28 | { |
| 29 | 29 | return main2() catch @panic("test failure"); |
| 30 | 30 | } |
| 31 | if (builtin.zig_backend == .stage1) processArgs(); | |
| 31 | processArgs(); | |
| 32 | 32 | const test_fn_list = builtin.test_functions; |
| 33 | 33 | var ok_count: usize = 0; |
| 34 | 34 | var skip_count: usize = 0; |
lib/std/start.zig+1-3| ... | ... | @@ -29,9 +29,7 @@ comptime { |
| 29 | 29 | builtin.zig_backend == .stage2_aarch64 or |
| 30 | 30 | builtin.zig_backend == .stage2_arm or |
| 31 | 31 | builtin.zig_backend == .stage2_riscv64 or |
| 32 | builtin.zig_backend == .stage2_sparcv9 or | |
| 33 | (builtin.zig_backend == .stage2_llvm and native_os != .linux and native_os != .macos) or | |
| 34 | (builtin.zig_backend == .stage2_llvm and native_arch != .x86_64 and native_arch != .aarch64)) | |
| 32 | builtin.zig_backend == .stage2_sparcv9) | |
| 35 | 33 | { |
| 36 | 34 | if (builtin.output_mode == .Exe) { |
| 37 | 35 | if ((builtin.link_libc or builtin.object_format == .c) and @hasDecl(root, "main")) { |
src/Air.zig+2| ... | ... | @@ -815,6 +815,8 @@ pub const VectorCmp = struct { |
| 815 | 815 | /// 1. `Inst.Ref` for every inputs_len |
| 816 | 816 | /// 2. for every outputs_len |
| 817 | 817 | /// - constraint: memory at this position is reinterpreted as a null |
| 818 | /// terminated string. | |
| 819 | /// - name: memory at this position is reinterpreted as a null | |
| 818 | 820 | /// terminated string. pad to the next u32 after the null byte. |
| 819 | 821 | /// 3. for every inputs_len |
| 820 | 822 | /// - constraint: memory at this position is reinterpreted as a null |
src/Sema.zig+14-6| ... | ... | @@ -4323,7 +4323,7 @@ pub fn analyzeExport( |
| 4323 | 4323 | const exported_decl = mod.declPtr(exported_decl_index); |
| 4324 | 4324 | // TODO run the same checks as we do for C ABI struct fields |
| 4325 | 4325 | switch (exported_decl.ty.zigTypeTag()) { |
| 4326 | .Fn, .Int, .Enum, .Struct, .Union, .Array, .Float => {}, | |
| 4326 | .Fn, .Int, .Enum, .Struct, .Union, .Array, .Float, .Pointer, .Optional => {}, | |
| 4327 | 4327 | else => return sema.fail(block, src, "unable to export type '{}'", .{ |
| 4328 | 4328 | exported_decl.ty.fmt(sema.mod), |
| 4329 | 4329 | }), |
| ... | ... | @@ -10535,7 +10535,11 @@ fn zirAsm( |
| 10535 | 10535 | var output_type_bits = extra.data.output_type_bits; |
| 10536 | 10536 | var needed_capacity: usize = @typeInfo(Air.Asm).Struct.fields.len + outputs_len + inputs_len; |
| 10537 | 10537 | |
| 10538 | const Output = struct { constraint: []const u8, ty: Type }; | |
| 10538 | const Output = struct { | |
| 10539 | constraint: []const u8, | |
| 10540 | name: []const u8, | |
| 10541 | ty: Type, | |
| 10542 | }; | |
| 10539 | 10543 | const output: ?Output = if (outputs_len == 0) null else blk: { |
| 10540 | 10544 | const output = sema.code.extraData(Zir.Inst.Asm.Output, extra_i); |
| 10541 | 10545 | extra_i = output.end; |
| ... | ... | @@ -10548,10 +10552,12 @@ fn zirAsm( |
| 10548 | 10552 | } |
| 10549 | 10553 | |
| 10550 | 10554 | const constraint = sema.code.nullTerminatedString(output.data.constraint); |
| 10551 | needed_capacity += constraint.len / 4 + 1; | |
| 10555 | const name = sema.code.nullTerminatedString(output.data.name); | |
| 10556 | needed_capacity += (constraint.len + name.len + (2 + 3)) / 4; | |
| 10552 | 10557 | |
| 10553 | 10558 | break :blk Output{ |
| 10554 | 10559 | .constraint = constraint, |
| 10560 | .name = name, | |
| 10555 | 10561 | .ty = try sema.resolveType(block, ret_ty_src, output.data.operand), |
| 10556 | 10562 | }; |
| 10557 | 10563 | }; |
| ... | ... | @@ -10573,7 +10579,7 @@ fn zirAsm( |
| 10573 | 10579 | |
| 10574 | 10580 | const constraint = sema.code.nullTerminatedString(input.data.constraint); |
| 10575 | 10581 | const name = sema.code.nullTerminatedString(input.data.name); |
| 10576 | needed_capacity += (constraint.len + name.len + 1) / 4 + 1; | |
| 10582 | needed_capacity += (constraint.len + name.len + (2 + 3)) / 4; | |
| 10577 | 10583 | inputs[arg_i] = .{ .c = constraint, .n = name }; |
| 10578 | 10584 | } |
| 10579 | 10585 | |
| ... | ... | @@ -10611,7 +10617,9 @@ fn zirAsm( |
| 10611 | 10617 | const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice()); |
| 10612 | 10618 | mem.copy(u8, buffer, o.constraint); |
| 10613 | 10619 | buffer[o.constraint.len] = 0; |
| 10614 | sema.air_extra.items.len += o.constraint.len / 4 + 1; | |
| 10620 | mem.copy(u8, buffer[o.constraint.len + 1 ..], o.name); | |
| 10621 | buffer[o.constraint.len + 1 + o.name.len] = 0; | |
| 10622 | sema.air_extra.items.len += (o.constraint.len + o.name.len + (2 + 3)) / 4; | |
| 10615 | 10623 | } |
| 10616 | 10624 | for (inputs) |input| { |
| 10617 | 10625 | const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice()); |
| ... | ... | @@ -10619,7 +10627,7 @@ fn zirAsm( |
| 10619 | 10627 | buffer[input.c.len] = 0; |
| 10620 | 10628 | mem.copy(u8, buffer[input.c.len + 1 ..], input.n); |
| 10621 | 10629 | buffer[input.c.len + 1 + input.n.len] = 0; |
| 10622 | sema.air_extra.items.len += (input.c.len + input.n.len + 1) / 4 + 1; | |
| 10630 | sema.air_extra.items.len += (input.c.len + input.n.len + (2 + 3)) / 4; | |
| 10623 | 10631 | } |
| 10624 | 10632 | for (clobbers) |clobber| { |
| 10625 | 10633 | const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice()); |
src/arch/aarch64/CodeGen.zig+5-3| ... | ... | @@ -3272,10 +3272,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 3272 | 3272 | if (output != .none) { |
| 3273 | 3273 | return self.fail("TODO implement codegen for non-expr asm", .{}); |
| 3274 | 3274 | } |
| 3275 | const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); | |
| 3275 | 3276 | const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0); |
| 3277 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | |
| 3276 | 3278 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 3277 | 3279 | // for the string, we still use the next u32 for the null terminator. |
| 3278 | extra_i += constraint.len / 4 + 1; | |
| 3280 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | |
| 3279 | 3281 | |
| 3280 | 3282 | break constraint; |
| 3281 | 3283 | } else null; |
| ... | ... | @@ -3283,10 +3285,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 3283 | 3285 | for (inputs) |input| { |
| 3284 | 3286 | const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); |
| 3285 | 3287 | const constraint = std.mem.sliceTo(input_bytes, 0); |
| 3286 | const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); | |
| 3288 | const name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); | |
| 3287 | 3289 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 3288 | 3290 | // for the string, we still use the next u32 for the null terminator. |
| 3289 | extra_i += (constraint.len + input_name.len + 1) / 4 + 1; | |
| 3291 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | |
| 3290 | 3292 | |
| 3291 | 3293 | if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') { |
| 3292 | 3294 | return self.fail("unrecognized asm input constraint: '{s}'", .{constraint}); |
src/arch/arm/CodeGen.zig+5-3| ... | ... | @@ -4078,10 +4078,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 4078 | 4078 | if (output != .none) { |
| 4079 | 4079 | return self.fail("TODO implement codegen for non-expr asm", .{}); |
| 4080 | 4080 | } |
| 4081 | const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); | |
| 4081 | 4082 | const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0); |
| 4083 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | |
| 4082 | 4084 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 4083 | 4085 | // for the string, we still use the next u32 for the null terminator. |
| 4084 | extra_i += constraint.len / 4 + 1; | |
| 4086 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | |
| 4085 | 4087 | |
| 4086 | 4088 | break constraint; |
| 4087 | 4089 | } else null; |
| ... | ... | @@ -4089,10 +4091,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 4089 | 4091 | for (inputs) |input| { |
| 4090 | 4092 | const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); |
| 4091 | 4093 | const constraint = std.mem.sliceTo(input_bytes, 0); |
| 4092 | const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); | |
| 4094 | const name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); | |
| 4093 | 4095 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 4094 | 4096 | // for the string, we still use the next u32 for the null terminator. |
| 4095 | extra_i += (constraint.len + input_name.len + 1) / 4 + 1; | |
| 4097 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | |
| 4096 | 4098 | |
| 4097 | 4099 | if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') { |
| 4098 | 4100 | return self.fail("unrecognized asm input constraint: '{s}'", .{constraint}); |
src/arch/riscv64/CodeGen.zig+5-3| ... | ... | @@ -2098,10 +2098,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 2098 | 2098 | if (output != .none) { |
| 2099 | 2099 | return self.fail("TODO implement codegen for non-expr asm", .{}); |
| 2100 | 2100 | } |
| 2101 | const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); | |
| 2101 | 2102 | const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0); |
| 2103 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | |
| 2102 | 2104 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 2103 | 2105 | // for the string, we still use the next u32 for the null terminator. |
| 2104 | extra_i += constraint.len / 4 + 1; | |
| 2106 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | |
| 2105 | 2107 | |
| 2106 | 2108 | break constraint; |
| 2107 | 2109 | } else null; |
| ... | ... | @@ -2109,10 +2111,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 2109 | 2111 | for (inputs) |input| { |
| 2110 | 2112 | const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); |
| 2111 | 2113 | const constraint = std.mem.sliceTo(input_bytes, 0); |
| 2112 | const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); | |
| 2114 | const name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); | |
| 2113 | 2115 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 2114 | 2116 | // for the string, we still use the next u32 for the null terminator. |
| 2115 | extra_i += (constraint.len + input_name.len + 1) / 4 + 1; | |
| 2117 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | |
| 2116 | 2118 | |
| 2117 | 2119 | if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') { |
| 2118 | 2120 | return self.fail("unrecognized asm input constraint: '{s}'", .{constraint}); |
src/arch/sparcv9/CodeGen.zig+5-3| ... | ... | @@ -642,10 +642,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 642 | 642 | if (output != .none) { |
| 643 | 643 | return self.fail("TODO implement codegen for non-expr asm", .{}); |
| 644 | 644 | } |
| 645 | const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); | |
| 645 | 646 | const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0); |
| 647 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | |
| 646 | 648 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 647 | 649 | // for the string, we still use the next u32 for the null terminator. |
| 648 | extra_i += constraint.len / 4 + 1; | |
| 650 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | |
| 649 | 651 | |
| 650 | 652 | break constraint; |
| 651 | 653 | } else null; |
| ... | ... | @@ -653,10 +655,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 653 | 655 | for (inputs) |input| { |
| 654 | 656 | const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); |
| 655 | 657 | const constraint = std.mem.sliceTo(input_bytes, 0); |
| 656 | const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); | |
| 658 | const name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); | |
| 657 | 659 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 658 | 660 | // for the string, we still use the next u32 for the null terminator. |
| 659 | extra_i += (constraint.len + input_name.len + 1) / 4 + 1; | |
| 661 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | |
| 660 | 662 | |
| 661 | 663 | if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') { |
| 662 | 664 | return self.fail("unrecognized asm input constraint: '{s}'", .{constraint}); |
src/arch/x86_64/CodeGen.zig+5-3| ... | ... | @@ -4738,10 +4738,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 4738 | 4738 | if (output != .none) { |
| 4739 | 4739 | return self.fail("TODO implement codegen for non-expr asm", .{}); |
| 4740 | 4740 | } |
| 4741 | const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); | |
| 4741 | 4742 | const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0); |
| 4743 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | |
| 4742 | 4744 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 4743 | 4745 | // for the string, we still use the next u32 for the null terminator. |
| 4744 | extra_i += constraint.len / 4 + 1; | |
| 4746 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | |
| 4745 | 4747 | |
| 4746 | 4748 | break constraint; |
| 4747 | 4749 | } else null; |
| ... | ... | @@ -4749,10 +4751,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { |
| 4749 | 4751 | for (inputs) |input| { |
| 4750 | 4752 | const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); |
| 4751 | 4753 | const constraint = std.mem.sliceTo(input_bytes, 0); |
| 4752 | const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); | |
| 4754 | const name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); | |
| 4753 | 4755 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 4754 | 4756 | // for the string, we still use the next u32 for the null terminator. |
| 4755 | extra_i += (constraint.len + input_name.len + 1) / 4 + 1; | |
| 4757 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | |
| 4756 | 4758 | |
| 4757 | 4759 | if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') { |
| 4758 | 4760 | return self.fail("unrecognized asm input constraint: '{s}'", .{constraint}); |
src/codegen/c.zig+7-3| ... | ... | @@ -3018,10 +3018,12 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3018 | 3018 | if (output != .none) { |
| 3019 | 3019 | return f.fail("TODO implement codegen for non-expr asm", .{}); |
| 3020 | 3020 | } |
| 3021 | const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]); | |
| 3021 | 3022 | const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0); |
| 3023 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | |
| 3022 | 3024 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 3023 | 3025 | // for the string, we still use the next u32 for the null terminator. |
| 3024 | extra_i += constraint.len / 4 + 1; | |
| 3026 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | |
| 3025 | 3027 | |
| 3026 | 3028 | break constraint; |
| 3027 | 3029 | } else null; |
| ... | ... | @@ -3031,10 +3033,12 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3031 | 3033 | |
| 3032 | 3034 | const inputs_extra_begin = extra_i; |
| 3033 | 3035 | for (inputs) |input, i| { |
| 3034 | const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0); | |
| 3036 | const input_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]); | |
| 3037 | const constraint = std.mem.sliceTo(input_bytes, 0); | |
| 3038 | const name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); | |
| 3035 | 3039 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 3036 | 3040 | // for the string, we still use the next u32 for the null terminator. |
| 3037 | extra_i += constraint.len / 4 + 1; | |
| 3041 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | |
| 3038 | 3042 | |
| 3039 | 3043 | if (constraint[0] == '{' and constraint[constraint.len - 1] == '}') { |
| 3040 | 3044 | const reg = constraint[1 .. constraint.len - 1]; |
src/codegen/llvm.zig+41-20| ... | ... | @@ -340,6 +340,10 @@ pub const Object = struct { |
| 340 | 340 | |
| 341 | 341 | llvm_module.setModuleDataLayout(target_data); |
| 342 | 342 | |
| 343 | if (options.pic) llvm_module.setModulePICLevel(); | |
| 344 | if (options.pie) llvm_module.setModulePIELevel(); | |
| 345 | if (code_model != .Default) llvm_module.setModuleCodeModel(code_model); | |
| 346 | ||
| 343 | 347 | return Object{ |
| 344 | 348 | .gpa = gpa, |
| 345 | 349 | .module = options.module.?, |
| ... | ... | @@ -4577,6 +4581,10 @@ pub const FuncGen = struct { |
| 4577 | 4581 | const operand_ty = self.air.typeOf(pl_op.operand); |
| 4578 | 4582 | const name = self.air.nullTerminatedString(pl_op.payload); |
| 4579 | 4583 | |
| 4584 | if (needDbgVarWorkaround(self.dg, operand_ty)) { | |
| 4585 | return null; | |
| 4586 | } | |
| 4587 | ||
| 4580 | 4588 | const di_local_var = dib.createAutoVariable( |
| 4581 | 4589 | self.di_scope.?, |
| 4582 | 4590 | name.ptr, |
| ... | ... | @@ -4638,14 +4646,19 @@ pub const FuncGen = struct { |
| 4638 | 4646 | var llvm_param_i: usize = 0; |
| 4639 | 4647 | var total_i: usize = 0; |
| 4640 | 4648 | |
| 4649 | var name_map: std.StringArrayHashMapUnmanaged(void) = .{}; | |
| 4650 | try name_map.ensureUnusedCapacity(arena, outputs.len + inputs.len); | |
| 4651 | ||
| 4641 | 4652 | for (outputs) |output| { |
| 4642 | 4653 | if (output != .none) { |
| 4643 | 4654 | return self.todo("implement inline asm with non-returned output", .{}); |
| 4644 | 4655 | } |
| 4656 | const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); | |
| 4645 | 4657 | const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0); |
| 4658 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | |
| 4646 | 4659 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 4647 | 4660 | // for the string, we still use the next u32 for the null terminator. |
| 4648 | extra_i += constraint.len / 4 + 1; | |
| 4661 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | |
| 4649 | 4662 | |
| 4650 | 4663 | try llvm_constraints.ensureUnusedCapacity(self.gpa, constraint.len + 1); |
| 4651 | 4664 | if (total_i != 0) { |
| ... | ... | @@ -4654,17 +4667,17 @@ pub const FuncGen = struct { |
| 4654 | 4667 | llvm_constraints.appendAssumeCapacity('='); |
| 4655 | 4668 | llvm_constraints.appendSliceAssumeCapacity(constraint[1..]); |
| 4656 | 4669 | |
| 4670 | name_map.putAssumeCapacityNoClobber(name, {}); | |
| 4657 | 4671 | total_i += 1; |
| 4658 | 4672 | } |
| 4659 | 4673 | |
| 4660 | const input_start_extra_i = extra_i; | |
| 4661 | 4674 | for (inputs) |input| { |
| 4662 | const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); | |
| 4663 | const constraint = std.mem.sliceTo(input_bytes, 0); | |
| 4664 | const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); | |
| 4675 | const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); | |
| 4676 | const constraint = std.mem.sliceTo(extra_bytes, 0); | |
| 4677 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | |
| 4665 | 4678 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 4666 | 4679 | // for the string, we still use the next u32 for the null terminator. |
| 4667 | extra_i += (constraint.len + input_name.len + 1) / 4 + 1; | |
| 4680 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | |
| 4668 | 4681 | |
| 4669 | 4682 | const arg_llvm_value = try self.resolveInst(input); |
| 4670 | 4683 | |
| ... | ... | @@ -4677,6 +4690,7 @@ pub const FuncGen = struct { |
| 4677 | 4690 | } |
| 4678 | 4691 | llvm_constraints.appendSliceAssumeCapacity(constraint); |
| 4679 | 4692 | |
| 4693 | name_map.putAssumeCapacityNoClobber(name, {}); | |
| 4680 | 4694 | llvm_param_i += 1; |
| 4681 | 4695 | total_i += 1; |
| 4682 | 4696 | } |
| ... | ... | @@ -4739,20 +4753,11 @@ pub const FuncGen = struct { |
| 4739 | 4753 | const name = asm_source[name_start..i]; |
| 4740 | 4754 | state = .start; |
| 4741 | 4755 | |
| 4742 | extra_i = input_start_extra_i; | |
| 4743 | for (inputs) |_, input_i| { | |
| 4744 | const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); | |
| 4745 | const constraint = std.mem.sliceTo(input_bytes, 0); | |
| 4746 | const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); | |
| 4747 | extra_i += (constraint.len + input_name.len + 1) / 4 + 1; | |
| 4748 | ||
| 4749 | if (std.mem.eql(u8, name, input_name)) { | |
| 4750 | try rendered_template.writer().print("{d}", .{input_i}); | |
| 4751 | break; | |
| 4752 | } | |
| 4753 | } else { | |
| 4754 | return self.todo("TODO validate asm in Sema", .{}); | |
| 4755 | } | |
| 4756 | const index = name_map.getIndex(name) orelse { | |
| 4757 | // we should validate the assembly in Sema; by now it is too late | |
| 4758 | return self.todo("unknown input or output name: '{s}'", .{name}); | |
| 4759 | }; | |
| 4760 | try rendered_template.writer().print("{d}", .{index}); | |
| 4756 | 4761 | }, |
| 4757 | 4762 | else => {}, |
| 4758 | 4763 | }, |
| ... | ... | @@ -6150,6 +6155,10 @@ pub const FuncGen = struct { |
| 6150 | 6155 | |
| 6151 | 6156 | const inst_ty = self.air.typeOfIndex(inst); |
| 6152 | 6157 | if (self.dg.object.di_builder) |dib| { |
| 6158 | if (needDbgVarWorkaround(self.dg, inst_ty)) { | |
| 6159 | return arg_val; | |
| 6160 | } | |
| 6161 | ||
| 6153 | 6162 | const src_index = self.getSrcArgIndex(self.arg_index - 1); |
| 6154 | 6163 | const func = self.dg.decl.getFunction().?; |
| 6155 | 6164 | const lbrace_line = self.dg.module.declPtr(func.owner_decl).src_line + func.lbrace_line + 1; |
| ... | ... | @@ -8251,3 +8260,15 @@ const AnnotatedDITypePtr = enum(usize) { |
| 8251 | 8260 | }; |
| 8252 | 8261 | |
| 8253 | 8262 | const lt_errors_fn_name = "__zig_lt_errors_len"; |
| 8263 | ||
| 8264 | /// Without this workaround, LLVM crashes with "unknown codeview register H1" | |
| 8265 | /// TODO use llvm-reduce and file upstream LLVM bug for this. | |
| 8266 | fn needDbgVarWorkaround(dg: *DeclGen, ty: Type) bool { | |
| 8267 | if (ty.tag() == .f16) { | |
| 8268 | const target = dg.module.getTarget(); | |
| 8269 | if (target.os.tag == .windows and target.cpu.arch == .aarch64) { | |
| 8270 | return true; | |
| 8271 | } | |
| 8272 | } | |
| 8273 | return false; | |
| 8274 | } |
src/codegen/llvm/bindings.zig+9| ... | ... | @@ -310,6 +310,15 @@ pub const Module = opaque { |
| 310 | 310 | pub const setModuleDataLayout = LLVMSetModuleDataLayout; |
| 311 | 311 | extern fn LLVMSetModuleDataLayout(*const Module, *const TargetData) void; |
| 312 | 312 | |
| 313 | pub const setModulePICLevel = ZigLLVMSetModulePICLevel; | |
| 314 | extern fn ZigLLVMSetModulePICLevel(module: *const Module) void; | |
| 315 | ||
| 316 | pub const setModulePIELevel = ZigLLVMSetModulePIELevel; | |
| 317 | extern fn ZigLLVMSetModulePIELevel(module: *const Module) void; | |
| 318 | ||
| 319 | pub const setModuleCodeModel = ZigLLVMSetModuleCodeModel; | |
| 320 | extern fn ZigLLVMSetModuleCodeModel(module: *const Module, code_model: CodeModel) void; | |
| 321 | ||
| 313 | 322 | pub const addFunction = LLVMAddFunction; |
| 314 | 323 | extern fn LLVMAddFunction(*const Module, Name: [*:0]const u8, FunctionTy: *const Type) *const Value; |
| 315 | 324 |
src/print_air.zig+18-10| ... | ... | @@ -542,15 +542,19 @@ const Writer = struct { |
| 542 | 542 | extra_i += inputs.len; |
| 543 | 543 | |
| 544 | 544 | for (outputs) |output| { |
| 545 | const constraint = w.air.nullTerminatedString(extra_i); | |
| 545 | const extra_bytes = std.mem.sliceAsBytes(w.air.extra[extra_i..]); | |
| 546 | const constraint = std.mem.sliceTo(extra_bytes, 0); | |
| 547 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | |
| 548 | ||
| 546 | 549 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 547 | // for the string, we still use the next u32 for the null terminator. | |
| 548 | extra_i += constraint.len / 4 + 1; | |
| 550 | // for the strings and their null terminators, we still use the next u32 | |
| 551 | // for the null terminator. | |
| 552 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | |
| 549 | 553 | |
| 550 | 554 | if (output == .none) { |
| 551 | try s.print(", -> {s}", .{constraint}); | |
| 555 | try s.print(", [{s}] -> {s}", .{ name, constraint }); | |
| 552 | 556 | } else { |
| 553 | try s.print(", out {s} = (", .{constraint}); | |
| 557 | try s.print(", [{s}] out {s} = (", .{ name, constraint }); | |
| 554 | 558 | try w.writeOperand(s, inst, op_index, output); |
| 555 | 559 | op_index += 1; |
| 556 | 560 | try s.writeByte(')'); |
| ... | ... | @@ -558,12 +562,15 @@ const Writer = struct { |
| 558 | 562 | } |
| 559 | 563 | |
| 560 | 564 | for (inputs) |input| { |
| 561 | const constraint = w.air.nullTerminatedString(extra_i); | |
| 565 | const extra_bytes = std.mem.sliceAsBytes(w.air.extra[extra_i..]); | |
| 566 | const constraint = std.mem.sliceTo(extra_bytes, 0); | |
| 567 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | |
| 562 | 568 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 563 | // for the string, we still use the next u32 for the null terminator. | |
| 564 | extra_i += constraint.len / 4 + 1; | |
| 569 | // for the strings and their null terminators, we still use the next u32 | |
| 570 | // for the null terminator. | |
| 571 | extra_i += (constraint.len + name.len + 1) / 4 + 1; | |
| 565 | 572 | |
| 566 | try s.print(", in {s} = (", .{constraint}); | |
| 573 | try s.print(", [{s}] in {s} = (", .{ name, constraint }); | |
| 567 | 574 | try w.writeOperand(s, inst, op_index, input); |
| 568 | 575 | op_index += 1; |
| 569 | 576 | try s.writeByte(')'); |
| ... | ... | @@ -572,7 +579,8 @@ const Writer = struct { |
| 572 | 579 | { |
| 573 | 580 | var clobber_i: u32 = 0; |
| 574 | 581 | while (clobber_i < clobbers_len) : (clobber_i += 1) { |
| 575 | const clobber = w.air.nullTerminatedString(extra_i); | |
| 582 | const extra_bytes = std.mem.sliceAsBytes(w.air.extra[extra_i..]); | |
| 583 | const clobber = std.mem.sliceTo(extra_bytes, 0); | |
| 576 | 584 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 577 | 585 | // for the string, we still use the next u32 for the null terminator. |
| 578 | 586 | extra_i += clobber.len / 4 + 1; |
test/behavior/struct.zig+4-15| ... | ... | @@ -421,21 +421,10 @@ test "packed struct 24bits" { |
| 421 | 421 | if (builtin.cpu.arch == .arm) return error.SkipZigTest; // TODO |
| 422 | 422 | |
| 423 | 423 | comptime { |
| 424 | // TODO Remove if and leave only the else branch when it is also fixed in stage2 | |
| 425 | if (builtin.zig_backend == .stage2_llvm or builtin.zig_backend == .stage2_x86 or | |
| 426 | builtin.zig_backend == .stage2_riscv64) | |
| 427 | { | |
| 428 | // Stage 2 still expects the wrong values | |
| 429 | try expect(@sizeOf(Foo24Bits) == 4); | |
| 430 | if (@sizeOf(usize) == 4) { | |
| 431 | try expect(@sizeOf(Foo96Bits) == 12); | |
| 432 | } else { | |
| 433 | try expect(@sizeOf(Foo96Bits) == 16); | |
| 434 | } | |
| 435 | } else { | |
| 436 | // Stage1 is now fixed and is expected to return right values | |
| 437 | try expectEqual(@sizeOf(Foo24Bits), 3); | |
| 438 | try expectEqual(@sizeOf(Foo96Bits), 12); | |
| 424 | // stage1 gets the wrong answer for sizeof | |
| 425 | if (builtin.zig_backend != .stage1) { | |
| 426 | std.debug.assert(@sizeOf(Foo24Bits) == @sizeOf(u24)); | |
| 427 | std.debug.assert(@sizeOf(Foo96Bits) == @sizeOf(u96)); | |
| 439 | 428 | } |
| 440 | 429 | } |
| 441 | 430 |
test/incremental/aarch64-macos/hello_world_with_updates.0.zig+1-1| ... | ... | @@ -2,4 +2,4 @@ |
| 2 | 2 | // output_mode=Exe |
| 3 | 3 | // target=aarch64-macos |
| 4 | 4 | // |
| 5 | // :109:9: error: struct 'tmp.tmp' has no member named 'main' | |
| 5 | // :107:9: error: struct 'tmp.tmp' has no member named 'main' |
test/incremental/x86_64-linux/hello_world_with_updates.0.zig+1-1| ... | ... | @@ -2,4 +2,4 @@ |
| 2 | 2 | // output_mode=Exe |
| 3 | 3 | // target=x86_64-linux |
| 4 | 4 | // |
| 5 | // :109:9: error: struct 'tmp.tmp' has no member named 'main' | |
| 5 | // :107:9: error: struct 'tmp.tmp' has no member named 'main' |
test/incremental/x86_64-macos/hello_world_with_updates.0.zig+1-1| ... | ... | @@ -2,4 +2,4 @@ |
| 2 | 2 | // output_mode=Exe |
| 3 | 3 | // target=x86_64-macos |
| 4 | 4 | // |
| 5 | // :109:9: error: struct 'tmp.tmp' has no member named 'main' | |
| 5 | // :107:9: error: struct 'tmp.tmp' has no member named 'main' |