enum Index [src]

Fields

none = std.math.maxInt(u32)
_

Members

Source

pub const Index = enum(u32) { none = std.math.maxInt(u32), _, pub fn unwrap(self: Index, builder: *const Builder) Index { var cur = self; while (true) { const replacement = cur.getReplacement(builder); if (replacement == .none) return cur; cur = replacement; } } pub fn eql(self: Index, other: Index, builder: *const Builder) bool { return self.unwrap(builder) == other.unwrap(builder); } pub fn ptr(self: Index, builder: *Builder) *Global { return &builder.globals.values()[@intFromEnum(self.unwrap(builder))]; } pub fn ptrConst(self: Index, builder: *const Builder) *const Global { return &builder.globals.values()[@intFromEnum(self.unwrap(builder))]; } pub fn name(self: Index, builder: *const Builder) StrtabString { return builder.globals.keys()[@intFromEnum(self.unwrap(builder))]; } pub fn strtab(self: Index, builder: *const Builder) struct { offset: u32, size: u32, } { const name_index = self.name(builder).toIndex() orelse return .{ .offset = 0, .size = 0, }; return .{ .offset = builder.strtab_string_indices.items[name_index], .size = builder.strtab_string_indices.items[name_index + 1] - builder.strtab_string_indices.items[name_index], }; } pub fn typeOf(self: Index, builder: *const Builder) Type { return self.ptrConst(builder).type; } pub fn toConst(self: Index) Constant { return @enumFromInt(@intFromEnum(Constant.first_global) + @intFromEnum(self)); } pub fn setLinkage(self: Index, linkage: Linkage, builder: *Builder) void { self.ptr(builder).linkage = linkage; self.updateDsoLocal(builder); } pub fn setVisibility(self: Index, visibility: Visibility, builder: *Builder) void { self.ptr(builder).visibility = visibility; self.updateDsoLocal(builder); } pub fn setDllStorageClass(self: Index, class: DllStorageClass, builder: *Builder) void { self.ptr(builder).dll_storage_class = class; } pub fn setUnnamedAddr(self: Index, unnamed_addr: UnnamedAddr, builder: *Builder) void { self.ptr(builder).unnamed_addr = unnamed_addr; } pub fn setDebugMetadata(self: Index, dbg: Metadata, builder: *Builder) void { self.ptr(builder).dbg = dbg; } const FormatData = struct { global: Index, builder: *const Builder, }; fn format( data: FormatData, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype, ) @TypeOf(writer).Error!void { try writer.print("@{}", .{ data.global.unwrap(data.builder).name(data.builder).fmt(data.builder), }); } pub fn fmt(self: Index, builder: *const Builder) std.fmt.Formatter(format) { return .{ .data = .{ .global = self, .builder = builder } }; } pub fn rename(self: Index, new_name: StrtabString, builder: *Builder) Allocator.Error!void { try builder.ensureUnusedGlobalCapacity(new_name); self.renameAssumeCapacity(new_name, builder); } pub fn takeName(self: Index, other: Index, builder: *Builder) Allocator.Error!void { try builder.ensureUnusedGlobalCapacity(.empty); self.takeNameAssumeCapacity(other, builder); } pub fn replace(self: Index, other: Index, builder: *Builder) Allocator.Error!void { try builder.ensureUnusedGlobalCapacity(.empty); self.replaceAssumeCapacity(other, builder); } pub fn delete(self: Index, builder: *Builder) void { self.ptr(builder).kind = .{ .replaced = .none }; } fn updateDsoLocal(self: Index, builder: *Builder) void { const self_ptr = self.ptr(builder); switch (self_ptr.linkage) { .private, .internal => { self_ptr.visibility = .default; self_ptr.dll_storage_class = .default; self_ptr.preemption = .implicit_dso_local; }, .extern_weak => if (self_ptr.preemption == .implicit_dso_local) { self_ptr.preemption = .dso_local; }, else => switch (self_ptr.visibility) { .default => if (self_ptr.preemption == .implicit_dso_local) { self_ptr.preemption = .dso_local; }, else => self_ptr.preemption = .implicit_dso_local, }, } } fn renameAssumeCapacity(self: Index, new_name: StrtabString, builder: *Builder) void { const old_name = self.name(builder); if (new_name == old_name) return; const index = @intFromEnum(self.unwrap(builder)); _ = builder.addGlobalAssumeCapacity(new_name, builder.globals.values()[index]); builder.globals.swapRemoveAt(index); if (!old_name.isAnon()) return; builder.next_unnamed_global = @enumFromInt(@intFromEnum(builder.next_unnamed_global) - 1); if (builder.next_unnamed_global == old_name) return; builder.getGlobal(builder.next_unnamed_global).?.renameAssumeCapacity(old_name, builder); } fn takeNameAssumeCapacity(self: Index, other: Index, builder: *Builder) void { const other_name = other.name(builder); other.renameAssumeCapacity(.empty, builder); self.renameAssumeCapacity(other_name, builder); } fn replaceAssumeCapacity(self: Index, other: Index, builder: *Builder) void { if (self.eql(other, builder)) return; builder.next_replaced_global = @enumFromInt(@intFromEnum(builder.next_replaced_global) - 1); self.renameAssumeCapacity(builder.next_replaced_global, builder); self.ptr(builder).kind = .{ .replaced = other.unwrap(builder) }; } fn getReplacement(self: Index, builder: *const Builder) Index { return switch (builder.globals.values()[@intFromEnum(self)].kind) { .replaced => |replacement| replacement, else => .none, }; } }