| ... | ... | @@ -7620,33 +7620,31 @@ pub const FuncGen = struct { |
| 7620 | 7620 | fn airTagName(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| 7621 | 7621 | if (self.liveness.isUnused(inst)) return null; |
| 7622 | 7622 | |
| 7623 | | var arena_allocator = std.heap.ArenaAllocator.init(self.gpa); |
| 7624 | | defer arena_allocator.deinit(); |
| 7625 | | const arena = arena_allocator.allocator(); |
| 7626 | | |
| 7627 | 7623 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 7628 | 7624 | const operand = try self.resolveInst(un_op); |
| 7629 | 7625 | const enum_ty = self.air.typeOf(un_op); |
| 7630 | 7626 | |
| 7631 | | const mod = self.dg.module; |
| 7632 | | const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{ |
| 7633 | | try mod.declPtr(enum_ty.getOwnerDecl()).getFullyQualifiedName(mod), |
| 7634 | | }); |
| 7635 | | |
| 7636 | | const llvm_fn = try self.getEnumTagNameFunction(enum_ty, llvm_fn_name); |
| 7627 | const llvm_fn = try self.getEnumTagNameFunction(enum_ty); |
| 7637 | 7628 | const params = [_]*const llvm.Value{operand}; |
| 7638 | 7629 | return self.builder.buildCall(llvm_fn, &params, params.len, .Fast, .Auto, ""); |
| 7639 | 7630 | } |
| 7640 | 7631 | |
| 7641 | | fn getEnumTagNameFunction( |
| 7642 | | self: *FuncGen, |
| 7643 | | enum_ty: Type, |
| 7644 | | llvm_fn_name: [:0]const u8, |
| 7645 | | ) !*const llvm.Value { |
| 7632 | fn getEnumTagNameFunction(self: *FuncGen, enum_ty: Type) !*const llvm.Value { |
| 7633 | const enum_decl = enum_ty.getOwnerDecl(); |
| 7634 | |
| 7646 | 7635 | // TODO: detect when the type changes and re-emit this function. |
| 7647 | | if (self.dg.object.llvm_module.getNamedFunction(llvm_fn_name)) |llvm_fn| { |
| 7648 | | return llvm_fn; |
| 7649 | | } |
| 7636 | const gop = try self.dg.object.decl_map.getOrPut(self.dg.gpa, enum_decl); |
| 7637 | if (gop.found_existing) return gop.value_ptr.*; |
| 7638 | errdefer assert(self.dg.object.decl_map.remove(enum_decl)); |
| 7639 | |
| 7640 | var arena_allocator = std.heap.ArenaAllocator.init(self.gpa); |
| 7641 | defer arena_allocator.deinit(); |
| 7642 | const arena = arena_allocator.allocator(); |
| 7643 | |
| 7644 | const mod = self.dg.module; |
| 7645 | const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{ |
| 7646 | try mod.declPtr(enum_decl).getFullyQualifiedName(mod), |
| 7647 | }); |
| 7650 | 7648 | |
| 7651 | 7649 | const slice_ty = Type.initTag(.const_slice_u8_sentinel_0); |
| 7652 | 7650 | const llvm_ret_ty = try self.dg.lowerType(slice_ty); |
| ... | ... | @@ -7663,6 +7661,7 @@ pub const FuncGen = struct { |
| 7663 | 7661 | fn_val.setLinkage(.Internal); |
| 7664 | 7662 | fn_val.setFunctionCallConv(.Fast); |
| 7665 | 7663 | self.dg.addCommonFnAttributes(fn_val); |
| 7664 | gop.value_ptr.* = fn_val; |
| 7666 | 7665 | |
| 7667 | 7666 | const prev_block = self.builder.getInsertBlock(); |
| 7668 | 7667 | const prev_debug_location = self.builder.getCurrentDebugLocation2(); |