aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2024-06-10 01:22:54 +0100
committermlugg <mlugg@mlugg.co.uk>2024-06-15 00:57:52 +0100
commite39cc0dff7fff510c3d72f61947b977589ea5583 (patch)
tree5d7c405520d5c898c46a517820bd331526b7852d /lib/std
parent82a934bb912241809ac8029e1fa5843092a7fdf6 (diff)
downloadzig-e39cc0dff7fff510c3d72f61947b977589ea5583.tar.gz
zig-e39cc0dff7fff510c3d72f61947b977589ea5583.zip
Zir: use absolute nodes for declarations and type declarations
The justification for using relative source nodes in ZIR is that it allows source locations -- which may be serialized across incremental updates -- to be relative to the source location of their containing declaration. However, having those "baseline" instructions themselves be relative to their own parent is counterproductive, since the source location updating problem is only being moved to `Decl`. Storing the absolute node here instead makes more sense, since it allows for this source location update logic to be elided entirely in the future by storing a `TrackedInst.Index` to resolve a source location relative to rather than a `Decl.Index`.
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/zig/AstGen.zig37
-rw-r--r--lib/std/zig/Zir.zig37
2 files changed, 51 insertions, 23 deletions
diff --git a/lib/std/zig/AstGen.zig b/lib/std/zig/AstGen.zig
index f02dcaa2db..b356789bfd 100644
--- a/lib/std/zig/AstGen.zig
+++ b/lib/std/zig/AstGen.zig
@@ -4011,7 +4011,7 @@ fn fnDecl(
// We insert this at the beginning so that its instruction index marks the
// start of the top level declaration.
- const decl_inst = try gz.makeBlockInst(.declaration, fn_proto.ast.proto_node);
+ const decl_inst = try gz.makeDeclaration(fn_proto.ast.proto_node);
astgen.advanceSourceCursorToNode(decl_node);
var decl_gz: GenZir = .{
@@ -4393,7 +4393,7 @@ fn globalVarDecl(
const is_mutable = token_tags[var_decl.ast.mut_token] == .keyword_var;
// We do this at the beginning so that the instruction index marks the range start
// of the top level declaration.
- const decl_inst = try gz.makeBlockInst(.declaration, node);
+ const decl_inst = try gz.makeDeclaration(node);
const name_token = var_decl.ast.mut_token + 1;
astgen.advanceSourceCursorToNode(node);
@@ -4555,7 +4555,7 @@ fn comptimeDecl(
// Up top so the ZIR instruction index marks the start range of this
// top-level declaration.
- const decl_inst = try gz.makeBlockInst(.declaration, node);
+ const decl_inst = try gz.makeDeclaration(node);
wip_members.nextDecl(decl_inst);
astgen.advanceSourceCursorToNode(node);
@@ -4607,7 +4607,7 @@ fn usingnamespaceDecl(
};
// Up top so the ZIR instruction index marks the start range of this
// top-level declaration.
- const decl_inst = try gz.makeBlockInst(.declaration, node);
+ const decl_inst = try gz.makeDeclaration(node);
wip_members.nextDecl(decl_inst);
astgen.advanceSourceCursorToNode(node);
@@ -4651,7 +4651,7 @@ fn testDecl(
// Up top so the ZIR instruction index marks the start range of this
// top-level declaration.
- const decl_inst = try gz.makeBlockInst(.declaration, node);
+ const decl_inst = try gz.makeDeclaration(node);
wip_members.nextDecl(decl_inst);
astgen.advanceSourceCursorToNode(node);
@@ -13072,6 +13072,21 @@ const GenZir = struct {
}
/// Note that this returns a `Zir.Inst.Index` not a ref.
+ /// Does *not* append the block instruction to the scope.
+ /// Leaves the `payload_index` field undefined. Use `setDeclaration` to finalize.
+ fn makeDeclaration(gz: *GenZir, node: Ast.Node.Index) !Zir.Inst.Index {
+ const new_index: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len);
+ try gz.astgen.instructions.append(gz.astgen.gpa, .{
+ .tag = .declaration,
+ .data = .{ .declaration = .{
+ .src_node = node,
+ .payload_index = undefined,
+ } },
+ });
+ return new_index;
+ }
+
+ /// Note that this returns a `Zir.Inst.Index` not a ref.
/// Leaves the `payload_index` field undefined.
fn addCondBr(gz: *GenZir, tag: Zir.Inst.Tag, node: Ast.Node.Index) !Zir.Inst.Index {
const gpa = gz.astgen.gpa;
@@ -13117,7 +13132,7 @@ const GenZir = struct {
.fields_hash_1 = fields_hash_arr[1],
.fields_hash_2 = fields_hash_arr[2],
.fields_hash_3 = fields_hash_arr[3],
- .src_node = gz.nodeIndexToRelative(args.src_node),
+ .src_node = args.src_node,
});
if (args.captures_len != 0) {
@@ -13177,7 +13192,7 @@ const GenZir = struct {
.fields_hash_1 = fields_hash_arr[1],
.fields_hash_2 = fields_hash_arr[2],
.fields_hash_3 = fields_hash_arr[3],
- .src_node = gz.nodeIndexToRelative(args.src_node),
+ .src_node = args.src_node,
});
if (args.tag_type != .none) {
@@ -13238,7 +13253,7 @@ const GenZir = struct {
.fields_hash_1 = fields_hash_arr[1],
.fields_hash_2 = fields_hash_arr[2],
.fields_hash_3 = fields_hash_arr[3],
- .src_node = gz.nodeIndexToRelative(args.src_node),
+ .src_node = args.src_node,
});
if (args.tag_type != .none) {
@@ -13285,9 +13300,7 @@ const GenZir = struct {
assert(args.src_node != 0);
try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.OpaqueDecl).Struct.fields.len + 2);
- const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.OpaqueDecl{
- .src_node = gz.nodeIndexToRelative(args.src_node),
- });
+ const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.OpaqueDecl{ .src_node = args.src_node });
if (args.captures_len != 0) {
astgen.extra.appendAssumeCapacity(args.captures_len);
@@ -13897,7 +13910,7 @@ fn setDeclaration(
.has_align_linksection_addrspace = align_len != 0 or linksection_len != 0 or addrspace_len != 0,
},
};
- astgen.instructions.items(.data)[@intFromEnum(decl_inst)].pl_node.payload_index = try astgen.addExtra(extra);
+ astgen.instructions.items(.data)[@intFromEnum(decl_inst)].declaration.payload_index = try astgen.addExtra(extra);
if (extra.flags.has_doc_comment) {
try astgen.extra.append(gpa, @intFromEnum(true_doc_comment));
}
diff --git a/lib/std/zig/Zir.zig b/lib/std/zig/Zir.zig
index a79e965fe9..1ab7e94842 100644
--- a/lib/std/zig/Zir.zig
+++ b/lib/std/zig/Zir.zig
@@ -287,7 +287,7 @@ pub const Inst = struct {
/// namespace type, e.g. within a `struct_decl` instruction. It represents a
/// single source declaration (`const`/`var`/`fn`), containing the name,
/// attributes, type, and value of the declaration.
- /// Uses the `pl_node` union field. Payload is `Declaration`.
+ /// Uses the `declaration` union field. Payload is `Declaration`.
declaration,
/// Implements `suspend {...}`.
/// Uses the `pl_node` union field. Payload is `Block`.
@@ -1596,7 +1596,7 @@ pub const Inst = struct {
.block = .pl_node,
.block_comptime = .pl_node,
.block_inline = .pl_node,
- .declaration = .pl_node,
+ .declaration = .declaration,
.suspend_block = .pl_node,
.bool_not = .un_node,
.bool_br_and = .pl_node,
@@ -2370,6 +2370,16 @@ pub const Inst = struct {
/// The index being accessed.
idx: u32,
},
+ declaration: struct {
+ /// This node provides a new absolute baseline node for all instructions within this struct.
+ src_node: Ast.Node.Index,
+ /// index into extra to a `Declaration` payload.
+ payload_index: u32,
+
+ pub fn src(self: @This()) LazySrcLoc {
+ return .{ .node_abs = self.src_node };
+ }
+ },
// Make sure we don't accidentally add a field to make this union
// bigger than expected. Note that in Debug builds, Zig is allowed
@@ -2408,6 +2418,7 @@ pub const Inst = struct {
defer_err_code,
save_err_ret_index,
elem_val_imm,
+ declaration,
};
};
@@ -3018,10 +3029,11 @@ pub const Inst = struct {
fields_hash_1: u32,
fields_hash_2: u32,
fields_hash_3: u32,
- src_node: i32,
+ /// This node provides a new absolute baseline node for all instructions within this struct.
+ src_node: Ast.Node.Index,
pub fn src(self: StructDecl) LazySrcLoc {
- return LazySrcLoc.nodeOffset(self.src_node);
+ return .{ .node_abs = self.src_node };
}
pub const Small = packed struct {
@@ -3150,10 +3162,11 @@ pub const Inst = struct {
fields_hash_1: u32,
fields_hash_2: u32,
fields_hash_3: u32,
- src_node: i32,
+ /// This node provides a new absolute baseline node for all instructions within this struct.
+ src_node: Ast.Node.Index,
pub fn src(self: EnumDecl) LazySrcLoc {
- return LazySrcLoc.nodeOffset(self.src_node);
+ return .{ .node_abs = self.src_node };
}
pub const Small = packed struct {
@@ -3198,10 +3211,11 @@ pub const Inst = struct {
fields_hash_1: u32,
fields_hash_2: u32,
fields_hash_3: u32,
- src_node: i32,
+ /// This node provides a new absolute baseline node for all instructions within this struct.
+ src_node: Ast.Node.Index,
pub fn src(self: UnionDecl) LazySrcLoc {
- return LazySrcLoc.nodeOffset(self.src_node);
+ return .{ .node_abs = self.src_node };
}
pub const Small = packed struct {
@@ -3230,10 +3244,11 @@ pub const Inst = struct {
/// 2. capture: Capture, // for every captures_len
/// 3. decl: Index, // for every decls_len; points to a `declaration` instruction
pub const OpaqueDecl = struct {
- src_node: i32,
+ /// This node provides a new absolute baseline node for all instructions within this struct.
+ src_node: Ast.Node.Index,
pub fn src(self: OpaqueDecl) LazySrcLoc {
- return LazySrcLoc.nodeOffset(self.src_node);
+ return .{ .node_abs = self.src_node };
}
pub const Small = packed struct {
@@ -4046,7 +4061,7 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {
pub fn getDeclaration(zir: Zir, inst: Zir.Inst.Index) struct { Inst.Declaration, u32 } {
assert(zir.instructions.items(.tag)[@intFromEnum(inst)] == .declaration);
- const pl_node = zir.instructions.items(.data)[@intFromEnum(inst)].pl_node;
+ const pl_node = zir.instructions.items(.data)[@intFromEnum(inst)].declaration;
const extra = zir.extraData(Inst.Declaration, pl_node.payload_index);
return .{
extra.data,