| ... | @@ -374,66 +374,7 @@ pub fn generateSymbol( | ... | @@ -374,66 +374,7 @@ pub fn generateSymbol( |
| 374 | | 374 | |
| 375 | return Result.ok; | 375 | return Result.ok; |
| 376 | }, | 376 | }, |
| 377 | .field_ptr => { | 377 | .field_ptr, .elem_ptr => return lowerParentPtr( |
| 378 | const field_ptr = typed_value.val.castTag(.field_ptr).?.data; | | |
| 379 | const container_ptr = field_ptr.container_ptr; | | |
| 380 | | | |
| 381 | switch (container_ptr.tag()) { | | |
| 382 | .decl_ref => { | | |
| 383 | const decl_index = container_ptr.castTag(.decl_ref).?.data; | | |
| 384 | const decl = mod.declPtr(decl_index); | | |
| 385 | const addend = blk: { | | |
| 386 | switch (decl.ty.zigTypeTag()) { | | |
| 387 | .Struct => { | | |
| 388 | const addend = decl.ty.structFieldOffset(field_ptr.field_index, target); | | |
| 389 | break :blk @intCast(u32, addend); | | |
| 390 | }, | | |
| 391 | .Pointer => { | | |
| 392 | assert(decl.ty.isSlice()); | | |
| 393 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | | |
| 394 | const addend = switch (field_ptr.field_index) { | | |
| 395 | 0 => 0, | | |
| 396 | 1 => decl.ty.slicePtrFieldType(&buf).abiSize(target), | | |
| 397 | else => unreachable, | | |
| 398 | }; | | |
| 399 | break :blk @intCast(u32, addend); | | |
| 400 | }, | | |
| 401 | else => return Result{ | | |
| 402 | .fail = try ErrorMsg.create( | | |
| 403 | bin_file.allocator, | | |
| 404 | src_loc, | | |
| 405 | "TODO implement generateSymbol for pointer type value: '{s}'", | | |
| 406 | .{@tagName(typed_value.val.tag())}, | | |
| 407 | ), | | |
| 408 | }, | | |
| 409 | } | | |
| 410 | }; | | |
| 411 | return lowerDeclRef(bin_file, src_loc, typed_value, decl_index, code, debug_output, .{ | | |
| 412 | .parent_atom_index = reloc_info.parent_atom_index, | | |
| 413 | .addend = (reloc_info.addend orelse 0) + addend, | | |
| 414 | }); | | |
| 415 | }, | | |
| 416 | .field_ptr => { | | |
| 417 | switch (try generateSymbol(bin_file, src_loc, .{ | | |
| 418 | .ty = typed_value.ty, | | |
| 419 | .val = container_ptr, | | |
| 420 | }, code, debug_output, reloc_info)) { | | |
| 421 | .ok => {}, | | |
| 422 | .fail => |em| return Result{ .fail = em }, | | |
| 423 | } | | |
| 424 | return Result.ok; | | |
| 425 | }, | | |
| 426 | else => return Result{ | | |
| 427 | .fail = try ErrorMsg.create( | | |
| 428 | bin_file.allocator, | | |
| 429 | src_loc, | | |
| 430 | "TODO implement generateSymbol for pointer type value: '{s}'", | | |
| 431 | .{@tagName(typed_value.val.tag())}, | | |
| 432 | ), | | |
| 433 | }, | | |
| 434 | } | | |
| 435 | }, | | |
| 436 | .elem_ptr => return lowerParentPtr( | | |
| 437 | bin_file, | 378 | bin_file, |
| 438 | src_loc, | 379 | src_loc, |
| 439 | typed_value, | 380 | typed_value, |
| ... | @@ -846,16 +787,12 @@ pub fn generateSymbol( | ... | @@ -846,16 +787,12 @@ pub fn generateSymbol( |
| 846 | }, | 787 | }, |
| 847 | else => unreachable, | 788 | else => unreachable, |
| 848 | }, | 789 | }, |
| 849 | else => |t| { | 790 | else => |t| return Result{ .fail = try ErrorMsg.create( |
| 850 | return Result{ | 791 | bin_file.allocator, |
| 851 | .fail = try ErrorMsg.create( | 792 | src_loc, |
| 852 | bin_file.allocator, | 793 | "TODO implement generateSymbol for type '{s}'", |
| 853 | src_loc, | 794 | .{@tagName(t)}, |
| 854 | "TODO implement generateSymbol for type '{s}'", | 795 | ) }, |
| 855 | .{@tagName(t)}, | | |
| 856 | ), | | |
| 857 | }; | | |
| 858 | }, | | |
| 859 | } | 796 | } |
| 860 | } | 797 | } |
| 861 | | 798 | |
| ... | @@ -871,6 +808,38 @@ fn lowerParentPtr( | ... | @@ -871,6 +808,38 @@ fn lowerParentPtr( |
| 871 | const target = bin_file.options.target; | 808 | const target = bin_file.options.target; |
| 872 | | 809 | |
| 873 | switch (parent_ptr.tag()) { | 810 | switch (parent_ptr.tag()) { |
| | 811 | .field_ptr => { |
| | 812 | const field_ptr = parent_ptr.castTag(.field_ptr).?.data; |
| | 813 | return lowerParentPtr( |
| | 814 | bin_file, |
| | 815 | src_loc, |
| | 816 | typed_value, |
| | 817 | field_ptr.container_ptr, |
| | 818 | code, |
| | 819 | debug_output, |
| | 820 | reloc_info.offset(@intCast(u32, switch (field_ptr.container_ty.zigTypeTag()) { |
| | 821 | .Pointer => offset: { |
| | 822 | assert(field_ptr.container_ty.isSlice()); |
| | 823 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| | 824 | break :offset switch (field_ptr.field_index) { |
| | 825 | 0 => 0, |
| | 826 | 1 => field_ptr.container_ty.slicePtrFieldType(&buf).abiSize(target), |
| | 827 | else => unreachable, |
| | 828 | }; |
| | 829 | }, |
| | 830 | .Struct, .Union => field_ptr.container_ty.structFieldOffset( |
| | 831 | field_ptr.field_index, |
| | 832 | target, |
| | 833 | ), |
| | 834 | else => return Result{ .fail = try ErrorMsg.create( |
| | 835 | bin_file.allocator, |
| | 836 | src_loc, |
| | 837 | "TODO implement lowerParentPtr for field_ptr with a container of type {}", |
| | 838 | .{field_ptr.container_ty.fmt(bin_file.options.module.?)}, |
| | 839 | ) }, |
| | 840 | })), |
| | 841 | ); |
| | 842 | }, |
| 874 | .elem_ptr => { | 843 | .elem_ptr => { |
| 875 | const elem_ptr = parent_ptr.castTag(.elem_ptr).?.data; | 844 | const elem_ptr = parent_ptr.castTag(.elem_ptr).?.data; |
| 876 | return lowerParentPtr( | 845 | return lowerParentPtr( |