authorgravatar for alichraghi@proton.meAli Chraghi <alichraghi@proton.me> 2023-10-31 13:12:15+03:30
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-08 16:33:33-08:00
log0e856da224d05816385550e292d97bc50985c2ff
tree5b9254e5b6626a4f4f4f44bec6528935bccdb823
parentdeed19496a98a22ed39025721d448ce2f47642ea

add type safety to ZIR for null terminated strings


6 files changed, 248 insertions(+), 240 deletions(-)

src/AstGen.zig+94-92
...@@ -46,7 +46,7 @@ fn_block: ?*GenZir = null,...@@ -46,7 +46,7 @@ fn_block: ?*GenZir = null,
46fn_var_args: bool = false,46fn_var_args: bool = false,
47/// Maps string table indexes to the first `@import` ZIR instruction47/// Maps string table indexes to the first `@import` ZIR instruction
48/// that uses this string as the operand.48/// that uses this string as the operand.
49imports: std.AutoArrayHashMapUnmanaged(u32, Ast.TokenIndex) = .{},49imports: std.AutoArrayHashMapUnmanaged(Zir.NullTerminatedString, Ast.TokenIndex) = .{},
50/// Used for temporary storage when building payloads.50/// Used for temporary storage when building payloads.
51scratch: std.ArrayListUnmanaged(u32) = .{},51scratch: std.ArrayListUnmanaged(u32) = .{},
52/// Whenever a `ref` instruction is needed, it is created and saved in this52/// Whenever a `ref` instruction is needed, it is created and saved in this
...@@ -86,6 +86,7 @@ fn setExtra(astgen: *AstGen, index: usize, extra: anytype) void {...@@ -86,6 +86,7 @@ fn setExtra(astgen: *AstGen, index: usize, extra: anytype) void {
8686
87 Zir.Inst.Ref,87 Zir.Inst.Ref,
88 Zir.Inst.Index,88 Zir.Inst.Index,
89 Zir.NullTerminatedString,
89 => @intFromEnum(@field(extra, field.name)),90 => @intFromEnum(@field(extra, field.name)),
9091
91 i32,92 i32,
...@@ -1301,12 +1302,12 @@ fn fnProtoExpr(...@@ -1301,12 +1302,12 @@ fn fnProtoExpr(
1301 }1302 }
1302 } else false;1303 } else false;
13031304
1304 const param_name: u32 = if (param.name_token) |name_token| blk: {1305 const param_name = if (param.name_token) |name_token| blk: {
1305 if (mem.eql(u8, "_", tree.tokenSlice(name_token)))1306 if (mem.eql(u8, "_", tree.tokenSlice(name_token)))
1306 break :blk 0;1307 break :blk .empty;
13071308
1308 break :blk try astgen.identAsString(name_token);1309 break :blk try astgen.identAsString(name_token);
1309 } else 0;1310 } else .empty;
13101311
1311 if (is_anytype) {1312 if (is_anytype) {
1312 const name_token = param.name_token orelse param.anytype_ellipsis3.?;1313 const name_token = param.name_token orelse param.anytype_ellipsis3.?;
...@@ -1379,7 +1380,7 @@ fn fnProtoExpr(...@@ -1379,7 +1380,7 @@ fn fnProtoExpr(
13791380
1380 .param_block = block_inst,1381 .param_block = block_inst,
1381 .body_gz = null,1382 .body_gz = null,
1382 .lib_name = 0,1383 .lib_name = .empty,
1383 .is_var_args = is_var_args,1384 .is_var_args = is_var_args,
1384 .is_inferred_error = false,1385 .is_inferred_error = false,
1385 .is_test = false,1386 .is_test = false,
...@@ -1725,7 +1726,7 @@ fn structInitExpr(...@@ -1725,7 +1726,7 @@ fn structInitExpr(
1725 var sfba = std.heap.stackFallback(256, astgen.arena);1726 var sfba = std.heap.stackFallback(256, astgen.arena);
1726 const sfba_allocator = sfba.get();1727 const sfba_allocator = sfba.get();
17271728
1728 var duplicate_names = std.AutoArrayHashMap(u32, ArrayListUnmanaged(Ast.TokenIndex)).init(sfba_allocator);1729 var duplicate_names = std.AutoArrayHashMap(Zir.NullTerminatedString, ArrayListUnmanaged(Ast.TokenIndex)).init(sfba_allocator);
1729 defer duplicate_names.deinit();1730 defer duplicate_names.deinit();
1730 try duplicate_names.ensureTotalCapacity(@intCast(struct_init.ast.fields.len));1731 try duplicate_names.ensureTotalCapacity(@intCast(struct_init.ast.fields.len));
17311732
...@@ -4068,10 +4069,10 @@ fn fnDecl(...@@ -4068,10 +4069,10 @@ fn fnDecl(
4068 }4069 }
4069 } else false;4070 } else false;
40704071
4071 const param_name: u32 = if (param.name_token) |name_token| blk: {4072 const param_name: Zir.NullTerminatedString = if (param.name_token) |name_token| blk: {
4072 const name_bytes = tree.tokenSlice(name_token);4073 const name_bytes = tree.tokenSlice(name_token);
4073 if (mem.eql(u8, "_", name_bytes))4074 if (mem.eql(u8, "_", name_bytes))
4074 break :blk 0;4075 break :blk .empty;
40754076
4076 const param_name = try astgen.identAsString(name_token);4077 const param_name = try astgen.identAsString(name_token);
4077 if (!is_extern) {4078 if (!is_extern) {
...@@ -4107,7 +4108,7 @@ fn fnDecl(...@@ -4107,7 +4108,7 @@ fn fnDecl(
4107 }4108 }
4108 return astgen.failNode(param.type_expr, "missing parameter name", .{});4109 return astgen.failNode(param.type_expr, "missing parameter name", .{});
4109 }4110 }
4110 } else 0;4111 } else .empty;
41114112
4112 const param_inst = if (is_anytype) param: {4113 const param_inst = if (is_anytype) param: {
4113 const name_token = param.name_token orelse param.anytype_ellipsis3.?;4114 const name_token = param.name_token orelse param.anytype_ellipsis3.?;
...@@ -4133,7 +4134,7 @@ fn fnDecl(...@@ -4133,7 +4134,7 @@ fn fnDecl(
4133 break :param param_inst.toRef();4134 break :param param_inst.toRef();
4134 };4135 };
41354136
4136 if (param_name == 0 or is_extern) continue;4137 if (param_name == .empty or is_extern) continue;
41374138
4138 const sub_scope = try astgen.arena.create(Scope.LocalVal);4139 const sub_scope = try astgen.arena.create(Scope.LocalVal);
4139 sub_scope.* = .{4140 sub_scope.* = .{
...@@ -4149,16 +4150,16 @@ fn fnDecl(...@@ -4149,16 +4150,16 @@ fn fnDecl(
4149 break :is_var_args false;4150 break :is_var_args false;
4150 };4151 };
41514152
4152 const lib_name: u32 = if (fn_proto.lib_name) |lib_name_token| blk: {4153 const lib_name = if (fn_proto.lib_name) |lib_name_token| blk: {
4153 const lib_name_str = try astgen.strLitAsString(lib_name_token);4154 const lib_name_str = try astgen.strLitAsString(lib_name_token);
4154 const lib_name_slice = astgen.string_bytes.items[lib_name_str.index..][0..lib_name_str.len];4155 const lib_name_slice = astgen.string_bytes.items[@intFromEnum(lib_name_str.index)..][0..lib_name_str.len];
4155 if (mem.indexOfScalar(u8, lib_name_slice, 0) != null) {4156 if (mem.indexOfScalar(u8, lib_name_slice, 0) != null) {
4156 return astgen.failTok(lib_name_token, "library name cannot contain null bytes", .{});4157 return astgen.failTok(lib_name_token, "library name cannot contain null bytes", .{});
4157 } else if (lib_name_str.len == 0) {4158 } else if (lib_name_str.len == 0) {
4158 return astgen.failTok(lib_name_token, "library name cannot be empty", .{});4159 return astgen.failTok(lib_name_token, "library name cannot be empty", .{});
4159 }4160 }
4160 break :blk lib_name_str.index;4161 break :blk lib_name_str.index;
4161 } else 0;4162 } else .empty;
41624163
4163 const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1;4164 const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1;
4164 const is_inferred_error = token_tags[maybe_bang] == .bang;4165 const is_inferred_error = token_tags[maybe_bang] == .bang;
...@@ -4343,9 +4344,9 @@ fn fnDecl(...@@ -4343,9 +4344,9 @@ fn fnDecl(
4343 const line_delta = decl_gz.decl_line - gz.decl_line;4344 const line_delta = decl_gz.decl_line - gz.decl_line;
4344 wip_members.appendToDecl(line_delta);4345 wip_members.appendToDecl(line_delta);
4345 }4346 }
4346 wip_members.appendToDecl(fn_name_str_index);4347 wip_members.appendToDecl(@intFromEnum(fn_name_str_index));
4347 wip_members.appendToDecl(@intFromEnum(block_inst));4348 wip_members.appendToDecl(@intFromEnum(block_inst));
4348 wip_members.appendToDecl(doc_comment_index);4349 wip_members.appendToDecl(@intFromEnum(doc_comment_index));
4349}4350}
43504351
4351fn globalVarDecl(4352fn globalVarDecl(
...@@ -4408,16 +4409,16 @@ fn globalVarDecl(...@@ -4408,16 +4409,16 @@ fn globalVarDecl(
4408 break :blk true;4409 break :blk true;
4409 } else false;4410 } else false;
44104411
4411 const lib_name: u32 = if (var_decl.lib_name) |lib_name_token| blk: {4412 const lib_name = if (var_decl.lib_name) |lib_name_token| blk: {
4412 const lib_name_str = try astgen.strLitAsString(lib_name_token);4413 const lib_name_str = try astgen.strLitAsString(lib_name_token);
4413 const lib_name_slice = astgen.string_bytes.items[lib_name_str.index..][0..lib_name_str.len];4414 const lib_name_slice = astgen.string_bytes.items[@intFromEnum(lib_name_str.index)..][0..lib_name_str.len];
4414 if (mem.indexOfScalar(u8, lib_name_slice, 0) != null) {4415 if (mem.indexOfScalar(u8, lib_name_slice, 0) != null) {
4415 return astgen.failTok(lib_name_token, "library name cannot contain null bytes", .{});4416 return astgen.failTok(lib_name_token, "library name cannot contain null bytes", .{});
4416 } else if (lib_name_str.len == 0) {4417 } else if (lib_name_str.len == 0) {
4417 return astgen.failTok(lib_name_token, "library name cannot be empty", .{});4418 return astgen.failTok(lib_name_token, "library name cannot be empty", .{});
4418 }4419 }
4419 break :blk lib_name_str.index;4420 break :blk lib_name_str.index;
4420 } else 0;4421 } else .empty;
44214422
4422 const doc_comment_index = try astgen.docCommentAsString(var_decl.firstToken());4423 const doc_comment_index = try astgen.docCommentAsString(var_decl.firstToken());
44234424
...@@ -4452,7 +4453,7 @@ fn globalVarDecl(...@@ -4452,7 +4453,7 @@ fn globalVarDecl(
4452 if (is_mutable) {4453 if (is_mutable) {
4453 const var_inst = try block_scope.addVar(.{4454 const var_inst = try block_scope.addVar(.{
4454 .var_type = type_inst,4455 .var_type = type_inst,
4455 .lib_name = 0,4456 .lib_name = .empty,
4456 .align_inst = .none, // passed via the decls data4457 .align_inst = .none, // passed via the decls data
4457 .init = init_inst,4458 .init = init_inst,
4458 .is_extern = false,4459 .is_extern = false,
...@@ -4495,9 +4496,9 @@ fn globalVarDecl(...@@ -4495,9 +4496,9 @@ fn globalVarDecl(
4495 const line_delta = block_scope.decl_line - gz.decl_line;4496 const line_delta = block_scope.decl_line - gz.decl_line;
4496 wip_members.appendToDecl(line_delta);4497 wip_members.appendToDecl(line_delta);
4497 }4498 }
4498 wip_members.appendToDecl(name_str_index);4499 wip_members.appendToDecl(@intFromEnum(name_str_index));
4499 wip_members.appendToDecl(@intFromEnum(block_inst));4500 wip_members.appendToDecl(@intFromEnum(block_inst));
4500 wip_members.appendToDecl(doc_comment_index); // doc_comment wip4501 wip_members.appendToDecl(@intFromEnum(doc_comment_index)); // doc_comment wip
4501 if (align_inst != .none) {4502 if (align_inst != .none) {
4502 wip_members.appendToDecl(@intFromEnum(align_inst));4503 wip_members.appendToDecl(@intFromEnum(align_inst));
4503 }4504 }
...@@ -4640,7 +4641,7 @@ fn testDecl(...@@ -4640,7 +4641,7 @@ fn testDecl(
4640 const test_name_token = test_token + 1;4641 const test_name_token = test_token + 1;
4641 const test_name_token_tag = token_tags[test_name_token];4642 const test_name_token_tag = token_tags[test_name_token];
4642 const is_decltest = test_name_token_tag == .identifier;4643 const is_decltest = test_name_token_tag == .identifier;
4643 const test_name: u32 = blk: {4644 const test_name: Zir.NullTerminatedString = blk: {
4644 if (test_name_token_tag == .string_literal) {4645 if (test_name_token_tag == .string_literal) {
4645 break :blk try astgen.testNameString(test_name_token);4646 break :blk try astgen.testNameString(test_name_token);
4646 } else if (test_name_token_tag == .identifier) {4647 } else if (test_name_token_tag == .identifier) {
...@@ -4716,7 +4717,7 @@ fn testDecl(...@@ -4716,7 +4717,7 @@ fn testDecl(
4716 break :blk name_str_index;4717 break :blk name_str_index;
4717 }4718 }
4718 // String table index 1 has a special meaning here of test decl with no name.4719 // String table index 1 has a special meaning here of test decl with no name.
4719 break :blk 1;4720 break :blk .unnamed_test_decl;
4720 };4721 };
47214722
4722 var fn_block: GenZir = .{4723 var fn_block: GenZir = .{
...@@ -4766,7 +4767,7 @@ fn testDecl(...@@ -4766,7 +4767,7 @@ fn testDecl(
4766 .lbrace_column = lbrace_column,4767 .lbrace_column = lbrace_column,
4767 .param_block = block_inst,4768 .param_block = block_inst,
4768 .body_gz = &fn_block,4769 .body_gz = &fn_block,
4769 .lib_name = 0,4770 .lib_name = .empty,
4770 .is_var_args = false,4771 .is_var_args = false,
4771 .is_inferred_error = false,4772 .is_inferred_error = false,
4772 .is_test = true,4773 .is_test = true,
...@@ -4789,10 +4790,10 @@ fn testDecl(...@@ -4789,10 +4790,10 @@ fn testDecl(
4789 if (is_decltest)4790 if (is_decltest)
4790 wip_members.appendToDecl(2) // 2 here means that it is a decltest, look at doc comment for name4791 wip_members.appendToDecl(2) // 2 here means that it is a decltest, look at doc comment for name
4791 else4792 else
4792 wip_members.appendToDecl(test_name);4793 wip_members.appendToDecl(@intFromEnum(test_name));
4793 wip_members.appendToDecl(@intFromEnum(block_inst));4794 wip_members.appendToDecl(@intFromEnum(block_inst));
4794 if (is_decltest)4795 if (is_decltest)
4795 wip_members.appendToDecl(test_name) // the doc comment on a decltest represents it's name4796 wip_members.appendToDecl(@intFromEnum(test_name)) // the doc comment on a decltest represents it's name
4796 else4797 else
4797 wip_members.appendToDecl(0); // no doc comments on test decls4798 wip_members.appendToDecl(0); // no doc comments on test decls
4798}4799}
...@@ -4945,7 +4946,7 @@ fn structDeclInner(...@@ -4945,7 +4946,7 @@ fn structDeclInner(
4945 var sfba = std.heap.stackFallback(256, astgen.arena);4946 var sfba = std.heap.stackFallback(256, astgen.arena);
4946 const sfba_allocator = sfba.get();4947 const sfba_allocator = sfba.get();
49474948
4948 var duplicate_names = std.AutoArrayHashMap(u32, std.ArrayListUnmanaged(Ast.TokenIndex)).init(sfba_allocator);4949 var duplicate_names = std.AutoArrayHashMap(Zir.NullTerminatedString, std.ArrayListUnmanaged(Ast.TokenIndex)).init(sfba_allocator);
4949 try duplicate_names.ensureTotalCapacity(field_count);4950 try duplicate_names.ensureTotalCapacity(field_count);
49504951
4951 // When there aren't errors, use this to avoid a second iteration.4952 // When there aren't errors, use this to avoid a second iteration.
...@@ -4968,7 +4969,7 @@ fn structDeclInner(...@@ -4968,7 +4969,7 @@ fn structDeclInner(
4968 member.convertToNonTupleLike(astgen.tree.nodes);4969 member.convertToNonTupleLike(astgen.tree.nodes);
4969 assert(!member.ast.tuple_like);4970 assert(!member.ast.tuple_like);
49704971
4971 wip_members.appendToField(field_name);4972 wip_members.appendToField(@intFromEnum(field_name));
49724973
4973 const gop = try duplicate_names.getOrPut(field_name);4974 const gop = try duplicate_names.getOrPut(field_name);
49744975
...@@ -4984,7 +4985,7 @@ fn structDeclInner(...@@ -4984,7 +4985,7 @@ fn structDeclInner(
4984 }4985 }
49854986
4986 const doc_comment_index = try astgen.docCommentAsString(member.firstToken());4987 const doc_comment_index = try astgen.docCommentAsString(member.firstToken());
4987 wip_members.appendToField(doc_comment_index);4988 wip_members.appendToField(@intFromEnum(doc_comment_index));
49884989
4989 if (member.ast.type_expr == 0) {4990 if (member.ast.type_expr == 0) {
4990 return astgen.failTok(member.ast.main_token, "struct field missing type", .{});4991 return astgen.failTok(member.ast.main_token, "struct field missing type", .{});
...@@ -5196,10 +5197,10 @@ fn unionDeclInner(...@@ -5196,10 +5197,10 @@ fn unionDeclInner(
5196 }5197 }
51975198
5198 const field_name = try astgen.identAsString(member.ast.main_token);5199 const field_name = try astgen.identAsString(member.ast.main_token);
5199 wip_members.appendToField(field_name);5200 wip_members.appendToField(@intFromEnum(field_name));
52005201
5201 const doc_comment_index = try astgen.docCommentAsString(member.firstToken());5202 const doc_comment_index = try astgen.docCommentAsString(member.firstToken());
5202 wip_members.appendToField(doc_comment_index);5203 wip_members.appendToField(@intFromEnum(doc_comment_index));
52035204
5204 const have_type = member.ast.type_expr != 0;5205 const have_type = member.ast.type_expr != 0;
5205 const have_align = member.ast.align_expr != 0;5206 const have_align = member.ast.align_expr != 0;
...@@ -5475,10 +5476,10 @@ fn containerDecl(...@@ -5475,10 +5476,10 @@ fn containerDecl(
5475 assert(member.ast.align_expr == 0);5476 assert(member.ast.align_expr == 0);
54765477
5477 const field_name = try astgen.identAsString(member.ast.main_token);5478 const field_name = try astgen.identAsString(member.ast.main_token);
5478 wip_members.appendToField(field_name);5479 wip_members.appendToField(@intFromEnum(field_name));
54795480
5480 const doc_comment_index = try astgen.docCommentAsString(member.firstToken());5481 const doc_comment_index = try astgen.docCommentAsString(member.firstToken());
5481 wip_members.appendToField(doc_comment_index);5482 wip_members.appendToField(@intFromEnum(doc_comment_index));
54825483
5483 const have_value = member.ast.value_expr != 0;5484 const have_value = member.ast.value_expr != 0;
5484 wip_members.nextField(bits_per_field, .{have_value});5485 wip_members.nextField(bits_per_field, .{have_value});
...@@ -5665,7 +5666,7 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi...@@ -5665,7 +5666,7 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi
5665 const payload_index = try reserveExtra(astgen, @typeInfo(Zir.Inst.ErrorSetDecl).Struct.fields.len);5666 const payload_index = try reserveExtra(astgen, @typeInfo(Zir.Inst.ErrorSetDecl).Struct.fields.len);
5666 var fields_len: usize = 0;5667 var fields_len: usize = 0;
5667 {5668 {
5668 var idents: std.AutoHashMapUnmanaged(u32, Ast.TokenIndex) = .{};5669 var idents: std.AutoHashMapUnmanaged(Zir.NullTerminatedString, Ast.TokenIndex) = .{};
5669 defer idents.deinit(gpa);5670 defer idents.deinit(gpa);
56705671
5671 const error_token = main_tokens[node];5672 const error_token = main_tokens[node];
...@@ -5695,9 +5696,9 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi...@@ -5695,9 +5696,9 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi
5695 gop.value_ptr.* = tok_i;5696 gop.value_ptr.* = tok_i;
56965697
5697 try astgen.extra.ensureUnusedCapacity(gpa, 2);5698 try astgen.extra.ensureUnusedCapacity(gpa, 2);
5698 astgen.extra.appendAssumeCapacity(str_index);5699 astgen.extra.appendAssumeCapacity(@intFromEnum(str_index));
5699 const doc_comment_index = try astgen.docCommentAsString(tok_i);5700 const doc_comment_index = try astgen.docCommentAsString(tok_i);
5700 astgen.extra.appendAssumeCapacity(doc_comment_index);5701 astgen.extra.appendAssumeCapacity(@intFromEnum(doc_comment_index));
5701 fields_len += 1;5702 fields_len += 1;
5702 },5703 },
5703 .r_brace => break,5704 .r_brace => break,
...@@ -6372,7 +6373,7 @@ fn whileExpr(...@@ -6372,7 +6373,7 @@ fn whileExpr(
6372 then_scope.instructions_top = GenZir.unstacked_top;6373 then_scope.instructions_top = GenZir.unstacked_top;
6373 defer then_scope.unstack();6374 defer then_scope.unstack();
63746375
6375 var dbg_var_name: ?u32 = null;6376 var dbg_var_name: Zir.NullTerminatedString = .empty;
6376 var dbg_var_inst: Zir.Inst.Ref = undefined;6377 var dbg_var_inst: Zir.Inst.Ref = undefined;
6377 var opt_payload_inst: Zir.Inst.OptionalIndex = .none;6378 var opt_payload_inst: Zir.Inst.OptionalIndex = .none;
6378 var payload_val_scope: Scope.LocalVal = undefined;6379 var payload_val_scope: Scope.LocalVal = undefined;
...@@ -6464,7 +6465,7 @@ fn whileExpr(...@@ -6464,7 +6465,7 @@ fn whileExpr(
6464 if (opt_payload_inst.unwrap()) |payload_inst| {6465 if (opt_payload_inst.unwrap()) |payload_inst| {
6465 try then_scope.instructions.append(astgen.gpa, payload_inst);6466 try then_scope.instructions.append(astgen.gpa, payload_inst);
6466 }6467 }
6467 if (dbg_var_name) |name| try then_scope.addDbgVar(.dbg_var_val, name, dbg_var_inst);6468 if (dbg_var_name != .empty) try then_scope.addDbgVar(.dbg_var_val, dbg_var_name, dbg_var_inst);
6468 try then_scope.instructions.append(astgen.gpa, continue_block);6469 try then_scope.instructions.append(astgen.gpa, continue_block);
6469 // This code could be improved to avoid emitting the continue expr when there6470 // This code could be improved to avoid emitting the continue expr when there
6470 // are no jumps to it. This happens when the last statement of a while body is noreturn6471 // are no jumps to it. This happens when the last statement of a while body is noreturn
...@@ -7069,9 +7070,9 @@ fn switchExpr(...@@ -7069,9 +7070,9 @@ fn switchExpr(
7069 const is_multi_case = case.ast.values.len > 1 or7070 const is_multi_case = case.ast.values.len > 1 or
7070 (case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .switch_range);7071 (case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .switch_range);
70717072
7072 var dbg_var_name: ?u32 = null;7073 var dbg_var_name: Zir.NullTerminatedString = .empty;
7073 var dbg_var_inst: Zir.Inst.Ref = undefined;7074 var dbg_var_inst: Zir.Inst.Ref = undefined;
7074 var dbg_var_tag_name: ?u32 = null;7075 var dbg_var_tag_name: Zir.NullTerminatedString = .empty;
7075 var dbg_var_tag_inst: Zir.Inst.Ref = undefined;7076 var dbg_var_tag_inst: Zir.Inst.Ref = undefined;
7076 var has_tag_capture = false;7077 var has_tag_capture = false;
7077 var capture_val_scope: Scope.LocalVal = undefined;7078 var capture_val_scope: Scope.LocalVal = undefined;
...@@ -7193,11 +7194,11 @@ fn switchExpr(...@@ -7193,11 +7194,11 @@ fn switchExpr(
7193 defer case_scope.unstack();7194 defer case_scope.unstack();
71947195
7195 try case_scope.addDbgBlockBegin();7196 try case_scope.addDbgBlockBegin();
7196 if (dbg_var_name) |some| {7197 if (dbg_var_name != .empty) {
7197 try case_scope.addDbgVar(.dbg_var_val, some, dbg_var_inst);7198 try case_scope.addDbgVar(.dbg_var_val, dbg_var_name, dbg_var_inst);
7198 }7199 }
7199 if (dbg_var_tag_name) |some| {7200 if (dbg_var_tag_name != .empty) {
7200 try case_scope.addDbgVar(.dbg_var_val, some, dbg_var_tag_inst);7201 try case_scope.addDbgVar(.dbg_var_val, dbg_var_tag_name, dbg_var_tag_inst);
7201 }7202 }
7202 const target_expr_node = case.ast.target_expr;7203 const target_expr_node = case.ast.target_expr;
7203 const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node);7204 const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node);
...@@ -7858,7 +7859,7 @@ fn asmExpr(...@@ -7858,7 +7859,7 @@ fn asmExpr(
7858 const node_tags = tree.nodes.items(.tag);7859 const node_tags = tree.nodes.items(.tag);
7859 const token_tags = tree.tokens.items(.tag);7860 const token_tags = tree.tokens.items(.tag);
78607861
7861 const TagAndTmpl = struct { tag: Zir.Inst.Extended, tmpl: u32 };7862 const TagAndTmpl = struct { tag: Zir.Inst.Extended, tmpl: Zir.NullTerminatedString };
7862 const tag_and_tmpl: TagAndTmpl = switch (node_tags[full.ast.template]) {7863 const tag_and_tmpl: TagAndTmpl = switch (node_tags[full.ast.template]) {
7863 .string_literal => .{7864 .string_literal => .{
7864 .tag = .@"asm",7865 .tag = .@"asm",
...@@ -7870,7 +7871,7 @@ fn asmExpr(...@@ -7870,7 +7871,7 @@ fn asmExpr(
7870 },7871 },
7871 else => .{7872 else => .{
7872 .tag = .asm_expr,7873 .tag = .asm_expr,
7873 .tmpl = @intFromEnum(try comptimeExpr(gz, scope, .{ .rl = .none }, full.ast.template)),7874 .tmpl = @enumFromInt(@intFromEnum(try comptimeExpr(gz, scope, .{ .rl = .none }, full.ast.template))),
7874 },7875 },
7875 };7876 };
78767877
...@@ -7956,7 +7957,7 @@ fn asmExpr(...@@ -7956,7 +7957,7 @@ fn asmExpr(
7956 if (clobber_i >= clobbers_buffer.len) {7957 if (clobber_i >= clobbers_buffer.len) {
7957 return astgen.failTok(tok_i, "too many asm clobbers", .{});7958 return astgen.failTok(tok_i, "too many asm clobbers", .{});
7958 }7959 }
7959 clobbers_buffer[clobber_i] = (try astgen.strLitAsString(tok_i)).index;7960 clobbers_buffer[clobber_i] = @intFromEnum((try astgen.strLitAsString(tok_i)).index);
7960 clobber_i += 1;7961 clobber_i += 1;
7961 tok_i += 1;7962 tok_i += 1;
7962 switch (token_tags[tok_i]) {7963 switch (token_tags[tok_i]) {
...@@ -8290,7 +8291,7 @@ fn builtinCall(...@@ -8290,7 +8291,7 @@ fn builtinCall(
8290 }8291 }
8291 const str_lit_token = main_tokens[operand_node];8292 const str_lit_token = main_tokens[operand_node];
8292 const str = try astgen.strLitAsString(str_lit_token);8293 const str = try astgen.strLitAsString(str_lit_token);
8293 const str_slice = astgen.string_bytes.items[str.index..][0..str.len];8294 const str_slice = astgen.string_bytes.items[@intFromEnum(str.index)..][0..str.len];
8294 if (mem.indexOfScalar(u8, str_slice, 0) != null) {8295 if (mem.indexOfScalar(u8, str_slice, 0) != null) {
8295 return astgen.failTok(str_lit_token, "import path cannot contain null bytes", .{});8296 return astgen.failTok(str_lit_token, "import path cannot contain null bytes", .{});
8296 } else if (str.len == 0) {8297 } else if (str.len == 0) {
...@@ -8346,7 +8347,7 @@ fn builtinCall(...@@ -8346,7 +8347,7 @@ fn builtinCall(
8346 // This function causes a Decl to be exported. The first parameter is not an expression,8347 // This function causes a Decl to be exported. The first parameter is not an expression,
8347 // but an identifier of the Decl to be exported.8348 // but an identifier of the Decl to be exported.
8348 var namespace: Zir.Inst.Ref = .none;8349 var namespace: Zir.Inst.Ref = .none;
8349 var decl_name: u32 = 0;8350 var decl_name: Zir.NullTerminatedString = .empty;
8350 switch (node_tags[params[0]]) {8351 switch (node_tags[params[0]]) {
8351 .identifier => {8352 .identifier => {
8352 const ident_token = main_tokens[params[0]];8353 const ident_token = main_tokens[params[0]];
...@@ -9263,7 +9264,7 @@ const Callee = union(enum) {...@@ -9263,7 +9264,7 @@ const Callee = union(enum) {
9263 /// promote the lvalue to an address if the first parameter requires it.9264 /// promote the lvalue to an address if the first parameter requires it.
9264 obj_ptr: Zir.Inst.Ref,9265 obj_ptr: Zir.Inst.Ref,
9265 /// Offset into `string_bytes`.9266 /// Offset into `string_bytes`.
9266 field_name_start: u32,9267 field_name_start: Zir.NullTerminatedString,
9267 },9268 },
9268 direct: Zir.Inst.Ref,9269 direct: Zir.Inst.Ref,
9269};9270};
...@@ -10529,7 +10530,7 @@ fn appendErrorNodeNotes(...@@ -10529,7 +10530,7 @@ fn appendErrorNodeNotes(
10529) Allocator.Error!void {10530) Allocator.Error!void {
10530 @setCold(true);10531 @setCold(true);
10531 const string_bytes = &astgen.string_bytes;10532 const string_bytes = &astgen.string_bytes;
10532 const msg: u32 = @intCast(string_bytes.items.len);10533 const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len);
10533 try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);10534 try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);
10534 const notes_index: u32 = if (notes.len != 0) blk: {10535 const notes_index: u32 = if (notes.len != 0) blk: {
10535 const notes_start = astgen.extra.items.len;10536 const notes_start = astgen.extra.items.len;
...@@ -10621,7 +10622,7 @@ fn appendErrorTokNotesOff(...@@ -10621,7 +10622,7 @@ fn appendErrorTokNotesOff(
10621 @setCold(true);10622 @setCold(true);
10622 const gpa = astgen.gpa;10623 const gpa = astgen.gpa;
10623 const string_bytes = &astgen.string_bytes;10624 const string_bytes = &astgen.string_bytes;
10624 const msg: u32 = @intCast(string_bytes.items.len);10625 const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len);
10625 try string_bytes.writer(gpa).print(format ++ "\x00", args);10626 try string_bytes.writer(gpa).print(format ++ "\x00", args);
10626 const notes_index: u32 = if (notes.len != 0) blk: {10627 const notes_index: u32 = if (notes.len != 0) blk: {
10627 const notes_start = astgen.extra.items.len;10628 const notes_start = astgen.extra.items.len;
...@@ -10657,7 +10658,7 @@ fn errNoteTokOff(...@@ -10657,7 +10658,7 @@ fn errNoteTokOff(
10657) Allocator.Error!u32 {10658) Allocator.Error!u32 {
10658 @setCold(true);10659 @setCold(true);
10659 const string_bytes = &astgen.string_bytes;10660 const string_bytes = &astgen.string_bytes;
10660 const msg: u32 = @intCast(string_bytes.items.len);10661 const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len);
10661 try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);10662 try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);
10662 return astgen.addExtra(Zir.Inst.CompileErrors.Item{10663 return astgen.addExtra(Zir.Inst.CompileErrors.Item{
10663 .msg = msg,10664 .msg = msg,
...@@ -10676,7 +10677,7 @@ fn errNoteNode(...@@ -10676,7 +10677,7 @@ fn errNoteNode(
10676) Allocator.Error!u32 {10677) Allocator.Error!u32 {
10677 @setCold(true);10678 @setCold(true);
10678 const string_bytes = &astgen.string_bytes;10679 const string_bytes = &astgen.string_bytes;
10679 const msg: u32 = @intCast(string_bytes.items.len);10680 const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len);
10680 try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);10681 try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);
10681 return astgen.addExtra(Zir.Inst.CompileErrors.Item{10682 return astgen.addExtra(Zir.Inst.CompileErrors.Item{
10682 .msg = msg,10683 .msg = msg,
...@@ -10687,7 +10688,7 @@ fn errNoteNode(...@@ -10687,7 +10688,7 @@ fn errNoteNode(
10687 });10688 });
10688}10689}
1068910690
10690fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !u32 {10691fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !Zir.NullTerminatedString {
10691 const gpa = astgen.gpa;10692 const gpa = astgen.gpa;
10692 const string_bytes = &astgen.string_bytes;10693 const string_bytes = &astgen.string_bytes;
10693 const str_index: u32 = @intCast(string_bytes.items.len);10694 const str_index: u32 = @intCast(string_bytes.items.len);
...@@ -10700,19 +10701,19 @@ fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !u32 {...@@ -10700,19 +10701,19 @@ fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !u32 {
10700 });10701 });
10701 if (gop.found_existing) {10702 if (gop.found_existing) {
10702 string_bytes.shrinkRetainingCapacity(str_index);10703 string_bytes.shrinkRetainingCapacity(str_index);
10703 return gop.key_ptr.*;10704 return @enumFromInt(gop.key_ptr.*);
10704 } else {10705 } else {
10705 gop.key_ptr.* = str_index;10706 gop.key_ptr.* = str_index;
10706 try string_bytes.append(gpa, 0);10707 try string_bytes.append(gpa, 0);
10707 return str_index;10708 return @enumFromInt(str_index);
10708 }10709 }
10709}10710}
1071010711
10711/// Adds a doc comment block to `string_bytes` by walking backwards from `end_token`.10712/// Adds a doc comment block to `string_bytes` by walking backwards from `end_token`.
10712/// `end_token` must point at the first token after the last doc coment line.10713/// `end_token` must point at the first token after the last doc coment line.
10713/// Returns 0 if no doc comment is present.10714/// Returns 0 if no doc comment is present.
10714fn docCommentAsString(astgen: *AstGen, end_token: Ast.TokenIndex) !u32 {10715fn docCommentAsString(astgen: *AstGen, end_token: Ast.TokenIndex) !Zir.NullTerminatedString {
10715 if (end_token == 0) return 0;10716 if (end_token == 0) return .empty;
1071610717
10717 const token_tags = astgen.tree.tokens.items(.tag);10718 const token_tags = astgen.tree.tokens.items(.tag);
1071810719
...@@ -10723,6 +10724,7 @@ fn docCommentAsString(astgen: *AstGen, end_token: Ast.TokenIndex) !u32 {...@@ -10723,6 +10724,7 @@ fn docCommentAsString(astgen: *AstGen, end_token: Ast.TokenIndex) !u32 {
10723 } else {10724 } else {
10724 tok += 1;10725 tok += 1;
10725 }10726 }
10727
10726 return docCommentAsStringFromFirst(astgen, end_token, tok);10728 return docCommentAsStringFromFirst(astgen, end_token, tok);
10727}10729}
1072810730
...@@ -10731,8 +10733,8 @@ fn docCommentAsStringFromFirst(...@@ -10731,8 +10733,8 @@ fn docCommentAsStringFromFirst(
10731 astgen: *AstGen,10733 astgen: *AstGen,
10732 end_token: Ast.TokenIndex,10734 end_token: Ast.TokenIndex,
10733 start_token: Ast.TokenIndex,10735 start_token: Ast.TokenIndex,
10734) !u32 {10736) !Zir.NullTerminatedString {
10735 if (start_token == end_token) return 0;10737 if (start_token == end_token) return .empty;
1073610738
10737 const gpa = astgen.gpa;10739 const gpa = astgen.gpa;
10738 const string_bytes = &astgen.string_bytes;10740 const string_bytes = &astgen.string_bytes;
...@@ -10766,15 +10768,15 @@ fn docCommentAsStringFromFirst(...@@ -10766,15 +10768,15 @@ fn docCommentAsStringFromFirst(
1076610768
10767 if (gop.found_existing) {10769 if (gop.found_existing) {
10768 string_bytes.shrinkRetainingCapacity(str_index);10770 string_bytes.shrinkRetainingCapacity(str_index);
10769 return gop.key_ptr.*;10771 return @enumFromInt(gop.key_ptr.*);
10770 } else {10772 } else {
10771 gop.key_ptr.* = str_index;10773 gop.key_ptr.* = str_index;
10772 try string_bytes.append(gpa, 0);10774 try string_bytes.append(gpa, 0);
10773 return str_index;10775 return @enumFromInt(str_index);
10774 }10776 }
10775}10777}
1077610778
10777const IndexSlice = struct { index: u32, len: u32 };10779const IndexSlice = struct { index: Zir.NullTerminatedString, len: u32 };
1077810780
10779fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice {10781fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice {
10780 const gpa = astgen.gpa;10782 const gpa = astgen.gpa;
...@@ -10791,7 +10793,7 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice {...@@ -10791,7 +10793,7 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice {
10791 if (gop.found_existing) {10793 if (gop.found_existing) {
10792 string_bytes.shrinkRetainingCapacity(str_index);10794 string_bytes.shrinkRetainingCapacity(str_index);
10793 return IndexSlice{10795 return IndexSlice{
10794 .index = gop.key_ptr.*,10796 .index = @enumFromInt(gop.key_ptr.*),
10795 .len = @intCast(key.len),10797 .len = @intCast(key.len),
10796 };10798 };
10797 } else {10799 } else {
...@@ -10801,7 +10803,7 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice {...@@ -10801,7 +10803,7 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice {
10801 // be null terminated for that to work.10803 // be null terminated for that to work.
10802 try string_bytes.append(gpa, 0);10804 try string_bytes.append(gpa, 0);
10803 return IndexSlice{10805 return IndexSlice{
10804 .index = str_index,10806 .index = @enumFromInt(str_index),
10805 .len = @intCast(key.len),10807 .len = @intCast(key.len),
10806 };10808 };
10807 }10809 }
...@@ -10839,12 +10841,12 @@ fn strLitNodeAsString(astgen: *AstGen, node: Ast.Node.Index) !IndexSlice {...@@ -10839,12 +10841,12 @@ fn strLitNodeAsString(astgen: *AstGen, node: Ast.Node.Index) !IndexSlice {
10839 const len = string_bytes.items.len - str_index;10841 const len = string_bytes.items.len - str_index;
10840 try string_bytes.append(gpa, 0);10842 try string_bytes.append(gpa, 0);
10841 return IndexSlice{10843 return IndexSlice{
10842 .index = @intCast(str_index),10844 .index = @enumFromInt(str_index),
10843 .len = @intCast(len),10845 .len = @intCast(len),
10844 };10846 };
10845}10847}
1084610848
10847fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !u32 {10849fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !Zir.NullTerminatedString {
10848 const gpa = astgen.gpa;10850 const gpa = astgen.gpa;
10849 const string_bytes = &astgen.string_bytes;10851 const string_bytes = &astgen.string_bytes;
10850 const str_index: u32 = @intCast(string_bytes.items.len);10852 const str_index: u32 = @intCast(string_bytes.items.len);
...@@ -10858,7 +10860,7 @@ fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !u32 {...@@ -10858,7 +10860,7 @@ fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !u32 {
10858 return astgen.failTok(str_lit_token, "empty test name must be omitted", .{});10860 return astgen.failTok(str_lit_token, "empty test name must be omitted", .{});
10859 }10861 }
10860 try string_bytes.append(gpa, 0);10862 try string_bytes.append(gpa, 0);
10861 return str_index;10863 return @enumFromInt(str_index);
10862}10864}
1086310865
10864const Scope = struct {10866const Scope = struct {
...@@ -10933,7 +10935,7 @@ const Scope = struct {...@@ -10933,7 +10935,7 @@ const Scope = struct {
10933 /// 0 means never discarded.10935 /// 0 means never discarded.
10934 discarded: Ast.TokenIndex = 0,10936 discarded: Ast.TokenIndex = 0,
10935 /// String table index.10937 /// String table index.
10936 name: u32,10938 name: Zir.NullTerminatedString,
10937 id_cat: IdCat,10939 id_cat: IdCat,
10938 };10940 };
1093910941
...@@ -10959,7 +10961,7 @@ const Scope = struct {...@@ -10959,7 +10961,7 @@ const Scope = struct {
10959 /// If not, we know it can be `const`, so will emit a compile error if it is `var`.10961 /// If not, we know it can be `const`, so will emit a compile error if it is `var`.
10960 used_as_lvalue: bool = false,10962 used_as_lvalue: bool = false,
10961 /// String table index.10963 /// String table index.
10962 name: u32,10964 name: Zir.NullTerminatedString,
10963 id_cat: IdCat,10965 id_cat: IdCat,
10964 /// true means we find out during Sema whether the value is comptime.10966 /// true means we find out during Sema whether the value is comptime.
10965 /// false means it is already known at AstGen the value is runtime-known.10967 /// false means it is already known at AstGen the value is runtime-known.
...@@ -10985,7 +10987,7 @@ const Scope = struct {...@@ -10985,7 +10987,7 @@ const Scope = struct {
10985 parent: *Scope,10987 parent: *Scope,
10986 /// Maps string table index to the source location of declaration,10988 /// Maps string table index to the source location of declaration,
10987 /// for the purposes of reporting name shadowing compile errors.10989 /// for the purposes of reporting name shadowing compile errors.
10988 decls: std.AutoHashMapUnmanaged(u32, Ast.Node.Index) = .{},10990 decls: std.AutoHashMapUnmanaged(Zir.NullTerminatedString, Ast.Node.Index) = .{},
10989 node: Ast.Node.Index,10991 node: Ast.Node.Index,
10990 inst: Zir.Inst.Index,10992 inst: Zir.Inst.Index,
1099110993
...@@ -11250,7 +11252,7 @@ const GenZir = struct {...@@ -11250,7 +11252,7 @@ const GenZir = struct {
11250 cc_ref: Zir.Inst.Ref,11252 cc_ref: Zir.Inst.Ref,
11251 ret_ref: Zir.Inst.Ref,11253 ret_ref: Zir.Inst.Ref,
1125211254
11253 lib_name: u32,11255 lib_name: Zir.NullTerminatedString,
11254 noalias_bits: u32,11256 noalias_bits: u32,
11255 is_var_args: bool,11257 is_var_args: bool,
11256 is_inferred_error: bool,11258 is_inferred_error: bool,
...@@ -11298,7 +11300,7 @@ const GenZir = struct {...@@ -11298,7 +11300,7 @@ const GenZir = struct {
11298 }11300 }
11299 const body_len = astgen.countBodyLenAfterFixups(body);11301 const body_len = astgen.countBodyLenAfterFixups(body);
1130011302
11301 if (args.cc_ref != .none or args.lib_name != 0 or args.is_var_args or args.is_test or11303 if (args.cc_ref != .none or args.lib_name != .empty or args.is_var_args or args.is_test or
11302 args.is_extern or args.align_ref != .none or args.section_ref != .none or11304 args.is_extern or args.align_ref != .none or args.section_ref != .none or
11303 args.addrspace_ref != .none or args.noalias_bits != 0 or args.is_noinline)11305 args.addrspace_ref != .none or args.noalias_bits != 0 or args.is_noinline)
11304 {11306 {
...@@ -11322,7 +11324,7 @@ const GenZir = struct {...@@ -11322,7 +11324,7 @@ const GenZir = struct {
11322 fancyFnExprExtraLen(astgen, cc_body, args.cc_ref) +11324 fancyFnExprExtraLen(astgen, cc_body, args.cc_ref) +
11323 fancyFnExprExtraLen(astgen, ret_body, ret_ref) +11325 fancyFnExprExtraLen(astgen, ret_body, ret_ref) +
11324 body_len + src_locs.len +11326 body_len + src_locs.len +
11325 @intFromBool(args.lib_name != 0) +11327 @intFromBool(args.lib_name != .empty) +
11326 @intFromBool(args.noalias_bits != 0),11328 @intFromBool(args.noalias_bits != 0),
11327 );11329 );
11328 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.FuncFancy{11330 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.FuncFancy{
...@@ -11334,7 +11336,7 @@ const GenZir = struct {...@@ -11334,7 +11336,7 @@ const GenZir = struct {
11334 .is_test = args.is_test,11336 .is_test = args.is_test,
11335 .is_extern = args.is_extern,11337 .is_extern = args.is_extern,
11336 .is_noinline = args.is_noinline,11338 .is_noinline = args.is_noinline,
11337 .has_lib_name = args.lib_name != 0,11339 .has_lib_name = args.lib_name != .empty,
11338 .has_any_noalias = args.noalias_bits != 0,11340 .has_any_noalias = args.noalias_bits != 0,
1133911341
11340 .has_align_ref = args.align_ref != .none,11342 .has_align_ref = args.align_ref != .none,
...@@ -11350,8 +11352,8 @@ const GenZir = struct {...@@ -11350,8 +11352,8 @@ const GenZir = struct {
11350 .has_ret_ty_body = ret_body.len != 0,11352 .has_ret_ty_body = ret_body.len != 0,
11351 },11353 },
11352 });11354 });
11353 if (args.lib_name != 0) {11355 if (args.lib_name != .empty) {
11354 astgen.extra.appendAssumeCapacity(args.lib_name);11356 astgen.extra.appendAssumeCapacity(@intFromEnum(args.lib_name));
11355 }11357 }
1135611358
11357 const zir_datas = astgen.instructions.items(.data);11359 const zir_datas = astgen.instructions.items(.data);
...@@ -11493,7 +11495,7 @@ const GenZir = struct {...@@ -11493,7 +11495,7 @@ const GenZir = struct {
1149311495
11494 fn addVar(gz: *GenZir, args: struct {11496 fn addVar(gz: *GenZir, args: struct {
11495 align_inst: Zir.Inst.Ref,11497 align_inst: Zir.Inst.Ref,
11496 lib_name: u32,11498 lib_name: Zir.NullTerminatedString,
11497 var_type: Zir.Inst.Ref,11499 var_type: Zir.Inst.Ref,
11498 init: Zir.Inst.Ref,11500 init: Zir.Inst.Ref,
11499 is_extern: bool,11501 is_extern: bool,
...@@ -11509,15 +11511,15 @@ const GenZir = struct {...@@ -11509,15 +11511,15 @@ const GenZir = struct {
11509 try astgen.extra.ensureUnusedCapacity(11511 try astgen.extra.ensureUnusedCapacity(
11510 gpa,11512 gpa,
11511 @typeInfo(Zir.Inst.ExtendedVar).Struct.fields.len +11513 @typeInfo(Zir.Inst.ExtendedVar).Struct.fields.len +
11512 @intFromBool(args.lib_name != 0) +11514 @intFromBool(args.lib_name != .empty) +
11513 @intFromBool(args.align_inst != .none) +11515 @intFromBool(args.align_inst != .none) +
11514 @intFromBool(args.init != .none),11516 @intFromBool(args.init != .none),
11515 );11517 );
11516 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.ExtendedVar{11518 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.ExtendedVar{
11517 .var_type = args.var_type,11519 .var_type = args.var_type,
11518 });11520 });
11519 if (args.lib_name != 0) {11521 if (args.lib_name != .empty) {
11520 astgen.extra.appendAssumeCapacity(args.lib_name);11522 astgen.extra.appendAssumeCapacity(@intFromEnum(args.lib_name));
11521 }11523 }
11522 if (args.align_inst != .none) {11524 if (args.align_inst != .none) {
11523 astgen.extra.appendAssumeCapacity(@intFromEnum(args.align_inst));11525 astgen.extra.appendAssumeCapacity(@intFromEnum(args.align_inst));
...@@ -11532,7 +11534,7 @@ const GenZir = struct {...@@ -11532,7 +11534,7 @@ const GenZir = struct {
11532 .data = .{ .extended = .{11534 .data = .{ .extended = .{
11533 .opcode = .variable,11535 .opcode = .variable,
11534 .small = @bitCast(Zir.Inst.ExtendedVar.Small{11536 .small = @bitCast(Zir.Inst.ExtendedVar.Small{
11535 .has_lib_name = args.lib_name != 0,11537 .has_lib_name = args.lib_name != .empty,
11536 .has_align = args.align_inst != .none,11538 .has_align = args.align_inst != .none,
11537 .has_init = args.init != .none,11539 .has_init = args.init != .none,
11538 .is_extern = args.is_extern,11540 .is_extern = args.is_extern,
...@@ -11588,7 +11590,7 @@ const GenZir = struct {...@@ -11588,7 +11590,7 @@ const GenZir = struct {
11588 astgen.instructions.appendAssumeCapacity(.{11590 astgen.instructions.appendAssumeCapacity(.{
11589 .tag = .int_big,11591 .tag = .int_big,
11590 .data = .{ .str = .{11592 .data = .{ .str = .{
11591 .start = @intCast(astgen.string_bytes.items.len),11593 .start = @enumFromInt(astgen.string_bytes.items.len),
11592 .len = @intCast(limbs.len),11594 .len = @intCast(limbs.len),
11593 } },11595 } },
11594 });11596 });
...@@ -11687,7 +11689,7 @@ const GenZir = struct {...@@ -11687,7 +11689,7 @@ const GenZir = struct {
11687 tag: Zir.Inst.Tag,11689 tag: Zir.Inst.Tag,
11688 /// Absolute token index. This function does the conversion to Decl offset.11690 /// Absolute token index. This function does the conversion to Decl offset.
11689 abs_tok_index: Ast.TokenIndex,11691 abs_tok_index: Ast.TokenIndex,
11690 name: u32,11692 name: Zir.NullTerminatedString,
11691 first_doc_comment: ?Ast.TokenIndex,11693 first_doc_comment: ?Ast.TokenIndex,
11692 ) !Zir.Inst.Index {11694 ) !Zir.Inst.Index {
11693 const gpa = gz.astgen.gpa;11695 const gpa = gz.astgen.gpa;
...@@ -11699,7 +11701,7 @@ const GenZir = struct {...@@ -11699,7 +11701,7 @@ const GenZir = struct {
11699 const doc_comment_index = if (first_doc_comment) |first|11701 const doc_comment_index = if (first_doc_comment) |first|
11700 try gz.astgen.docCommentAsStringFromFirst(abs_tok_index, first)11702 try gz.astgen.docCommentAsStringFromFirst(abs_tok_index, first)
11701 else11703 else
11702 0;11704 .empty;
1170311705
11704 const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Param{11706 const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Param{
11705 .name = name,11707 .name = name,
...@@ -11847,7 +11849,7 @@ const GenZir = struct {...@@ -11847,7 +11849,7 @@ const GenZir = struct {
11847 fn addStrTok(11849 fn addStrTok(
11848 gz: *GenZir,11850 gz: *GenZir,
11849 tag: Zir.Inst.Tag,11851 tag: Zir.Inst.Tag,
11850 str_index: u32,11852 str_index: Zir.NullTerminatedString,
11851 /// Absolute token index. This function does the conversion to Decl offset.11853 /// Absolute token index. This function does the conversion to Decl offset.
11852 abs_tok_index: Ast.TokenIndex,11854 abs_tok_index: Ast.TokenIndex,
11853 ) !Zir.Inst.Ref {11855 ) !Zir.Inst.Ref {
...@@ -12122,7 +12124,7 @@ const GenZir = struct {...@@ -12122,7 +12124,7 @@ const GenZir = struct {
12122 tag: Zir.Inst.Extended,12124 tag: Zir.Inst.Extended,
12123 /// Absolute node index. This function does the conversion to offset from Decl.12125 /// Absolute node index. This function does the conversion to offset from Decl.
12124 node: Ast.Node.Index,12126 node: Ast.Node.Index,
12125 asm_source: u32,12127 asm_source: Zir.NullTerminatedString,
12126 output_type_bits: u32,12128 output_type_bits: u32,
12127 is_volatile: bool,12129 is_volatile: bool,
12128 outputs: []const Zir.Inst.Asm.Output,12130 outputs: []const Zir.Inst.Asm.Output,
...@@ -12441,7 +12443,7 @@ const GenZir = struct {...@@ -12441,7 +12443,7 @@ const GenZir = struct {
12441 }12443 }
12442 }12444 }
1244312445
12444 fn addDbgVar(gz: *GenZir, tag: Zir.Inst.Tag, name: u32, inst: Zir.Inst.Ref) !void {12446 fn addDbgVar(gz: *GenZir, tag: Zir.Inst.Tag, name: Zir.NullTerminatedString, inst: Zir.Inst.Ref) !void {
12445 if (gz.is_comptime) return;12447 if (gz.is_comptime) return;
1244612448
12447 _ = try gz.add(.{ .tag = tag, .data = .{12449 _ = try gz.add(.{ .tag = tag, .data = .{
...@@ -12478,15 +12480,15 @@ const GenZir = struct {...@@ -12478,15 +12480,15 @@ const GenZir = struct {
1247812480
12479/// This can only be for short-lived references; the memory becomes invalidated12481/// This can only be for short-lived references; the memory becomes invalidated
12480/// when another string is added.12482/// when another string is added.
12481fn nullTerminatedString(astgen: AstGen, index: usize) [*:0]const u8 {12483fn nullTerminatedString(astgen: AstGen, index: Zir.NullTerminatedString) [*:0]const u8 {
12482 return @ptrCast(astgen.string_bytes.items[index..]);12484 return @ptrCast(astgen.string_bytes.items[@intFromEnum(index)..]);
12483}12485}
1248412486
12485/// Local variables shadowing detection, including function parameters.12487/// Local variables shadowing detection, including function parameters.
12486fn detectLocalShadowing(12488fn detectLocalShadowing(
12487 astgen: *AstGen,12489 astgen: *AstGen,
12488 scope: *Scope,12490 scope: *Scope,
12489 ident_name: u32,12491 ident_name: Zir.NullTerminatedString,
12490 name_token: Ast.TokenIndex,12492 name_token: Ast.TokenIndex,
12491 token_bytes: []const u8,12493 token_bytes: []const u8,
12492 id_cat: Scope.IdCat,12494 id_cat: Scope.IdCat,
src/Autodoc.zig+54-53
...@@ -447,7 +447,7 @@ fn generateZirData(self: *Autodoc, output_dir: std.fs.Dir) !void {...@@ -447,7 +447,7 @@ fn generateZirData(self: *Autodoc, output_dir: std.fs.Dir) !void {
447const Scope = struct {447const Scope = struct {
448 parent: ?*Scope,448 parent: ?*Scope,
449 map: std.AutoHashMapUnmanaged(449 map: std.AutoHashMapUnmanaged(
450 u32, // index into the current file's string table (decl name)450 Zir.NullTerminatedString, // index into the current file's string table (decl name)
451 *DeclStatus,451 *DeclStatus,
452 ) = .{},452 ) = .{},
453453
...@@ -464,7 +464,7 @@ const Scope = struct {...@@ -464,7 +464,7 @@ const Scope = struct {
464 /// Another reason is that in some places we use the pointer to uniquely464 /// Another reason is that in some places we use the pointer to uniquely
465 /// refer to a decl, as we wait for it to be analyzed. This means that465 /// refer to a decl, as we wait for it to be analyzed. This means that
466 /// those pointers must stay stable.466 /// those pointers must stay stable.
467 pub fn resolveDeclName(self: Scope, string_table_idx: u32, file: *File, inst: Zir.Inst.OptionalIndex) *DeclStatus {467 pub fn resolveDeclName(self: Scope, string_table_idx: Zir.NullTerminatedString, file: *File, inst: Zir.Inst.OptionalIndex) *DeclStatus {
468 var cur: ?*const Scope = &self;468 var cur: ?*const Scope = &self;
469 return while (cur) |s| : (cur = s.parent) {469 return while (cur) |s| : (cur = s.parent) {
470 break s.map.get(string_table_idx) orelse continue;470 break s.map.get(string_table_idx) orelse continue;
...@@ -482,7 +482,7 @@ const Scope = struct {...@@ -482,7 +482,7 @@ const Scope = struct {
482 pub fn insertDeclRef(482 pub fn insertDeclRef(
483 self: *Scope,483 self: *Scope,
484 arena: std.mem.Allocator,484 arena: std.mem.Allocator,
485 decl_name_index: u32, // index into the current file's string table485 decl_name_index: Zir.NullTerminatedString, // index into the current file's string table
486 decl_status: DeclStatus,486 decl_status: DeclStatus,
487 ) !void {487 ) !void {
488 const decl_status_ptr = try arena.create(DeclStatus);488 const decl_status_ptr = try arena.create(DeclStatus);
...@@ -1250,7 +1250,7 @@ fn walkInstruction(...@@ -1250,7 +1250,7 @@ fn walkInstruction(
1250 // @check1250 // @check
1251 const str = data[@intFromEnum(inst)].str; //.get(file.zir);1251 const str = data[@intFromEnum(inst)].str; //.get(file.zir);
1252 const byte_count = str.len * @sizeOf(std.math.big.Limb);1252 const byte_count = str.len * @sizeOf(std.math.big.Limb);
1253 const limb_bytes = file.zir.string_bytes[str.start..][0..byte_count];1253 const limb_bytes = file.zir.string_bytes[@intFromEnum(str.start)..][0..byte_count];
12541254
1255 const limbs = try self.arena.alloc(std.math.big.Limb, str.len);1255 const limbs = try self.arena.alloc(std.math.big.Limb, str.len);
1256 @memcpy(std.mem.sliceAsBytes(limbs)[0..limb_bytes.len], limb_bytes);1256 @memcpy(std.mem.sliceAsBytes(limbs)[0..limb_bytes.len], limb_bytes);
...@@ -2167,7 +2167,7 @@ fn walkInstruction(...@@ -2167,7 +2167,7 @@ fn walkInstruction(
2167 // present in json2167 // present in json
2168 var sentinel: ?DocData.Expr = null;2168 var sentinel: ?DocData.Expr = null;
2169 if (ptr.flags.has_sentinel) {2169 if (ptr.flags.has_sentinel) {
2170 const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));2170 const ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
2171 const ref_result = try self.walkRef(2171 const ref_result = try self.walkRef(
2172 file,2172 file,
2173 parent_scope,2173 parent_scope,
...@@ -2182,7 +2182,7 @@ fn walkInstruction(...@@ -2182,7 +2182,7 @@ fn walkInstruction(
21822182
2183 var @"align": ?DocData.Expr = null;2183 var @"align": ?DocData.Expr = null;
2184 if (ptr.flags.has_align) {2184 if (ptr.flags.has_align) {
2185 const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));2185 const ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
2186 const ref_result = try self.walkRef(2186 const ref_result = try self.walkRef(
2187 file,2187 file,
2188 parent_scope,2188 parent_scope,
...@@ -2196,7 +2196,7 @@ fn walkInstruction(...@@ -2196,7 +2196,7 @@ fn walkInstruction(
2196 }2196 }
2197 var address_space: ?DocData.Expr = null;2197 var address_space: ?DocData.Expr = null;
2198 if (ptr.flags.has_addrspace) {2198 if (ptr.flags.has_addrspace) {
2199 const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));2199 const ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
2200 const ref_result = try self.walkRef(2200 const ref_result = try self.walkRef(
2201 file,2201 file,
2202 parent_scope,2202 parent_scope,
...@@ -2210,7 +2210,7 @@ fn walkInstruction(...@@ -2210,7 +2210,7 @@ fn walkInstruction(
2210 }2210 }
2211 const bit_start: ?DocData.Expr = null;2211 const bit_start: ?DocData.Expr = null;
2212 if (ptr.flags.has_bit_range) {2212 if (ptr.flags.has_bit_range) {
2213 const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));2213 const ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
2214 const ref_result = try self.walkRef(2214 const ref_result = try self.walkRef(
2215 file,2215 file,
2216 parent_scope,2216 parent_scope,
...@@ -2225,7 +2225,7 @@ fn walkInstruction(...@@ -2225,7 +2225,7 @@ fn walkInstruction(
22252225
2226 var host_size: ?DocData.Expr = null;2226 var host_size: ?DocData.Expr = null;
2227 if (ptr.flags.has_bit_range) {2227 if (ptr.flags.has_bit_range) {
2228 const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));2228 const ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
2229 const ref_result = try self.walkRef(2229 const ref_result = try self.walkRef(
2230 file,2230 file,
2231 parent_scope,2231 parent_scope,
...@@ -3041,10 +3041,10 @@ fn walkInstruction(...@@ -3041,10 +3041,10 @@ fn walkInstruction(
3041 );3041 );
3042 var idx = extra.end;3042 var idx = extra.end;
3043 for (fields) |*f| {3043 for (fields) |*f| {
3044 const name = file.zir.nullTerminatedString(file.zir.extra[idx]);3044 const name = file.zir.nullTerminatedString(@enumFromInt(file.zir.extra[idx]));
3045 idx += 1;3045 idx += 1;
30463046
3047 const docs = file.zir.nullTerminatedString(file.zir.extra[idx]);3047 const docs = file.zir.nullTerminatedString(@enumFromInt(file.zir.extra[idx]));
3048 idx += 1;3048 idx += 1;
30493049
3050 f.* = .{3050 f.* = .{
...@@ -3706,10 +3706,10 @@ fn walkInstruction(...@@ -3706,10 +3706,10 @@ fn walkInstruction(
3706 const has_value = @as(u1, @truncate(cur_bit_bag)) != 0;3706 const has_value = @as(u1, @truncate(cur_bit_bag)) != 0;
3707 cur_bit_bag >>= 1;3707 cur_bit_bag >>= 1;
37083708
3709 const field_name_index = file.zir.extra[extra_index];3709 const field_name_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]);
3710 extra_index += 1;3710 extra_index += 1;
37113711
3712 const doc_comment_index = file.zir.extra[extra_index];3712 const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]);
3713 extra_index += 1;3713 extra_index += 1;
37143714
3715 const value_expr: ?DocData.Expr = if (has_value) blk: {3715 const value_expr: ?DocData.Expr = if (has_value) blk: {
...@@ -3730,7 +3730,7 @@ fn walkInstruction(...@@ -3730,7 +3730,7 @@ fn walkInstruction(
3730 const field_name = file.zir.nullTerminatedString(field_name_index);3730 const field_name = file.zir.nullTerminatedString(field_name_index);
37313731
3732 try field_name_indexes.append(self.arena, self.ast_nodes.items.len);3732 try field_name_indexes.append(self.arena, self.ast_nodes.items.len);
3733 const doc_comment: ?[]const u8 = if (doc_comment_index != 0)3733 const doc_comment: ?[]const u8 = if (doc_comment_index != .empty)
3734 file.zir.nullTerminatedString(doc_comment_index)3734 file.zir.nullTerminatedString(doc_comment_index)
3735 else3735 else
3736 null;3736 null;
...@@ -4085,10 +4085,13 @@ fn analyzeAllDecls(...@@ -4085,10 +4085,13 @@ fn analyzeAllDecls(
4085 {4085 {
4086 var it = original_it;4086 var it = original_it;
4087 while (it.next()) |d| {4087 while (it.next()) |d| {
4088 const decl_name_index = file.zir.extra[@intFromEnum(d.sub_index) + 5];4088 const decl_name_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[@intFromEnum(d.sub_index) + 5]);
4089 switch (decl_name_index) {4089 switch (decl_name_index) {
4090 0, 1, 2 => continue,4090 .empty,
4091 else => if (file.zir.string_bytes[decl_name_index] == 0) {4091 .unnamed_test_decl,
4092 .decltest,
4093 => continue,
4094 _ => if (file.zir.nullTerminatedString(decl_name_index).len == 0) {
4092 continue;4095 continue;
4093 },4096 },
4094 }4097 }
...@@ -4195,31 +4198,31 @@ fn analyzeDecl(...@@ -4195,31 +4198,31 @@ fn analyzeDecl(
4195 // const line = file.zir.extra[extra_index];4198 // const line = file.zir.extra[extra_index];
41964199
4197 extra_index += 1;4200 extra_index += 1;
4198 const decl_name_index = file.zir.extra[extra_index];4201 const decl_name_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]);
41994202
4200 extra_index += 1;4203 extra_index += 1;
4201 const value_index: Zir.Inst.Index = @enumFromInt(file.zir.extra[extra_index]);4204 const value_index: Zir.Inst.Index = @enumFromInt(file.zir.extra[extra_index]);
42024205
4203 extra_index += 1;4206 extra_index += 1;
4204 const doc_comment_index = file.zir.extra[extra_index];4207 const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]);
42054208
4206 extra_index += 1;4209 extra_index += 1;
4207 const align_inst: Zir.Inst.Ref = if (!has_align) .none else inst: {4210 const align_inst: Zir.Inst.Ref = if (!has_align) .none else inst: {
4208 const inst = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));4211 const inst: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
4209 extra_index += 1;4212 extra_index += 1;
4210 break :inst inst;4213 break :inst inst;
4211 };4214 };
4212 _ = align_inst;4215 _ = align_inst;
42134216
4214 const section_inst: Zir.Inst.Ref = if (!has_section_or_addrspace) .none else inst: {4217 const section_inst: Zir.Inst.Ref = if (!has_section_or_addrspace) .none else inst: {
4215 const inst = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));4218 const inst: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
4216 extra_index += 1;4219 extra_index += 1;
4217 break :inst inst;4220 break :inst inst;
4218 };4221 };
4219 _ = section_inst;4222 _ = section_inst;
42204223
4221 const addrspace_inst: Zir.Inst.Ref = if (!has_section_or_addrspace) .none else inst: {4224 const addrspace_inst: Zir.Inst.Ref = if (!has_section_or_addrspace) .none else inst: {
4222 const inst = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));4225 const inst: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
4223 extra_index += 1;4226 extra_index += 1;
4224 break :inst inst;4227 break :inst inst;
4225 };4228 };
...@@ -4230,9 +4233,9 @@ fn analyzeDecl(...@@ -4230,9 +4233,9 @@ fn analyzeDecl(
4230 const decl_src = try self.srcLocInfo(file, value_pl_node.src_node, parent_src);4233 const decl_src = try self.srcLocInfo(file, value_pl_node.src_node, parent_src);
42314234
4232 const name: []const u8 = switch (decl_name_index) {4235 const name: []const u8 = switch (decl_name_index) {
4233 0, 1, 2 => unreachable, // comptime or usingnamespace decl, decltest4236 .empty, .unnamed_test_decl, .decltest => unreachable,
4234 else => blk: {4237 _ => blk: {
4235 if (file.zir.string_bytes[decl_name_index] == 0) {4238 if (decl_name_index == .empty) {
4236 // test decl4239 // test decl
4237 unreachable;4240 unreachable;
4238 }4241 }
...@@ -4240,7 +4243,7 @@ fn analyzeDecl(...@@ -4240,7 +4243,7 @@ fn analyzeDecl(
4240 },4243 },
4241 };4244 };
42424245
4243 const doc_comment: ?[]const u8 = if (doc_comment_index != 0)4246 const doc_comment: ?[]const u8 = if (doc_comment_index != .empty)
4244 file.zir.nullTerminatedString(doc_comment_index)4247 file.zir.nullTerminatedString(doc_comment_index)
4245 else4248 else
4246 null;4249 null;
...@@ -4319,13 +4322,13 @@ fn analyzeUsingnamespaceDecl(...@@ -4319,13 +4322,13 @@ fn analyzeUsingnamespaceDecl(
43194322
4320 const is_pub = @as(u1, @truncate(d.flags)) != 0;4323 const is_pub = @as(u1, @truncate(d.flags)) != 0;
4321 const value_index: Zir.Inst.Index = @enumFromInt(file.zir.extra[@intFromEnum(d.sub_index) + 6]);4324 const value_index: Zir.Inst.Index = @enumFromInt(file.zir.extra[@intFromEnum(d.sub_index) + 6]);
4322 const doc_comment_index = file.zir.extra[@intFromEnum(d.sub_index) + 7];4325 const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[@intFromEnum(d.sub_index) + 7]);
43234326
4324 // This is known to work because decl values are always block_inlines4327 // This is known to work because decl values are always block_inlines
4325 const value_pl_node = data[@intFromEnum(value_index)].pl_node;4328 const value_pl_node = data[@intFromEnum(value_index)].pl_node;
4326 const decl_src = try self.srcLocInfo(file, value_pl_node.src_node, parent_src);4329 const decl_src = try self.srcLocInfo(file, value_pl_node.src_node, parent_src);
43274330
4328 const doc_comment: ?[]const u8 = if (doc_comment_index != 0)4331 const doc_comment: ?[]const u8 = if (doc_comment_index != .empty)
4329 file.zir.nullTerminatedString(doc_comment_index)4332 file.zir.nullTerminatedString(doc_comment_index)
4330 else4333 else
4331 null;4334 null;
...@@ -4379,14 +4382,14 @@ fn analyzeDecltest(...@@ -4379,14 +4382,14 @@ fn analyzeDecltest(
4379 const data = file.zir.instructions.items(.data);4382 const data = file.zir.instructions.items(.data);
43804383
4381 const value_index = file.zir.extra[@intFromEnum(d.sub_index) + 6];4384 const value_index = file.zir.extra[@intFromEnum(d.sub_index) + 6];
4382 const decl_name_index = file.zir.extra[@intFromEnum(d.sub_index) + 7];4385 const decl_name_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[@intFromEnum(d.sub_index) + 7]);
43834386
4384 const value_pl_node = data[value_index].pl_node;4387 const value_pl_node = data[value_index].pl_node;
4385 const decl_src = try self.srcLocInfo(file, value_pl_node.src_node, parent_src);4388 const decl_src = try self.srcLocInfo(file, value_pl_node.src_node, parent_src);
43864389
4387 const test_source_code = try self.getBlockSource(file, parent_src, value_pl_node.src_node);4390 const test_source_code = try self.getBlockSource(file, parent_src, value_pl_node.src_node);
43884391
4389 const decl_name: ?[]const u8 = if (decl_name_index != 0)4392 const decl_name: ?[]const u8 = if (decl_name_index != .empty)
4390 file.zir.nullTerminatedString(decl_name_index)4393 file.zir.nullTerminatedString(decl_name_index)
4391 else4394 else
4392 null;4395 null;
...@@ -5018,7 +5021,7 @@ fn analyzeFancyFunction(...@@ -5018,7 +5021,7 @@ fn analyzeFancyFunction(
5018 .param, .param_comptime => {5021 .param, .param_comptime => {
5019 const pl_tok = data[@intFromEnum(param_index)].pl_tok;5022 const pl_tok = data[@intFromEnum(param_index)].pl_tok;
5020 const extra = file.zir.extraData(Zir.Inst.Param, pl_tok.payload_index);5023 const extra = file.zir.extraData(Zir.Inst.Param, pl_tok.payload_index);
5021 const doc_comment = if (extra.data.doc_comment != 0)5024 const doc_comment = if (extra.data.doc_comment != .empty)
5022 file.zir.nullTerminatedString(extra.data.doc_comment)5025 file.zir.nullTerminatedString(extra.data.doc_comment)
5023 else5026 else
5024 "";5027 "";
...@@ -5056,13 +5059,14 @@ fn analyzeFancyFunction(...@@ -5056,13 +5059,14 @@ fn analyzeFancyFunction(
50565059
5057 var lib_name: []const u8 = "";5060 var lib_name: []const u8 = "";
5058 if (extra.data.bits.has_lib_name) {5061 if (extra.data.bits.has_lib_name) {
5059 lib_name = file.zir.nullTerminatedString(file.zir.extra[extra_index]);5062 const lib_name_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]);
5063 lib_name = file.zir.nullTerminatedString(lib_name_index);
5060 extra_index += 1;5064 extra_index += 1;
5061 }5065 }
50625066
5063 var align_index: ?usize = null;5067 var align_index: ?usize = null;
5064 if (extra.data.bits.has_align_ref) {5068 if (extra.data.bits.has_align_ref) {
5065 const align_ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));5069 const align_ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
5066 align_index = self.exprs.items.len;5070 align_index = self.exprs.items.len;
5067 _ = try self.walkRef(5071 _ = try self.walkRef(
5068 file,5072 file,
...@@ -5086,7 +5090,7 @@ fn analyzeFancyFunction(...@@ -5086,7 +5090,7 @@ fn analyzeFancyFunction(
50865090
5087 var addrspace_index: ?usize = null;5091 var addrspace_index: ?usize = null;
5088 if (extra.data.bits.has_addrspace_ref) {5092 if (extra.data.bits.has_addrspace_ref) {
5089 const addrspace_ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));5093 const addrspace_ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
5090 addrspace_index = self.exprs.items.len;5094 addrspace_index = self.exprs.items.len;
5091 _ = try self.walkRef(5095 _ = try self.walkRef(
5092 file,5096 file,
...@@ -5110,7 +5114,7 @@ fn analyzeFancyFunction(...@@ -5110,7 +5114,7 @@ fn analyzeFancyFunction(
51105114
5111 var section_index: ?usize = null;5115 var section_index: ?usize = null;
5112 if (extra.data.bits.has_section_ref) {5116 if (extra.data.bits.has_section_ref) {
5113 const section_ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));5117 const section_ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
5114 section_index = self.exprs.items.len;5118 section_index = self.exprs.items.len;
5115 _ = try self.walkRef(5119 _ = try self.walkRef(
5116 file,5120 file,
...@@ -5310,7 +5314,7 @@ fn analyzeFunction(...@@ -5310,7 +5314,7 @@ fn analyzeFunction(
5310 .param, .param_comptime => {5314 .param, .param_comptime => {
5311 const pl_tok = data[@intFromEnum(param_index)].pl_tok;5315 const pl_tok = data[@intFromEnum(param_index)].pl_tok;
5312 const extra = file.zir.extraData(Zir.Inst.Param, pl_tok.payload_index);5316 const extra = file.zir.extraData(Zir.Inst.Param, pl_tok.payload_index);
5313 const doc_comment = if (extra.data.doc_comment != 0)5317 const doc_comment = if (extra.data.doc_comment != .empty)
5314 file.zir.nullTerminatedString(extra.data.doc_comment)5318 file.zir.nullTerminatedString(extra.data.doc_comment)
5315 else5319 else
5316 "";5320 "";
...@@ -5497,14 +5501,11 @@ fn collectUnionFieldInfo(...@@ -5497,14 +5501,11 @@ fn collectUnionFieldInfo(
5497 cur_bit_bag >>= 1;5501 cur_bit_bag >>= 1;
5498 _ = unused;5502 _ = unused;
54995503
5500 const field_name = file.zir.nullTerminatedString(file.zir.extra[extra_index]);5504 const field_name = file.zir.nullTerminatedString(@enumFromInt(file.zir.extra[extra_index]));
5501 extra_index += 1;5505 extra_index += 1;
5502 const doc_comment_index = file.zir.extra[extra_index];5506 const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]);
5503 extra_index += 1;5507 extra_index += 1;
5504 const field_type = if (has_type)5508 const field_type: Zir.Inst.Ref = if (has_type) @enumFromInt(file.zir.extra[extra_index]) else .void_type;
5505 @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]))
5506 else
5507 .void_type;
5508 if (has_type) extra_index += 1;5509 if (has_type) extra_index += 1;
55095510
5510 if (has_align) extra_index += 1;5511 if (has_align) extra_index += 1;
...@@ -5526,7 +5527,7 @@ fn collectUnionFieldInfo(...@@ -5526,7 +5527,7 @@ fn collectUnionFieldInfo(
5526 // ast node5527 // ast node
5527 {5528 {
5528 try field_name_indexes.append(self.arena, self.ast_nodes.items.len);5529 try field_name_indexes.append(self.arena, self.ast_nodes.items.len);
5529 const doc_comment: ?[]const u8 = if (doc_comment_index != 0)5530 const doc_comment: ?[]const u8 = if (doc_comment_index != .empty)
5530 file.zir.nullTerminatedString(doc_comment_index)5531 file.zir.nullTerminatedString(doc_comment_index)
5531 else5532 else
5532 null;5533 null;
...@@ -5559,8 +5560,8 @@ fn collectStructFieldInfo(...@@ -5559,8 +5560,8 @@ fn collectStructFieldInfo(
5559 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;5560 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;
55605561
5561 const Field = struct {5562 const Field = struct {
5562 field_name: ?u32,5563 field_name: Zir.NullTerminatedString,
5563 doc_comment_index: u32,5564 doc_comment_index: Zir.NullTerminatedString,
5564 type_body_len: u32 = 0,5565 type_body_len: u32 = 0,
5565 align_body_len: u32 = 0,5566 align_body_len: u32 = 0,
5566 init_body_len: u32 = 0,5567 init_body_len: u32 = 0,
...@@ -5587,13 +5588,13 @@ fn collectStructFieldInfo(...@@ -5587,13 +5588,13 @@ fn collectStructFieldInfo(
5587 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;5588 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;
5588 cur_bit_bag >>= 1;5589 cur_bit_bag >>= 1;
55895590
5590 const field_name: ?u32 = if (!is_tuple) blk: {5591 const field_name: Zir.NullTerminatedString = if (!is_tuple) blk: {
5591 const fname = file.zir.extra[extra_index];5592 const fname = file.zir.extra[extra_index];
5592 extra_index += 1;5593 extra_index += 1;
5593 break :blk fname;5594 break :blk @enumFromInt(fname);
5594 } else null;5595 } else .empty;
55955596
5596 const doc_comment_index = file.zir.extra[extra_index];5597 const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]);
5597 extra_index += 1;5598 extra_index += 1;
55985599
5599 fields[field_i] = .{5600 fields[field_i] = .{
...@@ -5604,7 +5605,7 @@ fn collectStructFieldInfo(...@@ -5604,7 +5605,7 @@ fn collectStructFieldInfo(
5604 if (has_type_body) {5605 if (has_type_body) {
5605 fields[field_i].type_body_len = file.zir.extra[extra_index];5606 fields[field_i].type_body_len = file.zir.extra[extra_index];
5606 } else {5607 } else {
5607 fields[field_i].type_ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));5608 fields[field_i].type_ref = @enumFromInt(file.zir.extra[extra_index]);
5608 }5609 }
5609 extra_index += 1;5610 extra_index += 1;
56105611
...@@ -5686,12 +5687,12 @@ fn collectStructFieldInfo(...@@ -5686,12 +5687,12 @@ fn collectStructFieldInfo(
5686 // ast node5687 // ast node
5687 {5688 {
5688 try field_name_indexes.append(self.arena, self.ast_nodes.items.len);5689 try field_name_indexes.append(self.arena, self.ast_nodes.items.len);
5689 const doc_comment: ?[]const u8 = if (field.doc_comment_index != 0)5690 const doc_comment: ?[]const u8 = if (field.doc_comment_index != .empty)
5690 file.zir.nullTerminatedString(field.doc_comment_index)5691 file.zir.nullTerminatedString(field.doc_comment_index)
5691 else5692 else
5692 null;5693 null;
5693 const field_name: []const u8 = if (field.field_name) |f_name|5694 const field_name: []const u8 = if (field.field_name != .empty)
5694 file.zir.nullTerminatedString(f_name)5695 file.zir.nullTerminatedString(field.field_name)
5695 else5696 else
5696 "";5697 "";
56975698
src/Module.zig+10-10
...@@ -4198,7 +4198,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err...@@ -4198,7 +4198,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
41984198
4199 const line_off = zir.extra[decl_sub_index + 4];4199 const line_off = zir.extra[decl_sub_index + 4];
4200 const line = iter.parent_decl.relativeToLine(line_off);4200 const line = iter.parent_decl.relativeToLine(line_off);
4201 const decl_name_index = zir.extra[decl_sub_index + 5];4201 const decl_name_index: Zir.NullTerminatedString = @enumFromInt(zir.extra[decl_sub_index + 5]);
4202 const decl_doccomment_index = zir.extra[decl_sub_index + 7];4202 const decl_doccomment_index = zir.extra[decl_sub_index + 7];
4203 const decl_zir_index = zir.extra[decl_sub_index + 6];4203 const decl_zir_index = zir.extra[decl_sub_index + 6];
4204 const decl_block_inst_data = zir.instructions.items(.data)[decl_zir_index].pl_node;4204 const decl_block_inst_data = zir.instructions.items(.data)[decl_zir_index].pl_node;
...@@ -4208,7 +4208,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err...@@ -4208,7 +4208,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
4208 var is_named_test = false;4208 var is_named_test = false;
4209 var kind: Decl.Kind = .named;4209 var kind: Decl.Kind = .named;
4210 const decl_name: InternPool.NullTerminatedString = switch (decl_name_index) {4210 const decl_name: InternPool.NullTerminatedString = switch (decl_name_index) {
4211 0 => name: {4211 .empty => name: {
4212 if (export_bit) {4212 if (export_bit) {
4213 const i = iter.usingnamespace_index;4213 const i = iter.usingnamespace_index;
4214 iter.usingnamespace_index += 1;4214 iter.usingnamespace_index += 1;
...@@ -4221,23 +4221,23 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err...@@ -4221,23 +4221,23 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
4221 break :name try ip.getOrPutStringFmt(gpa, "comptime_{d}", .{i});4221 break :name try ip.getOrPutStringFmt(gpa, "comptime_{d}", .{i});
4222 }4222 }
4223 },4223 },
4224 1 => name: {4224 .unnamed_test_decl => name: {
4225 const i = iter.unnamed_test_index;4225 const i = iter.unnamed_test_index;
4226 iter.unnamed_test_index += 1;4226 iter.unnamed_test_index += 1;
4227 kind = .@"test";4227 kind = .@"test";
4228 break :name try ip.getOrPutStringFmt(gpa, "test_{d}", .{i});4228 break :name try ip.getOrPutStringFmt(gpa, "test_{d}", .{i});
4229 },4229 },
4230 2 => name: {4230 .decltest => name: {
4231 is_named_test = true;4231 is_named_test = true;
4232 const test_name = zir.nullTerminatedString(decl_doccomment_index);4232 const test_name = zir.nullTerminatedString(@enumFromInt(decl_doccomment_index));
4233 kind = .@"test";4233 kind = .@"test";
4234 break :name try ip.getOrPutStringFmt(gpa, "decltest.{s}", .{test_name});4234 break :name try ip.getOrPutStringFmt(gpa, "decltest.{s}", .{test_name});
4235 },4235 },
4236 else => name: {4236 _ => name: {
4237 const raw_name = zir.nullTerminatedString(decl_name_index);4237 const raw_name = zir.nullTerminatedString(decl_name_index);
4238 if (raw_name.len == 0) {4238 if (raw_name.len == 0) {
4239 is_named_test = true;4239 is_named_test = true;
4240 const test_name = zir.nullTerminatedString(decl_name_index + 1);4240 const test_name = zir.nullTerminatedString(@enumFromInt(@intFromEnum(decl_name_index) + 1));
4241 kind = .@"test";4241 kind = .@"test";
4242 break :name try ip.getOrPutStringFmt(gpa, "test.{s}", .{test_name});4242 break :name try ip.getOrPutStringFmt(gpa, "test.{s}", .{test_name});
4243 } else {4243 } else {
...@@ -4246,7 +4246,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err...@@ -4246,7 +4246,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
4246 },4246 },
4247 };4247 };
42484248
4249 const is_exported = export_bit and decl_name_index != 0;4249 const is_exported = export_bit and decl_name_index != .empty;
4250 if (kind == .@"usingnamespace") try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1);4250 if (kind == .@"usingnamespace") try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1);
42514251
4252 // We create a Decl for it regardless of analysis status.4252 // We create a Decl for it regardless of analysis status.
...@@ -4271,8 +4271,8 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err...@@ -4271,8 +4271,8 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
4271 // test decls if in test mode, get analyzed.4271 // test decls if in test mode, get analyzed.
4272 const decl_mod = namespace.file_scope.mod;4272 const decl_mod = namespace.file_scope.mod;
4273 const want_analysis = is_exported or switch (decl_name_index) {4273 const want_analysis = is_exported or switch (decl_name_index) {
4274 0 => true, // comptime or usingnamespace decl4274 .empty => true, // comptime or usingnamespace decl
4275 1 => blk: {4275 .unnamed_test_decl => blk: {
4276 // test decl with no name. Skip the part where we check against4276 // test decl with no name. Skip the part where we check against
4277 // the test name filter.4277 // the test name filter.
4278 if (!comp.config.is_test) break :blk false;4278 if (!comp.config.is_test) break :blk false;
src/Sema.zig+20-15
...@@ -3044,7 +3044,8 @@ fn zirEnumDecl(...@@ -3044,7 +3044,8 @@ fn zirEnumDecl(
3044 const has_tag_value = @as(u1, @truncate(cur_bit_bag)) != 0;3044 const has_tag_value = @as(u1, @truncate(cur_bit_bag)) != 0;
3045 cur_bit_bag >>= 1;3045 cur_bit_bag >>= 1;
30463046
3047 const field_name_zir = sema.code.nullTerminatedString(sema.code.extra[extra_index]);3047 const field_name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);
3048 const field_name_zir = sema.code.nullTerminatedString(field_name_index);
3048 extra_index += 1;3049 extra_index += 1;
30493050
3050 // doc comment3051 // doc comment
...@@ -3322,8 +3323,8 @@ fn zirErrorSetDecl(...@@ -3322,8 +3323,8 @@ fn zirErrorSetDecl(
3322 var extra_index: u32 = @intCast(extra.end);3323 var extra_index: u32 = @intCast(extra.end);
3323 const extra_index_end = extra_index + (extra.data.fields_len * 2);3324 const extra_index_end = extra_index + (extra.data.fields_len * 2);
3324 while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string3325 while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string
3325 const str_index = sema.code.extra[extra_index];3326 const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);
3326 const name = sema.code.nullTerminatedString(str_index);3327 const name = sema.code.nullTerminatedString(name_index);
3327 const name_ip = try mod.intern_pool.getOrPutString(gpa, name);3328 const name_ip = try mod.intern_pool.getOrPutString(gpa, name);
3328 _ = try mod.getErrorValue(name_ip);3329 _ = try mod.getErrorValue(name_ip);
3329 const result = names.getOrPutAssumeCapacity(name_ip);3330 const result = names.getOrPutAssumeCapacity(name_ip);
...@@ -5522,7 +5523,7 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -5522,7 +5523,7 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
5522 const mod = sema.mod;5523 const mod = sema.mod;
5523 const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].str;5524 const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].str;
5524 const byte_count = int.len * @sizeOf(std.math.big.Limb);5525 const byte_count = int.len * @sizeOf(std.math.big.Limb);
5525 const limb_bytes = sema.code.string_bytes[int.start..][0..byte_count];5526 const limb_bytes = sema.code.string_bytes[@intFromEnum(int.start)..][0..byte_count];
55265527
5527 // TODO: this allocation and copy is only needed because the limbs may be unaligned.5528 // TODO: this allocation and copy is only needed because the limbs may be unaligned.
5528 // If ZIR is adjusted so that big int limbs are guaranteed to be aligned, these5529 // If ZIR is adjusted so that big int limbs are guaranteed to be aligned, these
...@@ -7999,11 +8000,11 @@ fn instantiateGenericCall(...@@ -7999,11 +8000,11 @@ fn instantiateGenericCall(
7999 } },8000 } },
8000 }));8001 }));
8001 const param_name: Zir.NullTerminatedString = switch (param_tag) {8002 const param_name: Zir.NullTerminatedString = switch (param_tag) {
8002 .param_anytype => @enumFromInt(fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].str_tok.start),8003 .param_anytype => fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].str_tok.start,
8003 .param => name: {8004 .param => name: {
8004 const inst_data = fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].pl_tok;8005 const inst_data = fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].pl_tok;
8005 const extra = fn_zir.extraData(Zir.Inst.Param, inst_data.payload_index);8006 const extra = fn_zir.extraData(Zir.Inst.Param, inst_data.payload_index);
8006 break :name @enumFromInt(extra.data.name);8007 break :name extra.data.name;
8007 },8008 },
8008 else => unreachable,8009 else => unreachable,
8009 };8010 };
...@@ -9616,7 +9617,7 @@ fn finishFunc(...@@ -9616,7 +9617,7 @@ fn finishFunc(
9616 .param_anytype => data[@intFromEnum(param_index)].str_tok.src(),9617 .param_anytype => data[@intFromEnum(param_index)].str_tok.src(),
9617 else => unreachable,9618 else => unreachable,
9618 };9619 };
9619 const name = sema.code.nullTerminatedString2(name_nts);9620 const name = sema.code.nullTerminatedString(name_nts);
9620 if (name.len != 0) {9621 if (name.len != 0) {
9621 try sema.errNote(block, param_src, msg, "param '{s}' is required to be comptime", .{name});9622 try sema.errNote(block, param_src, msg, "param '{s}' is required to be comptime", .{name});
9622 } else {9623 } else {
...@@ -9690,7 +9691,7 @@ fn zirParam(...@@ -9690,7 +9691,7 @@ fn zirParam(
9690 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_tok;9691 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_tok;
9691 const src = inst_data.src();9692 const src = inst_data.src();
9692 const extra = sema.code.extraData(Zir.Inst.Param, inst_data.payload_index);9693 const extra = sema.code.extraData(Zir.Inst.Param, inst_data.payload_index);
9693 const param_name: Zir.NullTerminatedString = @enumFromInt(extra.data.name);9694 const param_name: Zir.NullTerminatedString = extra.data.name;
9694 const body = sema.code.bodySlice(extra.end, extra.data.body_len);9695 const body = sema.code.bodySlice(extra.end, extra.data.body_len);
96959696
9696 const param_ty = param_ty: {9697 const param_ty = param_ty: {
...@@ -9781,7 +9782,7 @@ fn zirParamAnytype(...@@ -9781,7 +9782,7 @@ fn zirParamAnytype(
9781 comptime_syntax: bool,9782 comptime_syntax: bool,
9782) CompileError!void {9783) CompileError!void {
9783 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;9784 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
9784 const param_name: Zir.NullTerminatedString = @enumFromInt(inst_data.start);9785 const param_name: Zir.NullTerminatedString = inst_data.start;
97859786
9786 // We are evaluating a generic function without any comptime args provided.9787 // We are evaluating a generic function without any comptime args provided.
97879788
...@@ -16184,7 +16185,7 @@ fn zirAsm(...@@ -16184,7 +16185,7 @@ fn zirAsm(
16184 const is_global_assembly = sema.func_index == .none;16185 const is_global_assembly = sema.func_index == .none;
1618516186
16186 const asm_source: []const u8 = if (tmpl_is_expr) blk: {16187 const asm_source: []const u8 = if (tmpl_is_expr) blk: {
16187 const tmpl: Zir.Inst.Ref = @enumFromInt(extra.data.asm_source);16188 const tmpl: Zir.Inst.Ref = @enumFromInt(@intFromEnum(extra.data.asm_source));
16188 const s: []const u8 = try sema.resolveConstString(block, src, tmpl, .{16189 const s: []const u8 = try sema.resolveConstString(block, src, tmpl, .{
16189 .needed_comptime_reason = "assembly code must be comptime-known",16190 .needed_comptime_reason = "assembly code must be comptime-known",
16190 });16191 });
...@@ -16272,7 +16273,8 @@ fn zirAsm(...@@ -16272,7 +16273,8 @@ fn zirAsm(
1627216273
16273 const clobbers = try sema.arena.alloc([]const u8, clobbers_len);16274 const clobbers = try sema.arena.alloc([]const u8, clobbers_len);
16274 for (clobbers) |*name| {16275 for (clobbers) |*name| {
16275 name.* = sema.code.nullTerminatedString(sema.code.extra[extra_i]);16276 const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_i]);
16277 name.* = sema.code.nullTerminatedString(name_index);
16276 extra_i += 1;16278 extra_i += 1;
1627716279
16278 needed_capacity += name.*.len / 4 + 1;16280 needed_capacity += name.*.len / 4 + 1;
...@@ -24713,7 +24715,8 @@ fn zirVarExtended(...@@ -24713,7 +24715,8 @@ fn zirVarExtended(
24713 var extra_index: usize = extra.end;24715 var extra_index: usize = extra.end;
2471424716
24715 const lib_name = if (small.has_lib_name) lib_name: {24717 const lib_name = if (small.has_lib_name) lib_name: {
24716 const lib_name = sema.code.nullTerminatedString(sema.code.extra[extra_index]);24718 const lib_name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);
24719 const lib_name = sema.code.nullTerminatedString(lib_name_index);
24717 extra_index += 1;24720 extra_index += 1;
24718 try sema.handleExternLibName(block, ty_src, lib_name);24721 try sema.handleExternLibName(block, ty_src, lib_name);
24719 break :lib_name lib_name;24722 break :lib_name lib_name;
...@@ -24781,7 +24784,8 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -24781,7 +24784,8 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
24781 var extra_index: usize = extra.end;24784 var extra_index: usize = extra.end;
2478224785
24783 const lib_name: ?[]const u8 = if (extra.data.bits.has_lib_name) blk: {24786 const lib_name: ?[]const u8 = if (extra.data.bits.has_lib_name) blk: {
24784 const lib_name = sema.code.nullTerminatedString(sema.code.extra[extra_index]);24787 const lib_name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);
24788 const lib_name = sema.code.nullTerminatedString(lib_name_index);
24785 extra_index += 1;24789 extra_index += 1;
24786 break :blk lib_name;24790 break :blk lib_name;
24787 } else null;24791 } else null;
...@@ -35841,7 +35845,7 @@ fn semaStructFields(...@@ -35841,7 +35845,7 @@ fn semaStructFields(
3584135845
35842 var opt_field_name_zir: ?[:0]const u8 = null;35846 var opt_field_name_zir: ?[:0]const u8 = null;
35843 if (!small.is_tuple) {35847 if (!small.is_tuple) {
35844 opt_field_name_zir = zir.nullTerminatedString(zir.extra[extra_index]);35848 opt_field_name_zir = zir.nullTerminatedString(@enumFromInt(zir.extra[extra_index]));
35845 extra_index += 1;35849 extra_index += 1;
35846 }35850 }
35847 extra_index += 1; // doc_comment35851 extra_index += 1; // doc_comment
...@@ -36344,7 +36348,8 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un...@@ -36344,7 +36348,8 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un
36344 cur_bit_bag >>= 1;36348 cur_bit_bag >>= 1;
36345 _ = unused;36349 _ = unused;
3634636350
36347 const field_name_zir = zir.nullTerminatedString(zir.extra[extra_index]);36351 const field_name_index: Zir.NullTerminatedString = @enumFromInt(zir.extra[extra_index]);
36352 const field_name_zir = zir.nullTerminatedString(field_name_index);
36348 extra_index += 1;36353 extra_index += 1;
3634936354
36350 // doc_comment36355 // doc_comment
src/Zir.zig+42-44
...@@ -93,6 +93,7 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) ExtraData(T) {...@@ -93,6 +93,7 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) ExtraData(T) {
9393
94 Inst.Ref,94 Inst.Ref,
95 Inst.Index,95 Inst.Index,
96 NullTerminatedString,
96 => @enumFromInt(code.extra[i]),97 => @enumFromInt(code.extra[i]),
9798
98 i32,99 i32,
...@@ -112,18 +113,15 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) ExtraData(T) {...@@ -112,18 +113,15 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) ExtraData(T) {
112 };113 };
113}114}
114115
115/// TODO migrate to use this for type safety
116pub const NullTerminatedString = enum(u32) {116pub const NullTerminatedString = enum(u32) {
117 empty = 0,
118 unnamed_test_decl = 1,
119 decltest = 2,
117 _,120 _,
118};121};
119122
120/// TODO: migrate to nullTerminatedString2 for type safety
121pub fn nullTerminatedString(code: Zir, index: usize) [:0]const u8 {
122 return nullTerminatedString2(code, @enumFromInt(index));
123}
124
125/// Given an index into `string_bytes` returns the null-terminated string found there.123/// Given an index into `string_bytes` returns the null-terminated string found there.
126pub fn nullTerminatedString2(code: Zir, index: NullTerminatedString) [:0]const u8 {124pub fn nullTerminatedString(code: Zir, index: NullTerminatedString) [:0]const u8 {
127 const start = @intFromEnum(index);125 const start = @intFromEnum(index);
128 var end: u32 = start;126 var end: u32 = start;
129 while (code.string_bytes[end] != 0) {127 while (code.string_bytes[end] != 0) {
...@@ -2298,17 +2296,17 @@ pub const Inst = struct {...@@ -2298,17 +2296,17 @@ pub const Inst = struct {
2298 /// For strings which may contain null bytes.2296 /// For strings which may contain null bytes.
2299 str: struct {2297 str: struct {
2300 /// Offset into `string_bytes`.2298 /// Offset into `string_bytes`.
2301 start: u32,2299 start: NullTerminatedString,
2302 /// Number of bytes in the string.2300 /// Number of bytes in the string.
2303 len: u32,2301 len: u32,
23042302
2305 pub fn get(self: @This(), code: Zir) []const u8 {2303 pub fn get(self: @This(), code: Zir) []const u8 {
2306 return code.string_bytes[self.start..][0..self.len];2304 return code.string_bytes[@intFromEnum(self.start)..][0..self.len];
2307 }2305 }
2308 },2306 },
2309 str_tok: struct {2307 str_tok: struct {
2310 /// Offset into `string_bytes`. Null-terminated.2308 /// Offset into `string_bytes`. Null-terminated.
2311 start: u32,2309 start: NullTerminatedString,
2312 /// Offset from Decl AST token index.2310 /// Offset from Decl AST token index.
2313 src_tok: u32,2311 src_tok: u32,
23142312
...@@ -2385,7 +2383,7 @@ pub const Inst = struct {...@@ -2385,7 +2383,7 @@ pub const Inst = struct {
2385 },2383 },
2386 str_op: struct {2384 str_op: struct {
2387 /// Offset into `string_bytes`. Null-terminated.2385 /// Offset into `string_bytes`. Null-terminated.
2388 str: u32,2386 str: NullTerminatedString,
2389 operand: Ref,2387 operand: Ref,
23902388
2391 pub fn getStr(self: @This(), zir: Zir) [:0]const u8 {2389 pub fn getStr(self: @This(), zir: Zir) [:0]const u8 {
...@@ -2466,11 +2464,11 @@ pub const Inst = struct {...@@ -2466,11 +2464,11 @@ pub const Inst = struct {
2466 /// Trailing:2464 /// Trailing:
2467 /// 0. Output for every outputs_len2465 /// 0. Output for every outputs_len
2468 /// 1. Input for every inputs_len2466 /// 1. Input for every inputs_len
2469 /// 2. clobber: u32 // index into string_bytes (null terminated) for every clobbers_len.2467 /// 2. clobber: NullTerminatedString // index into string_bytes (null terminated) for every clobbers_len.
2470 pub const Asm = struct {2468 pub const Asm = struct {
2471 src_node: i32,2469 src_node: i32,
2472 // null-terminated string index2470 // null-terminated string index
2473 asm_source: u32,2471 asm_source: NullTerminatedString,
2474 /// 1 bit for each outputs_len: whether it uses `-> T` or not.2472 /// 1 bit for each outputs_len: whether it uses `-> T` or not.
2475 /// 0b0 - operand is a pointer to where to store the output.2473 /// 0b0 - operand is a pointer to where to store the output.
2476 /// 0b1 - operand is a type; asm expression has the output as the result.2474 /// 0b1 - operand is a type; asm expression has the output as the result.
...@@ -2479,18 +2477,18 @@ pub const Inst = struct {...@@ -2479,18 +2477,18 @@ pub const Inst = struct {
24792477
2480 pub const Output = struct {2478 pub const Output = struct {
2481 /// index into string_bytes (null terminated)2479 /// index into string_bytes (null terminated)
2482 name: u32,2480 name: NullTerminatedString,
2483 /// index into string_bytes (null terminated)2481 /// index into string_bytes (null terminated)
2484 constraint: u32,2482 constraint: NullTerminatedString,
2485 /// How to interpret this is determined by `output_type_bits`.2483 /// How to interpret this is determined by `output_type_bits`.
2486 operand: Ref,2484 operand: Ref,
2487 };2485 };
24882486
2489 pub const Input = struct {2487 pub const Input = struct {
2490 /// index into string_bytes (null terminated)2488 /// index into string_bytes (null terminated)
2491 name: u32,2489 name: NullTerminatedString,
2492 /// index into string_bytes (null terminated)2490 /// index into string_bytes (null terminated)
2493 constraint: u32,2491 constraint: NullTerminatedString,
2494 operand: Ref,2492 operand: Ref,
2495 };2493 };
2496 };2494 };
...@@ -2524,7 +2522,7 @@ pub const Inst = struct {...@@ -2524,7 +2522,7 @@ pub const Inst = struct {
2524 };2522 };
25252523
2526 /// Trailing:2524 /// Trailing:
2527 /// 0. lib_name: u32, // null terminated string index, if has_lib_name is set2525 /// 0. lib_name: NullTerminatedString, // null terminated string index, if has_lib_name is set
2528 /// if (has_align_ref and !has_align_body) {2526 /// if (has_align_ref and !has_align_body) {
2529 /// 1. align: Ref,2527 /// 1. align: Ref,
2530 /// }2528 /// }
...@@ -2598,7 +2596,7 @@ pub const Inst = struct {...@@ -2598,7 +2596,7 @@ pub const Inst = struct {
2598 };2596 };
25992597
2600 /// Trailing:2598 /// Trailing:
2601 /// 0. lib_name: u32, // null terminated string index, if has_lib_name is set2599 /// 0. lib_name: NullTerminatedString, // null terminated string index, if has_lib_name is set
2602 /// 1. align: Ref, // if has_align is set2600 /// 1. align: Ref, // if has_align is set
2603 /// 2. init: Ref // if has_init is set2601 /// 2. init: Ref // if has_init is set
2604 /// The source node is obtained from the containing `block_inline`.2602 /// The source node is obtained from the containing `block_inline`.
...@@ -2672,7 +2670,7 @@ pub const Inst = struct {...@@ -2672,7 +2670,7 @@ pub const Inst = struct {
2672 flags: Call.Flags,2670 flags: Call.Flags,
2673 obj_ptr: Ref,2671 obj_ptr: Ref,
2674 /// Offset into `string_bytes`.2672 /// Offset into `string_bytes`.
2675 field_name_start: u32,2673 field_name_start: NullTerminatedString,
2676 };2674 };
26772675
2678 pub const TypeOfPeer = struct {2676 pub const TypeOfPeer = struct {
...@@ -2871,7 +2869,7 @@ pub const Inst = struct {...@@ -2871,7 +2869,7 @@ pub const Inst = struct {
2871 pub const Field = struct {2869 pub const Field = struct {
2872 lhs: Ref,2870 lhs: Ref,
2873 /// Offset into `string_bytes`.2871 /// Offset into `string_bytes`.
2874 field_name_start: u32,2872 field_name_start: NullTerminatedString,
2875 };2873 };
28762874
2877 pub const FieldNamed = struct {2875 pub const FieldNamed = struct {
...@@ -2900,7 +2898,7 @@ pub const Inst = struct {...@@ -2900,7 +2898,7 @@ pub const Inst = struct {
2900 /// 7. decl: { // for every decls_len2898 /// 7. decl: { // for every decls_len
2901 /// src_hash: [4]u32, // hash of source bytes2899 /// src_hash: [4]u32, // hash of source bytes
2902 /// line: u32, // line number of decl, relative to parent2900 /// line: u32, // line number of decl, relative to parent
2903 /// name: u32, // null terminated string index2901 /// name: NullTerminatedString, // null terminated string index
2904 /// - 0 means comptime or usingnamespace decl.2902 /// - 0 means comptime or usingnamespace decl.
2905 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace2903 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
2906 /// - 1 means test decl with no name.2904 /// - 1 means test decl with no name.
...@@ -2908,7 +2906,7 @@ pub const Inst = struct {...@@ -2908,7 +2906,7 @@ pub const Inst = struct {
2908 /// - if there is a 0 byte at the position `name` indexes, it indicates2906 /// - if there is a 0 byte at the position `name` indexes, it indicates
2909 /// this is a test decl, and the name starts at `name+1`.2907 /// this is a test decl, and the name starts at `name+1`.
2910 /// value: Index,2908 /// value: Index,
2911 /// doc_comment: u32, 0 if no doc comment, if this is a decltest, doc_comment references the decl name in the string table2909 /// doc_comment: u32, .empty if no doc comment, if this is a decltest, doc_comment references the decl name in the string table
2912 /// align: Ref, // if corresponding bit is set2910 /// align: Ref, // if corresponding bit is set
2913 /// link_section_or_address_space: { // if corresponding bit is set.2911 /// link_section_or_address_space: { // if corresponding bit is set.
2914 /// link_section: Ref,2912 /// link_section: Ref,
...@@ -2923,7 +2921,7 @@ pub const Inst = struct {...@@ -2923,7 +2921,7 @@ pub const Inst = struct {
2923 /// 0bX000: whether corresponding field has a type expression2921 /// 0bX000: whether corresponding field has a type expression
2924 /// 9. fields: { // for every fields_len2922 /// 9. fields: { // for every fields_len
2925 /// field_name: u32, // if !is_tuple2923 /// field_name: u32, // if !is_tuple
2926 /// doc_comment: u32, // 0 if no doc comment2924 /// doc_comment: NullTerminatedString, // .empty if no doc comment
2927 /// field_type: Ref, // if corresponding bit is not set. none means anytype.2925 /// field_type: Ref, // if corresponding bit is not set. none means anytype.
2928 /// field_type_body_len: u32, // if corresponding bit is set2926 /// field_type_body_len: u32, // if corresponding bit is set
2929 /// align_body_len: u32, // if corresponding bit is set2927 /// align_body_len: u32, // if corresponding bit is set
...@@ -2996,14 +2994,14 @@ pub const Inst = struct {...@@ -2996,14 +2994,14 @@ pub const Inst = struct {
2996 /// 6. decl: { // for every decls_len2994 /// 6. decl: { // for every decls_len
2997 /// src_hash: [4]u32, // hash of source bytes2995 /// src_hash: [4]u32, // hash of source bytes
2998 /// line: u32, // line number of decl, relative to parent2996 /// line: u32, // line number of decl, relative to parent
2999 /// name: u32, // null terminated string index2997 /// name: NullTerminatedString, // null terminated string index
3000 /// - 0 means comptime or usingnamespace decl.2998 /// - 0 means comptime or usingnamespace decl.
3001 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace2999 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
3002 /// - 1 means test decl with no name.3000 /// - 1 means test decl with no name.
3003 /// - if there is a 0 byte at the position `name` indexes, it indicates3001 /// - if there is a 0 byte at the position `name` indexes, it indicates
3004 /// this is a test decl, and the name starts at `name+1`.3002 /// this is a test decl, and the name starts at `name+1`.
3005 /// value: Index,3003 /// value: Index,
3006 /// doc_comment: u32, // 0 if no doc_comment3004 /// doc_comment: u32, // .empty if no doc_comment
3007 /// align: Ref, // if corresponding bit is set3005 /// align: Ref, // if corresponding bit is set
3008 /// link_section_or_address_space: { // if corresponding bit is set.3006 /// link_section_or_address_space: { // if corresponding bit is set.
3009 /// link_section: Ref,3007 /// link_section: Ref,
...@@ -3015,7 +3013,7 @@ pub const Inst = struct {...@@ -3015,7 +3013,7 @@ pub const Inst = struct {
3015 /// - the bit is whether corresponding field has an value expression3013 /// - the bit is whether corresponding field has an value expression
3016 /// 9. fields: { // for every fields_len3014 /// 9. fields: { // for every fields_len
3017 /// field_name: u32,3015 /// field_name: u32,
3018 /// doc_comment: u32, // 0 if no doc_comment3016 /// doc_comment: u32, // .empty if no doc_comment
3019 /// value: Ref, // if corresponding bit is set3017 /// value: Ref, // if corresponding bit is set
3020 /// }3018 /// }
3021 pub const EnumDecl = struct {3019 pub const EnumDecl = struct {
...@@ -3046,14 +3044,14 @@ pub const Inst = struct {...@@ -3046,14 +3044,14 @@ pub const Inst = struct {
3046 /// 6. decl: { // for every decls_len3044 /// 6. decl: { // for every decls_len
3047 /// src_hash: [4]u32, // hash of source bytes3045 /// src_hash: [4]u32, // hash of source bytes
3048 /// line: u32, // line number of decl, relative to parent3046 /// line: u32, // line number of decl, relative to parent
3049 /// name: u32, // null terminated string index3047 /// name: NullTerminatedString, // null terminated string index
3050 /// - 0 means comptime or usingnamespace decl.3048 /// - 0 means comptime or usingnamespace decl.
3051 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace3049 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
3052 /// - 1 means test decl with no name.3050 /// - 1 means test decl with no name.
3053 /// - if there is a 0 byte at the position `name` indexes, it indicates3051 /// - if there is a 0 byte at the position `name` indexes, it indicates
3054 /// this is a test decl, and the name starts at `name+1`.3052 /// this is a test decl, and the name starts at `name+1`.
3055 /// value: Index,3053 /// value: Index,
3056 /// doc_comment: u32, // 0 if no doc comment3054 /// doc_comment: NullTerminatedString, // .empty if no doc comment
3057 /// align: Ref, // if corresponding bit is set3055 /// align: Ref, // if corresponding bit is set
3058 /// link_section_or_address_space: { // if corresponding bit is set.3056 /// link_section_or_address_space: { // if corresponding bit is set.
3059 /// link_section: Ref,3057 /// link_section: Ref,
...@@ -3068,8 +3066,8 @@ pub const Inst = struct {...@@ -3068,8 +3066,8 @@ pub const Inst = struct {
3068 /// 0b0X00: whether corresponding field has a tag value expression3066 /// 0b0X00: whether corresponding field has a tag value expression
3069 /// 0bX000: unused3067 /// 0bX000: unused
3070 /// 9. fields: { // for every fields_len3068 /// 9. fields: { // for every fields_len
3071 /// field_name: u32, // null terminated string index3069 /// field_name: NullTerminatedString, // null terminated string index
3072 /// doc_comment: u32, // 0 if no doc comment3070 /// doc_comment: NullTerminatedString, // .empty if no doc comment
3073 /// field_type: Ref, // if corresponding bit is set3071 /// field_type: Ref, // if corresponding bit is set
3074 /// - if none, means `anytype`.3072 /// - if none, means `anytype`.
3075 /// align: Ref, // if corresponding bit is set3073 /// align: Ref, // if corresponding bit is set
...@@ -3108,14 +3106,14 @@ pub const Inst = struct {...@@ -3108,14 +3106,14 @@ pub const Inst = struct {
3108 /// 3. decl: { // for every decls_len3106 /// 3. decl: { // for every decls_len
3109 /// src_hash: [4]u32, // hash of source bytes3107 /// src_hash: [4]u32, // hash of source bytes
3110 /// line: u32, // line number of decl, relative to parent3108 /// line: u32, // line number of decl, relative to parent
3111 /// name: u32, // null terminated string index3109 /// name: NullTerminatedString, // null terminated string index
3112 /// - 0 means comptime or usingnamespace decl.3110 /// - 0 means comptime or usingnamespace decl.
3113 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace3111 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
3114 /// - 1 means test decl with no name.3112 /// - 1 means test decl with no name.
3115 /// - if there is a 0 byte at the position `name` indexes, it indicates3113 /// - if there is a 0 byte at the position `name` indexes, it indicates
3116 /// this is a test decl, and the name starts at `name+1`.3114 /// this is a test decl, and the name starts at `name+1`.
3117 /// value: Index,3115 /// value: Index,
3118 /// doc_comment: u32, // 0 if no doc comment,3116 /// doc_comment: NullTerminatedString, // .empty if no doc comment,
3119 /// align: Ref, // if corresponding bit is set3117 /// align: Ref, // if corresponding bit is set
3120 /// link_section_or_address_space: { // if corresponding bit is set.3118 /// link_section_or_address_space: { // if corresponding bit is set.
3121 /// link_section: Ref,3119 /// link_section: Ref,
...@@ -3133,8 +3131,8 @@ pub const Inst = struct {...@@ -3133,8 +3131,8 @@ pub const Inst = struct {
31333131
3134 /// Trailing:3132 /// Trailing:
3135 /// { // for every fields_len3133 /// { // for every fields_len
3136 /// field_name: u32 // null terminated string index3134 /// field_name: NullTerminatedString // null terminated string index
3137 /// doc_comment: u32 // null terminated string index3135 /// doc_comment: NullTerminatedString // null terminated string index
3138 /// }3136 /// }
3139 pub const ErrorSetDecl = struct {3137 pub const ErrorSetDecl = struct {
3140 fields_len: u32,3138 fields_len: u32,
...@@ -3177,7 +3175,7 @@ pub const Inst = struct {...@@ -3177,7 +3175,7 @@ pub const Inst = struct {
31773175
3178 pub const Item = struct {3176 pub const Item = struct {
3179 /// Null-terminated string table index.3177 /// Null-terminated string table index.
3180 field_name: u32,3178 field_name: NullTerminatedString,
3181 /// The field init expression to be used as the field value.3179 /// The field init expression to be used as the field value.
3182 init: Ref,3180 init: Ref,
3183 };3181 };
...@@ -3186,7 +3184,7 @@ pub const Inst = struct {...@@ -3186,7 +3184,7 @@ pub const Inst = struct {
3186 pub const FieldType = struct {3184 pub const FieldType = struct {
3187 container_type: Ref,3185 container_type: Ref,
3188 /// Offset into `string_bytes`, null terminated.3186 /// Offset into `string_bytes`, null terminated.
3189 name_start: u32,3187 name_start: NullTerminatedString,
3190 };3188 };
31913189
3192 pub const FieldTypeRef = struct {3190 pub const FieldTypeRef = struct {
...@@ -3266,9 +3264,9 @@ pub const Inst = struct {...@@ -3266,9 +3264,9 @@ pub const Inst = struct {
3266 /// Trailing: inst: Index // for every body_len3264 /// Trailing: inst: Index // for every body_len
3267 pub const Param = struct {3265 pub const Param = struct {
3268 /// Null-terminated string index.3266 /// Null-terminated string index.
3269 name: u32,3267 name: NullTerminatedString,
3270 /// 0 if no doc comment3268 /// Null-terminated string index.
3271 doc_comment: u32,3269 doc_comment: NullTerminatedString,
3272 /// The body contains the type of the parameter.3270 /// The body contains the type of the parameter.
3273 body_len: u32,3271 body_len: u32,
3274 };3272 };
...@@ -3293,7 +3291,7 @@ pub const Inst = struct {...@@ -3293,7 +3291,7 @@ pub const Inst = struct {
3293 /// If omitted, this is referring to a Decl via identifier, e.g. `a`.3291 /// If omitted, this is referring to a Decl via identifier, e.g. `a`.
3294 namespace: Ref,3292 namespace: Ref,
3295 /// Null-terminated string index.3293 /// Null-terminated string index.
3296 decl_name: u32,3294 decl_name: NullTerminatedString,
3297 options: Ref,3295 options: Ref,
3298 };3296 };
32993297
...@@ -3311,7 +3309,7 @@ pub const Inst = struct {...@@ -3311,7 +3309,7 @@ pub const Inst = struct {
3311 /// It's a payload index of another `Item`.3309 /// It's a payload index of another `Item`.
3312 pub const Item = struct {3310 pub const Item = struct {
3313 /// null terminated string index3311 /// null terminated string index
3314 msg: u32,3312 msg: NullTerminatedString,
3315 node: Ast.Node.Index,3313 node: Ast.Node.Index,
3316 /// If node is 0 then this will be populated.3314 /// If node is 0 then this will be populated.
3317 token: Ast.TokenIndex,3315 token: Ast.TokenIndex,
...@@ -3335,7 +3333,7 @@ pub const Inst = struct {...@@ -3335,7 +3333,7 @@ pub const Inst = struct {
33353333
3336 pub const Item = struct {3334 pub const Item = struct {
3337 /// null terminated string index3335 /// null terminated string index
3338 name: u32,3336 name: NullTerminatedString,
3339 /// points to the import name3337 /// points to the import name
3340 token: Ast.TokenIndex,3338 token: Ast.TokenIndex,
3341 };3339 };
...@@ -3412,7 +3410,7 @@ pub const DeclIterator = struct {...@@ -3412,7 +3410,7 @@ pub const DeclIterator = struct {
34123410
3413 const sub_index: ExtraIndex = @enumFromInt(it.extra_index);3411 const sub_index: ExtraIndex = @enumFromInt(it.extra_index);
3414 it.extra_index += 5; // src_hash(4) + line(1)3412 it.extra_index += 5; // src_hash(4) + line(1)
3415 const name = it.zir.nullTerminatedString(it.zir.extra[it.extra_index]);3413 const name = it.zir.nullTerminatedString(@enumFromInt(it.zir.extra[it.extra_index]));
3416 it.extra_index += 3; // name(1) + value(1) + doc_comment(1)3414 it.extra_index += 3; // name(1) + value(1) + doc_comment(1)
3417 it.extra_index += @as(u1, @truncate(flags >> 2)); // align3415 it.extra_index += @as(u1, @truncate(flags >> 2)); // align
3418 it.extra_index += @as(u1, @truncate(flags >> 3)); // link_section3416 it.extra_index += @as(u1, @truncate(flags >> 3)); // link_section
src/print_zir.zig+28-26
...@@ -752,7 +752,7 @@ const Writer = struct {...@@ -752,7 +752,7 @@ const Writer = struct {
752 fn writeIntBig(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {752 fn writeIntBig(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
753 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str;753 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str;
754 const byte_count = inst_data.len * @sizeOf(std.math.big.Limb);754 const byte_count = inst_data.len * @sizeOf(std.math.big.Limb);
755 const limb_bytes = self.code.string_bytes[inst_data.start..][0..byte_count];755 const limb_bytes = self.code.nullTerminatedString(inst_data.start)[0..byte_count];
756 // limb_bytes is not aligned properly; we must allocate and copy the bytes756 // limb_bytes is not aligned properly; we must allocate and copy the bytes
757 // in order to accomplish this.757 // in order to accomplish this.
758 const limbs = try self.gpa.alloc(std.math.big.Limb, inst_data.len);758 const limbs = try self.gpa.alloc(std.math.big.Limb, inst_data.len);
...@@ -945,7 +945,7 @@ const Writer = struct {...@@ -945,7 +945,7 @@ const Writer = struct {
945 std.zig.fmtEscapes(self.code.nullTerminatedString(extra.data.name)),945 std.zig.fmtEscapes(self.code.nullTerminatedString(extra.data.name)),
946 });946 });
947947
948 if (extra.data.doc_comment != 0) {948 if (extra.data.doc_comment != .empty) {
949 try stream.writeAll("\n");949 try stream.writeAll("\n");
950 try self.writeDocComment(stream, extra.data.doc_comment);950 try self.writeDocComment(stream, extra.data.doc_comment);
951 try stream.writeByteNTimes(' ', self.indent);951 try stream.writeByteNTimes(' ', self.indent);
...@@ -1226,7 +1226,7 @@ const Writer = struct {...@@ -1226,7 +1226,7 @@ const Writer = struct {
12261226
1227 try self.writeFlag(stream, "volatile, ", is_volatile);1227 try self.writeFlag(stream, "volatile, ", is_volatile);
1228 if (tmpl_is_expr) {1228 if (tmpl_is_expr) {
1229 try self.writeInstRef(stream, @as(Zir.Inst.Ref, @enumFromInt(extra.data.asm_source)));1229 try self.writeInstRef(stream, @enumFromInt(@intFromEnum(extra.data.asm_source)));
1230 try stream.writeAll(", ");1230 try stream.writeAll(", ");
1231 } else {1231 } else {
1232 const asm_source = self.code.nullTerminatedString(extra.data.asm_source);1232 const asm_source = self.code.nullTerminatedString(extra.data.asm_source);
...@@ -1281,7 +1281,7 @@ const Writer = struct {...@@ -1281,7 +1281,7 @@ const Writer = struct {
1281 while (i < clobbers_len) : (i += 1) {1281 while (i < clobbers_len) : (i += 1) {
1282 const str_index = self.code.extra[extra_i];1282 const str_index = self.code.extra[extra_i];
1283 extra_i += 1;1283 extra_i += 1;
1284 const clobber = self.code.nullTerminatedString(str_index);1284 const clobber = self.code.nullTerminatedString(@enumFromInt(str_index));
1285 try stream.print("{}", .{std.zig.fmtId(clobber)});1285 try stream.print("{}", .{std.zig.fmtId(clobber)});
1286 if (i + 1 < clobbers_len) {1286 if (i + 1 < clobbers_len) {
1287 try stream.writeAll(", ");1287 try stream.writeAll(", ");
...@@ -1466,12 +1466,12 @@ const Writer = struct {...@@ -1466,12 +1466,12 @@ const Writer = struct {
1466 const fields_per_u32 = 32 / bits_per_field;1466 const fields_per_u32 = 32 / bits_per_field;
1467 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;1467 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;
1468 const Field = struct {1468 const Field = struct {
1469 doc_comment_index: u32,1469 doc_comment_index: Zir.NullTerminatedString,
1470 type_len: u32 = 0,1470 type_len: u32 = 0,
1471 align_len: u32 = 0,1471 align_len: u32 = 0,
1472 init_len: u32 = 0,1472 init_len: u32 = 0,
1473 type: Zir.Inst.Ref = .none,1473 type: Zir.Inst.Ref = .none,
1474 name: u32,1474 name: Zir.NullTerminatedString,
1475 is_comptime: bool,1475 is_comptime: bool,
1476 };1476 };
1477 const fields = try self.arena.alloc(Field, fields_len);1477 const fields = try self.arena.alloc(Field, fields_len);
...@@ -1494,24 +1494,24 @@ const Writer = struct {...@@ -1494,24 +1494,24 @@ const Writer = struct {
1494 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;1494 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;
1495 cur_bit_bag >>= 1;1495 cur_bit_bag >>= 1;
14961496
1497 var field_name: u32 = 0;1497 var field_name_index: Zir.NullTerminatedString = .empty;
1498 if (!small.is_tuple) {1498 if (!small.is_tuple) {
1499 field_name = self.code.extra[extra_index];1499 field_name_index = @enumFromInt(self.code.extra[extra_index]);
1500 extra_index += 1;1500 extra_index += 1;
1501 }1501 }
1502 const doc_comment_index = self.code.extra[extra_index];1502 const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
1503 extra_index += 1;1503 extra_index += 1;
15041504
1505 fields[field_i] = .{1505 fields[field_i] = .{
1506 .doc_comment_index = doc_comment_index,1506 .doc_comment_index = doc_comment_index,
1507 .is_comptime = is_comptime,1507 .is_comptime = is_comptime,
1508 .name = field_name,1508 .name = field_name_index,
1509 };1509 };
15101510
1511 if (has_type_body) {1511 if (has_type_body) {
1512 fields[field_i].type_len = self.code.extra[extra_index];1512 fields[field_i].type_len = self.code.extra[extra_index];
1513 } else {1513 } else {
1514 fields[field_i].type = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index]));1514 fields[field_i].type = @enumFromInt(self.code.extra[extra_index]);
1515 }1515 }
1516 extra_index += 1;1516 extra_index += 1;
15171517
...@@ -1536,7 +1536,7 @@ const Writer = struct {...@@ -1536,7 +1536,7 @@ const Writer = struct {
1536 try self.writeDocComment(stream, field.doc_comment_index);1536 try self.writeDocComment(stream, field.doc_comment_index);
1537 try stream.writeByteNTimes(' ', self.indent);1537 try stream.writeByteNTimes(' ', self.indent);
1538 try self.writeFlag(stream, "comptime ", field.is_comptime);1538 try self.writeFlag(stream, "comptime ", field.is_comptime);
1539 if (field.name != 0) {1539 if (field.name != .empty) {
1540 const field_name = self.code.nullTerminatedString(field.name);1540 const field_name = self.code.nullTerminatedString(field.name);
1541 try stream.print("{}: ", .{std.zig.fmtId(field_name)});1541 try stream.print("{}: ", .{std.zig.fmtId(field_name)});
1542 } else {1542 } else {
...@@ -1684,9 +1684,10 @@ const Writer = struct {...@@ -1684,9 +1684,10 @@ const Writer = struct {
16841684
1685 _ = unused;1685 _ = unused;
16861686
1687 const field_name = self.code.nullTerminatedString(self.code.extra[extra_index]);1687 const field_name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
1688 const field_name = self.code.nullTerminatedString(field_name_index);
1688 extra_index += 1;1689 extra_index += 1;
1689 const doc_comment_index = self.code.extra[extra_index];1690 const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
1690 extra_index += 1;1691 extra_index += 1;
16911692
1692 try self.writeDocComment(stream, doc_comment_index);1693 try self.writeDocComment(stream, doc_comment_index);
...@@ -1756,7 +1757,7 @@ const Writer = struct {...@@ -1756,7 +1757,7 @@ const Writer = struct {
1756 extra_index += 1;1757 extra_index += 1;
1757 const decl_index: Zir.Inst.Index = @enumFromInt(self.code.extra[extra_index]);1758 const decl_index: Zir.Inst.Index = @enumFromInt(self.code.extra[extra_index]);
1758 extra_index += 1;1759 extra_index += 1;
1759 const doc_comment_index = self.code.extra[extra_index];1760 const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
1760 extra_index += 1;1761 extra_index += 1;
17611762
1762 const align_inst: Zir.Inst.Ref = if (!has_align) .none else inst: {1763 const align_inst: Zir.Inst.Ref = if (!has_align) .none else inst: {
...@@ -1789,9 +1790,9 @@ const Writer = struct {...@@ -1789,9 +1790,9 @@ const Writer = struct {
1789 try stream.writeByteNTimes(' ', self.indent);1790 try stream.writeByteNTimes(' ', self.indent);
1790 try stream.print("[{d}] decltest {s}", .{ sub_index, self.code.nullTerminatedString(doc_comment_index) });1791 try stream.print("[{d}] decltest {s}", .{ sub_index, self.code.nullTerminatedString(doc_comment_index) });
1791 } else {1792 } else {
1792 const raw_decl_name = self.code.nullTerminatedString(decl_name_index);1793 const raw_decl_name = self.code.nullTerminatedString(@enumFromInt(decl_name_index));
1793 const decl_name = if (raw_decl_name.len == 0)1794 const decl_name = if (raw_decl_name.len == 0)
1794 self.code.nullTerminatedString(decl_name_index + 1)1795 self.code.nullTerminatedString(@enumFromInt(decl_name_index + 1))
1795 else1796 else
1796 raw_decl_name;1797 raw_decl_name;
1797 const test_str = if (raw_decl_name.len == 0) "test \"" else "";1798 const test_str = if (raw_decl_name.len == 0) "test \"" else "";
...@@ -1927,10 +1928,10 @@ const Writer = struct {...@@ -1927,10 +1928,10 @@ const Writer = struct {
1927 const has_tag_value = @as(u1, @truncate(cur_bit_bag)) != 0;1928 const has_tag_value = @as(u1, @truncate(cur_bit_bag)) != 0;
1928 cur_bit_bag >>= 1;1929 cur_bit_bag >>= 1;
19291930
1930 const field_name = self.code.nullTerminatedString(self.code.extra[extra_index]);1931 const field_name = self.code.nullTerminatedString(@enumFromInt(self.code.extra[extra_index]));
1931 extra_index += 1;1932 extra_index += 1;
19321933
1933 const doc_comment_index = self.code.extra[extra_index];1934 const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
1934 extra_index += 1;1935 extra_index += 1;
19351936
1936 try self.writeDocComment(stream, doc_comment_index);1937 try self.writeDocComment(stream, doc_comment_index);
...@@ -2011,9 +2012,9 @@ const Writer = struct {...@@ -2011,9 +2012,9 @@ const Writer = struct {
2011 var extra_index = @as(u32, @intCast(extra.end));2012 var extra_index = @as(u32, @intCast(extra.end));
2012 const extra_index_end = extra_index + (extra.data.fields_len * 2);2013 const extra_index_end = extra_index + (extra.data.fields_len * 2);
2013 while (extra_index < extra_index_end) : (extra_index += 2) {2014 while (extra_index < extra_index_end) : (extra_index += 2) {
2014 const str_index = self.code.extra[extra_index];2015 const name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
2015 const name = self.code.nullTerminatedString(str_index);2016 const name = self.code.nullTerminatedString(name_index);
2016 const doc_comment_index = self.code.extra[extra_index + 1];2017 const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index + 1]);
2017 try self.writeDocComment(stream, doc_comment_index);2018 try self.writeDocComment(stream, doc_comment_index);
2018 try stream.writeByteNTimes(' ', self.indent);2019 try stream.writeByteNTimes(' ', self.indent);
2019 try stream.print("{},\n", .{std.zig.fmtId(name)});2020 try stream.print("{},\n", .{std.zig.fmtId(name)});
...@@ -2292,7 +2293,7 @@ const Writer = struct {...@@ -2292,7 +2293,7 @@ const Writer = struct {
2292 var ret_ty_body: []const Zir.Inst.Index = &.{};2293 var ret_ty_body: []const Zir.Inst.Index = &.{};
22932294
2294 if (extra.data.bits.has_lib_name) {2295 if (extra.data.bits.has_lib_name) {
2295 const lib_name = self.code.nullTerminatedString(self.code.extra[extra_index]);2296 const lib_name = self.code.nullTerminatedString(@enumFromInt(self.code.extra[extra_index]));
2296 extra_index += 1;2297 extra_index += 1;
2297 try stream.print("lib_name=\"{}\", ", .{std.zig.fmtEscapes(lib_name)});2298 try stream.print("lib_name=\"{}\", ", .{std.zig.fmtEscapes(lib_name)});
2298 }2299 }
...@@ -2388,7 +2389,8 @@ const Writer = struct {...@@ -2388,7 +2389,8 @@ const Writer = struct {
23882389
2389 var extra_index: usize = extra.end;2390 var extra_index: usize = extra.end;
2390 if (small.has_lib_name) {2391 if (small.has_lib_name) {
2391 const lib_name = self.code.nullTerminatedString(self.code.extra[extra_index]);2392 const lib_name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
2393 const lib_name = self.code.nullTerminatedString(lib_name_index);
2392 extra_index += 1;2394 extra_index += 1;
2393 try stream.print(", lib_name=\"{}\"", .{std.zig.fmtEscapes(lib_name)});2395 try stream.print(", lib_name=\"{}\"", .{std.zig.fmtEscapes(lib_name)});
2394 }2396 }
...@@ -2740,8 +2742,8 @@ const Writer = struct {...@@ -2740,8 +2742,8 @@ const Writer = struct {
2740 }2742 }
2741 }2743 }
27422744
2743 fn writeDocComment(self: *Writer, stream: anytype, doc_comment_index: u32) !void {2745 fn writeDocComment(self: *Writer, stream: anytype, doc_comment_index: Zir.NullTerminatedString) !void {
2744 if (doc_comment_index != 0) {2746 if (doc_comment_index != .empty) {
2745 const doc_comment = self.code.nullTerminatedString(doc_comment_index);2747 const doc_comment = self.code.nullTerminatedString(doc_comment_index);
2746 var it = std.mem.tokenizeScalar(u8, doc_comment, '\n');2748 var it = std.mem.tokenizeScalar(u8, doc_comment, '\n');
2747 while (it.next()) |doc_line| {2749 while (it.next()) |doc_line| {