add type safety to ZIR for null terminated strings
This commit is contained in:
committed by
Andrew Kelley
parent
deed19496a
commit
0e856da224
186
src/AstGen.zig
186
src/AstGen.zig
@@ -46,7 +46,7 @@ fn_block: ?*GenZir = null,
|
||||
fn_var_args: bool = false,
|
||||
/// Maps string table indexes to the first `@import` ZIR instruction
|
||||
/// that uses this string as the operand.
|
||||
imports: std.AutoArrayHashMapUnmanaged(u32, Ast.TokenIndex) = .{},
|
||||
imports: std.AutoArrayHashMapUnmanaged(Zir.NullTerminatedString, Ast.TokenIndex) = .{},
|
||||
/// Used for temporary storage when building payloads.
|
||||
scratch: std.ArrayListUnmanaged(u32) = .{},
|
||||
/// 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 {
|
||||
|
||||
Zir.Inst.Ref,
|
||||
Zir.Inst.Index,
|
||||
Zir.NullTerminatedString,
|
||||
=> @intFromEnum(@field(extra, field.name)),
|
||||
|
||||
i32,
|
||||
@@ -1301,12 +1302,12 @@ fn fnProtoExpr(
|
||||
}
|
||||
} else false;
|
||||
|
||||
const param_name: u32 = if (param.name_token) |name_token| blk: {
|
||||
const param_name = if (param.name_token) |name_token| blk: {
|
||||
if (mem.eql(u8, "_", tree.tokenSlice(name_token)))
|
||||
break :blk 0;
|
||||
break :blk .empty;
|
||||
|
||||
break :blk try astgen.identAsString(name_token);
|
||||
} else 0;
|
||||
} else .empty;
|
||||
|
||||
if (is_anytype) {
|
||||
const name_token = param.name_token orelse param.anytype_ellipsis3.?;
|
||||
@@ -1379,7 +1380,7 @@ fn fnProtoExpr(
|
||||
|
||||
.param_block = block_inst,
|
||||
.body_gz = null,
|
||||
.lib_name = 0,
|
||||
.lib_name = .empty,
|
||||
.is_var_args = is_var_args,
|
||||
.is_inferred_error = false,
|
||||
.is_test = false,
|
||||
@@ -1725,7 +1726,7 @@ fn structInitExpr(
|
||||
var sfba = std.heap.stackFallback(256, astgen.arena);
|
||||
const sfba_allocator = sfba.get();
|
||||
|
||||
var duplicate_names = std.AutoArrayHashMap(u32, ArrayListUnmanaged(Ast.TokenIndex)).init(sfba_allocator);
|
||||
var duplicate_names = std.AutoArrayHashMap(Zir.NullTerminatedString, ArrayListUnmanaged(Ast.TokenIndex)).init(sfba_allocator);
|
||||
defer duplicate_names.deinit();
|
||||
try duplicate_names.ensureTotalCapacity(@intCast(struct_init.ast.fields.len));
|
||||
|
||||
@@ -4068,10 +4069,10 @@ fn fnDecl(
|
||||
}
|
||||
} else false;
|
||||
|
||||
const param_name: u32 = if (param.name_token) |name_token| blk: {
|
||||
const param_name: Zir.NullTerminatedString = if (param.name_token) |name_token| blk: {
|
||||
const name_bytes = tree.tokenSlice(name_token);
|
||||
if (mem.eql(u8, "_", name_bytes))
|
||||
break :blk 0;
|
||||
break :blk .empty;
|
||||
|
||||
const param_name = try astgen.identAsString(name_token);
|
||||
if (!is_extern) {
|
||||
@@ -4107,7 +4108,7 @@ fn fnDecl(
|
||||
}
|
||||
return astgen.failNode(param.type_expr, "missing parameter name", .{});
|
||||
}
|
||||
} else 0;
|
||||
} else .empty;
|
||||
|
||||
const param_inst = if (is_anytype) param: {
|
||||
const name_token = param.name_token orelse param.anytype_ellipsis3.?;
|
||||
@@ -4133,7 +4134,7 @@ fn fnDecl(
|
||||
break :param param_inst.toRef();
|
||||
};
|
||||
|
||||
if (param_name == 0 or is_extern) continue;
|
||||
if (param_name == .empty or is_extern) continue;
|
||||
|
||||
const sub_scope = try astgen.arena.create(Scope.LocalVal);
|
||||
sub_scope.* = .{
|
||||
@@ -4149,16 +4150,16 @@ fn fnDecl(
|
||||
break :is_var_args false;
|
||||
};
|
||||
|
||||
const lib_name: u32 = if (fn_proto.lib_name) |lib_name_token| blk: {
|
||||
const lib_name = if (fn_proto.lib_name) |lib_name_token| blk: {
|
||||
const lib_name_str = try astgen.strLitAsString(lib_name_token);
|
||||
const lib_name_slice = astgen.string_bytes.items[lib_name_str.index..][0..lib_name_str.len];
|
||||
const lib_name_slice = astgen.string_bytes.items[@intFromEnum(lib_name_str.index)..][0..lib_name_str.len];
|
||||
if (mem.indexOfScalar(u8, lib_name_slice, 0) != null) {
|
||||
return astgen.failTok(lib_name_token, "library name cannot contain null bytes", .{});
|
||||
} else if (lib_name_str.len == 0) {
|
||||
return astgen.failTok(lib_name_token, "library name cannot be empty", .{});
|
||||
}
|
||||
break :blk lib_name_str.index;
|
||||
} else 0;
|
||||
} else .empty;
|
||||
|
||||
const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1;
|
||||
const is_inferred_error = token_tags[maybe_bang] == .bang;
|
||||
@@ -4343,9 +4344,9 @@ fn fnDecl(
|
||||
const line_delta = decl_gz.decl_line - gz.decl_line;
|
||||
wip_members.appendToDecl(line_delta);
|
||||
}
|
||||
wip_members.appendToDecl(fn_name_str_index);
|
||||
wip_members.appendToDecl(@intFromEnum(fn_name_str_index));
|
||||
wip_members.appendToDecl(@intFromEnum(block_inst));
|
||||
wip_members.appendToDecl(doc_comment_index);
|
||||
wip_members.appendToDecl(@intFromEnum(doc_comment_index));
|
||||
}
|
||||
|
||||
fn globalVarDecl(
|
||||
@@ -4408,16 +4409,16 @@ fn globalVarDecl(
|
||||
break :blk true;
|
||||
} else false;
|
||||
|
||||
const lib_name: u32 = if (var_decl.lib_name) |lib_name_token| blk: {
|
||||
const lib_name = if (var_decl.lib_name) |lib_name_token| blk: {
|
||||
const lib_name_str = try astgen.strLitAsString(lib_name_token);
|
||||
const lib_name_slice = astgen.string_bytes.items[lib_name_str.index..][0..lib_name_str.len];
|
||||
const lib_name_slice = astgen.string_bytes.items[@intFromEnum(lib_name_str.index)..][0..lib_name_str.len];
|
||||
if (mem.indexOfScalar(u8, lib_name_slice, 0) != null) {
|
||||
return astgen.failTok(lib_name_token, "library name cannot contain null bytes", .{});
|
||||
} else if (lib_name_str.len == 0) {
|
||||
return astgen.failTok(lib_name_token, "library name cannot be empty", .{});
|
||||
}
|
||||
break :blk lib_name_str.index;
|
||||
} else 0;
|
||||
} else .empty;
|
||||
|
||||
const doc_comment_index = try astgen.docCommentAsString(var_decl.firstToken());
|
||||
|
||||
@@ -4452,7 +4453,7 @@ fn globalVarDecl(
|
||||
if (is_mutable) {
|
||||
const var_inst = try block_scope.addVar(.{
|
||||
.var_type = type_inst,
|
||||
.lib_name = 0,
|
||||
.lib_name = .empty,
|
||||
.align_inst = .none, // passed via the decls data
|
||||
.init = init_inst,
|
||||
.is_extern = false,
|
||||
@@ -4495,9 +4496,9 @@ fn globalVarDecl(
|
||||
const line_delta = block_scope.decl_line - gz.decl_line;
|
||||
wip_members.appendToDecl(line_delta);
|
||||
}
|
||||
wip_members.appendToDecl(name_str_index);
|
||||
wip_members.appendToDecl(@intFromEnum(name_str_index));
|
||||
wip_members.appendToDecl(@intFromEnum(block_inst));
|
||||
wip_members.appendToDecl(doc_comment_index); // doc_comment wip
|
||||
wip_members.appendToDecl(@intFromEnum(doc_comment_index)); // doc_comment wip
|
||||
if (align_inst != .none) {
|
||||
wip_members.appendToDecl(@intFromEnum(align_inst));
|
||||
}
|
||||
@@ -4640,7 +4641,7 @@ fn testDecl(
|
||||
const test_name_token = test_token + 1;
|
||||
const test_name_token_tag = token_tags[test_name_token];
|
||||
const is_decltest = test_name_token_tag == .identifier;
|
||||
const test_name: u32 = blk: {
|
||||
const test_name: Zir.NullTerminatedString = blk: {
|
||||
if (test_name_token_tag == .string_literal) {
|
||||
break :blk try astgen.testNameString(test_name_token);
|
||||
} else if (test_name_token_tag == .identifier) {
|
||||
@@ -4716,7 +4717,7 @@ fn testDecl(
|
||||
break :blk name_str_index;
|
||||
}
|
||||
// String table index 1 has a special meaning here of test decl with no name.
|
||||
break :blk 1;
|
||||
break :blk .unnamed_test_decl;
|
||||
};
|
||||
|
||||
var fn_block: GenZir = .{
|
||||
@@ -4766,7 +4767,7 @@ fn testDecl(
|
||||
.lbrace_column = lbrace_column,
|
||||
.param_block = block_inst,
|
||||
.body_gz = &fn_block,
|
||||
.lib_name = 0,
|
||||
.lib_name = .empty,
|
||||
.is_var_args = false,
|
||||
.is_inferred_error = false,
|
||||
.is_test = true,
|
||||
@@ -4789,10 +4790,10 @@ fn testDecl(
|
||||
if (is_decltest)
|
||||
wip_members.appendToDecl(2) // 2 here means that it is a decltest, look at doc comment for name
|
||||
else
|
||||
wip_members.appendToDecl(test_name);
|
||||
wip_members.appendToDecl(@intFromEnum(test_name));
|
||||
wip_members.appendToDecl(@intFromEnum(block_inst));
|
||||
if (is_decltest)
|
||||
wip_members.appendToDecl(test_name) // the doc comment on a decltest represents it's name
|
||||
wip_members.appendToDecl(@intFromEnum(test_name)) // the doc comment on a decltest represents it's name
|
||||
else
|
||||
wip_members.appendToDecl(0); // no doc comments on test decls
|
||||
}
|
||||
@@ -4945,7 +4946,7 @@ fn structDeclInner(
|
||||
var sfba = std.heap.stackFallback(256, astgen.arena);
|
||||
const sfba_allocator = sfba.get();
|
||||
|
||||
var duplicate_names = std.AutoArrayHashMap(u32, std.ArrayListUnmanaged(Ast.TokenIndex)).init(sfba_allocator);
|
||||
var duplicate_names = std.AutoArrayHashMap(Zir.NullTerminatedString, std.ArrayListUnmanaged(Ast.TokenIndex)).init(sfba_allocator);
|
||||
try duplicate_names.ensureTotalCapacity(field_count);
|
||||
|
||||
// When there aren't errors, use this to avoid a second iteration.
|
||||
@@ -4968,7 +4969,7 @@ fn structDeclInner(
|
||||
member.convertToNonTupleLike(astgen.tree.nodes);
|
||||
assert(!member.ast.tuple_like);
|
||||
|
||||
wip_members.appendToField(field_name);
|
||||
wip_members.appendToField(@intFromEnum(field_name));
|
||||
|
||||
const gop = try duplicate_names.getOrPut(field_name);
|
||||
|
||||
@@ -4984,7 +4985,7 @@ fn structDeclInner(
|
||||
}
|
||||
|
||||
const doc_comment_index = try astgen.docCommentAsString(member.firstToken());
|
||||
wip_members.appendToField(doc_comment_index);
|
||||
wip_members.appendToField(@intFromEnum(doc_comment_index));
|
||||
|
||||
if (member.ast.type_expr == 0) {
|
||||
return astgen.failTok(member.ast.main_token, "struct field missing type", .{});
|
||||
@@ -5196,10 +5197,10 @@ fn unionDeclInner(
|
||||
}
|
||||
|
||||
const field_name = try astgen.identAsString(member.ast.main_token);
|
||||
wip_members.appendToField(field_name);
|
||||
wip_members.appendToField(@intFromEnum(field_name));
|
||||
|
||||
const doc_comment_index = try astgen.docCommentAsString(member.firstToken());
|
||||
wip_members.appendToField(doc_comment_index);
|
||||
wip_members.appendToField(@intFromEnum(doc_comment_index));
|
||||
|
||||
const have_type = member.ast.type_expr != 0;
|
||||
const have_align = member.ast.align_expr != 0;
|
||||
@@ -5475,10 +5476,10 @@ fn containerDecl(
|
||||
assert(member.ast.align_expr == 0);
|
||||
|
||||
const field_name = try astgen.identAsString(member.ast.main_token);
|
||||
wip_members.appendToField(field_name);
|
||||
wip_members.appendToField(@intFromEnum(field_name));
|
||||
|
||||
const doc_comment_index = try astgen.docCommentAsString(member.firstToken());
|
||||
wip_members.appendToField(doc_comment_index);
|
||||
wip_members.appendToField(@intFromEnum(doc_comment_index));
|
||||
|
||||
const have_value = member.ast.value_expr != 0;
|
||||
wip_members.nextField(bits_per_field, .{have_value});
|
||||
@@ -5665,7 +5666,7 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi
|
||||
const payload_index = try reserveExtra(astgen, @typeInfo(Zir.Inst.ErrorSetDecl).Struct.fields.len);
|
||||
var fields_len: usize = 0;
|
||||
{
|
||||
var idents: std.AutoHashMapUnmanaged(u32, Ast.TokenIndex) = .{};
|
||||
var idents: std.AutoHashMapUnmanaged(Zir.NullTerminatedString, Ast.TokenIndex) = .{};
|
||||
defer idents.deinit(gpa);
|
||||
|
||||
const error_token = main_tokens[node];
|
||||
@@ -5695,9 +5696,9 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi
|
||||
gop.value_ptr.* = tok_i;
|
||||
|
||||
try astgen.extra.ensureUnusedCapacity(gpa, 2);
|
||||
astgen.extra.appendAssumeCapacity(str_index);
|
||||
astgen.extra.appendAssumeCapacity(@intFromEnum(str_index));
|
||||
const doc_comment_index = try astgen.docCommentAsString(tok_i);
|
||||
astgen.extra.appendAssumeCapacity(doc_comment_index);
|
||||
astgen.extra.appendAssumeCapacity(@intFromEnum(doc_comment_index));
|
||||
fields_len += 1;
|
||||
},
|
||||
.r_brace => break,
|
||||
@@ -6372,7 +6373,7 @@ fn whileExpr(
|
||||
then_scope.instructions_top = GenZir.unstacked_top;
|
||||
defer then_scope.unstack();
|
||||
|
||||
var dbg_var_name: ?u32 = null;
|
||||
var dbg_var_name: Zir.NullTerminatedString = .empty;
|
||||
var dbg_var_inst: Zir.Inst.Ref = undefined;
|
||||
var opt_payload_inst: Zir.Inst.OptionalIndex = .none;
|
||||
var payload_val_scope: Scope.LocalVal = undefined;
|
||||
@@ -6464,7 +6465,7 @@ fn whileExpr(
|
||||
if (opt_payload_inst.unwrap()) |payload_inst| {
|
||||
try then_scope.instructions.append(astgen.gpa, payload_inst);
|
||||
}
|
||||
if (dbg_var_name) |name| try then_scope.addDbgVar(.dbg_var_val, name, dbg_var_inst);
|
||||
if (dbg_var_name != .empty) try then_scope.addDbgVar(.dbg_var_val, dbg_var_name, dbg_var_inst);
|
||||
try then_scope.instructions.append(astgen.gpa, continue_block);
|
||||
// This code could be improved to avoid emitting the continue expr when there
|
||||
// are no jumps to it. This happens when the last statement of a while body is noreturn
|
||||
@@ -7069,9 +7070,9 @@ fn switchExpr(
|
||||
const is_multi_case = case.ast.values.len > 1 or
|
||||
(case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .switch_range);
|
||||
|
||||
var dbg_var_name: ?u32 = null;
|
||||
var dbg_var_name: Zir.NullTerminatedString = .empty;
|
||||
var dbg_var_inst: Zir.Inst.Ref = undefined;
|
||||
var dbg_var_tag_name: ?u32 = null;
|
||||
var dbg_var_tag_name: Zir.NullTerminatedString = .empty;
|
||||
var dbg_var_tag_inst: Zir.Inst.Ref = undefined;
|
||||
var has_tag_capture = false;
|
||||
var capture_val_scope: Scope.LocalVal = undefined;
|
||||
@@ -7193,11 +7194,11 @@ fn switchExpr(
|
||||
defer case_scope.unstack();
|
||||
|
||||
try case_scope.addDbgBlockBegin();
|
||||
if (dbg_var_name) |some| {
|
||||
try case_scope.addDbgVar(.dbg_var_val, some, dbg_var_inst);
|
||||
if (dbg_var_name != .empty) {
|
||||
try case_scope.addDbgVar(.dbg_var_val, dbg_var_name, dbg_var_inst);
|
||||
}
|
||||
if (dbg_var_tag_name) |some| {
|
||||
try case_scope.addDbgVar(.dbg_var_val, some, dbg_var_tag_inst);
|
||||
if (dbg_var_tag_name != .empty) {
|
||||
try case_scope.addDbgVar(.dbg_var_val, dbg_var_tag_name, dbg_var_tag_inst);
|
||||
}
|
||||
const target_expr_node = case.ast.target_expr;
|
||||
const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node);
|
||||
@@ -7858,7 +7859,7 @@ fn asmExpr(
|
||||
const node_tags = tree.nodes.items(.tag);
|
||||
const token_tags = tree.tokens.items(.tag);
|
||||
|
||||
const TagAndTmpl = struct { tag: Zir.Inst.Extended, tmpl: u32 };
|
||||
const TagAndTmpl = struct { tag: Zir.Inst.Extended, tmpl: Zir.NullTerminatedString };
|
||||
const tag_and_tmpl: TagAndTmpl = switch (node_tags[full.ast.template]) {
|
||||
.string_literal => .{
|
||||
.tag = .@"asm",
|
||||
@@ -7870,7 +7871,7 @@ fn asmExpr(
|
||||
},
|
||||
else => .{
|
||||
.tag = .asm_expr,
|
||||
.tmpl = @intFromEnum(try comptimeExpr(gz, scope, .{ .rl = .none }, full.ast.template)),
|
||||
.tmpl = @enumFromInt(@intFromEnum(try comptimeExpr(gz, scope, .{ .rl = .none }, full.ast.template))),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -7956,7 +7957,7 @@ fn asmExpr(
|
||||
if (clobber_i >= clobbers_buffer.len) {
|
||||
return astgen.failTok(tok_i, "too many asm clobbers", .{});
|
||||
}
|
||||
clobbers_buffer[clobber_i] = (try astgen.strLitAsString(tok_i)).index;
|
||||
clobbers_buffer[clobber_i] = @intFromEnum((try astgen.strLitAsString(tok_i)).index);
|
||||
clobber_i += 1;
|
||||
tok_i += 1;
|
||||
switch (token_tags[tok_i]) {
|
||||
@@ -8290,7 +8291,7 @@ fn builtinCall(
|
||||
}
|
||||
const str_lit_token = main_tokens[operand_node];
|
||||
const str = try astgen.strLitAsString(str_lit_token);
|
||||
const str_slice = astgen.string_bytes.items[str.index..][0..str.len];
|
||||
const str_slice = astgen.string_bytes.items[@intFromEnum(str.index)..][0..str.len];
|
||||
if (mem.indexOfScalar(u8, str_slice, 0) != null) {
|
||||
return astgen.failTok(str_lit_token, "import path cannot contain null bytes", .{});
|
||||
} else if (str.len == 0) {
|
||||
@@ -8346,7 +8347,7 @@ fn builtinCall(
|
||||
// This function causes a Decl to be exported. The first parameter is not an expression,
|
||||
// but an identifier of the Decl to be exported.
|
||||
var namespace: Zir.Inst.Ref = .none;
|
||||
var decl_name: u32 = 0;
|
||||
var decl_name: Zir.NullTerminatedString = .empty;
|
||||
switch (node_tags[params[0]]) {
|
||||
.identifier => {
|
||||
const ident_token = main_tokens[params[0]];
|
||||
@@ -9263,7 +9264,7 @@ const Callee = union(enum) {
|
||||
/// promote the lvalue to an address if the first parameter requires it.
|
||||
obj_ptr: Zir.Inst.Ref,
|
||||
/// Offset into `string_bytes`.
|
||||
field_name_start: u32,
|
||||
field_name_start: Zir.NullTerminatedString,
|
||||
},
|
||||
direct: Zir.Inst.Ref,
|
||||
};
|
||||
@@ -10529,7 +10530,7 @@ fn appendErrorNodeNotes(
|
||||
) Allocator.Error!void {
|
||||
@setCold(true);
|
||||
const string_bytes = &astgen.string_bytes;
|
||||
const msg: u32 = @intCast(string_bytes.items.len);
|
||||
const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len);
|
||||
try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);
|
||||
const notes_index: u32 = if (notes.len != 0) blk: {
|
||||
const notes_start = astgen.extra.items.len;
|
||||
@@ -10621,7 +10622,7 @@ fn appendErrorTokNotesOff(
|
||||
@setCold(true);
|
||||
const gpa = astgen.gpa;
|
||||
const string_bytes = &astgen.string_bytes;
|
||||
const msg: u32 = @intCast(string_bytes.items.len);
|
||||
const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len);
|
||||
try string_bytes.writer(gpa).print(format ++ "\x00", args);
|
||||
const notes_index: u32 = if (notes.len != 0) blk: {
|
||||
const notes_start = astgen.extra.items.len;
|
||||
@@ -10657,7 +10658,7 @@ fn errNoteTokOff(
|
||||
) Allocator.Error!u32 {
|
||||
@setCold(true);
|
||||
const string_bytes = &astgen.string_bytes;
|
||||
const msg: u32 = @intCast(string_bytes.items.len);
|
||||
const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len);
|
||||
try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);
|
||||
return astgen.addExtra(Zir.Inst.CompileErrors.Item{
|
||||
.msg = msg,
|
||||
@@ -10676,7 +10677,7 @@ fn errNoteNode(
|
||||
) Allocator.Error!u32 {
|
||||
@setCold(true);
|
||||
const string_bytes = &astgen.string_bytes;
|
||||
const msg: u32 = @intCast(string_bytes.items.len);
|
||||
const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len);
|
||||
try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args);
|
||||
return astgen.addExtra(Zir.Inst.CompileErrors.Item{
|
||||
.msg = msg,
|
||||
@@ -10687,7 +10688,7 @@ fn errNoteNode(
|
||||
});
|
||||
}
|
||||
|
||||
fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !u32 {
|
||||
fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !Zir.NullTerminatedString {
|
||||
const gpa = astgen.gpa;
|
||||
const string_bytes = &astgen.string_bytes;
|
||||
const str_index: u32 = @intCast(string_bytes.items.len);
|
||||
@@ -10700,19 +10701,19 @@ fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !u32 {
|
||||
});
|
||||
if (gop.found_existing) {
|
||||
string_bytes.shrinkRetainingCapacity(str_index);
|
||||
return gop.key_ptr.*;
|
||||
return @enumFromInt(gop.key_ptr.*);
|
||||
} else {
|
||||
gop.key_ptr.* = str_index;
|
||||
try string_bytes.append(gpa, 0);
|
||||
return str_index;
|
||||
return @enumFromInt(str_index);
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds a doc comment block to `string_bytes` by walking backwards from `end_token`.
|
||||
/// `end_token` must point at the first token after the last doc coment line.
|
||||
/// Returns 0 if no doc comment is present.
|
||||
fn docCommentAsString(astgen: *AstGen, end_token: Ast.TokenIndex) !u32 {
|
||||
if (end_token == 0) return 0;
|
||||
fn docCommentAsString(astgen: *AstGen, end_token: Ast.TokenIndex) !Zir.NullTerminatedString {
|
||||
if (end_token == 0) return .empty;
|
||||
|
||||
const token_tags = astgen.tree.tokens.items(.tag);
|
||||
|
||||
@@ -10723,6 +10724,7 @@ fn docCommentAsString(astgen: *AstGen, end_token: Ast.TokenIndex) !u32 {
|
||||
} else {
|
||||
tok += 1;
|
||||
}
|
||||
|
||||
return docCommentAsStringFromFirst(astgen, end_token, tok);
|
||||
}
|
||||
|
||||
@@ -10731,8 +10733,8 @@ fn docCommentAsStringFromFirst(
|
||||
astgen: *AstGen,
|
||||
end_token: Ast.TokenIndex,
|
||||
start_token: Ast.TokenIndex,
|
||||
) !u32 {
|
||||
if (start_token == end_token) return 0;
|
||||
) !Zir.NullTerminatedString {
|
||||
if (start_token == end_token) return .empty;
|
||||
|
||||
const gpa = astgen.gpa;
|
||||
const string_bytes = &astgen.string_bytes;
|
||||
@@ -10766,15 +10768,15 @@ fn docCommentAsStringFromFirst(
|
||||
|
||||
if (gop.found_existing) {
|
||||
string_bytes.shrinkRetainingCapacity(str_index);
|
||||
return gop.key_ptr.*;
|
||||
return @enumFromInt(gop.key_ptr.*);
|
||||
} else {
|
||||
gop.key_ptr.* = str_index;
|
||||
try string_bytes.append(gpa, 0);
|
||||
return str_index;
|
||||
return @enumFromInt(str_index);
|
||||
}
|
||||
}
|
||||
|
||||
const IndexSlice = struct { index: u32, len: u32 };
|
||||
const IndexSlice = struct { index: Zir.NullTerminatedString, len: u32 };
|
||||
|
||||
fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice {
|
||||
const gpa = astgen.gpa;
|
||||
@@ -10791,7 +10793,7 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice {
|
||||
if (gop.found_existing) {
|
||||
string_bytes.shrinkRetainingCapacity(str_index);
|
||||
return IndexSlice{
|
||||
.index = gop.key_ptr.*,
|
||||
.index = @enumFromInt(gop.key_ptr.*),
|
||||
.len = @intCast(key.len),
|
||||
};
|
||||
} else {
|
||||
@@ -10801,7 +10803,7 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice {
|
||||
// be null terminated for that to work.
|
||||
try string_bytes.append(gpa, 0);
|
||||
return IndexSlice{
|
||||
.index = str_index,
|
||||
.index = @enumFromInt(str_index),
|
||||
.len = @intCast(key.len),
|
||||
};
|
||||
}
|
||||
@@ -10839,12 +10841,12 @@ fn strLitNodeAsString(astgen: *AstGen, node: Ast.Node.Index) !IndexSlice {
|
||||
const len = string_bytes.items.len - str_index;
|
||||
try string_bytes.append(gpa, 0);
|
||||
return IndexSlice{
|
||||
.index = @intCast(str_index),
|
||||
.index = @enumFromInt(str_index),
|
||||
.len = @intCast(len),
|
||||
};
|
||||
}
|
||||
|
||||
fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !u32 {
|
||||
fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !Zir.NullTerminatedString {
|
||||
const gpa = astgen.gpa;
|
||||
const string_bytes = &astgen.string_bytes;
|
||||
const str_index: u32 = @intCast(string_bytes.items.len);
|
||||
@@ -10858,7 +10860,7 @@ fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !u32 {
|
||||
return astgen.failTok(str_lit_token, "empty test name must be omitted", .{});
|
||||
}
|
||||
try string_bytes.append(gpa, 0);
|
||||
return str_index;
|
||||
return @enumFromInt(str_index);
|
||||
}
|
||||
|
||||
const Scope = struct {
|
||||
@@ -10933,7 +10935,7 @@ const Scope = struct {
|
||||
/// 0 means never discarded.
|
||||
discarded: Ast.TokenIndex = 0,
|
||||
/// String table index.
|
||||
name: u32,
|
||||
name: Zir.NullTerminatedString,
|
||||
id_cat: IdCat,
|
||||
};
|
||||
|
||||
@@ -10959,7 +10961,7 @@ const Scope = struct {
|
||||
/// If not, we know it can be `const`, so will emit a compile error if it is `var`.
|
||||
used_as_lvalue: bool = false,
|
||||
/// String table index.
|
||||
name: u32,
|
||||
name: Zir.NullTerminatedString,
|
||||
id_cat: IdCat,
|
||||
/// true means we find out during Sema whether the value is comptime.
|
||||
/// false means it is already known at AstGen the value is runtime-known.
|
||||
@@ -10985,7 +10987,7 @@ const Scope = struct {
|
||||
parent: *Scope,
|
||||
/// Maps string table index to the source location of declaration,
|
||||
/// for the purposes of reporting name shadowing compile errors.
|
||||
decls: std.AutoHashMapUnmanaged(u32, Ast.Node.Index) = .{},
|
||||
decls: std.AutoHashMapUnmanaged(Zir.NullTerminatedString, Ast.Node.Index) = .{},
|
||||
node: Ast.Node.Index,
|
||||
inst: Zir.Inst.Index,
|
||||
|
||||
@@ -11250,7 +11252,7 @@ const GenZir = struct {
|
||||
cc_ref: Zir.Inst.Ref,
|
||||
ret_ref: Zir.Inst.Ref,
|
||||
|
||||
lib_name: u32,
|
||||
lib_name: Zir.NullTerminatedString,
|
||||
noalias_bits: u32,
|
||||
is_var_args: bool,
|
||||
is_inferred_error: bool,
|
||||
@@ -11298,7 +11300,7 @@ const GenZir = struct {
|
||||
}
|
||||
const body_len = astgen.countBodyLenAfterFixups(body);
|
||||
|
||||
if (args.cc_ref != .none or args.lib_name != 0 or args.is_var_args or args.is_test or
|
||||
if (args.cc_ref != .none or args.lib_name != .empty or args.is_var_args or args.is_test or
|
||||
args.is_extern or args.align_ref != .none or args.section_ref != .none or
|
||||
args.addrspace_ref != .none or args.noalias_bits != 0 or args.is_noinline)
|
||||
{
|
||||
@@ -11322,7 +11324,7 @@ const GenZir = struct {
|
||||
fancyFnExprExtraLen(astgen, cc_body, args.cc_ref) +
|
||||
fancyFnExprExtraLen(astgen, ret_body, ret_ref) +
|
||||
body_len + src_locs.len +
|
||||
@intFromBool(args.lib_name != 0) +
|
||||
@intFromBool(args.lib_name != .empty) +
|
||||
@intFromBool(args.noalias_bits != 0),
|
||||
);
|
||||
const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.FuncFancy{
|
||||
@@ -11334,7 +11336,7 @@ const GenZir = struct {
|
||||
.is_test = args.is_test,
|
||||
.is_extern = args.is_extern,
|
||||
.is_noinline = args.is_noinline,
|
||||
.has_lib_name = args.lib_name != 0,
|
||||
.has_lib_name = args.lib_name != .empty,
|
||||
.has_any_noalias = args.noalias_bits != 0,
|
||||
|
||||
.has_align_ref = args.align_ref != .none,
|
||||
@@ -11350,8 +11352,8 @@ const GenZir = struct {
|
||||
.has_ret_ty_body = ret_body.len != 0,
|
||||
},
|
||||
});
|
||||
if (args.lib_name != 0) {
|
||||
astgen.extra.appendAssumeCapacity(args.lib_name);
|
||||
if (args.lib_name != .empty) {
|
||||
astgen.extra.appendAssumeCapacity(@intFromEnum(args.lib_name));
|
||||
}
|
||||
|
||||
const zir_datas = astgen.instructions.items(.data);
|
||||
@@ -11493,7 +11495,7 @@ const GenZir = struct {
|
||||
|
||||
fn addVar(gz: *GenZir, args: struct {
|
||||
align_inst: Zir.Inst.Ref,
|
||||
lib_name: u32,
|
||||
lib_name: Zir.NullTerminatedString,
|
||||
var_type: Zir.Inst.Ref,
|
||||
init: Zir.Inst.Ref,
|
||||
is_extern: bool,
|
||||
@@ -11509,15 +11511,15 @@ const GenZir = struct {
|
||||
try astgen.extra.ensureUnusedCapacity(
|
||||
gpa,
|
||||
@typeInfo(Zir.Inst.ExtendedVar).Struct.fields.len +
|
||||
@intFromBool(args.lib_name != 0) +
|
||||
@intFromBool(args.lib_name != .empty) +
|
||||
@intFromBool(args.align_inst != .none) +
|
||||
@intFromBool(args.init != .none),
|
||||
);
|
||||
const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.ExtendedVar{
|
||||
.var_type = args.var_type,
|
||||
});
|
||||
if (args.lib_name != 0) {
|
||||
astgen.extra.appendAssumeCapacity(args.lib_name);
|
||||
if (args.lib_name != .empty) {
|
||||
astgen.extra.appendAssumeCapacity(@intFromEnum(args.lib_name));
|
||||
}
|
||||
if (args.align_inst != .none) {
|
||||
astgen.extra.appendAssumeCapacity(@intFromEnum(args.align_inst));
|
||||
@@ -11532,7 +11534,7 @@ const GenZir = struct {
|
||||
.data = .{ .extended = .{
|
||||
.opcode = .variable,
|
||||
.small = @bitCast(Zir.Inst.ExtendedVar.Small{
|
||||
.has_lib_name = args.lib_name != 0,
|
||||
.has_lib_name = args.lib_name != .empty,
|
||||
.has_align = args.align_inst != .none,
|
||||
.has_init = args.init != .none,
|
||||
.is_extern = args.is_extern,
|
||||
@@ -11588,7 +11590,7 @@ const GenZir = struct {
|
||||
astgen.instructions.appendAssumeCapacity(.{
|
||||
.tag = .int_big,
|
||||
.data = .{ .str = .{
|
||||
.start = @intCast(astgen.string_bytes.items.len),
|
||||
.start = @enumFromInt(astgen.string_bytes.items.len),
|
||||
.len = @intCast(limbs.len),
|
||||
} },
|
||||
});
|
||||
@@ -11687,7 +11689,7 @@ const GenZir = struct {
|
||||
tag: Zir.Inst.Tag,
|
||||
/// Absolute token index. This function does the conversion to Decl offset.
|
||||
abs_tok_index: Ast.TokenIndex,
|
||||
name: u32,
|
||||
name: Zir.NullTerminatedString,
|
||||
first_doc_comment: ?Ast.TokenIndex,
|
||||
) !Zir.Inst.Index {
|
||||
const gpa = gz.astgen.gpa;
|
||||
@@ -11699,7 +11701,7 @@ const GenZir = struct {
|
||||
const doc_comment_index = if (first_doc_comment) |first|
|
||||
try gz.astgen.docCommentAsStringFromFirst(abs_tok_index, first)
|
||||
else
|
||||
0;
|
||||
.empty;
|
||||
|
||||
const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Param{
|
||||
.name = name,
|
||||
@@ -11847,7 +11849,7 @@ const GenZir = struct {
|
||||
fn addStrTok(
|
||||
gz: *GenZir,
|
||||
tag: Zir.Inst.Tag,
|
||||
str_index: u32,
|
||||
str_index: Zir.NullTerminatedString,
|
||||
/// Absolute token index. This function does the conversion to Decl offset.
|
||||
abs_tok_index: Ast.TokenIndex,
|
||||
) !Zir.Inst.Ref {
|
||||
@@ -12122,7 +12124,7 @@ const GenZir = struct {
|
||||
tag: Zir.Inst.Extended,
|
||||
/// Absolute node index. This function does the conversion to offset from Decl.
|
||||
node: Ast.Node.Index,
|
||||
asm_source: u32,
|
||||
asm_source: Zir.NullTerminatedString,
|
||||
output_type_bits: u32,
|
||||
is_volatile: bool,
|
||||
outputs: []const Zir.Inst.Asm.Output,
|
||||
@@ -12441,7 +12443,7 @@ const GenZir = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn addDbgVar(gz: *GenZir, tag: Zir.Inst.Tag, name: u32, inst: Zir.Inst.Ref) !void {
|
||||
fn addDbgVar(gz: *GenZir, tag: Zir.Inst.Tag, name: Zir.NullTerminatedString, inst: Zir.Inst.Ref) !void {
|
||||
if (gz.is_comptime) return;
|
||||
|
||||
_ = try gz.add(.{ .tag = tag, .data = .{
|
||||
@@ -12478,15 +12480,15 @@ const GenZir = struct {
|
||||
|
||||
/// This can only be for short-lived references; the memory becomes invalidated
|
||||
/// when another string is added.
|
||||
fn nullTerminatedString(astgen: AstGen, index: usize) [*:0]const u8 {
|
||||
return @ptrCast(astgen.string_bytes.items[index..]);
|
||||
fn nullTerminatedString(astgen: AstGen, index: Zir.NullTerminatedString) [*:0]const u8 {
|
||||
return @ptrCast(astgen.string_bytes.items[@intFromEnum(index)..]);
|
||||
}
|
||||
|
||||
/// Local variables shadowing detection, including function parameters.
|
||||
fn detectLocalShadowing(
|
||||
astgen: *AstGen,
|
||||
scope: *Scope,
|
||||
ident_name: u32,
|
||||
ident_name: Zir.NullTerminatedString,
|
||||
name_token: Ast.TokenIndex,
|
||||
token_bytes: []const u8,
|
||||
id_cat: Scope.IdCat,
|
||||
|
||||
107
src/Autodoc.zig
107
src/Autodoc.zig
@@ -447,7 +447,7 @@ fn generateZirData(self: *Autodoc, output_dir: std.fs.Dir) !void {
|
||||
const Scope = struct {
|
||||
parent: ?*Scope,
|
||||
map: std.AutoHashMapUnmanaged(
|
||||
u32, // index into the current file's string table (decl name)
|
||||
Zir.NullTerminatedString, // index into the current file's string table (decl name)
|
||||
*DeclStatus,
|
||||
) = .{},
|
||||
|
||||
@@ -464,7 +464,7 @@ const Scope = struct {
|
||||
/// Another reason is that in some places we use the pointer to uniquely
|
||||
/// refer to a decl, as we wait for it to be analyzed. This means that
|
||||
/// those pointers must stay stable.
|
||||
pub fn resolveDeclName(self: Scope, string_table_idx: u32, file: *File, inst: Zir.Inst.OptionalIndex) *DeclStatus {
|
||||
pub fn resolveDeclName(self: Scope, string_table_idx: Zir.NullTerminatedString, file: *File, inst: Zir.Inst.OptionalIndex) *DeclStatus {
|
||||
var cur: ?*const Scope = &self;
|
||||
return while (cur) |s| : (cur = s.parent) {
|
||||
break s.map.get(string_table_idx) orelse continue;
|
||||
@@ -482,7 +482,7 @@ const Scope = struct {
|
||||
pub fn insertDeclRef(
|
||||
self: *Scope,
|
||||
arena: std.mem.Allocator,
|
||||
decl_name_index: u32, // index into the current file's string table
|
||||
decl_name_index: Zir.NullTerminatedString, // index into the current file's string table
|
||||
decl_status: DeclStatus,
|
||||
) !void {
|
||||
const decl_status_ptr = try arena.create(DeclStatus);
|
||||
@@ -1250,7 +1250,7 @@ fn walkInstruction(
|
||||
// @check
|
||||
const str = data[@intFromEnum(inst)].str; //.get(file.zir);
|
||||
const byte_count = str.len * @sizeOf(std.math.big.Limb);
|
||||
const limb_bytes = file.zir.string_bytes[str.start..][0..byte_count];
|
||||
const limb_bytes = file.zir.string_bytes[@intFromEnum(str.start)..][0..byte_count];
|
||||
|
||||
const limbs = try self.arena.alloc(std.math.big.Limb, str.len);
|
||||
@memcpy(std.mem.sliceAsBytes(limbs)[0..limb_bytes.len], limb_bytes);
|
||||
@@ -2167,7 +2167,7 @@ fn walkInstruction(
|
||||
// present in json
|
||||
var sentinel: ?DocData.Expr = null;
|
||||
if (ptr.flags.has_sentinel) {
|
||||
const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
|
||||
const ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
|
||||
const ref_result = try self.walkRef(
|
||||
file,
|
||||
parent_scope,
|
||||
@@ -2182,7 +2182,7 @@ fn walkInstruction(
|
||||
|
||||
var @"align": ?DocData.Expr = null;
|
||||
if (ptr.flags.has_align) {
|
||||
const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
|
||||
const ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
|
||||
const ref_result = try self.walkRef(
|
||||
file,
|
||||
parent_scope,
|
||||
@@ -2196,7 +2196,7 @@ fn walkInstruction(
|
||||
}
|
||||
var address_space: ?DocData.Expr = null;
|
||||
if (ptr.flags.has_addrspace) {
|
||||
const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
|
||||
const ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
|
||||
const ref_result = try self.walkRef(
|
||||
file,
|
||||
parent_scope,
|
||||
@@ -2210,7 +2210,7 @@ fn walkInstruction(
|
||||
}
|
||||
const bit_start: ?DocData.Expr = null;
|
||||
if (ptr.flags.has_bit_range) {
|
||||
const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
|
||||
const ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
|
||||
const ref_result = try self.walkRef(
|
||||
file,
|
||||
parent_scope,
|
||||
@@ -2225,7 +2225,7 @@ fn walkInstruction(
|
||||
|
||||
var host_size: ?DocData.Expr = null;
|
||||
if (ptr.flags.has_bit_range) {
|
||||
const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
|
||||
const ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
|
||||
const ref_result = try self.walkRef(
|
||||
file,
|
||||
parent_scope,
|
||||
@@ -3041,10 +3041,10 @@ fn walkInstruction(
|
||||
);
|
||||
var idx = extra.end;
|
||||
for (fields) |*f| {
|
||||
const name = file.zir.nullTerminatedString(file.zir.extra[idx]);
|
||||
const name = file.zir.nullTerminatedString(@enumFromInt(file.zir.extra[idx]));
|
||||
idx += 1;
|
||||
|
||||
const docs = file.zir.nullTerminatedString(file.zir.extra[idx]);
|
||||
const docs = file.zir.nullTerminatedString(@enumFromInt(file.zir.extra[idx]));
|
||||
idx += 1;
|
||||
|
||||
f.* = .{
|
||||
@@ -3706,10 +3706,10 @@ fn walkInstruction(
|
||||
const has_value = @as(u1, @truncate(cur_bit_bag)) != 0;
|
||||
cur_bit_bag >>= 1;
|
||||
|
||||
const field_name_index = file.zir.extra[extra_index];
|
||||
const field_name_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
|
||||
const doc_comment_index = file.zir.extra[extra_index];
|
||||
const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
|
||||
const value_expr: ?DocData.Expr = if (has_value) blk: {
|
||||
@@ -3730,7 +3730,7 @@ fn walkInstruction(
|
||||
const field_name = file.zir.nullTerminatedString(field_name_index);
|
||||
|
||||
try field_name_indexes.append(self.arena, self.ast_nodes.items.len);
|
||||
const doc_comment: ?[]const u8 = if (doc_comment_index != 0)
|
||||
const doc_comment: ?[]const u8 = if (doc_comment_index != .empty)
|
||||
file.zir.nullTerminatedString(doc_comment_index)
|
||||
else
|
||||
null;
|
||||
@@ -4085,10 +4085,13 @@ fn analyzeAllDecls(
|
||||
{
|
||||
var it = original_it;
|
||||
while (it.next()) |d| {
|
||||
const decl_name_index = file.zir.extra[@intFromEnum(d.sub_index) + 5];
|
||||
const decl_name_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[@intFromEnum(d.sub_index) + 5]);
|
||||
switch (decl_name_index) {
|
||||
0, 1, 2 => continue,
|
||||
else => if (file.zir.string_bytes[decl_name_index] == 0) {
|
||||
.empty,
|
||||
.unnamed_test_decl,
|
||||
.decltest,
|
||||
=> continue,
|
||||
_ => if (file.zir.nullTerminatedString(decl_name_index).len == 0) {
|
||||
continue;
|
||||
},
|
||||
}
|
||||
@@ -4195,31 +4198,31 @@ fn analyzeDecl(
|
||||
// const line = file.zir.extra[extra_index];
|
||||
|
||||
extra_index += 1;
|
||||
const decl_name_index = file.zir.extra[extra_index];
|
||||
const decl_name_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]);
|
||||
|
||||
extra_index += 1;
|
||||
const value_index: Zir.Inst.Index = @enumFromInt(file.zir.extra[extra_index]);
|
||||
|
||||
extra_index += 1;
|
||||
const doc_comment_index = file.zir.extra[extra_index];
|
||||
const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]);
|
||||
|
||||
extra_index += 1;
|
||||
const align_inst: Zir.Inst.Ref = if (!has_align) .none else inst: {
|
||||
const inst = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
|
||||
const inst: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
break :inst inst;
|
||||
};
|
||||
_ = align_inst;
|
||||
|
||||
const section_inst: Zir.Inst.Ref = if (!has_section_or_addrspace) .none else inst: {
|
||||
const inst = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
|
||||
const inst: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
break :inst inst;
|
||||
};
|
||||
_ = section_inst;
|
||||
|
||||
const addrspace_inst: Zir.Inst.Ref = if (!has_section_or_addrspace) .none else inst: {
|
||||
const inst = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
|
||||
const inst: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
break :inst inst;
|
||||
};
|
||||
@@ -4230,9 +4233,9 @@ fn analyzeDecl(
|
||||
const decl_src = try self.srcLocInfo(file, value_pl_node.src_node, parent_src);
|
||||
|
||||
const name: []const u8 = switch (decl_name_index) {
|
||||
0, 1, 2 => unreachable, // comptime or usingnamespace decl, decltest
|
||||
else => blk: {
|
||||
if (file.zir.string_bytes[decl_name_index] == 0) {
|
||||
.empty, .unnamed_test_decl, .decltest => unreachable,
|
||||
_ => blk: {
|
||||
if (decl_name_index == .empty) {
|
||||
// test decl
|
||||
unreachable;
|
||||
}
|
||||
@@ -4240,7 +4243,7 @@ fn analyzeDecl(
|
||||
},
|
||||
};
|
||||
|
||||
const doc_comment: ?[]const u8 = if (doc_comment_index != 0)
|
||||
const doc_comment: ?[]const u8 = if (doc_comment_index != .empty)
|
||||
file.zir.nullTerminatedString(doc_comment_index)
|
||||
else
|
||||
null;
|
||||
@@ -4319,13 +4322,13 @@ fn analyzeUsingnamespaceDecl(
|
||||
|
||||
const is_pub = @as(u1, @truncate(d.flags)) != 0;
|
||||
const value_index: Zir.Inst.Index = @enumFromInt(file.zir.extra[@intFromEnum(d.sub_index) + 6]);
|
||||
const doc_comment_index = file.zir.extra[@intFromEnum(d.sub_index) + 7];
|
||||
const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[@intFromEnum(d.sub_index) + 7]);
|
||||
|
||||
// This is known to work because decl values are always block_inlines
|
||||
const value_pl_node = data[@intFromEnum(value_index)].pl_node;
|
||||
const decl_src = try self.srcLocInfo(file, value_pl_node.src_node, parent_src);
|
||||
|
||||
const doc_comment: ?[]const u8 = if (doc_comment_index != 0)
|
||||
const doc_comment: ?[]const u8 = if (doc_comment_index != .empty)
|
||||
file.zir.nullTerminatedString(doc_comment_index)
|
||||
else
|
||||
null;
|
||||
@@ -4379,14 +4382,14 @@ fn analyzeDecltest(
|
||||
const data = file.zir.instructions.items(.data);
|
||||
|
||||
const value_index = file.zir.extra[@intFromEnum(d.sub_index) + 6];
|
||||
const decl_name_index = file.zir.extra[@intFromEnum(d.sub_index) + 7];
|
||||
const decl_name_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[@intFromEnum(d.sub_index) + 7]);
|
||||
|
||||
const value_pl_node = data[value_index].pl_node;
|
||||
const decl_src = try self.srcLocInfo(file, value_pl_node.src_node, parent_src);
|
||||
|
||||
const test_source_code = try self.getBlockSource(file, parent_src, value_pl_node.src_node);
|
||||
|
||||
const decl_name: ?[]const u8 = if (decl_name_index != 0)
|
||||
const decl_name: ?[]const u8 = if (decl_name_index != .empty)
|
||||
file.zir.nullTerminatedString(decl_name_index)
|
||||
else
|
||||
null;
|
||||
@@ -5018,7 +5021,7 @@ fn analyzeFancyFunction(
|
||||
.param, .param_comptime => {
|
||||
const pl_tok = data[@intFromEnum(param_index)].pl_tok;
|
||||
const extra = file.zir.extraData(Zir.Inst.Param, pl_tok.payload_index);
|
||||
const doc_comment = if (extra.data.doc_comment != 0)
|
||||
const doc_comment = if (extra.data.doc_comment != .empty)
|
||||
file.zir.nullTerminatedString(extra.data.doc_comment)
|
||||
else
|
||||
"";
|
||||
@@ -5056,13 +5059,14 @@ fn analyzeFancyFunction(
|
||||
|
||||
var lib_name: []const u8 = "";
|
||||
if (extra.data.bits.has_lib_name) {
|
||||
lib_name = file.zir.nullTerminatedString(file.zir.extra[extra_index]);
|
||||
const lib_name_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]);
|
||||
lib_name = file.zir.nullTerminatedString(lib_name_index);
|
||||
extra_index += 1;
|
||||
}
|
||||
|
||||
var align_index: ?usize = null;
|
||||
if (extra.data.bits.has_align_ref) {
|
||||
const align_ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
|
||||
const align_ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
|
||||
align_index = self.exprs.items.len;
|
||||
_ = try self.walkRef(
|
||||
file,
|
||||
@@ -5086,7 +5090,7 @@ fn analyzeFancyFunction(
|
||||
|
||||
var addrspace_index: ?usize = null;
|
||||
if (extra.data.bits.has_addrspace_ref) {
|
||||
const addrspace_ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
|
||||
const addrspace_ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
|
||||
addrspace_index = self.exprs.items.len;
|
||||
_ = try self.walkRef(
|
||||
file,
|
||||
@@ -5110,7 +5114,7 @@ fn analyzeFancyFunction(
|
||||
|
||||
var section_index: ?usize = null;
|
||||
if (extra.data.bits.has_section_ref) {
|
||||
const section_ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
|
||||
const section_ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]);
|
||||
section_index = self.exprs.items.len;
|
||||
_ = try self.walkRef(
|
||||
file,
|
||||
@@ -5310,7 +5314,7 @@ fn analyzeFunction(
|
||||
.param, .param_comptime => {
|
||||
const pl_tok = data[@intFromEnum(param_index)].pl_tok;
|
||||
const extra = file.zir.extraData(Zir.Inst.Param, pl_tok.payload_index);
|
||||
const doc_comment = if (extra.data.doc_comment != 0)
|
||||
const doc_comment = if (extra.data.doc_comment != .empty)
|
||||
file.zir.nullTerminatedString(extra.data.doc_comment)
|
||||
else
|
||||
"";
|
||||
@@ -5497,14 +5501,11 @@ fn collectUnionFieldInfo(
|
||||
cur_bit_bag >>= 1;
|
||||
_ = unused;
|
||||
|
||||
const field_name = file.zir.nullTerminatedString(file.zir.extra[extra_index]);
|
||||
const field_name = file.zir.nullTerminatedString(@enumFromInt(file.zir.extra[extra_index]));
|
||||
extra_index += 1;
|
||||
const doc_comment_index = file.zir.extra[extra_index];
|
||||
const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
const field_type = if (has_type)
|
||||
@as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]))
|
||||
else
|
||||
.void_type;
|
||||
const field_type: Zir.Inst.Ref = if (has_type) @enumFromInt(file.zir.extra[extra_index]) else .void_type;
|
||||
if (has_type) extra_index += 1;
|
||||
|
||||
if (has_align) extra_index += 1;
|
||||
@@ -5526,7 +5527,7 @@ fn collectUnionFieldInfo(
|
||||
// ast node
|
||||
{
|
||||
try field_name_indexes.append(self.arena, self.ast_nodes.items.len);
|
||||
const doc_comment: ?[]const u8 = if (doc_comment_index != 0)
|
||||
const doc_comment: ?[]const u8 = if (doc_comment_index != .empty)
|
||||
file.zir.nullTerminatedString(doc_comment_index)
|
||||
else
|
||||
null;
|
||||
@@ -5559,8 +5560,8 @@ fn collectStructFieldInfo(
|
||||
const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;
|
||||
|
||||
const Field = struct {
|
||||
field_name: ?u32,
|
||||
doc_comment_index: u32,
|
||||
field_name: Zir.NullTerminatedString,
|
||||
doc_comment_index: Zir.NullTerminatedString,
|
||||
type_body_len: u32 = 0,
|
||||
align_body_len: u32 = 0,
|
||||
init_body_len: u32 = 0,
|
||||
@@ -5587,13 +5588,13 @@ fn collectStructFieldInfo(
|
||||
const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;
|
||||
cur_bit_bag >>= 1;
|
||||
|
||||
const field_name: ?u32 = if (!is_tuple) blk: {
|
||||
const field_name: Zir.NullTerminatedString = if (!is_tuple) blk: {
|
||||
const fname = file.zir.extra[extra_index];
|
||||
extra_index += 1;
|
||||
break :blk fname;
|
||||
} else null;
|
||||
break :blk @enumFromInt(fname);
|
||||
} else .empty;
|
||||
|
||||
const doc_comment_index = file.zir.extra[extra_index];
|
||||
const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
|
||||
fields[field_i] = .{
|
||||
@@ -5604,7 +5605,7 @@ fn collectStructFieldInfo(
|
||||
if (has_type_body) {
|
||||
fields[field_i].type_body_len = file.zir.extra[extra_index];
|
||||
} else {
|
||||
fields[field_i].type_ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index]));
|
||||
fields[field_i].type_ref = @enumFromInt(file.zir.extra[extra_index]);
|
||||
}
|
||||
extra_index += 1;
|
||||
|
||||
@@ -5686,12 +5687,12 @@ fn collectStructFieldInfo(
|
||||
// ast node
|
||||
{
|
||||
try field_name_indexes.append(self.arena, self.ast_nodes.items.len);
|
||||
const doc_comment: ?[]const u8 = if (field.doc_comment_index != 0)
|
||||
const doc_comment: ?[]const u8 = if (field.doc_comment_index != .empty)
|
||||
file.zir.nullTerminatedString(field.doc_comment_index)
|
||||
else
|
||||
null;
|
||||
const field_name: []const u8 = if (field.field_name) |f_name|
|
||||
file.zir.nullTerminatedString(f_name)
|
||||
const field_name: []const u8 = if (field.field_name != .empty)
|
||||
file.zir.nullTerminatedString(field.field_name)
|
||||
else
|
||||
"";
|
||||
|
||||
|
||||
@@ -4198,7 +4198,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
|
||||
|
||||
const line_off = zir.extra[decl_sub_index + 4];
|
||||
const line = iter.parent_decl.relativeToLine(line_off);
|
||||
const decl_name_index = zir.extra[decl_sub_index + 5];
|
||||
const decl_name_index: Zir.NullTerminatedString = @enumFromInt(zir.extra[decl_sub_index + 5]);
|
||||
const decl_doccomment_index = zir.extra[decl_sub_index + 7];
|
||||
const decl_zir_index = zir.extra[decl_sub_index + 6];
|
||||
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
|
||||
var is_named_test = false;
|
||||
var kind: Decl.Kind = .named;
|
||||
const decl_name: InternPool.NullTerminatedString = switch (decl_name_index) {
|
||||
0 => name: {
|
||||
.empty => name: {
|
||||
if (export_bit) {
|
||||
const i = iter.usingnamespace_index;
|
||||
iter.usingnamespace_index += 1;
|
||||
@@ -4221,23 +4221,23 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
|
||||
break :name try ip.getOrPutStringFmt(gpa, "comptime_{d}", .{i});
|
||||
}
|
||||
},
|
||||
1 => name: {
|
||||
.unnamed_test_decl => name: {
|
||||
const i = iter.unnamed_test_index;
|
||||
iter.unnamed_test_index += 1;
|
||||
kind = .@"test";
|
||||
break :name try ip.getOrPutStringFmt(gpa, "test_{d}", .{i});
|
||||
},
|
||||
2 => name: {
|
||||
.decltest => name: {
|
||||
is_named_test = true;
|
||||
const test_name = zir.nullTerminatedString(decl_doccomment_index);
|
||||
const test_name = zir.nullTerminatedString(@enumFromInt(decl_doccomment_index));
|
||||
kind = .@"test";
|
||||
break :name try ip.getOrPutStringFmt(gpa, "decltest.{s}", .{test_name});
|
||||
},
|
||||
else => name: {
|
||||
_ => name: {
|
||||
const raw_name = zir.nullTerminatedString(decl_name_index);
|
||||
if (raw_name.len == 0) {
|
||||
is_named_test = true;
|
||||
const test_name = zir.nullTerminatedString(decl_name_index + 1);
|
||||
const test_name = zir.nullTerminatedString(@enumFromInt(@intFromEnum(decl_name_index) + 1));
|
||||
kind = .@"test";
|
||||
break :name try ip.getOrPutStringFmt(gpa, "test.{s}", .{test_name});
|
||||
} else {
|
||||
@@ -4246,7 +4246,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
|
||||
},
|
||||
};
|
||||
|
||||
const is_exported = export_bit and decl_name_index != 0;
|
||||
const is_exported = export_bit and decl_name_index != .empty;
|
||||
if (kind == .@"usingnamespace") try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1);
|
||||
|
||||
// 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
|
||||
// test decls if in test mode, get analyzed.
|
||||
const decl_mod = namespace.file_scope.mod;
|
||||
const want_analysis = is_exported or switch (decl_name_index) {
|
||||
0 => true, // comptime or usingnamespace decl
|
||||
1 => blk: {
|
||||
.empty => true, // comptime or usingnamespace decl
|
||||
.unnamed_test_decl => blk: {
|
||||
// test decl with no name. Skip the part where we check against
|
||||
// the test name filter.
|
||||
if (!comp.config.is_test) break :blk false;
|
||||
|
||||
35
src/Sema.zig
35
src/Sema.zig
@@ -3044,7 +3044,8 @@ fn zirEnumDecl(
|
||||
const has_tag_value = @as(u1, @truncate(cur_bit_bag)) != 0;
|
||||
cur_bit_bag >>= 1;
|
||||
|
||||
const field_name_zir = sema.code.nullTerminatedString(sema.code.extra[extra_index]);
|
||||
const field_name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);
|
||||
const field_name_zir = sema.code.nullTerminatedString(field_name_index);
|
||||
extra_index += 1;
|
||||
|
||||
// doc comment
|
||||
@@ -3322,8 +3323,8 @@ fn zirErrorSetDecl(
|
||||
var extra_index: u32 = @intCast(extra.end);
|
||||
const extra_index_end = extra_index + (extra.data.fields_len * 2);
|
||||
while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string
|
||||
const str_index = sema.code.extra[extra_index];
|
||||
const name = sema.code.nullTerminatedString(str_index);
|
||||
const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);
|
||||
const name = sema.code.nullTerminatedString(name_index);
|
||||
const name_ip = try mod.intern_pool.getOrPutString(gpa, name);
|
||||
_ = try mod.getErrorValue(name_ip);
|
||||
const result = names.getOrPutAssumeCapacity(name_ip);
|
||||
@@ -5522,7 +5523,7 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
|
||||
const mod = sema.mod;
|
||||
const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].str;
|
||||
const byte_count = int.len * @sizeOf(std.math.big.Limb);
|
||||
const limb_bytes = sema.code.string_bytes[int.start..][0..byte_count];
|
||||
const limb_bytes = sema.code.string_bytes[@intFromEnum(int.start)..][0..byte_count];
|
||||
|
||||
// TODO: this allocation and copy is only needed because the limbs may be unaligned.
|
||||
// If ZIR is adjusted so that big int limbs are guaranteed to be aligned, these
|
||||
@@ -7999,11 +8000,11 @@ fn instantiateGenericCall(
|
||||
} },
|
||||
}));
|
||||
const param_name: Zir.NullTerminatedString = switch (param_tag) {
|
||||
.param_anytype => @enumFromInt(fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].str_tok.start),
|
||||
.param_anytype => fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].str_tok.start,
|
||||
.param => name: {
|
||||
const inst_data = fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].pl_tok;
|
||||
const extra = fn_zir.extraData(Zir.Inst.Param, inst_data.payload_index);
|
||||
break :name @enumFromInt(extra.data.name);
|
||||
break :name extra.data.name;
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
@@ -9616,7 +9617,7 @@ fn finishFunc(
|
||||
.param_anytype => data[@intFromEnum(param_index)].str_tok.src(),
|
||||
else => unreachable,
|
||||
};
|
||||
const name = sema.code.nullTerminatedString2(name_nts);
|
||||
const name = sema.code.nullTerminatedString(name_nts);
|
||||
if (name.len != 0) {
|
||||
try sema.errNote(block, param_src, msg, "param '{s}' is required to be comptime", .{name});
|
||||
} else {
|
||||
@@ -9690,7 +9691,7 @@ fn zirParam(
|
||||
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_tok;
|
||||
const src = inst_data.src();
|
||||
const extra = sema.code.extraData(Zir.Inst.Param, inst_data.payload_index);
|
||||
const param_name: Zir.NullTerminatedString = @enumFromInt(extra.data.name);
|
||||
const param_name: Zir.NullTerminatedString = extra.data.name;
|
||||
const body = sema.code.bodySlice(extra.end, extra.data.body_len);
|
||||
|
||||
const param_ty = param_ty: {
|
||||
@@ -9781,7 +9782,7 @@ fn zirParamAnytype(
|
||||
comptime_syntax: bool,
|
||||
) CompileError!void {
|
||||
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok;
|
||||
const param_name: Zir.NullTerminatedString = @enumFromInt(inst_data.start);
|
||||
const param_name: Zir.NullTerminatedString = inst_data.start;
|
||||
|
||||
// We are evaluating a generic function without any comptime args provided.
|
||||
|
||||
@@ -16184,7 +16185,7 @@ fn zirAsm(
|
||||
const is_global_assembly = sema.func_index == .none;
|
||||
|
||||
const asm_source: []const u8 = if (tmpl_is_expr) blk: {
|
||||
const tmpl: Zir.Inst.Ref = @enumFromInt(extra.data.asm_source);
|
||||
const tmpl: Zir.Inst.Ref = @enumFromInt(@intFromEnum(extra.data.asm_source));
|
||||
const s: []const u8 = try sema.resolveConstString(block, src, tmpl, .{
|
||||
.needed_comptime_reason = "assembly code must be comptime-known",
|
||||
});
|
||||
@@ -16272,7 +16273,8 @@ fn zirAsm(
|
||||
|
||||
const clobbers = try sema.arena.alloc([]const u8, clobbers_len);
|
||||
for (clobbers) |*name| {
|
||||
name.* = sema.code.nullTerminatedString(sema.code.extra[extra_i]);
|
||||
const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_i]);
|
||||
name.* = sema.code.nullTerminatedString(name_index);
|
||||
extra_i += 1;
|
||||
|
||||
needed_capacity += name.*.len / 4 + 1;
|
||||
@@ -24713,7 +24715,8 @@ fn zirVarExtended(
|
||||
var extra_index: usize = extra.end;
|
||||
|
||||
const lib_name = if (small.has_lib_name) lib_name: {
|
||||
const lib_name = sema.code.nullTerminatedString(sema.code.extra[extra_index]);
|
||||
const lib_name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);
|
||||
const lib_name = sema.code.nullTerminatedString(lib_name_index);
|
||||
extra_index += 1;
|
||||
try sema.handleExternLibName(block, ty_src, lib_name);
|
||||
break :lib_name lib_name;
|
||||
@@ -24781,7 +24784,8 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
|
||||
var extra_index: usize = extra.end;
|
||||
|
||||
const lib_name: ?[]const u8 = if (extra.data.bits.has_lib_name) blk: {
|
||||
const lib_name = sema.code.nullTerminatedString(sema.code.extra[extra_index]);
|
||||
const lib_name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);
|
||||
const lib_name = sema.code.nullTerminatedString(lib_name_index);
|
||||
extra_index += 1;
|
||||
break :blk lib_name;
|
||||
} else null;
|
||||
@@ -35841,7 +35845,7 @@ fn semaStructFields(
|
||||
|
||||
var opt_field_name_zir: ?[:0]const u8 = null;
|
||||
if (!small.is_tuple) {
|
||||
opt_field_name_zir = zir.nullTerminatedString(zir.extra[extra_index]);
|
||||
opt_field_name_zir = zir.nullTerminatedString(@enumFromInt(zir.extra[extra_index]));
|
||||
extra_index += 1;
|
||||
}
|
||||
extra_index += 1; // doc_comment
|
||||
@@ -36344,7 +36348,8 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un
|
||||
cur_bit_bag >>= 1;
|
||||
_ = unused;
|
||||
|
||||
const field_name_zir = zir.nullTerminatedString(zir.extra[extra_index]);
|
||||
const field_name_index: Zir.NullTerminatedString = @enumFromInt(zir.extra[extra_index]);
|
||||
const field_name_zir = zir.nullTerminatedString(field_name_index);
|
||||
extra_index += 1;
|
||||
|
||||
// doc_comment
|
||||
|
||||
86
src/Zir.zig
86
src/Zir.zig
@@ -93,6 +93,7 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) ExtraData(T) {
|
||||
|
||||
Inst.Ref,
|
||||
Inst.Index,
|
||||
NullTerminatedString,
|
||||
=> @enumFromInt(code.extra[i]),
|
||||
|
||||
i32,
|
||||
@@ -112,18 +113,15 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) ExtraData(T) {
|
||||
};
|
||||
}
|
||||
|
||||
/// TODO migrate to use this for type safety
|
||||
pub const NullTerminatedString = enum(u32) {
|
||||
empty = 0,
|
||||
unnamed_test_decl = 1,
|
||||
decltest = 2,
|
||||
_,
|
||||
};
|
||||
|
||||
/// TODO: migrate to nullTerminatedString2 for type safety
|
||||
pub fn nullTerminatedString(code: Zir, index: usize) [:0]const u8 {
|
||||
return nullTerminatedString2(code, @enumFromInt(index));
|
||||
}
|
||||
|
||||
/// Given an index into `string_bytes` returns the null-terminated string found there.
|
||||
pub fn nullTerminatedString2(code: Zir, index: NullTerminatedString) [:0]const u8 {
|
||||
pub fn nullTerminatedString(code: Zir, index: NullTerminatedString) [:0]const u8 {
|
||||
const start = @intFromEnum(index);
|
||||
var end: u32 = start;
|
||||
while (code.string_bytes[end] != 0) {
|
||||
@@ -2298,17 +2296,17 @@ pub const Inst = struct {
|
||||
/// For strings which may contain null bytes.
|
||||
str: struct {
|
||||
/// Offset into `string_bytes`.
|
||||
start: u32,
|
||||
start: NullTerminatedString,
|
||||
/// Number of bytes in the string.
|
||||
len: u32,
|
||||
|
||||
pub fn get(self: @This(), code: Zir) []const u8 {
|
||||
return code.string_bytes[self.start..][0..self.len];
|
||||
return code.string_bytes[@intFromEnum(self.start)..][0..self.len];
|
||||
}
|
||||
},
|
||||
str_tok: struct {
|
||||
/// Offset into `string_bytes`. Null-terminated.
|
||||
start: u32,
|
||||
start: NullTerminatedString,
|
||||
/// Offset from Decl AST token index.
|
||||
src_tok: u32,
|
||||
|
||||
@@ -2385,7 +2383,7 @@ pub const Inst = struct {
|
||||
},
|
||||
str_op: struct {
|
||||
/// Offset into `string_bytes`. Null-terminated.
|
||||
str: u32,
|
||||
str: NullTerminatedString,
|
||||
operand: Ref,
|
||||
|
||||
pub fn getStr(self: @This(), zir: Zir) [:0]const u8 {
|
||||
@@ -2466,11 +2464,11 @@ pub const Inst = struct {
|
||||
/// Trailing:
|
||||
/// 0. Output for every outputs_len
|
||||
/// 1. Input for every inputs_len
|
||||
/// 2. clobber: u32 // index into string_bytes (null terminated) for every clobbers_len.
|
||||
/// 2. clobber: NullTerminatedString // index into string_bytes (null terminated) for every clobbers_len.
|
||||
pub const Asm = struct {
|
||||
src_node: i32,
|
||||
// null-terminated string index
|
||||
asm_source: u32,
|
||||
asm_source: NullTerminatedString,
|
||||
/// 1 bit for each outputs_len: whether it uses `-> T` or not.
|
||||
/// 0b0 - operand is a pointer to where to store the output.
|
||||
/// 0b1 - operand is a type; asm expression has the output as the result.
|
||||
@@ -2479,18 +2477,18 @@ pub const Inst = struct {
|
||||
|
||||
pub const Output = struct {
|
||||
/// index into string_bytes (null terminated)
|
||||
name: u32,
|
||||
name: NullTerminatedString,
|
||||
/// index into string_bytes (null terminated)
|
||||
constraint: u32,
|
||||
constraint: NullTerminatedString,
|
||||
/// How to interpret this is determined by `output_type_bits`.
|
||||
operand: Ref,
|
||||
};
|
||||
|
||||
pub const Input = struct {
|
||||
/// index into string_bytes (null terminated)
|
||||
name: u32,
|
||||
name: NullTerminatedString,
|
||||
/// index into string_bytes (null terminated)
|
||||
constraint: u32,
|
||||
constraint: NullTerminatedString,
|
||||
operand: Ref,
|
||||
};
|
||||
};
|
||||
@@ -2524,7 +2522,7 @@ pub const Inst = struct {
|
||||
};
|
||||
|
||||
/// Trailing:
|
||||
/// 0. lib_name: u32, // null terminated string index, if has_lib_name is set
|
||||
/// 0. lib_name: NullTerminatedString, // null terminated string index, if has_lib_name is set
|
||||
/// if (has_align_ref and !has_align_body) {
|
||||
/// 1. align: Ref,
|
||||
/// }
|
||||
@@ -2598,7 +2596,7 @@ pub const Inst = struct {
|
||||
};
|
||||
|
||||
/// Trailing:
|
||||
/// 0. lib_name: u32, // null terminated string index, if has_lib_name is set
|
||||
/// 0. lib_name: NullTerminatedString, // null terminated string index, if has_lib_name is set
|
||||
/// 1. align: Ref, // if has_align is set
|
||||
/// 2. init: Ref // if has_init is set
|
||||
/// The source node is obtained from the containing `block_inline`.
|
||||
@@ -2672,7 +2670,7 @@ pub const Inst = struct {
|
||||
flags: Call.Flags,
|
||||
obj_ptr: Ref,
|
||||
/// Offset into `string_bytes`.
|
||||
field_name_start: u32,
|
||||
field_name_start: NullTerminatedString,
|
||||
};
|
||||
|
||||
pub const TypeOfPeer = struct {
|
||||
@@ -2871,7 +2869,7 @@ pub const Inst = struct {
|
||||
pub const Field = struct {
|
||||
lhs: Ref,
|
||||
/// Offset into `string_bytes`.
|
||||
field_name_start: u32,
|
||||
field_name_start: NullTerminatedString,
|
||||
};
|
||||
|
||||
pub const FieldNamed = struct {
|
||||
@@ -2900,7 +2898,7 @@ pub const Inst = struct {
|
||||
/// 7. decl: { // for every decls_len
|
||||
/// src_hash: [4]u32, // hash of source bytes
|
||||
/// line: u32, // line number of decl, relative to parent
|
||||
/// name: u32, // null terminated string index
|
||||
/// name: NullTerminatedString, // null terminated string index
|
||||
/// - 0 means comptime or usingnamespace decl.
|
||||
/// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
|
||||
/// - 1 means test decl with no name.
|
||||
@@ -2908,7 +2906,7 @@ pub const Inst = struct {
|
||||
/// - if there is a 0 byte at the position `name` indexes, it indicates
|
||||
/// this is a test decl, and the name starts at `name+1`.
|
||||
/// value: Index,
|
||||
/// doc_comment: u32, 0 if no doc comment, if this is a decltest, doc_comment references the decl name in the string table
|
||||
/// doc_comment: u32, .empty if no doc comment, if this is a decltest, doc_comment references the decl name in the string table
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// link_section_or_address_space: { // if corresponding bit is set.
|
||||
/// link_section: Ref,
|
||||
@@ -2923,7 +2921,7 @@ pub const Inst = struct {
|
||||
/// 0bX000: whether corresponding field has a type expression
|
||||
/// 9. fields: { // for every fields_len
|
||||
/// field_name: u32, // if !is_tuple
|
||||
/// doc_comment: u32, // 0 if no doc comment
|
||||
/// doc_comment: NullTerminatedString, // .empty if no doc comment
|
||||
/// field_type: Ref, // if corresponding bit is not set. none means anytype.
|
||||
/// field_type_body_len: u32, // if corresponding bit is set
|
||||
/// align_body_len: u32, // if corresponding bit is set
|
||||
@@ -2996,14 +2994,14 @@ pub const Inst = struct {
|
||||
/// 6. decl: { // for every decls_len
|
||||
/// src_hash: [4]u32, // hash of source bytes
|
||||
/// line: u32, // line number of decl, relative to parent
|
||||
/// name: u32, // null terminated string index
|
||||
/// name: NullTerminatedString, // null terminated string index
|
||||
/// - 0 means comptime or usingnamespace decl.
|
||||
/// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
|
||||
/// - 1 means test decl with no name.
|
||||
/// - if there is a 0 byte at the position `name` indexes, it indicates
|
||||
/// this is a test decl, and the name starts at `name+1`.
|
||||
/// value: Index,
|
||||
/// doc_comment: u32, // 0 if no doc_comment
|
||||
/// doc_comment: u32, // .empty if no doc_comment
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// link_section_or_address_space: { // if corresponding bit is set.
|
||||
/// link_section: Ref,
|
||||
@@ -3015,7 +3013,7 @@ pub const Inst = struct {
|
||||
/// - the bit is whether corresponding field has an value expression
|
||||
/// 9. fields: { // for every fields_len
|
||||
/// field_name: u32,
|
||||
/// doc_comment: u32, // 0 if no doc_comment
|
||||
/// doc_comment: u32, // .empty if no doc_comment
|
||||
/// value: Ref, // if corresponding bit is set
|
||||
/// }
|
||||
pub const EnumDecl = struct {
|
||||
@@ -3046,14 +3044,14 @@ pub const Inst = struct {
|
||||
/// 6. decl: { // for every decls_len
|
||||
/// src_hash: [4]u32, // hash of source bytes
|
||||
/// line: u32, // line number of decl, relative to parent
|
||||
/// name: u32, // null terminated string index
|
||||
/// name: NullTerminatedString, // null terminated string index
|
||||
/// - 0 means comptime or usingnamespace decl.
|
||||
/// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
|
||||
/// - 1 means test decl with no name.
|
||||
/// - if there is a 0 byte at the position `name` indexes, it indicates
|
||||
/// this is a test decl, and the name starts at `name+1`.
|
||||
/// value: Index,
|
||||
/// doc_comment: u32, // 0 if no doc comment
|
||||
/// doc_comment: NullTerminatedString, // .empty if no doc comment
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// link_section_or_address_space: { // if corresponding bit is set.
|
||||
/// link_section: Ref,
|
||||
@@ -3068,8 +3066,8 @@ pub const Inst = struct {
|
||||
/// 0b0X00: whether corresponding field has a tag value expression
|
||||
/// 0bX000: unused
|
||||
/// 9. fields: { // for every fields_len
|
||||
/// field_name: u32, // null terminated string index
|
||||
/// doc_comment: u32, // 0 if no doc comment
|
||||
/// field_name: NullTerminatedString, // null terminated string index
|
||||
/// doc_comment: NullTerminatedString, // .empty if no doc comment
|
||||
/// field_type: Ref, // if corresponding bit is set
|
||||
/// - if none, means `anytype`.
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
@@ -3108,14 +3106,14 @@ pub const Inst = struct {
|
||||
/// 3. decl: { // for every decls_len
|
||||
/// src_hash: [4]u32, // hash of source bytes
|
||||
/// line: u32, // line number of decl, relative to parent
|
||||
/// name: u32, // null terminated string index
|
||||
/// name: NullTerminatedString, // null terminated string index
|
||||
/// - 0 means comptime or usingnamespace decl.
|
||||
/// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
|
||||
/// - 1 means test decl with no name.
|
||||
/// - if there is a 0 byte at the position `name` indexes, it indicates
|
||||
/// this is a test decl, and the name starts at `name+1`.
|
||||
/// value: Index,
|
||||
/// doc_comment: u32, // 0 if no doc comment,
|
||||
/// doc_comment: NullTerminatedString, // .empty if no doc comment,
|
||||
/// align: Ref, // if corresponding bit is set
|
||||
/// link_section_or_address_space: { // if corresponding bit is set.
|
||||
/// link_section: Ref,
|
||||
@@ -3133,8 +3131,8 @@ pub const Inst = struct {
|
||||
|
||||
/// Trailing:
|
||||
/// { // for every fields_len
|
||||
/// field_name: u32 // null terminated string index
|
||||
/// doc_comment: u32 // null terminated string index
|
||||
/// field_name: NullTerminatedString // null terminated string index
|
||||
/// doc_comment: NullTerminatedString // null terminated string index
|
||||
/// }
|
||||
pub const ErrorSetDecl = struct {
|
||||
fields_len: u32,
|
||||
@@ -3177,7 +3175,7 @@ pub const Inst = struct {
|
||||
|
||||
pub const Item = struct {
|
||||
/// Null-terminated string table index.
|
||||
field_name: u32,
|
||||
field_name: NullTerminatedString,
|
||||
/// The field init expression to be used as the field value.
|
||||
init: Ref,
|
||||
};
|
||||
@@ -3186,7 +3184,7 @@ pub const Inst = struct {
|
||||
pub const FieldType = struct {
|
||||
container_type: Ref,
|
||||
/// Offset into `string_bytes`, null terminated.
|
||||
name_start: u32,
|
||||
name_start: NullTerminatedString,
|
||||
};
|
||||
|
||||
pub const FieldTypeRef = struct {
|
||||
@@ -3266,9 +3264,9 @@ pub const Inst = struct {
|
||||
/// Trailing: inst: Index // for every body_len
|
||||
pub const Param = struct {
|
||||
/// Null-terminated string index.
|
||||
name: u32,
|
||||
/// 0 if no doc comment
|
||||
doc_comment: u32,
|
||||
name: NullTerminatedString,
|
||||
/// Null-terminated string index.
|
||||
doc_comment: NullTerminatedString,
|
||||
/// The body contains the type of the parameter.
|
||||
body_len: u32,
|
||||
};
|
||||
@@ -3293,7 +3291,7 @@ pub const Inst = struct {
|
||||
/// If omitted, this is referring to a Decl via identifier, e.g. `a`.
|
||||
namespace: Ref,
|
||||
/// Null-terminated string index.
|
||||
decl_name: u32,
|
||||
decl_name: NullTerminatedString,
|
||||
options: Ref,
|
||||
};
|
||||
|
||||
@@ -3311,7 +3309,7 @@ pub const Inst = struct {
|
||||
/// It's a payload index of another `Item`.
|
||||
pub const Item = struct {
|
||||
/// null terminated string index
|
||||
msg: u32,
|
||||
msg: NullTerminatedString,
|
||||
node: Ast.Node.Index,
|
||||
/// If node is 0 then this will be populated.
|
||||
token: Ast.TokenIndex,
|
||||
@@ -3335,7 +3333,7 @@ pub const Inst = struct {
|
||||
|
||||
pub const Item = struct {
|
||||
/// null terminated string index
|
||||
name: u32,
|
||||
name: NullTerminatedString,
|
||||
/// points to the import name
|
||||
token: Ast.TokenIndex,
|
||||
};
|
||||
@@ -3412,7 +3410,7 @@ pub const DeclIterator = struct {
|
||||
|
||||
const sub_index: ExtraIndex = @enumFromInt(it.extra_index);
|
||||
it.extra_index += 5; // src_hash(4) + line(1)
|
||||
const name = it.zir.nullTerminatedString(it.zir.extra[it.extra_index]);
|
||||
const name = it.zir.nullTerminatedString(@enumFromInt(it.zir.extra[it.extra_index]));
|
||||
it.extra_index += 3; // name(1) + value(1) + doc_comment(1)
|
||||
it.extra_index += @as(u1, @truncate(flags >> 2)); // align
|
||||
it.extra_index += @as(u1, @truncate(flags >> 3)); // link_section
|
||||
|
||||
@@ -752,7 +752,7 @@ const Writer = struct {
|
||||
fn writeIntBig(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
|
||||
const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str;
|
||||
const byte_count = inst_data.len * @sizeOf(std.math.big.Limb);
|
||||
const limb_bytes = self.code.string_bytes[inst_data.start..][0..byte_count];
|
||||
const limb_bytes = self.code.nullTerminatedString(inst_data.start)[0..byte_count];
|
||||
// limb_bytes is not aligned properly; we must allocate and copy the bytes
|
||||
// in order to accomplish this.
|
||||
const limbs = try self.gpa.alloc(std.math.big.Limb, inst_data.len);
|
||||
@@ -945,7 +945,7 @@ const Writer = struct {
|
||||
std.zig.fmtEscapes(self.code.nullTerminatedString(extra.data.name)),
|
||||
});
|
||||
|
||||
if (extra.data.doc_comment != 0) {
|
||||
if (extra.data.doc_comment != .empty) {
|
||||
try stream.writeAll("\n");
|
||||
try self.writeDocComment(stream, extra.data.doc_comment);
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
@@ -1226,7 +1226,7 @@ const Writer = struct {
|
||||
|
||||
try self.writeFlag(stream, "volatile, ", is_volatile);
|
||||
if (tmpl_is_expr) {
|
||||
try self.writeInstRef(stream, @as(Zir.Inst.Ref, @enumFromInt(extra.data.asm_source)));
|
||||
try self.writeInstRef(stream, @enumFromInt(@intFromEnum(extra.data.asm_source)));
|
||||
try stream.writeAll(", ");
|
||||
} else {
|
||||
const asm_source = self.code.nullTerminatedString(extra.data.asm_source);
|
||||
@@ -1281,7 +1281,7 @@ const Writer = struct {
|
||||
while (i < clobbers_len) : (i += 1) {
|
||||
const str_index = self.code.extra[extra_i];
|
||||
extra_i += 1;
|
||||
const clobber = self.code.nullTerminatedString(str_index);
|
||||
const clobber = self.code.nullTerminatedString(@enumFromInt(str_index));
|
||||
try stream.print("{}", .{std.zig.fmtId(clobber)});
|
||||
if (i + 1 < clobbers_len) {
|
||||
try stream.writeAll(", ");
|
||||
@@ -1466,12 +1466,12 @@ const Writer = struct {
|
||||
const fields_per_u32 = 32 / bits_per_field;
|
||||
const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;
|
||||
const Field = struct {
|
||||
doc_comment_index: u32,
|
||||
doc_comment_index: Zir.NullTerminatedString,
|
||||
type_len: u32 = 0,
|
||||
align_len: u32 = 0,
|
||||
init_len: u32 = 0,
|
||||
type: Zir.Inst.Ref = .none,
|
||||
name: u32,
|
||||
name: Zir.NullTerminatedString,
|
||||
is_comptime: bool,
|
||||
};
|
||||
const fields = try self.arena.alloc(Field, fields_len);
|
||||
@@ -1494,24 +1494,24 @@ const Writer = struct {
|
||||
const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;
|
||||
cur_bit_bag >>= 1;
|
||||
|
||||
var field_name: u32 = 0;
|
||||
var field_name_index: Zir.NullTerminatedString = .empty;
|
||||
if (!small.is_tuple) {
|
||||
field_name = self.code.extra[extra_index];
|
||||
field_name_index = @enumFromInt(self.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
}
|
||||
const doc_comment_index = self.code.extra[extra_index];
|
||||
const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
|
||||
fields[field_i] = .{
|
||||
.doc_comment_index = doc_comment_index,
|
||||
.is_comptime = is_comptime,
|
||||
.name = field_name,
|
||||
.name = field_name_index,
|
||||
};
|
||||
|
||||
if (has_type_body) {
|
||||
fields[field_i].type_len = self.code.extra[extra_index];
|
||||
} else {
|
||||
fields[field_i].type = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index]));
|
||||
fields[field_i].type = @enumFromInt(self.code.extra[extra_index]);
|
||||
}
|
||||
extra_index += 1;
|
||||
|
||||
@@ -1536,7 +1536,7 @@ const Writer = struct {
|
||||
try self.writeDocComment(stream, field.doc_comment_index);
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try self.writeFlag(stream, "comptime ", field.is_comptime);
|
||||
if (field.name != 0) {
|
||||
if (field.name != .empty) {
|
||||
const field_name = self.code.nullTerminatedString(field.name);
|
||||
try stream.print("{}: ", .{std.zig.fmtId(field_name)});
|
||||
} else {
|
||||
@@ -1684,9 +1684,10 @@ const Writer = struct {
|
||||
|
||||
_ = unused;
|
||||
|
||||
const field_name = self.code.nullTerminatedString(self.code.extra[extra_index]);
|
||||
const field_name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
|
||||
const field_name = self.code.nullTerminatedString(field_name_index);
|
||||
extra_index += 1;
|
||||
const doc_comment_index = self.code.extra[extra_index];
|
||||
const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
|
||||
try self.writeDocComment(stream, doc_comment_index);
|
||||
@@ -1756,7 +1757,7 @@ const Writer = struct {
|
||||
extra_index += 1;
|
||||
const decl_index: Zir.Inst.Index = @enumFromInt(self.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
const doc_comment_index = self.code.extra[extra_index];
|
||||
const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
|
||||
const align_inst: Zir.Inst.Ref = if (!has_align) .none else inst: {
|
||||
@@ -1789,9 +1790,9 @@ const Writer = struct {
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.print("[{d}] decltest {s}", .{ sub_index, self.code.nullTerminatedString(doc_comment_index) });
|
||||
} else {
|
||||
const raw_decl_name = self.code.nullTerminatedString(decl_name_index);
|
||||
const raw_decl_name = self.code.nullTerminatedString(@enumFromInt(decl_name_index));
|
||||
const decl_name = if (raw_decl_name.len == 0)
|
||||
self.code.nullTerminatedString(decl_name_index + 1)
|
||||
self.code.nullTerminatedString(@enumFromInt(decl_name_index + 1))
|
||||
else
|
||||
raw_decl_name;
|
||||
const test_str = if (raw_decl_name.len == 0) "test \"" else "";
|
||||
@@ -1927,10 +1928,10 @@ const Writer = struct {
|
||||
const has_tag_value = @as(u1, @truncate(cur_bit_bag)) != 0;
|
||||
cur_bit_bag >>= 1;
|
||||
|
||||
const field_name = self.code.nullTerminatedString(self.code.extra[extra_index]);
|
||||
const field_name = self.code.nullTerminatedString(@enumFromInt(self.code.extra[extra_index]));
|
||||
extra_index += 1;
|
||||
|
||||
const doc_comment_index = self.code.extra[extra_index];
|
||||
const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
|
||||
try self.writeDocComment(stream, doc_comment_index);
|
||||
@@ -2011,9 +2012,9 @@ const Writer = struct {
|
||||
var extra_index = @as(u32, @intCast(extra.end));
|
||||
const extra_index_end = extra_index + (extra.data.fields_len * 2);
|
||||
while (extra_index < extra_index_end) : (extra_index += 2) {
|
||||
const str_index = self.code.extra[extra_index];
|
||||
const name = self.code.nullTerminatedString(str_index);
|
||||
const doc_comment_index = self.code.extra[extra_index + 1];
|
||||
const name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
|
||||
const name = self.code.nullTerminatedString(name_index);
|
||||
const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index + 1]);
|
||||
try self.writeDocComment(stream, doc_comment_index);
|
||||
try stream.writeByteNTimes(' ', self.indent);
|
||||
try stream.print("{},\n", .{std.zig.fmtId(name)});
|
||||
@@ -2292,7 +2293,7 @@ const Writer = struct {
|
||||
var ret_ty_body: []const Zir.Inst.Index = &.{};
|
||||
|
||||
if (extra.data.bits.has_lib_name) {
|
||||
const lib_name = self.code.nullTerminatedString(self.code.extra[extra_index]);
|
||||
const lib_name = self.code.nullTerminatedString(@enumFromInt(self.code.extra[extra_index]));
|
||||
extra_index += 1;
|
||||
try stream.print("lib_name=\"{}\", ", .{std.zig.fmtEscapes(lib_name)});
|
||||
}
|
||||
@@ -2388,7 +2389,8 @@ const Writer = struct {
|
||||
|
||||
var extra_index: usize = extra.end;
|
||||
if (small.has_lib_name) {
|
||||
const lib_name = self.code.nullTerminatedString(self.code.extra[extra_index]);
|
||||
const lib_name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
|
||||
const lib_name = self.code.nullTerminatedString(lib_name_index);
|
||||
extra_index += 1;
|
||||
try stream.print(", lib_name=\"{}\"", .{std.zig.fmtEscapes(lib_name)});
|
||||
}
|
||||
@@ -2740,8 +2742,8 @@ const Writer = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn writeDocComment(self: *Writer, stream: anytype, doc_comment_index: u32) !void {
|
||||
if (doc_comment_index != 0) {
|
||||
fn writeDocComment(self: *Writer, stream: anytype, doc_comment_index: Zir.NullTerminatedString) !void {
|
||||
if (doc_comment_index != .empty) {
|
||||
const doc_comment = self.code.nullTerminatedString(doc_comment_index);
|
||||
var it = std.mem.tokenizeScalar(u8, doc_comment, '\n');
|
||||
while (it.next()) |doc_line| {
|
||||
|
||||
Reference in New Issue
Block a user