| ... | ... | @@ -484,46 +484,51 @@ pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link. |
| 484 | 484 | return vaddr; |
| 485 | 485 | } |
| 486 | 486 | |
| 487 | | pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result { |
| 488 | | // This is basically the same as lowerUnnamedConst. |
| 489 | | // example: |
| 490 | | // const ty = mod.intern_pool.typeOf(decl_val).toType(); |
| 491 | | // const val = decl_val.toValue(); |
| 492 | | // The symbol name can be something like `__anon_{d}` with `@intFromEnum(decl_val)`. |
| 493 | | // It doesn't have an owner decl because it's just an unnamed constant that might |
| 494 | | // be used by more than one function, however, its address is being used so we need |
| 495 | | // to put it in some location. |
| 496 | | // ... |
| 487 | pub fn lowerAnonDecl( |
| 488 | self: *Elf, |
| 489 | decl_val: InternPool.Index, |
| 490 | explicit_alignment: InternPool.Alignment, |
| 491 | src_loc: Module.SrcLoc, |
| 492 | ) !codegen.Result { |
| 497 | 493 | const gpa = self.base.allocator; |
| 498 | 494 | const mod = self.base.options.module.?; |
| 499 | 495 | const ty = mod.intern_pool.typeOf(decl_val).toType(); |
| 500 | | const gop = try self.anon_decls.getOrPut(gpa, decl_val); |
| 501 | | const required_alignment = switch (decl_align) { |
| 496 | const decl_alignment = switch (explicit_alignment) { |
| 502 | 497 | .none => ty.abiAlignment(mod), |
| 503 | | else => decl_align, |
| 498 | else => explicit_alignment, |
| 504 | 499 | }; |
| 505 | | if (!gop.found_existing or |
| 506 | | required_alignment.order(self.symbol(gop.value_ptr.*).atom(self).?.alignment).compare(.gt)) |
| 507 | | { |
| 508 | | const val = decl_val.toValue(); |
| 509 | | const tv = TypedValue{ .ty = ty, .val = val }; |
| 510 | | const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)}); |
| 511 | | defer gpa.free(name); |
| 512 | | const res = self.lowerConst(name, tv, required_alignment, self.zig_rodata_section_index.?, src_loc) catch |err| switch (err) { |
| 513 | | else => { |
| 514 | | // TODO improve error message |
| 515 | | const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{ |
| 516 | | @errorName(err), |
| 517 | | }); |
| 518 | | return .{ .fail = em }; |
| 519 | | }, |
| 520 | | }; |
| 521 | | const sym_index = switch (res) { |
| 522 | | .ok => |sym_index| sym_index, |
| 523 | | .fail => |em| return .{ .fail = em }, |
| 524 | | }; |
| 525 | | gop.value_ptr.* = sym_index; |
| 526 | | } |
| 500 | if (self.anon_decls.get(decl_val)) |sym_index| { |
| 501 | const existing_alignment = self.symbol(sym_index).atom(self).?.alignment; |
| 502 | if (decl_alignment.order(existing_alignment).compare(.lte)) |
| 503 | return .ok; |
| 504 | } |
| 505 | |
| 506 | const val = decl_val.toValue(); |
| 507 | const tv = TypedValue{ .ty = ty, .val = val }; |
| 508 | var name_buf: [32]u8 = undefined; |
| 509 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ |
| 510 | @intFromEnum(decl_val), |
| 511 | }) catch unreachable; |
| 512 | const res = self.lowerConst( |
| 513 | name, |
| 514 | tv, |
| 515 | decl_alignment, |
| 516 | self.zig_rodata_section_index.?, |
| 517 | src_loc, |
| 518 | ) catch |err| switch (err) { |
| 519 | error.OutOfMemory => return error.OutOfMemory, |
| 520 | else => |e| return .{ .fail = try Module.ErrorMsg.create( |
| 521 | gpa, |
| 522 | src_loc, |
| 523 | "unable to lower constant value: {s}", |
| 524 | .{@errorName(e)}, |
| 525 | ) }, |
| 526 | }; |
| 527 | const sym_index = switch (res) { |
| 528 | .ok => |sym_index| sym_index, |
| 529 | .fail => |em| return .{ .fail = em }, |
| 530 | }; |
| 531 | try self.anon_decls.put(gpa, decl_val, sym_index); |
| 527 | 532 | return .ok; |
| 528 | 533 | } |
| 529 | 534 | |