| ... | @@ -1367,7 +1367,7 @@ pub fn structInitExprRlNone( | ... | @@ -1367,7 +1367,7 @@ pub fn structInitExprRlNone( |
| 1367 | | 1367 | |
| 1368 | for (struct_init.ast.fields) |field_init, i| { | 1368 | for (struct_init.ast.fields) |field_init, i| { |
| 1369 | const name_token = tree.firstToken(field_init) - 2; | 1369 | const name_token = tree.firstToken(field_init) - 2; |
| 1370 | const str_index = try gz.identAsString(name_token); | 1370 | const str_index = try astgen.identAsString(name_token); |
| 1371 | | 1371 | |
| 1372 | fields_list[i] = .{ | 1372 | fields_list[i] = .{ |
| 1373 | .field_name = str_index, | 1373 | .field_name = str_index, |
| ... | @@ -1402,7 +1402,7 @@ pub fn structInitExprRlPtr( | ... | @@ -1402,7 +1402,7 @@ pub fn structInitExprRlPtr( |
| 1402 | | 1402 | |
| 1403 | for (struct_init.ast.fields) |field_init, i| { | 1403 | for (struct_init.ast.fields) |field_init, i| { |
| 1404 | const name_token = tree.firstToken(field_init) - 2; | 1404 | const name_token = tree.firstToken(field_init) - 2; |
| 1405 | const str_index = try gz.identAsString(name_token); | 1405 | const str_index = try astgen.identAsString(name_token); |
| 1406 | const field_ptr = try gz.addPlNode(.field_ptr, field_init, Zir.Inst.Field{ | 1406 | const field_ptr = try gz.addPlNode(.field_ptr, field_init, Zir.Inst.Field{ |
| 1407 | .lhs = result_ptr, | 1407 | .lhs = result_ptr, |
| 1408 | .field_name_start = str_index, | 1408 | .field_name_start = str_index, |
| ... | @@ -1435,7 +1435,7 @@ pub fn structInitExprRlTy( | ... | @@ -1435,7 +1435,7 @@ pub fn structInitExprRlTy( |
| 1435 | | 1435 | |
| 1436 | for (struct_init.ast.fields) |field_init, i| { | 1436 | for (struct_init.ast.fields) |field_init, i| { |
| 1437 | const name_token = tree.firstToken(field_init) - 2; | 1437 | const name_token = tree.firstToken(field_init) - 2; |
| 1438 | const str_index = try gz.identAsString(name_token); | 1438 | const str_index = try astgen.identAsString(name_token); |
| 1439 | | 1439 | |
| 1440 | const field_ty_inst = try gz.addPlNode(.field_type, field_init, Zir.Inst.FieldType{ | 1440 | const field_ty_inst = try gz.addPlNode(.field_type, field_init, Zir.Inst.FieldType{ |
| 1441 | .container_type = ty_inst, | 1441 | .container_type = ty_inst, |
| ... | @@ -1832,6 +1832,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner | ... | @@ -1832,6 +1832,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner |
| 1832 | // ZIR instructions that might be a type other than `noreturn` or `void`. | 1832 | // ZIR instructions that might be a type other than `noreturn` or `void`. |
| 1833 | .add, | 1833 | .add, |
| 1834 | .addwrap, | 1834 | .addwrap, |
| | 1835 | .arg, |
| 1835 | .alloc, | 1836 | .alloc, |
| 1836 | .alloc_mut, | 1837 | .alloc_mut, |
| 1837 | .alloc_comptime, | 1838 | .alloc_comptime, |
| ... | @@ -2163,7 +2164,7 @@ fn varDecl( | ... | @@ -2163,7 +2164,7 @@ fn varDecl( |
| 2163 | const token_tags = tree.tokens.items(.tag); | 2164 | const token_tags = tree.tokens.items(.tag); |
| 2164 | | 2165 | |
| 2165 | const name_token = var_decl.ast.mut_token + 1; | 2166 | const name_token = var_decl.ast.mut_token + 1; |
| 2166 | const ident_name = try astgen.identifierTokenString(name_token); | 2167 | const ident_name = try astgen.identAsString(name_token); |
| 2167 | | 2168 | |
| 2168 | // Local variables shadowing detection, including function parameters. | 2169 | // Local variables shadowing detection, including function parameters. |
| 2169 | { | 2170 | { |
| ... | @@ -2171,9 +2172,9 @@ fn varDecl( | ... | @@ -2171,9 +2172,9 @@ fn varDecl( |
| 2171 | while (true) switch (s.tag) { | 2172 | while (true) switch (s.tag) { |
| 2172 | .local_val => { | 2173 | .local_val => { |
| 2173 | const local_val = s.cast(Scope.LocalVal).?; | 2174 | const local_val = s.cast(Scope.LocalVal).?; |
| 2174 | if (mem.eql(u8, local_val.name, ident_name)) { | 2175 | if (local_val.name == ident_name) { |
| 2175 | return astgen.failTokNotes(name_token, "redeclaration of '{s}'", .{ | 2176 | return astgen.failTokNotes(name_token, "redeclaration of '{s}'", .{ |
| 2176 | ident_name, | 2177 | @ptrCast([*:0]const u8, astgen.string_bytes.items.ptr) + ident_name, |
| 2177 | }, &[_]u32{ | 2178 | }, &[_]u32{ |
| 2178 | try astgen.errNoteTok( | 2179 | try astgen.errNoteTok( |
| 2179 | local_val.token_src, | 2180 | local_val.token_src, |
| ... | @@ -2186,9 +2187,9 @@ fn varDecl( | ... | @@ -2186,9 +2187,9 @@ fn varDecl( |
| 2186 | }, | 2187 | }, |
| 2187 | .local_ptr => { | 2188 | .local_ptr => { |
| 2188 | const local_ptr = s.cast(Scope.LocalPtr).?; | 2189 | const local_ptr = s.cast(Scope.LocalPtr).?; |
| 2189 | if (mem.eql(u8, local_ptr.name, ident_name)) { | 2190 | if (local_ptr.name == ident_name) { |
| 2190 | return astgen.failTokNotes(name_token, "redeclaration of '{s}'", .{ | 2191 | return astgen.failTokNotes(name_token, "redeclaration of '{s}'", .{ |
| 2191 | ident_name, | 2192 | @ptrCast([*:0]const u8, astgen.string_bytes.items.ptr) + ident_name, |
| 2192 | }, &[_]u32{ | 2193 | }, &[_]u32{ |
| 2193 | try astgen.errNoteTok( | 2194 | try astgen.errNoteTok( |
| 2194 | local_ptr.token_src, | 2195 | local_ptr.token_src, |
| ... | @@ -2690,7 +2691,6 @@ fn fnDecl( | ... | @@ -2690,7 +2691,6 @@ fn fnDecl( |
| 2690 | .decl_node_index = fn_proto.ast.proto_node, | 2691 | .decl_node_index = fn_proto.ast.proto_node, |
| 2691 | .parent = &gz.base, | 2692 | .parent = &gz.base, |
| 2692 | .astgen = astgen, | 2693 | .astgen = astgen, |
| 2693 | .ref_start_index = @intCast(u32, Zir.Inst.Ref.typed_value_map.len), | | |
| 2694 | }; | 2694 | }; |
| 2695 | defer decl_gz.instructions.deinit(gpa); | 2695 | defer decl_gz.instructions.deinit(gpa); |
| 2696 | | 2696 | |
| ... | @@ -2757,7 +2757,7 @@ fn fnDecl( | ... | @@ -2757,7 +2757,7 @@ fn fnDecl( |
| 2757 | } | 2757 | } |
| 2758 | | 2758 | |
| 2759 | const lib_name: u32 = if (fn_proto.lib_name) |lib_name_token| blk: { | 2759 | const lib_name: u32 = if (fn_proto.lib_name) |lib_name_token| blk: { |
| 2760 | const lib_name_str = try decl_gz.strLitAsString(lib_name_token); | 2760 | const lib_name_str = try astgen.strLitAsString(lib_name_token); |
| 2761 | break :blk lib_name_str.index; | 2761 | break :blk lib_name_str.index; |
| 2762 | } else 0; | 2762 | } else 0; |
| 2763 | | 2763 | |
| ... | @@ -2812,7 +2812,6 @@ fn fnDecl( | ... | @@ -2812,7 +2812,6 @@ fn fnDecl( |
| 2812 | .decl_node_index = fn_proto.ast.proto_node, | 2812 | .decl_node_index = fn_proto.ast.proto_node, |
| 2813 | .parent = &decl_gz.base, | 2813 | .parent = &decl_gz.base, |
| 2814 | .astgen = astgen, | 2814 | .astgen = astgen, |
| 2815 | .ref_start_index = @intCast(u32, Zir.Inst.Ref.typed_value_map.len + param_count), | | |
| 2816 | }; | 2815 | }; |
| 2817 | defer fn_gz.instructions.deinit(gpa); | 2816 | defer fn_gz.instructions.deinit(gpa); |
| 2818 | | 2817 | |
| ... | @@ -2832,21 +2831,24 @@ fn fnDecl( | ... | @@ -2832,21 +2831,24 @@ fn fnDecl( |
| 2832 | const name_token = param.name_token orelse { | 2831 | const name_token = param.name_token orelse { |
| 2833 | return astgen.failNode(param.type_expr, "missing parameter name", .{}); | 2832 | return astgen.failNode(param.type_expr, "missing parameter name", .{}); |
| 2834 | }; | 2833 | }; |
| 2835 | const param_name = try astgen.identifierTokenString(name_token); | 2834 | const param_name = try astgen.identAsString(name_token); |
| | 2835 | // Create an arg instruction. This is needed to emit a semantic analysis |
| | 2836 | // error for shadowing decls. |
| | 2837 | // TODO emit a compile error here for shadowing locals. |
| | 2838 | const arg_inst = try fn_gz.addStrTok(.arg, param_name, name_token); |
| 2836 | const sub_scope = try astgen.arena.create(Scope.LocalVal); | 2839 | const sub_scope = try astgen.arena.create(Scope.LocalVal); |
| 2837 | sub_scope.* = .{ | 2840 | sub_scope.* = .{ |
| 2838 | .parent = params_scope, | 2841 | .parent = params_scope, |
| 2839 | .gen_zir = &fn_gz, | 2842 | .gen_zir = &fn_gz, |
| 2840 | .name = param_name, | 2843 | .name = param_name, |
| 2841 | // Implicit const list first, then implicit arg list. | 2844 | .inst = arg_inst, |
| 2842 | .inst = @intToEnum(Zir.Inst.Ref, @intCast(u32, Zir.Inst.Ref.typed_value_map.len + i)), | | |
| 2843 | .token_src = name_token, | 2845 | .token_src = name_token, |
| 2844 | }; | 2846 | }; |
| 2845 | params_scope = &sub_scope.base; | 2847 | params_scope = &sub_scope.base; |
| 2846 | | 2848 | |
| 2847 | // Additionally put the param name into `string_bytes` and reference it with | 2849 | // Additionally put the param name into `string_bytes` and reference it with |
| 2848 | // `extra` so that we have access to the data in codegen, for debug info. | 2850 | // `extra` so that we have access to the data in codegen, for debug info. |
| 2849 | const str_index = try fn_gz.identAsString(name_token); | 2851 | const str_index = try astgen.identAsString(name_token); |
| 2850 | astgen.extra.appendAssumeCapacity(str_index); | 2852 | astgen.extra.appendAssumeCapacity(str_index); |
| 2851 | } | 2853 | } |
| 2852 | | 2854 | |
| ... | @@ -2880,7 +2882,7 @@ fn fnDecl( | ... | @@ -2880,7 +2882,7 @@ fn fnDecl( |
| 2880 | const fn_name_token = fn_proto.name_token orelse { | 2882 | const fn_name_token = fn_proto.name_token orelse { |
| 2881 | return astgen.failTok(fn_proto.ast.fn_token, "missing function name", .{}); | 2883 | return astgen.failTok(fn_proto.ast.fn_token, "missing function name", .{}); |
| 2882 | }; | 2884 | }; |
| 2883 | const fn_name_str_index = try decl_gz.identAsString(fn_name_token); | 2885 | const fn_name_str_index = try astgen.identAsString(fn_name_token); |
| 2884 | | 2886 | |
| 2885 | // We add this at the end so that its instruction index marks the end range | 2887 | // We add this at the end so that its instruction index marks the end range |
| 2886 | // of the top level declaration. | 2888 | // of the top level declaration. |
| ... | @@ -2953,7 +2955,7 @@ fn globalVarDecl( | ... | @@ -2953,7 +2955,7 @@ fn globalVarDecl( |
| 2953 | } else false; | 2955 | } else false; |
| 2954 | | 2956 | |
| 2955 | const lib_name: u32 = if (var_decl.lib_name) |lib_name_token| blk: { | 2957 | const lib_name: u32 = if (var_decl.lib_name) |lib_name_token| blk: { |
| 2956 | const lib_name_str = try gz.strLitAsString(lib_name_token); | 2958 | const lib_name_str = try astgen.strLitAsString(lib_name_token); |
| 2957 | break :blk lib_name_str.index; | 2959 | break :blk lib_name_str.index; |
| 2958 | } else 0; | 2960 | } else 0; |
| 2959 | | 2961 | |
| ... | @@ -3020,7 +3022,7 @@ fn globalVarDecl( | ... | @@ -3020,7 +3022,7 @@ fn globalVarDecl( |
| 3020 | try block_scope.setBlockBody(block_inst); | 3022 | try block_scope.setBlockBody(block_inst); |
| 3021 | | 3023 | |
| 3022 | const name_token = var_decl.ast.mut_token + 1; | 3024 | const name_token = var_decl.ast.mut_token + 1; |
| 3023 | const name_str_index = try gz.identAsString(name_token); | 3025 | const name_str_index = try astgen.identAsString(name_token); |
| 3024 | | 3026 | |
| 3025 | try wip_decls.payload.ensureUnusedCapacity(gpa, 8); | 3027 | try wip_decls.payload.ensureUnusedCapacity(gpa, 8); |
| 3026 | { | 3028 | { |
| ... | @@ -3156,7 +3158,7 @@ fn testDecl( | ... | @@ -3156,7 +3158,7 @@ fn testDecl( |
| 3156 | const test_token = main_tokens[node]; | 3158 | const test_token = main_tokens[node]; |
| 3157 | const str_lit_token = test_token + 1; | 3159 | const str_lit_token = test_token + 1; |
| 3158 | if (token_tags[str_lit_token] == .string_literal) { | 3160 | if (token_tags[str_lit_token] == .string_literal) { |
| 3159 | break :blk (try decl_block.strLitAsString(str_lit_token)).index; | 3161 | break :blk (try astgen.strLitAsString(str_lit_token)).index; |
| 3160 | } | 3162 | } |
| 3161 | // String table index 1 has a special meaning here of test decl with no name. | 3163 | // String table index 1 has a special meaning here of test decl with no name. |
| 3162 | break :blk 1; | 3164 | break :blk 1; |
| ... | @@ -3344,7 +3346,7 @@ fn structDeclInner( | ... | @@ -3344,7 +3346,7 @@ fn structDeclInner( |
| 3344 | } | 3346 | } |
| 3345 | try fields_data.ensureUnusedCapacity(gpa, 4); | 3347 | try fields_data.ensureUnusedCapacity(gpa, 4); |
| 3346 | | 3348 | |
| 3347 | const field_name = try gz.identAsString(member.ast.name_token); | 3349 | const field_name = try astgen.identAsString(member.ast.name_token); |
| 3348 | fields_data.appendAssumeCapacity(field_name); | 3350 | fields_data.appendAssumeCapacity(field_name); |
| 3349 | | 3351 | |
| 3350 | const field_type: Zir.Inst.Ref = if (node_tags[member.ast.type_expr] == .@"anytype") | 3352 | const field_type: Zir.Inst.Ref = if (node_tags[member.ast.type_expr] == .@"anytype") |
| ... | @@ -3558,7 +3560,7 @@ fn unionDeclInner( | ... | @@ -3558,7 +3560,7 @@ fn unionDeclInner( |
| 3558 | } | 3560 | } |
| 3559 | try fields_data.ensureUnusedCapacity(gpa, 4); | 3561 | try fields_data.ensureUnusedCapacity(gpa, 4); |
| 3560 | | 3562 | |
| 3561 | const field_name = try gz.identAsString(member.ast.name_token); | 3563 | const field_name = try astgen.identAsString(member.ast.name_token); |
| 3562 | fields_data.appendAssumeCapacity(field_name); | 3564 | fields_data.appendAssumeCapacity(field_name); |
| 3563 | | 3565 | |
| 3564 | const have_type = member.ast.type_expr != 0; | 3566 | const have_type = member.ast.type_expr != 0; |
| ... | @@ -3906,7 +3908,7 @@ fn containerDecl( | ... | @@ -3906,7 +3908,7 @@ fn containerDecl( |
| 3906 | assert(member.ast.type_expr == 0); | 3908 | assert(member.ast.type_expr == 0); |
| 3907 | assert(member.ast.align_expr == 0); | 3909 | assert(member.ast.align_expr == 0); |
| 3908 | | 3910 | |
| 3909 | const field_name = try gz.identAsString(member.ast.name_token); | 3911 | const field_name = try astgen.identAsString(member.ast.name_token); |
| 3910 | fields_data.appendAssumeCapacity(field_name); | 3912 | fields_data.appendAssumeCapacity(field_name); |
| 3911 | | 3913 | |
| 3912 | const have_value = member.ast.value_expr != 0; | 3914 | const have_value = member.ast.value_expr != 0; |
| ... | @@ -4115,7 +4117,7 @@ fn errorSetDecl( | ... | @@ -4115,7 +4117,7 @@ fn errorSetDecl( |
| 4115 | switch (token_tags[tok_i]) { | 4117 | switch (token_tags[tok_i]) { |
| 4116 | .doc_comment, .comma => {}, | 4118 | .doc_comment, .comma => {}, |
| 4117 | .identifier => { | 4119 | .identifier => { |
| 4118 | const str_index = try gz.identAsString(tok_i); | 4120 | const str_index = try astgen.identAsString(tok_i); |
| 4119 | try field_names.append(gpa, str_index); | 4121 | try field_names.append(gpa, str_index); |
| 4120 | field_i += 1; | 4122 | field_i += 1; |
| 4121 | }, | 4123 | }, |
| ... | @@ -4255,7 +4257,7 @@ fn orelseCatchExpr( | ... | @@ -4255,7 +4257,7 @@ fn orelseCatchExpr( |
| 4255 | if (mem.eql(u8, tree.tokenSlice(payload), "_")) { | 4257 | if (mem.eql(u8, tree.tokenSlice(payload), "_")) { |
| 4256 | return astgen.failTok(payload, "discard of error capture; omit it instead", .{}); | 4258 | return astgen.failTok(payload, "discard of error capture; omit it instead", .{}); |
| 4257 | } | 4259 | } |
| 4258 | const err_name = try astgen.identifierTokenString(payload); | 4260 | const err_name = try astgen.identAsString(payload); |
| 4259 | err_val_scope = .{ | 4261 | err_val_scope = .{ |
| 4260 | .parent = &then_scope.base, | 4262 | .parent = &then_scope.base, |
| 4261 | .gen_zir = &then_scope, | 4263 | .gen_zir = &then_scope, |
| ... | @@ -4386,7 +4388,7 @@ pub fn fieldAccess( | ... | @@ -4386,7 +4388,7 @@ pub fn fieldAccess( |
| 4386 | const object_node = node_datas[node].lhs; | 4388 | const object_node = node_datas[node].lhs; |
| 4387 | const dot_token = main_tokens[node]; | 4389 | const dot_token = main_tokens[node]; |
| 4388 | const field_ident = dot_token + 1; | 4390 | const field_ident = dot_token + 1; |
| 4389 | const str_index = try gz.identAsString(field_ident); | 4391 | const str_index = try astgen.identAsString(field_ident); |
| 4390 | switch (rl) { | 4392 | switch (rl) { |
| 4391 | .ref => return gz.addPlNode(.field_ptr, node, Zir.Inst.Field{ | 4393 | .ref => return gz.addPlNode(.field_ptr, node, Zir.Inst.Field{ |
| 4392 | .lhs = try expr(gz, scope, .ref, object_node), | 4394 | .lhs = try expr(gz, scope, .ref, object_node), |
| ... | @@ -4449,7 +4451,8 @@ fn simpleStrTok( | ... | @@ -4449,7 +4451,8 @@ fn simpleStrTok( |
| 4449 | node: ast.Node.Index, | 4451 | node: ast.Node.Index, |
| 4450 | op_inst_tag: Zir.Inst.Tag, | 4452 | op_inst_tag: Zir.Inst.Tag, |
| 4451 | ) InnerError!Zir.Inst.Ref { | 4453 | ) InnerError!Zir.Inst.Ref { |
| 4452 | const str_index = try gz.identAsString(ident_token); | 4454 | const astgen = gz.astgen; |
| | 4455 | const str_index = try astgen.identAsString(ident_token); |
| 4453 | const result = try gz.addStrTok(op_inst_tag, str_index, ident_token); | 4456 | const result = try gz.addStrTok(op_inst_tag, str_index, ident_token); |
| 4454 | return rvalue(gz, scope, rl, result, node); | 4457 | return rvalue(gz, scope, rl, result, node); |
| 4455 | } | 4458 | } |
| ... | @@ -4545,7 +4548,7 @@ fn ifExpr( | ... | @@ -4545,7 +4548,7 @@ fn ifExpr( |
| 4545 | else | 4548 | else |
| 4546 | .err_union_payload_unsafe; | 4549 | .err_union_payload_unsafe; |
| 4547 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, node); | 4550 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, node); |
| 4548 | const ident_name = try astgen.identifierTokenString(error_token); | 4551 | const ident_name = try astgen.identAsString(error_token); |
| 4549 | payload_val_scope = .{ | 4552 | payload_val_scope = .{ |
| 4550 | .parent = &then_scope.base, | 4553 | .parent = &then_scope.base, |
| 4551 | .gen_zir = &then_scope, | 4554 | .gen_zir = &then_scope, |
| ... | @@ -4561,7 +4564,7 @@ fn ifExpr( | ... | @@ -4561,7 +4564,7 @@ fn ifExpr( |
| 4561 | else | 4564 | else |
| 4562 | .optional_payload_unsafe; | 4565 | .optional_payload_unsafe; |
| 4563 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, node); | 4566 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, node); |
| 4564 | const ident_name = try astgen.identifierTokenString(ident_token); | 4567 | const ident_name = try astgen.identAsString(ident_token); |
| 4565 | payload_val_scope = .{ | 4568 | payload_val_scope = .{ |
| 4566 | .parent = &then_scope.base, | 4569 | .parent = &then_scope.base, |
| 4567 | .gen_zir = &then_scope, | 4570 | .gen_zir = &then_scope, |
| ... | @@ -4597,7 +4600,7 @@ fn ifExpr( | ... | @@ -4597,7 +4600,7 @@ fn ifExpr( |
| 4597 | else | 4600 | else |
| 4598 | .err_union_code; | 4601 | .err_union_code; |
| 4599 | const payload_inst = try else_scope.addUnNode(tag, cond.inst, node); | 4602 | const payload_inst = try else_scope.addUnNode(tag, cond.inst, node); |
| 4600 | const ident_name = try astgen.identifierTokenString(error_token); | 4603 | const ident_name = try astgen.identAsString(error_token); |
| 4601 | payload_val_scope = .{ | 4604 | payload_val_scope = .{ |
| 4602 | .parent = &else_scope.base, | 4605 | .parent = &else_scope.base, |
| 4603 | .gen_zir = &else_scope, | 4606 | .gen_zir = &else_scope, |
| ... | @@ -4804,7 +4807,7 @@ fn whileExpr( | ... | @@ -4804,7 +4807,7 @@ fn whileExpr( |
| 4804 | else | 4807 | else |
| 4805 | .err_union_payload_unsafe; | 4808 | .err_union_payload_unsafe; |
| 4806 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, node); | 4809 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, node); |
| 4807 | const ident_name = try astgen.identifierTokenString(error_token); | 4810 | const ident_name = try astgen.identAsString(error_token); |
| 4808 | payload_val_scope = .{ | 4811 | payload_val_scope = .{ |
| 4809 | .parent = &then_scope.base, | 4812 | .parent = &then_scope.base, |
| 4810 | .gen_zir = &then_scope, | 4813 | .gen_zir = &then_scope, |
| ... | @@ -4820,7 +4823,7 @@ fn whileExpr( | ... | @@ -4820,7 +4823,7 @@ fn whileExpr( |
| 4820 | else | 4823 | else |
| 4821 | .optional_payload_unsafe; | 4824 | .optional_payload_unsafe; |
| 4822 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, node); | 4825 | const payload_inst = try then_scope.addUnNode(tag, cond.inst, node); |
| 4823 | const ident_name = try astgen.identifierTokenString(ident_token); | 4826 | const ident_name = try astgen.identAsString(ident_token); |
| 4824 | payload_val_scope = .{ | 4827 | payload_val_scope = .{ |
| 4825 | .parent = &then_scope.base, | 4828 | .parent = &then_scope.base, |
| 4826 | .gen_zir = &then_scope, | 4829 | .gen_zir = &then_scope, |
| ... | @@ -4853,7 +4856,7 @@ fn whileExpr( | ... | @@ -4853,7 +4856,7 @@ fn whileExpr( |
| 4853 | else | 4856 | else |
| 4854 | .err_union_code; | 4857 | .err_union_code; |
| 4855 | const payload_inst = try else_scope.addUnNode(tag, cond.inst, node); | 4858 | const payload_inst = try else_scope.addUnNode(tag, cond.inst, node); |
| 4856 | const ident_name = try astgen.identifierTokenString(error_token); | 4859 | const ident_name = try astgen.identAsString(error_token); |
| 4857 | payload_val_scope = .{ | 4860 | payload_val_scope = .{ |
| 4858 | .parent = &else_scope.base, | 4861 | .parent = &else_scope.base, |
| 4859 | .gen_zir = &else_scope, | 4862 | .gen_zir = &else_scope, |
| ... | @@ -4988,12 +4991,13 @@ fn forExpr( | ... | @@ -4988,12 +4991,13 @@ fn forExpr( |
| 4988 | const value_name = tree.tokenSlice(ident); | 4991 | const value_name = tree.tokenSlice(ident); |
| 4989 | var payload_sub_scope: *Scope = undefined; | 4992 | var payload_sub_scope: *Scope = undefined; |
| 4990 | if (!mem.eql(u8, value_name, "_")) { | 4993 | if (!mem.eql(u8, value_name, "_")) { |
| | 4994 | const name_str_index = try astgen.identAsString(ident); |
| 4991 | const tag: Zir.Inst.Tag = if (is_ptr) .elem_ptr else .elem_val; | 4995 | const tag: Zir.Inst.Tag = if (is_ptr) .elem_ptr else .elem_val; |
| 4992 | const payload_inst = try then_scope.addBin(tag, array_ptr, index); | 4996 | const payload_inst = try then_scope.addBin(tag, array_ptr, index); |
| 4993 | payload_val_scope = .{ | 4997 | payload_val_scope = .{ |
| 4994 | .parent = &then_scope.base, | 4998 | .parent = &then_scope.base, |
| 4995 | .gen_zir = &then_scope, | 4999 | .gen_zir = &then_scope, |
| 4996 | .name = value_name, | 5000 | .name = name_str_index, |
| 4997 | .inst = payload_inst, | 5001 | .inst = payload_inst, |
| 4998 | .token_src = ident, | 5002 | .token_src = ident, |
| 4999 | }; | 5003 | }; |
| ... | @@ -5011,7 +5015,7 @@ fn forExpr( | ... | @@ -5011,7 +5015,7 @@ fn forExpr( |
| 5011 | if (mem.eql(u8, tree.tokenSlice(index_token), "_")) { | 5015 | if (mem.eql(u8, tree.tokenSlice(index_token), "_")) { |
| 5012 | return astgen.failTok(index_token, "discard of index capture; omit it instead", .{}); | 5016 | return astgen.failTok(index_token, "discard of index capture; omit it instead", .{}); |
| 5013 | } | 5017 | } |
| 5014 | const index_name = try astgen.identifierTokenString(index_token); | 5018 | const index_name = try astgen.identAsString(index_token); |
| 5015 | index_scope = .{ | 5019 | index_scope = .{ |
| 5016 | .parent = payload_sub_scope, | 5020 | .parent = payload_sub_scope, |
| 5017 | .gen_zir = &then_scope, | 5021 | .gen_zir = &then_scope, |
| ... | @@ -5364,7 +5368,7 @@ fn switchExpr( | ... | @@ -5364,7 +5368,7 @@ fn switchExpr( |
| 5364 | .prong_index = undefined, | 5368 | .prong_index = undefined, |
| 5365 | } }, | 5369 | } }, |
| 5366 | }); | 5370 | }); |
| 5367 | const capture_name = try astgen.identifierTokenString(payload_token); | 5371 | const capture_name = try astgen.identAsString(payload_token); |
| 5368 | capture_val_scope = .{ | 5372 | capture_val_scope = .{ |
| 5369 | .parent = &case_scope.base, | 5373 | .parent = &case_scope.base, |
| 5370 | .gen_zir = &case_scope, | 5374 | .gen_zir = &case_scope, |
| ... | @@ -5456,7 +5460,7 @@ fn switchExpr( | ... | @@ -5456,7 +5460,7 @@ fn switchExpr( |
| 5456 | .prong_index = capture_index, | 5460 | .prong_index = capture_index, |
| 5457 | } }, | 5461 | } }, |
| 5458 | }); | 5462 | }); |
| 5459 | const capture_name = try astgen.identifierTokenString(ident); | 5463 | const capture_name = try astgen.identAsString(ident); |
| 5460 | capture_val_scope = .{ | 5464 | capture_val_scope = .{ |
| 5461 | .parent = &case_scope.base, | 5465 | .parent = &case_scope.base, |
| 5462 | .gen_zir = &case_scope, | 5466 | .gen_zir = &case_scope, |
| ... | @@ -5810,7 +5814,7 @@ fn identifier( | ... | @@ -5810,7 +5814,7 @@ fn identifier( |
| 5810 | const ident_token = main_tokens[ident]; | 5814 | const ident_token = main_tokens[ident]; |
| 5811 | const ident_name = try astgen.identifierTokenString(ident_token); | 5815 | const ident_name = try astgen.identifierTokenString(ident_token); |
| 5812 | if (mem.eql(u8, ident_name, "_")) { | 5816 | if (mem.eql(u8, ident_name, "_")) { |
| 5813 | return astgen.failNode(ident, "TODO implement '_' identifier", .{}); | 5817 | return astgen.failNode(ident, "'_' may not be used as an identifier", .{}); |
| 5814 | } | 5818 | } |
| 5815 | | 5819 | |
| 5816 | if (simple_types.get(ident_name)) |zir_const_ref| { | 5820 | if (simple_types.get(ident_name)) |zir_const_ref| { |
| ... | @@ -5845,19 +5849,20 @@ fn identifier( | ... | @@ -5845,19 +5849,20 @@ fn identifier( |
| 5845 | } | 5849 | } |
| 5846 | | 5850 | |
| 5847 | // Local variables, including function parameters. | 5851 | // Local variables, including function parameters. |
| | 5852 | const name_str_index = try astgen.identAsString(ident_token); |
| 5848 | { | 5853 | { |
| 5849 | var s = scope; | 5854 | var s = scope; |
| 5850 | while (true) switch (s.tag) { | 5855 | while (true) switch (s.tag) { |
| 5851 | .local_val => { | 5856 | .local_val => { |
| 5852 | const local_val = s.cast(Scope.LocalVal).?; | 5857 | const local_val = s.cast(Scope.LocalVal).?; |
| 5853 | if (mem.eql(u8, local_val.name, ident_name)) { | 5858 | if (local_val.name == name_str_index) { |
| 5854 | return rvalue(gz, scope, rl, local_val.inst, ident); | 5859 | return rvalue(gz, scope, rl, local_val.inst, ident); |
| 5855 | } | 5860 | } |
| 5856 | s = local_val.parent; | 5861 | s = local_val.parent; |
| 5857 | }, | 5862 | }, |
| 5858 | .local_ptr => { | 5863 | .local_ptr => { |
| 5859 | const local_ptr = s.cast(Scope.LocalPtr).?; | 5864 | const local_ptr = s.cast(Scope.LocalPtr).?; |
| 5860 | if (mem.eql(u8, local_ptr.name, ident_name)) { | 5865 | if (local_ptr.name == name_str_index) { |
| 5861 | switch (rl) { | 5866 | switch (rl) { |
| 5862 | .ref, .none_or_ref => return local_ptr.ptr, | 5867 | .ref, .none_or_ref => return local_ptr.ptr, |
| 5863 | else => { | 5868 | else => { |
| ... | @@ -5876,11 +5881,10 @@ fn identifier( | ... | @@ -5876,11 +5881,10 @@ fn identifier( |
| 5876 | // We can't look up Decls until Sema because the same ZIR code is supposed to be | 5881 | // We can't look up Decls until Sema because the same ZIR code is supposed to be |
| 5877 | // used for multiple generic instantiations, and this may refer to a different Decl | 5882 | // used for multiple generic instantiations, and this may refer to a different Decl |
| 5878 | // depending on the scope, determined by the generic instantiation. | 5883 | // depending on the scope, determined by the generic instantiation. |
| 5879 | const str_index = try gz.identAsString(ident_token); | | |
| 5880 | switch (rl) { | 5884 | switch (rl) { |
| 5881 | .ref, .none_or_ref => return gz.addStrTok(.decl_ref, str_index, ident_token), | 5885 | .ref, .none_or_ref => return gz.addStrTok(.decl_ref, name_str_index, ident_token), |
| 5882 | else => { | 5886 | else => { |
| 5883 | const result = try gz.addStrTok(.decl_val, str_index, ident_token); | 5887 | const result = try gz.addStrTok(.decl_val, name_str_index, ident_token); |
| 5884 | return rvalue(gz, scope, rl, result, ident); | 5888 | return rvalue(gz, scope, rl, result, ident); |
| 5885 | }, | 5889 | }, |
| 5886 | } | 5890 | } |
| ... | @@ -5892,10 +5896,11 @@ fn stringLiteral( | ... | @@ -5892,10 +5896,11 @@ fn stringLiteral( |
| 5892 | rl: ResultLoc, | 5896 | rl: ResultLoc, |
| 5893 | node: ast.Node.Index, | 5897 | node: ast.Node.Index, |
| 5894 | ) InnerError!Zir.Inst.Ref { | 5898 | ) InnerError!Zir.Inst.Ref { |
| 5895 | const tree = gz.astgen.file.tree; | 5899 | const astgen = gz.astgen; |
| | 5900 | const tree = astgen.file.tree; |
| 5896 | const main_tokens = tree.nodes.items(.main_token); | 5901 | const main_tokens = tree.nodes.items(.main_token); |
| 5897 | const str_lit_token = main_tokens[node]; | 5902 | const str_lit_token = main_tokens[node]; |
| 5898 | const str = try gz.strLitAsString(str_lit_token); | 5903 | const str = try astgen.strLitAsString(str_lit_token); |
| 5899 | const result = try gz.add(.{ | 5904 | const result = try gz.add(.{ |
| 5900 | .tag = .str, | 5905 | .tag = .str, |
| 5901 | .data = .{ .str = .{ | 5906 | .data = .{ .str = .{ |
| ... | @@ -6097,9 +6102,9 @@ fn asmExpr( | ... | @@ -6097,9 +6102,9 @@ fn asmExpr( |
| 6097 | | 6102 | |
| 6098 | for (full.outputs) |output_node, i| { | 6103 | for (full.outputs) |output_node, i| { |
| 6099 | const symbolic_name = main_tokens[output_node]; | 6104 | const symbolic_name = main_tokens[output_node]; |
| 6100 | const name = try gz.identAsString(symbolic_name); | 6105 | const name = try astgen.identAsString(symbolic_name); |
| 6101 | const constraint_token = symbolic_name + 2; | 6106 | const constraint_token = symbolic_name + 2; |
| 6102 | const constraint = (try gz.strLitAsString(constraint_token)).index; | 6107 | const constraint = (try astgen.strLitAsString(constraint_token)).index; |
| 6103 | const has_arrow = token_tags[symbolic_name + 4] == .arrow; | 6108 | const has_arrow = token_tags[symbolic_name + 4] == .arrow; |
| 6104 | if (has_arrow) { | 6109 | if (has_arrow) { |
| 6105 | output_type_bits |= @as(u32, 1) << @intCast(u5, i); | 6110 | output_type_bits |= @as(u32, 1) << @intCast(u5, i); |
| ... | @@ -6112,7 +6117,7 @@ fn asmExpr( | ... | @@ -6112,7 +6117,7 @@ fn asmExpr( |
| 6112 | }; | 6117 | }; |
| 6113 | } else { | 6118 | } else { |
| 6114 | const ident_token = symbolic_name + 4; | 6119 | const ident_token = symbolic_name + 4; |
| 6115 | const str_index = try gz.identAsString(ident_token); | 6120 | const str_index = try astgen.identAsString(ident_token); |
| 6116 | // TODO this needs extra code for local variables. Have a look at #215 and related | 6121 | // TODO this needs extra code for local variables. Have a look at #215 and related |
| 6117 | // issues and decide how to handle outputs. Do we want this to be identifiers? | 6122 | // issues and decide how to handle outputs. Do we want this to be identifiers? |
| 6118 | // Or maybe we want to force this to be expressions with a pointer type. | 6123 | // Or maybe we want to force this to be expressions with a pointer type. |
| ... | @@ -6134,9 +6139,9 @@ fn asmExpr( | ... | @@ -6134,9 +6139,9 @@ fn asmExpr( |
| 6134 | | 6139 | |
| 6135 | for (full.inputs) |input_node, i| { | 6140 | for (full.inputs) |input_node, i| { |
| 6136 | const symbolic_name = main_tokens[input_node]; | 6141 | const symbolic_name = main_tokens[input_node]; |
| 6137 | const name = try gz.identAsString(symbolic_name); | 6142 | const name = try astgen.identAsString(symbolic_name); |
| 6138 | const constraint_token = symbolic_name + 2; | 6143 | const constraint_token = symbolic_name + 2; |
| 6139 | const constraint = (try gz.strLitAsString(constraint_token)).index; | 6144 | const constraint = (try astgen.strLitAsString(constraint_token)).index; |
| 6140 | const has_arrow = token_tags[symbolic_name + 4] == .arrow; | 6145 | const has_arrow = token_tags[symbolic_name + 4] == .arrow; |
| 6141 | const operand = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[input_node].lhs); | 6146 | const operand = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[input_node].lhs); |
| 6142 | inputs[i] = .{ | 6147 | inputs[i] = .{ |
| ... | @@ -6156,7 +6161,7 @@ fn asmExpr( | ... | @@ -6156,7 +6161,7 @@ fn asmExpr( |
| 6156 | if (clobber_i >= clobbers_buffer.len) { | 6161 | if (clobber_i >= clobbers_buffer.len) { |
| 6157 | return astgen.failTok(tok_i, "too many asm clobbers", .{}); | 6162 | return astgen.failTok(tok_i, "too many asm clobbers", .{}); |
| 6158 | } | 6163 | } |
| 6159 | clobbers_buffer[clobber_i] = (try gz.strLitAsString(tok_i)).index; | 6164 | clobbers_buffer[clobber_i] = (try astgen.strLitAsString(tok_i)).index; |
| 6160 | clobber_i += 1; | 6165 | clobber_i += 1; |
| 6161 | tok_i += 1; | 6166 | tok_i += 1; |
| 6162 | switch (token_tags[tok_i]) { | 6167 | switch (token_tags[tok_i]) { |
| ... | @@ -6409,7 +6414,7 @@ fn builtinCall( | ... | @@ -6409,7 +6414,7 @@ fn builtinCall( |
| 6409 | return astgen.failNode(operand_node, "@import operand must be a string literal", .{}); | 6414 | return astgen.failNode(operand_node, "@import operand must be a string literal", .{}); |
| 6410 | } | 6415 | } |
| 6411 | const str_lit_token = main_tokens[operand_node]; | 6416 | const str_lit_token = main_tokens[operand_node]; |
| 6412 | const str = try gz.strLitAsString(str_lit_token); | 6417 | const str = try astgen.strLitAsString(str_lit_token); |
| 6413 | try astgen.imports.put(astgen.gpa, str.index, {}); | 6418 | try astgen.imports.put(astgen.gpa, str.index, {}); |
| 6414 | const result = try gz.addStrTok(.import, str.index, str_lit_token); | 6419 | const result = try gz.addStrTok(.import, str.index, str_lit_token); |
| 6415 | return rvalue(gz, scope, rl, result, node); | 6420 | return rvalue(gz, scope, rl, result, node); |
| ... | @@ -6451,7 +6456,7 @@ fn builtinCall( | ... | @@ -6451,7 +6456,7 @@ fn builtinCall( |
| 6451 | return astgen.failNode(params[0], "the first @export parameter must be an identifier", .{}); | 6456 | return astgen.failNode(params[0], "the first @export parameter must be an identifier", .{}); |
| 6452 | } | 6457 | } |
| 6453 | const ident_token = main_tokens[params[0]]; | 6458 | const ident_token = main_tokens[params[0]]; |
| 6454 | const decl_name = try gz.identAsString(ident_token); | 6459 | const decl_name = try astgen.identAsString(ident_token); |
| 6455 | // TODO look for local variables in scope matching `decl_name` and emit a compile | 6460 | // TODO look for local variables in scope matching `decl_name` and emit a compile |
| 6456 | // error. Only top-level declarations can be exported. Until this is done, the | 6461 | // error. Only top-level declarations can be exported. Until this is done, the |
| 6457 | // compile error will end up being "use of undeclared identifier" in Sema. | 6462 | // compile error will end up being "use of undeclared identifier" in Sema. |
| ... | @@ -7698,3 +7703,57 @@ pub fn errNoteNode( | ... | @@ -7698,3 +7703,57 @@ pub fn errNoteNode( |
| 7698 | .notes = 0, | 7703 | .notes = 0, |
| 7699 | }); | 7704 | }); |
| 7700 | } | 7705 | } |
| | 7706 | |
| | 7707 | fn identAsString(astgen: *AstGen, ident_token: ast.TokenIndex) !u32 { |
| | 7708 | const gpa = astgen.gpa; |
| | 7709 | const string_bytes = &astgen.string_bytes; |
| | 7710 | const str_index = @intCast(u32, string_bytes.items.len); |
| | 7711 | try astgen.appendIdentStr(ident_token, string_bytes); |
| | 7712 | const key = string_bytes.items[str_index..]; |
| | 7713 | const gop = try astgen.string_table.getOrPut(gpa, key); |
| | 7714 | if (gop.found_existing) { |
| | 7715 | string_bytes.shrinkRetainingCapacity(str_index); |
| | 7716 | return gop.entry.value; |
| | 7717 | } else { |
| | 7718 | // We have to dupe the key into the arena, otherwise the memory |
| | 7719 | // becomes invalidated when string_bytes gets data appended. |
| | 7720 | // TODO https://github.com/ziglang/zig/issues/8528 |
| | 7721 | gop.entry.key = try astgen.arena.dupe(u8, key); |
| | 7722 | gop.entry.value = str_index; |
| | 7723 | try string_bytes.append(gpa, 0); |
| | 7724 | return str_index; |
| | 7725 | } |
| | 7726 | } |
| | 7727 | |
| | 7728 | const IndexSlice = struct { index: u32, len: u32 }; |
| | 7729 | |
| | 7730 | fn strLitAsString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !IndexSlice { |
| | 7731 | const gpa = astgen.gpa; |
| | 7732 | const string_bytes = &astgen.string_bytes; |
| | 7733 | const str_index = @intCast(u32, string_bytes.items.len); |
| | 7734 | const token_bytes = astgen.file.tree.tokenSlice(str_lit_token); |
| | 7735 | try astgen.parseStrLit(str_lit_token, string_bytes, token_bytes, 0); |
| | 7736 | const key = string_bytes.items[str_index..]; |
| | 7737 | const gop = try astgen.string_table.getOrPut(gpa, key); |
| | 7738 | if (gop.found_existing) { |
| | 7739 | string_bytes.shrinkRetainingCapacity(str_index); |
| | 7740 | return IndexSlice{ |
| | 7741 | .index = gop.entry.value, |
| | 7742 | .len = @intCast(u32, key.len), |
| | 7743 | }; |
| | 7744 | } else { |
| | 7745 | // We have to dupe the key into the arena, otherwise the memory |
| | 7746 | // becomes invalidated when string_bytes gets data appended. |
| | 7747 | // TODO https://github.com/ziglang/zig/issues/8528 |
| | 7748 | gop.entry.key = try astgen.arena.dupe(u8, key); |
| | 7749 | gop.entry.value = str_index; |
| | 7750 | // Still need a null byte because we are using the same table |
| | 7751 | // to lookup null terminated strings, so if we get a match, it has to |
| | 7752 | // be null terminated for that to work. |
| | 7753 | try string_bytes.append(gpa, 0); |
| | 7754 | return IndexSlice{ |
| | 7755 | .index = str_index, |
| | 7756 | .len = @intCast(u32, key.len), |
| | 7757 | }; |
| | 7758 | } |
| | 7759 | } |