| author | |
| committer | |
| log | 0611aa39858e6d7613cda3b3da981ff6b208a5e8 |
| tree | 271d5fa44237d19d7fb4b09d21b84c939658b9ca |
| parent | 4dd724d06a99d7b82b1b1758d28aa5559550f5bb |
This allows Sema to namespace them separately from function decls with
the same name. Ran into this in std.math.order conflicting with a test
with the same name.4 files changed, 40 insertions(+), 7 deletions(-)
BRANCH_TODO+3| ... | ... | @@ -1,3 +1,6 @@ |
| 1 | * running build-exe with cached ZIR crashes | |
| 2 | * implement lazy struct field resolution; don't resolve struct fields until | |
| 3 | they are needed. | |
| 1 | 4 | * decouple AstGen from Module, Compilation |
| 2 | 5 | * AstGen threadlocal |
| 3 | 6 | * extern "foo" for vars and for functions |
src/AstGen.zig+12-1| ... | ... | @@ -3197,7 +3197,7 @@ fn testDecl( |
| 3197 | 3197 | const test_token = main_tokens[node]; |
| 3198 | 3198 | const str_lit_token = test_token + 1; |
| 3199 | 3199 | if (token_tags[str_lit_token] == .string_literal) { |
| 3200 | break :blk (try astgen.strLitAsString(str_lit_token)).index; | |
| 3200 | break :blk try astgen.testNameString(str_lit_token); | |
| 3201 | 3201 | } |
| 3202 | 3202 | // String table index 1 has a special meaning here of test decl with no name. |
| 3203 | 3203 | break :blk 1; |
| ... | ... | @@ -7806,3 +7806,14 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !IndexSlice { |
| 7806 | 7806 | }; |
| 7807 | 7807 | } |
| 7808 | 7808 | } |
| 7809 | ||
| 7810 | fn testNameString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !u32 { | |
| 7811 | const gpa = astgen.gpa; | |
| 7812 | const string_bytes = &astgen.string_bytes; | |
| 7813 | const str_index = @intCast(u32, string_bytes.items.len); | |
| 7814 | const token_bytes = astgen.file.tree.tokenSlice(str_lit_token); | |
| 7815 | try string_bytes.append(gpa, 0); // Indicates this is a test. | |
| 7816 | try astgen.parseStrLit(str_lit_token, string_bytes, token_bytes, 0); | |
| 7817 | try string_bytes.append(gpa, 0); | |
| 7818 | return str_index; | |
| 7819 | } |
src/Module.zig+7-2| ... | ... | @@ -3817,7 +3817,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) InnerError!vo |
| 3817 | 3817 | const decl_node = iter.parent_decl.relativeToNodeIndex(decl_block_inst_data.src_node); |
| 3818 | 3818 | |
| 3819 | 3819 | // Every Decl needs a name. |
| 3820 | const decl_name: [:0]const u8 = switch (decl_name_index) { | |
| 3820 | const raw_decl_name: [:0]const u8 = switch (decl_name_index) { | |
| 3821 | 3821 | 0 => name: { |
| 3822 | 3822 | if (is_exported) { |
| 3823 | 3823 | const i = iter.usingnamespace_index; |
| ... | ... | @@ -3836,6 +3836,10 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) InnerError!vo |
| 3836 | 3836 | }, |
| 3837 | 3837 | else => zir.nullTerminatedString(decl_name_index), |
| 3838 | 3838 | }; |
| 3839 | const decl_name = if (raw_decl_name.len != 0) raw_decl_name else name: { | |
| 3840 | const test_name = zir.nullTerminatedString(decl_name_index + 1); | |
| 3841 | break :name try std.fmt.allocPrintZ(gpa, "test.{s}", .{test_name}); | |
| 3842 | }; | |
| 3839 | 3843 | log.debug("scan decl {s} is_pub={}", .{ decl_name, is_pub }); |
| 3840 | 3844 | |
| 3841 | 3845 | // We create a Decl for it regardless of analysis status. |
| ... | ... | @@ -3847,10 +3851,11 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) InnerError!vo |
| 3847 | 3851 | gop.entry.value = new_decl; |
| 3848 | 3852 | // Exported decls, comptime decls, usingnamespace decls, and |
| 3849 | 3853 | // test decls if in test mode, get analyzed. |
| 3854 | const is_named_test = raw_decl_name.len == 0; | |
| 3850 | 3855 | const want_analysis = is_exported or switch (decl_name_index) { |
| 3851 | 3856 | 0 => true, // comptime decl |
| 3852 | 3857 | 1 => mod.comp.bin_file.options.is_test, // test decl |
| 3853 | else => false, // TODO set to true for named tests when testing | |
| 3858 | else => is_named_test and mod.comp.bin_file.options.is_test, | |
| 3854 | 3859 | }; |
| 3855 | 3860 | if (want_analysis) { |
| 3856 | 3861 | mod.comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl }); |
src/Zir.zig+18-4| ... | ... | @@ -2421,6 +2421,8 @@ pub const Inst = struct { |
| 2421 | 2421 | /// - 0 means comptime or usingnamespace decl. |
| 2422 | 2422 | /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace |
| 2423 | 2423 | /// - 1 means test decl with no name. |
| 2424 | /// - if there is a 0 byte at the position `name` indexes, it indicates | |
| 2425 | /// this is a test decl, and the name starts at `name+1`. | |
| 2424 | 2426 | /// value: Index, |
| 2425 | 2427 | /// align: Ref, // if corresponding bit is set |
| 2426 | 2428 | /// link_section: Ref, // if corresponding bit is set |
| ... | ... | @@ -2459,6 +2461,8 @@ pub const Inst = struct { |
| 2459 | 2461 | /// - 0 means comptime or usingnamespace decl. |
| 2460 | 2462 | /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace |
| 2461 | 2463 | /// - 1 means test decl with no name. |
| 2464 | /// - if there is a 0 byte at the position `name` indexes, it indicates | |
| 2465 | /// this is a test decl, and the name starts at `name+1`. | |
| 2462 | 2466 | /// value: Index, |
| 2463 | 2467 | /// align: Ref, // if corresponding bit is set |
| 2464 | 2468 | /// link_section: Ref, // if corresponding bit is set |
| ... | ... | @@ -2492,6 +2496,8 @@ pub const Inst = struct { |
| 2492 | 2496 | /// - 0 means comptime or usingnamespace decl. |
| 2493 | 2497 | /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace |
| 2494 | 2498 | /// - 1 means test decl with no name. |
| 2499 | /// - if there is a 0 byte at the position `name` indexes, it indicates | |
| 2500 | /// this is a test decl, and the name starts at `name+1`. | |
| 2495 | 2501 | /// value: Index, |
| 2496 | 2502 | /// align: Ref, // if corresponding bit is set |
| 2497 | 2503 | /// link_section: Ref, // if corresponding bit is set |
| ... | ... | @@ -2535,8 +2541,9 @@ pub const Inst = struct { |
| 2535 | 2541 | /// - 0 means comptime or usingnamespace decl. |
| 2536 | 2542 | /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace |
| 2537 | 2543 | /// - 1 means test decl with no name. |
| 2544 | /// - if there is a 0 byte at the position `name` indexes, it indicates | |
| 2545 | /// this is a test decl, and the name starts at `name+1`. | |
| 2538 | 2546 | /// value: Index, |
| 2539 | /// - one of: block_inline | |
| 2540 | 2547 | /// align: Ref, // if corresponding bit is set |
| 2541 | 2548 | /// link_section: Ref, // if corresponding bit is set |
| 2542 | 2549 | /// } |
| ... | ... | @@ -3631,7 +3638,6 @@ const Writer = struct { |
| 3631 | 3638 | const line = self.code.extra[extra_index]; |
| 3632 | 3639 | extra_index += 1; |
| 3633 | 3640 | const decl_name_index = self.code.extra[extra_index]; |
| 3634 | const decl_name = self.code.nullTerminatedString(decl_name_index); | |
| 3635 | 3641 | extra_index += 1; |
| 3636 | 3642 | const decl_index = self.code.extra[extra_index]; |
| 3637 | 3643 | extra_index += 1; |
| ... | ... | @@ -3653,10 +3659,18 @@ const Writer = struct { |
| 3653 | 3659 | const name = if (is_exported) "usingnamespace" else "comptime"; |
| 3654 | 3660 | try stream.writeAll(pub_str); |
| 3655 | 3661 | try stream.writeAll(name); |
| 3662 | } else if (decl_name_index == 1) { | |
| 3663 | try stream.writeAll("test"); | |
| 3656 | 3664 | } else { |
| 3665 | const raw_decl_name = self.code.nullTerminatedString(decl_name_index); | |
| 3666 | const decl_name = if (raw_decl_name.len == 0) | |
| 3667 | self.code.nullTerminatedString(decl_name_index + 1) | |
| 3668 | else | |
| 3669 | raw_decl_name; | |
| 3670 | const test_str = if (raw_decl_name.len == 0) "test " else ""; | |
| 3657 | 3671 | const export_str = if (is_exported) "export " else ""; |
| 3658 | try stream.print("{s}{s}{}", .{ | |
| 3659 | pub_str, export_str, std.zig.fmtId(decl_name), | |
| 3672 | try stream.print("{s}{s}{s}{}", .{ | |
| 3673 | pub_str, test_str, export_str, std.zig.fmtId(decl_name), | |
| 3660 | 3674 | }); |
| 3661 | 3675 | if (align_inst != .none) { |
| 3662 | 3676 | try stream.writeAll(" align("); |