| ... | ... | @@ -77,11 +77,11 @@ pub const String = enum(u32) { |
| 77 | 77 | return self.toIndex() == null; |
| 78 | 78 | } |
| 79 | 79 | |
| 80 | | pub fn slice(self: String, builder: *const Builder) ?[:0]const u8 { |
| 80 | pub fn slice(self: String, builder: *const Builder) ?[]const u8 { |
| 81 | 81 | const index = self.toIndex() orelse return null; |
| 82 | 82 | const start = builder.string_indices.items[index]; |
| 83 | 83 | const end = builder.string_indices.items[index + 1]; |
| 84 | | return builder.string_bytes.items[start .. end - 1 :0]; |
| 84 | return builder.string_bytes.items[start..end]; |
| 85 | 85 | } |
| 86 | 86 | |
| 87 | 87 | const FormatData = struct { |
| ... | ... | @@ -94,17 +94,21 @@ pub const String = enum(u32) { |
| 94 | 94 | _: std.fmt.FormatOptions, |
| 95 | 95 | writer: anytype, |
| 96 | 96 | ) @TypeOf(writer).Error!void { |
| 97 | | if (comptime std.mem.indexOfNone(u8, fmt_str, "@\"")) |_| |
| 97 | if (comptime std.mem.indexOfNone(u8, fmt_str, "\"r")) |_| |
| 98 | 98 | @compileError("invalid format string: '" ++ fmt_str ++ "'"); |
| 99 | 99 | assert(data.string != .none); |
| 100 | | const sentinel_slice = data.string.slice(data.builder) orelse |
| 100 | const string_slice = data.string.slice(data.builder) orelse |
| 101 | 101 | return writer.print("{d}", .{@intFromEnum(data.string)}); |
| 102 | | try printEscapedString(sentinel_slice[0 .. sentinel_slice.len + comptime @intFromBool( |
| 103 | | std.mem.indexOfScalar(u8, fmt_str, '@') != null, |
| 104 | | )], if (comptime std.mem.indexOfScalar(u8, fmt_str, '"')) |_| |
| 105 | | .always_quote |
| 106 | | else |
| 107 | | .quote_unless_valid_identifier, writer); |
| 102 | if (comptime std.mem.indexOfScalar(u8, fmt_str, 'r')) |_| |
| 103 | return writer.writeAll(string_slice); |
| 104 | try printEscapedString( |
| 105 | string_slice, |
| 106 | if (comptime std.mem.indexOfScalar(u8, fmt_str, '"')) |_| |
| 107 | .always_quote |
| 108 | else |
| 109 | .quote_unless_valid_identifier, |
| 110 | writer, |
| 111 | ); |
| 108 | 112 | } |
| 109 | 113 | pub fn fmt(self: String, builder: *const Builder) std.fmt.Formatter(format) { |
| 110 | 114 | return .{ .data = .{ .string = self, .builder = builder } }; |
| ... | ... | @@ -4597,13 +4601,6 @@ pub const Function = struct { |
| 4597 | 4601 | ) std.fmt.Formatter(format) { |
| 4598 | 4602 | return .{ .data = .{ .instruction = self, .function = function, .builder = builder } }; |
| 4599 | 4603 | } |
| 4600 | | |
| 4601 | | fn llvmName(self: Instruction.Index, wip: *const WipFunction) [:0]const u8 { |
| 4602 | | return if (wip.builder.strip) |
| 4603 | | "" |
| 4604 | | else |
| 4605 | | wip.names.items[@intFromEnum(self)].slice(wip.builder).?; |
| 4606 | | } |
| 4607 | 4604 | }; |
| 4608 | 4605 | |
| 4609 | 4606 | pub const ExtraIndex = u32; |
| ... | ... | @@ -5931,15 +5928,47 @@ pub const WipFunction = struct { |
| 5931 | 5928 | |
| 5932 | 5929 | var wip_name: struct { |
| 5933 | 5930 | next_name: String = @enumFromInt(0), |
| 5931 | next_unique_name: std.AutoHashMap(String, String), |
| 5932 | builder: *Builder, |
| 5934 | 5933 | |
| 5935 | | fn map(wip_name: *@This(), old_name: String) String { |
| 5936 | | if (old_name != .empty) return old_name; |
| 5934 | fn map(wip_name: *@This(), name: String, sep: []const u8) Allocator.Error!String { |
| 5935 | switch (name) { |
| 5936 | .none => return .none, |
| 5937 | .empty => { |
| 5938 | assert(wip_name.next_name != .none); |
| 5939 | defer wip_name.next_name = @enumFromInt(@intFromEnum(wip_name.next_name) + 1); |
| 5940 | return wip_name.next_name; |
| 5941 | }, |
| 5942 | _ => { |
| 5943 | assert(!name.isAnon()); |
| 5944 | const gop = try wip_name.next_unique_name.getOrPut(name); |
| 5945 | if (!gop.found_existing) { |
| 5946 | gop.value_ptr.* = @enumFromInt(0); |
| 5947 | return name; |
| 5948 | } |
| 5937 | 5949 | |
| 5938 | | const new_name = wip_name.next_name; |
| 5939 | | wip_name.next_name = @enumFromInt(@intFromEnum(new_name) + 1); |
| 5940 | | return new_name; |
| 5950 | while (true) { |
| 5951 | gop.value_ptr.* = @enumFromInt(@intFromEnum(gop.value_ptr.*) + 1); |
| 5952 | const unique_name = try wip_name.builder.fmt("{r}{s}{r}", .{ |
| 5953 | name.fmt(wip_name.builder), |
| 5954 | sep, |
| 5955 | gop.value_ptr.fmt(wip_name.builder), |
| 5956 | }); |
| 5957 | const unique_gop = try wip_name.next_unique_name.getOrPut(unique_name); |
| 5958 | if (!unique_gop.found_existing) { |
| 5959 | unique_gop.value_ptr.* = @enumFromInt(0); |
| 5960 | return unique_name; |
| 5961 | } |
| 5962 | } |
| 5963 | }, |
| 5964 | } |
| 5941 | 5965 | } |
| 5942 | | } = .{}; |
| 5966 | } = .{ |
| 5967 | .next_unique_name = std.AutoHashMap(String, String).init(gpa), |
| 5968 | .builder = self.builder, |
| 5969 | }; |
| 5970 | defer wip_name.next_unique_name.deinit(); |
| 5971 | |
| 5943 | 5972 | var value_index: u32 = 0; |
| 5944 | 5973 | for (0..params_len) |param_index| { |
| 5945 | 5974 | const old_argument_index: Instruction.Index = @enumFromInt(param_index); |
| ... | ... | @@ -5950,8 +5979,9 @@ pub const WipFunction = struct { |
| 5950 | 5979 | value_indices[function.instructions.len] = value_index; |
| 5951 | 5980 | value_index += 1; |
| 5952 | 5981 | function.instructions.appendAssumeCapacity(argument); |
| 5953 | | names[@intFromEnum(new_argument_index)] = wip_name.map( |
| 5982 | names[@intFromEnum(new_argument_index)] = try wip_name.map( |
| 5954 | 5983 | if (self.builder.strip) .empty else self.names.items[@intFromEnum(old_argument_index)], |
| 5984 | ".", |
| 5955 | 5985 | ); |
| 5956 | 5986 | if (self.debug_locations.get(old_argument_index)) |location| { |
| 5957 | 5987 | debug_locations.putAssumeCapacity(new_argument_index, location); |
| ... | ... | @@ -5967,7 +5997,7 @@ pub const WipFunction = struct { |
| 5967 | 5997 | .tag = .block, |
| 5968 | 5998 | .data = current_block.incoming, |
| 5969 | 5999 | }); |
| 5970 | | names[@intFromEnum(new_block_index)] = wip_name.map(current_block.name); |
| 6000 | names[@intFromEnum(new_block_index)] = try wip_name.map(current_block.name, ""); |
| 5971 | 6001 | for (current_block.instructions.items) |old_instruction_index| { |
| 5972 | 6002 | const new_instruction_index: Instruction.Index = |
| 5973 | 6003 | @enumFromInt(function.instructions.len); |
| ... | ... | @@ -6268,10 +6298,10 @@ pub const WipFunction = struct { |
| 6268 | 6298 | }, |
| 6269 | 6299 | } |
| 6270 | 6300 | function.instructions.appendAssumeCapacity(instruction); |
| 6271 | | names[@intFromEnum(new_instruction_index)] = wip_name.map(if (self.builder.strip) |
| 6301 | names[@intFromEnum(new_instruction_index)] = try wip_name.map(if (self.builder.strip) |
| 6272 | 6302 | if (old_instruction_index.hasResultWip(self)) .empty else .none |
| 6273 | 6303 | else |
| 6274 | | self.names.items[@intFromEnum(old_instruction_index)]); |
| 6304 | self.names.items[@intFromEnum(old_instruction_index)], "."); |
| 6275 | 6305 | |
| 6276 | 6306 | if (self.debug_locations.get(old_instruction_index)) |location| { |
| 6277 | 6307 | debug_locations.putAssumeCapacity(new_instruction_index, location); |
| ... | ... | @@ -6687,7 +6717,6 @@ pub const Constant = enum(u32) { |
| 6687 | 6717 | packed_structure, |
| 6688 | 6718 | array, |
| 6689 | 6719 | string, |
| 6690 | | string_null, |
| 6691 | 6720 | vector, |
| 6692 | 6721 | splat, |
| 6693 | 6722 | zeroinitializer, |
| ... | ... | @@ -6943,10 +6972,8 @@ pub const Constant = enum(u32) { |
| 6943 | 6972 | => builder.constantExtraData(Aggregate, item.data).type, |
| 6944 | 6973 | .splat => builder.constantExtraData(Splat, item.data).type, |
| 6945 | 6974 | .string, |
| 6946 | | .string_null, |
| 6947 | 6975 | => builder.arrayTypeAssumeCapacity( |
| 6948 | | @as(String, @enumFromInt(item.data)).slice(builder).?.len + |
| 6949 | | @intFromBool(item.tag == .string_null), |
| 6976 | @as(String, @enumFromInt(item.data)).slice(builder).?.len, |
| 6950 | 6977 | .i8, |
| 6951 | 6978 | ), |
| 6952 | 6979 | .blockaddress => builder.ptrTypeAssumeCapacity( |
| ... | ... | @@ -7281,13 +7308,9 @@ pub const Constant = enum(u32) { |
| 7281 | 7308 | } |
| 7282 | 7309 | try writer.writeByte('>'); |
| 7283 | 7310 | }, |
| 7284 | | inline .string, |
| 7285 | | .string_null, |
| 7286 | | => |tag| try writer.print("c{\"" ++ switch (tag) { |
| 7287 | | .string => "", |
| 7288 | | .string_null => "@", |
| 7289 | | else => unreachable, |
| 7290 | | } ++ "}", .{@as(String, @enumFromInt(item.data)).fmt(data.builder)}), |
| 7311 | .string => try writer.print("c{\"}", .{ |
| 7312 | @as(String, @enumFromInt(item.data)).fmt(data.builder), |
| 7313 | }), |
| 7291 | 7314 | .blockaddress => |tag| { |
| 7292 | 7315 | const extra = data.builder.constantExtraData(BlockAddress, item.data); |
| 7293 | 7316 | const function = extra.function.ptrConst(data.builder); |
| ... | ... | @@ -7658,7 +7681,7 @@ pub const Metadata = enum(u32) { |
| 7658 | 7681 | { |
| 7659 | 7682 | const index = @intFromEnum(metadata) - Metadata.first_forward_reference; |
| 7660 | 7683 | metadata = builder.metadata_forward_references.items[index]; |
| 7661 | | std.debug.assert(metadata != .none); |
| 7684 | assert(metadata != .none); |
| 7662 | 7685 | } |
| 7663 | 7686 | return metadata; |
| 7664 | 7687 | } |
| ... | ... | @@ -8058,30 +8081,33 @@ pub const Metadata = enum(u32) { |
| 8058 | 8081 | } |
| 8059 | 8082 | }, |
| 8060 | 8083 | .index => |item| try writer.print("!{d}", .{item}), |
| 8061 | | .value => |item| try Value.format(.{ |
| 8062 | | .value = switch (item.value.unwrap()) { |
| 8063 | | .instruction, .constant => item.value, |
| 8064 | | .metadata => |metadata| if (@intFromEnum(metadata) >= |
| 8065 | | Metadata.first_local_metadata) |
| 8066 | | item.function.ptrConst(builder).debug_values[ |
| 8084 | .value => |item| switch (item.value.unwrap()) { |
| 8085 | .instruction, .constant => try Value.format(.{ |
| 8086 | .value = item.value, |
| 8087 | .function = item.function, |
| 8088 | .builder = builder, |
| 8089 | }, fmt_str, fmt_opts, writer), |
| 8090 | .metadata => |metadata| if (@intFromEnum(metadata) >= |
| 8091 | Metadata.first_local_metadata) |
| 8092 | try Value.format(.{ |
| 8093 | .value = item.function.ptrConst(builder).debug_values[ |
| 8067 | 8094 | @intFromEnum(metadata) - Metadata.first_local_metadata |
| 8068 | | ].toValue() |
| 8069 | | else if (metadata != .none) { |
| 8070 | | if (comptime std.mem.eql(u8, fmt_str, "%")) |
| 8071 | | try writer.print("{%} ", .{Type.metadata.fmt(builder)}); |
| 8072 | | try Metadata.Formatter.format(.{ |
| 8073 | | .formatter = data.formatter, |
| 8074 | | .item = data.formatter.unwrapAssumeExists(metadata), |
| 8075 | | }, "", fmt_opts, writer); |
| 8076 | | return; |
| 8077 | | } else return, |
| 8095 | ].toValue(), |
| 8096 | .function = item.function, |
| 8097 | .builder = builder, |
| 8098 | }, "%", fmt_opts, writer) |
| 8099 | else if (metadata != .none) { |
| 8100 | if (comptime std.mem.eql(u8, fmt_str, "%")) |
| 8101 | try writer.print("{%} ", .{Type.metadata.fmt(builder)}); |
| 8102 | try Metadata.Formatter.format(.{ |
| 8103 | .formatter = data.formatter, |
| 8104 | .item = data.formatter.unwrapAssumeExists(metadata), |
| 8105 | }, "", fmt_opts, writer); |
| 8078 | 8106 | }, |
| 8079 | | .function = item.function, |
| 8080 | | .builder = builder, |
| 8081 | | }, "%", fmt_opts, writer), |
| 8107 | }, |
| 8082 | 8108 | .string => |item| try writer.print("{}", .{item.fmt(data.formatter.builder)}), |
| 8083 | 8109 | inline .bool, .u32, .u64 => |item| try writer.print("{}", .{item}), |
| 8084 | | .raw => |item| try writer.print("{s}", .{item}), |
| 8110 | .raw => |item| try writer.writeAll(item), |
| 8085 | 8111 | } |
| 8086 | 8112 | } |
| 8087 | 8113 | inline fn fmt(formatter: *Formatter, prefix: []const u8, item: anytype) switch (@TypeOf(item)) { |
| ... | ... | @@ -8188,7 +8214,7 @@ pub const Metadata = enum(u32) { |
| 8188 | 8214 | inline for (fields[2..], names) |*field, name| { |
| 8189 | 8215 | fmt_str = fmt_str ++ "{[" ++ name ++ "]}"; |
| 8190 | 8216 | field.* = .{ |
| 8191 | | .name = name ++ "", |
| 8217 | .name = name, |
| 8192 | 8218 | .type = std.fmt.Formatter(format), |
| 8193 | 8219 | .default_value = null, |
| 8194 | 8220 | .is_comptime = false, |
| ... | ... | @@ -8305,7 +8331,7 @@ pub fn init(options: Options) Allocator.Error!Builder { |
| 8305 | 8331 | assert(try self.intConst(.i1, 0) == .false); |
| 8306 | 8332 | assert(try self.intConst(.i1, 1) == .true); |
| 8307 | 8333 | assert(try self.noneConst(.token) == .none); |
| 8308 | | assert(try self.debugNone() == .none); |
| 8334 | if (!self.strip) assert(try self.debugNone() == .none); |
| 8309 | 8335 | |
| 8310 | 8336 | try self.metadata_string_indices.append(self.gpa, 0); |
| 8311 | 8337 | assert(try self.metadataString("") == .none); |
| ... | ... | @@ -8374,19 +8400,22 @@ pub fn finishModuleAsm(self: *Builder) Allocator.Error!void { |
| 8374 | 8400 | } |
| 8375 | 8401 | |
| 8376 | 8402 | pub fn string(self: *Builder, bytes: []const u8) Allocator.Error!String { |
| 8377 | | try self.string_bytes.ensureUnusedCapacity(self.gpa, bytes.len + 1); |
| 8403 | try self.string_bytes.ensureUnusedCapacity(self.gpa, bytes.len); |
| 8378 | 8404 | try self.string_indices.ensureUnusedCapacity(self.gpa, 1); |
| 8379 | 8405 | try self.string_map.ensureUnusedCapacity(self.gpa, 1); |
| 8380 | 8406 | |
| 8381 | 8407 | const gop = self.string_map.getOrPutAssumeCapacityAdapted(bytes, String.Adapter{ .builder = self }); |
| 8382 | 8408 | if (!gop.found_existing) { |
| 8383 | 8409 | self.string_bytes.appendSliceAssumeCapacity(bytes); |
| 8384 | | self.string_bytes.appendAssumeCapacity(0); |
| 8385 | 8410 | self.string_indices.appendAssumeCapacity(@intCast(self.string_bytes.items.len)); |
| 8386 | 8411 | } |
| 8387 | 8412 | return String.fromIndex(gop.index); |
| 8388 | 8413 | } |
| 8389 | 8414 | |
| 8415 | pub fn stringNull(self: *Builder, bytes: [:0]const u8) Allocator.Error!String { |
| 8416 | return self.string(bytes[0 .. bytes.len + 1]); |
| 8417 | } |
| 8418 | |
| 8390 | 8419 | pub fn stringIfExists(self: *const Builder, bytes: []const u8) ?String { |
| 8391 | 8420 | return String.fromIndex( |
| 8392 | 8421 | self.string_map.getIndexAdapted(bytes, String.Adapter{ .builder = self }) orelse return null, |
| ... | ... | @@ -8395,15 +8424,15 @@ pub fn stringIfExists(self: *const Builder, bytes: []const u8) ?String { |
| 8395 | 8424 | |
| 8396 | 8425 | pub fn fmt(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) Allocator.Error!String { |
| 8397 | 8426 | try self.string_map.ensureUnusedCapacity(self.gpa, 1); |
| 8398 | | try self.string_bytes.ensureUnusedCapacity(self.gpa, @intCast(std.fmt.count(fmt_str ++ .{0}, fmt_args))); |
| 8427 | try self.string_bytes.ensureUnusedCapacity(self.gpa, @intCast(std.fmt.count(fmt_str, fmt_args))); |
| 8399 | 8428 | try self.string_indices.ensureUnusedCapacity(self.gpa, 1); |
| 8400 | 8429 | return self.fmtAssumeCapacity(fmt_str, fmt_args); |
| 8401 | 8430 | } |
| 8402 | 8431 | |
| 8403 | 8432 | pub fn fmtAssumeCapacity(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) String { |
| 8404 | 8433 | const start = self.string_bytes.items.len; |
| 8405 | | self.string_bytes.writer(self.gpa).print(fmt_str ++ .{0}, fmt_args) catch unreachable; |
| 8406 | | const bytes: []const u8 = self.string_bytes.items[start .. self.string_bytes.items.len - 1]; |
| 8434 | self.string_bytes.writer(undefined).print(fmt_str, fmt_args) catch unreachable; |
| 8435 | const bytes: []const u8 = self.string_bytes.items[start..]; |
| 8407 | 8436 | |
| 8408 | 8437 | const gop = self.string_map.getOrPutAssumeCapacityAdapted(bytes, String.Adapter{ .builder = self }); |
| 8409 | 8438 | if (gop.found_existing) { |
| ... | ... | @@ -8468,7 +8497,7 @@ pub fn structType( |
| 8468 | 8497 | pub fn opaqueType(self: *Builder, name: String) Allocator.Error!Type { |
| 8469 | 8498 | try self.string_map.ensureUnusedCapacity(self.gpa, 1); |
| 8470 | 8499 | if (name.slice(self)) |id| { |
| 8471 | | const count: usize = comptime std.fmt.count("{d}" ++ .{0}, .{std.math.maxInt(u32)}); |
| 8500 | const count: usize = comptime std.fmt.count("{d}", .{std.math.maxInt(u32)}); |
| 8472 | 8501 | try self.string_bytes.ensureUnusedCapacity(self.gpa, id.len + count); |
| 8473 | 8502 | } |
| 8474 | 8503 | try self.string_indices.ensureUnusedCapacity(self.gpa, 1); |
| ... | ... | @@ -8911,16 +8940,6 @@ pub fn stringValue(self: *Builder, val: String) Allocator.Error!Value { |
| 8911 | 8940 | return (try self.stringConst(val)).toValue(); |
| 8912 | 8941 | } |
| 8913 | 8942 | |
| 8914 | | pub fn stringNullConst(self: *Builder, val: String) Allocator.Error!Constant { |
| 8915 | | try self.ensureUnusedTypeCapacity(1, Type.Array, 0); |
| 8916 | | try self.ensureUnusedConstantCapacity(1, NoExtra, 0); |
| 8917 | | return self.stringNullConstAssumeCapacity(val); |
| 8918 | | } |
| 8919 | | |
| 8920 | | pub fn stringNullValue(self: *Builder, val: String) Allocator.Error!Value { |
| 8921 | | return (try self.stringNullConst(val)).toValue(); |
| 8922 | | } |
| 8923 | | |
| 8924 | 8943 | pub fn vectorConst(self: *Builder, ty: Type, vals: []const Constant) Allocator.Error!Constant { |
| 8925 | 8944 | try self.ensureUnusedConstantCapacity(1, Constant.Aggregate, vals.len); |
| 8926 | 8945 | return self.vectorConstAssumeCapacity(ty, vals); |
| ... | ... | @@ -9354,7 +9373,7 @@ pub fn printUnbuffered( |
| 9354 | 9373 | defer metadata_formatter.need_comma = undefined; |
| 9355 | 9374 | try writer.print("{ }{}", .{ |
| 9356 | 9375 | function.alignment, |
| 9357 | | try metadata_formatter.fmt("!dbg ", global.dbg), |
| 9376 | try metadata_formatter.fmt(" !dbg ", global.dbg), |
| 9358 | 9377 | }); |
| 9359 | 9378 | } |
| 9360 | 9379 | if (function.instructions.len > 0) { |
| ... | ... | @@ -9513,7 +9532,8 @@ pub fn printUnbuffered( |
| 9513 | 9532 | const name = instruction_index.name(&function); |
| 9514 | 9533 | if (@intFromEnum(instruction_index) > params_len) |
| 9515 | 9534 | try writer.writeByte('\n'); |
| 9516 | | try writer.print("{}:", .{name.fmt(self)}); |
| 9535 | try writer.print("{}:\n", .{name.fmt(self)}); |
| 9536 | continue; |
| 9517 | 9537 | }, |
| 9518 | 9538 | .br => |tag| { |
| 9519 | 9539 | const target: Function.Block.Index = @enumFromInt(instruction.data); |
| ... | ... | @@ -9965,6 +9985,7 @@ pub fn printUnbuffered( |
| 9965 | 9985 | .composite_union_type, |
| 9966 | 9986 | .composite_enumeration_type, |
| 9967 | 9987 | .composite_array_type, |
| 9988 | .composite_vector_type, |
| 9968 | 9989 | => |kind| { |
| 9969 | 9990 | const extra = self.metadataExtraData(Metadata.CompositeType, metadata_item.data); |
| 9970 | 9991 | try metadata_formatter.specialized(.@"distinct !", .DICompositeType, .{ |
| ... | ... | @@ -10165,9 +10186,6 @@ pub fn printUnbuffered( |
| 10165 | 10186 | .expr = extra.expression, |
| 10166 | 10187 | }, writer); |
| 10167 | 10188 | }, |
| 10168 | | else => { |
| 10169 | | try writer.writeByte('\n'); |
| 10170 | | }, |
| 10171 | 10189 | } |
| 10172 | 10190 | } |
| 10173 | 10191 | } |
| ... | ... | @@ -10206,7 +10224,7 @@ fn printEscapedString( |
| 10206 | 10224 | fn ensureUnusedGlobalCapacity(self: *Builder, name: String) Allocator.Error!void { |
| 10207 | 10225 | try self.string_map.ensureUnusedCapacity(self.gpa, 1); |
| 10208 | 10226 | if (name.slice(self)) |id| { |
| 10209 | | const count: usize = comptime std.fmt.count("{d}" ++ .{0}, .{std.math.maxInt(u32)}); |
| 10227 | const count: usize = comptime std.fmt.count("{d}", .{std.math.maxInt(u32)}); |
| 10210 | 10228 | try self.string_bytes.ensureUnusedCapacity(self.gpa, id.len + count); |
| 10211 | 10229 | } |
| 10212 | 10230 | try self.string_indices.ensureUnusedCapacity(self.gpa, 1); |
| ... | ... | @@ -10881,16 +10899,6 @@ fn stringConstAssumeCapacity(self: *Builder, val: String) Constant { |
| 10881 | 10899 | return result.constant; |
| 10882 | 10900 | } |
| 10883 | 10901 | |
| 10884 | | fn stringNullConstAssumeCapacity(self: *Builder, val: String) Constant { |
| 10885 | | const slice = val.slice(self).?; |
| 10886 | | const ty = self.arrayTypeAssumeCapacity(slice.len + 1, .i8); |
| 10887 | | if (std.mem.allEqual(u8, slice, 0)) return self.zeroInitConstAssumeCapacity(ty); |
| 10888 | | const result = self.getOrPutConstantNoExtraAssumeCapacity( |
| 10889 | | .{ .tag = .string_null, .data = @intFromEnum(val) }, |
| 10890 | | ); |
| 10891 | | return result.constant; |
| 10892 | | } |
| 10893 | | |
| 10894 | 10902 | fn vectorConstAssumeCapacity(self: *Builder, ty: Type, vals: []const Constant) Constant { |
| 10895 | 10903 | assert(ty.isVector(self)); |
| 10896 | 10904 | assert(ty.vectorLen(self) == vals.len); |
| ... | ... | @@ -11756,8 +11764,8 @@ pub fn metadataStringFmt(self: *Builder, comptime fmt_str: []const u8, fmt_args: |
| 11756 | 11764 | |
| 11757 | 11765 | pub fn metadataStringFmtAssumeCapacity(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) MetadataString { |
| 11758 | 11766 | const start = self.metadata_string_bytes.items.len; |
| 11759 | | self.metadata_string_bytes.writer(self.gpa).print(fmt_str, fmt_args) catch unreachable; |
| 11760 | | const bytes: []const u8 = self.metadata_string_bytes.items[start..self.metadata_string_bytes.items.len]; |
| 11767 | self.metadata_string_bytes.writer(undefined).print(fmt_str, fmt_args) catch unreachable; |
| 11768 | const bytes: []const u8 = self.metadata_string_bytes.items[start..]; |
| 11761 | 11769 | |
| 11762 | 11770 | const gop = self.metadata_string_map.getOrPutAssumeCapacityAdapted(bytes, String.Adapter{ .builder = self }); |
| 11763 | 11771 | if (gop.found_existing) { |
| ... | ... | @@ -12042,7 +12050,7 @@ pub fn debugEnumerator( |
| 12042 | 12050 | bit_width: u32, |
| 12043 | 12051 | value: std.math.big.int.Const, |
| 12044 | 12052 | ) Allocator.Error!Metadata { |
| 12045 | | std.debug.assert(!(unsigned and !value.positive)); |
| 12053 | assert(!(unsigned and !value.positive)); |
| 12046 | 12054 | try self.ensureUnusedMetadataCapacity(1, Metadata.Enumerator, 0); |
| 12047 | 12055 | try self.metadata_limbs.ensureUnusedCapacity(self.gpa, value.limbs.len); |
| 12048 | 12056 | return self.debugEnumeratorAssumeCapacity(name, unsigned, bit_width, value); |
| ... | ... | @@ -12147,7 +12155,7 @@ pub fn debugConstant(self: *Builder, value: Constant) Allocator.Error!Metadata { |
| 12147 | 12155 | } |
| 12148 | 12156 | |
| 12149 | 12157 | pub fn debugForwardReferenceSetType(self: *Builder, fwd_ref: Metadata, ty: Metadata) void { |
| 12150 | | std.debug.assert( |
| 12158 | assert( |
| 12151 | 12159 | @intFromEnum(fwd_ref) >= Metadata.first_forward_reference and |
| 12152 | 12160 | @intFromEnum(fwd_ref) <= Metadata.first_local_metadata, |
| 12153 | 12161 | ); |
| ... | ... | @@ -12226,7 +12234,8 @@ fn metadataDistinctAssumeCapacity(self: *Builder, tag: Metadata.Tag, value: anyt |
| 12226 | 12234 | } |
| 12227 | 12235 | |
| 12228 | 12236 | fn debugNamedAssumeCapacity(self: *Builder, name: MetadataString, operands: []const Metadata) void { |
| 12229 | | std.debug.assert(name != .none); |
| 12237 | assert(!self.strip); |
| 12238 | assert(name != .none); |
| 12230 | 12239 | const extra_index: u32 = @intCast(self.metadata_extra.items.len); |
| 12231 | 12240 | self.metadata_extra.appendSliceAssumeCapacity(@ptrCast(operands)); |
| 12232 | 12241 | |
| ... | ... | @@ -12238,6 +12247,7 @@ fn debugNamedAssumeCapacity(self: *Builder, name: MetadataString, operands: []co |
| 12238 | 12247 | } |
| 12239 | 12248 | |
| 12240 | 12249 | pub fn debugNoneAssumeCapacity(self: *Builder) Metadata { |
| 12250 | assert(!self.strip); |
| 12241 | 12251 | return self.metadataSimpleAssumeCapacity(.none, .{}); |
| 12242 | 12252 | } |
| 12243 | 12253 | |
| ... | ... | @@ -12246,6 +12256,7 @@ fn debugFileAssumeCapacity( |
| 12246 | 12256 | filename: MetadataString, |
| 12247 | 12257 | directory: MetadataString, |
| 12248 | 12258 | ) Metadata { |
| 12259 | assert(!self.strip); |
| 12249 | 12260 | return self.metadataDistinctAssumeCapacity(.file, Metadata.File{ |
| 12250 | 12261 | .filename = filename, |
| 12251 | 12262 | .directory = directory, |
| ... | ... | @@ -12260,6 +12271,7 @@ pub fn debugCompileUnitAssumeCapacity( |
| 12260 | 12271 | globals: Metadata, |
| 12261 | 12272 | options: Metadata.CompileUnit.Options, |
| 12262 | 12273 | ) Metadata { |
| 12274 | assert(!self.strip); |
| 12263 | 12275 | return self.metadataDistinctAssumeCapacity( |
| 12264 | 12276 | if (options.optimized) .@"compile_unit optimized" else .compile_unit, |
| 12265 | 12277 | Metadata.CompileUnit{ |
| ... | ... | @@ -12282,6 +12294,7 @@ fn debugSubprogramAssumeCapacity( |
| 12282 | 12294 | options: Metadata.Subprogram.Options, |
| 12283 | 12295 | compile_unit: Metadata, |
| 12284 | 12296 | ) Metadata { |
| 12297 | assert(!self.strip); |
| 12285 | 12298 | const tag: Metadata.Tag = @enumFromInt(@intFromEnum(Metadata.Tag.subprogram) + |
| 12286 | 12299 | @as(u3, @truncate(@as(u32, @bitCast(options.sp_flags)) >> 2))); |
| 12287 | 12300 | return self.metadataDistinctAssumeCapacity(tag, Metadata.Subprogram{ |
| ... | ... | @@ -12297,6 +12310,7 @@ fn debugSubprogramAssumeCapacity( |
| 12297 | 12310 | } |
| 12298 | 12311 | |
| 12299 | 12312 | fn debugLexicalBlockAssumeCapacity(self: *Builder, scope: Metadata, file: Metadata, line: u32, column: u32) Metadata { |
| 12313 | assert(!self.strip); |
| 12300 | 12314 | return self.metadataDistinctAssumeCapacity(.lexical_block, Metadata.LexicalBlock{ |
| 12301 | 12315 | .scope = scope, |
| 12302 | 12316 | .file = file, |
| ... | ... | @@ -12306,6 +12320,7 @@ fn debugLexicalBlockAssumeCapacity(self: *Builder, scope: Metadata, file: Metada |
| 12306 | 12320 | } |
| 12307 | 12321 | |
| 12308 | 12322 | fn debugLocationAssumeCapacity(self: *Builder, line: u32, column: u32, scope: Metadata, inlined_at: Metadata) Metadata { |
| 12323 | assert(!self.strip); |
| 12309 | 12324 | return self.metadataSimpleAssumeCapacity(.location, Metadata.Location{ |
| 12310 | 12325 | .line = line, |
| 12311 | 12326 | .column = column, |
| ... | ... | @@ -12315,6 +12330,7 @@ fn debugLocationAssumeCapacity(self: *Builder, line: u32, column: u32, scope: Me |
| 12315 | 12330 | } |
| 12316 | 12331 | |
| 12317 | 12332 | fn debugBoolTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bits: u64) Metadata { |
| 12333 | assert(!self.strip); |
| 12318 | 12334 | return self.metadataDistinctAssumeCapacity(.basic_bool_type, Metadata.BasicType{ |
| 12319 | 12335 | .name = name, |
| 12320 | 12336 | .size_in_bits_lo = @truncate(size_in_bits), |
| ... | ... | @@ -12323,6 +12339,7 @@ fn debugBoolTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bit |
| 12323 | 12339 | } |
| 12324 | 12340 | |
| 12325 | 12341 | fn debugUnsignedTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bits: u64) Metadata { |
| 12342 | assert(!self.strip); |
| 12326 | 12343 | return self.metadataDistinctAssumeCapacity(.basic_unsigned_type, Metadata.BasicType{ |
| 12327 | 12344 | .name = name, |
| 12328 | 12345 | .size_in_bits_lo = @truncate(size_in_bits), |
| ... | ... | @@ -12331,6 +12348,7 @@ fn debugUnsignedTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in |
| 12331 | 12348 | } |
| 12332 | 12349 | |
| 12333 | 12350 | fn debugSignedTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bits: u64) Metadata { |
| 12351 | assert(!self.strip); |
| 12334 | 12352 | return self.metadataDistinctAssumeCapacity(.basic_signed_type, Metadata.BasicType{ |
| 12335 | 12353 | .name = name, |
| 12336 | 12354 | .size_in_bits_lo = @truncate(size_in_bits), |
| ... | ... | @@ -12339,6 +12357,7 @@ fn debugSignedTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_b |
| 12339 | 12357 | } |
| 12340 | 12358 | |
| 12341 | 12359 | fn debugFloatTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bits: u64) Metadata { |
| 12360 | assert(!self.strip); |
| 12342 | 12361 | return self.metadataDistinctAssumeCapacity(.basic_float_type, Metadata.BasicType{ |
| 12343 | 12362 | .name = name, |
| 12344 | 12363 | .size_in_bits_lo = @truncate(size_in_bits), |
| ... | ... | @@ -12347,6 +12366,7 @@ fn debugFloatTypeAssumeCapacity(self: *Builder, name: MetadataString, size_in_bi |
| 12347 | 12366 | } |
| 12348 | 12367 | |
| 12349 | 12368 | fn debugForwardReferenceAssumeCapacity(self: *Builder) Metadata { |
| 12369 | assert(!self.strip); |
| 12350 | 12370 | const index = Metadata.first_forward_reference + self.metadata_forward_references.items.len; |
| 12351 | 12371 | self.metadata_forward_references.appendAssumeCapacity(.none); |
| 12352 | 12372 | return @enumFromInt(index); |
| ... | ... | @@ -12363,6 +12383,7 @@ fn debugStructTypeAssumeCapacity( |
| 12363 | 12383 | align_in_bits: u64, |
| 12364 | 12384 | fields_tuple: Metadata, |
| 12365 | 12385 | ) Metadata { |
| 12386 | assert(!self.strip); |
| 12366 | 12387 | return self.debugCompositeTypeAssumeCapacity( |
| 12367 | 12388 | .composite_struct_type, |
| 12368 | 12389 | name, |
| ... | ... | @@ -12387,6 +12408,7 @@ fn debugUnionTypeAssumeCapacity( |
| 12387 | 12408 | align_in_bits: u64, |
| 12388 | 12409 | fields_tuple: Metadata, |
| 12389 | 12410 | ) Metadata { |
| 12411 | assert(!self.strip); |
| 12390 | 12412 | return self.debugCompositeTypeAssumeCapacity( |
| 12391 | 12413 | .composite_union_type, |
| 12392 | 12414 | name, |
| ... | ... | @@ -12411,6 +12433,7 @@ fn debugEnumerationTypeAssumeCapacity( |
| 12411 | 12433 | align_in_bits: u64, |
| 12412 | 12434 | fields_tuple: Metadata, |
| 12413 | 12435 | ) Metadata { |
| 12436 | assert(!self.strip); |
| 12414 | 12437 | return self.debugCompositeTypeAssumeCapacity( |
| 12415 | 12438 | .composite_enumeration_type, |
| 12416 | 12439 | name, |
| ... | ... | @@ -12435,6 +12458,7 @@ fn debugArrayTypeAssumeCapacity( |
| 12435 | 12458 | align_in_bits: u64, |
| 12436 | 12459 | fields_tuple: Metadata, |
| 12437 | 12460 | ) Metadata { |
| 12461 | assert(!self.strip); |
| 12438 | 12462 | return self.debugCompositeTypeAssumeCapacity( |
| 12439 | 12463 | .composite_array_type, |
| 12440 | 12464 | name, |
| ... | ... | @@ -12459,6 +12483,7 @@ fn debugVectorTypeAssumeCapacity( |
| 12459 | 12483 | align_in_bits: u64, |
| 12460 | 12484 | fields_tuple: Metadata, |
| 12461 | 12485 | ) Metadata { |
| 12486 | assert(!self.strip); |
| 12462 | 12487 | return self.debugCompositeTypeAssumeCapacity( |
| 12463 | 12488 | .composite_vector_type, |
| 12464 | 12489 | name, |
| ... | ... | @@ -12484,6 +12509,7 @@ fn debugCompositeTypeAssumeCapacity( |
| 12484 | 12509 | align_in_bits: u64, |
| 12485 | 12510 | fields_tuple: Metadata, |
| 12486 | 12511 | ) Metadata { |
| 12512 | assert(!self.strip); |
| 12487 | 12513 | return self.metadataDistinctAssumeCapacity(tag, Metadata.CompositeType{ |
| 12488 | 12514 | .name = name, |
| 12489 | 12515 | .file = file, |
| ... | ... | @@ -12509,6 +12535,7 @@ fn debugPointerTypeAssumeCapacity( |
| 12509 | 12535 | align_in_bits: u64, |
| 12510 | 12536 | offset_in_bits: u64, |
| 12511 | 12537 | ) Metadata { |
| 12538 | assert(!self.strip); |
| 12512 | 12539 | return self.metadataDistinctAssumeCapacity(.derived_pointer_type, Metadata.DerivedType{ |
| 12513 | 12540 | .name = name, |
| 12514 | 12541 | .file = file, |
| ... | ... | @@ -12535,6 +12562,7 @@ fn debugMemberTypeAssumeCapacity( |
| 12535 | 12562 | align_in_bits: u64, |
| 12536 | 12563 | offset_in_bits: u64, |
| 12537 | 12564 | ) Metadata { |
| 12565 | assert(!self.strip); |
| 12538 | 12566 | return self.metadataDistinctAssumeCapacity(.derived_member_type, Metadata.DerivedType{ |
| 12539 | 12567 | .name = name, |
| 12540 | 12568 | .file = file, |
| ... | ... | @@ -12554,6 +12582,7 @@ fn debugSubroutineTypeAssumeCapacity( |
| 12554 | 12582 | self: *Builder, |
| 12555 | 12583 | types_tuple: Metadata, |
| 12556 | 12584 | ) Metadata { |
| 12585 | assert(!self.strip); |
| 12557 | 12586 | return self.metadataDistinctAssumeCapacity(.subroutine_type, Metadata.SubroutineType{ |
| 12558 | 12587 | .types_tuple = types_tuple, |
| 12559 | 12588 | }); |
| ... | ... | @@ -12566,6 +12595,7 @@ fn debugEnumeratorAssumeCapacity( |
| 12566 | 12595 | bit_width: u32, |
| 12567 | 12596 | value: std.math.big.int.Const, |
| 12568 | 12597 | ) Metadata { |
| 12598 | assert(!self.strip); |
| 12569 | 12599 | const Key = struct { tag: Metadata.Tag, index: Metadata }; |
| 12570 | 12600 | const Adapter = struct { |
| 12571 | 12601 | pub fn hash(_: @This(), key: Key) u32 { |
| ... | ... | @@ -12587,7 +12617,7 @@ fn debugEnumeratorAssumeCapacity( |
| 12587 | 12617 | else |
| 12588 | 12618 | .enumerator_signed_negative; |
| 12589 | 12619 | |
| 12590 | | std.debug.assert(!(tag == .enumerator_unsigned and !value.positive)); |
| 12620 | assert(!(tag == .enumerator_unsigned and !value.positive)); |
| 12591 | 12621 | |
| 12592 | 12622 | const gop = self.metadata_map.getOrPutAssumeCapacityAdapted( |
| 12593 | 12623 | Key{ .tag = tag, .index = @enumFromInt(self.metadata_map.count()) }, |
| ... | ... | @@ -12616,6 +12646,7 @@ fn debugSubrangeAssumeCapacity( |
| 12616 | 12646 | lower_bound: Metadata, |
| 12617 | 12647 | count: Metadata, |
| 12618 | 12648 | ) Metadata { |
| 12649 | assert(!self.strip); |
| 12619 | 12650 | return self.metadataDistinctAssumeCapacity(.subrange, Metadata.Subrange{ |
| 12620 | 12651 | .lower_bound = lower_bound, |
| 12621 | 12652 | .count = count, |
| ... | ... | @@ -12626,6 +12657,7 @@ fn debugExpressionAssumeCapacity( |
| 12626 | 12657 | self: *Builder, |
| 12627 | 12658 | elements: []const u32, |
| 12628 | 12659 | ) Metadata { |
| 12660 | assert(!self.strip); |
| 12629 | 12661 | const Key = struct { |
| 12630 | 12662 | elements: []const u32, |
| 12631 | 12663 | }; |
| ... | ... | @@ -12672,6 +12704,7 @@ fn debugTupleAssumeCapacity( |
| 12672 | 12704 | self: *Builder, |
| 12673 | 12705 | elements: []const Metadata, |
| 12674 | 12706 | ) Metadata { |
| 12707 | assert(!self.strip); |
| 12675 | 12708 | const Key = struct { |
| 12676 | 12709 | elements: []const Metadata, |
| 12677 | 12710 | }; |
| ... | ... | @@ -12720,6 +12753,7 @@ fn debugModuleFlagAssumeCapacity( |
| 12720 | 12753 | name: MetadataString, |
| 12721 | 12754 | constant: Metadata, |
| 12722 | 12755 | ) Metadata { |
| 12756 | assert(!self.strip); |
| 12723 | 12757 | return self.metadataSimpleAssumeCapacity(.module_flag, Metadata.ModuleFlag{ |
| 12724 | 12758 | .behavior = behavior, |
| 12725 | 12759 | .name = name, |
| ... | ... | @@ -12734,7 +12768,8 @@ fn debugLocalVarAssumeCapacity( |
| 12734 | 12768 | scope: Metadata, |
| 12735 | 12769 | line: u32, |
| 12736 | 12770 | ty: Metadata, |
| 12737 | | ) Allocator.Error!Metadata { |
| 12771 | ) Metadata { |
| 12772 | assert(!self.strip); |
| 12738 | 12773 | return self.metadataDistinctAssumeCapacity(.local_var, Metadata.LocalVar{ |
| 12739 | 12774 | .name = name, |
| 12740 | 12775 | .file = file, |
| ... | ... | @@ -12752,7 +12787,8 @@ fn debugParameterAssumeCapacity( |
| 12752 | 12787 | line: u32, |
| 12753 | 12788 | ty: Metadata, |
| 12754 | 12789 | arg_no: u32, |
| 12755 | | ) Allocator.Error!Metadata { |
| 12790 | ) Metadata { |
| 12791 | assert(!self.strip); |
| 12756 | 12792 | return self.metadataDistinctAssumeCapacity(.parameter, Metadata.Parameter{ |
| 12757 | 12793 | .name = name, |
| 12758 | 12794 | .file = file, |
| ... | ... | @@ -12773,7 +12809,8 @@ fn debugGlobalVarAssumeCapacity( |
| 12773 | 12809 | ty: Metadata, |
| 12774 | 12810 | variable: Variable.Index, |
| 12775 | 12811 | options: Metadata.GlobalVar.Options, |
| 12776 | | ) Allocator.Error!Metadata { |
| 12812 | ) Metadata { |
| 12813 | assert(!self.strip); |
| 12777 | 12814 | return self.metadataDistinctAssumeCapacity( |
| 12778 | 12815 | if (options.local) .@"global_var local" else .global_var, |
| 12779 | 12816 | Metadata.GlobalVar{ |
| ... | ... | @@ -12793,6 +12830,7 @@ fn debugGlobalVarExpressionAssumeCapacity( |
| 12793 | 12830 | variable: Metadata, |
| 12794 | 12831 | expression: Metadata, |
| 12795 | 12832 | ) Metadata { |
| 12833 | assert(!self.strip); |
| 12796 | 12834 | return self.metadataDistinctAssumeCapacity(.global_var_expression, Metadata.GlobalVarExpression{ |
| 12797 | 12835 | .variable = variable, |
| 12798 | 12836 | .expression = expression, |
| ... | ... | @@ -12800,6 +12838,7 @@ fn debugGlobalVarExpressionAssumeCapacity( |
| 12800 | 12838 | } |
| 12801 | 12839 | |
| 12802 | 12840 | fn debugConstantAssumeCapacity(self: *Builder, constant: Constant) Metadata { |
| 12841 | assert(!self.strip); |
| 12803 | 12842 | const Adapter = struct { |
| 12804 | 12843 | builder: *const Builder, |
| 12805 | 12844 | pub fn hash(_: @This(), key: Constant) u32 { |
| ... | ... | @@ -13528,18 +13567,16 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 13528 | 13567 | } |
| 13529 | 13568 | }, |
| 13530 | 13569 | .string, |
| 13531 | | .string_null, |
| 13532 | 13570 | => { |
| 13533 | 13571 | const str: String = @enumFromInt(data); |
| 13534 | 13572 | if (str == .none) { |
| 13535 | 13573 | try constants_block.writeAbbrev(Constants.Null{}); |
| 13536 | 13574 | } else { |
| 13537 | 13575 | const slice = str.slice(self) orelse unreachable; |
| 13538 | | switch (tags[index]) { |
| 13539 | | .string => try constants_block.writeAbbrev(Constants.String{ .string = slice }), |
| 13540 | | .string_null => try constants_block.writeAbbrev(Constants.CString{ .string = slice }), |
| 13541 | | else => unreachable, |
| 13542 | | } |
| 13576 | if (slice.len > 0 and slice[slice.len - 1] == 0) |
| 13577 | try constants_block.writeAbbrev(Constants.CString{ .string = slice[0 .. slice.len - 1] }) |
| 13578 | else |
| 13579 | try constants_block.writeAbbrev(Constants.String{ .string = slice }); |
| 13543 | 13580 | } |
| 13544 | 13581 | }, |
| 13545 | 13582 | .bitcast, |
| ... | ... | @@ -13918,7 +13955,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 13918 | 13955 | }, |
| 13919 | 13956 | .location => { |
| 13920 | 13957 | const extra = self.metadataExtraData(Metadata.Location, data); |
| 13921 | | std.debug.assert(extra.scope != .none); |
| 13958 | assert(extra.scope != .none); |
| 13922 | 13959 | try metadata_block.writeAbbrev(MetadataBlock.Location{ |
| 13923 | 13960 | .line = extra.line, |
| 13924 | 13961 | .column = extra.column, |