diff options
| author | mlugg <mlugg@mlugg.co.uk> | 2024-06-10 01:22:54 +0100 |
|---|---|---|
| committer | mlugg <mlugg@mlugg.co.uk> | 2024-06-15 00:57:52 +0100 |
| commit | e39cc0dff7fff510c3d72f61947b977589ea5583 (patch) | |
| tree | 5d7c405520d5c898c46a517820bd331526b7852d /lib/std | |
| parent | 82a934bb912241809ac8029e1fa5843092a7fdf6 (diff) | |
| download | zig-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.zig | 37 | ||||
| -rw-r--r-- | lib/std/zig/Zir.zig | 37 |
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, |
