| ... | @@ -13,17 +13,11 @@ const assert = std.debug.assert; | ... | @@ -13,17 +13,11 @@ const assert = std.debug.assert; |
| 13 | const ArrayListUnmanaged = std.ArrayListUnmanaged; | 13 | const ArrayListUnmanaged = std.ArrayListUnmanaged; |
| 14 | | 14 | |
| 15 | const Zir = @import("Zir.zig"); | 15 | const Zir = @import("Zir.zig"); |
| 16 | const Module = @import("Module.zig"); | | |
| 17 | const trace = @import("tracy.zig").trace; | 16 | const trace = @import("tracy.zig").trace; |
| 18 | const Scope = Module.Scope; | | |
| 19 | const GenZir = Scope.GenZir; | | |
| 20 | const InnerError = Module.InnerError; | | |
| 21 | const Decl = Module.Decl; | | |
| 22 | const LazySrcLoc = Module.LazySrcLoc; | | |
| 23 | const BuiltinFn = @import("BuiltinFn.zig"); | 17 | const BuiltinFn = @import("BuiltinFn.zig"); |
| 24 | | 18 | |
| 25 | gpa: *Allocator, | 19 | gpa: *Allocator, |
| 26 | file: *Scope.File, | 20 | tree: *const ast.Tree, |
| 27 | instructions: std.MultiArrayList(Zir.Inst) = .{}, | 21 | instructions: std.MultiArrayList(Zir.Inst) = .{}, |
| 28 | extra: ArrayListUnmanaged(u32) = .{}, | 22 | extra: ArrayListUnmanaged(u32) = .{}, |
| 29 | string_bytes: ArrayListUnmanaged(u8) = .{}, | 23 | string_bytes: ArrayListUnmanaged(u8) = .{}, |
| ... | @@ -37,13 +31,15 @@ fn_block: ?*GenZir = null, | ... | @@ -37,13 +31,15 @@ fn_block: ?*GenZir = null, |
| 37 | /// String table indexes, keeps track of all `@import` operands. | 31 | /// String table indexes, keeps track of all `@import` operands. |
| 38 | imports: std.AutoArrayHashMapUnmanaged(u32, void) = .{}, | 32 | imports: std.AutoArrayHashMapUnmanaged(u32, void) = .{}, |
| 39 | | 33 | |
| 40 | pub fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 { | 34 | const InnerError = error{ OutOfMemory, AnalysisFail }; |
| | 35 | |
| | 36 | fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 { |
| 41 | const fields = std.meta.fields(@TypeOf(extra)); | 37 | const fields = std.meta.fields(@TypeOf(extra)); |
| 42 | try astgen.extra.ensureCapacity(astgen.gpa, astgen.extra.items.len + fields.len); | 38 | try astgen.extra.ensureCapacity(astgen.gpa, astgen.extra.items.len + fields.len); |
| 43 | return addExtraAssumeCapacity(astgen, extra); | 39 | return addExtraAssumeCapacity(astgen, extra); |
| 44 | } | 40 | } |
| 45 | | 41 | |
| 46 | pub fn addExtraAssumeCapacity(astgen: *AstGen, extra: anytype) u32 { | 42 | fn addExtraAssumeCapacity(astgen: *AstGen, extra: anytype) u32 { |
| 47 | const fields = std.meta.fields(@TypeOf(extra)); | 43 | const fields = std.meta.fields(@TypeOf(extra)); |
| 48 | const result = @intCast(u32, astgen.extra.items.len); | 44 | const result = @intCast(u32, astgen.extra.items.len); |
| 49 | inline for (fields) |field| { | 45 | inline for (fields) |field| { |
| ... | @@ -57,24 +53,24 @@ pub fn addExtraAssumeCapacity(astgen: *AstGen, extra: anytype) u32 { | ... | @@ -57,24 +53,24 @@ pub fn addExtraAssumeCapacity(astgen: *AstGen, extra: anytype) u32 { |
| 57 | return result; | 53 | return result; |
| 58 | } | 54 | } |
| 59 | | 55 | |
| 60 | pub fn appendRefs(astgen: *AstGen, refs: []const Zir.Inst.Ref) !void { | 56 | fn appendRefs(astgen: *AstGen, refs: []const Zir.Inst.Ref) !void { |
| 61 | const coerced = @bitCast([]const u32, refs); | 57 | const coerced = @bitCast([]const u32, refs); |
| 62 | return astgen.extra.appendSlice(astgen.gpa, coerced); | 58 | return astgen.extra.appendSlice(astgen.gpa, coerced); |
| 63 | } | 59 | } |
| 64 | | 60 | |
| 65 | pub fn appendRefsAssumeCapacity(astgen: *AstGen, refs: []const Zir.Inst.Ref) void { | 61 | fn appendRefsAssumeCapacity(astgen: *AstGen, refs: []const Zir.Inst.Ref) void { |
| 66 | const coerced = @bitCast([]const u32, refs); | 62 | const coerced = @bitCast([]const u32, refs); |
| 67 | astgen.extra.appendSliceAssumeCapacity(coerced); | 63 | astgen.extra.appendSliceAssumeCapacity(coerced); |
| 68 | } | 64 | } |
| 69 | | 65 | |
| 70 | pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir { | 66 | pub fn generate(gpa: *Allocator, tree: ast.Tree) InnerError!Zir { |
| 71 | var arena = std.heap.ArenaAllocator.init(gpa); | 67 | var arena = std.heap.ArenaAllocator.init(gpa); |
| 72 | defer arena.deinit(); | 68 | defer arena.deinit(); |
| 73 | | 69 | |
| 74 | var astgen: AstGen = .{ | 70 | var astgen: AstGen = .{ |
| 75 | .gpa = gpa, | 71 | .gpa = gpa, |
| 76 | .arena = &arena.allocator, | 72 | .arena = &arena.allocator, |
| 77 | .file = file, | 73 | .tree = &tree, |
| 78 | }; | 74 | }; |
| 79 | defer astgen.deinit(gpa); | 75 | defer astgen.deinit(gpa); |
| 80 | | 76 | |
| ... | @@ -83,16 +79,16 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir { | ... | @@ -83,16 +79,16 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir { |
| 83 | | 79 | |
| 84 | // We expect at least as many ZIR instructions and extra data items | 80 | // We expect at least as many ZIR instructions and extra data items |
| 85 | // as AST nodes. | 81 | // as AST nodes. |
| 86 | try astgen.instructions.ensureTotalCapacity(gpa, file.tree.nodes.len); | 82 | try astgen.instructions.ensureTotalCapacity(gpa, tree.nodes.len); |
| 87 | | 83 | |
| 88 | // First few indexes of extra are reserved and set at the end. | 84 | // First few indexes of extra are reserved and set at the end. |
| 89 | const reserved_count = @typeInfo(Zir.ExtraIndex).Enum.fields.len; | 85 | const reserved_count = @typeInfo(Zir.ExtraIndex).Enum.fields.len; |
| 90 | try astgen.extra.ensureTotalCapacity(gpa, file.tree.nodes.len + reserved_count); | 86 | try astgen.extra.ensureTotalCapacity(gpa, tree.nodes.len + reserved_count); |
| 91 | astgen.extra.items.len += reserved_count; | 87 | astgen.extra.items.len += reserved_count; |
| 92 | | 88 | |
| 93 | var gen_scope: GenZir = .{ | 89 | var gen_scope: GenZir = .{ |
| 94 | .force_comptime = true, | 90 | .force_comptime = true, |
| 95 | .parent = &file.base, | 91 | .parent = null, |
| 96 | .decl_node_index = 0, | 92 | .decl_node_index = 0, |
| 97 | .decl_line = 0, | 93 | .decl_line = 0, |
| 98 | .astgen = &astgen, | 94 | .astgen = &astgen, |
| ... | @@ -104,7 +100,7 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir { | ... | @@ -104,7 +100,7 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir { |
| 104 | .ast = .{ | 100 | .ast = .{ |
| 105 | .main_token = undefined, | 101 | .main_token = undefined, |
| 106 | .enum_token = null, | 102 | .enum_token = null, |
| 107 | .members = file.tree.rootDecls(), | 103 | .members = tree.rootDecls(), |
| 108 | .arg = 0, | 104 | .arg = 0, |
| 109 | }, | 105 | }, |
| 110 | }; | 106 | }; |
| ... | @@ -250,7 +246,7 @@ pub const ResultLoc = union(enum) { | ... | @@ -250,7 +246,7 @@ pub const ResultLoc = union(enum) { |
| 250 | pub const align_rl: ResultLoc = .{ .ty = .u16_type }; | 246 | pub const align_rl: ResultLoc = .{ .ty = .u16_type }; |
| 251 | pub const bool_rl: ResultLoc = .{ .ty = .bool_type }; | 247 | pub const bool_rl: ResultLoc = .{ .ty = .bool_type }; |
| 252 | | 248 | |
| 253 | pub fn typeExpr(gz: *GenZir, scope: *Scope, type_node: ast.Node.Index) InnerError!Zir.Inst.Ref { | 249 | fn typeExpr(gz: *GenZir, scope: *Scope, type_node: ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 254 | const prev_force_comptime = gz.force_comptime; | 250 | const prev_force_comptime = gz.force_comptime; |
| 255 | gz.force_comptime = true; | 251 | gz.force_comptime = true; |
| 256 | const e = expr(gz, scope, .{ .ty = .type_type }, type_node); | 252 | const e = expr(gz, scope, .{ .ty = .type_type }, type_node); |
| ... | @@ -260,7 +256,7 @@ pub fn typeExpr(gz: *GenZir, scope: *Scope, type_node: ast.Node.Index) InnerErro | ... | @@ -260,7 +256,7 @@ pub fn typeExpr(gz: *GenZir, scope: *Scope, type_node: ast.Node.Index) InnerErro |
| 260 | | 256 | |
| 261 | fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref { | 257 | fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 262 | const astgen = gz.astgen; | 258 | const astgen = gz.astgen; |
| 263 | const tree = &astgen.file.tree; | 259 | const tree = astgen.tree; |
| 264 | const node_tags = tree.nodes.items(.tag); | 260 | const node_tags = tree.nodes.items(.tag); |
| 265 | const main_tokens = tree.nodes.items(.main_token); | 261 | const main_tokens = tree.nodes.items(.main_token); |
| 266 | switch (node_tags[node]) { | 262 | switch (node_tags[node]) { |
| ... | @@ -453,9 +449,9 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Ins | ... | @@ -453,9 +449,9 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Ins |
| 453 | /// When `rl` is discard, ptr, inferred_ptr, or inferred_ptr, the | 449 | /// When `rl` is discard, ptr, inferred_ptr, or inferred_ptr, the |
| 454 | /// result instruction can be used to inspect whether it is isNoReturn() but that is it, | 450 | /// result instruction can be used to inspect whether it is isNoReturn() but that is it, |
| 455 | /// it must otherwise not be used. | 451 | /// it must otherwise not be used. |
| 456 | pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref { | 452 | fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 457 | const astgen = gz.astgen; | 453 | const astgen = gz.astgen; |
| 458 | const tree = &astgen.file.tree; | 454 | const tree = astgen.tree; |
| 459 | const main_tokens = tree.nodes.items(.main_token); | 455 | const main_tokens = tree.nodes.items(.main_token); |
| 460 | const token_tags = tree.tokens.items(.tag); | 456 | const token_tags = tree.tokens.items(.tag); |
| 461 | const node_datas = tree.nodes.items(.data); | 457 | const node_datas = tree.nodes.items(.data); |
| ... | @@ -888,7 +884,7 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn | ... | @@ -888,7 +884,7 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn |
| 888 | } | 884 | } |
| 889 | } | 885 | } |
| 890 | | 886 | |
| 891 | pub fn nosuspendExpr( | 887 | fn nosuspendExpr( |
| 892 | gz: *GenZir, | 888 | gz: *GenZir, |
| 893 | scope: *Scope, | 889 | scope: *Scope, |
| 894 | rl: ResultLoc, | 890 | rl: ResultLoc, |
| ... | @@ -896,7 +892,7 @@ pub fn nosuspendExpr( | ... | @@ -896,7 +892,7 @@ pub fn nosuspendExpr( |
| 896 | ) InnerError!Zir.Inst.Ref { | 892 | ) InnerError!Zir.Inst.Ref { |
| 897 | const astgen = gz.astgen; | 893 | const astgen = gz.astgen; |
| 898 | const gpa = astgen.gpa; | 894 | const gpa = astgen.gpa; |
| 899 | const tree = &astgen.file.tree; | 895 | const tree = astgen.tree; |
| 900 | const node_datas = tree.nodes.items(.data); | 896 | const node_datas = tree.nodes.items(.data); |
| 901 | const body_node = node_datas[node].lhs; | 897 | const body_node = node_datas[node].lhs; |
| 902 | assert(body_node != 0); | 898 | assert(body_node != 0); |
| ... | @@ -911,7 +907,7 @@ pub fn nosuspendExpr( | ... | @@ -911,7 +907,7 @@ pub fn nosuspendExpr( |
| 911 | return rvalue(gz, scope, rl, result, node); | 907 | return rvalue(gz, scope, rl, result, node); |
| 912 | } | 908 | } |
| 913 | | 909 | |
| 914 | pub fn suspendExpr( | 910 | fn suspendExpr( |
| 915 | gz: *GenZir, | 911 | gz: *GenZir, |
| 916 | scope: *Scope, | 912 | scope: *Scope, |
| 917 | rl: ResultLoc, | 913 | rl: ResultLoc, |
| ... | @@ -919,7 +915,7 @@ pub fn suspendExpr( | ... | @@ -919,7 +915,7 @@ pub fn suspendExpr( |
| 919 | ) InnerError!Zir.Inst.Ref { | 915 | ) InnerError!Zir.Inst.Ref { |
| 920 | const astgen = gz.astgen; | 916 | const astgen = gz.astgen; |
| 921 | const gpa = astgen.gpa; | 917 | const gpa = astgen.gpa; |
| 922 | const tree = &astgen.file.tree; | 918 | const tree = astgen.tree; |
| 923 | const node_datas = tree.nodes.items(.data); | 919 | const node_datas = tree.nodes.items(.data); |
| 924 | const body_node = node_datas[node].lhs; | 920 | const body_node = node_datas[node].lhs; |
| 925 | | 921 | |
| ... | @@ -951,14 +947,14 @@ pub fn suspendExpr( | ... | @@ -951,14 +947,14 @@ pub fn suspendExpr( |
| 951 | return gz.indexToRef(suspend_inst); | 947 | return gz.indexToRef(suspend_inst); |
| 952 | } | 948 | } |
| 953 | | 949 | |
| 954 | pub fn awaitExpr( | 950 | fn awaitExpr( |
| 955 | gz: *GenZir, | 951 | gz: *GenZir, |
| 956 | scope: *Scope, | 952 | scope: *Scope, |
| 957 | rl: ResultLoc, | 953 | rl: ResultLoc, |
| 958 | node: ast.Node.Index, | 954 | node: ast.Node.Index, |
| 959 | ) InnerError!Zir.Inst.Ref { | 955 | ) InnerError!Zir.Inst.Ref { |
| 960 | const astgen = gz.astgen; | 956 | const astgen = gz.astgen; |
| 961 | const tree = &astgen.file.tree; | 957 | const tree = astgen.tree; |
| 962 | const node_datas = tree.nodes.items(.data); | 958 | const node_datas = tree.nodes.items(.data); |
| 963 | const rhs_node = node_datas[node].lhs; | 959 | const rhs_node = node_datas[node].lhs; |
| 964 | | 960 | |
| ... | @@ -973,14 +969,14 @@ pub fn awaitExpr( | ... | @@ -973,14 +969,14 @@ pub fn awaitExpr( |
| 973 | return rvalue(gz, scope, rl, result, node); | 969 | return rvalue(gz, scope, rl, result, node); |
| 974 | } | 970 | } |
| 975 | | 971 | |
| 976 | pub fn resumeExpr( | 972 | fn resumeExpr( |
| 977 | gz: *GenZir, | 973 | gz: *GenZir, |
| 978 | scope: *Scope, | 974 | scope: *Scope, |
| 979 | rl: ResultLoc, | 975 | rl: ResultLoc, |
| 980 | node: ast.Node.Index, | 976 | node: ast.Node.Index, |
| 981 | ) InnerError!Zir.Inst.Ref { | 977 | ) InnerError!Zir.Inst.Ref { |
| 982 | const astgen = gz.astgen; | 978 | const astgen = gz.astgen; |
| 983 | const tree = &astgen.file.tree; | 979 | const tree = astgen.tree; |
| 984 | const node_datas = tree.nodes.items(.data); | 980 | const node_datas = tree.nodes.items(.data); |
| 985 | const rhs_node = node_datas[node].lhs; | 981 | const rhs_node = node_datas[node].lhs; |
| 986 | const operand = try expr(gz, scope, .none, rhs_node); | 982 | const operand = try expr(gz, scope, .none, rhs_node); |
| ... | @@ -988,7 +984,7 @@ pub fn resumeExpr( | ... | @@ -988,7 +984,7 @@ pub fn resumeExpr( |
| 988 | return rvalue(gz, scope, rl, result, node); | 984 | return rvalue(gz, scope, rl, result, node); |
| 989 | } | 985 | } |
| 990 | | 986 | |
| 991 | pub fn fnProtoExpr( | 987 | fn fnProtoExpr( |
| 992 | gz: *GenZir, | 988 | gz: *GenZir, |
| 993 | scope: *Scope, | 989 | scope: *Scope, |
| 994 | rl: ResultLoc, | 990 | rl: ResultLoc, |
| ... | @@ -996,7 +992,7 @@ pub fn fnProtoExpr( | ... | @@ -996,7 +992,7 @@ pub fn fnProtoExpr( |
| 996 | ) InnerError!Zir.Inst.Ref { | 992 | ) InnerError!Zir.Inst.Ref { |
| 997 | const astgen = gz.astgen; | 993 | const astgen = gz.astgen; |
| 998 | const gpa = astgen.gpa; | 994 | const gpa = astgen.gpa; |
| 999 | const tree = &astgen.file.tree; | 995 | const tree = astgen.tree; |
| 1000 | const token_tags = tree.tokens.items(.tag); | 996 | const token_tags = tree.tokens.items(.tag); |
| 1001 | | 997 | |
| 1002 | const is_extern = blk: { | 998 | const is_extern = blk: { |
| ... | @@ -1093,7 +1089,7 @@ pub fn fnProtoExpr( | ... | @@ -1093,7 +1089,7 @@ pub fn fnProtoExpr( |
| 1093 | return rvalue(gz, scope, rl, result, fn_proto.ast.proto_node); | 1089 | return rvalue(gz, scope, rl, result, fn_proto.ast.proto_node); |
| 1094 | } | 1090 | } |
| 1095 | | 1091 | |
| 1096 | pub fn arrayInitExpr( | 1092 | fn arrayInitExpr( |
| 1097 | gz: *GenZir, | 1093 | gz: *GenZir, |
| 1098 | scope: *Scope, | 1094 | scope: *Scope, |
| 1099 | rl: ResultLoc, | 1095 | rl: ResultLoc, |
| ... | @@ -1101,7 +1097,7 @@ pub fn arrayInitExpr( | ... | @@ -1101,7 +1097,7 @@ pub fn arrayInitExpr( |
| 1101 | array_init: ast.full.ArrayInit, | 1097 | array_init: ast.full.ArrayInit, |
| 1102 | ) InnerError!Zir.Inst.Ref { | 1098 | ) InnerError!Zir.Inst.Ref { |
| 1103 | const astgen = gz.astgen; | 1099 | const astgen = gz.astgen; |
| 1104 | const tree = &astgen.file.tree; | 1100 | const tree = astgen.tree; |
| 1105 | const gpa = astgen.gpa; | 1101 | const gpa = astgen.gpa; |
| 1106 | const node_tags = tree.nodes.items(.tag); | 1102 | const node_tags = tree.nodes.items(.tag); |
| 1107 | const main_tokens = tree.nodes.items(.main_token); | 1103 | const main_tokens = tree.nodes.items(.main_token); |
| ... | @@ -1192,7 +1188,7 @@ pub fn arrayInitExpr( | ... | @@ -1192,7 +1188,7 @@ pub fn arrayInitExpr( |
| 1192 | } | 1188 | } |
| 1193 | } | 1189 | } |
| 1194 | | 1190 | |
| 1195 | pub fn arrayInitExprRlNone( | 1191 | fn arrayInitExprRlNone( |
| 1196 | gz: *GenZir, | 1192 | gz: *GenZir, |
| 1197 | scope: *Scope, | 1193 | scope: *Scope, |
| 1198 | rl: ResultLoc, | 1194 | rl: ResultLoc, |
| ... | @@ -1215,7 +1211,7 @@ pub fn arrayInitExprRlNone( | ... | @@ -1215,7 +1211,7 @@ pub fn arrayInitExprRlNone( |
| 1215 | return init_inst; | 1211 | return init_inst; |
| 1216 | } | 1212 | } |
| 1217 | | 1213 | |
| 1218 | pub fn arrayInitExprRlTy( | 1214 | fn arrayInitExprRlTy( |
| 1219 | gz: *GenZir, | 1215 | gz: *GenZir, |
| 1220 | scope: *Scope, | 1216 | scope: *Scope, |
| 1221 | rl: ResultLoc, | 1217 | rl: ResultLoc, |
| ... | @@ -1243,7 +1239,7 @@ pub fn arrayInitExprRlTy( | ... | @@ -1243,7 +1239,7 @@ pub fn arrayInitExprRlTy( |
| 1243 | return init_inst; | 1239 | return init_inst; |
| 1244 | } | 1240 | } |
| 1245 | | 1241 | |
| 1246 | pub fn arrayInitExprRlPtr( | 1242 | fn arrayInitExprRlPtr( |
| 1247 | gz: *GenZir, | 1243 | gz: *GenZir, |
| 1248 | scope: *Scope, | 1244 | scope: *Scope, |
| 1249 | rl: ResultLoc, | 1245 | rl: ResultLoc, |
| ... | @@ -1273,7 +1269,7 @@ pub fn arrayInitExprRlPtr( | ... | @@ -1273,7 +1269,7 @@ pub fn arrayInitExprRlPtr( |
| 1273 | return .void_value; | 1269 | return .void_value; |
| 1274 | } | 1270 | } |
| 1275 | | 1271 | |
| 1276 | pub fn structInitExpr( | 1272 | fn structInitExpr( |
| 1277 | gz: *GenZir, | 1273 | gz: *GenZir, |
| 1278 | scope: *Scope, | 1274 | scope: *Scope, |
| 1279 | rl: ResultLoc, | 1275 | rl: ResultLoc, |
| ... | @@ -1281,7 +1277,7 @@ pub fn structInitExpr( | ... | @@ -1281,7 +1277,7 @@ pub fn structInitExpr( |
| 1281 | struct_init: ast.full.StructInit, | 1277 | struct_init: ast.full.StructInit, |
| 1282 | ) InnerError!Zir.Inst.Ref { | 1278 | ) InnerError!Zir.Inst.Ref { |
| 1283 | const astgen = gz.astgen; | 1279 | const astgen = gz.astgen; |
| 1284 | const tree = &astgen.file.tree; | 1280 | const tree = astgen.tree; |
| 1285 | const gpa = astgen.gpa; | 1281 | const gpa = astgen.gpa; |
| 1286 | | 1282 | |
| 1287 | if (struct_init.ast.fields.len == 0) { | 1283 | if (struct_init.ast.fields.len == 0) { |
| ... | @@ -1351,7 +1347,7 @@ pub fn structInitExpr( | ... | @@ -1351,7 +1347,7 @@ pub fn structInitExpr( |
| 1351 | } | 1347 | } |
| 1352 | } | 1348 | } |
| 1353 | | 1349 | |
| 1354 | pub fn structInitExprRlNone( | 1350 | fn structInitExprRlNone( |
| 1355 | gz: *GenZir, | 1351 | gz: *GenZir, |
| 1356 | scope: *Scope, | 1352 | scope: *Scope, |
| 1357 | rl: ResultLoc, | 1353 | rl: ResultLoc, |
| ... | @@ -1361,7 +1357,7 @@ pub fn structInitExprRlNone( | ... | @@ -1361,7 +1357,7 @@ pub fn structInitExprRlNone( |
| 1361 | ) InnerError!Zir.Inst.Ref { | 1357 | ) InnerError!Zir.Inst.Ref { |
| 1362 | const astgen = gz.astgen; | 1358 | const astgen = gz.astgen; |
| 1363 | const gpa = astgen.gpa; | 1359 | const gpa = astgen.gpa; |
| 1364 | const tree = &astgen.file.tree; | 1360 | const tree = astgen.tree; |
| 1365 | | 1361 | |
| 1366 | const fields_list = try gpa.alloc(Zir.Inst.StructInitAnon.Item, struct_init.ast.fields.len); | 1362 | const fields_list = try gpa.alloc(Zir.Inst.StructInitAnon.Item, struct_init.ast.fields.len); |
| 1367 | defer gpa.free(fields_list); | 1363 | defer gpa.free(fields_list); |
| ... | @@ -1386,7 +1382,7 @@ pub fn structInitExprRlNone( | ... | @@ -1386,7 +1382,7 @@ pub fn structInitExprRlNone( |
| 1386 | return init_inst; | 1382 | return init_inst; |
| 1387 | } | 1383 | } |
| 1388 | | 1384 | |
| 1389 | pub fn structInitExprRlPtr( | 1385 | fn structInitExprRlPtr( |
| 1390 | gz: *GenZir, | 1386 | gz: *GenZir, |
| 1391 | scope: *Scope, | 1387 | scope: *Scope, |
| 1392 | rl: ResultLoc, | 1388 | rl: ResultLoc, |
| ... | @@ -1396,7 +1392,7 @@ pub fn structInitExprRlPtr( | ... | @@ -1396,7 +1392,7 @@ pub fn structInitExprRlPtr( |
| 1396 | ) InnerError!Zir.Inst.Ref { | 1392 | ) InnerError!Zir.Inst.Ref { |
| 1397 | const astgen = gz.astgen; | 1393 | const astgen = gz.astgen; |
| 1398 | const gpa = astgen.gpa; | 1394 | const gpa = astgen.gpa; |
| 1399 | const tree = &astgen.file.tree; | 1395 | const tree = astgen.tree; |
| 1400 | | 1396 | |
| 1401 | const field_ptr_list = try gpa.alloc(Zir.Inst.Index, struct_init.ast.fields.len); | 1397 | const field_ptr_list = try gpa.alloc(Zir.Inst.Index, struct_init.ast.fields.len); |
| 1402 | defer gpa.free(field_ptr_list); | 1398 | defer gpa.free(field_ptr_list); |
| ... | @@ -1418,7 +1414,7 @@ pub fn structInitExprRlPtr( | ... | @@ -1418,7 +1414,7 @@ pub fn structInitExprRlPtr( |
| 1418 | return .void_value; | 1414 | return .void_value; |
| 1419 | } | 1415 | } |
| 1420 | | 1416 | |
| 1421 | pub fn structInitExprRlTy( | 1417 | fn structInitExprRlTy( |
| 1422 | gz: *GenZir, | 1418 | gz: *GenZir, |
| 1423 | scope: *Scope, | 1419 | scope: *Scope, |
| 1424 | rl: ResultLoc, | 1420 | rl: ResultLoc, |
| ... | @@ -1429,7 +1425,7 @@ pub fn structInitExprRlTy( | ... | @@ -1429,7 +1425,7 @@ pub fn structInitExprRlTy( |
| 1429 | ) InnerError!Zir.Inst.Ref { | 1425 | ) InnerError!Zir.Inst.Ref { |
| 1430 | const astgen = gz.astgen; | 1426 | const astgen = gz.astgen; |
| 1431 | const gpa = astgen.gpa; | 1427 | const gpa = astgen.gpa; |
| 1432 | const tree = &astgen.file.tree; | 1428 | const tree = astgen.tree; |
| 1433 | | 1429 | |
| 1434 | const fields_list = try gpa.alloc(Zir.Inst.StructInit.Item, struct_init.ast.fields.len); | 1430 | const fields_list = try gpa.alloc(Zir.Inst.StructInit.Item, struct_init.ast.fields.len); |
| 1435 | defer gpa.free(fields_list); | 1431 | defer gpa.free(fields_list); |
| ... | @@ -1486,7 +1482,7 @@ fn comptimeExprAst( | ... | @@ -1486,7 +1482,7 @@ fn comptimeExprAst( |
| 1486 | if (gz.force_comptime) { | 1482 | if (gz.force_comptime) { |
| 1487 | return astgen.failNode(node, "redundant comptime keyword in already comptime scope", .{}); | 1483 | return astgen.failNode(node, "redundant comptime keyword in already comptime scope", .{}); |
| 1488 | } | 1484 | } |
| 1489 | const tree = &astgen.file.tree; | 1485 | const tree = astgen.tree; |
| 1490 | const node_datas = tree.nodes.items(.data); | 1486 | const node_datas = tree.nodes.items(.data); |
| 1491 | const body_node = node_datas[node].lhs; | 1487 | const body_node = node_datas[node].lhs; |
| 1492 | gz.force_comptime = true; | 1488 | gz.force_comptime = true; |
| ... | @@ -1497,7 +1493,7 @@ fn comptimeExprAst( | ... | @@ -1497,7 +1493,7 @@ fn comptimeExprAst( |
| 1497 | | 1493 | |
| 1498 | fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref { | 1494 | fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 1499 | const astgen = parent_gz.astgen; | 1495 | const astgen = parent_gz.astgen; |
| 1500 | const tree = &astgen.file.tree; | 1496 | const tree = astgen.tree; |
| 1501 | const node_datas = tree.nodes.items(.data); | 1497 | const node_datas = tree.nodes.items(.data); |
| 1502 | const break_label = node_datas[node].lhs; | 1498 | const break_label = node_datas[node].lhs; |
| 1503 | const rhs = node_datas[node].rhs; | 1499 | const rhs = node_datas[node].rhs; |
| ... | @@ -1520,7 +1516,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn | ... | @@ -1520,7 +1516,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn |
| 1520 | } else if (block_gz.break_block != 0) { | 1516 | } else if (block_gz.break_block != 0) { |
| 1521 | break :blk block_gz.break_block; | 1517 | break :blk block_gz.break_block; |
| 1522 | } | 1518 | } |
| 1523 | scope = block_gz.parent; | 1519 | scope = block_gz.parent orelse break; |
| 1524 | continue; | 1520 | continue; |
| 1525 | }; | 1521 | }; |
| 1526 | | 1522 | |
| ... | @@ -1558,19 +1554,19 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn | ... | @@ -1558,19 +1554,19 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn |
| 1558 | try unusedResultExpr(parent_gz, defer_scope.parent, expr_node); | 1554 | try unusedResultExpr(parent_gz, defer_scope.parent, expr_node); |
| 1559 | }, | 1555 | }, |
| 1560 | .defer_error => scope = scope.cast(Scope.Defer).?.parent, | 1556 | .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| 1561 | else => if (break_label != 0) { | | |
| 1562 | const label_name = try astgen.identifierTokenString(break_label); | | |
| 1563 | return astgen.failTok(break_label, "label not found: '{s}'", .{label_name}); | | |
| 1564 | } else { | | |
| 1565 | return astgen.failNode(node, "break expression outside loop", .{}); | | |
| 1566 | }, | | |
| 1567 | } | 1557 | } |
| 1568 | } | 1558 | } |
| | 1559 | if (break_label != 0) { |
| | 1560 | const label_name = try astgen.identifierTokenString(break_label); |
| | 1561 | return astgen.failTok(break_label, "label not found: '{s}'", .{label_name}); |
| | 1562 | } else { |
| | 1563 | return astgen.failNode(node, "break expression outside loop", .{}); |
| | 1564 | } |
| 1569 | } | 1565 | } |
| 1570 | | 1566 | |
| 1571 | fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref { | 1567 | fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 1572 | const astgen = parent_gz.astgen; | 1568 | const astgen = parent_gz.astgen; |
| 1573 | const tree = &astgen.file.tree; | 1569 | const tree = astgen.tree; |
| 1574 | const node_datas = tree.nodes.items(.data); | 1570 | const node_datas = tree.nodes.items(.data); |
| 1575 | const break_label = node_datas[node].lhs; | 1571 | const break_label = node_datas[node].lhs; |
| 1576 | | 1572 | |
| ... | @@ -1582,7 +1578,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) | ... | @@ -1582,7 +1578,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) |
| 1582 | const gen_zir = scope.cast(GenZir).?; | 1578 | const gen_zir = scope.cast(GenZir).?; |
| 1583 | const continue_block = gen_zir.continue_block; | 1579 | const continue_block = gen_zir.continue_block; |
| 1584 | if (continue_block == 0) { | 1580 | if (continue_block == 0) { |
| 1585 | scope = gen_zir.parent; | 1581 | scope = gen_zir.parent orelse break; |
| 1586 | continue; | 1582 | continue; |
| 1587 | } | 1583 | } |
| 1588 | if (break_label != 0) blk: { | 1584 | if (break_label != 0) blk: { |
| ... | @@ -1593,7 +1589,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) | ... | @@ -1593,7 +1589,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) |
| 1593 | } | 1589 | } |
| 1594 | } | 1590 | } |
| 1595 | // found continue but either it has a different label, or no label | 1591 | // found continue but either it has a different label, or no label |
| 1596 | scope = gen_zir.parent; | 1592 | scope = gen_zir.parent orelse break; |
| 1597 | continue; | 1593 | continue; |
| 1598 | } | 1594 | } |
| 1599 | | 1595 | |
| ... | @@ -1610,17 +1606,17 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) | ... | @@ -1610,17 +1606,17 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) |
| 1610 | try unusedResultExpr(parent_gz, defer_scope.parent, expr_node); | 1606 | try unusedResultExpr(parent_gz, defer_scope.parent, expr_node); |
| 1611 | }, | 1607 | }, |
| 1612 | .defer_error => scope = scope.cast(Scope.Defer).?.parent, | 1608 | .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| 1613 | else => if (break_label != 0) { | | |
| 1614 | const label_name = try astgen.identifierTokenString(break_label); | | |
| 1615 | return astgen.failTok(break_label, "label not found: '{s}'", .{label_name}); | | |
| 1616 | } else { | | |
| 1617 | return astgen.failNode(node, "continue expression outside loop", .{}); | | |
| 1618 | }, | | |
| 1619 | } | 1609 | } |
| 1620 | } | 1610 | } |
| | 1611 | if (break_label != 0) { |
| | 1612 | const label_name = try astgen.identifierTokenString(break_label); |
| | 1613 | return astgen.failTok(break_label, "label not found: '{s}'", .{label_name}); |
| | 1614 | } else { |
| | 1615 | return astgen.failNode(node, "continue expression outside loop", .{}); |
| | 1616 | } |
| 1621 | } | 1617 | } |
| 1622 | | 1618 | |
| 1623 | pub fn blockExpr( | 1619 | fn blockExpr( |
| 1624 | gz: *GenZir, | 1620 | gz: *GenZir, |
| 1625 | scope: *Scope, | 1621 | scope: *Scope, |
| 1626 | rl: ResultLoc, | 1622 | rl: ResultLoc, |
| ... | @@ -1631,7 +1627,7 @@ pub fn blockExpr( | ... | @@ -1631,7 +1627,7 @@ pub fn blockExpr( |
| 1631 | defer tracy.end(); | 1627 | defer tracy.end(); |
| 1632 | | 1628 | |
| 1633 | const astgen = gz.astgen; | 1629 | const astgen = gz.astgen; |
| 1634 | const tree = &astgen.file.tree; | 1630 | const tree = astgen.tree; |
| 1635 | const main_tokens = tree.nodes.items(.main_token); | 1631 | const main_tokens = tree.nodes.items(.main_token); |
| 1636 | const token_tags = tree.tokens.items(.tag); | 1632 | const token_tags = tree.tokens.items(.tag); |
| 1637 | | 1633 | |
| ... | @@ -1655,7 +1651,7 @@ fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: ast.Toke | ... | @@ -1655,7 +1651,7 @@ fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: ast.Toke |
| 1655 | const gen_zir = scope.cast(GenZir).?; | 1651 | const gen_zir = scope.cast(GenZir).?; |
| 1656 | if (gen_zir.label) |prev_label| { | 1652 | if (gen_zir.label) |prev_label| { |
| 1657 | if (try astgen.tokenIdentEql(label, prev_label.token)) { | 1653 | if (try astgen.tokenIdentEql(label, prev_label.token)) { |
| 1658 | const tree = &astgen.file.tree; | 1654 | const tree = astgen.tree; |
| 1659 | const main_tokens = tree.nodes.items(.main_token); | 1655 | const main_tokens = tree.nodes.items(.main_token); |
| 1660 | | 1656 | |
| 1661 | const label_name = try astgen.identifierTokenString(label); | 1657 | const label_name = try astgen.identifierTokenString(label); |
| ... | @@ -1670,12 +1666,11 @@ fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: ast.Toke | ... | @@ -1670,12 +1666,11 @@ fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: ast.Toke |
| 1670 | }); | 1666 | }); |
| 1671 | } | 1667 | } |
| 1672 | } | 1668 | } |
| 1673 | scope = gen_zir.parent; | 1669 | scope = gen_zir.parent orelse return; |
| 1674 | }, | 1670 | }, |
| 1675 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, | 1671 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 1676 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, | 1672 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 1677 | .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent, | 1673 | .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| 1678 | else => return, | | |
| 1679 | } | 1674 | } |
| 1680 | } | 1675 | } |
| 1681 | } | 1676 | } |
| ... | @@ -1694,7 +1689,7 @@ fn labeledBlockExpr( | ... | @@ -1694,7 +1689,7 @@ fn labeledBlockExpr( |
| 1694 | assert(zir_tag == .block); | 1689 | assert(zir_tag == .block); |
| 1695 | | 1690 | |
| 1696 | const astgen = gz.astgen; | 1691 | const astgen = gz.astgen; |
| 1697 | const tree = &astgen.file.tree; | 1692 | const tree = astgen.tree; |
| 1698 | const main_tokens = tree.nodes.items(.main_token); | 1693 | const main_tokens = tree.nodes.items(.main_token); |
| 1699 | const token_tags = tree.tokens.items(.tag); | 1694 | const token_tags = tree.tokens.items(.tag); |
| 1700 | | 1695 | |
| ... | @@ -1768,7 +1763,7 @@ fn blockExprStmts( | ... | @@ -1768,7 +1763,7 @@ fn blockExprStmts( |
| 1768 | statements: []const ast.Node.Index, | 1763 | statements: []const ast.Node.Index, |
| 1769 | ) !void { | 1764 | ) !void { |
| 1770 | const astgen = gz.astgen; | 1765 | const astgen = gz.astgen; |
| 1771 | const tree = &astgen.file.tree; | 1766 | const tree = astgen.tree; |
| 1772 | const main_tokens = tree.nodes.items(.main_token); | 1767 | const main_tokens = tree.nodes.items(.main_token); |
| 1773 | const node_tags = tree.nodes.items(.tag); | 1768 | const node_tags = tree.nodes.items(.tag); |
| 1774 | | 1769 | |
| ... | @@ -2108,13 +2103,13 @@ fn genDefers( | ... | @@ -2108,13 +2103,13 @@ fn genDefers( |
| 2108 | err_code: Zir.Inst.Ref, | 2103 | err_code: Zir.Inst.Ref, |
| 2109 | ) InnerError!void { | 2104 | ) InnerError!void { |
| 2110 | const astgen = gz.astgen; | 2105 | const astgen = gz.astgen; |
| 2111 | const tree = &astgen.file.tree; | 2106 | const tree = astgen.tree; |
| 2112 | const node_datas = tree.nodes.items(.data); | 2107 | const node_datas = tree.nodes.items(.data); |
| 2113 | | 2108 | |
| 2114 | var scope = inner_scope; | 2109 | var scope = inner_scope; |
| 2115 | while (scope != outer_scope) { | 2110 | while (scope != outer_scope) { |
| 2116 | switch (scope.tag) { | 2111 | switch (scope.tag) { |
| 2117 | .gen_zir => scope = scope.cast(GenZir).?.parent, | 2112 | .gen_zir => scope = scope.cast(GenZir).?.parent.?, |
| 2118 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, | 2113 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 2119 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, | 2114 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 2120 | .defer_normal => { | 2115 | .defer_normal => { |
| ... | @@ -2130,7 +2125,6 @@ fn genDefers( | ... | @@ -2130,7 +2125,6 @@ fn genDefers( |
| 2130 | const expr_node = node_datas[defer_scope.defer_node].rhs; | 2125 | const expr_node = node_datas[defer_scope.defer_node].rhs; |
| 2131 | try unusedResultExpr(gz, defer_scope.parent, expr_node); | 2126 | try unusedResultExpr(gz, defer_scope.parent, expr_node); |
| 2132 | }, | 2127 | }, |
| 2133 | else => unreachable, | | |
| 2134 | } | 2128 | } |
| 2135 | } | 2129 | } |
| 2136 | } | 2130 | } |
| ... | @@ -2161,7 +2155,7 @@ fn varDecl( | ... | @@ -2161,7 +2155,7 @@ fn varDecl( |
| 2161 | try emitDbgNode(gz, node); | 2155 | try emitDbgNode(gz, node); |
| 2162 | const astgen = gz.astgen; | 2156 | const astgen = gz.astgen; |
| 2163 | const gpa = astgen.gpa; | 2157 | const gpa = astgen.gpa; |
| 2164 | const tree = &astgen.file.tree; | 2158 | const tree = astgen.tree; |
| 2165 | const token_tags = tree.tokens.items(.tag); | 2159 | const token_tags = tree.tokens.items(.tag); |
| 2166 | | 2160 | |
| 2167 | const name_token = var_decl.ast.mut_token + 1; | 2161 | const name_token = var_decl.ast.mut_token + 1; |
| ... | @@ -2201,10 +2195,8 @@ fn varDecl( | ... | @@ -2201,10 +2195,8 @@ fn varDecl( |
| 2201 | } | 2195 | } |
| 2202 | s = local_ptr.parent; | 2196 | s = local_ptr.parent; |
| 2203 | }, | 2197 | }, |
| 2204 | .gen_zir => s = s.cast(GenZir).?.parent, | 2198 | .gen_zir => s = s.cast(GenZir).?.parent orelse break, |
| 2205 | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, | 2199 | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, |
| 2206 | .file => break, | | |
| 2207 | else => unreachable, | | |
| 2208 | }; | 2200 | }; |
| 2209 | } | 2201 | } |
| 2210 | | 2202 | |
| ... | @@ -2402,7 +2394,7 @@ fn emitDbgNode(gz: *GenZir, node: ast.Node.Index) !void { | ... | @@ -2402,7 +2394,7 @@ fn emitDbgNode(gz: *GenZir, node: ast.Node.Index) !void { |
| 2402 | if (gz.force_comptime) return; | 2394 | if (gz.force_comptime) return; |
| 2403 | | 2395 | |
| 2404 | const astgen = gz.astgen; | 2396 | const astgen = gz.astgen; |
| 2405 | const tree = &astgen.file.tree; | 2397 | const tree = astgen.tree; |
| 2406 | const node_tags = tree.nodes.items(.tag); | 2398 | const node_tags = tree.nodes.items(.tag); |
| 2407 | const token_starts = tree.tokens.items(.start); | 2399 | const token_starts = tree.tokens.items(.start); |
| 2408 | const decl_start = token_starts[tree.firstToken(gz.decl_node_index)]; | 2400 | const decl_start = token_starts[tree.firstToken(gz.decl_node_index)]; |
| ... | @@ -2420,7 +2412,7 @@ fn emitDbgNode(gz: *GenZir, node: ast.Node.Index) !void { | ... | @@ -2420,7 +2412,7 @@ fn emitDbgNode(gz: *GenZir, node: ast.Node.Index) !void { |
| 2420 | fn assign(gz: *GenZir, scope: *Scope, infix_node: ast.Node.Index) InnerError!void { | 2412 | fn assign(gz: *GenZir, scope: *Scope, infix_node: ast.Node.Index) InnerError!void { |
| 2421 | try emitDbgNode(gz, infix_node); | 2413 | try emitDbgNode(gz, infix_node); |
| 2422 | const astgen = gz.astgen; | 2414 | const astgen = gz.astgen; |
| 2423 | const tree = &astgen.file.tree; | 2415 | const tree = astgen.tree; |
| 2424 | const node_datas = tree.nodes.items(.data); | 2416 | const node_datas = tree.nodes.items(.data); |
| 2425 | const main_tokens = tree.nodes.items(.main_token); | 2417 | const main_tokens = tree.nodes.items(.main_token); |
| 2426 | const node_tags = tree.nodes.items(.tag); | 2418 | const node_tags = tree.nodes.items(.tag); |
| ... | @@ -2447,7 +2439,7 @@ fn assignOp( | ... | @@ -2447,7 +2439,7 @@ fn assignOp( |
| 2447 | ) InnerError!void { | 2439 | ) InnerError!void { |
| 2448 | try emitDbgNode(gz, infix_node); | 2440 | try emitDbgNode(gz, infix_node); |
| 2449 | const astgen = gz.astgen; | 2441 | const astgen = gz.astgen; |
| 2450 | const tree = &astgen.file.tree; | 2442 | const tree = astgen.tree; |
| 2451 | const node_datas = tree.nodes.items(.data); | 2443 | const node_datas = tree.nodes.items(.data); |
| 2452 | | 2444 | |
| 2453 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); | 2445 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); |
| ... | @@ -2470,7 +2462,7 @@ fn assignShift( | ... | @@ -2470,7 +2462,7 @@ fn assignShift( |
| 2470 | ) InnerError!void { | 2462 | ) InnerError!void { |
| 2471 | try emitDbgNode(gz, infix_node); | 2463 | try emitDbgNode(gz, infix_node); |
| 2472 | const astgen = gz.astgen; | 2464 | const astgen = gz.astgen; |
| 2473 | const tree = &astgen.file.tree; | 2465 | const tree = astgen.tree; |
| 2474 | const node_datas = tree.nodes.items(.data); | 2466 | const node_datas = tree.nodes.items(.data); |
| 2475 | | 2467 | |
| 2476 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); | 2468 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); |
| ... | @@ -2487,7 +2479,7 @@ fn assignShift( | ... | @@ -2487,7 +2479,7 @@ fn assignShift( |
| 2487 | | 2479 | |
| 2488 | fn boolNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref { | 2480 | fn boolNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 2489 | const astgen = gz.astgen; | 2481 | const astgen = gz.astgen; |
| 2490 | const tree = &astgen.file.tree; | 2482 | const tree = astgen.tree; |
| 2491 | const node_datas = tree.nodes.items(.data); | 2483 | const node_datas = tree.nodes.items(.data); |
| 2492 | | 2484 | |
| 2493 | const operand = try expr(gz, scope, bool_rl, node_datas[node].lhs); | 2485 | const operand = try expr(gz, scope, bool_rl, node_datas[node].lhs); |
| ... | @@ -2497,7 +2489,7 @@ fn boolNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inne | ... | @@ -2497,7 +2489,7 @@ fn boolNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inne |
| 2497 | | 2489 | |
| 2498 | fn bitNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref { | 2490 | fn bitNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 2499 | const astgen = gz.astgen; | 2491 | const astgen = gz.astgen; |
| 2500 | const tree = &astgen.file.tree; | 2492 | const tree = astgen.tree; |
| 2501 | const node_datas = tree.nodes.items(.data); | 2493 | const node_datas = tree.nodes.items(.data); |
| 2502 | | 2494 | |
| 2503 | const operand = try expr(gz, scope, .none, node_datas[node].lhs); | 2495 | const operand = try expr(gz, scope, .none, node_datas[node].lhs); |
| ... | @@ -2513,7 +2505,7 @@ fn negation( | ... | @@ -2513,7 +2505,7 @@ fn negation( |
| 2513 | tag: Zir.Inst.Tag, | 2505 | tag: Zir.Inst.Tag, |
| 2514 | ) InnerError!Zir.Inst.Ref { | 2506 | ) InnerError!Zir.Inst.Ref { |
| 2515 | const astgen = gz.astgen; | 2507 | const astgen = gz.astgen; |
| 2516 | const tree = &astgen.file.tree; | 2508 | const tree = astgen.tree; |
| 2517 | const node_datas = tree.nodes.items(.data); | 2509 | const node_datas = tree.nodes.items(.data); |
| 2518 | | 2510 | |
| 2519 | const operand = try expr(gz, scope, .none, node_datas[node].lhs); | 2511 | const operand = try expr(gz, scope, .none, node_datas[node].lhs); |
| ... | @@ -2529,7 +2521,7 @@ fn ptrType( | ... | @@ -2529,7 +2521,7 @@ fn ptrType( |
| 2529 | ptr_info: ast.full.PtrType, | 2521 | ptr_info: ast.full.PtrType, |
| 2530 | ) InnerError!Zir.Inst.Ref { | 2522 | ) InnerError!Zir.Inst.Ref { |
| 2531 | const astgen = gz.astgen; | 2523 | const astgen = gz.astgen; |
| 2532 | const tree = &astgen.file.tree; | 2524 | const tree = astgen.tree; |
| 2533 | | 2525 | |
| 2534 | const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type); | 2526 | const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type); |
| 2535 | | 2527 | |
| ... | @@ -2612,7 +2604,7 @@ fn ptrType( | ... | @@ -2612,7 +2604,7 @@ fn ptrType( |
| 2612 | | 2604 | |
| 2613 | fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref { | 2605 | fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref { |
| 2614 | const astgen = gz.astgen; | 2606 | const astgen = gz.astgen; |
| 2615 | const tree = &astgen.file.tree; | 2607 | const tree = astgen.tree; |
| 2616 | const node_datas = tree.nodes.items(.data); | 2608 | const node_datas = tree.nodes.items(.data); |
| 2617 | const node_tags = tree.nodes.items(.tag); | 2609 | const node_tags = tree.nodes.items(.tag); |
| 2618 | const main_tokens = tree.nodes.items(.main_token); | 2610 | const main_tokens = tree.nodes.items(.main_token); |
| ... | @@ -2632,7 +2624,7 @@ fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Z | ... | @@ -2632,7 +2624,7 @@ fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Z |
| 2632 | | 2624 | |
| 2633 | fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref { | 2625 | fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref { |
| 2634 | const astgen = gz.astgen; | 2626 | const astgen = gz.astgen; |
| 2635 | const tree = &astgen.file.tree; | 2627 | const tree = astgen.tree; |
| 2636 | const node_datas = tree.nodes.items(.data); | 2628 | const node_datas = tree.nodes.items(.data); |
| 2637 | const node_tags = tree.nodes.items(.tag); | 2629 | const node_tags = tree.nodes.items(.tag); |
| 2638 | const main_tokens = tree.nodes.items(.main_token); | 2630 | const main_tokens = tree.nodes.items(.main_token); |
| ... | @@ -2696,7 +2688,7 @@ fn fnDecl( | ... | @@ -2696,7 +2688,7 @@ fn fnDecl( |
| 2696 | fn_proto: ast.full.FnProto, | 2688 | fn_proto: ast.full.FnProto, |
| 2697 | ) InnerError!void { | 2689 | ) InnerError!void { |
| 2698 | const gpa = astgen.gpa; | 2690 | const gpa = astgen.gpa; |
| 2699 | const tree = &astgen.file.tree; | 2691 | const tree = astgen.tree; |
| 2700 | const token_tags = tree.tokens.items(.tag); | 2692 | const token_tags = tree.tokens.items(.tag); |
| 2701 | | 2693 | |
| 2702 | // We insert this at the beginning so that its instruction index marks the | 2694 | // We insert this at the beginning so that its instruction index marks the |
| ... | @@ -2937,7 +2929,7 @@ fn globalVarDecl( | ... | @@ -2937,7 +2929,7 @@ fn globalVarDecl( |
| 2937 | var_decl: ast.full.VarDecl, | 2929 | var_decl: ast.full.VarDecl, |
| 2938 | ) InnerError!void { | 2930 | ) InnerError!void { |
| 2939 | const gpa = astgen.gpa; | 2931 | const gpa = astgen.gpa; |
| 2940 | const tree = &astgen.file.tree; | 2932 | const tree = astgen.tree; |
| 2941 | const token_tags = tree.tokens.items(.tag); | 2933 | const token_tags = tree.tokens.items(.tag); |
| 2942 | | 2934 | |
| 2943 | const is_mutable = token_tags[var_decl.ast.mut_token] == .keyword_var; | 2935 | const is_mutable = token_tags[var_decl.ast.mut_token] == .keyword_var; |
| ... | @@ -3076,7 +3068,7 @@ fn comptimeDecl( | ... | @@ -3076,7 +3068,7 @@ fn comptimeDecl( |
| 3076 | node: ast.Node.Index, | 3068 | node: ast.Node.Index, |
| 3077 | ) InnerError!void { | 3069 | ) InnerError!void { |
| 3078 | const gpa = astgen.gpa; | 3070 | const gpa = astgen.gpa; |
| 3079 | const tree = &astgen.file.tree; | 3071 | const tree = astgen.tree; |
| 3080 | const node_datas = tree.nodes.items(.data); | 3072 | const node_datas = tree.nodes.items(.data); |
| 3081 | const body_node = node_datas[node].lhs; | 3073 | const body_node = node_datas[node].lhs; |
| 3082 | | 3074 | |
| ... | @@ -3122,7 +3114,7 @@ fn usingnamespaceDecl( | ... | @@ -3122,7 +3114,7 @@ fn usingnamespaceDecl( |
| 3122 | node: ast.Node.Index, | 3114 | node: ast.Node.Index, |
| 3123 | ) InnerError!void { | 3115 | ) InnerError!void { |
| 3124 | const gpa = astgen.gpa; | 3116 | const gpa = astgen.gpa; |
| 3125 | const tree = &astgen.file.tree; | 3117 | const tree = astgen.tree; |
| 3126 | const node_datas = tree.nodes.items(.data); | 3118 | const node_datas = tree.nodes.items(.data); |
| 3127 | | 3119 | |
| 3128 | const type_expr = node_datas[node].lhs; | 3120 | const type_expr = node_datas[node].lhs; |
| ... | @@ -3172,7 +3164,7 @@ fn testDecl( | ... | @@ -3172,7 +3164,7 @@ fn testDecl( |
| 3172 | node: ast.Node.Index, | 3164 | node: ast.Node.Index, |
| 3173 | ) InnerError!void { | 3165 | ) InnerError!void { |
| 3174 | const gpa = astgen.gpa; | 3166 | const gpa = astgen.gpa; |
| 3175 | const tree = &astgen.file.tree; | 3167 | const tree = astgen.tree; |
| 3176 | const node_datas = tree.nodes.items(.data); | 3168 | const node_datas = tree.nodes.items(.data); |
| 3177 | const body_node = node_datas[node].rhs; | 3169 | const body_node = node_datas[node].rhs; |
| 3178 | | 3170 | |
| ... | @@ -3271,7 +3263,7 @@ fn structDeclInner( | ... | @@ -3271,7 +3263,7 @@ fn structDeclInner( |
| 3271 | | 3263 | |
| 3272 | const astgen = gz.astgen; | 3264 | const astgen = gz.astgen; |
| 3273 | const gpa = astgen.gpa; | 3265 | const gpa = astgen.gpa; |
| 3274 | const tree = &astgen.file.tree; | 3266 | const tree = astgen.tree; |
| 3275 | const node_tags = tree.nodes.items(.tag); | 3267 | const node_tags = tree.nodes.items(.tag); |
| 3276 | const node_datas = tree.nodes.items(.data); | 3268 | const node_datas = tree.nodes.items(.data); |
| 3277 | | 3269 | |
| ... | @@ -3483,7 +3475,7 @@ fn unionDeclInner( | ... | @@ -3483,7 +3475,7 @@ fn unionDeclInner( |
| 3483 | ) InnerError!Zir.Inst.Ref { | 3475 | ) InnerError!Zir.Inst.Ref { |
| 3484 | const astgen = gz.astgen; | 3476 | const astgen = gz.astgen; |
| 3485 | const gpa = astgen.gpa; | 3477 | const gpa = astgen.gpa; |
| 3486 | const tree = &astgen.file.tree; | 3478 | const tree = astgen.tree; |
| 3487 | const node_tags = tree.nodes.items(.tag); | 3479 | const node_tags = tree.nodes.items(.tag); |
| 3488 | const node_datas = tree.nodes.items(.data); | 3480 | const node_datas = tree.nodes.items(.data); |
| 3489 | | 3481 | |
| ... | @@ -3705,7 +3697,7 @@ fn containerDecl( | ... | @@ -3705,7 +3697,7 @@ fn containerDecl( |
| 3705 | ) InnerError!Zir.Inst.Ref { | 3697 | ) InnerError!Zir.Inst.Ref { |
| 3706 | const astgen = gz.astgen; | 3698 | const astgen = gz.astgen; |
| 3707 | const gpa = astgen.gpa; | 3699 | const gpa = astgen.gpa; |
| 3708 | const tree = &astgen.file.tree; | 3700 | const tree = astgen.tree; |
| 3709 | const token_tags = tree.tokens.items(.tag); | 3701 | const token_tags = tree.tokens.items(.tag); |
| 3710 | const node_tags = tree.nodes.items(.tag); | 3702 | const node_tags = tree.nodes.items(.tag); |
| 3711 | const node_datas = tree.nodes.items(.data); | 3703 | const node_datas = tree.nodes.items(.data); |
| ... | @@ -4149,7 +4141,7 @@ fn errorSetDecl( | ... | @@ -4149,7 +4141,7 @@ fn errorSetDecl( |
| 4149 | ) InnerError!Zir.Inst.Ref { | 4141 | ) InnerError!Zir.Inst.Ref { |
| 4150 | const astgen = gz.astgen; | 4142 | const astgen = gz.astgen; |
| 4151 | const gpa = astgen.gpa; | 4143 | const gpa = astgen.gpa; |
| 4152 | const tree = &astgen.file.tree; | 4144 | const tree = astgen.tree; |
| 4153 | const main_tokens = tree.nodes.items(.main_token); | 4145 | const main_tokens = tree.nodes.items(.main_token); |
| 4154 | const token_tags = tree.tokens.items(.tag); | 4146 | const token_tags = tree.tokens.items(.tag); |
| 4155 | | 4147 | |
| ... | @@ -4189,7 +4181,7 @@ fn tryExpr( | ... | @@ -4189,7 +4181,7 @@ fn tryExpr( |
| 4189 | operand_node: ast.Node.Index, | 4181 | operand_node: ast.Node.Index, |
| 4190 | ) InnerError!Zir.Inst.Ref { | 4182 | ) InnerError!Zir.Inst.Ref { |
| 4191 | const astgen = parent_gz.astgen; | 4183 | const astgen = parent_gz.astgen; |
| 4192 | const tree = &astgen.file.tree; | 4184 | const tree = astgen.tree; |
| 4193 | | 4185 | |
| 4194 | const fn_block = astgen.fn_block orelse { | 4186 | const fn_block = astgen.fn_block orelse { |
| 4195 | return astgen.failNode(node, "invalid 'try' outside function scope", .{}); | 4187 | return astgen.failNode(node, "invalid 'try' outside function scope", .{}); |
| ... | @@ -4272,7 +4264,7 @@ fn orelseCatchExpr( | ... | @@ -4272,7 +4264,7 @@ fn orelseCatchExpr( |
| 4272 | payload_token: ?ast.TokenIndex, | 4264 | payload_token: ?ast.TokenIndex, |
| 4273 | ) InnerError!Zir.Inst.Ref { | 4265 | ) InnerError!Zir.Inst.Ref { |
| 4274 | const astgen = parent_gz.astgen; | 4266 | const astgen = parent_gz.astgen; |
| 4275 | const tree = &astgen.file.tree; | 4267 | const tree = astgen.tree; |
| 4276 | | 4268 | |
| 4277 | var block_scope = parent_gz.makeSubBlock(scope); | 4269 | var block_scope = parent_gz.makeSubBlock(scope); |
| 4278 | block_scope.setBreakResultLoc(rl); | 4270 | block_scope.setBreakResultLoc(rl); |
| ... | @@ -4421,14 +4413,14 @@ fn tokenIdentEql(astgen: *AstGen, token1: ast.TokenIndex, token2: ast.TokenIndex | ... | @@ -4421,14 +4413,14 @@ fn tokenIdentEql(astgen: *AstGen, token1: ast.TokenIndex, token2: ast.TokenIndex |
| 4421 | return mem.eql(u8, ident_name_1, ident_name_2); | 4413 | return mem.eql(u8, ident_name_1, ident_name_2); |
| 4422 | } | 4414 | } |
| 4423 | | 4415 | |
| 4424 | pub fn fieldAccess( | 4416 | fn fieldAccess( |
| 4425 | gz: *GenZir, | 4417 | gz: *GenZir, |
| 4426 | scope: *Scope, | 4418 | scope: *Scope, |
| 4427 | rl: ResultLoc, | 4419 | rl: ResultLoc, |
| 4428 | node: ast.Node.Index, | 4420 | node: ast.Node.Index, |
| 4429 | ) InnerError!Zir.Inst.Ref { | 4421 | ) InnerError!Zir.Inst.Ref { |
| 4430 | const astgen = gz.astgen; | 4422 | const astgen = gz.astgen; |
| 4431 | const tree = &astgen.file.tree; | 4423 | const tree = astgen.tree; |
| 4432 | const main_tokens = tree.nodes.items(.main_token); | 4424 | const main_tokens = tree.nodes.items(.main_token); |
| 4433 | const node_datas = tree.nodes.items(.data); | 4425 | const node_datas = tree.nodes.items(.data); |
| 4434 | | 4426 | |
| ... | @@ -4455,7 +4447,7 @@ fn arrayAccess( | ... | @@ -4455,7 +4447,7 @@ fn arrayAccess( |
| 4455 | node: ast.Node.Index, | 4447 | node: ast.Node.Index, |
| 4456 | ) InnerError!Zir.Inst.Ref { | 4448 | ) InnerError!Zir.Inst.Ref { |
| 4457 | const astgen = gz.astgen; | 4449 | const astgen = gz.astgen; |
| 4458 | const tree = &astgen.file.tree; | 4450 | const tree = astgen.tree; |
| 4459 | const main_tokens = tree.nodes.items(.main_token); | 4451 | const main_tokens = tree.nodes.items(.main_token); |
| 4460 | const node_datas = tree.nodes.items(.data); | 4452 | const node_datas = tree.nodes.items(.data); |
| 4461 | switch (rl) { | 4453 | switch (rl) { |
| ... | @@ -4480,7 +4472,7 @@ fn simpleBinOp( | ... | @@ -4480,7 +4472,7 @@ fn simpleBinOp( |
| 4480 | op_inst_tag: Zir.Inst.Tag, | 4472 | op_inst_tag: Zir.Inst.Tag, |
| 4481 | ) InnerError!Zir.Inst.Ref { | 4473 | ) InnerError!Zir.Inst.Ref { |
| 4482 | const astgen = gz.astgen; | 4474 | const astgen = gz.astgen; |
| 4483 | const tree = &astgen.file.tree; | 4475 | const tree = astgen.tree; |
| 4484 | const node_datas = tree.nodes.items(.data); | 4476 | const node_datas = tree.nodes.items(.data); |
| 4485 | | 4477 | |
| 4486 | const result = try gz.addPlNode(op_inst_tag, node, Zir.Inst.Bin{ | 4478 | const result = try gz.addPlNode(op_inst_tag, node, Zir.Inst.Bin{ |
| ... | @@ -4512,7 +4504,7 @@ fn boolBinOp( | ... | @@ -4512,7 +4504,7 @@ fn boolBinOp( |
| 4512 | zir_tag: Zir.Inst.Tag, | 4504 | zir_tag: Zir.Inst.Tag, |
| 4513 | ) InnerError!Zir.Inst.Ref { | 4505 | ) InnerError!Zir.Inst.Ref { |
| 4514 | const astgen = gz.astgen; | 4506 | const astgen = gz.astgen; |
| 4515 | const tree = &astgen.file.tree; | 4507 | const tree = astgen.tree; |
| 4516 | const node_datas = tree.nodes.items(.data); | 4508 | const node_datas = tree.nodes.items(.data); |
| 4517 | | 4509 | |
| 4518 | const lhs = try expr(gz, scope, bool_rl, node_datas[node].lhs); | 4510 | const lhs = try expr(gz, scope, bool_rl, node_datas[node].lhs); |
| ... | @@ -4538,7 +4530,7 @@ fn ifExpr( | ... | @@ -4538,7 +4530,7 @@ fn ifExpr( |
| 4538 | if_full: ast.full.If, | 4530 | if_full: ast.full.If, |
| 4539 | ) InnerError!Zir.Inst.Ref { | 4531 | ) InnerError!Zir.Inst.Ref { |
| 4540 | const astgen = parent_gz.astgen; | 4532 | const astgen = parent_gz.astgen; |
| 4541 | const tree = &astgen.file.tree; | 4533 | const tree = astgen.tree; |
| 4542 | const token_tags = tree.tokens.items(.tag); | 4534 | const token_tags = tree.tokens.items(.tag); |
| 4543 | | 4535 | |
| 4544 | var block_scope = parent_gz.makeSubBlock(scope); | 4536 | var block_scope = parent_gz.makeSubBlock(scope); |
| ... | @@ -4765,7 +4757,7 @@ fn whileExpr( | ... | @@ -4765,7 +4757,7 @@ fn whileExpr( |
| 4765 | while_full: ast.full.While, | 4757 | while_full: ast.full.While, |
| 4766 | ) InnerError!Zir.Inst.Ref { | 4758 | ) InnerError!Zir.Inst.Ref { |
| 4767 | const astgen = parent_gz.astgen; | 4759 | const astgen = parent_gz.astgen; |
| 4768 | const tree = &astgen.file.tree; | 4760 | const tree = astgen.tree; |
| 4769 | const token_tags = tree.tokens.items(.tag); | 4761 | const token_tags = tree.tokens.items(.tag); |
| 4770 | | 4762 | |
| 4771 | if (while_full.label_token) |label_token| { | 4763 | if (while_full.label_token) |label_token| { |
| ... | @@ -4967,7 +4959,7 @@ fn forExpr( | ... | @@ -4967,7 +4959,7 @@ fn forExpr( |
| 4967 | } | 4959 | } |
| 4968 | // Set up variables and constants. | 4960 | // Set up variables and constants. |
| 4969 | const is_inline = parent_gz.force_comptime or for_full.inline_token != null; | 4961 | const is_inline = parent_gz.force_comptime or for_full.inline_token != null; |
| 4970 | const tree = &astgen.file.tree; | 4962 | const tree = astgen.tree; |
| 4971 | const token_tags = tree.tokens.items(.tag); | 4963 | const token_tags = tree.tokens.items(.tag); |
| 4972 | | 4964 | |
| 4973 | const array_ptr = try expr(parent_gz, scope, .ref, for_full.ast.cond_expr); | 4965 | const array_ptr = try expr(parent_gz, scope, .ref, for_full.ast.cond_expr); |
| ... | @@ -5123,111 +5115,6 @@ fn forExpr( | ... | @@ -5123,111 +5115,6 @@ fn forExpr( |
| 5123 | ); | 5115 | ); |
| 5124 | } | 5116 | } |
| 5125 | | 5117 | |
| 5126 | fn getRangeNode( | | |
| 5127 | node_tags: []const ast.Node.Tag, | | |
| 5128 | node_datas: []const ast.Node.Data, | | |
| 5129 | node: ast.Node.Index, | | |
| 5130 | ) ?ast.Node.Index { | | |
| 5131 | switch (node_tags[node]) { | | |
| 5132 | .switch_range => return node, | | |
| 5133 | .grouped_expression => unreachable, | | |
| 5134 | else => return null, | | |
| 5135 | } | | |
| 5136 | } | | |
| 5137 | | | |
| 5138 | pub const SwitchProngSrc = union(enum) { | | |
| 5139 | scalar: u32, | | |
| 5140 | multi: Multi, | | |
| 5141 | range: Multi, | | |
| 5142 | | | |
| 5143 | pub const Multi = struct { | | |
| 5144 | prong: u32, | | |
| 5145 | item: u32, | | |
| 5146 | }; | | |
| 5147 | | | |
| 5148 | pub const RangeExpand = enum { none, first, last }; | | |
| 5149 | | | |
| 5150 | /// This function is intended to be called only when it is certain that we need | | |
| 5151 | /// the LazySrcLoc in order to emit a compile error. | | |
| 5152 | pub fn resolve( | | |
| 5153 | prong_src: SwitchProngSrc, | | |
| 5154 | decl: *Decl, | | |
| 5155 | switch_node_offset: i32, | | |
| 5156 | range_expand: RangeExpand, | | |
| 5157 | ) LazySrcLoc { | | |
| 5158 | @setCold(true); | | |
| 5159 | const switch_node = decl.relativeToNodeIndex(switch_node_offset); | | |
| 5160 | const tree = decl.namespace.file_scope.tree; | | |
| 5161 | const main_tokens = tree.nodes.items(.main_token); | | |
| 5162 | const node_datas = tree.nodes.items(.data); | | |
| 5163 | const node_tags = tree.nodes.items(.tag); | | |
| 5164 | const extra = tree.extraData(node_datas[switch_node].rhs, ast.Node.SubRange); | | |
| 5165 | const case_nodes = tree.extra_data[extra.start..extra.end]; | | |
| 5166 | | | |
| 5167 | var multi_i: u32 = 0; | | |
| 5168 | var scalar_i: u32 = 0; | | |
| 5169 | for (case_nodes) |case_node| { | | |
| 5170 | const case = switch (node_tags[case_node]) { | | |
| 5171 | .switch_case_one => tree.switchCaseOne(case_node), | | |
| 5172 | .switch_case => tree.switchCase(case_node), | | |
| 5173 | else => unreachable, | | |
| 5174 | }; | | |
| 5175 | if (case.ast.values.len == 0) | | |
| 5176 | continue; | | |
| 5177 | if (case.ast.values.len == 1 and | | |
| 5178 | node_tags[case.ast.values[0]] == .identifier and | | |
| 5179 | mem.eql(u8, tree.tokenSlice(main_tokens[case.ast.values[0]]), "_")) | | |
| 5180 | { | | |
| 5181 | continue; | | |
| 5182 | } | | |
| 5183 | const is_multi = case.ast.values.len != 1 or | | |
| 5184 | getRangeNode(node_tags, node_datas, case.ast.values[0]) != null; | | |
| 5185 | | | |
| 5186 | switch (prong_src) { | | |
| 5187 | .scalar => |i| if (!is_multi and i == scalar_i) return LazySrcLoc{ | | |
| 5188 | .node_offset = decl.nodeIndexToRelative(case.ast.values[0]), | | |
| 5189 | }, | | |
| 5190 | .multi => |s| if (is_multi and s.prong == multi_i) { | | |
| 5191 | var item_i: u32 = 0; | | |
| 5192 | for (case.ast.values) |item_node| { | | |
| 5193 | if (getRangeNode(node_tags, node_datas, item_node) != null) | | |
| 5194 | continue; | | |
| 5195 | | | |
| 5196 | if (item_i == s.item) return LazySrcLoc{ | | |
| 5197 | .node_offset = decl.nodeIndexToRelative(item_node), | | |
| 5198 | }; | | |
| 5199 | item_i += 1; | | |
| 5200 | } else unreachable; | | |
| 5201 | }, | | |
| 5202 | .range => |s| if (is_multi and s.prong == multi_i) { | | |
| 5203 | var range_i: u32 = 0; | | |
| 5204 | for (case.ast.values) |item_node| { | | |
| 5205 | const range = getRangeNode(node_tags, node_datas, item_node) orelse continue; | | |
| 5206 | | | |
| 5207 | if (range_i == s.item) switch (range_expand) { | | |
| 5208 | .none => return LazySrcLoc{ | | |
| 5209 | .node_offset = decl.nodeIndexToRelative(item_node), | | |
| 5210 | }, | | |
| 5211 | .first => return LazySrcLoc{ | | |
| 5212 | .node_offset = decl.nodeIndexToRelative(node_datas[range].lhs), | | |
| 5213 | }, | | |
| 5214 | .last => return LazySrcLoc{ | | |
| 5215 | .node_offset = decl.nodeIndexToRelative(node_datas[range].rhs), | | |
| 5216 | }, | | |
| 5217 | }; | | |
| 5218 | range_i += 1; | | |
| 5219 | } else unreachable; | | |
| 5220 | }, | | |
| 5221 | } | | |
| 5222 | if (is_multi) { | | |
| 5223 | multi_i += 1; | | |
| 5224 | } else { | | |
| 5225 | scalar_i += 1; | | |
| 5226 | } | | |
| 5227 | } else unreachable; | | |
| 5228 | } | | |
| 5229 | }; | | |
| 5230 | | | |
| 5231 | fn switchExpr( | 5118 | fn switchExpr( |
| 5232 | parent_gz: *GenZir, | 5119 | parent_gz: *GenZir, |
| 5233 | scope: *Scope, | 5120 | scope: *Scope, |
| ... | @@ -5236,7 +5123,7 @@ fn switchExpr( | ... | @@ -5236,7 +5123,7 @@ fn switchExpr( |
| 5236 | ) InnerError!Zir.Inst.Ref { | 5123 | ) InnerError!Zir.Inst.Ref { |
| 5237 | const astgen = parent_gz.astgen; | 5124 | const astgen = parent_gz.astgen; |
| 5238 | const gpa = astgen.gpa; | 5125 | const gpa = astgen.gpa; |
| 5239 | const tree = &astgen.file.tree; | 5126 | const tree = astgen.tree; |
| 5240 | const node_datas = tree.nodes.items(.data); | 5127 | const node_datas = tree.nodes.items(.data); |
| 5241 | const node_tags = tree.nodes.items(.tag); | 5128 | const node_tags = tree.nodes.items(.tag); |
| 5242 | const main_tokens = tree.nodes.items(.main_token); | 5129 | const main_tokens = tree.nodes.items(.main_token); |
| ... | @@ -5348,9 +5235,7 @@ fn switchExpr( | ... | @@ -5348,9 +5235,7 @@ fn switchExpr( |
| 5348 | continue; | 5235 | continue; |
| 5349 | } | 5236 | } |
| 5350 | | 5237 | |
| 5351 | if (case.ast.values.len == 1 and | 5238 | if (case.ast.values.len == 1 and node_tags[case.ast.values[0]] != .switch_range) { |
| 5352 | getRangeNode(node_tags, node_datas, case.ast.values[0]) == null) | | |
| 5353 | { | | |
| 5354 | scalar_cases_len += 1; | 5239 | scalar_cases_len += 1; |
| 5355 | } else { | 5240 | } else { |
| 5356 | multi_cases_len += 1; | 5241 | multi_cases_len += 1; |
| ... | @@ -5472,7 +5357,7 @@ fn switchExpr( | ... | @@ -5472,7 +5357,7 @@ fn switchExpr( |
| 5472 | case_scope.instructions.shrinkRetainingCapacity(0); | 5357 | case_scope.instructions.shrinkRetainingCapacity(0); |
| 5473 | | 5358 | |
| 5474 | const is_multi_case = case.ast.values.len != 1 or | 5359 | const is_multi_case = case.ast.values.len != 1 or |
| 5475 | getRangeNode(node_tags, node_datas, case.ast.values[0]) != null; | 5360 | node_tags[case.ast.values[0]] == .switch_range; |
| 5476 | | 5361 | |
| 5477 | const sub_scope = blk: { | 5362 | const sub_scope = blk: { |
| 5478 | const payload_token = case.payload_token orelse break :blk &case_scope.base; | 5363 | const payload_token = case.payload_token orelse break :blk &case_scope.base; |
| ... | @@ -5528,7 +5413,7 @@ fn switchExpr( | ... | @@ -5528,7 +5413,7 @@ fn switchExpr( |
| 5528 | // items | 5413 | // items |
| 5529 | var items_len: u32 = 0; | 5414 | var items_len: u32 = 0; |
| 5530 | for (case.ast.values) |item_node| { | 5415 | for (case.ast.values) |item_node| { |
| 5531 | if (getRangeNode(node_tags, node_datas, item_node) != null) continue; | 5416 | if (node_tags[item_node] == .switch_range) continue; |
| 5532 | items_len += 1; | 5417 | items_len += 1; |
| 5533 | | 5418 | |
| 5534 | const item_inst = try comptimeExpr(parent_gz, scope, item_rl, item_node); | 5419 | const item_inst = try comptimeExpr(parent_gz, scope, item_rl, item_node); |
| ... | @@ -5537,8 +5422,8 @@ fn switchExpr( | ... | @@ -5537,8 +5422,8 @@ fn switchExpr( |
| 5537 | | 5422 | |
| 5538 | // ranges | 5423 | // ranges |
| 5539 | var ranges_len: u32 = 0; | 5424 | var ranges_len: u32 = 0; |
| 5540 | for (case.ast.values) |item_node| { | 5425 | for (case.ast.values) |range| { |
| 5541 | const range = getRangeNode(node_tags, node_datas, item_node) orelse continue; | 5426 | if (node_tags[range] != .switch_range) continue; |
| 5542 | ranges_len += 1; | 5427 | ranges_len += 1; |
| 5543 | | 5428 | |
| 5544 | const first = try comptimeExpr(parent_gz, scope, item_rl, node_datas[range].lhs); | 5429 | const first = try comptimeExpr(parent_gz, scope, item_rl, node_datas[range].lhs); |
| ... | @@ -5824,7 +5709,7 @@ fn switchExpr( | ... | @@ -5824,7 +5709,7 @@ fn switchExpr( |
| 5824 | | 5709 | |
| 5825 | fn ret(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref { | 5710 | fn ret(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 5826 | const astgen = gz.astgen; | 5711 | const astgen = gz.astgen; |
| 5827 | const tree = &astgen.file.tree; | 5712 | const tree = astgen.tree; |
| 5828 | const node_datas = tree.nodes.items(.data); | 5713 | const node_datas = tree.nodes.items(.data); |
| 5829 | const main_tokens = tree.nodes.items(.main_token); | 5714 | const main_tokens = tree.nodes.items(.main_token); |
| 5830 | | 5715 | |
| ... | @@ -5857,7 +5742,7 @@ fn identifier( | ... | @@ -5857,7 +5742,7 @@ fn identifier( |
| 5857 | defer tracy.end(); | 5742 | defer tracy.end(); |
| 5858 | | 5743 | |
| 5859 | const astgen = gz.astgen; | 5744 | const astgen = gz.astgen; |
| 5860 | const tree = &astgen.file.tree; | 5745 | const tree = astgen.tree; |
| 5861 | const main_tokens = tree.nodes.items(.main_token); | 5746 | const main_tokens = tree.nodes.items(.main_token); |
| 5862 | | 5747 | |
| 5863 | const ident_token = main_tokens[ident]; | 5748 | const ident_token = main_tokens[ident]; |
| ... | @@ -5922,8 +5807,8 @@ fn identifier( | ... | @@ -5922,8 +5807,8 @@ fn identifier( |
| 5922 | } | 5807 | } |
| 5923 | s = local_ptr.parent; | 5808 | s = local_ptr.parent; |
| 5924 | }, | 5809 | }, |
| 5925 | .gen_zir => s = s.cast(GenZir).?.parent, | 5810 | .gen_zir => s = s.cast(GenZir).?.parent orelse break, |
| 5926 | else => break, | 5811 | .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent, |
| 5927 | }; | 5812 | }; |
| 5928 | } | 5813 | } |
| 5929 | | 5814 | |
| ... | @@ -5946,7 +5831,7 @@ fn stringLiteral( | ... | @@ -5946,7 +5831,7 @@ fn stringLiteral( |
| 5946 | node: ast.Node.Index, | 5831 | node: ast.Node.Index, |
| 5947 | ) InnerError!Zir.Inst.Ref { | 5832 | ) InnerError!Zir.Inst.Ref { |
| 5948 | const astgen = gz.astgen; | 5833 | const astgen = gz.astgen; |
| 5949 | const tree = astgen.file.tree; | 5834 | const tree = astgen.tree; |
| 5950 | const main_tokens = tree.nodes.items(.main_token); | 5835 | const main_tokens = tree.nodes.items(.main_token); |
| 5951 | const str_lit_token = main_tokens[node]; | 5836 | const str_lit_token = main_tokens[node]; |
| 5952 | const str = try astgen.strLitAsString(str_lit_token); | 5837 | const str = try astgen.strLitAsString(str_lit_token); |
| ... | @@ -5967,7 +5852,7 @@ fn multilineStringLiteral( | ... | @@ -5967,7 +5852,7 @@ fn multilineStringLiteral( |
| 5967 | node: ast.Node.Index, | 5852 | node: ast.Node.Index, |
| 5968 | ) InnerError!Zir.Inst.Ref { | 5853 | ) InnerError!Zir.Inst.Ref { |
| 5969 | const astgen = gz.astgen; | 5854 | const astgen = gz.astgen; |
| 5970 | const tree = &astgen.file.tree; | 5855 | const tree = astgen.tree; |
| 5971 | const node_datas = tree.nodes.items(.data); | 5856 | const node_datas = tree.nodes.items(.data); |
| 5972 | const main_tokens = tree.nodes.items(.main_token); | 5857 | const main_tokens = tree.nodes.items(.main_token); |
| 5973 | | 5858 | |
| ... | @@ -6006,7 +5891,7 @@ fn multilineStringLiteral( | ... | @@ -6006,7 +5891,7 @@ fn multilineStringLiteral( |
| 6006 | | 5891 | |
| 6007 | fn charLiteral(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref { | 5892 | fn charLiteral(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !Zir.Inst.Ref { |
| 6008 | const astgen = gz.astgen; | 5893 | const astgen = gz.astgen; |
| 6009 | const tree = &astgen.file.tree; | 5894 | const tree = astgen.tree; |
| 6010 | const main_tokens = tree.nodes.items(.main_token); | 5895 | const main_tokens = tree.nodes.items(.main_token); |
| 6011 | const main_token = main_tokens[node]; | 5896 | const main_token = main_tokens[node]; |
| 6012 | const slice = tree.tokenSlice(main_token); | 5897 | const slice = tree.tokenSlice(main_token); |
| ... | @@ -6035,7 +5920,7 @@ fn integerLiteral( | ... | @@ -6035,7 +5920,7 @@ fn integerLiteral( |
| 6035 | node: ast.Node.Index, | 5920 | node: ast.Node.Index, |
| 6036 | ) InnerError!Zir.Inst.Ref { | 5921 | ) InnerError!Zir.Inst.Ref { |
| 6037 | const astgen = gz.astgen; | 5922 | const astgen = gz.astgen; |
| 6038 | const tree = &astgen.file.tree; | 5923 | const tree = astgen.tree; |
| 6039 | const main_tokens = tree.nodes.items(.main_token); | 5924 | const main_tokens = tree.nodes.items(.main_token); |
| 6040 | const int_token = main_tokens[node]; | 5925 | const int_token = main_tokens[node]; |
| 6041 | const prefixed_bytes = tree.tokenSlice(int_token); | 5926 | const prefixed_bytes = tree.tokenSlice(int_token); |
| ... | @@ -6087,7 +5972,7 @@ fn floatLiteral( | ... | @@ -6087,7 +5972,7 @@ fn floatLiteral( |
| 6087 | ) InnerError!Zir.Inst.Ref { | 5972 | ) InnerError!Zir.Inst.Ref { |
| 6088 | const astgen = gz.astgen; | 5973 | const astgen = gz.astgen; |
| 6089 | const arena = astgen.arena; | 5974 | const arena = astgen.arena; |
| 6090 | const tree = &astgen.file.tree; | 5975 | const tree = astgen.tree; |
| 6091 | const main_tokens = tree.nodes.items(.main_token); | 5976 | const main_tokens = tree.nodes.items(.main_token); |
| 6092 | | 5977 | |
| 6093 | const main_token = main_tokens[node]; | 5978 | const main_token = main_tokens[node]; |
| ... | @@ -6130,7 +6015,7 @@ fn asmExpr( | ... | @@ -6130,7 +6015,7 @@ fn asmExpr( |
| 6130 | ) InnerError!Zir.Inst.Ref { | 6015 | ) InnerError!Zir.Inst.Ref { |
| 6131 | const astgen = gz.astgen; | 6016 | const astgen = gz.astgen; |
| 6132 | const arena = astgen.arena; | 6017 | const arena = astgen.arena; |
| 6133 | const tree = &astgen.file.tree; | 6018 | const tree = astgen.tree; |
| 6134 | const main_tokens = tree.nodes.items(.main_token); | 6019 | const main_tokens = tree.nodes.items(.main_token); |
| 6135 | const node_datas = tree.nodes.items(.data); | 6020 | const node_datas = tree.nodes.items(.data); |
| 6136 | const token_tags = tree.tokens.items(.tag); | 6021 | const token_tags = tree.tokens.items(.tag); |
| ... | @@ -6426,7 +6311,7 @@ fn builtinCall( | ... | @@ -6426,7 +6311,7 @@ fn builtinCall( |
| 6426 | params: []const ast.Node.Index, | 6311 | params: []const ast.Node.Index, |
| 6427 | ) InnerError!Zir.Inst.Ref { | 6312 | ) InnerError!Zir.Inst.Ref { |
| 6428 | const astgen = gz.astgen; | 6313 | const astgen = gz.astgen; |
| 6429 | const tree = &astgen.file.tree; | 6314 | const tree = astgen.tree; |
| 6430 | const main_tokens = tree.nodes.items(.main_token); | 6315 | const main_tokens = tree.nodes.items(.main_token); |
| 6431 | | 6316 | |
| 6432 | const builtin_token = main_tokens[node]; | 6317 | const builtin_token = main_tokens[node]; |
| ... | @@ -7406,7 +7291,7 @@ fn rvalue( | ... | @@ -7406,7 +7291,7 @@ fn rvalue( |
| 7406 | }, | 7291 | }, |
| 7407 | .ref => { | 7292 | .ref => { |
| 7408 | // We need a pointer but we have a value. | 7293 | // We need a pointer but we have a value. |
| 7409 | const tree = &gz.astgen.file.tree; | 7294 | const tree = gz.astgen.tree; |
| 7410 | const src_token = tree.firstToken(src_node); | 7295 | const src_token = tree.firstToken(src_node); |
| 7411 | return gz.addUnTok(.ref, result, src_token); | 7296 | return gz.addUnTok(.ref, result, src_token); |
| 7412 | }, | 7297 | }, |
| ... | @@ -7498,8 +7383,8 @@ fn rvalue( | ... | @@ -7498,8 +7383,8 @@ fn rvalue( |
| 7498 | /// and allocates the result within `astgen.arena`. | 7383 | /// and allocates the result within `astgen.arena`. |
| 7499 | /// Otherwise, returns a reference to the source code bytes directly. | 7384 | /// Otherwise, returns a reference to the source code bytes directly. |
| 7500 | /// See also `appendIdentStr` and `parseStrLit`. | 7385 | /// See also `appendIdentStr` and `parseStrLit`. |
| 7501 | pub fn identifierTokenString(astgen: *AstGen, token: ast.TokenIndex) InnerError![]const u8 { | 7386 | fn identifierTokenString(astgen: *AstGen, token: ast.TokenIndex) InnerError![]const u8 { |
| 7502 | const tree = &astgen.file.tree; | 7387 | const tree = astgen.tree; |
| 7503 | const token_tags = tree.tokens.items(.tag); | 7388 | const token_tags = tree.tokens.items(.tag); |
| 7504 | assert(token_tags[token] == .identifier); | 7389 | assert(token_tags[token] == .identifier); |
| 7505 | const ident_name = tree.tokenSlice(token); | 7390 | const ident_name = tree.tokenSlice(token); |
| ... | @@ -7516,12 +7401,12 @@ pub fn identifierTokenString(astgen: *AstGen, token: ast.TokenIndex) InnerError! | ... | @@ -7516,12 +7401,12 @@ pub fn identifierTokenString(astgen: *AstGen, token: ast.TokenIndex) InnerError! |
| 7516 | /// Given an identifier token, obtain the string for it (possibly parsing as a string | 7401 | /// Given an identifier token, obtain the string for it (possibly parsing as a string |
| 7517 | /// literal if it is @"" syntax), and append the string to `buf`. | 7402 | /// literal if it is @"" syntax), and append the string to `buf`. |
| 7518 | /// See also `identifierTokenString` and `parseStrLit`. | 7403 | /// See also `identifierTokenString` and `parseStrLit`. |
| 7519 | pub fn appendIdentStr( | 7404 | fn appendIdentStr( |
| 7520 | astgen: *AstGen, | 7405 | astgen: *AstGen, |
| 7521 | token: ast.TokenIndex, | 7406 | token: ast.TokenIndex, |
| 7522 | buf: *ArrayListUnmanaged(u8), | 7407 | buf: *ArrayListUnmanaged(u8), |
| 7523 | ) InnerError!void { | 7408 | ) InnerError!void { |
| 7524 | const tree = &astgen.file.tree; | 7409 | const tree = astgen.tree; |
| 7525 | const token_tags = tree.tokens.items(.tag); | 7410 | const token_tags = tree.tokens.items(.tag); |
| 7526 | assert(token_tags[token] == .identifier); | 7411 | assert(token_tags[token] == .identifier); |
| 7527 | const ident_name = tree.tokenSlice(token); | 7412 | const ident_name = tree.tokenSlice(token); |
| ... | @@ -7533,14 +7418,14 @@ pub fn appendIdentStr( | ... | @@ -7533,14 +7418,14 @@ pub fn appendIdentStr( |
| 7533 | } | 7418 | } |
| 7534 | | 7419 | |
| 7535 | /// Appends the result to `buf`. | 7420 | /// Appends the result to `buf`. |
| 7536 | pub fn parseStrLit( | 7421 | fn parseStrLit( |
| 7537 | astgen: *AstGen, | 7422 | astgen: *AstGen, |
| 7538 | token: ast.TokenIndex, | 7423 | token: ast.TokenIndex, |
| 7539 | buf: *ArrayListUnmanaged(u8), | 7424 | buf: *ArrayListUnmanaged(u8), |
| 7540 | bytes: []const u8, | 7425 | bytes: []const u8, |
| 7541 | offset: u32, | 7426 | offset: u32, |
| 7542 | ) InnerError!void { | 7427 | ) InnerError!void { |
| 7543 | const tree = &astgen.file.tree; | 7428 | const tree = astgen.tree; |
| 7544 | const raw_string = bytes[offset..]; | 7429 | const raw_string = bytes[offset..]; |
| 7545 | var buf_managed = buf.toManaged(astgen.gpa); | 7430 | var buf_managed = buf.toManaged(astgen.gpa); |
| 7546 | const result = std.zig.string_literal.parseAppend(&buf_managed, raw_string); | 7431 | const result = std.zig.string_literal.parseAppend(&buf_managed, raw_string); |
| ... | @@ -7598,7 +7483,7 @@ pub fn parseStrLit( | ... | @@ -7598,7 +7483,7 @@ pub fn parseStrLit( |
| 7598 | } | 7483 | } |
| 7599 | } | 7484 | } |
| 7600 | | 7485 | |
| 7601 | pub fn failNode( | 7486 | fn failNode( |
| 7602 | astgen: *AstGen, | 7487 | astgen: *AstGen, |
| 7603 | node: ast.Node.Index, | 7488 | node: ast.Node.Index, |
| 7604 | comptime format: []const u8, | 7489 | comptime format: []const u8, |
| ... | @@ -7607,7 +7492,7 @@ pub fn failNode( | ... | @@ -7607,7 +7492,7 @@ pub fn failNode( |
| 7607 | return astgen.failNodeNotes(node, format, args, &[0]u32{}); | 7492 | return astgen.failNodeNotes(node, format, args, &[0]u32{}); |
| 7608 | } | 7493 | } |
| 7609 | | 7494 | |
| 7610 | pub fn failNodeNotes( | 7495 | fn failNodeNotes( |
| 7611 | astgen: *AstGen, | 7496 | astgen: *AstGen, |
| 7612 | node: ast.Node.Index, | 7497 | node: ast.Node.Index, |
| 7613 | comptime format: []const u8, | 7498 | comptime format: []const u8, |
| ... | @@ -7639,7 +7524,7 @@ pub fn failNodeNotes( | ... | @@ -7639,7 +7524,7 @@ pub fn failNodeNotes( |
| 7639 | return error.AnalysisFail; | 7524 | return error.AnalysisFail; |
| 7640 | } | 7525 | } |
| 7641 | | 7526 | |
| 7642 | pub fn failTok( | 7527 | fn failTok( |
| 7643 | astgen: *AstGen, | 7528 | astgen: *AstGen, |
| 7644 | token: ast.TokenIndex, | 7529 | token: ast.TokenIndex, |
| 7645 | comptime format: []const u8, | 7530 | comptime format: []const u8, |
| ... | @@ -7648,7 +7533,7 @@ pub fn failTok( | ... | @@ -7648,7 +7533,7 @@ pub fn failTok( |
| 7648 | return astgen.failTokNotes(token, format, args, &[0]u32{}); | 7533 | return astgen.failTokNotes(token, format, args, &[0]u32{}); |
| 7649 | } | 7534 | } |
| 7650 | | 7535 | |
| 7651 | pub fn failTokNotes( | 7536 | fn failTokNotes( |
| 7652 | astgen: *AstGen, | 7537 | astgen: *AstGen, |
| 7653 | token: ast.TokenIndex, | 7538 | token: ast.TokenIndex, |
| 7654 | comptime format: []const u8, | 7539 | comptime format: []const u8, |
| ... | @@ -7680,9 +7565,8 @@ pub fn failTokNotes( | ... | @@ -7680,9 +7565,8 @@ pub fn failTokNotes( |
| 7680 | return error.AnalysisFail; | 7565 | return error.AnalysisFail; |
| 7681 | } | 7566 | } |
| 7682 | | 7567 | |
| 7683 | /// Same as `fail`, except given an absolute byte offset, and the function sets up the `LazySrcLoc` | 7568 | /// Same as `fail`, except given an absolute byte offset. |
| 7684 | /// for pointing at it relatively by subtracting from the containing `Decl`. | 7569 | fn failOff( |
| 7685 | pub fn failOff( | | |
| 7686 | astgen: *AstGen, | 7570 | astgen: *AstGen, |
| 7687 | token: ast.TokenIndex, | 7571 | token: ast.TokenIndex, |
| 7688 | byte_offset: u32, | 7572 | byte_offset: u32, |
| ... | @@ -7707,7 +7591,7 @@ pub fn failOff( | ... | @@ -7707,7 +7591,7 @@ pub fn failOff( |
| 7707 | return error.AnalysisFail; | 7591 | return error.AnalysisFail; |
| 7708 | } | 7592 | } |
| 7709 | | 7593 | |
| 7710 | pub fn errNoteTok( | 7594 | fn errNoteTok( |
| 7711 | astgen: *AstGen, | 7595 | astgen: *AstGen, |
| 7712 | token: ast.TokenIndex, | 7596 | token: ast.TokenIndex, |
| 7713 | comptime format: []const u8, | 7597 | comptime format: []const u8, |
| ... | @@ -7730,7 +7614,7 @@ pub fn errNoteTok( | ... | @@ -7730,7 +7614,7 @@ pub fn errNoteTok( |
| 7730 | }); | 7614 | }); |
| 7731 | } | 7615 | } |
| 7732 | | 7616 | |
| 7733 | pub fn errNoteNode( | 7617 | fn errNoteNode( |
| 7734 | astgen: *AstGen, | 7618 | astgen: *AstGen, |
| 7735 | node: ast.Node.Index, | 7619 | node: ast.Node.Index, |
| 7736 | comptime format: []const u8, | 7620 | comptime format: []const u8, |
| ... | @@ -7780,7 +7664,7 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !IndexSlice { | ... | @@ -7780,7 +7664,7 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !IndexSlice { |
| 7780 | const gpa = astgen.gpa; | 7664 | const gpa = astgen.gpa; |
| 7781 | const string_bytes = &astgen.string_bytes; | 7665 | const string_bytes = &astgen.string_bytes; |
| 7782 | const str_index = @intCast(u32, string_bytes.items.len); | 7666 | const str_index = @intCast(u32, string_bytes.items.len); |
| 7783 | const token_bytes = astgen.file.tree.tokenSlice(str_lit_token); | 7667 | const token_bytes = astgen.tree.tokenSlice(str_lit_token); |
| 7784 | try astgen.parseStrLit(str_lit_token, string_bytes, token_bytes, 0); | 7668 | try astgen.parseStrLit(str_lit_token, string_bytes, token_bytes, 0); |
| 7785 | const key = string_bytes.items[str_index..]; | 7669 | const key = string_bytes.items[str_index..]; |
| 7786 | const gop = try astgen.string_table.getOrPut(gpa, key); | 7670 | const gop = try astgen.string_table.getOrPut(gpa, key); |
| ... | @@ -7811,9 +7695,934 @@ fn testNameString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !u32 { | ... | @@ -7811,9 +7695,934 @@ fn testNameString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !u32 { |
| 7811 | const gpa = astgen.gpa; | 7695 | const gpa = astgen.gpa; |
| 7812 | const string_bytes = &astgen.string_bytes; | 7696 | const string_bytes = &astgen.string_bytes; |
| 7813 | const str_index = @intCast(u32, string_bytes.items.len); | 7697 | const str_index = @intCast(u32, string_bytes.items.len); |
| 7814 | const token_bytes = astgen.file.tree.tokenSlice(str_lit_token); | 7698 | const token_bytes = astgen.tree.tokenSlice(str_lit_token); |
| 7815 | try string_bytes.append(gpa, 0); // Indicates this is a test. | 7699 | try string_bytes.append(gpa, 0); // Indicates this is a test. |
| 7816 | try astgen.parseStrLit(str_lit_token, string_bytes, token_bytes, 0); | 7700 | try astgen.parseStrLit(str_lit_token, string_bytes, token_bytes, 0); |
| 7817 | try string_bytes.append(gpa, 0); | 7701 | try string_bytes.append(gpa, 0); |
| 7818 | return str_index; | 7702 | return str_index; |
| 7819 | } | 7703 | } |
| | 7704 | |
| | 7705 | const Scope = struct { |
| | 7706 | tag: Tag, |
| | 7707 | |
| | 7708 | fn cast(base: *Scope, comptime T: type) ?*T { |
| | 7709 | if (T == Defer) { |
| | 7710 | switch (base.tag) { |
| | 7711 | .defer_normal, .defer_error => return @fieldParentPtr(T, "base", base), |
| | 7712 | else => return null, |
| | 7713 | } |
| | 7714 | } |
| | 7715 | if (base.tag != T.base_tag) |
| | 7716 | return null; |
| | 7717 | |
| | 7718 | return @fieldParentPtr(T, "base", base); |
| | 7719 | } |
| | 7720 | |
| | 7721 | const Tag = enum { |
| | 7722 | gen_zir, |
| | 7723 | local_val, |
| | 7724 | local_ptr, |
| | 7725 | defer_normal, |
| | 7726 | defer_error, |
| | 7727 | }; |
| | 7728 | |
| | 7729 | /// This is always a `const` local and importantly the `inst` is a value type, not a pointer. |
| | 7730 | /// This structure lives as long as the AST generation of the Block |
| | 7731 | /// node that contains the variable. |
| | 7732 | const LocalVal = struct { |
| | 7733 | const base_tag: Tag = .local_val; |
| | 7734 | base: Scope = Scope{ .tag = base_tag }, |
| | 7735 | /// Parents can be: `LocalVal`, `LocalPtr`, `GenZir`, `Defer`. |
| | 7736 | parent: *Scope, |
| | 7737 | gen_zir: *GenZir, |
| | 7738 | inst: Zir.Inst.Ref, |
| | 7739 | /// Source location of the corresponding variable declaration. |
| | 7740 | token_src: ast.TokenIndex, |
| | 7741 | /// String table index. |
| | 7742 | name: u32, |
| | 7743 | }; |
| | 7744 | |
| | 7745 | /// This could be a `const` or `var` local. It has a pointer instead of a value. |
| | 7746 | /// This structure lives as long as the AST generation of the Block |
| | 7747 | /// node that contains the variable. |
| | 7748 | const LocalPtr = struct { |
| | 7749 | const base_tag: Tag = .local_ptr; |
| | 7750 | base: Scope = Scope{ .tag = base_tag }, |
| | 7751 | /// Parents can be: `LocalVal`, `LocalPtr`, `GenZir`, `Defer`. |
| | 7752 | parent: *Scope, |
| | 7753 | gen_zir: *GenZir, |
| | 7754 | ptr: Zir.Inst.Ref, |
| | 7755 | /// Source location of the corresponding variable declaration. |
| | 7756 | token_src: ast.TokenIndex, |
| | 7757 | /// String table index. |
| | 7758 | name: u32, |
| | 7759 | }; |
| | 7760 | |
| | 7761 | const Defer = struct { |
| | 7762 | base: Scope, |
| | 7763 | /// Parents can be: `LocalVal`, `LocalPtr`, `GenZir`, `Defer`. |
| | 7764 | parent: *Scope, |
| | 7765 | defer_node: ast.Node.Index, |
| | 7766 | }; |
| | 7767 | }; |
| | 7768 | |
| | 7769 | /// This is a temporary structure; references to it are valid only |
| | 7770 | /// while constructing a `Zir`. |
| | 7771 | const GenZir = struct { |
| | 7772 | const base_tag: Scope.Tag = .gen_zir; |
| | 7773 | base: Scope = Scope{ .tag = base_tag }, |
| | 7774 | force_comptime: bool, |
| | 7775 | /// The end of special indexes. `Zir.Inst.Ref` subtracts against this number to convert |
| | 7776 | /// to `Zir.Inst.Index`. The default here is correct if there are 0 parameters. |
| | 7777 | ref_start_index: u32 = Zir.Inst.Ref.typed_value_map.len, |
| | 7778 | /// The containing decl AST node. |
| | 7779 | decl_node_index: ast.Node.Index, |
| | 7780 | /// The containing decl line index, absolute. |
| | 7781 | decl_line: u32, |
| | 7782 | parent: ?*Scope, |
| | 7783 | /// All `GenZir` scopes for the same ZIR share this. |
| | 7784 | astgen: *AstGen, |
| | 7785 | /// Keeps track of the list of instructions in this scope only. Indexes |
| | 7786 | /// to instructions in `astgen`. |
| | 7787 | instructions: ArrayListUnmanaged(Zir.Inst.Index) = .{}, |
| | 7788 | label: ?Label = null, |
| | 7789 | break_block: Zir.Inst.Index = 0, |
| | 7790 | continue_block: Zir.Inst.Index = 0, |
| | 7791 | /// Only valid when setBreakResultLoc is called. |
| | 7792 | break_result_loc: AstGen.ResultLoc = undefined, |
| | 7793 | /// When a block has a pointer result location, here it is. |
| | 7794 | rl_ptr: Zir.Inst.Ref = .none, |
| | 7795 | /// When a block has a type result location, here it is. |
| | 7796 | rl_ty_inst: Zir.Inst.Ref = .none, |
| | 7797 | /// Keeps track of how many branches of a block did not actually |
| | 7798 | /// consume the result location. astgen uses this to figure out |
| | 7799 | /// whether to rely on break instructions or writing to the result |
| | 7800 | /// pointer for the result instruction. |
| | 7801 | rvalue_rl_count: usize = 0, |
| | 7802 | /// Keeps track of how many break instructions there are. When astgen is finished |
| | 7803 | /// with a block, it can check this against rvalue_rl_count to find out whether |
| | 7804 | /// the break instructions should be downgraded to break_void. |
| | 7805 | break_count: usize = 0, |
| | 7806 | /// Tracks `break :foo bar` instructions so they can possibly be elided later if |
| | 7807 | /// the labeled block ends up not needing a result location pointer. |
| | 7808 | labeled_breaks: ArrayListUnmanaged(Zir.Inst.Index) = .{}, |
| | 7809 | /// Tracks `store_to_block_ptr` instructions that correspond to break instructions |
| | 7810 | /// so they can possibly be elided later if the labeled block ends up not needing |
| | 7811 | /// a result location pointer. |
| | 7812 | labeled_store_to_block_ptr_list: ArrayListUnmanaged(Zir.Inst.Index) = .{}, |
| | 7813 | |
| | 7814 | suspend_node: ast.Node.Index = 0, |
| | 7815 | nosuspend_node: ast.Node.Index = 0, |
| | 7816 | |
| | 7817 | fn makeSubBlock(gz: *GenZir, scope: *Scope) GenZir { |
| | 7818 | return .{ |
| | 7819 | .force_comptime = gz.force_comptime, |
| | 7820 | .ref_start_index = gz.ref_start_index, |
| | 7821 | .decl_node_index = gz.decl_node_index, |
| | 7822 | .decl_line = gz.decl_line, |
| | 7823 | .parent = scope, |
| | 7824 | .astgen = gz.astgen, |
| | 7825 | .suspend_node = gz.suspend_node, |
| | 7826 | .nosuspend_node = gz.nosuspend_node, |
| | 7827 | }; |
| | 7828 | } |
| | 7829 | |
| | 7830 | const Label = struct { |
| | 7831 | token: ast.TokenIndex, |
| | 7832 | block_inst: Zir.Inst.Index, |
| | 7833 | used: bool = false, |
| | 7834 | }; |
| | 7835 | |
| | 7836 | fn refIsNoReturn(gz: GenZir, inst_ref: Zir.Inst.Ref) bool { |
| | 7837 | if (inst_ref == .unreachable_value) return true; |
| | 7838 | if (gz.refToIndex(inst_ref)) |inst_index| { |
| | 7839 | return gz.astgen.instructions.items(.tag)[inst_index].isNoReturn(); |
| | 7840 | } |
| | 7841 | return false; |
| | 7842 | } |
| | 7843 | |
| | 7844 | fn calcLine(gz: GenZir, node: ast.Node.Index) u32 { |
| | 7845 | const astgen = gz.astgen; |
| | 7846 | const tree = astgen.tree; |
| | 7847 | const node_tags = tree.nodes.items(.tag); |
| | 7848 | const token_starts = tree.tokens.items(.start); |
| | 7849 | const decl_start = token_starts[tree.firstToken(gz.decl_node_index)]; |
| | 7850 | const node_start = token_starts[tree.firstToken(node)]; |
| | 7851 | const source = tree.source[decl_start..node_start]; |
| | 7852 | const loc = std.zig.findLineColumn(source, source.len); |
| | 7853 | return @intCast(u32, gz.decl_line + loc.line); |
| | 7854 | } |
| | 7855 | |
| | 7856 | fn tokSrcLoc(gz: GenZir, token_index: ast.TokenIndex) LazySrcLoc { |
| | 7857 | return .{ .token_offset = token_index - gz.srcToken() }; |
| | 7858 | } |
| | 7859 | |
| | 7860 | fn nodeSrcLoc(gz: GenZir, node_index: ast.Node.Index) LazySrcLoc { |
| | 7861 | return .{ .node_offset = gz.nodeIndexToRelative(node_index) }; |
| | 7862 | } |
| | 7863 | |
| | 7864 | fn nodeIndexToRelative(gz: GenZir, node_index: ast.Node.Index) i32 { |
| | 7865 | return @bitCast(i32, node_index) - @bitCast(i32, gz.decl_node_index); |
| | 7866 | } |
| | 7867 | |
| | 7868 | fn tokenIndexToRelative(gz: GenZir, token: ast.TokenIndex) u32 { |
| | 7869 | return token - gz.srcToken(); |
| | 7870 | } |
| | 7871 | |
| | 7872 | fn srcToken(gz: GenZir) ast.TokenIndex { |
| | 7873 | return gz.astgen.tree.firstToken(gz.decl_node_index); |
| | 7874 | } |
| | 7875 | |
| | 7876 | fn indexToRef(gz: GenZir, inst: Zir.Inst.Index) Zir.Inst.Ref { |
| | 7877 | return @intToEnum(Zir.Inst.Ref, gz.ref_start_index + inst); |
| | 7878 | } |
| | 7879 | |
| | 7880 | fn refToIndex(gz: GenZir, inst: Zir.Inst.Ref) ?Zir.Inst.Index { |
| | 7881 | const ref_int = @enumToInt(inst); |
| | 7882 | if (ref_int >= gz.ref_start_index) { |
| | 7883 | return ref_int - gz.ref_start_index; |
| | 7884 | } else { |
| | 7885 | return null; |
| | 7886 | } |
| | 7887 | } |
| | 7888 | |
| | 7889 | fn setBreakResultLoc(gz: *GenZir, parent_rl: AstGen.ResultLoc) void { |
| | 7890 | // Depending on whether the result location is a pointer or value, different |
| | 7891 | // ZIR needs to be generated. In the former case we rely on storing to the |
| | 7892 | // pointer to communicate the result, and use breakvoid; in the latter case |
| | 7893 | // the block break instructions will have the result values. |
| | 7894 | // One more complication: when the result location is a pointer, we detect |
| | 7895 | // the scenario where the result location is not consumed. In this case |
| | 7896 | // we emit ZIR for the block break instructions to have the result values, |
| | 7897 | // and then rvalue() on that to pass the value to the result location. |
| | 7898 | switch (parent_rl) { |
| | 7899 | .ty => |ty_inst| { |
| | 7900 | gz.rl_ty_inst = ty_inst; |
| | 7901 | gz.break_result_loc = parent_rl; |
| | 7902 | }, |
| | 7903 | .none_or_ref => { |
| | 7904 | gz.break_result_loc = .ref; |
| | 7905 | }, |
| | 7906 | .discard, .none, .ptr, .ref => { |
| | 7907 | gz.break_result_loc = parent_rl; |
| | 7908 | }, |
| | 7909 | |
| | 7910 | .inferred_ptr => |ptr| { |
| | 7911 | gz.rl_ptr = ptr; |
| | 7912 | gz.break_result_loc = .{ .block_ptr = gz }; |
| | 7913 | }, |
| | 7914 | |
| | 7915 | .block_ptr => |parent_block_scope| { |
| | 7916 | gz.rl_ty_inst = parent_block_scope.rl_ty_inst; |
| | 7917 | gz.rl_ptr = parent_block_scope.rl_ptr; |
| | 7918 | gz.break_result_loc = .{ .block_ptr = gz }; |
| | 7919 | }, |
| | 7920 | } |
| | 7921 | } |
| | 7922 | |
| | 7923 | fn setBoolBrBody(gz: GenZir, inst: Zir.Inst.Index) !void { |
| | 7924 | const gpa = gz.astgen.gpa; |
| | 7925 | try gz.astgen.extra.ensureCapacity(gpa, gz.astgen.extra.items.len + |
| | 7926 | @typeInfo(Zir.Inst.Block).Struct.fields.len + gz.instructions.items.len); |
| | 7927 | const zir_datas = gz.astgen.instructions.items(.data); |
| | 7928 | zir_datas[inst].bool_br.payload_index = gz.astgen.addExtraAssumeCapacity( |
| | 7929 | Zir.Inst.Block{ .body_len = @intCast(u32, gz.instructions.items.len) }, |
| | 7930 | ); |
| | 7931 | gz.astgen.extra.appendSliceAssumeCapacity(gz.instructions.items); |
| | 7932 | } |
| | 7933 | |
| | 7934 | fn setBlockBody(gz: GenZir, inst: Zir.Inst.Index) !void { |
| | 7935 | const gpa = gz.astgen.gpa; |
| | 7936 | try gz.astgen.extra.ensureCapacity(gpa, gz.astgen.extra.items.len + |
| | 7937 | @typeInfo(Zir.Inst.Block).Struct.fields.len + gz.instructions.items.len); |
| | 7938 | const zir_datas = gz.astgen.instructions.items(.data); |
| | 7939 | zir_datas[inst].pl_node.payload_index = gz.astgen.addExtraAssumeCapacity( |
| | 7940 | Zir.Inst.Block{ .body_len = @intCast(u32, gz.instructions.items.len) }, |
| | 7941 | ); |
| | 7942 | gz.astgen.extra.appendSliceAssumeCapacity(gz.instructions.items); |
| | 7943 | } |
| | 7944 | |
| | 7945 | /// Same as `setBlockBody` except we don't copy instructions which are |
| | 7946 | /// `store_to_block_ptr` instructions with lhs set to .none. |
| | 7947 | fn setBlockBodyEliding(gz: GenZir, inst: Zir.Inst.Index) !void { |
| | 7948 | const gpa = gz.astgen.gpa; |
| | 7949 | try gz.astgen.extra.ensureCapacity(gpa, gz.astgen.extra.items.len + |
| | 7950 | @typeInfo(Zir.Inst.Block).Struct.fields.len + gz.instructions.items.len); |
| | 7951 | const zir_datas = gz.astgen.instructions.items(.data); |
| | 7952 | const zir_tags = gz.astgen.instructions.items(.tag); |
| | 7953 | const block_pl_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Block{ |
| | 7954 | .body_len = @intCast(u32, gz.instructions.items.len), |
| | 7955 | }); |
| | 7956 | zir_datas[inst].pl_node.payload_index = block_pl_index; |
| | 7957 | for (gz.instructions.items) |sub_inst| { |
| | 7958 | if (zir_tags[sub_inst] == .store_to_block_ptr and |
| | 7959 | zir_datas[sub_inst].bin.lhs == .none) |
| | 7960 | { |
| | 7961 | // Decrement `body_len`. |
| | 7962 | gz.astgen.extra.items[block_pl_index] -= 1; |
| | 7963 | continue; |
| | 7964 | } |
| | 7965 | gz.astgen.extra.appendAssumeCapacity(sub_inst); |
| | 7966 | } |
| | 7967 | } |
| | 7968 | |
| | 7969 | fn addFunc(gz: *GenZir, args: struct { |
| | 7970 | src_node: ast.Node.Index, |
| | 7971 | param_types: []const Zir.Inst.Ref, |
| | 7972 | body: []const Zir.Inst.Index, |
| | 7973 | ret_ty: Zir.Inst.Ref, |
| | 7974 | cc: Zir.Inst.Ref, |
| | 7975 | align_inst: Zir.Inst.Ref, |
| | 7976 | lib_name: u32, |
| | 7977 | is_var_args: bool, |
| | 7978 | is_inferred_error: bool, |
| | 7979 | is_test: bool, |
| | 7980 | }) !Zir.Inst.Ref { |
| | 7981 | assert(args.src_node != 0); |
| | 7982 | assert(args.ret_ty != .none); |
| | 7983 | const astgen = gz.astgen; |
| | 7984 | const gpa = astgen.gpa; |
| | 7985 | |
| | 7986 | try gz.instructions.ensureUnusedCapacity(gpa, 1); |
| | 7987 | try astgen.instructions.ensureUnusedCapacity(gpa, 1); |
| | 7988 | |
| | 7989 | var src_locs_buffer: [3]u32 = undefined; |
| | 7990 | var src_locs: []u32 = src_locs_buffer[0..0]; |
| | 7991 | if (args.body.len != 0) { |
| | 7992 | const tree = astgen.tree; |
| | 7993 | const node_tags = tree.nodes.items(.tag); |
| | 7994 | const node_datas = tree.nodes.items(.data); |
| | 7995 | const token_starts = tree.tokens.items(.start); |
| | 7996 | const decl_start = token_starts[tree.firstToken(gz.decl_node_index)]; |
| | 7997 | const fn_decl = args.src_node; |
| | 7998 | assert(node_tags[fn_decl] == .fn_decl or node_tags[fn_decl] == .test_decl); |
| | 7999 | const block = node_datas[fn_decl].rhs; |
| | 8000 | const lbrace_start = token_starts[tree.firstToken(block)]; |
| | 8001 | const rbrace_start = token_starts[tree.lastToken(block)]; |
| | 8002 | const lbrace_source = tree.source[decl_start..lbrace_start]; |
| | 8003 | const lbrace_loc = std.zig.findLineColumn(lbrace_source, lbrace_source.len); |
| | 8004 | const rbrace_source = tree.source[lbrace_start..rbrace_start]; |
| | 8005 | const rbrace_loc = std.zig.findLineColumn(rbrace_source, rbrace_source.len); |
| | 8006 | const lbrace_line = @intCast(u32, lbrace_loc.line); |
| | 8007 | const rbrace_line = lbrace_line + @intCast(u32, rbrace_loc.line); |
| | 8008 | const columns = @intCast(u32, lbrace_loc.column) | |
| | 8009 | (@intCast(u32, rbrace_loc.column) << 16); |
| | 8010 | src_locs_buffer[0] = lbrace_line; |
| | 8011 | src_locs_buffer[1] = rbrace_line; |
| | 8012 | src_locs_buffer[2] = columns; |
| | 8013 | src_locs = &src_locs_buffer; |
| | 8014 | } |
| | 8015 | |
| | 8016 | if (args.cc != .none or args.lib_name != 0 or |
| | 8017 | args.is_var_args or args.is_test or args.align_inst != .none) |
| | 8018 | { |
| | 8019 | try astgen.extra.ensureUnusedCapacity( |
| | 8020 | gpa, |
| | 8021 | @typeInfo(Zir.Inst.ExtendedFunc).Struct.fields.len + |
| | 8022 | args.param_types.len + args.body.len + src_locs.len + |
| | 8023 | @boolToInt(args.lib_name != 0) + |
| | 8024 | @boolToInt(args.align_inst != .none) + |
| | 8025 | @boolToInt(args.cc != .none), |
| | 8026 | ); |
| | 8027 | const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.ExtendedFunc{ |
| | 8028 | .src_node = gz.nodeIndexToRelative(args.src_node), |
| | 8029 | .return_type = args.ret_ty, |
| | 8030 | .param_types_len = @intCast(u32, args.param_types.len), |
| | 8031 | .body_len = @intCast(u32, args.body.len), |
| | 8032 | }); |
| | 8033 | if (args.lib_name != 0) { |
| | 8034 | astgen.extra.appendAssumeCapacity(args.lib_name); |
| | 8035 | } |
| | 8036 | if (args.cc != .none) { |
| | 8037 | astgen.extra.appendAssumeCapacity(@enumToInt(args.cc)); |
| | 8038 | } |
| | 8039 | if (args.align_inst != .none) { |
| | 8040 | astgen.extra.appendAssumeCapacity(@enumToInt(args.align_inst)); |
| | 8041 | } |
| | 8042 | astgen.appendRefsAssumeCapacity(args.param_types); |
| | 8043 | astgen.extra.appendSliceAssumeCapacity(args.body); |
| | 8044 | astgen.extra.appendSliceAssumeCapacity(src_locs); |
| | 8045 | |
| | 8046 | const new_index = @intCast(Zir.Inst.Index, astgen.instructions.len); |
| | 8047 | astgen.instructions.appendAssumeCapacity(.{ |
| | 8048 | .tag = .extended, |
| | 8049 | .data = .{ .extended = .{ |
| | 8050 | .opcode = .func, |
| | 8051 | .small = @bitCast(u16, Zir.Inst.ExtendedFunc.Small{ |
| | 8052 | .is_var_args = args.is_var_args, |
| | 8053 | .is_inferred_error = args.is_inferred_error, |
| | 8054 | .has_lib_name = args.lib_name != 0, |
| | 8055 | .has_cc = args.cc != .none, |
| | 8056 | .has_align = args.align_inst != .none, |
| | 8057 | .is_test = args.is_test, |
| | 8058 | }), |
| | 8059 | .operand = payload_index, |
| | 8060 | } }, |
| | 8061 | }); |
| | 8062 | gz.instructions.appendAssumeCapacity(new_index); |
| | 8063 | return gz.indexToRef(new_index); |
| | 8064 | } else { |
| | 8065 | try gz.astgen.extra.ensureUnusedCapacity( |
| | 8066 | gpa, |
| | 8067 | @typeInfo(Zir.Inst.Func).Struct.fields.len + |
| | 8068 | args.param_types.len + args.body.len + src_locs.len, |
| | 8069 | ); |
| | 8070 | |
| | 8071 | const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Func{ |
| | 8072 | .return_type = args.ret_ty, |
| | 8073 | .param_types_len = @intCast(u32, args.param_types.len), |
| | 8074 | .body_len = @intCast(u32, args.body.len), |
| | 8075 | }); |
| | 8076 | gz.astgen.appendRefsAssumeCapacity(args.param_types); |
| | 8077 | gz.astgen.extra.appendSliceAssumeCapacity(args.body); |
| | 8078 | gz.astgen.extra.appendSliceAssumeCapacity(src_locs); |
| | 8079 | |
| | 8080 | const tag: Zir.Inst.Tag = if (args.is_inferred_error) .func_inferred else .func; |
| | 8081 | const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); |
| | 8082 | gz.astgen.instructions.appendAssumeCapacity(.{ |
| | 8083 | .tag = tag, |
| | 8084 | .data = .{ .pl_node = .{ |
| | 8085 | .src_node = gz.nodeIndexToRelative(args.src_node), |
| | 8086 | .payload_index = payload_index, |
| | 8087 | } }, |
| | 8088 | }); |
| | 8089 | gz.instructions.appendAssumeCapacity(new_index); |
| | 8090 | return gz.indexToRef(new_index); |
| | 8091 | } |
| | 8092 | } |
| | 8093 | |
| | 8094 | fn addVar(gz: *GenZir, args: struct { |
| | 8095 | align_inst: Zir.Inst.Ref, |
| | 8096 | lib_name: u32, |
| | 8097 | var_type: Zir.Inst.Ref, |
| | 8098 | init: Zir.Inst.Ref, |
| | 8099 | is_extern: bool, |
| | 8100 | }) !Zir.Inst.Ref { |
| | 8101 | const astgen = gz.astgen; |
| | 8102 | const gpa = astgen.gpa; |
| | 8103 | |
| | 8104 | try gz.instructions.ensureUnusedCapacity(gpa, 1); |
| | 8105 | try astgen.instructions.ensureUnusedCapacity(gpa, 1); |
| | 8106 | |
| | 8107 | try astgen.extra.ensureUnusedCapacity( |
| | 8108 | gpa, |
| | 8109 | @typeInfo(Zir.Inst.ExtendedVar).Struct.fields.len + |
| | 8110 | @boolToInt(args.lib_name != 0) + |
| | 8111 | @boolToInt(args.align_inst != .none) + |
| | 8112 | @boolToInt(args.init != .none), |
| | 8113 | ); |
| | 8114 | const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.ExtendedVar{ |
| | 8115 | .var_type = args.var_type, |
| | 8116 | }); |
| | 8117 | if (args.lib_name != 0) { |
| | 8118 | astgen.extra.appendAssumeCapacity(args.lib_name); |
| | 8119 | } |
| | 8120 | if (args.align_inst != .none) { |
| | 8121 | astgen.extra.appendAssumeCapacity(@enumToInt(args.align_inst)); |
| | 8122 | } |
| | 8123 | if (args.init != .none) { |
| | 8124 | astgen.extra.appendAssumeCapacity(@enumToInt(args.init)); |
| | 8125 | } |
| | 8126 | |
| | 8127 | const new_index = @intCast(Zir.Inst.Index, astgen.instructions.len); |
| | 8128 | astgen.instructions.appendAssumeCapacity(.{ |
| | 8129 | .tag = .extended, |
| | 8130 | .data = .{ .extended = .{ |
| | 8131 | .opcode = .variable, |
| | 8132 | .small = @bitCast(u16, Zir.Inst.ExtendedVar.Small{ |
| | 8133 | .has_lib_name = args.lib_name != 0, |
| | 8134 | .has_align = args.align_inst != .none, |
| | 8135 | .has_init = args.init != .none, |
| | 8136 | .is_extern = args.is_extern, |
| | 8137 | }), |
| | 8138 | .operand = payload_index, |
| | 8139 | } }, |
| | 8140 | }); |
| | 8141 | gz.instructions.appendAssumeCapacity(new_index); |
| | 8142 | return gz.indexToRef(new_index); |
| | 8143 | } |
| | 8144 | |
| | 8145 | fn addCall( |
| | 8146 | gz: *GenZir, |
| | 8147 | tag: Zir.Inst.Tag, |
| | 8148 | callee: Zir.Inst.Ref, |
| | 8149 | args: []const Zir.Inst.Ref, |
| | 8150 | /// Absolute node index. This function does the conversion to offset from Decl. |
| | 8151 | src_node: ast.Node.Index, |
| | 8152 | ) !Zir.Inst.Ref { |
| | 8153 | assert(callee != .none); |
| | 8154 | assert(src_node != 0); |
| | 8155 | const gpa = gz.astgen.gpa; |
| | 8156 | try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1); |
| | 8157 | try gz.astgen.instructions.ensureCapacity(gpa, gz.astgen.instructions.len + 1); |
| | 8158 | try gz.astgen.extra.ensureCapacity(gpa, gz.astgen.extra.items.len + |
| | 8159 | @typeInfo(Zir.Inst.Call).Struct.fields.len + args.len); |
| | 8160 | |
| | 8161 | const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Call{ |
| | 8162 | .callee = callee, |
| | 8163 | .args_len = @intCast(u32, args.len), |
| | 8164 | }); |
| | 8165 | gz.astgen.appendRefsAssumeCapacity(args); |
| | 8166 | |
| | 8167 | const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); |
| | 8168 | gz.astgen.instructions.appendAssumeCapacity(.{ |
| | 8169 | .tag = tag, |
| | 8170 | .data = .{ .pl_node = .{ |
| | 8171 | .src_node = gz.nodeIndexToRelative(src_node), |
| | 8172 | .payload_index = payload_index, |
| | 8173 | } }, |
| | 8174 | }); |
| | 8175 | gz.instructions.appendAssumeCapacity(new_index); |
| | 8176 | return gz.indexToRef(new_index); |
| | 8177 | } |
| | 8178 | |
| | 8179 | /// Note that this returns a `Zir.Inst.Index` not a ref. |
| | 8180 | /// Leaves the `payload_index` field undefined. |
| | 8181 | fn addBoolBr( |
| | 8182 | gz: *GenZir, |
| | 8183 | tag: Zir.Inst.Tag, |
| | 8184 | lhs: Zir.Inst.Ref, |
| | 8185 | ) !Zir.Inst.Index { |
| | 8186 | assert(lhs != .none); |
| | 8187 | const gpa = gz.astgen.gpa; |
| | 8188 | try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1); |
| | 8189 | try gz.astgen.instructions.ensureCapacity(gpa, gz.astgen.instructions.len + 1); |
| | 8190 | |
| | 8191 | const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); |
| | 8192 | gz.astgen.instructions.appendAssumeCapacity(.{ |
| | 8193 | .tag = tag, |
| | 8194 | .data = .{ .bool_br = .{ |
| | 8195 | .lhs = lhs, |
| | 8196 | .payload_index = undefined, |
| | 8197 | } }, |
| | 8198 | }); |
| | 8199 | gz.instructions.appendAssumeCapacity(new_index); |
| | 8200 | return new_index; |
| | 8201 | } |
| | 8202 | |
| | 8203 | fn addInt(gz: *GenZir, integer: u64) !Zir.Inst.Ref { |
| | 8204 | return gz.add(.{ |
| | 8205 | .tag = .int, |
| | 8206 | .data = .{ .int = integer }, |
| | 8207 | }); |
| | 8208 | } |
| | 8209 | |
| | 8210 | fn addIntBig(gz: *GenZir, limbs: []const std.math.big.Limb) !Zir.Inst.Ref { |
| | 8211 | const astgen = gz.astgen; |
| | 8212 | const gpa = astgen.gpa; |
| | 8213 | try gz.instructions.ensureUnusedCapacity(gpa, 1); |
| | 8214 | try astgen.instructions.ensureUnusedCapacity(gpa, 1); |
| | 8215 | try astgen.string_bytes.ensureUnusedCapacity(gpa, @sizeOf(std.math.big.Limb) * limbs.len); |
| | 8216 | |
| | 8217 | const new_index = @intCast(Zir.Inst.Index, astgen.instructions.len); |
| | 8218 | astgen.instructions.appendAssumeCapacity(.{ |
| | 8219 | .tag = .int_big, |
| | 8220 | .data = .{ .str = .{ |
| | 8221 | .start = @intCast(u32, astgen.string_bytes.items.len), |
| | 8222 | .len = @intCast(u32, limbs.len), |
| | 8223 | } }, |
| | 8224 | }); |
| | 8225 | gz.instructions.appendAssumeCapacity(new_index); |
| | 8226 | astgen.string_bytes.appendSliceAssumeCapacity(mem.sliceAsBytes(limbs)); |
| | 8227 | return gz.indexToRef(new_index); |
| | 8228 | } |
| | 8229 | |
| | 8230 | fn addFloat(gz: *GenZir, number: f32, src_node: ast.Node.Index) !Zir.Inst.Ref { |
| | 8231 | return gz.add(.{ |
| | 8232 | .tag = .float, |
| | 8233 | .data = .{ .float = .{ |
| | 8234 | .src_node = gz.nodeIndexToRelative(src_node), |
| | 8235 | .number = number, |
| | 8236 | } }, |
| | 8237 | }); |
| | 8238 | } |
| | 8239 | |
| | 8240 | fn addUnNode( |
| | 8241 | gz: *GenZir, |
| | 8242 | tag: Zir.Inst.Tag, |
| | 8243 | operand: Zir.Inst.Ref, |
| | 8244 | /// Absolute node index. This function does the conversion to offset from Decl. |
| | 8245 | src_node: ast.Node.Index, |
| | 8246 | ) !Zir.Inst.Ref { |
| | 8247 | assert(operand != .none); |
| | 8248 | return gz.add(.{ |
| | 8249 | .tag = tag, |
| | 8250 | .data = .{ .un_node = .{ |
| | 8251 | .operand = operand, |
| | 8252 | .src_node = gz.nodeIndexToRelative(src_node), |
| | 8253 | } }, |
| | 8254 | }); |
| | 8255 | } |
| | 8256 | |
| | 8257 | fn addPlNode( |
| | 8258 | gz: *GenZir, |
| | 8259 | tag: Zir.Inst.Tag, |
| | 8260 | /// Absolute node index. This function does the conversion to offset from Decl. |
| | 8261 | src_node: ast.Node.Index, |
| | 8262 | extra: anytype, |
| | 8263 | ) !Zir.Inst.Ref { |
| | 8264 | const gpa = gz.astgen.gpa; |
| | 8265 | try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1); |
| | 8266 | try gz.astgen.instructions.ensureCapacity(gpa, gz.astgen.instructions.len + 1); |
| | 8267 | |
| | 8268 | const payload_index = try gz.astgen.addExtra(extra); |
| | 8269 | const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); |
| | 8270 | gz.astgen.instructions.appendAssumeCapacity(.{ |
| | 8271 | .tag = tag, |
| | 8272 | .data = .{ .pl_node = .{ |
| | 8273 | .src_node = gz.nodeIndexToRelative(src_node), |
| | 8274 | .payload_index = payload_index, |
| | 8275 | } }, |
| | 8276 | }); |
| | 8277 | gz.instructions.appendAssumeCapacity(new_index); |
| | 8278 | return gz.indexToRef(new_index); |
| | 8279 | } |
| | 8280 | |
| | 8281 | fn addExtendedPayload( |
| | 8282 | gz: *GenZir, |
| | 8283 | opcode: Zir.Inst.Extended, |
| | 8284 | extra: anytype, |
| | 8285 | ) !Zir.Inst.Ref { |
| | 8286 | const gpa = gz.astgen.gpa; |
| | 8287 | |
| | 8288 | try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1); |
| | 8289 | try gz.astgen.instructions.ensureCapacity(gpa, gz.astgen.instructions.len + 1); |
| | 8290 | |
| | 8291 | const payload_index = try gz.astgen.addExtra(extra); |
| | 8292 | const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); |
| | 8293 | gz.astgen.instructions.appendAssumeCapacity(.{ |
| | 8294 | .tag = .extended, |
| | 8295 | .data = .{ .extended = .{ |
| | 8296 | .opcode = opcode, |
| | 8297 | .small = undefined, |
| | 8298 | .operand = payload_index, |
| | 8299 | } }, |
| | 8300 | }); |
| | 8301 | gz.instructions.appendAssumeCapacity(new_index); |
| | 8302 | return gz.indexToRef(new_index); |
| | 8303 | } |
| | 8304 | |
| | 8305 | fn addExtendedMultiOp( |
| | 8306 | gz: *GenZir, |
| | 8307 | opcode: Zir.Inst.Extended, |
| | 8308 | node: ast.Node.Index, |
| | 8309 | operands: []const Zir.Inst.Ref, |
| | 8310 | ) !Zir.Inst.Ref { |
| | 8311 | const astgen = gz.astgen; |
| | 8312 | const gpa = astgen.gpa; |
| | 8313 | |
| | 8314 | try gz.instructions.ensureUnusedCapacity(gpa, 1); |
| | 8315 | try astgen.instructions.ensureUnusedCapacity(gpa, 1); |
| | 8316 | try astgen.extra.ensureUnusedCapacity( |
| | 8317 | gpa, |
| | 8318 | @typeInfo(Zir.Inst.NodeMultiOp).Struct.fields.len + operands.len, |
| | 8319 | ); |
| | 8320 | |
| | 8321 | const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.NodeMultiOp{ |
| | 8322 | .src_node = gz.nodeIndexToRelative(node), |
| | 8323 | }); |
| | 8324 | const new_index = @intCast(Zir.Inst.Index, astgen.instructions.len); |
| | 8325 | astgen.instructions.appendAssumeCapacity(.{ |
| | 8326 | .tag = .extended, |
| | 8327 | .data = .{ .extended = .{ |
| | 8328 | .opcode = opcode, |
| | 8329 | .small = @intCast(u16, operands.len), |
| | 8330 | .operand = payload_index, |
| | 8331 | } }, |
| | 8332 | }); |
| | 8333 | gz.instructions.appendAssumeCapacity(new_index); |
| | 8334 | astgen.appendRefsAssumeCapacity(operands); |
| | 8335 | return gz.indexToRef(new_index); |
| | 8336 | } |
| | 8337 | |
| | 8338 | fn addArrayTypeSentinel( |
| | 8339 | gz: *GenZir, |
| | 8340 | len: Zir.Inst.Ref, |
| | 8341 | sentinel: Zir.Inst.Ref, |
| | 8342 | elem_type: Zir.Inst.Ref, |
| | 8343 | ) !Zir.Inst.Ref { |
| | 8344 | const gpa = gz.astgen.gpa; |
| | 8345 | try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1); |
| | 8346 | try gz.astgen.instructions.ensureCapacity(gpa, gz.astgen.instructions.len + 1); |
| | 8347 | |
| | 8348 | const payload_index = try gz.astgen.addExtra(Zir.Inst.ArrayTypeSentinel{ |
| | 8349 | .sentinel = sentinel, |
| | 8350 | .elem_type = elem_type, |
| | 8351 | }); |
| | 8352 | const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); |
| | 8353 | gz.astgen.instructions.appendAssumeCapacity(.{ |
| | 8354 | .tag = .array_type_sentinel, |
| | 8355 | .data = .{ .array_type_sentinel = .{ |
| | 8356 | .len = len, |
| | 8357 | .payload_index = payload_index, |
| | 8358 | } }, |
| | 8359 | }); |
| | 8360 | gz.instructions.appendAssumeCapacity(new_index); |
| | 8361 | return gz.indexToRef(new_index); |
| | 8362 | } |
| | 8363 | |
| | 8364 | fn addUnTok( |
| | 8365 | gz: *GenZir, |
| | 8366 | tag: Zir.Inst.Tag, |
| | 8367 | operand: Zir.Inst.Ref, |
| | 8368 | /// Absolute token index. This function does the conversion to Decl offset. |
| | 8369 | abs_tok_index: ast.TokenIndex, |
| | 8370 | ) !Zir.Inst.Ref { |
| | 8371 | assert(operand != .none); |
| | 8372 | return gz.add(.{ |
| | 8373 | .tag = tag, |
| | 8374 | .data = .{ .un_tok = .{ |
| | 8375 | .operand = operand, |
| | 8376 | .src_tok = gz.tokenIndexToRelative(abs_tok_index), |
| | 8377 | } }, |
| | 8378 | }); |
| | 8379 | } |
| | 8380 | |
| | 8381 | fn addStrTok( |
| | 8382 | gz: *GenZir, |
| | 8383 | tag: Zir.Inst.Tag, |
| | 8384 | str_index: u32, |
| | 8385 | /// Absolute token index. This function does the conversion to Decl offset. |
| | 8386 | abs_tok_index: ast.TokenIndex, |
| | 8387 | ) !Zir.Inst.Ref { |
| | 8388 | return gz.add(.{ |
| | 8389 | .tag = tag, |
| | 8390 | .data = .{ .str_tok = .{ |
| | 8391 | .start = str_index, |
| | 8392 | .src_tok = gz.tokenIndexToRelative(abs_tok_index), |
| | 8393 | } }, |
| | 8394 | }); |
| | 8395 | } |
| | 8396 | |
| | 8397 | fn addBreak( |
| | 8398 | gz: *GenZir, |
| | 8399 | tag: Zir.Inst.Tag, |
| | 8400 | break_block: Zir.Inst.Index, |
| | 8401 | operand: Zir.Inst.Ref, |
| | 8402 | ) !Zir.Inst.Index { |
| | 8403 | return gz.addAsIndex(.{ |
| | 8404 | .tag = tag, |
| | 8405 | .data = .{ .@"break" = .{ |
| | 8406 | .block_inst = break_block, |
| | 8407 | .operand = operand, |
| | 8408 | } }, |
| | 8409 | }); |
| | 8410 | } |
| | 8411 | |
| | 8412 | fn addBin( |
| | 8413 | gz: *GenZir, |
| | 8414 | tag: Zir.Inst.Tag, |
| | 8415 | lhs: Zir.Inst.Ref, |
| | 8416 | rhs: Zir.Inst.Ref, |
| | 8417 | ) !Zir.Inst.Ref { |
| | 8418 | assert(lhs != .none); |
| | 8419 | assert(rhs != .none); |
| | 8420 | return gz.add(.{ |
| | 8421 | .tag = tag, |
| | 8422 | .data = .{ .bin = .{ |
| | 8423 | .lhs = lhs, |
| | 8424 | .rhs = rhs, |
| | 8425 | } }, |
| | 8426 | }); |
| | 8427 | } |
| | 8428 | |
| | 8429 | fn addDecl( |
| | 8430 | gz: *GenZir, |
| | 8431 | tag: Zir.Inst.Tag, |
| | 8432 | decl_index: u32, |
| | 8433 | src_node: ast.Node.Index, |
| | 8434 | ) !Zir.Inst.Ref { |
| | 8435 | return gz.add(.{ |
| | 8436 | .tag = tag, |
| | 8437 | .data = .{ .pl_node = .{ |
| | 8438 | .src_node = gz.nodeIndexToRelative(src_node), |
| | 8439 | .payload_index = decl_index, |
| | 8440 | } }, |
| | 8441 | }); |
| | 8442 | } |
| | 8443 | |
| | 8444 | fn addNode( |
| | 8445 | gz: *GenZir, |
| | 8446 | tag: Zir.Inst.Tag, |
| | 8447 | /// Absolute node index. This function does the conversion to offset from Decl. |
| | 8448 | src_node: ast.Node.Index, |
| | 8449 | ) !Zir.Inst.Ref { |
| | 8450 | return gz.add(.{ |
| | 8451 | .tag = tag, |
| | 8452 | .data = .{ .node = gz.nodeIndexToRelative(src_node) }, |
| | 8453 | }); |
| | 8454 | } |
| | 8455 | |
| | 8456 | fn addNodeExtended( |
| | 8457 | gz: *GenZir, |
| | 8458 | opcode: Zir.Inst.Extended, |
| | 8459 | /// Absolute node index. This function does the conversion to offset from Decl. |
| | 8460 | src_node: ast.Node.Index, |
| | 8461 | ) !Zir.Inst.Ref { |
| | 8462 | return gz.add(.{ |
| | 8463 | .tag = .extended, |
| | 8464 | .data = .{ .extended = .{ |
| | 8465 | .opcode = opcode, |
| | 8466 | .small = undefined, |
| | 8467 | .operand = @bitCast(u32, gz.nodeIndexToRelative(src_node)), |
| | 8468 | } }, |
| | 8469 | }); |
| | 8470 | } |
| | 8471 | |
| | 8472 | fn addAllocExtended( |
| | 8473 | gz: *GenZir, |
| | 8474 | args: struct { |
| | 8475 | /// Absolute node index. This function does the conversion to offset from Decl. |
| | 8476 | node: ast.Node.Index, |
| | 8477 | type_inst: Zir.Inst.Ref, |
| | 8478 | align_inst: Zir.Inst.Ref, |
| | 8479 | is_const: bool, |
| | 8480 | is_comptime: bool, |
| | 8481 | }, |
| | 8482 | ) !Zir.Inst.Ref { |
| | 8483 | const astgen = gz.astgen; |
| | 8484 | const gpa = astgen.gpa; |
| | 8485 | |
| | 8486 | try gz.instructions.ensureUnusedCapacity(gpa, 1); |
| | 8487 | try astgen.instructions.ensureUnusedCapacity(gpa, 1); |
| | 8488 | try astgen.extra.ensureUnusedCapacity( |
| | 8489 | gpa, |
| | 8490 | @typeInfo(Zir.Inst.AllocExtended).Struct.fields.len + |
| | 8491 | @as(usize, @boolToInt(args.type_inst != .none)) + |
| | 8492 | @as(usize, @boolToInt(args.align_inst != .none)), |
| | 8493 | ); |
| | 8494 | const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.AllocExtended{ |
| | 8495 | .src_node = gz.nodeIndexToRelative(args.node), |
| | 8496 | }); |
| | 8497 | if (args.type_inst != .none) { |
| | 8498 | astgen.extra.appendAssumeCapacity(@enumToInt(args.type_inst)); |
| | 8499 | } |
| | 8500 | if (args.align_inst != .none) { |
| | 8501 | astgen.extra.appendAssumeCapacity(@enumToInt(args.align_inst)); |
| | 8502 | } |
| | 8503 | |
| | 8504 | const has_type: u4 = @boolToInt(args.type_inst != .none); |
| | 8505 | const has_align: u4 = @boolToInt(args.align_inst != .none); |
| | 8506 | const is_const: u4 = @boolToInt(args.is_const); |
| | 8507 | const is_comptime: u4 = @boolToInt(args.is_comptime); |
| | 8508 | const small: u16 = has_type | (has_align << 1) | (is_const << 2) | (is_comptime << 3); |
| | 8509 | |
| | 8510 | const new_index = @intCast(Zir.Inst.Index, astgen.instructions.len); |
| | 8511 | astgen.instructions.appendAssumeCapacity(.{ |
| | 8512 | .tag = .extended, |
| | 8513 | .data = .{ .extended = .{ |
| | 8514 | .opcode = .alloc, |
| | 8515 | .small = small, |
| | 8516 | .operand = payload_index, |
| | 8517 | } }, |
| | 8518 | }); |
| | 8519 | gz.instructions.appendAssumeCapacity(new_index); |
| | 8520 | return gz.indexToRef(new_index); |
| | 8521 | } |
| | 8522 | |
| | 8523 | fn addAsm( |
| | 8524 | gz: *GenZir, |
| | 8525 | args: struct { |
| | 8526 | /// Absolute node index. This function does the conversion to offset from Decl. |
| | 8527 | node: ast.Node.Index, |
| | 8528 | asm_source: Zir.Inst.Ref, |
| | 8529 | output_type_bits: u32, |
| | 8530 | is_volatile: bool, |
| | 8531 | outputs: []const Zir.Inst.Asm.Output, |
| | 8532 | inputs: []const Zir.Inst.Asm.Input, |
| | 8533 | clobbers: []const u32, |
| | 8534 | }, |
| | 8535 | ) !Zir.Inst.Ref { |
| | 8536 | const astgen = gz.astgen; |
| | 8537 | const gpa = astgen.gpa; |
| | 8538 | |
| | 8539 | try gz.instructions.ensureUnusedCapacity(gpa, 1); |
| | 8540 | try astgen.instructions.ensureUnusedCapacity(gpa, 1); |
| | 8541 | try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Asm).Struct.fields.len + |
| | 8542 | args.outputs.len * @typeInfo(Zir.Inst.Asm.Output).Struct.fields.len + |
| | 8543 | args.inputs.len * @typeInfo(Zir.Inst.Asm.Input).Struct.fields.len + |
| | 8544 | args.clobbers.len); |
| | 8545 | |
| | 8546 | const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Asm{ |
| | 8547 | .src_node = gz.nodeIndexToRelative(args.node), |
| | 8548 | .asm_source = args.asm_source, |
| | 8549 | .output_type_bits = args.output_type_bits, |
| | 8550 | }); |
| | 8551 | for (args.outputs) |output| { |
| | 8552 | _ = gz.astgen.addExtraAssumeCapacity(output); |
| | 8553 | } |
| | 8554 | for (args.inputs) |input| { |
| | 8555 | _ = gz.astgen.addExtraAssumeCapacity(input); |
| | 8556 | } |
| | 8557 | gz.astgen.extra.appendSliceAssumeCapacity(args.clobbers); |
| | 8558 | |
| | 8559 | // * 0b00000000_000XXXXX - `outputs_len`. |
| | 8560 | // * 0b000000XX_XXX00000 - `inputs_len`. |
| | 8561 | // * 0b0XXXXX00_00000000 - `clobbers_len`. |
| | 8562 | // * 0bX0000000_00000000 - is volatile |
| | 8563 | const small: u16 = @intCast(u16, args.outputs.len) | |
| | 8564 | @intCast(u16, args.inputs.len << 5) | |
| | 8565 | @intCast(u16, args.clobbers.len << 10) | |
| | 8566 | (@as(u16, @boolToInt(args.is_volatile)) << 15); |
| | 8567 | |
| | 8568 | const new_index = @intCast(Zir.Inst.Index, astgen.instructions.len); |
| | 8569 | astgen.instructions.appendAssumeCapacity(.{ |
| | 8570 | .tag = .extended, |
| | 8571 | .data = .{ .extended = .{ |
| | 8572 | .opcode = .@"asm", |
| | 8573 | .small = small, |
| | 8574 | .operand = payload_index, |
| | 8575 | } }, |
| | 8576 | }); |
| | 8577 | gz.instructions.appendAssumeCapacity(new_index); |
| | 8578 | return gz.indexToRef(new_index); |
| | 8579 | } |
| | 8580 | |
| | 8581 | /// Note that this returns a `Zir.Inst.Index` not a ref. |
| | 8582 | /// Does *not* append the block instruction to the scope. |
| | 8583 | /// Leaves the `payload_index` field undefined. |
| | 8584 | fn addBlock(gz: *GenZir, tag: Zir.Inst.Tag, node: ast.Node.Index) !Zir.Inst.Index { |
| | 8585 | const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); |
| | 8586 | const gpa = gz.astgen.gpa; |
| | 8587 | try gz.astgen.instructions.append(gpa, .{ |
| | 8588 | .tag = tag, |
| | 8589 | .data = .{ .pl_node = .{ |
| | 8590 | .src_node = gz.nodeIndexToRelative(node), |
| | 8591 | .payload_index = undefined, |
| | 8592 | } }, |
| | 8593 | }); |
| | 8594 | return new_index; |
| | 8595 | } |
| | 8596 | |
| | 8597 | /// Note that this returns a `Zir.Inst.Index` not a ref. |
| | 8598 | /// Leaves the `payload_index` field undefined. |
| | 8599 | fn addCondBr(gz: *GenZir, tag: Zir.Inst.Tag, node: ast.Node.Index) !Zir.Inst.Index { |
| | 8600 | const gpa = gz.astgen.gpa; |
| | 8601 | try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1); |
| | 8602 | const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); |
| | 8603 | try gz.astgen.instructions.append(gpa, .{ |
| | 8604 | .tag = tag, |
| | 8605 | .data = .{ .pl_node = .{ |
| | 8606 | .src_node = gz.nodeIndexToRelative(node), |
| | 8607 | .payload_index = undefined, |
| | 8608 | } }, |
| | 8609 | }); |
| | 8610 | gz.instructions.appendAssumeCapacity(new_index); |
| | 8611 | return new_index; |
| | 8612 | } |
| | 8613 | |
| | 8614 | fn add(gz: *GenZir, inst: Zir.Inst) !Zir.Inst.Ref { |
| | 8615 | return gz.indexToRef(try gz.addAsIndex(inst)); |
| | 8616 | } |
| | 8617 | |
| | 8618 | fn addAsIndex(gz: *GenZir, inst: Zir.Inst) !Zir.Inst.Index { |
| | 8619 | const gpa = gz.astgen.gpa; |
| | 8620 | try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1); |
| | 8621 | try gz.astgen.instructions.ensureCapacity(gpa, gz.astgen.instructions.len + 1); |
| | 8622 | |
| | 8623 | const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); |
| | 8624 | gz.astgen.instructions.appendAssumeCapacity(inst); |
| | 8625 | gz.instructions.appendAssumeCapacity(new_index); |
| | 8626 | return new_index; |
| | 8627 | } |
| | 8628 | }; |