| ... | ... | @@ -3434,6 +3434,25 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCVa |
| 3434 | 3434 | _ = tv; |
| 3435 | 3435 | } |
| 3436 | 3436 | |
| 3437 | fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue { |
| 3438 | log.debug("lowerUnnamedConst: ty = {}, val = {}", .{ tv.ty, tv.val }); |
| 3439 | const local_sym_index = self.bin_file.lowerUnnamedConst(tv, self.mod_fn.owner_decl) catch |err| { |
| 3440 | return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)}); |
| 3441 | }; |
| 3442 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { |
| 3443 | const vaddr = elf_file.local_symbols.items[local_sym_index].st_value; |
| 3444 | return MCValue{ .memory = vaddr }; |
| 3445 | } else if (self.bin_file.cast(link.File.MachO)) |_| { |
| 3446 | return MCValue{ .direct_load = local_sym_index }; |
| 3447 | } else if (self.bin_file.cast(link.File.Coff)) |_| { |
| 3448 | return self.fail("TODO lower unnamed const in COFF", .{}); |
| 3449 | } else if (self.bin_file.cast(link.File.Plan9)) |_| { |
| 3450 | return self.fail("TODO lower unnamed const in Plan9", .{}); |
| 3451 | } else { |
| 3452 | return self.fail("TODO lower unnamed const", .{}); |
| 3453 | } |
| 3454 | } |
| 3455 | |
| 3437 | 3456 | fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { |
| 3438 | 3457 | if (typed_value.val.isUndef()) |
| 3439 | 3458 | return MCValue{ .undef = {} }; |
| ... | ... | @@ -3449,23 +3468,20 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { |
| 3449 | 3468 | switch (typed_value.ty.zigTypeTag()) { |
| 3450 | 3469 | .Pointer => switch (typed_value.ty.ptrSize()) { |
| 3451 | 3470 | .Slice => { |
| 3452 | | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 3453 | | const ptr_type = typed_value.ty.slicePtrFieldType(&buf); |
| 3454 | | const ptr_mcv = try self.genTypedValue(.{ .ty = ptr_type, .val = typed_value.val }); |
| 3455 | | const slice_len = typed_value.val.sliceLen(); |
| 3456 | | // Codegen can't handle some kinds of indirection. If the wrong union field is accessed here it may mean |
| 3457 | | // the Sema code needs to use anonymous Decls or alloca instructions to store data. |
| 3458 | | const ptr_imm = ptr_mcv.memory; |
| 3459 | | _ = slice_len; |
| 3460 | | _ = ptr_imm; |
| 3461 | | // We need more general support for const data being stored in memory to make this work. |
| 3462 | | return self.fail("TODO codegen for const slices", .{}); |
| 3471 | return self.lowerUnnamedConst(typed_value); |
| 3463 | 3472 | }, |
| 3464 | 3473 | else => { |
| 3465 | | if (typed_value.val.tag() == .int_u64) { |
| 3466 | | return MCValue{ .immediate = typed_value.val.toUnsignedInt() }; |
| 3474 | switch (typed_value.val.tag()) { |
| 3475 | .int_u64 => { |
| 3476 | return MCValue{ .immediate = typed_value.val.toUnsignedInt() }; |
| 3477 | }, |
| 3478 | .slice => { |
| 3479 | return self.lowerUnnamedConst(typed_value); |
| 3480 | }, |
| 3481 | else => { |
| 3482 | return self.fail("TODO codegen more kinds of const pointers: {}", .{typed_value.val.tag()}); |
| 3483 | }, |
| 3467 | 3484 | } |
| 3468 | | return self.fail("TODO codegen more kinds of const pointers", .{}); |
| 3469 | 3485 | }, |
| 3470 | 3486 | }, |
| 3471 | 3487 | .Int => { |
| ... | ... | @@ -3549,6 +3565,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { |
| 3549 | 3565 | return self.fail("TODO implement error union const of type '{}' (error)", .{typed_value.ty}); |
| 3550 | 3566 | } |
| 3551 | 3567 | }, |
| 3568 | .Struct => { |
| 3569 | return self.lowerUnnamedConst(typed_value); |
| 3570 | }, |
| 3552 | 3571 | else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty}), |
| 3553 | 3572 | } |
| 3554 | 3573 | } |