authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-02-25 14:04:06+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-25 19:12:08-08:00
logd656c2a7abe90d00ef6dbc3731b82bd26180038a
treeac4498c15bba5a39cb64ea6d879a7a5c59cfc9c9
parent429e542f3f25813a57abceda6ace715398eb0dd5

test: rework how filtering works

* make test names contain the fully qualified name * make test filters match the fully qualified name * allow multiple test filters, where a test is skipped if it does not match any of the specified filters

26 files changed, 494 insertions(+), 506 deletions(-)

build.zig+13-13
......@@ -390,7 +390,7 @@ pub fn build(b: *std.Build) !void {
390390 }
391391 }
392392
393 const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter");
393 const test_filters = b.option([]const []const u8, "test-filter", "Skip tests that do not match any filter") orelse &[0][]const u8{};
394394
395395 const test_cases_options = b.addOptions();
396396 check_case_exe.root_module.addOptions("build_options", test_cases_options);
......@@ -418,7 +418,7 @@ pub fn build(b: *std.Build) !void {
418418 test_cases_options.addOption(?[]const u8, "glibc_runtimes_dir", b.glibc_runtimes_dir);
419419 test_cases_options.addOption([:0]const u8, "version", version);
420420 test_cases_options.addOption(std.SemanticVersion, "semver", semver);
421 test_cases_options.addOption(?[]const u8, "test_filter", test_filter);
421 test_cases_options.addOption([]const []const u8, "test_filters", test_filters);
422422
423423 var chosen_opt_modes_buf: [4]builtin.OptimizeMode = undefined;
424424 var chosen_mode_index: usize = 0;
......@@ -454,7 +454,7 @@ pub fn build(b: *std.Build) !void {
454454 }).step);
455455
456456 const test_cases_step = b.step("test-cases", "Run the main compiler test cases");
457 try tests.addCases(b, test_cases_step, test_filter, check_case_exe, .{
457 try tests.addCases(b, test_cases_step, test_filters, check_case_exe, .{
458458 .enable_llvm = enable_llvm,
459459 .llvm_has_m68k = llvm_has_m68k,
460460 .llvm_has_csky = llvm_has_csky,
......@@ -464,7 +464,7 @@ pub fn build(b: *std.Build) !void {
464464 test_step.dependOn(test_cases_step);
465465
466466 test_step.dependOn(tests.addModuleTests(b, .{
467 .test_filter = test_filter,
467 .test_filters = test_filters,
468468 .root_src = "test/behavior.zig",
469469 .name = "behavior",
470470 .desc = "Run the behavior tests",
......@@ -477,7 +477,7 @@ pub fn build(b: *std.Build) !void {
477477 }));
478478
479479 test_step.dependOn(tests.addModuleTests(b, .{
480 .test_filter = test_filter,
480 .test_filters = test_filters,
481481 .root_src = "test/c_import.zig",
482482 .name = "c-import",
483483 .desc = "Run the @cImport tests",
......@@ -489,7 +489,7 @@ pub fn build(b: *std.Build) !void {
489489 }));
490490
491491 test_step.dependOn(tests.addModuleTests(b, .{
492 .test_filter = test_filter,
492 .test_filters = test_filters,
493493 .root_src = "lib/compiler_rt.zig",
494494 .name = "compiler-rt",
495495 .desc = "Run the compiler_rt tests",
......@@ -501,7 +501,7 @@ pub fn build(b: *std.Build) !void {
501501 }));
502502
503503 test_step.dependOn(tests.addModuleTests(b, .{
504 .test_filter = test_filter,
504 .test_filters = test_filters,
505505 .root_src = "lib/c.zig",
506506 .name = "universal-libc",
507507 .desc = "Run the universal libc tests",
......@@ -512,7 +512,7 @@ pub fn build(b: *std.Build) !void {
512512 .skip_libc = true,
513513 }));
514514
515 test_step.dependOn(tests.addCompareOutputTests(b, test_filter, optimization_modes));
515 test_step.dependOn(tests.addCompareOutputTests(b, test_filters, optimization_modes));
516516 test_step.dependOn(tests.addStandaloneTests(
517517 b,
518518 optimization_modes,
......@@ -523,16 +523,16 @@ pub fn build(b: *std.Build) !void {
523523 ));
524524 test_step.dependOn(tests.addCAbiTests(b, skip_non_native, skip_release));
525525 test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, false, enable_symlinks_windows));
526 test_step.dependOn(tests.addStackTraceTests(b, test_filter, optimization_modes));
526 test_step.dependOn(tests.addStackTraceTests(b, test_filters, optimization_modes));
527527 test_step.dependOn(tests.addCliTests(b));
528 test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter, optimization_modes));
529 test_step.dependOn(tests.addTranslateCTests(b, test_filter));
528 test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filters, optimization_modes));
529 test_step.dependOn(tests.addTranslateCTests(b, test_filters));
530530 if (!skip_run_translated_c) {
531 test_step.dependOn(tests.addRunTranslatedCTests(b, test_filter, target));
531 test_step.dependOn(tests.addRunTranslatedCTests(b, test_filters, target));
532532 }
533533
534534 test_step.dependOn(tests.addModuleTests(b, .{
535 .test_filter = test_filter,
535 .test_filters = test_filters,
536536 .root_src = "lib/std/std.zig",
537537 .name = "std",
538538 .desc = "Run the standard library tests",
doc/langref.html.in+4-4
......@@ -988,13 +988,13 @@ fn addOne(number: i32) i32 {
988988 printed to standard error by the default test runner:
989989 </p>
990990 <dl>
991 <dt><samp>Test [1/2] test.expect addOne adds one to 41...</samp></dt>
991 <dt><samp>1/2 testing_introduction.test.expect addOne adds one to 41...</samp></dt>
992992 <dd>Lines like this indicate which test, out of the total number of tests, is being run.
993 In this case, <samp>[1/2]</samp> indicates that the first test, out of a total of
994 two test, is being run. Note that, when the test runner program's standard error is output
993 In this case, <samp>1/2</samp> indicates that the first test, out of a total of two tests,
994 is being run. Note that, when the test runner program's standard error is output
995995 to the terminal, these lines are cleared when a test succeeds.
996996 </dd>
997 <dt><samp>Test [2/2] decltest.addOne...</samp></dt>
997 <dt><samp>2/2 testing_introduction.decltest.addOne...</samp></dt>
998998 <dd>When the test name is an identifier, the default test runner uses the text
999999 decltest instead of test.
10001000 </dd>
lib/std/Build.zig+9-4
......@@ -855,7 +855,9 @@ pub const TestOptions = struct {
855855 optimize: std.builtin.OptimizeMode = .Debug,
856856 version: ?std.SemanticVersion = null,
857857 max_rss: usize = 0,
858 /// deprecated: use `.filters = &.{filter}` instead of `.filter = filter`.
858859 filter: ?[]const u8 = null,
860 filters: []const []const u8 = &.{},
859861 test_runner: ?[]const u8 = null,
860862 link_libc: ?bool = null,
861863 single_threaded: ?bool = null,
......@@ -888,7 +890,12 @@ pub fn addTest(b: *Build, options: TestOptions) *Step.Compile {
888890 .error_tracing = options.error_tracing,
889891 },
890892 .max_rss = options.max_rss,
891 .filter = options.filter,
893 .filters = if (options.filter != null and options.filters.len > 0) filters: {
894 const filters = b.allocator.alloc([]const u8, 1 + options.filters.len) catch @panic("OOM");
895 filters[0] = b.dupe(options.filter.?);
896 for (filters[1..], options.filters) |*dest, source| dest.* = b.dupe(source);
897 break :filters filters;
898 } else b.dupeStrings(if (options.filter) |filter| &.{filter} else options.filters),
892899 .test_runner = options.test_runner,
893900 .use_llvm = options.use_llvm,
894901 .use_lld = options.use_lld,
......@@ -993,9 +1000,7 @@ pub fn dupe(self: *Build, bytes: []const u8) []u8 {
9931000/// Duplicates an array of strings without the need to handle out of memory.
9941001pub fn dupeStrings(self: *Build, strings: []const []const u8) [][]u8 {
9951002 const array = self.allocator.alloc([]u8, strings.len) catch @panic("OOM");
996 for (strings, 0..) |s, i| {
997 array[i] = self.dupe(s);
998 }
1003 for (array, strings) |*dest, source| dest.* = self.dupe(source);
9991004 return array;
10001005}
10011006
lib/std/Build/Step/Compile.zig+4-4
......@@ -54,7 +54,7 @@ global_base: ?u64 = null,
5454/// Set via options; intended to be read-only after that.
5555zig_lib_dir: ?LazyPath,
5656exec_cmd_args: ?[]const ?[]const u8,
57filter: ?[]const u8,
57filters: []const []const u8,
5858test_runner: ?[]const u8,
5959test_server_mode: bool,
6060wasi_exec_model: ?std.builtin.WasiExecModel = null,
......@@ -223,7 +223,7 @@ pub const Options = struct {
223223 linkage: ?Linkage = null,
224224 version: ?std.SemanticVersion = null,
225225 max_rss: usize = 0,
226 filter: ?[]const u8 = null,
226 filters: []const []const u8 = &.{},
227227 test_runner: ?[]const u8 = null,
228228 use_llvm: ?bool = null,
229229 use_lld: ?bool = null,
......@@ -310,7 +310,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
310310 .installed_headers = ArrayList(*Step).init(owner.allocator),
311311 .zig_lib_dir = null,
312312 .exec_cmd_args = null,
313 .filter = options.filter,
313 .filters = options.filters,
314314 .test_runner = options.test_runner,
315315 .test_server_mode = options.test_runner == null,
316316 .rdynamic = false,
......@@ -1297,7 +1297,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
12971297 try zig_args.append(b.fmt("0x{x}", .{image_base}));
12981298 }
12991299
1300 if (self.filter) |filter| {
1300 for (self.filters) |filter| {
13011301 try zig_args.append("--test-filter");
13021302 try zig_args.append(filter);
13031303 }
src/Compilation.zig+5-5
......@@ -217,7 +217,7 @@ libcxx_abi_version: libcxx.AbiVersion = libcxx.AbiVersion.default,
217217/// This mutex guards all `Compilation` mutable state.
218218mutex: std.Thread.Mutex = .{},
219219
220test_filter: ?[]const u8,
220test_filters: []const []const u8,
221221test_name_prefix: ?[]const u8,
222222
223223emit_asm: ?EmitLoc,
......@@ -1097,7 +1097,7 @@ pub const CreateOptions = struct {
10971097 native_system_include_paths: []const []const u8 = &.{},
10981098 clang_preprocessor_mode: ClangPreprocessorMode = .no,
10991099 reference_trace: ?u32 = null,
1100 test_filter: ?[]const u8 = null,
1100 test_filters: []const []const u8 = &.{},
11011101 test_name_prefix: ?[]const u8 = null,
11021102 test_runner_path: ?[]const u8 = null,
11031103 subsystem: ?std.Target.SubSystem = null,
......@@ -1506,7 +1506,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
15061506 .formatted_panics = formatted_panics,
15071507 .time_report = options.time_report,
15081508 .stack_report = options.stack_report,
1509 .test_filter = options.test_filter,
1509 .test_filters = options.test_filters,
15101510 .test_name_prefix = options.test_name_prefix,
15111511 .debug_compiler_runtime_libs = options.debug_compiler_runtime_libs,
15121512 .debug_compile_errors = options.debug_compile_errors,
......@@ -1613,7 +1613,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
16131613 hash.add(options.config.use_lib_llvm);
16141614 hash.add(options.config.dll_export_fns);
16151615 hash.add(options.config.is_test);
1616 hash.addOptionalBytes(options.test_filter);
1616 hash.addListOfBytes(options.test_filters);
16171617 hash.addOptionalBytes(options.test_name_prefix);
16181618 hash.add(options.skip_linker_dependencies);
16191619 hash.add(formatted_panics);
......@@ -2475,7 +2475,7 @@ fn addNonIncrementalStuffToCacheManifest(
24752475 try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.root_mod, mod.main_mod, .{ .files = man });
24762476
24772477 // Synchronize with other matching comments: ZigOnlyHashStuff
2478 man.hash.addOptionalBytes(comp.test_filter);
2478 man.hash.addListOfBytes(comp.test_filters);
24792479 man.hash.addOptionalBytes(comp.test_name_prefix);
24802480 man.hash.add(comp.skip_linker_dependencies);
24812481 man.hash.add(comp.formatted_panics);
src/InternPool.zig+1-1
......@@ -7904,7 +7904,7 @@ pub fn destroyNamespace(ip: *InternPool, gpa: Allocator, index: NamespaceIndex)
79047904 ip.namespacePtr(index).* = .{
79057905 .parent = undefined,
79067906 .file_scope = undefined,
7907 .ty = undefined,
7907 .decl_index = undefined,
79087908 };
79097909 ip.namespaces_free_list.append(gpa, index) catch {
79107910 // In order to keep `destroyNamespace` a non-fallible function, we ignore memory
src/Module.zig+130-122
......@@ -411,15 +411,15 @@ pub const Decl = struct {
411411 /// This state detects dependency loops.
412412 in_progress,
413413 /// The file corresponding to this Decl had a parse error or ZIR error.
414 /// There will be a corresponding ErrorMsg in Module.failed_files.
414 /// There will be a corresponding ErrorMsg in Zcu.failed_files.
415415 file_failure,
416416 /// This Decl might be OK but it depends on another one which did not
417417 /// successfully complete semantic analysis.
418418 dependency_failure,
419419 /// Semantic analysis failure.
420 /// There will be a corresponding ErrorMsg in Module.failed_decls.
420 /// There will be a corresponding ErrorMsg in Zcu.failed_decls.
421421 sema_failure,
422 /// There will be a corresponding ErrorMsg in Module.failed_decls.
422 /// There will be a corresponding ErrorMsg in Zcu.failed_decls.
423423 codegen_failure,
424424 /// Sematic analysis and constant value codegen of this Decl has
425425 /// succeeded. However, the Decl may be outdated due to an in-progress
......@@ -494,77 +494,45 @@ pub const Decl = struct {
494494 return LazySrcLoc.nodeOffset(decl.nodeIndexToRelative(node_index));
495495 }
496496
497 pub fn srcLoc(decl: Decl, mod: *Module) SrcLoc {
498 return decl.nodeOffsetSrcLoc(0, mod);
497 pub fn srcLoc(decl: Decl, zcu: *Zcu) SrcLoc {
498 return decl.nodeOffsetSrcLoc(0, zcu);
499499 }
500500
501 pub fn nodeOffsetSrcLoc(decl: Decl, node_offset: i32, mod: *Module) SrcLoc {
501 pub fn nodeOffsetSrcLoc(decl: Decl, node_offset: i32, zcu: *Zcu) SrcLoc {
502502 return .{
503 .file_scope = decl.getFileScope(mod),
503 .file_scope = decl.getFileScope(zcu),
504504 .parent_decl_node = decl.src_node,
505505 .lazy = LazySrcLoc.nodeOffset(node_offset),
506506 };
507507 }
508508
509 pub fn srcToken(decl: Decl, mod: *Module) Ast.TokenIndex {
510 const tree = &decl.getFileScope(mod).tree;
509 pub fn srcToken(decl: Decl, zcu: *Zcu) Ast.TokenIndex {
510 const tree = &decl.getFileScope(zcu).tree;
511511 return tree.firstToken(decl.src_node);
512512 }
513513
514 pub fn srcByteOffset(decl: Decl, mod: *Module) u32 {
515 const tree = &decl.getFileScope(mod).tree;
514 pub fn srcByteOffset(decl: Decl, zcu: *Zcu) u32 {
515 const tree = &decl.getFileScope(zcu).tree;
516516 return tree.tokens.items(.start)[decl.srcToken()];
517517 }
518518
519 pub fn renderFullyQualifiedName(decl: Decl, mod: *Module, writer: anytype) !void {
519 pub fn renderFullyQualifiedName(decl: Decl, zcu: *Zcu, writer: anytype) !void {
520520 if (decl.name_fully_qualified) {
521 try writer.print("{}", .{decl.name.fmt(&mod.intern_pool)});
521 try writer.print("{}", .{decl.name.fmt(&zcu.intern_pool)});
522522 } else {
523 try mod.namespacePtr(decl.src_namespace).renderFullyQualifiedName(mod, decl.name, writer);
523 try zcu.namespacePtr(decl.src_namespace).renderFullyQualifiedName(zcu, decl.name, writer);
524524 }
525525 }
526526
527 pub fn renderFullyQualifiedDebugName(decl: Decl, mod: *Module, writer: anytype) !void {
528 return mod.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(mod, decl.name, writer);
527 pub fn renderFullyQualifiedDebugName(decl: Decl, zcu: *Zcu, writer: anytype) !void {
528 return zcu.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(zcu, decl.name, writer);
529529 }
530530
531 pub fn getFullyQualifiedName(decl: Decl, mod: *Module) !InternPool.NullTerminatedString {
532 if (decl.name_fully_qualified) return decl.name;
533
534 const ip = &mod.intern_pool;
535 const count = count: {
536 var count: usize = ip.stringToSlice(decl.name).len + 1;
537 var ns: Namespace.Index = decl.src_namespace;
538 while (true) {
539 const namespace = mod.namespacePtr(ns);
540 const ns_decl = mod.declPtr(namespace.getDeclIndex(mod));
541 count += ip.stringToSlice(ns_decl.name).len + 1;
542 ns = namespace.parent.unwrap() orelse {
543 count += namespace.file_scope.sub_file_path.len;
544 break :count count;
545 };
546 }
547 };
548
549 const gpa = mod.gpa;
550 const start = ip.string_bytes.items.len;
551 // Protects reads of interned strings from being reallocated during the call to
552 // renderFullyQualifiedName.
553 try ip.string_bytes.ensureUnusedCapacity(gpa, count);
554 decl.renderFullyQualifiedName(mod, ip.string_bytes.writer(gpa)) catch unreachable;
555
556 // Sanitize the name for nvptx which is more restrictive.
557 // TODO This should be handled by the backend, not the frontend. Have a
558 // look at how the C backend does it for inspiration.
559 const cpu_arch = mod.root_mod.resolved_target.result.cpu.arch;
560 if (cpu_arch.isNvptx()) {
561 for (ip.string_bytes.items[start..]) |*byte| switch (byte.*) {
562 '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
563 else => {},
564 };
565 }
566
567 return ip.getOrPutTrailingString(gpa, ip.string_bytes.items.len - start);
531 pub fn fullyQualifiedName(decl: Decl, zcu: *Zcu) !InternPool.NullTerminatedString {
532 return if (decl.name_fully_qualified)
533 decl.name
534 else
535 zcu.namespacePtr(decl.src_namespace).fullyQualifiedName(zcu, decl.name);
568536 }
569537
570538 pub fn typedValue(decl: Decl) error{AnalysisFail}!TypedValue {
......@@ -572,38 +540,38 @@ pub const Decl = struct {
572540 return TypedValue{ .ty = decl.ty, .val = decl.val };
573541 }
574542
575 pub fn internValue(decl: *Decl, mod: *Module) Allocator.Error!InternPool.Index {
543 pub fn internValue(decl: *Decl, zcu: *Zcu) Allocator.Error!InternPool.Index {
576544 assert(decl.has_tv);
577 const ip_index = try decl.val.intern(decl.ty, mod);
545 const ip_index = try decl.val.intern(decl.ty, zcu);
578546 decl.val = Value.fromInterned(ip_index);
579547 return ip_index;
580548 }
581549
582 pub fn isFunction(decl: Decl, mod: *const Module) !bool {
550 pub fn isFunction(decl: Decl, zcu: *const Zcu) !bool {
583551 const tv = try decl.typedValue();
584 return tv.ty.zigTypeTag(mod) == .Fn;
552 return tv.ty.zigTypeTag(zcu) == .Fn;
585553 }
586554
587555 /// If the Decl owns its value and it is a struct, return it,
588556 /// otherwise null.
589 pub fn getOwnedStruct(decl: Decl, mod: *Module) ?InternPool.Key.StructType {
557 pub fn getOwnedStruct(decl: Decl, zcu: *Zcu) ?InternPool.Key.StructType {
590558 if (!decl.owns_tv) return null;
591559 if (decl.val.ip_index == .none) return null;
592 return mod.typeToStruct(decl.val.toType());
560 return zcu.typeToStruct(decl.val.toType());
593561 }
594562
595563 /// If the Decl owns its value and it is a union, return it,
596564 /// otherwise null.
597 pub fn getOwnedUnion(decl: Decl, mod: *Module) ?InternPool.UnionType {
565 pub fn getOwnedUnion(decl: Decl, zcu: *Zcu) ?InternPool.UnionType {
598566 if (!decl.owns_tv) return null;
599567 if (decl.val.ip_index == .none) return null;
600 return mod.typeToUnion(decl.val.toType());
568 return zcu.typeToUnion(decl.val.toType());
601569 }
602570
603 pub fn getOwnedFunction(decl: Decl, mod: *Module) ?InternPool.Key.Func {
571 pub fn getOwnedFunction(decl: Decl, zcu: *Zcu) ?InternPool.Key.Func {
604572 const i = decl.getOwnedFunctionIndex();
605573 if (i == .none) return null;
606 return switch (mod.intern_pool.indexToKey(i)) {
574 return switch (zcu.intern_pool.indexToKey(i)) {
607575 .func => |func| func,
608576 else => null,
609577 };
......@@ -616,24 +584,24 @@ pub const Decl = struct {
616584
617585 /// If the Decl owns its value and it is an extern function, returns it,
618586 /// otherwise null.
619 pub fn getOwnedExternFunc(decl: Decl, mod: *Module) ?InternPool.Key.ExternFunc {
620 return if (decl.owns_tv) decl.val.getExternFunc(mod) else null;
587 pub fn getOwnedExternFunc(decl: Decl, zcu: *Zcu) ?InternPool.Key.ExternFunc {
588 return if (decl.owns_tv) decl.val.getExternFunc(zcu) else null;
621589 }
622590
623591 /// If the Decl owns its value and it is a variable, returns it,
624592 /// otherwise null.
625 pub fn getOwnedVariable(decl: Decl, mod: *Module) ?InternPool.Key.Variable {
626 return if (decl.owns_tv) decl.val.getVariable(mod) else null;
593 pub fn getOwnedVariable(decl: Decl, zcu: *Zcu) ?InternPool.Key.Variable {
594 return if (decl.owns_tv) decl.val.getVariable(zcu) else null;
627595 }
628596
629597 /// Gets the namespace that this Decl creates by being a struct, union,
630598 /// enum, or opaque.
631 pub fn getInnerNamespaceIndex(decl: Decl, mod: *Module) Namespace.OptionalIndex {
599 pub fn getInnerNamespaceIndex(decl: Decl, zcu: *Zcu) Namespace.OptionalIndex {
632600 if (!decl.has_tv) return .none;
633601 return switch (decl.val.ip_index) {
634602 .empty_struct_type => .none,
635603 .none => .none,
636 else => switch (mod.intern_pool.indexToKey(decl.val.toIntern())) {
604 else => switch (zcu.intern_pool.indexToKey(decl.val.toIntern())) {
637605 .opaque_type => |opaque_type| opaque_type.namespace.toOptional(),
638606 .struct_type => |struct_type| struct_type.namespace,
639607 .union_type => |union_type| union_type.namespace.toOptional(),
......@@ -644,19 +612,19 @@ pub const Decl = struct {
644612 }
645613
646614 /// Like `getInnerNamespaceIndex`, but only returns it if the Decl is the owner.
647 pub fn getOwnedInnerNamespaceIndex(decl: Decl, mod: *Module) Namespace.OptionalIndex {
615 pub fn getOwnedInnerNamespaceIndex(decl: Decl, zcu: *Zcu) Namespace.OptionalIndex {
648616 if (!decl.owns_tv) return .none;
649 return decl.getInnerNamespaceIndex(mod);
617 return decl.getInnerNamespaceIndex(zcu);
650618 }
651619
652620 /// Same as `getOwnedInnerNamespaceIndex` but additionally obtains the pointer.
653 pub fn getOwnedInnerNamespace(decl: Decl, mod: *Module) ?*Namespace {
654 return mod.namespacePtrUnwrap(decl.getOwnedInnerNamespaceIndex(mod));
621 pub fn getOwnedInnerNamespace(decl: Decl, zcu: *Zcu) ?*Namespace {
622 return zcu.namespacePtrUnwrap(decl.getOwnedInnerNamespaceIndex(zcu));
655623 }
656624
657625 /// Same as `getInnerNamespaceIndex` but additionally obtains the pointer.
658 pub fn getInnerNamespace(decl: Decl, mod: *Module) ?*Namespace {
659 return mod.namespacePtrUnwrap(decl.getInnerNamespaceIndex(mod));
626 pub fn getInnerNamespace(decl: Decl, zcu: *Zcu) ?*Namespace {
627 return zcu.namespacePtrUnwrap(decl.getInnerNamespaceIndex(zcu));
660628 }
661629
662630 pub fn dump(decl: *Decl) void {
......@@ -674,27 +642,27 @@ pub const Decl = struct {
674642 std.debug.print("\n", .{});
675643 }
676644
677 pub fn getFileScope(decl: Decl, mod: *Module) *File {
678 return mod.namespacePtr(decl.src_namespace).file_scope;
645 pub fn getFileScope(decl: Decl, zcu: *Zcu) *File {
646 return zcu.namespacePtr(decl.src_namespace).file_scope;
679647 }
680648
681 pub fn getExternDecl(decl: Decl, mod: *Module) OptionalIndex {
649 pub fn getExternDecl(decl: Decl, zcu: *Zcu) OptionalIndex {
682650 assert(decl.has_tv);
683 return switch (mod.intern_pool.indexToKey(decl.val.toIntern())) {
651 return switch (zcu.intern_pool.indexToKey(decl.val.toIntern())) {
684652 .variable => |variable| if (variable.is_extern) variable.decl.toOptional() else .none,
685653 .extern_func => |extern_func| extern_func.decl.toOptional(),
686654 else => .none,
687655 };
688656 }
689657
690 pub fn isExtern(decl: Decl, mod: *Module) bool {
691 return decl.getExternDecl(mod) != .none;
658 pub fn isExtern(decl: Decl, zcu: *Zcu) bool {
659 return decl.getExternDecl(zcu) != .none;
692660 }
693661
694 pub fn getAlignment(decl: Decl, mod: *Module) Alignment {
662 pub fn getAlignment(decl: Decl, zcu: *Zcu) Alignment {
695663 assert(decl.has_tv);
696664 if (decl.alignment != .none) return decl.alignment;
697 return decl.ty.abiAlignment(mod);
665 return decl.ty.abiAlignment(zcu);
698666 }
699667};
700668
......@@ -704,7 +672,7 @@ pub const EmitH = struct {
704672};
705673
706674pub const DeclAdapter = struct {
707 mod: *Module,
675 zcu: *Zcu,
708676
709677 pub fn hash(self: @This(), s: InternPool.NullTerminatedString) u32 {
710678 _ = self;
......@@ -713,8 +681,7 @@ pub const DeclAdapter = struct {
713681
714682 pub fn eql(self: @This(), a: InternPool.NullTerminatedString, b_decl_index: Decl.Index, b_index: usize) bool {
715683 _ = b_index;
716 const b_decl = self.mod.declPtr(b_decl_index);
717 return a == b_decl.name;
684 return a == self.zcu.declPtr(b_decl_index).name;
718685 }
719686};
720687
......@@ -723,7 +690,7 @@ pub const Namespace = struct {
723690 parent: OptionalIndex,
724691 file_scope: *File,
725692 /// Will be a struct, enum, union, or opaque.
726 ty: Type,
693 decl_index: Decl.Index,
727694 /// Direct children of the namespace.
728695 /// Declaration order is preserved via entry order.
729696 /// These are only declarations named directly by the AST; anonymous
......@@ -739,7 +706,7 @@ pub const Namespace = struct {
739706 const OptionalIndex = InternPool.OptionalNamespaceIndex;
740707
741708 const DeclContext = struct {
742 module: *Module,
709 zcu: *Zcu,
743710
744711 pub fn hash(ctx: @This(), decl_index: Decl.Index) u32 {
745712 const decl = ctx.module.declPtr(decl_index);
......@@ -757,39 +724,87 @@ pub const Namespace = struct {
757724 // This renders e.g. "std.fs.Dir.OpenOptions"
758725 pub fn renderFullyQualifiedName(
759726 ns: Namespace,
760 mod: *Module,
727 zcu: *Zcu,
761728 name: InternPool.NullTerminatedString,
762729 writer: anytype,
763730 ) @TypeOf(writer).Error!void {
764731 if (ns.parent.unwrap()) |parent| {
765 const decl = mod.declPtr(ns.getDeclIndex(mod));
766 try mod.namespacePtr(parent).renderFullyQualifiedName(mod, decl.name, writer);
732 try zcu.namespacePtr(parent).renderFullyQualifiedName(
733 zcu,
734 zcu.declPtr(ns.decl_index).name,
735 writer,
736 );
767737 } else {
768738 try ns.file_scope.renderFullyQualifiedName(writer);
769739 }
770 if (name != .empty) try writer.print(".{}", .{name.fmt(&mod.intern_pool)});
740 if (name != .empty) try writer.print(".{}", .{name.fmt(&zcu.intern_pool)});
771741 }
772742
773743 /// This renders e.g. "std/fs.zig:Dir.OpenOptions"
774744 pub fn renderFullyQualifiedDebugName(
775745 ns: Namespace,
776 mod: *Module,
746 zcu: *Zcu,
777747 name: InternPool.NullTerminatedString,
778748 writer: anytype,
779749 ) @TypeOf(writer).Error!void {
780 const separator_char: u8 = if (ns.parent.unwrap()) |parent| sep: {
781 const decl = mod.declPtr(ns.getDeclIndex(mod));
782 try mod.namespacePtr(parent).renderFullyQualifiedDebugName(mod, decl.name, writer);
750 const sep: u8 = if (ns.parent.unwrap()) |parent| sep: {
751 try zcu.namespacePtr(parent).renderFullyQualifiedDebugName(
752 zcu,
753 zcu.declPtr(ns.decl_index).name,
754 writer,
755 );
783756 break :sep '.';
784757 } else sep: {
785758 try ns.file_scope.renderFullyQualifiedDebugName(writer);
786759 break :sep ':';
787760 };
788 if (name != .empty) try writer.print("{c}{}", .{ separator_char, name.fmt(&mod.intern_pool) });
761 if (name != .empty) try writer.print("{c}{}", .{ sep, name.fmt(&zcu.intern_pool) });
789762 }
790763
791 pub fn getDeclIndex(ns: Namespace, mod: *Module) Decl.Index {
792 return ns.ty.getOwnerDecl(mod);
764 pub fn fullyQualifiedName(
765 ns: Namespace,
766 zcu: *Zcu,
767 name: InternPool.NullTerminatedString,
768 ) !InternPool.NullTerminatedString {
769 const ip = &zcu.intern_pool;
770 const count = count: {
771 var count: usize = ip.stringToSlice(name).len + 1;
772 var cur_ns = &ns;
773 while (true) {
774 const decl = zcu.declPtr(cur_ns.decl_index);
775 count += ip.stringToSlice(decl.name).len + 1;
776 cur_ns = zcu.namespacePtr(cur_ns.parent.unwrap() orelse {
777 count += ns.file_scope.sub_file_path.len;
778 break :count count;
779 });
780 }
781 };
782
783 const gpa = zcu.gpa;
784 const start = ip.string_bytes.items.len;
785 // Protects reads of interned strings from being reallocated during the call to
786 // renderFullyQualifiedName.
787 try ip.string_bytes.ensureUnusedCapacity(gpa, count);
788 ns.renderFullyQualifiedName(zcu, name, ip.string_bytes.writer(gpa)) catch unreachable;
789
790 // Sanitize the name for nvptx which is more restrictive.
791 // TODO This should be handled by the backend, not the frontend. Have a
792 // look at how the C backend does it for inspiration.
793 const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch;
794 if (cpu_arch.isNvptx()) {
795 for (ip.string_bytes.items[start..]) |*byte| switch (byte.*) {
796 '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
797 else => {},
798 };
799 }
800
801 return ip.getOrPutTrailingString(gpa, ip.string_bytes.items.len - start);
802 }
803
804 pub fn getType(ns: Namespace, zcu: *Zcu) Type {
805 const decl = zcu.declPtr(ns.decl_index);
806 assert(decl.has_tv);
807 return decl.val.toType();
793808 }
794809};
795810
......@@ -2559,9 +2574,8 @@ pub fn namespacePtrUnwrap(mod: *Module, index: Namespace.OptionalIndex) ?*Namesp
25592574pub fn declIsRoot(mod: *Module, decl_index: Decl.Index) bool {
25602575 const decl = mod.declPtr(decl_index);
25612576 const namespace = mod.namespacePtr(decl.src_namespace);
2562 if (namespace.parent != .none)
2563 return false;
2564 return decl_index == namespace.getDeclIndex(mod);
2577 if (namespace.parent != .none) return false;
2578 return decl_index == namespace.decl_index;
25652579}
25662580
25672581fn freeExportList(gpa: Allocator, export_list: *ArrayListUnmanaged(*Export)) void {
......@@ -3592,7 +3606,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError
35923606 defer liveness.deinit(gpa);
35933607
35943608 if (dump_air) {
3595 const fqn = try decl.getFullyQualifiedName(zcu);
3609 const fqn = try decl.fullyQualifiedName(zcu);
35963610 std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)});
35973611 @import("print_air.zig").dump(zcu, air, liveness);
35983612 std.debug.print("# End Function AIR: {}\n\n", .{fqn.fmt(ip)});
......@@ -3738,7 +3752,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
37383752 // InternPool index.
37393753 const new_namespace_index = try mod.createNamespace(.{
37403754 .parent = .none,
3741 .ty = undefined,
3755 .decl_index = undefined,
37423756 .file_scope = file,
37433757 });
37443758 const new_namespace = mod.namespacePtr(new_namespace_index);
......@@ -3749,6 +3763,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
37493763 errdefer @panic("TODO error handling");
37503764
37513765 file.root_decl = new_decl_index.toOptional();
3766 new_namespace.decl_index = new_decl_index;
37523767
37533768 new_decl.name = try file.fullyQualifiedName(mod);
37543769 new_decl.name_fully_qualified = true;
......@@ -3808,7 +3823,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
38083823 _ = try decl.internValue(mod);
38093824 }
38103825
3811 new_namespace.ty = Type.fromInterned(struct_ty);
38123826 new_decl.val = Value.fromInterned(struct_ty);
38133827 new_decl.has_tv = true;
38143828 new_decl.owns_tv = true;
......@@ -3881,7 +3895,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
38813895 const std_decl = mod.declPtr(std_file.root_decl.unwrap().?);
38823896 const std_namespace = std_decl.getInnerNamespace(mod).?;
38833897 const builtin_str = try ip.getOrPutString(gpa, "builtin");
3884 const builtin_decl = mod.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, DeclAdapter{ .mod = mod }) orelse break :blk .none);
3898 const builtin_decl = mod.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, DeclAdapter{ .zcu = mod }) orelse break :blk .none);
38853899 const builtin_namespace = builtin_decl.getInnerNamespaceIndex(mod).unwrap() orelse break :blk .none;
38863900 if (decl.src_namespace != builtin_namespace) break :blk .none;
38873901 // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index.
......@@ -4576,8 +4590,8 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void
45764590 const gop = try namespace.decls.getOrPutContextAdapted(
45774591 gpa,
45784592 decl_name,
4579 DeclAdapter{ .mod = zcu },
4580 Namespace.DeclContext{ .module = zcu },
4593 DeclAdapter{ .zcu = zcu },
4594 Namespace.DeclContext{ .zcu = zcu },
45814595 );
45824596 const comp = zcu.comp;
45834597 if (!gop.found_existing) {
......@@ -4600,12 +4614,11 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void
46004614 .@"test" => a: {
46014615 if (!comp.config.is_test) break :a false;
46024616 if (decl_mod != zcu.main_mod) break :a false;
4603 if (is_named_test) {
4604 if (comp.test_filter) |test_filter| {
4605 if (mem.indexOf(u8, ip.stringToSlice(decl_name), test_filter) == null) {
4606 break :a false;
4607 }
4608 }
4617 if (is_named_test and comp.test_filters.len > 0) {
4618 const decl_fqn = ip.stringToSlice(try namespace.fullyQualifiedName(zcu, decl_name));
4619 for (comp.test_filters) |test_filter| {
4620 if (mem.indexOf(u8, decl_fqn, test_filter)) |_| break;
4621 } else break :a false;
46094622 }
46104623 try zcu.test_functions.put(gpa, new_decl_index, {});
46114624 break :a true;
......@@ -5622,7 +5635,7 @@ pub fn populateTestFunctions(
56225635 const test_functions_str = try ip.getOrPutString(gpa, "test_functions");
56235636 const decl_index = builtin_namespace.decls.getKeyAdapted(
56245637 test_functions_str,
5625 DeclAdapter{ .mod = mod },
5638 DeclAdapter{ .zcu = mod },
56265639 ).?;
56275640 {
56285641 // We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions`
......@@ -5646,8 +5659,7 @@ pub fn populateTestFunctions(
56465659
56475660 for (test_fn_vals, mod.test_functions.keys()) |*test_fn_val, test_decl_index| {
56485661 const test_decl = mod.declPtr(test_decl_index);
5649 // TODO: write something like getCoercedInts to avoid needing to dupe
5650 const test_decl_name = try gpa.dupe(u8, ip.stringToSlice(test_decl.name));
5662 const test_decl_name = try gpa.dupe(u8, ip.stringToSlice(try test_decl.fullyQualifiedName(mod)));
56515663 defer gpa.free(test_decl_name);
56525664 const test_name_decl_index = n: {
56535665 const test_name_decl_ty = try mod.arrayType(.{
......@@ -6359,17 +6371,13 @@ pub fn opaqueSrcLoc(mod: *Module, opaque_type: InternPool.Key.OpaqueType) SrcLoc
63596371}
63606372
63616373pub fn opaqueFullyQualifiedName(mod: *Module, opaque_type: InternPool.Key.OpaqueType) !InternPool.NullTerminatedString {
6362 return mod.declPtr(opaque_type.decl).getFullyQualifiedName(mod);
6374 return mod.declPtr(opaque_type.decl).fullyQualifiedName(mod);
63636375}
63646376
63656377pub fn declFileScope(mod: *Module, decl_index: Decl.Index) *File {
63666378 return mod.declPtr(decl_index).getFileScope(mod);
63676379}
63686380
6369pub fn namespaceDeclIndex(mod: *Module, namespace_index: Namespace.Index) Decl.Index {
6370 return mod.namespacePtr(namespace_index).getDeclIndex(mod);
6371}
6372
63736381/// Returns null in the following cases:
63746382/// * `@TypeOf(.{})`
63756383/// * A struct which has no fields (`struct {}`).
src/Sema.zig+17-31
......@@ -2801,10 +2801,9 @@ fn zirStructDecl(
28012801
28022802 const new_namespace_index = try mod.createNamespace(.{
28032803 .parent = block.namespace.toOptional(),
2804 .ty = undefined,
2804 .decl_index = new_decl_index,
28052805 .file_scope = block.getFileScope(mod),
28062806 });
2807 const new_namespace = mod.namespacePtr(new_namespace_index);
28082807 errdefer mod.destroyNamespace(new_namespace_index);
28092808
28102809 const struct_ty = ty: {
......@@ -2821,7 +2820,6 @@ fn zirStructDecl(
28212820
28222821 new_decl.ty = Type.type;
28232822 new_decl.val = Value.fromInterned(struct_ty);
2824 new_namespace.ty = Type.fromInterned(struct_ty);
28252823
28262824 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
28272825 try mod.finalizeAnonDecl(new_decl_index);
......@@ -2990,10 +2988,9 @@ fn zirEnumDecl(
29902988
29912989 const new_namespace_index = try mod.createNamespace(.{
29922990 .parent = block.namespace.toOptional(),
2993 .ty = undefined,
2991 .decl_index = new_decl_index,
29942992 .file_scope = block.getFileScope(mod),
29952993 });
2996 const new_namespace = mod.namespacePtr(new_namespace_index);
29972994 errdefer if (!done) mod.destroyNamespace(new_namespace_index);
29982995
29992996 const decls = sema.code.bodySlice(extra_index, decls_len);
......@@ -3036,7 +3033,6 @@ fn zirEnumDecl(
30363033
30373034 new_decl.ty = Type.type;
30383035 new_decl.val = Value.fromInterned(incomplete_enum.index);
3039 new_namespace.ty = Type.fromInterned(incomplete_enum.index);
30403036
30413037 const decl_val = try sema.analyzeDeclVal(block, src, new_decl_index);
30423038 try mod.finalizeAnonDecl(new_decl_index);
......@@ -3248,10 +3244,9 @@ fn zirUnionDecl(
32483244
32493245 const new_namespace_index = try mod.createNamespace(.{
32503246 .parent = block.namespace.toOptional(),
3251 .ty = undefined,
3247 .decl_index = new_decl_index,
32523248 .file_scope = block.getFileScope(mod),
32533249 });
3254 const new_namespace = mod.namespacePtr(new_namespace_index);
32553250 errdefer mod.destroyNamespace(new_namespace_index);
32563251
32573252 const union_ty = ty: {
......@@ -3292,7 +3287,6 @@ fn zirUnionDecl(
32923287
32933288 new_decl.ty = Type.type;
32943289 new_decl.val = Value.fromInterned(union_ty);
3295 new_namespace.ty = Type.fromInterned(union_ty);
32963290
32973291 const decls = sema.code.bodySlice(extra_index, decls_len);
32983292 try mod.scanNamespace(new_namespace_index, decls, new_decl);
......@@ -3346,10 +3340,9 @@ fn zirOpaqueDecl(
33463340
33473341 const new_namespace_index = try mod.createNamespace(.{
33483342 .parent = block.namespace.toOptional(),
3349 .ty = undefined,
3343 .decl_index = new_decl_index,
33503344 .file_scope = block.getFileScope(mod),
33513345 });
3352 const new_namespace = mod.namespacePtr(new_namespace_index);
33533346 errdefer mod.destroyNamespace(new_namespace_index);
33543347
33553348 const opaque_ty = try mod.intern(.{ .opaque_type = .{
......@@ -3362,7 +3355,6 @@ fn zirOpaqueDecl(
33623355
33633356 new_decl.ty = Type.type;
33643357 new_decl.val = Value.fromInterned(opaque_ty);
3365 new_namespace.ty = Type.fromInterned(opaque_ty);
33663358
33673359 const decls = sema.code.bodySlice(extra_index, decls_len);
33683360 try mod.scanNamespace(new_namespace_index, decls, new_decl);
......@@ -4834,7 +4826,7 @@ fn validateStructInit(
48344826 if (root_msg) |msg| {
48354827 if (mod.typeToStruct(struct_ty)) |struct_type| {
48364828 const decl = mod.declPtr(struct_type.decl.unwrap().?);
4837 const fqn = try decl.getFullyQualifiedName(mod);
4829 const fqn = try decl.fullyQualifiedName(mod);
48384830 try mod.errNoteNonLazy(
48394831 decl.srcLoc(mod),
48404832 msg,
......@@ -4961,7 +4953,7 @@ fn validateStructInit(
49614953 if (root_msg) |msg| {
49624954 if (mod.typeToStruct(struct_ty)) |struct_type| {
49634955 const decl = mod.declPtr(struct_type.decl.unwrap().?);
4964 const fqn = try decl.getFullyQualifiedName(mod);
4956 const fqn = try decl.fullyQualifiedName(mod);
49654957 try mod.errNoteNonLazy(
49664958 decl.srcLoc(mod),
49674959 msg,
......@@ -5355,7 +5347,7 @@ fn failWithBadStructFieldAccess(
53555347 const mod = sema.mod;
53565348 const gpa = sema.gpa;
53575349 const decl = mod.declPtr(struct_type.decl.unwrap().?);
5358 const fqn = try decl.getFullyQualifiedName(mod);
5350 const fqn = try decl.fullyQualifiedName(mod);
53595351
53605352 const msg = msg: {
53615353 const msg = try sema.errMsg(
......@@ -5382,7 +5374,7 @@ fn failWithBadUnionFieldAccess(
53825374 const gpa = sema.gpa;
53835375
53845376 const decl = mod.declPtr(union_obj.decl);
5385 const fqn = try decl.getFullyQualifiedName(mod);
5377 const fqn = try decl.fullyQualifiedName(mod);
53865378
53875379 const msg = msg: {
53885380 const msg = try sema.errMsg(
......@@ -6504,8 +6496,7 @@ fn lookupInNamespace(
65046496 const mod = sema.mod;
65056497
65066498 const namespace = mod.namespacePtr(namespace_index);
6507 const namespace_decl_index = namespace.getDeclIndex(mod);
6508 const namespace_decl = mod.declPtr(namespace_decl_index);
6499 const namespace_decl = mod.declPtr(namespace.decl_index);
65096500 if (namespace_decl.analysis == .file_failure) {
65106501 return error.AnalysisFail;
65116502 }
......@@ -6526,7 +6517,7 @@ fn lookupInNamespace(
65266517
65276518 while (check_i < checked_namespaces.count()) : (check_i += 1) {
65286519 const check_ns = checked_namespaces.keys()[check_i];
6529 if (check_ns.decls.getKeyAdapted(ident_name, Module.DeclAdapter{ .mod = mod })) |decl_index| {
6520 if (check_ns.decls.getKeyAdapted(ident_name, Module.DeclAdapter{ .zcu = mod })) |decl_index| {
65306521 // Skip decls which are not marked pub, which are in a different
65316522 // file than the `a.b`/`@hasDecl` syntax.
65326523 const decl = mod.declPtr(decl_index);
......@@ -6584,7 +6575,7 @@ fn lookupInNamespace(
65846575 return sema.failWithOwnedErrorMsg(block, msg);
65856576 },
65866577 }
6587 } else if (namespace.decls.getKeyAdapted(ident_name, Module.DeclAdapter{ .mod = mod })) |decl_index| {
6578 } else if (namespace.decls.getKeyAdapted(ident_name, Module.DeclAdapter{ .zcu = mod })) |decl_index| {
65886579 return decl_index;
65896580 }
65906581
......@@ -17210,7 +17201,7 @@ fn zirThis(
1721017201 extended: Zir.Inst.Extended.InstData,
1721117202) CompileError!Air.Inst.Ref {
1721217203 const mod = sema.mod;
17213 const this_decl_index = mod.namespaceDeclIndex(block.namespace);
17204 const this_decl_index = mod.namespacePtr(block.namespace).decl_index;
1721417205 const src = LazySrcLoc.nodeOffset(@bitCast(extended.operand));
1721517206 return sema.analyzeDeclVal(block, src, this_decl_index);
1721617207}
......@@ -20075,7 +20066,7 @@ fn finishStructInit(
2007520066 if (root_msg) |msg| {
2007620067 if (mod.typeToStruct(struct_ty)) |struct_type| {
2007720068 const decl = mod.declPtr(struct_type.decl.unwrap().?);
20078 const fqn = try decl.getFullyQualifiedName(mod);
20069 const fqn = try decl.fullyQualifiedName(mod);
2007920070 try mod.errNoteNonLazy(
2008020071 decl.srcLoc(mod),
2008120072 msg,
......@@ -21404,10 +21395,9 @@ fn zirReify(
2140421395
2140521396 const new_namespace_index = try mod.createNamespace(.{
2140621397 .parent = block.namespace.toOptional(),
21407 .ty = undefined,
21398 .decl_index = new_decl_index,
2140821399 .file_scope = block.getFileScope(mod),
2140921400 });
21410 const new_namespace = mod.namespacePtr(new_namespace_index);
2141121401 errdefer mod.destroyNamespace(new_namespace_index);
2141221402
2141321403 const opaque_ty = try mod.intern(.{ .opaque_type = .{
......@@ -21420,7 +21410,6 @@ fn zirReify(
2142021410
2142121411 new_decl.ty = Type.type;
2142221412 new_decl.val = Value.fromInterned(opaque_ty);
21423 new_namespace.ty = Type.fromInterned(opaque_ty);
2142421413
2142521414 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
2142621415 try mod.finalizeAnonDecl(new_decl_index);
......@@ -21614,10 +21603,9 @@ fn zirReify(
2161421603
2161521604 const new_namespace_index = try mod.createNamespace(.{
2161621605 .parent = block.namespace.toOptional(),
21617 .ty = undefined,
21606 .decl_index = new_decl_index,
2161821607 .file_scope = block.getFileScope(mod),
2161921608 });
21620 const new_namespace = mod.namespacePtr(new_namespace_index);
2162121609 errdefer mod.destroyNamespace(new_namespace_index);
2162221610
2162321611 const union_ty = try ip.getUnionType(gpa, .{
......@@ -21649,7 +21637,6 @@ fn zirReify(
2164921637
2165021638 new_decl.ty = Type.type;
2165121639 new_decl.val = Value.fromInterned(union_ty);
21652 new_namespace.ty = Type.fromInterned(union_ty);
2165321640
2165421641 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
2165521642 try mod.finalizeAnonDecl(new_decl_index);
......@@ -37260,7 +37247,7 @@ fn generateUnionTagTypeNumbered(
3726037247 const src_decl = mod.declPtr(block.src_decl);
3726137248 const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);
3726237249 errdefer mod.destroyDecl(new_decl_index);
37263 const fqn = try decl.getFullyQualifiedName(mod);
37250 const fqn = try decl.fullyQualifiedName(mod);
3726437251 const name = try ip.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(ip)});
3726537252 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, .{
3726637253 .ty = Type.noreturn,
......@@ -37269,7 +37256,6 @@ fn generateUnionTagTypeNumbered(
3726937256 errdefer mod.abortAnonDecl(new_decl_index);
3727037257
3727137258 const new_decl = mod.declPtr(new_decl_index);
37272 new_decl.name_fully_qualified = true;
3727337259 new_decl.owns_tv = true;
3727437260 new_decl.name_fully_qualified = true;
3727537261
......@@ -37310,7 +37296,7 @@ fn generateUnionTagTypeSimple(
3731037296 .val = Value.@"unreachable",
3731137297 });
3731237298 };
37313 const fqn = try mod.declPtr(decl_index).getFullyQualifiedName(mod);
37299 const fqn = try mod.declPtr(decl_index).fullyQualifiedName(mod);
3731437300 const src_decl = mod.declPtr(block.src_decl);
3731537301 const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);
3731637302 errdefer mod.destroyDecl(new_decl_index);
src/arch/wasm/CodeGen.zig+1-1
......@@ -7223,7 +7223,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
72237223 defer arena_allocator.deinit();
72247224 const arena = arena_allocator.allocator();
72257225
7226 const fqn = ip.stringToSlice(try mod.declPtr(enum_decl_index).getFullyQualifiedName(mod));
7226 const fqn = ip.stringToSlice(try mod.declPtr(enum_decl_index).fullyQualifiedName(mod));
72277227 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});
72287228
72297229 // check if we already generated code for this.
src/codegen/llvm.zig+11-13
......@@ -1163,7 +1163,7 @@ pub const Object = struct {
11631163 const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i];
11641164
11651165 const namespace = self.module.namespacePtr(namespace_index);
1166 const debug_type = try self.lowerDebugType(namespace.ty);
1166 const debug_type = try self.lowerDebugType(namespace.getType(self.module));
11671167
11681168 self.builder.debugForwardReferenceSetType(fwd_ref, debug_type);
11691169 }
......@@ -1797,7 +1797,7 @@ pub const Object = struct {
17971797 return updateExportedGlobal(self, mod, global_index, exports);
17981798 } else {
17991799 const fqn = try self.builder.string(
1800 mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)),
1800 mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod)),
18011801 );
18021802 try global_index.rename(fqn, &self.builder);
18031803 global_index.setLinkage(.internal, &self.builder);
......@@ -2835,15 +2835,13 @@ pub const Object = struct {
28352835
28362836 const builtin_str = try mod.intern_pool.getOrPutString(mod.gpa, "builtin");
28372837 const std_namespace = mod.namespacePtr(mod.declPtr(std_file.root_decl.unwrap().?).src_namespace);
2838 const builtin_decl = std_namespace.decls
2839 .getKeyAdapted(builtin_str, Module.DeclAdapter{ .mod = mod }).?;
2838 const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Module.DeclAdapter{ .zcu = mod }).?;
28402839
28412840 const stack_trace_str = try mod.intern_pool.getOrPutString(mod.gpa, "StackTrace");
28422841 // buffer is only used for int_type, `builtin` is a struct.
28432842 const builtin_ty = mod.declPtr(builtin_decl).val.toType();
28442843 const builtin_namespace = builtin_ty.getNamespace(mod).?;
2845 const stack_trace_decl_index = builtin_namespace.decls
2846 .getKeyAdapted(stack_trace_str, Module.DeclAdapter{ .mod = mod }).?;
2844 const stack_trace_decl_index = builtin_namespace.decls.getKeyAdapted(stack_trace_str, Module.DeclAdapter{ .zcu = mod }).?;
28472845 const stack_trace_decl = mod.declPtr(stack_trace_decl_index);
28482846
28492847 // Sema should have ensured that StackTrace was analyzed.
......@@ -2886,7 +2884,7 @@ pub const Object = struct {
28862884 try o.builder.string(ip.stringToSlice(if (is_extern)
28872885 decl.name
28882886 else
2889 try decl.getFullyQualifiedName(zcu))),
2887 try decl.fullyQualifiedName(zcu))),
28902888 toLlvmAddressSpace(decl.@"addrspace", target),
28912889 );
28922890 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
......@@ -3100,7 +3098,7 @@ pub const Object = struct {
31003098
31013099 const variable_index = try o.builder.addVariable(
31023100 try o.builder.string(mod.intern_pool.stringToSlice(
3103 if (is_extern) decl.name else try decl.getFullyQualifiedName(mod),
3101 if (is_extern) decl.name else try decl.fullyQualifiedName(mod),
31043102 )),
31053103 try o.lowerType(decl.ty),
31063104 toLlvmGlobalAddressSpace(decl.@"addrspace", mod.getTarget()),
......@@ -3325,7 +3323,7 @@ pub const Object = struct {
33253323 }
33263324
33273325 const name = try o.builder.string(ip.stringToSlice(
3328 try mod.declPtr(struct_type.decl.unwrap().?).getFullyQualifiedName(mod),
3326 try mod.declPtr(struct_type.decl.unwrap().?).fullyQualifiedName(mod),
33293327 ));
33303328
33313329 var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};
......@@ -3481,7 +3479,7 @@ pub const Object = struct {
34813479 }
34823480
34833481 const name = try o.builder.string(ip.stringToSlice(
3484 try mod.declPtr(union_obj.decl).getFullyQualifiedName(mod),
3482 try mod.declPtr(union_obj.decl).fullyQualifiedName(mod),
34853483 ));
34863484
34873485 const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);
......@@ -4599,7 +4597,7 @@ pub const Object = struct {
45994597
46004598 const usize_ty = try o.lowerType(Type.usize);
46014599 const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);
4602 const fqn = try zcu.declPtr(enum_type.decl).getFullyQualifiedName(zcu);
4600 const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(zcu);
46034601 const target = zcu.root_mod.resolved_target.result;
46044602 const function_index = try o.builder.addFunction(
46054603 try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
......@@ -6613,7 +6611,7 @@ pub const FuncGen = struct {
66136611 .base_line = self.base_line,
66146612 });
66156613
6616 const fqn = try decl.getFullyQualifiedName(zcu);
6614 const fqn = try decl.fullyQualifiedName(zcu);
66176615
66186616 const is_internal_linkage = !zcu.decl_exports.contains(decl_index);
66196617 const fn_ty = try zcu.funcType(.{
......@@ -9643,7 +9641,7 @@ pub const FuncGen = struct {
96439641 if (gop.found_existing) return gop.value_ptr.*;
96449642 errdefer assert(o.named_enum_map.remove(enum_type.decl));
96459643
9646 const fqn = try zcu.declPtr(enum_type.decl).getFullyQualifiedName(zcu);
9644 const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(zcu);
96479645 const target = zcu.root_mod.resolved_target.result;
96489646 const function_index = try o.builder.addFunction(
96499647 try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
src/codegen/spirv.zig+2-2
......@@ -2019,7 +2019,7 @@ const DeclGen = struct {
20192019 // Append the actual code into the functions section.
20202020 try self.spv.addFunction(spv_decl_index, self.func);
20212021
2022 const fqn = ip.stringToSlice(try decl.getFullyQualifiedName(self.module));
2022 const fqn = ip.stringToSlice(try decl.fullyQualifiedName(self.module));
20232023 try self.spv.debugName(decl_id, fqn);
20242024
20252025 // Temporarily generate a test kernel declaration if this is a test function.
......@@ -2055,7 +2055,7 @@ const DeclGen = struct {
20552055 .id_result = decl_id,
20562056 .storage_class = actual_storage_class,
20572057 });
2058 const fqn = ip.stringToSlice(try decl.getFullyQualifiedName(self.module));
2058 const fqn = ip.stringToSlice(try decl.fullyQualifiedName(self.module));
20592059 try self.spv.debugName(decl_id, fqn);
20602060
20612061 if (opt_init_val) |init_val| {
src/link/Coff.zig+2-2
......@@ -1176,7 +1176,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: InternPool.Dec
11761176 gop.value_ptr.* = .{};
11771177 }
11781178 const unnamed_consts = gop.value_ptr;
1179 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1179 const decl_name = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
11801180 const index = unnamed_consts.items.len;
11811181 const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
11821182 defer gpa.free(sym_name);
......@@ -1427,7 +1427,7 @@ fn updateDeclCode(self: *Coff, decl_index: InternPool.DeclIndex, code: []u8, com
14271427 const mod = self.base.comp.module.?;
14281428 const decl = mod.declPtr(decl_index);
14291429
1430 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1430 const decl_name = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
14311431
14321432 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
14331433 const required_alignment: u32 = @intCast(decl.getAlignment(mod).toByteUnits(0));
src/link/Dwarf.zig+1-1
......@@ -1082,7 +1082,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde
10821082 defer tracy.end();
10831083
10841084 const decl = mod.declPtr(decl_index);
1085 const decl_linkage_name = try decl.getFullyQualifiedName(mod);
1085 const decl_linkage_name = try decl.fullyQualifiedName(mod);
10861086
10871087 log.debug("initDeclState {}{*}", .{ decl_linkage_name.fmt(&mod.intern_pool), decl });
10881088
src/link/Elf/ZigObject.zig+4-4
......@@ -903,7 +903,7 @@ fn updateDeclCode(
903903 const gpa = elf_file.base.comp.gpa;
904904 const mod = elf_file.base.comp.module.?;
905905 const decl = mod.declPtr(decl_index);
906 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
906 const decl_name = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
907907
908908 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
909909
......@@ -1001,7 +1001,7 @@ fn updateTlv(
10011001 const gpa = elf_file.base.comp.gpa;
10021002 const mod = elf_file.base.comp.module.?;
10031003 const decl = mod.declPtr(decl_index);
1004 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1004 const decl_name = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
10051005
10061006 log.debug("updateTlv {s} ({*})", .{ decl_name, decl });
10071007
......@@ -1300,7 +1300,7 @@ pub fn lowerUnnamedConst(
13001300 }
13011301 const unnamed_consts = gop.value_ptr;
13021302 const decl = mod.declPtr(decl_index);
1303 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1303 const decl_name = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
13041304 const index = unnamed_consts.items.len;
13051305 const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
13061306 defer gpa.free(name);
......@@ -1482,7 +1482,7 @@ pub fn updateDeclLineNumber(
14821482 defer tracy.end();
14831483
14841484 const decl = mod.declPtr(decl_index);
1485 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1485 const decl_name = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
14861486
14871487 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });
14881488
src/link/MachO/ZigObject.zig+3-3
......@@ -792,7 +792,7 @@ fn updateDeclCode(
792792 const gpa = macho_file.base.comp.gpa;
793793 const mod = macho_file.base.comp.module.?;
794794 const decl = mod.declPtr(decl_index);
795 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
795 const decl_name = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
796796
797797 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
798798
......@@ -876,7 +876,7 @@ fn updateTlv(
876876) !void {
877877 const mod = macho_file.base.comp.module.?;
878878 const decl = mod.declPtr(decl_index);
879 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
879 const decl_name = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
880880
881881 log.debug("updateTlv {s} ({*})", .{ decl_name, decl });
882882
......@@ -1079,7 +1079,7 @@ pub fn lowerUnnamedConst(
10791079 }
10801080 const unnamed_consts = gop.value_ptr;
10811081 const decl = mod.declPtr(decl_index);
1082 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1082 const decl_name = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
10831083 const index = unnamed_consts.items.len;
10841084 const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
10851085 defer gpa.free(name);
src/link/Plan9.zig+1-1
......@@ -478,7 +478,7 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: InternPool.De
478478 }
479479 const unnamed_consts = gop.value_ptr;
480480
481 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
481 const decl_name = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
482482
483483 const index = unnamed_consts.items.len;
484484 // name is freed when the unnamed const is freed
src/link/Wasm.zig+4-4
......@@ -662,7 +662,7 @@ pub fn getOrCreateAtomForDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) !At
662662 const symbol = atom.symbolLoc().getSymbol(wasm);
663663 const mod = wasm.base.comp.module.?;
664664 const decl = mod.declPtr(decl_index);
665 const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
665 const full_name = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
666666 symbol.name = try wasm.string_table.put(gpa, full_name);
667667 }
668668 return gop.value_ptr.*;
......@@ -1598,7 +1598,7 @@ pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl_index: InternPool.De
15981598 defer tracy.end();
15991599
16001600 const decl = mod.declPtr(decl_index);
1601 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1601 const decl_name = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
16021602
16031603 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });
16041604 try dw.updateDeclLineNumber(mod, decl_index);
......@@ -1612,7 +1612,7 @@ fn finishUpdateDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex, code: []const
16121612 const atom_index = wasm.decls.get(decl_index).?;
16131613 const atom = wasm.getAtomPtr(atom_index);
16141614 const symbol = &wasm.symbols.items[atom.sym_index];
1615 const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1615 const full_name = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
16161616 symbol.name = try wasm.string_table.put(gpa, full_name);
16171617 symbol.tag = symbol_tag;
16181618 try atom.code.appendSlice(gpa, code);
......@@ -1678,7 +1678,7 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: InternPool.Dec
16781678 const parent_atom_index = try wasm.getOrCreateAtomForDecl(decl_index);
16791679 const parent_atom = wasm.getAtom(parent_atom_index);
16801680 const local_index = parent_atom.locals.items.len;
1681 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1681 const fqn = mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod));
16821682 const name = try std.fmt.allocPrintZ(gpa, "__unnamed_{s}_{d}", .{
16831683 fqn, local_index,
16841684 });
src/main.zig+15-18
......@@ -596,7 +596,7 @@ const usage_build_generic =
596596 \\ --export=[value] (WebAssembly) Force a symbol to be exported
597597 \\
598598 \\Test Options:
599 \\ --test-filter [text] Skip tests that do not match filter
599 \\ --test-filter [text] Skip tests that do not match any filter
600600 \\ --test-name-prefix [text] Add prefix to all tests
601601 \\ --test-cmd [arg] Specify test execution command one arg at a time
602602 \\ --test-cmd-bin Appends test binary path to test cmd args
......@@ -869,7 +869,7 @@ fn buildOutputType(
869869 var link_emit_relocs = false;
870870 var build_id: ?std.zig.BuildId = null;
871871 var runtime_args_start: ?usize = null;
872 var test_filter: ?[]const u8 = null;
872 var test_filters: std.ArrayListUnmanaged([]const u8) = .{};
873873 var test_name_prefix: ?[]const u8 = null;
874874 var test_runner_path: ?[]const u8 = null;
875875 var override_local_cache_dir: ?[]const u8 = try EnvVar.ZIG_LOCAL_CACHE_DIR.get(arena);
......@@ -909,7 +909,7 @@ fn buildOutputType(
909909 var rc_source_files_owner_index: usize = 0;
910910
911911 // null means replace with the test executable binary
912 var test_exec_args = std.ArrayList(?[]const u8).init(arena);
912 var test_exec_args: std.ArrayListUnmanaged(?[]const u8) = .{};
913913
914914 // These get set by CLI flags and then snapshotted when a `--mod` flag is
915915 // encountered.
......@@ -1278,13 +1278,13 @@ fn buildOutputType(
12781278 } else if (mem.eql(u8, arg, "--libc")) {
12791279 create_module.libc_paths_file = args_iter.nextOrFatal();
12801280 } else if (mem.eql(u8, arg, "--test-filter")) {
1281 test_filter = args_iter.nextOrFatal();
1281 try test_filters.append(arena, args_iter.nextOrFatal());
12821282 } else if (mem.eql(u8, arg, "--test-name-prefix")) {
12831283 test_name_prefix = args_iter.nextOrFatal();
12841284 } else if (mem.eql(u8, arg, "--test-runner")) {
12851285 test_runner_path = args_iter.nextOrFatal();
12861286 } else if (mem.eql(u8, arg, "--test-cmd")) {
1287 try test_exec_args.append(args_iter.nextOrFatal());
1287 try test_exec_args.append(arena, args_iter.nextOrFatal());
12881288 } else if (mem.eql(u8, arg, "--cache-dir")) {
12891289 override_local_cache_dir = args_iter.nextOrFatal();
12901290 } else if (mem.eql(u8, arg, "--global-cache-dir")) {
......@@ -1334,7 +1334,7 @@ fn buildOutputType(
13341334 } else if (mem.eql(u8, arg, "-fno-each-lib-rpath")) {
13351335 create_module.each_lib_rpath = false;
13361336 } else if (mem.eql(u8, arg, "--test-cmd-bin")) {
1337 try test_exec_args.append(null);
1337 try test_exec_args.append(arena, null);
13381338 } else if (mem.eql(u8, arg, "--test-no-exec")) {
13391339 test_no_exec = true;
13401340 } else if (mem.eql(u8, arg, "-ftime-report")) {
......@@ -3246,7 +3246,7 @@ fn buildOutputType(
32463246 .time_report = time_report,
32473247 .stack_report = stack_report,
32483248 .build_id = build_id,
3249 .test_filter = test_filter,
3249 .test_filters = test_filters.items,
32503250 .test_name_prefix = test_name_prefix,
32513251 .test_runner_path = test_runner_path,
32523252 .disable_lld_caching = disable_lld_caching,
......@@ -3369,16 +3369,15 @@ fn buildOutputType(
33693369 const c_code_path = try fs.path.join(arena, &[_][]const u8{
33703370 c_code_directory.path orelse ".", c_code_loc.basename,
33713371 });
3372 try test_exec_args.append(self_exe_path);
3373 try test_exec_args.append("run");
3372 try test_exec_args.appendSlice(arena, &.{ self_exe_path, "run" });
33743373 if (zig_lib_directory.path) |p| {
3375 try test_exec_args.appendSlice(&.{ "-I", p });
3374 try test_exec_args.appendSlice(arena, &.{ "-I", p });
33763375 }
33773376
33783377 if (create_module.resolved_options.link_libc) {
3379 try test_exec_args.append("-lc");
3378 try test_exec_args.append(arena, "-lc");
33803379 } else if (target.os.tag == .windows) {
3381 try test_exec_args.appendSlice(&.{
3380 try test_exec_args.appendSlice(arena, &.{
33823381 "--subsystem", "console",
33833382 "-lkernel32", "-lntdll",
33843383 });
......@@ -3386,17 +3385,15 @@ fn buildOutputType(
33863385
33873386 const first_cli_mod = create_module.modules.values()[0];
33883387 if (first_cli_mod.target_arch_os_abi) |triple| {
3389 try test_exec_args.append("-target");
3390 try test_exec_args.append(triple);
3388 try test_exec_args.appendSlice(arena, &.{ "-target", triple });
33913389 }
33923390 if (first_cli_mod.target_mcpu) |mcpu| {
3393 try test_exec_args.append(try std.fmt.allocPrint(arena, "-mcpu={s}", .{mcpu}));
3391 try test_exec_args.append(arena, try std.fmt.allocPrint(arena, "-mcpu={s}", .{mcpu}));
33943392 }
33953393 if (create_module.dynamic_linker) |dl| {
3396 try test_exec_args.append("--dynamic-linker");
3397 try test_exec_args.append(dl);
3394 try test_exec_args.appendSlice(arena, &.{ "--dynamic-linker", dl });
33983395 }
3399 try test_exec_args.append(c_code_path);
3396 try test_exec_args.append(arena, c_code_path);
34003397 }
34013398
34023399 const run_or_test = switch (arg_mode) {
test/src/Cases.zig+16-16
......@@ -537,7 +537,7 @@ pub fn lowerToBuildSteps(
537537 self: *Cases,
538538 b: *std.Build,
539539 parent_step: *std.Build.Step,
540 opt_test_filter: ?[]const u8,
540 test_filters: []const []const u8,
541541 cases_dir_path: []const u8,
542542 incremental_exe: *std.Build.Step.Compile,
543543) void {
......@@ -552,9 +552,9 @@ pub fn lowerToBuildSteps(
552552 // compilation is in a happier state.
553553 continue;
554554 }
555 if (opt_test_filter) |test_filter| {
556 if (std.mem.indexOf(u8, incr_case.base_path, test_filter) == null) continue;
557 }
555 for (test_filters) |test_filter| {
556 if (std.mem.indexOf(u8, incr_case.base_path, test_filter)) |_| break;
557 } else if (test_filters.len > 0) continue;
558558 const case_base_path_with_dir = std.fs.path.join(b.allocator, &.{
559559 cases_dir_path, incr_case.base_path,
560560 }) catch @panic("OOM");
......@@ -573,9 +573,9 @@ pub fn lowerToBuildSteps(
573573 assert(case.updates.items.len == 1);
574574 const update = case.updates.items[0];
575575
576 if (opt_test_filter) |test_filter| {
577 if (std.mem.indexOf(u8, case.name, test_filter) == null) continue;
578 }
576 for (test_filters) |test_filter| {
577 if (std.mem.indexOf(u8, case.name, test_filter)) |_| break;
578 } else if (test_filters.len > 0) continue;
579579
580580 const writefiles = b.addWriteFiles();
581581 var file_sources = std.StringHashMap(std.Build.LazyPath).init(b.allocator);
......@@ -685,9 +685,9 @@ pub fn lowerToBuildSteps(
685685 for (self.translate.items) |case| switch (case.kind) {
686686 .run => |output| {
687687 const annotated_case_name = b.fmt("run-translated-c {s}", .{case.name});
688 if (opt_test_filter) |filter| {
689 if (std.mem.indexOf(u8, annotated_case_name, filter) == null) continue;
690 }
688 for (test_filters) |test_filter| {
689 if (std.mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
690 } else if (test_filters.len > 0) continue;
691691 if (!std.process.can_spawn) {
692692 std.debug.print("Unable to spawn child processes on {s}, skipping test.\n", .{@tagName(builtin.os.tag)});
693693 continue; // Pass test.
......@@ -721,9 +721,9 @@ pub fn lowerToBuildSteps(
721721 },
722722 .translate => |output| {
723723 const annotated_case_name = b.fmt("zig translate-c {s}", .{case.name});
724 if (opt_test_filter) |filter| {
725 if (std.mem.indexOf(u8, annotated_case_name, filter) == null) continue;
726 }
724 for (test_filters) |test_filter| {
725 if (std.mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
726 } else if (test_filters.len > 0) continue;
727727
728728 const write_src = b.addWriteFiles();
729729 const file_source = write_src.add("tmp.c", case.input);
......@@ -1440,9 +1440,9 @@ fn runCases(self: *Cases, zig_exe_path: []const u8) !void {
14401440
14411441 assert(case.backend != .stage1);
14421442
1443 if (build_options.test_filter) |test_filter| {
1444 if (std.mem.indexOf(u8, case.name, test_filter) == null) continue;
1445 }
1443 for (build_options.test_filters) |test_filter| {
1444 if (std.mem.indexOf(u8, case.name, test_filter)) |_| break;
1445 } else if (build_options.test_filters.len > 0) continue;
14461446
14471447 var prg_node = root_node.start(case.name, case.updates.items.len);
14481448 prg_node.activate();
test/src/CompareOutput.zig+10-10
......@@ -4,7 +4,7 @@
44b: *std.Build,
55step: *std.Build.Step,
66test_index: usize,
7test_filter: ?[]const u8,
7test_filters: []const []const u8,
88optimize_modes: []const OptimizeMode,
99
1010const Special = enum {
......@@ -90,9 +90,9 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {
9090 const annotated_case_name = fmt.allocPrint(self.b.allocator, "run assemble-and-link {s}", .{
9191 case.name,
9292 }) catch @panic("OOM");
93 if (self.test_filter) |filter| {
94 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
95 }
93 for (self.test_filters) |test_filter| {
94 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
95 } else if (self.test_filters.len > 0) return;
9696
9797 const exe = b.addExecutable(.{
9898 .name = "test",
......@@ -113,9 +113,9 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {
113113 const annotated_case_name = fmt.allocPrint(self.b.allocator, "run compare-output {s} ({s})", .{
114114 case.name, @tagName(optimize),
115115 }) catch @panic("OOM");
116 if (self.test_filter) |filter| {
117 if (mem.indexOf(u8, annotated_case_name, filter) == null) continue;
118 }
116 for (self.test_filters) |test_filter| {
117 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
118 } else if (self.test_filters.len > 0) return;
119119
120120 const exe = b.addExecutable(.{
121121 .name = "test",
......@@ -139,9 +139,9 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {
139139 // TODO iterate over self.optimize_modes and test this in both
140140 // debug and release safe mode
141141 const annotated_case_name = fmt.allocPrint(self.b.allocator, "run safety {s}", .{case.name}) catch @panic("OOM");
142 if (self.test_filter) |filter| {
143 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
144 }
142 for (self.test_filters) |test_filter| {
143 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
144 } else if (self.test_filters.len > 0) return;
145145
146146 const exe = b.addExecutable(.{
147147 .name = "test",
test/src/RunTranslatedC.zig created+103
......@@ -0,0 +1,103 @@
1b: *std.Build,
2step: *std.Build.Step,
3test_index: usize,
4test_filters: []const []const u8,
5target: std.Build.ResolvedTarget,
6
7const TestCase = struct {
8 name: []const u8,
9 sources: ArrayList(SourceFile),
10 expected_stdout: []const u8,
11 allow_warnings: bool,
12
13 const SourceFile = struct {
14 filename: []const u8,
15 source: []const u8,
16 };
17
18 pub fn addSourceFile(self: *TestCase, filename: []const u8, source: []const u8) void {
19 self.sources.append(SourceFile{
20 .filename = filename,
21 .source = source,
22 }) catch unreachable;
23 }
24};
25
26pub fn create(
27 self: *RunTranslatedCContext,
28 allow_warnings: bool,
29 filename: []const u8,
30 name: []const u8,
31 source: []const u8,
32 expected_stdout: []const u8,
33) *TestCase {
34 const tc = self.b.allocator.create(TestCase) catch unreachable;
35 tc.* = TestCase{
36 .name = name,
37 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
38 .expected_stdout = expected_stdout,
39 .allow_warnings = allow_warnings,
40 };
41
42 tc.addSourceFile(filename, source);
43 return tc;
44}
45
46pub fn add(
47 self: *RunTranslatedCContext,
48 name: []const u8,
49 source: []const u8,
50 expected_stdout: []const u8,
51) void {
52 const tc = self.create(false, "source.c", name, source, expected_stdout);
53 self.addCase(tc);
54}
55
56pub fn addAllowWarnings(
57 self: *RunTranslatedCContext,
58 name: []const u8,
59 source: []const u8,
60 expected_stdout: []const u8,
61) void {
62 const tc = self.create(true, "source.c", name, source, expected_stdout);
63 self.addCase(tc);
64}
65
66pub fn addCase(self: *RunTranslatedCContext, case: *const TestCase) void {
67 const b = self.b;
68
69 const annotated_case_name = fmt.allocPrint(self.b.allocator, "run-translated-c {s}", .{case.name}) catch unreachable;
70 for (self.test_filters) |test_filter| {
71 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
72 } else if (self.test_filters.len > 0) return;
73
74 const write_src = b.addWriteFiles();
75 for (case.sources.items) |src_file| {
76 _ = write_src.add(src_file.filename, src_file.source);
77 }
78 const translate_c = b.addTranslateC(.{
79 .root_source_file = write_src.files.items[0].getPath(),
80 .target = b.host,
81 .optimize = .Debug,
82 });
83
84 translate_c.step.name = b.fmt("{s} translate-c", .{annotated_case_name});
85 const exe = translate_c.addExecutable(.{});
86 exe.step.name = b.fmt("{s} build-exe", .{annotated_case_name});
87 exe.linkLibC();
88 const run = b.addRunArtifact(exe);
89 run.step.name = b.fmt("{s} run", .{annotated_case_name});
90 if (!case.allow_warnings) {
91 run.expectStdErrEqual("");
92 }
93 run.expectStdOutEqual(case.expected_stdout);
94
95 self.step.dependOn(&run.step);
96}
97
98const RunTranslatedCContext = @This();
99const std = @import("std");
100const ArrayList = std.ArrayList;
101const fmt = std.fmt;
102const mem = std.mem;
103const fs = std.fs;
test/src/StackTrace.zig+4-4
......@@ -1,7 +1,7 @@
11b: *std.Build,
22step: *Step,
33test_index: usize,
4test_filter: ?[]const u8,
4test_filters: []const []const u8,
55optimize_modes: []const OptimizeMode,
66check_exe: *std.Build.Step.Compile,
77
......@@ -47,9 +47,9 @@ fn addExpect(
4747 const annotated_case_name = fmt.allocPrint(b.allocator, "check {s} ({s})", .{
4848 name, @tagName(optimize_mode),
4949 }) catch @panic("OOM");
50 if (self.test_filter) |filter| {
51 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
52 }
50 for (self.test_filters) |test_filter| {
51 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
52 } else if (self.test_filters.len > 0) return;
5353
5454 const write_src = b.addWriteFile("source.zig", source);
5555 const exe = b.addExecutable(.{
test/src/TranslateC.zig created+118
......@@ -0,0 +1,118 @@
1b: *std.Build,
2step: *std.Build.Step,
3test_index: usize,
4test_filters: []const []const u8,
5
6const TestCase = struct {
7 name: []const u8,
8 sources: ArrayList(SourceFile),
9 expected_lines: ArrayList([]const u8),
10 allow_warnings: bool,
11 target: std.Target.Query = .{},
12
13 const SourceFile = struct {
14 filename: []const u8,
15 source: []const u8,
16 };
17
18 pub fn addSourceFile(self: *TestCase, filename: []const u8, source: []const u8) void {
19 self.sources.append(SourceFile{
20 .filename = filename,
21 .source = source,
22 }) catch unreachable;
23 }
24
25 pub fn addExpectedLine(self: *TestCase, text: []const u8) void {
26 self.expected_lines.append(text) catch unreachable;
27 }
28};
29
30pub fn create(
31 self: *TranslateCContext,
32 allow_warnings: bool,
33 filename: []const u8,
34 name: []const u8,
35 source: []const u8,
36 expected_lines: []const []const u8,
37) *TestCase {
38 const tc = self.b.allocator.create(TestCase) catch unreachable;
39 tc.* = TestCase{
40 .name = name,
41 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
42 .expected_lines = ArrayList([]const u8).init(self.b.allocator),
43 .allow_warnings = allow_warnings,
44 };
45
46 tc.addSourceFile(filename, source);
47 var arg_i: usize = 0;
48 while (arg_i < expected_lines.len) : (arg_i += 1) {
49 tc.addExpectedLine(expected_lines[arg_i]);
50 }
51 return tc;
52}
53
54pub fn add(
55 self: *TranslateCContext,
56 name: []const u8,
57 source: []const u8,
58 expected_lines: []const []const u8,
59) void {
60 const tc = self.create(false, "source.h", name, source, expected_lines);
61 self.addCase(tc);
62}
63
64pub fn addWithTarget(
65 self: *TranslateCContext,
66 name: []const u8,
67 target: std.Target.Query,
68 source: []const u8,
69 expected_lines: []const []const u8,
70) void {
71 const tc = self.create(false, "source.h", name, source, expected_lines);
72 tc.target = target;
73 self.addCase(tc);
74}
75
76pub fn addAllowWarnings(
77 self: *TranslateCContext,
78 name: []const u8,
79 source: []const u8,
80 expected_lines: []const []const u8,
81) void {
82 const tc = self.create(true, "source.h", name, source, expected_lines);
83 self.addCase(tc);
84}
85
86pub fn addCase(self: *TranslateCContext, case: *const TestCase) void {
87 const b = self.b;
88
89 const translate_c_cmd = "translate-c";
90 const annotated_case_name = fmt.allocPrint(self.b.allocator, "{s} {s}", .{ translate_c_cmd, case.name }) catch unreachable;
91 for (self.test_filters) |test_filter| {
92 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
93 } else if (self.test_filters.len > 0) return;
94
95 const write_src = b.addWriteFiles();
96 for (case.sources.items) |src_file| {
97 _ = write_src.add(src_file.filename, src_file.source);
98 }
99
100 const translate_c = b.addTranslateC(.{
101 .root_source_file = write_src.files.items[0].getPath(),
102 .target = b.resolveTargetQuery(case.target),
103 .optimize = .Debug,
104 });
105
106 translate_c.step.name = annotated_case_name;
107
108 const check_file = translate_c.addCheckFile(case.expected_lines.items);
109
110 self.step.dependOn(&check_file.step);
111}
112
113const TranslateCContext = @This();
114const std = @import("std");
115const ArrayList = std.ArrayList;
116const fmt = std.fmt;
117const mem = std.mem;
118const fs = std.fs;
test/src/run_translated_c.zig deleted-106
......@@ -1,106 +0,0 @@
1// This is the implementation of the test harness for running translated
2// C code. For the actual test cases, see test/run_translated_c.zig.
3const std = @import("std");
4const ArrayList = std.ArrayList;
5const fmt = std.fmt;
6const mem = std.mem;
7const fs = std.fs;
8
9pub const RunTranslatedCContext = struct {
10 b: *std.Build,
11 step: *std.Build.Step,
12 test_index: usize,
13 test_filter: ?[]const u8,
14 target: std.Build.ResolvedTarget,
15
16 const TestCase = struct {
17 name: []const u8,
18 sources: ArrayList(SourceFile),
19 expected_stdout: []const u8,
20 allow_warnings: bool,
21
22 const SourceFile = struct {
23 filename: []const u8,
24 source: []const u8,
25 };
26
27 pub fn addSourceFile(self: *TestCase, filename: []const u8, source: []const u8) void {
28 self.sources.append(SourceFile{
29 .filename = filename,
30 .source = source,
31 }) catch unreachable;
32 }
33 };
34
35 pub fn create(
36 self: *RunTranslatedCContext,
37 allow_warnings: bool,
38 filename: []const u8,
39 name: []const u8,
40 source: []const u8,
41 expected_stdout: []const u8,
42 ) *TestCase {
43 const tc = self.b.allocator.create(TestCase) catch unreachable;
44 tc.* = TestCase{
45 .name = name,
46 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
47 .expected_stdout = expected_stdout,
48 .allow_warnings = allow_warnings,
49 };
50
51 tc.addSourceFile(filename, source);
52 return tc;
53 }
54
55 pub fn add(
56 self: *RunTranslatedCContext,
57 name: []const u8,
58 source: []const u8,
59 expected_stdout: []const u8,
60 ) void {
61 const tc = self.create(false, "source.c", name, source, expected_stdout);
62 self.addCase(tc);
63 }
64
65 pub fn addAllowWarnings(
66 self: *RunTranslatedCContext,
67 name: []const u8,
68 source: []const u8,
69 expected_stdout: []const u8,
70 ) void {
71 const tc = self.create(true, "source.c", name, source, expected_stdout);
72 self.addCase(tc);
73 }
74
75 pub fn addCase(self: *RunTranslatedCContext, case: *const TestCase) void {
76 const b = self.b;
77
78 const annotated_case_name = fmt.allocPrint(self.b.allocator, "run-translated-c {s}", .{case.name}) catch unreachable;
79 if (self.test_filter) |filter| {
80 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
81 }
82
83 const write_src = b.addWriteFiles();
84 for (case.sources.items) |src_file| {
85 _ = write_src.add(src_file.filename, src_file.source);
86 }
87 const translate_c = b.addTranslateC(.{
88 .root_source_file = write_src.files.items[0].getPath(),
89 .target = b.host,
90 .optimize = .Debug,
91 });
92
93 translate_c.step.name = b.fmt("{s} translate-c", .{annotated_case_name});
94 const exe = translate_c.addExecutable(.{});
95 exe.step.name = b.fmt("{s} build-exe", .{annotated_case_name});
96 exe.linkLibC();
97 const run = b.addRunArtifact(exe);
98 run.step.name = b.fmt("{s} run", .{annotated_case_name});
99 if (!case.allow_warnings) {
100 run.expectStdErrEqual("");
101 }
102 run.expectStdOutEqual(case.expected_stdout);
103
104 self.step.dependOn(&run.step);
105 }
106};
test/src/translate_c.zig deleted-121
......@@ -1,121 +0,0 @@
1// This is the implementation of the test harness.
2// For the actual test cases, see test/translate_c.zig.
3const std = @import("std");
4const ArrayList = std.ArrayList;
5const fmt = std.fmt;
6const mem = std.mem;
7const fs = std.fs;
8
9pub const TranslateCContext = struct {
10 b: *std.Build,
11 step: *std.Build.Step,
12 test_index: usize,
13 test_filter: ?[]const u8,
14
15 const TestCase = struct {
16 name: []const u8,
17 sources: ArrayList(SourceFile),
18 expected_lines: ArrayList([]const u8),
19 allow_warnings: bool,
20 target: std.Target.Query = .{},
21
22 const SourceFile = struct {
23 filename: []const u8,
24 source: []const u8,
25 };
26
27 pub fn addSourceFile(self: *TestCase, filename: []const u8, source: []const u8) void {
28 self.sources.append(SourceFile{
29 .filename = filename,
30 .source = source,
31 }) catch unreachable;
32 }
33
34 pub fn addExpectedLine(self: *TestCase, text: []const u8) void {
35 self.expected_lines.append(text) catch unreachable;
36 }
37 };
38
39 pub fn create(
40 self: *TranslateCContext,
41 allow_warnings: bool,
42 filename: []const u8,
43 name: []const u8,
44 source: []const u8,
45 expected_lines: []const []const u8,
46 ) *TestCase {
47 const tc = self.b.allocator.create(TestCase) catch unreachable;
48 tc.* = TestCase{
49 .name = name,
50 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
51 .expected_lines = ArrayList([]const u8).init(self.b.allocator),
52 .allow_warnings = allow_warnings,
53 };
54
55 tc.addSourceFile(filename, source);
56 var arg_i: usize = 0;
57 while (arg_i < expected_lines.len) : (arg_i += 1) {
58 tc.addExpectedLine(expected_lines[arg_i]);
59 }
60 return tc;
61 }
62
63 pub fn add(
64 self: *TranslateCContext,
65 name: []const u8,
66 source: []const u8,
67 expected_lines: []const []const u8,
68 ) void {
69 const tc = self.create(false, "source.h", name, source, expected_lines);
70 self.addCase(tc);
71 }
72
73 pub fn addWithTarget(
74 self: *TranslateCContext,
75 name: []const u8,
76 target: std.Target.Query,
77 source: []const u8,
78 expected_lines: []const []const u8,
79 ) void {
80 const tc = self.create(false, "source.h", name, source, expected_lines);
81 tc.target = target;
82 self.addCase(tc);
83 }
84
85 pub fn addAllowWarnings(
86 self: *TranslateCContext,
87 name: []const u8,
88 source: []const u8,
89 expected_lines: []const []const u8,
90 ) void {
91 const tc = self.create(true, "source.h", name, source, expected_lines);
92 self.addCase(tc);
93 }
94
95 pub fn addCase(self: *TranslateCContext, case: *const TestCase) void {
96 const b = self.b;
97
98 const translate_c_cmd = "translate-c";
99 const annotated_case_name = fmt.allocPrint(self.b.allocator, "{s} {s}", .{ translate_c_cmd, case.name }) catch unreachable;
100 if (self.test_filter) |filter| {
101 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
102 }
103
104 const write_src = b.addWriteFiles();
105 for (case.sources.items) |src_file| {
106 _ = write_src.add(src_file.filename, src_file.source);
107 }
108
109 const translate_c = b.addTranslateC(.{
110 .root_source_file = write_src.files.items[0].getPath(),
111 .target = b.resolveTargetQuery(case.target),
112 .optimize = .Debug,
113 });
114
115 translate_c.step.name = annotated_case_name;
116
117 const check_file = translate_c.addCheckFile(case.expected_lines.items);
118
119 self.step.dependOn(&check_file.step);
120 }
121};
test/tests.zig+16-16
......@@ -15,8 +15,8 @@ const run_translated_c = @import("run_translated_c.zig");
1515const link = @import("link.zig");
1616
1717// Implementations
18pub const TranslateCContext = @import("src/translate_c.zig").TranslateCContext;
19pub const RunTranslatedCContext = @import("src/run_translated_c.zig").RunTranslatedCContext;
18pub const TranslateCContext = @import("src/TranslateC.zig");
19pub const RunTranslatedCContext = @import("src/RunTranslatedC.zig");
2020pub const CompareOutputContext = @import("src/CompareOutput.zig");
2121pub const StackTracesContext = @import("src/StackTrace.zig");
2222
......@@ -619,7 +619,7 @@ const c_abi_targets = [_]CAbiTarget{
619619
620620pub fn addCompareOutputTests(
621621 b: *std.Build,
622 test_filter: ?[]const u8,
622 test_filters: []const []const u8,
623623 optimize_modes: []const OptimizeMode,
624624) *Step {
625625 const cases = b.allocator.create(CompareOutputContext) catch @panic("OOM");
......@@ -627,7 +627,7 @@ pub fn addCompareOutputTests(
627627 .b = b,
628628 .step = b.step("test-compare-output", "Run the compare output tests"),
629629 .test_index = 0,
630 .test_filter = test_filter,
630 .test_filters = test_filters,
631631 .optimize_modes = optimize_modes,
632632 };
633633
......@@ -638,7 +638,7 @@ pub fn addCompareOutputTests(
638638
639639pub fn addStackTraceTests(
640640 b: *std.Build,
641 test_filter: ?[]const u8,
641 test_filters: []const []const u8,
642642 optimize_modes: []const OptimizeMode,
643643) *Step {
644644 const check_exe = b.addExecutable(.{
......@@ -653,7 +653,7 @@ pub fn addStackTraceTests(
653653 .b = b,
654654 .step = b.step("test-stack-traces", "Run the stack trace tests"),
655655 .test_index = 0,
656 .test_filter = test_filter,
656 .test_filters = test_filters,
657657 .optimize_modes = optimize_modes,
658658 .check_exe = check_exe,
659659 };
......@@ -983,13 +983,13 @@ pub fn addCliTests(b: *std.Build) *Step {
983983 return step;
984984}
985985
986pub fn addAssembleAndLinkTests(b: *std.Build, test_filter: ?[]const u8, optimize_modes: []const OptimizeMode) *Step {
986pub fn addAssembleAndLinkTests(b: *std.Build, test_filters: []const []const u8, optimize_modes: []const OptimizeMode) *Step {
987987 const cases = b.allocator.create(CompareOutputContext) catch @panic("OOM");
988988 cases.* = CompareOutputContext{
989989 .b = b,
990990 .step = b.step("test-asm-link", "Run the assemble and link tests"),
991991 .test_index = 0,
992 .test_filter = test_filter,
992 .test_filters = test_filters,
993993 .optimize_modes = optimize_modes,
994994 };
995995
......@@ -998,13 +998,13 @@ pub fn addAssembleAndLinkTests(b: *std.Build, test_filter: ?[]const u8, optimize
998998 return cases.step;
999999}
10001000
1001pub fn addTranslateCTests(b: *std.Build, test_filter: ?[]const u8) *Step {
1001pub fn addTranslateCTests(b: *std.Build, test_filters: []const []const u8) *Step {
10021002 const cases = b.allocator.create(TranslateCContext) catch @panic("OOM");
10031003 cases.* = TranslateCContext{
10041004 .b = b,
10051005 .step = b.step("test-translate-c", "Run the C translation tests"),
10061006 .test_index = 0,
1007 .test_filter = test_filter,
1007 .test_filters = test_filters,
10081008 };
10091009
10101010 translate_c.addCases(cases);
......@@ -1014,7 +1014,7 @@ pub fn addTranslateCTests(b: *std.Build, test_filter: ?[]const u8) *Step {
10141014
10151015pub fn addRunTranslatedCTests(
10161016 b: *std.Build,
1017 test_filter: ?[]const u8,
1017 test_filters: []const []const u8,
10181018 target: std.Build.ResolvedTarget,
10191019) *Step {
10201020 const cases = b.allocator.create(RunTranslatedCContext) catch @panic("OOM");
......@@ -1022,7 +1022,7 @@ pub fn addRunTranslatedCTests(
10221022 .b = b,
10231023 .step = b.step("test-run-translated-c", "Run the Run-Translated-C tests"),
10241024 .test_index = 0,
1025 .test_filter = test_filter,
1025 .test_filters = test_filters,
10261026 .target = target,
10271027 };
10281028
......@@ -1032,7 +1032,7 @@ pub fn addRunTranslatedCTests(
10321032}
10331033
10341034const ModuleTestOptions = struct {
1035 test_filter: ?[]const u8,
1035 test_filters: []const []const u8,
10361036 root_src: []const u8,
10371037 name: []const u8,
10381038 desc: []const u8,
......@@ -1115,7 +1115,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
11151115 .optimize = test_target.optimize_mode,
11161116 .target = resolved_target,
11171117 .max_rss = max_rss,
1118 .filter = options.test_filter,
1118 .filters = options.test_filters,
11191119 .link_libc = test_target.link_libc,
11201120 .single_threaded = test_target.single_threaded,
11211121 .use_llvm = test_target.use_llvm,
......@@ -1291,7 +1291,7 @@ pub fn addCAbiTests(b: *std.Build, skip_non_native: bool, skip_release: bool) *S
12911291pub fn addCases(
12921292 b: *std.Build,
12931293 parent_step: *Step,
1294 opt_test_filter: ?[]const u8,
1294 test_filters: []const []const u8,
12951295 check_case_exe: *std.Build.Step.Compile,
12961296 build_options: @import("cases.zig").BuildOptions,
12971297) !void {
......@@ -1310,7 +1310,7 @@ pub fn addCases(
13101310 cases.lowerToBuildSteps(
13111311 b,
13121312 parent_step,
1313 opt_test_filter,
1313 test_filters,
13141314 cases_dir_path,
13151315 check_case_exe,
13161316 );