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 {...@@ -390,7 +390,7 @@ pub fn build(b: *std.Build) !void {
390 }390 }
391 }391 }
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
395 const test_cases_options = b.addOptions();395 const test_cases_options = b.addOptions();
396 check_case_exe.root_module.addOptions("build_options", test_cases_options);396 check_case_exe.root_module.addOptions("build_options", test_cases_options);
...@@ -418,7 +418,7 @@ pub fn build(b: *std.Build) !void {...@@ -418,7 +418,7 @@ pub fn build(b: *std.Build) !void {
418 test_cases_options.addOption(?[]const u8, "glibc_runtimes_dir", b.glibc_runtimes_dir);418 test_cases_options.addOption(?[]const u8, "glibc_runtimes_dir", b.glibc_runtimes_dir);
419 test_cases_options.addOption([:0]const u8, "version", version);419 test_cases_options.addOption([:0]const u8, "version", version);
420 test_cases_options.addOption(std.SemanticVersion, "semver", semver);420 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
423 var chosen_opt_modes_buf: [4]builtin.OptimizeMode = undefined;423 var chosen_opt_modes_buf: [4]builtin.OptimizeMode = undefined;
424 var chosen_mode_index: usize = 0;424 var chosen_mode_index: usize = 0;
...@@ -454,7 +454,7 @@ pub fn build(b: *std.Build) !void {...@@ -454,7 +454,7 @@ pub fn build(b: *std.Build) !void {
454 }).step);454 }).step);
455455
456 const test_cases_step = b.step("test-cases", "Run the main compiler test cases");456 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, .{
458 .enable_llvm = enable_llvm,458 .enable_llvm = enable_llvm,
459 .llvm_has_m68k = llvm_has_m68k,459 .llvm_has_m68k = llvm_has_m68k,
460 .llvm_has_csky = llvm_has_csky,460 .llvm_has_csky = llvm_has_csky,
...@@ -464,7 +464,7 @@ pub fn build(b: *std.Build) !void {...@@ -464,7 +464,7 @@ pub fn build(b: *std.Build) !void {
464 test_step.dependOn(test_cases_step);464 test_step.dependOn(test_cases_step);
465465
466 test_step.dependOn(tests.addModuleTests(b, .{466 test_step.dependOn(tests.addModuleTests(b, .{
467 .test_filter = test_filter,467 .test_filters = test_filters,
468 .root_src = "test/behavior.zig",468 .root_src = "test/behavior.zig",
469 .name = "behavior",469 .name = "behavior",
470 .desc = "Run the behavior tests",470 .desc = "Run the behavior tests",
...@@ -477,7 +477,7 @@ pub fn build(b: *std.Build) !void {...@@ -477,7 +477,7 @@ pub fn build(b: *std.Build) !void {
477 }));477 }));
478478
479 test_step.dependOn(tests.addModuleTests(b, .{479 test_step.dependOn(tests.addModuleTests(b, .{
480 .test_filter = test_filter,480 .test_filters = test_filters,
481 .root_src = "test/c_import.zig",481 .root_src = "test/c_import.zig",
482 .name = "c-import",482 .name = "c-import",
483 .desc = "Run the @cImport tests",483 .desc = "Run the @cImport tests",
...@@ -489,7 +489,7 @@ pub fn build(b: *std.Build) !void {...@@ -489,7 +489,7 @@ pub fn build(b: *std.Build) !void {
489 }));489 }));
490490
491 test_step.dependOn(tests.addModuleTests(b, .{491 test_step.dependOn(tests.addModuleTests(b, .{
492 .test_filter = test_filter,492 .test_filters = test_filters,
493 .root_src = "lib/compiler_rt.zig",493 .root_src = "lib/compiler_rt.zig",
494 .name = "compiler-rt",494 .name = "compiler-rt",
495 .desc = "Run the compiler_rt tests",495 .desc = "Run the compiler_rt tests",
...@@ -501,7 +501,7 @@ pub fn build(b: *std.Build) !void {...@@ -501,7 +501,7 @@ pub fn build(b: *std.Build) !void {
501 }));501 }));
502502
503 test_step.dependOn(tests.addModuleTests(b, .{503 test_step.dependOn(tests.addModuleTests(b, .{
504 .test_filter = test_filter,504 .test_filters = test_filters,
505 .root_src = "lib/c.zig",505 .root_src = "lib/c.zig",
506 .name = "universal-libc",506 .name = "universal-libc",
507 .desc = "Run the universal libc tests",507 .desc = "Run the universal libc tests",
...@@ -512,7 +512,7 @@ pub fn build(b: *std.Build) !void {...@@ -512,7 +512,7 @@ pub fn build(b: *std.Build) !void {
512 .skip_libc = true,512 .skip_libc = true,
513 }));513 }));
514514
515 test_step.dependOn(tests.addCompareOutputTests(b, test_filter, optimization_modes));515 test_step.dependOn(tests.addCompareOutputTests(b, test_filters, optimization_modes));
516 test_step.dependOn(tests.addStandaloneTests(516 test_step.dependOn(tests.addStandaloneTests(
517 b,517 b,
518 optimization_modes,518 optimization_modes,
...@@ -523,16 +523,16 @@ pub fn build(b: *std.Build) !void {...@@ -523,16 +523,16 @@ pub fn build(b: *std.Build) !void {
523 ));523 ));
524 test_step.dependOn(tests.addCAbiTests(b, skip_non_native, skip_release));524 test_step.dependOn(tests.addCAbiTests(b, skip_non_native, skip_release));
525 test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, false, enable_symlinks_windows));525 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));
527 test_step.dependOn(tests.addCliTests(b));527 test_step.dependOn(tests.addCliTests(b));
528 test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter, optimization_modes));528 test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filters, optimization_modes));
529 test_step.dependOn(tests.addTranslateCTests(b, test_filter));529 test_step.dependOn(tests.addTranslateCTests(b, test_filters));
530 if (!skip_run_translated_c) {530 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));
532 }532 }
533533
534 test_step.dependOn(tests.addModuleTests(b, .{534 test_step.dependOn(tests.addModuleTests(b, .{
535 .test_filter = test_filter,535 .test_filters = test_filters,
536 .root_src = "lib/std/std.zig",536 .root_src = "lib/std/std.zig",
537 .name = "std",537 .name = "std",
538 .desc = "Run the standard library tests",538 .desc = "Run the standard library tests",
doc/langref.html.in+4-4
...@@ -988,13 +988,13 @@ fn addOne(number: i32) i32 {...@@ -988,13 +988,13 @@ fn addOne(number: i32) i32 {
988 printed to standard error by the default test runner:988 printed to standard error by the default test runner:
989 </p>989 </p>
990 <dl>990 <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>
992 <dd>Lines like this indicate which test, out of the total number of tests, is being run.992 <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 of993 In this case, <samp>1/2</samp> indicates that the first test, out of a total of two tests,
994 two test, is being run. Note that, when the test runner program's standard error is output994 is being run. Note that, when the test runner program's standard error is output
995 to the terminal, these lines are cleared when a test succeeds.995 to the terminal, these lines are cleared when a test succeeds.
996 </dd>996 </dd>
997 <dt><samp>Test [2/2] decltest.addOne...</samp></dt>997 <dt><samp>2/2 testing_introduction.decltest.addOne...</samp></dt>
998 <dd>When the test name is an identifier, the default test runner uses the text998 <dd>When the test name is an identifier, the default test runner uses the text
999 decltest instead of test.999 decltest instead of test.
1000 </dd>1000 </dd>
lib/std/Build.zig+9-4
...@@ -855,7 +855,9 @@ pub const TestOptions = struct {...@@ -855,7 +855,9 @@ pub const TestOptions = struct {
855 optimize: std.builtin.OptimizeMode = .Debug,855 optimize: std.builtin.OptimizeMode = .Debug,
856 version: ?std.SemanticVersion = null,856 version: ?std.SemanticVersion = null,
857 max_rss: usize = 0,857 max_rss: usize = 0,
858 /// deprecated: use `.filters = &.{filter}` instead of `.filter = filter`.
858 filter: ?[]const u8 = null,859 filter: ?[]const u8 = null,
860 filters: []const []const u8 = &.{},
859 test_runner: ?[]const u8 = null,861 test_runner: ?[]const u8 = null,
860 link_libc: ?bool = null,862 link_libc: ?bool = null,
861 single_threaded: ?bool = null,863 single_threaded: ?bool = null,
...@@ -888,7 +890,12 @@ pub fn addTest(b: *Build, options: TestOptions) *Step.Compile {...@@ -888,7 +890,12 @@ pub fn addTest(b: *Build, options: TestOptions) *Step.Compile {
888 .error_tracing = options.error_tracing,890 .error_tracing = options.error_tracing,
889 },891 },
890 .max_rss = options.max_rss,892 .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),
892 .test_runner = options.test_runner,899 .test_runner = options.test_runner,
893 .use_llvm = options.use_llvm,900 .use_llvm = options.use_llvm,
894 .use_lld = options.use_lld,901 .use_lld = options.use_lld,
...@@ -993,9 +1000,7 @@ pub fn dupe(self: *Build, bytes: []const u8) []u8 {...@@ -993,9 +1000,7 @@ pub fn dupe(self: *Build, bytes: []const u8) []u8 {
993/// Duplicates an array of strings without the need to handle out of memory.1000/// Duplicates an array of strings without the need to handle out of memory.
994pub fn dupeStrings(self: *Build, strings: []const []const u8) [][]u8 {1001pub fn dupeStrings(self: *Build, strings: []const []const u8) [][]u8 {
995 const array = self.allocator.alloc([]u8, strings.len) catch @panic("OOM");1002 const array = self.allocator.alloc([]u8, strings.len) catch @panic("OOM");
996 for (strings, 0..) |s, i| {1003 for (array, strings) |*dest, source| dest.* = self.dupe(source);
997 array[i] = self.dupe(s);
998 }
999 return array;1004 return array;
1000}1005}
10011006
lib/std/Build/Step/Compile.zig+4-4
...@@ -54,7 +54,7 @@ global_base: ?u64 = null,...@@ -54,7 +54,7 @@ global_base: ?u64 = null,
54/// Set via options; intended to be read-only after that.54/// Set via options; intended to be read-only after that.
55zig_lib_dir: ?LazyPath,55zig_lib_dir: ?LazyPath,
56exec_cmd_args: ?[]const ?[]const u8,56exec_cmd_args: ?[]const ?[]const u8,
57filter: ?[]const u8,57filters: []const []const u8,
58test_runner: ?[]const u8,58test_runner: ?[]const u8,
59test_server_mode: bool,59test_server_mode: bool,
60wasi_exec_model: ?std.builtin.WasiExecModel = null,60wasi_exec_model: ?std.builtin.WasiExecModel = null,
...@@ -223,7 +223,7 @@ pub const Options = struct {...@@ -223,7 +223,7 @@ pub const Options = struct {
223 linkage: ?Linkage = null,223 linkage: ?Linkage = null,
224 version: ?std.SemanticVersion = null,224 version: ?std.SemanticVersion = null,
225 max_rss: usize = 0,225 max_rss: usize = 0,
226 filter: ?[]const u8 = null,226 filters: []const []const u8 = &.{},
227 test_runner: ?[]const u8 = null,227 test_runner: ?[]const u8 = null,
228 use_llvm: ?bool = null,228 use_llvm: ?bool = null,
229 use_lld: ?bool = null,229 use_lld: ?bool = null,
...@@ -310,7 +310,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {...@@ -310,7 +310,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
310 .installed_headers = ArrayList(*Step).init(owner.allocator),310 .installed_headers = ArrayList(*Step).init(owner.allocator),
311 .zig_lib_dir = null,311 .zig_lib_dir = null,
312 .exec_cmd_args = null,312 .exec_cmd_args = null,
313 .filter = options.filter,313 .filters = options.filters,
314 .test_runner = options.test_runner,314 .test_runner = options.test_runner,
315 .test_server_mode = options.test_runner == null,315 .test_server_mode = options.test_runner == null,
316 .rdynamic = false,316 .rdynamic = false,
...@@ -1297,7 +1297,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1297,7 +1297,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1297 try zig_args.append(b.fmt("0x{x}", .{image_base}));1297 try zig_args.append(b.fmt("0x{x}", .{image_base}));
1298 }1298 }
12991299
1300 if (self.filter) |filter| {1300 for (self.filters) |filter| {
1301 try zig_args.append("--test-filter");1301 try zig_args.append("--test-filter");
1302 try zig_args.append(filter);1302 try zig_args.append(filter);
1303 }1303 }
src/Compilation.zig+5-5
...@@ -217,7 +217,7 @@ libcxx_abi_version: libcxx.AbiVersion = libcxx.AbiVersion.default,...@@ -217,7 +217,7 @@ libcxx_abi_version: libcxx.AbiVersion = libcxx.AbiVersion.default,
217/// This mutex guards all `Compilation` mutable state.217/// This mutex guards all `Compilation` mutable state.
218mutex: std.Thread.Mutex = .{},218mutex: std.Thread.Mutex = .{},
219219
220test_filter: ?[]const u8,220test_filters: []const []const u8,
221test_name_prefix: ?[]const u8,221test_name_prefix: ?[]const u8,
222222
223emit_asm: ?EmitLoc,223emit_asm: ?EmitLoc,
...@@ -1097,7 +1097,7 @@ pub const CreateOptions = struct {...@@ -1097,7 +1097,7 @@ pub const CreateOptions = struct {
1097 native_system_include_paths: []const []const u8 = &.{},1097 native_system_include_paths: []const []const u8 = &.{},
1098 clang_preprocessor_mode: ClangPreprocessorMode = .no,1098 clang_preprocessor_mode: ClangPreprocessorMode = .no,
1099 reference_trace: ?u32 = null,1099 reference_trace: ?u32 = null,
1100 test_filter: ?[]const u8 = null,1100 test_filters: []const []const u8 = &.{},
1101 test_name_prefix: ?[]const u8 = null,1101 test_name_prefix: ?[]const u8 = null,
1102 test_runner_path: ?[]const u8 = null,1102 test_runner_path: ?[]const u8 = null,
1103 subsystem: ?std.Target.SubSystem = null,1103 subsystem: ?std.Target.SubSystem = null,
...@@ -1506,7 +1506,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1506,7 +1506,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1506 .formatted_panics = formatted_panics,1506 .formatted_panics = formatted_panics,
1507 .time_report = options.time_report,1507 .time_report = options.time_report,
1508 .stack_report = options.stack_report,1508 .stack_report = options.stack_report,
1509 .test_filter = options.test_filter,1509 .test_filters = options.test_filters,
1510 .test_name_prefix = options.test_name_prefix,1510 .test_name_prefix = options.test_name_prefix,
1511 .debug_compiler_runtime_libs = options.debug_compiler_runtime_libs,1511 .debug_compiler_runtime_libs = options.debug_compiler_runtime_libs,
1512 .debug_compile_errors = options.debug_compile_errors,1512 .debug_compile_errors = options.debug_compile_errors,
...@@ -1613,7 +1613,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1613,7 +1613,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1613 hash.add(options.config.use_lib_llvm);1613 hash.add(options.config.use_lib_llvm);
1614 hash.add(options.config.dll_export_fns);1614 hash.add(options.config.dll_export_fns);
1615 hash.add(options.config.is_test);1615 hash.add(options.config.is_test);
1616 hash.addOptionalBytes(options.test_filter);1616 hash.addListOfBytes(options.test_filters);
1617 hash.addOptionalBytes(options.test_name_prefix);1617 hash.addOptionalBytes(options.test_name_prefix);
1618 hash.add(options.skip_linker_dependencies);1618 hash.add(options.skip_linker_dependencies);
1619 hash.add(formatted_panics);1619 hash.add(formatted_panics);
...@@ -2475,7 +2475,7 @@ fn addNonIncrementalStuffToCacheManifest(...@@ -2475,7 +2475,7 @@ fn addNonIncrementalStuffToCacheManifest(
2475 try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.root_mod, mod.main_mod, .{ .files = man });2475 try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.root_mod, mod.main_mod, .{ .files = man });
24762476
2477 // Synchronize with other matching comments: ZigOnlyHashStuff2477 // Synchronize with other matching comments: ZigOnlyHashStuff
2478 man.hash.addOptionalBytes(comp.test_filter);2478 man.hash.addListOfBytes(comp.test_filters);
2479 man.hash.addOptionalBytes(comp.test_name_prefix);2479 man.hash.addOptionalBytes(comp.test_name_prefix);
2480 man.hash.add(comp.skip_linker_dependencies);2480 man.hash.add(comp.skip_linker_dependencies);
2481 man.hash.add(comp.formatted_panics);2481 man.hash.add(comp.formatted_panics);
src/InternPool.zig+1-1
...@@ -7904,7 +7904,7 @@ pub fn destroyNamespace(ip: *InternPool, gpa: Allocator, index: NamespaceIndex)...@@ -7904,7 +7904,7 @@ pub fn destroyNamespace(ip: *InternPool, gpa: Allocator, index: NamespaceIndex)
7904 ip.namespacePtr(index).* = .{7904 ip.namespacePtr(index).* = .{
7905 .parent = undefined,7905 .parent = undefined,
7906 .file_scope = undefined,7906 .file_scope = undefined,
7907 .ty = undefined,7907 .decl_index = undefined,
7908 };7908 };
7909 ip.namespaces_free_list.append(gpa, index) catch {7909 ip.namespaces_free_list.append(gpa, index) catch {
7910 // In order to keep `destroyNamespace` a non-fallible function, we ignore memory7910 // 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 {...@@ -411,15 +411,15 @@ pub const Decl = struct {
411 /// This state detects dependency loops.411 /// This state detects dependency loops.
412 in_progress,412 in_progress,
413 /// The file corresponding to this Decl had a parse error or ZIR error.413 /// 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.
415 file_failure,415 file_failure,
416 /// This Decl might be OK but it depends on another one which did not416 /// This Decl might be OK but it depends on another one which did not
417 /// successfully complete semantic analysis.417 /// successfully complete semantic analysis.
418 dependency_failure,418 dependency_failure,
419 /// Semantic analysis failure.419 /// 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.
421 sema_failure,421 sema_failure,
422 /// There will be a corresponding ErrorMsg in Module.failed_decls.422 /// There will be a corresponding ErrorMsg in Zcu.failed_decls.
423 codegen_failure,423 codegen_failure,
424 /// Sematic analysis and constant value codegen of this Decl has424 /// Sematic analysis and constant value codegen of this Decl has
425 /// succeeded. However, the Decl may be outdated due to an in-progress425 /// succeeded. However, the Decl may be outdated due to an in-progress
...@@ -494,77 +494,45 @@ pub const Decl = struct {...@@ -494,77 +494,45 @@ pub const Decl = struct {
494 return LazySrcLoc.nodeOffset(decl.nodeIndexToRelative(node_index));494 return LazySrcLoc.nodeOffset(decl.nodeIndexToRelative(node_index));
495 }495 }
496496
497 pub fn srcLoc(decl: Decl, mod: *Module) SrcLoc {497 pub fn srcLoc(decl: Decl, zcu: *Zcu) SrcLoc {
498 return decl.nodeOffsetSrcLoc(0, mod);498 return decl.nodeOffsetSrcLoc(0, zcu);
499 }499 }
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 {
502 return .{502 return .{
503 .file_scope = decl.getFileScope(mod),503 .file_scope = decl.getFileScope(zcu),
504 .parent_decl_node = decl.src_node,504 .parent_decl_node = decl.src_node,
505 .lazy = LazySrcLoc.nodeOffset(node_offset),505 .lazy = LazySrcLoc.nodeOffset(node_offset),
506 };506 };
507 }507 }
508508
509 pub fn srcToken(decl: Decl, mod: *Module) Ast.TokenIndex {509 pub fn srcToken(decl: Decl, zcu: *Zcu) Ast.TokenIndex {
510 const tree = &decl.getFileScope(mod).tree;510 const tree = &decl.getFileScope(zcu).tree;
511 return tree.firstToken(decl.src_node);511 return tree.firstToken(decl.src_node);
512 }512 }
513513
514 pub fn srcByteOffset(decl: Decl, mod: *Module) u32 {514 pub fn srcByteOffset(decl: Decl, zcu: *Zcu) u32 {
515 const tree = &decl.getFileScope(mod).tree;515 const tree = &decl.getFileScope(zcu).tree;
516 return tree.tokens.items(.start)[decl.srcToken()];516 return tree.tokens.items(.start)[decl.srcToken()];
517 }517 }
518518
519 pub fn renderFullyQualifiedName(decl: Decl, mod: *Module, writer: anytype) !void {519 pub fn renderFullyQualifiedName(decl: Decl, zcu: *Zcu, writer: anytype) !void {
520 if (decl.name_fully_qualified) {520 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)});
522 } else {522 } 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);
524 }524 }
525 }525 }
526526
527 pub fn renderFullyQualifiedDebugName(decl: Decl, mod: *Module, writer: anytype) !void {527 pub fn renderFullyQualifiedDebugName(decl: Decl, zcu: *Zcu, writer: anytype) !void {
528 return mod.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(mod, decl.name, writer);528 return zcu.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(zcu, decl.name, writer);
529 }529 }
530530
531 pub fn getFullyQualifiedName(decl: Decl, mod: *Module) !InternPool.NullTerminatedString {531 pub fn fullyQualifiedName(decl: Decl, zcu: *Zcu) !InternPool.NullTerminatedString {
532 if (decl.name_fully_qualified) return decl.name;532 return if (decl.name_fully_qualified)
533533 decl.name
534 const ip = &mod.intern_pool;534 else
535 const count = count: {535 zcu.namespacePtr(decl.src_namespace).fullyQualifiedName(zcu, decl.name);
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);
568 }536 }
569537
570 pub fn typedValue(decl: Decl) error{AnalysisFail}!TypedValue {538 pub fn typedValue(decl: Decl) error{AnalysisFail}!TypedValue {
...@@ -572,38 +540,38 @@ pub const Decl = struct {...@@ -572,38 +540,38 @@ pub const Decl = struct {
572 return TypedValue{ .ty = decl.ty, .val = decl.val };540 return TypedValue{ .ty = decl.ty, .val = decl.val };
573 }541 }
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 {
576 assert(decl.has_tv);544 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);
578 decl.val = Value.fromInterned(ip_index);546 decl.val = Value.fromInterned(ip_index);
579 return ip_index;547 return ip_index;
580 }548 }
581549
582 pub fn isFunction(decl: Decl, mod: *const Module) !bool {550 pub fn isFunction(decl: Decl, zcu: *const Zcu) !bool {
583 const tv = try decl.typedValue();551 const tv = try decl.typedValue();
584 return tv.ty.zigTypeTag(mod) == .Fn;552 return tv.ty.zigTypeTag(zcu) == .Fn;
585 }553 }
586554
587 /// If the Decl owns its value and it is a struct, return it,555 /// If the Decl owns its value and it is a struct, return it,
588 /// otherwise null.556 /// otherwise null.
589 pub fn getOwnedStruct(decl: Decl, mod: *Module) ?InternPool.Key.StructType {557 pub fn getOwnedStruct(decl: Decl, zcu: *Zcu) ?InternPool.Key.StructType {
590 if (!decl.owns_tv) return null;558 if (!decl.owns_tv) return null;
591 if (decl.val.ip_index == .none) return null;559 if (decl.val.ip_index == .none) return null;
592 return mod.typeToStruct(decl.val.toType());560 return zcu.typeToStruct(decl.val.toType());
593 }561 }
594562
595 /// If the Decl owns its value and it is a union, return it,563 /// If the Decl owns its value and it is a union, return it,
596 /// otherwise null.564 /// otherwise null.
597 pub fn getOwnedUnion(decl: Decl, mod: *Module) ?InternPool.UnionType {565 pub fn getOwnedUnion(decl: Decl, zcu: *Zcu) ?InternPool.UnionType {
598 if (!decl.owns_tv) return null;566 if (!decl.owns_tv) return null;
599 if (decl.val.ip_index == .none) return null;567 if (decl.val.ip_index == .none) return null;
600 return mod.typeToUnion(decl.val.toType());568 return zcu.typeToUnion(decl.val.toType());
601 }569 }
602570
603 pub fn getOwnedFunction(decl: Decl, mod: *Module) ?InternPool.Key.Func {571 pub fn getOwnedFunction(decl: Decl, zcu: *Zcu) ?InternPool.Key.Func {
604 const i = decl.getOwnedFunctionIndex();572 const i = decl.getOwnedFunctionIndex();
605 if (i == .none) return null;573 if (i == .none) return null;
606 return switch (mod.intern_pool.indexToKey(i)) {574 return switch (zcu.intern_pool.indexToKey(i)) {
607 .func => |func| func,575 .func => |func| func,
608 else => null,576 else => null,
609 };577 };
...@@ -616,24 +584,24 @@ pub const Decl = struct {...@@ -616,24 +584,24 @@ pub const Decl = struct {
616584
617 /// If the Decl owns its value and it is an extern function, returns it,585 /// If the Decl owns its value and it is an extern function, returns it,
618 /// otherwise null.586 /// otherwise null.
619 pub fn getOwnedExternFunc(decl: Decl, mod: *Module) ?InternPool.Key.ExternFunc {587 pub fn getOwnedExternFunc(decl: Decl, zcu: *Zcu) ?InternPool.Key.ExternFunc {
620 return if (decl.owns_tv) decl.val.getExternFunc(mod) else null;588 return if (decl.owns_tv) decl.val.getExternFunc(zcu) else null;
621 }589 }
622590
623 /// If the Decl owns its value and it is a variable, returns it,591 /// If the Decl owns its value and it is a variable, returns it,
624 /// otherwise null.592 /// otherwise null.
625 pub fn getOwnedVariable(decl: Decl, mod: *Module) ?InternPool.Key.Variable {593 pub fn getOwnedVariable(decl: Decl, zcu: *Zcu) ?InternPool.Key.Variable {
626 return if (decl.owns_tv) decl.val.getVariable(mod) else null;594 return if (decl.owns_tv) decl.val.getVariable(zcu) else null;
627 }595 }
628596
629 /// Gets the namespace that this Decl creates by being a struct, union,597 /// Gets the namespace that this Decl creates by being a struct, union,
630 /// enum, or opaque.598 /// enum, or opaque.
631 pub fn getInnerNamespaceIndex(decl: Decl, mod: *Module) Namespace.OptionalIndex {599 pub fn getInnerNamespaceIndex(decl: Decl, zcu: *Zcu) Namespace.OptionalIndex {
632 if (!decl.has_tv) return .none;600 if (!decl.has_tv) return .none;
633 return switch (decl.val.ip_index) {601 return switch (decl.val.ip_index) {
634 .empty_struct_type => .none,602 .empty_struct_type => .none,
635 .none => .none,603 .none => .none,
636 else => switch (mod.intern_pool.indexToKey(decl.val.toIntern())) {604 else => switch (zcu.intern_pool.indexToKey(decl.val.toIntern())) {
637 .opaque_type => |opaque_type| opaque_type.namespace.toOptional(),605 .opaque_type => |opaque_type| opaque_type.namespace.toOptional(),
638 .struct_type => |struct_type| struct_type.namespace,606 .struct_type => |struct_type| struct_type.namespace,
639 .union_type => |union_type| union_type.namespace.toOptional(),607 .union_type => |union_type| union_type.namespace.toOptional(),
...@@ -644,19 +612,19 @@ pub const Decl = struct {...@@ -644,19 +612,19 @@ pub const Decl = struct {
644 }612 }
645613
646 /// Like `getInnerNamespaceIndex`, but only returns it if the Decl is the owner.614 /// 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 {
648 if (!decl.owns_tv) return .none;616 if (!decl.owns_tv) return .none;
649 return decl.getInnerNamespaceIndex(mod);617 return decl.getInnerNamespaceIndex(zcu);
650 }618 }
651619
652 /// Same as `getOwnedInnerNamespaceIndex` but additionally obtains the pointer.620 /// Same as `getOwnedInnerNamespaceIndex` but additionally obtains the pointer.
653 pub fn getOwnedInnerNamespace(decl: Decl, mod: *Module) ?*Namespace {621 pub fn getOwnedInnerNamespace(decl: Decl, zcu: *Zcu) ?*Namespace {
654 return mod.namespacePtrUnwrap(decl.getOwnedInnerNamespaceIndex(mod));622 return zcu.namespacePtrUnwrap(decl.getOwnedInnerNamespaceIndex(zcu));
655 }623 }
656624
657 /// Same as `getInnerNamespaceIndex` but additionally obtains the pointer.625 /// Same as `getInnerNamespaceIndex` but additionally obtains the pointer.
658 pub fn getInnerNamespace(decl: Decl, mod: *Module) ?*Namespace {626 pub fn getInnerNamespace(decl: Decl, zcu: *Zcu) ?*Namespace {
659 return mod.namespacePtrUnwrap(decl.getInnerNamespaceIndex(mod));627 return zcu.namespacePtrUnwrap(decl.getInnerNamespaceIndex(zcu));
660 }628 }
661629
662 pub fn dump(decl: *Decl) void {630 pub fn dump(decl: *Decl) void {
...@@ -674,27 +642,27 @@ pub const Decl = struct {...@@ -674,27 +642,27 @@ pub const Decl = struct {
674 std.debug.print("\n", .{});642 std.debug.print("\n", .{});
675 }643 }
676644
677 pub fn getFileScope(decl: Decl, mod: *Module) *File {645 pub fn getFileScope(decl: Decl, zcu: *Zcu) *File {
678 return mod.namespacePtr(decl.src_namespace).file_scope;646 return zcu.namespacePtr(decl.src_namespace).file_scope;
679 }647 }
680648
681 pub fn getExternDecl(decl: Decl, mod: *Module) OptionalIndex {649 pub fn getExternDecl(decl: Decl, zcu: *Zcu) OptionalIndex {
682 assert(decl.has_tv);650 assert(decl.has_tv);
683 return switch (mod.intern_pool.indexToKey(decl.val.toIntern())) {651 return switch (zcu.intern_pool.indexToKey(decl.val.toIntern())) {
684 .variable => |variable| if (variable.is_extern) variable.decl.toOptional() else .none,652 .variable => |variable| if (variable.is_extern) variable.decl.toOptional() else .none,
685 .extern_func => |extern_func| extern_func.decl.toOptional(),653 .extern_func => |extern_func| extern_func.decl.toOptional(),
686 else => .none,654 else => .none,
687 };655 };
688 }656 }
689657
690 pub fn isExtern(decl: Decl, mod: *Module) bool {658 pub fn isExtern(decl: Decl, zcu: *Zcu) bool {
691 return decl.getExternDecl(mod) != .none;659 return decl.getExternDecl(zcu) != .none;
692 }660 }
693661
694 pub fn getAlignment(decl: Decl, mod: *Module) Alignment {662 pub fn getAlignment(decl: Decl, zcu: *Zcu) Alignment {
695 assert(decl.has_tv);663 assert(decl.has_tv);
696 if (decl.alignment != .none) return decl.alignment;664 if (decl.alignment != .none) return decl.alignment;
697 return decl.ty.abiAlignment(mod);665 return decl.ty.abiAlignment(zcu);
698 }666 }
699};667};
700668
...@@ -704,7 +672,7 @@ pub const EmitH = struct {...@@ -704,7 +672,7 @@ pub const EmitH = struct {
704};672};
705673
706pub const DeclAdapter = struct {674pub const DeclAdapter = struct {
707 mod: *Module,675 zcu: *Zcu,
708676
709 pub fn hash(self: @This(), s: InternPool.NullTerminatedString) u32 {677 pub fn hash(self: @This(), s: InternPool.NullTerminatedString) u32 {
710 _ = self;678 _ = self;
...@@ -713,8 +681,7 @@ pub const DeclAdapter = struct {...@@ -713,8 +681,7 @@ pub const DeclAdapter = struct {
713681
714 pub fn eql(self: @This(), a: InternPool.NullTerminatedString, b_decl_index: Decl.Index, b_index: usize) bool {682 pub fn eql(self: @This(), a: InternPool.NullTerminatedString, b_decl_index: Decl.Index, b_index: usize) bool {
715 _ = b_index;683 _ = b_index;
716 const b_decl = self.mod.declPtr(b_decl_index);684 return a == self.zcu.declPtr(b_decl_index).name;
717 return a == b_decl.name;
718 }685 }
719};686};
720687
...@@ -723,7 +690,7 @@ pub const Namespace = struct {...@@ -723,7 +690,7 @@ pub const Namespace = struct {
723 parent: OptionalIndex,690 parent: OptionalIndex,
724 file_scope: *File,691 file_scope: *File,
725 /// Will be a struct, enum, union, or opaque.692 /// Will be a struct, enum, union, or opaque.
726 ty: Type,693 decl_index: Decl.Index,
727 /// Direct children of the namespace.694 /// Direct children of the namespace.
728 /// Declaration order is preserved via entry order.695 /// Declaration order is preserved via entry order.
729 /// These are only declarations named directly by the AST; anonymous696 /// These are only declarations named directly by the AST; anonymous
...@@ -739,7 +706,7 @@ pub const Namespace = struct {...@@ -739,7 +706,7 @@ pub const Namespace = struct {
739 const OptionalIndex = InternPool.OptionalNamespaceIndex;706 const OptionalIndex = InternPool.OptionalNamespaceIndex;
740707
741 const DeclContext = struct {708 const DeclContext = struct {
742 module: *Module,709 zcu: *Zcu,
743710
744 pub fn hash(ctx: @This(), decl_index: Decl.Index) u32 {711 pub fn hash(ctx: @This(), decl_index: Decl.Index) u32 {
745 const decl = ctx.module.declPtr(decl_index);712 const decl = ctx.module.declPtr(decl_index);
...@@ -757,39 +724,87 @@ pub const Namespace = struct {...@@ -757,39 +724,87 @@ pub const Namespace = struct {
757 // This renders e.g. "std.fs.Dir.OpenOptions"724 // This renders e.g. "std.fs.Dir.OpenOptions"
758 pub fn renderFullyQualifiedName(725 pub fn renderFullyQualifiedName(
759 ns: Namespace,726 ns: Namespace,
760 mod: *Module,727 zcu: *Zcu,
761 name: InternPool.NullTerminatedString,728 name: InternPool.NullTerminatedString,
762 writer: anytype,729 writer: anytype,
763 ) @TypeOf(writer).Error!void {730 ) @TypeOf(writer).Error!void {
764 if (ns.parent.unwrap()) |parent| {731 if (ns.parent.unwrap()) |parent| {
765 const decl = mod.declPtr(ns.getDeclIndex(mod));732 try zcu.namespacePtr(parent).renderFullyQualifiedName(
766 try mod.namespacePtr(parent).renderFullyQualifiedName(mod, decl.name, writer);733 zcu,
734 zcu.declPtr(ns.decl_index).name,
735 writer,
736 );
767 } else {737 } else {
768 try ns.file_scope.renderFullyQualifiedName(writer);738 try ns.file_scope.renderFullyQualifiedName(writer);
769 }739 }
770 if (name != .empty) try writer.print(".{}", .{name.fmt(&mod.intern_pool)});740 if (name != .empty) try writer.print(".{}", .{name.fmt(&zcu.intern_pool)});
771 }741 }
772742
773 /// This renders e.g. "std/fs.zig:Dir.OpenOptions"743 /// This renders e.g. "std/fs.zig:Dir.OpenOptions"
774 pub fn renderFullyQualifiedDebugName(744 pub fn renderFullyQualifiedDebugName(
775 ns: Namespace,745 ns: Namespace,
776 mod: *Module,746 zcu: *Zcu,
777 name: InternPool.NullTerminatedString,747 name: InternPool.NullTerminatedString,
778 writer: anytype,748 writer: anytype,
779 ) @TypeOf(writer).Error!void {749 ) @TypeOf(writer).Error!void {
780 const separator_char: u8 = if (ns.parent.unwrap()) |parent| sep: {750 const sep: u8 = if (ns.parent.unwrap()) |parent| sep: {
781 const decl = mod.declPtr(ns.getDeclIndex(mod));751 try zcu.namespacePtr(parent).renderFullyQualifiedDebugName(
782 try mod.namespacePtr(parent).renderFullyQualifiedDebugName(mod, decl.name, writer);752 zcu,
753 zcu.declPtr(ns.decl_index).name,
754 writer,
755 );
783 break :sep '.';756 break :sep '.';
784 } else sep: {757 } else sep: {
785 try ns.file_scope.renderFullyQualifiedDebugName(writer);758 try ns.file_scope.renderFullyQualifiedDebugName(writer);
786 break :sep ':';759 break :sep ':';
787 };760 };
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) });
789 }762 }
790763
791 pub fn getDeclIndex(ns: Namespace, mod: *Module) Decl.Index {764 pub fn fullyQualifiedName(
792 return ns.ty.getOwnerDecl(mod);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();
793 }808 }
794};809};
795810
...@@ -2559,9 +2574,8 @@ pub fn namespacePtrUnwrap(mod: *Module, index: Namespace.OptionalIndex) ?*Namesp...@@ -2559,9 +2574,8 @@ pub fn namespacePtrUnwrap(mod: *Module, index: Namespace.OptionalIndex) ?*Namesp
2559pub fn declIsRoot(mod: *Module, decl_index: Decl.Index) bool {2574pub fn declIsRoot(mod: *Module, decl_index: Decl.Index) bool {
2560 const decl = mod.declPtr(decl_index);2575 const decl = mod.declPtr(decl_index);
2561 const namespace = mod.namespacePtr(decl.src_namespace);2576 const namespace = mod.namespacePtr(decl.src_namespace);
2562 if (namespace.parent != .none)2577 if (namespace.parent != .none) return false;
2563 return false;2578 return decl_index == namespace.decl_index;
2564 return decl_index == namespace.getDeclIndex(mod);
2565}2579}
25662580
2567fn freeExportList(gpa: Allocator, export_list: *ArrayListUnmanaged(*Export)) void {2581fn freeExportList(gpa: Allocator, export_list: *ArrayListUnmanaged(*Export)) void {
...@@ -3592,7 +3606,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError...@@ -3592,7 +3606,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError
3592 defer liveness.deinit(gpa);3606 defer liveness.deinit(gpa);
35933607
3594 if (dump_air) {3608 if (dump_air) {
3595 const fqn = try decl.getFullyQualifiedName(zcu);3609 const fqn = try decl.fullyQualifiedName(zcu);
3596 std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)});3610 std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)});
3597 @import("print_air.zig").dump(zcu, air, liveness);3611 @import("print_air.zig").dump(zcu, air, liveness);
3598 std.debug.print("# End Function AIR: {}\n\n", .{fqn.fmt(ip)});3612 std.debug.print("# End Function AIR: {}\n\n", .{fqn.fmt(ip)});
...@@ -3738,7 +3752,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -3738,7 +3752,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
3738 // InternPool index.3752 // InternPool index.
3739 const new_namespace_index = try mod.createNamespace(.{3753 const new_namespace_index = try mod.createNamespace(.{
3740 .parent = .none,3754 .parent = .none,
3741 .ty = undefined,3755 .decl_index = undefined,
3742 .file_scope = file,3756 .file_scope = file,
3743 });3757 });
3744 const new_namespace = mod.namespacePtr(new_namespace_index);3758 const new_namespace = mod.namespacePtr(new_namespace_index);
...@@ -3749,6 +3763,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -3749,6 +3763,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
3749 errdefer @panic("TODO error handling");3763 errdefer @panic("TODO error handling");
37503764
3751 file.root_decl = new_decl_index.toOptional();3765 file.root_decl = new_decl_index.toOptional();
3766 new_namespace.decl_index = new_decl_index;
37523767
3753 new_decl.name = try file.fullyQualifiedName(mod);3768 new_decl.name = try file.fullyQualifiedName(mod);
3754 new_decl.name_fully_qualified = true;3769 new_decl.name_fully_qualified = true;
...@@ -3808,7 +3823,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -3808,7 +3823,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
3808 _ = try decl.internValue(mod);3823 _ = try decl.internValue(mod);
3809 }3824 }
38103825
3811 new_namespace.ty = Type.fromInterned(struct_ty);
3812 new_decl.val = Value.fromInterned(struct_ty);3826 new_decl.val = Value.fromInterned(struct_ty);
3813 new_decl.has_tv = true;3827 new_decl.has_tv = true;
3814 new_decl.owns_tv = true;3828 new_decl.owns_tv = true;
...@@ -3881,7 +3895,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {...@@ -3881,7 +3895,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
3881 const std_decl = mod.declPtr(std_file.root_decl.unwrap().?);3895 const std_decl = mod.declPtr(std_file.root_decl.unwrap().?);
3882 const std_namespace = std_decl.getInnerNamespace(mod).?;3896 const std_namespace = std_decl.getInnerNamespace(mod).?;
3883 const builtin_str = try ip.getOrPutString(gpa, "builtin");3897 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);
3885 const builtin_namespace = builtin_decl.getInnerNamespaceIndex(mod).unwrap() orelse break :blk .none;3899 const builtin_namespace = builtin_decl.getInnerNamespaceIndex(mod).unwrap() orelse break :blk .none;
3886 if (decl.src_namespace != builtin_namespace) break :blk .none;3900 if (decl.src_namespace != builtin_namespace) break :blk .none;
3887 // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index.3901 // 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...@@ -4576,8 +4590,8 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void
4576 const gop = try namespace.decls.getOrPutContextAdapted(4590 const gop = try namespace.decls.getOrPutContextAdapted(
4577 gpa,4591 gpa,
4578 decl_name,4592 decl_name,
4579 DeclAdapter{ .mod = zcu },4593 DeclAdapter{ .zcu = zcu },
4580 Namespace.DeclContext{ .module = zcu },4594 Namespace.DeclContext{ .zcu = zcu },
4581 );4595 );
4582 const comp = zcu.comp;4596 const comp = zcu.comp;
4583 if (!gop.found_existing) {4597 if (!gop.found_existing) {
...@@ -4600,12 +4614,11 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void...@@ -4600,12 +4614,11 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void
4600 .@"test" => a: {4614 .@"test" => a: {
4601 if (!comp.config.is_test) break :a false;4615 if (!comp.config.is_test) break :a false;
4602 if (decl_mod != zcu.main_mod) break :a false;4616 if (decl_mod != zcu.main_mod) break :a false;
4603 if (is_named_test) {4617 if (is_named_test and comp.test_filters.len > 0) {
4604 if (comp.test_filter) |test_filter| {4618 const decl_fqn = ip.stringToSlice(try namespace.fullyQualifiedName(zcu, decl_name));
4605 if (mem.indexOf(u8, ip.stringToSlice(decl_name), test_filter) == null) {4619 for (comp.test_filters) |test_filter| {
4606 break :a false;4620 if (mem.indexOf(u8, decl_fqn, test_filter)) |_| break;
4607 }4621 } else break :a false;
4608 }
4609 }4622 }
4610 try zcu.test_functions.put(gpa, new_decl_index, {});4623 try zcu.test_functions.put(gpa, new_decl_index, {});
4611 break :a true;4624 break :a true;
...@@ -5622,7 +5635,7 @@ pub fn populateTestFunctions(...@@ -5622,7 +5635,7 @@ pub fn populateTestFunctions(
5622 const test_functions_str = try ip.getOrPutString(gpa, "test_functions");5635 const test_functions_str = try ip.getOrPutString(gpa, "test_functions");
5623 const decl_index = builtin_namespace.decls.getKeyAdapted(5636 const decl_index = builtin_namespace.decls.getKeyAdapted(
5624 test_functions_str,5637 test_functions_str,
5625 DeclAdapter{ .mod = mod },5638 DeclAdapter{ .zcu = mod },
5626 ).?;5639 ).?;
5627 {5640 {
5628 // We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions`5641 // We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions`
...@@ -5646,8 +5659,7 @@ pub fn populateTestFunctions(...@@ -5646,8 +5659,7 @@ pub fn populateTestFunctions(
56465659
5647 for (test_fn_vals, mod.test_functions.keys()) |*test_fn_val, test_decl_index| {5660 for (test_fn_vals, mod.test_functions.keys()) |*test_fn_val, test_decl_index| {
5648 const test_decl = mod.declPtr(test_decl_index);5661 const test_decl = mod.declPtr(test_decl_index);
5649 // TODO: write something like getCoercedInts to avoid needing to dupe5662 const test_decl_name = try gpa.dupe(u8, ip.stringToSlice(try test_decl.fullyQualifiedName(mod)));
5650 const test_decl_name = try gpa.dupe(u8, ip.stringToSlice(test_decl.name));
5651 defer gpa.free(test_decl_name);5663 defer gpa.free(test_decl_name);
5652 const test_name_decl_index = n: {5664 const test_name_decl_index = n: {
5653 const test_name_decl_ty = try mod.arrayType(.{5665 const test_name_decl_ty = try mod.arrayType(.{
...@@ -6359,17 +6371,13 @@ pub fn opaqueSrcLoc(mod: *Module, opaque_type: InternPool.Key.OpaqueType) SrcLoc...@@ -6359,17 +6371,13 @@ pub fn opaqueSrcLoc(mod: *Module, opaque_type: InternPool.Key.OpaqueType) SrcLoc
6359}6371}
63606372
6361pub fn opaqueFullyQualifiedName(mod: *Module, opaque_type: InternPool.Key.OpaqueType) !InternPool.NullTerminatedString {6373pub 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);
6363}6375}
63646376
6365pub fn declFileScope(mod: *Module, decl_index: Decl.Index) *File {6377pub fn declFileScope(mod: *Module, decl_index: Decl.Index) *File {
6366 return mod.declPtr(decl_index).getFileScope(mod);6378 return mod.declPtr(decl_index).getFileScope(mod);
6367}6379}
63686380
6369pub fn namespaceDeclIndex(mod: *Module, namespace_index: Namespace.Index) Decl.Index {
6370 return mod.namespacePtr(namespace_index).getDeclIndex(mod);
6371}
6372
6373/// Returns null in the following cases:6381/// Returns null in the following cases:
6374/// * `@TypeOf(.{})`6382/// * `@TypeOf(.{})`
6375/// * A struct which has no fields (`struct {}`).6383/// * A struct which has no fields (`struct {}`).
src/Sema.zig+17-31
...@@ -2801,10 +2801,9 @@ fn zirStructDecl(...@@ -2801,10 +2801,9 @@ fn zirStructDecl(
28012801
2802 const new_namespace_index = try mod.createNamespace(.{2802 const new_namespace_index = try mod.createNamespace(.{
2803 .parent = block.namespace.toOptional(),2803 .parent = block.namespace.toOptional(),
2804 .ty = undefined,2804 .decl_index = new_decl_index,
2805 .file_scope = block.getFileScope(mod),2805 .file_scope = block.getFileScope(mod),
2806 });2806 });
2807 const new_namespace = mod.namespacePtr(new_namespace_index);
2808 errdefer mod.destroyNamespace(new_namespace_index);2807 errdefer mod.destroyNamespace(new_namespace_index);
28092808
2810 const struct_ty = ty: {2809 const struct_ty = ty: {
...@@ -2821,7 +2820,6 @@ fn zirStructDecl(...@@ -2821,7 +2820,6 @@ fn zirStructDecl(
28212820
2822 new_decl.ty = Type.type;2821 new_decl.ty = Type.type;
2823 new_decl.val = Value.fromInterned(struct_ty);2822 new_decl.val = Value.fromInterned(struct_ty);
2824 new_namespace.ty = Type.fromInterned(struct_ty);
28252823
2826 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);2824 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
2827 try mod.finalizeAnonDecl(new_decl_index);2825 try mod.finalizeAnonDecl(new_decl_index);
...@@ -2990,10 +2988,9 @@ fn zirEnumDecl(...@@ -2990,10 +2988,9 @@ fn zirEnumDecl(
29902988
2991 const new_namespace_index = try mod.createNamespace(.{2989 const new_namespace_index = try mod.createNamespace(.{
2992 .parent = block.namespace.toOptional(),2990 .parent = block.namespace.toOptional(),
2993 .ty = undefined,2991 .decl_index = new_decl_index,
2994 .file_scope = block.getFileScope(mod),2992 .file_scope = block.getFileScope(mod),
2995 });2993 });
2996 const new_namespace = mod.namespacePtr(new_namespace_index);
2997 errdefer if (!done) mod.destroyNamespace(new_namespace_index);2994 errdefer if (!done) mod.destroyNamespace(new_namespace_index);
29982995
2999 const decls = sema.code.bodySlice(extra_index, decls_len);2996 const decls = sema.code.bodySlice(extra_index, decls_len);
...@@ -3036,7 +3033,6 @@ fn zirEnumDecl(...@@ -3036,7 +3033,6 @@ fn zirEnumDecl(
30363033
3037 new_decl.ty = Type.type;3034 new_decl.ty = Type.type;
3038 new_decl.val = Value.fromInterned(incomplete_enum.index);3035 new_decl.val = Value.fromInterned(incomplete_enum.index);
3039 new_namespace.ty = Type.fromInterned(incomplete_enum.index);
30403036
3041 const decl_val = try sema.analyzeDeclVal(block, src, new_decl_index);3037 const decl_val = try sema.analyzeDeclVal(block, src, new_decl_index);
3042 try mod.finalizeAnonDecl(new_decl_index);3038 try mod.finalizeAnonDecl(new_decl_index);
...@@ -3248,10 +3244,9 @@ fn zirUnionDecl(...@@ -3248,10 +3244,9 @@ fn zirUnionDecl(
32483244
3249 const new_namespace_index = try mod.createNamespace(.{3245 const new_namespace_index = try mod.createNamespace(.{
3250 .parent = block.namespace.toOptional(),3246 .parent = block.namespace.toOptional(),
3251 .ty = undefined,3247 .decl_index = new_decl_index,
3252 .file_scope = block.getFileScope(mod),3248 .file_scope = block.getFileScope(mod),
3253 });3249 });
3254 const new_namespace = mod.namespacePtr(new_namespace_index);
3255 errdefer mod.destroyNamespace(new_namespace_index);3250 errdefer mod.destroyNamespace(new_namespace_index);
32563251
3257 const union_ty = ty: {3252 const union_ty = ty: {
...@@ -3292,7 +3287,6 @@ fn zirUnionDecl(...@@ -3292,7 +3287,6 @@ fn zirUnionDecl(
32923287
3293 new_decl.ty = Type.type;3288 new_decl.ty = Type.type;
3294 new_decl.val = Value.fromInterned(union_ty);3289 new_decl.val = Value.fromInterned(union_ty);
3295 new_namespace.ty = Type.fromInterned(union_ty);
32963290
3297 const decls = sema.code.bodySlice(extra_index, decls_len);3291 const decls = sema.code.bodySlice(extra_index, decls_len);
3298 try mod.scanNamespace(new_namespace_index, decls, new_decl);3292 try mod.scanNamespace(new_namespace_index, decls, new_decl);
...@@ -3346,10 +3340,9 @@ fn zirOpaqueDecl(...@@ -3346,10 +3340,9 @@ fn zirOpaqueDecl(
33463340
3347 const new_namespace_index = try mod.createNamespace(.{3341 const new_namespace_index = try mod.createNamespace(.{
3348 .parent = block.namespace.toOptional(),3342 .parent = block.namespace.toOptional(),
3349 .ty = undefined,3343 .decl_index = new_decl_index,
3350 .file_scope = block.getFileScope(mod),3344 .file_scope = block.getFileScope(mod),
3351 });3345 });
3352 const new_namespace = mod.namespacePtr(new_namespace_index);
3353 errdefer mod.destroyNamespace(new_namespace_index);3346 errdefer mod.destroyNamespace(new_namespace_index);
33543347
3355 const opaque_ty = try mod.intern(.{ .opaque_type = .{3348 const opaque_ty = try mod.intern(.{ .opaque_type = .{
...@@ -3362,7 +3355,6 @@ fn zirOpaqueDecl(...@@ -3362,7 +3355,6 @@ fn zirOpaqueDecl(
33623355
3363 new_decl.ty = Type.type;3356 new_decl.ty = Type.type;
3364 new_decl.val = Value.fromInterned(opaque_ty);3357 new_decl.val = Value.fromInterned(opaque_ty);
3365 new_namespace.ty = Type.fromInterned(opaque_ty);
33663358
3367 const decls = sema.code.bodySlice(extra_index, decls_len);3359 const decls = sema.code.bodySlice(extra_index, decls_len);
3368 try mod.scanNamespace(new_namespace_index, decls, new_decl);3360 try mod.scanNamespace(new_namespace_index, decls, new_decl);
...@@ -4834,7 +4826,7 @@ fn validateStructInit(...@@ -4834,7 +4826,7 @@ fn validateStructInit(
4834 if (root_msg) |msg| {4826 if (root_msg) |msg| {
4835 if (mod.typeToStruct(struct_ty)) |struct_type| {4827 if (mod.typeToStruct(struct_ty)) |struct_type| {
4836 const decl = mod.declPtr(struct_type.decl.unwrap().?);4828 const decl = mod.declPtr(struct_type.decl.unwrap().?);
4837 const fqn = try decl.getFullyQualifiedName(mod);4829 const fqn = try decl.fullyQualifiedName(mod);
4838 try mod.errNoteNonLazy(4830 try mod.errNoteNonLazy(
4839 decl.srcLoc(mod),4831 decl.srcLoc(mod),
4840 msg,4832 msg,
...@@ -4961,7 +4953,7 @@ fn validateStructInit(...@@ -4961,7 +4953,7 @@ fn validateStructInit(
4961 if (root_msg) |msg| {4953 if (root_msg) |msg| {
4962 if (mod.typeToStruct(struct_ty)) |struct_type| {4954 if (mod.typeToStruct(struct_ty)) |struct_type| {
4963 const decl = mod.declPtr(struct_type.decl.unwrap().?);4955 const decl = mod.declPtr(struct_type.decl.unwrap().?);
4964 const fqn = try decl.getFullyQualifiedName(mod);4956 const fqn = try decl.fullyQualifiedName(mod);
4965 try mod.errNoteNonLazy(4957 try mod.errNoteNonLazy(
4966 decl.srcLoc(mod),4958 decl.srcLoc(mod),
4967 msg,4959 msg,
...@@ -5355,7 +5347,7 @@ fn failWithBadStructFieldAccess(...@@ -5355,7 +5347,7 @@ fn failWithBadStructFieldAccess(
5355 const mod = sema.mod;5347 const mod = sema.mod;
5356 const gpa = sema.gpa;5348 const gpa = sema.gpa;
5357 const decl = mod.declPtr(struct_type.decl.unwrap().?);5349 const decl = mod.declPtr(struct_type.decl.unwrap().?);
5358 const fqn = try decl.getFullyQualifiedName(mod);5350 const fqn = try decl.fullyQualifiedName(mod);
53595351
5360 const msg = msg: {5352 const msg = msg: {
5361 const msg = try sema.errMsg(5353 const msg = try sema.errMsg(
...@@ -5382,7 +5374,7 @@ fn failWithBadUnionFieldAccess(...@@ -5382,7 +5374,7 @@ fn failWithBadUnionFieldAccess(
5382 const gpa = sema.gpa;5374 const gpa = sema.gpa;
53835375
5384 const decl = mod.declPtr(union_obj.decl);5376 const decl = mod.declPtr(union_obj.decl);
5385 const fqn = try decl.getFullyQualifiedName(mod);5377 const fqn = try decl.fullyQualifiedName(mod);
53865378
5387 const msg = msg: {5379 const msg = msg: {
5388 const msg = try sema.errMsg(5380 const msg = try sema.errMsg(
...@@ -6504,8 +6496,7 @@ fn lookupInNamespace(...@@ -6504,8 +6496,7 @@ fn lookupInNamespace(
6504 const mod = sema.mod;6496 const mod = sema.mod;
65056497
6506 const namespace = mod.namespacePtr(namespace_index);6498 const namespace = mod.namespacePtr(namespace_index);
6507 const namespace_decl_index = namespace.getDeclIndex(mod);6499 const namespace_decl = mod.declPtr(namespace.decl_index);
6508 const namespace_decl = mod.declPtr(namespace_decl_index);
6509 if (namespace_decl.analysis == .file_failure) {6500 if (namespace_decl.analysis == .file_failure) {
6510 return error.AnalysisFail;6501 return error.AnalysisFail;
6511 }6502 }
...@@ -6526,7 +6517,7 @@ fn lookupInNamespace(...@@ -6526,7 +6517,7 @@ fn lookupInNamespace(
65266517
6527 while (check_i < checked_namespaces.count()) : (check_i += 1) {6518 while (check_i < checked_namespaces.count()) : (check_i += 1) {
6528 const check_ns = checked_namespaces.keys()[check_i];6519 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| {
6530 // Skip decls which are not marked pub, which are in a different6521 // Skip decls which are not marked pub, which are in a different
6531 // file than the `a.b`/`@hasDecl` syntax.6522 // file than the `a.b`/`@hasDecl` syntax.
6532 const decl = mod.declPtr(decl_index);6523 const decl = mod.declPtr(decl_index);
...@@ -6584,7 +6575,7 @@ fn lookupInNamespace(...@@ -6584,7 +6575,7 @@ fn lookupInNamespace(
6584 return sema.failWithOwnedErrorMsg(block, msg);6575 return sema.failWithOwnedErrorMsg(block, msg);
6585 },6576 },
6586 }6577 }
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| {
6588 return decl_index;6579 return decl_index;
6589 }6580 }
65906581
...@@ -17210,7 +17201,7 @@ fn zirThis(...@@ -17210,7 +17201,7 @@ fn zirThis(
17210 extended: Zir.Inst.Extended.InstData,17201 extended: Zir.Inst.Extended.InstData,
17211) CompileError!Air.Inst.Ref {17202) CompileError!Air.Inst.Ref {
17212 const mod = sema.mod;17203 const mod = sema.mod;
17213 const this_decl_index = mod.namespaceDeclIndex(block.namespace);17204 const this_decl_index = mod.namespacePtr(block.namespace).decl_index;
17214 const src = LazySrcLoc.nodeOffset(@bitCast(extended.operand));17205 const src = LazySrcLoc.nodeOffset(@bitCast(extended.operand));
17215 return sema.analyzeDeclVal(block, src, this_decl_index);17206 return sema.analyzeDeclVal(block, src, this_decl_index);
17216}17207}
...@@ -20075,7 +20066,7 @@ fn finishStructInit(...@@ -20075,7 +20066,7 @@ fn finishStructInit(
20075 if (root_msg) |msg| {20066 if (root_msg) |msg| {
20076 if (mod.typeToStruct(struct_ty)) |struct_type| {20067 if (mod.typeToStruct(struct_ty)) |struct_type| {
20077 const decl = mod.declPtr(struct_type.decl.unwrap().?);20068 const decl = mod.declPtr(struct_type.decl.unwrap().?);
20078 const fqn = try decl.getFullyQualifiedName(mod);20069 const fqn = try decl.fullyQualifiedName(mod);
20079 try mod.errNoteNonLazy(20070 try mod.errNoteNonLazy(
20080 decl.srcLoc(mod),20071 decl.srcLoc(mod),
20081 msg,20072 msg,
...@@ -21404,10 +21395,9 @@ fn zirReify(...@@ -21404,10 +21395,9 @@ fn zirReify(
2140421395
21405 const new_namespace_index = try mod.createNamespace(.{21396 const new_namespace_index = try mod.createNamespace(.{
21406 .parent = block.namespace.toOptional(),21397 .parent = block.namespace.toOptional(),
21407 .ty = undefined,21398 .decl_index = new_decl_index,
21408 .file_scope = block.getFileScope(mod),21399 .file_scope = block.getFileScope(mod),
21409 });21400 });
21410 const new_namespace = mod.namespacePtr(new_namespace_index);
21411 errdefer mod.destroyNamespace(new_namespace_index);21401 errdefer mod.destroyNamespace(new_namespace_index);
2141221402
21413 const opaque_ty = try mod.intern(.{ .opaque_type = .{21403 const opaque_ty = try mod.intern(.{ .opaque_type = .{
...@@ -21420,7 +21410,6 @@ fn zirReify(...@@ -21420,7 +21410,6 @@ fn zirReify(
2142021410
21421 new_decl.ty = Type.type;21411 new_decl.ty = Type.type;
21422 new_decl.val = Value.fromInterned(opaque_ty);21412 new_decl.val = Value.fromInterned(opaque_ty);
21423 new_namespace.ty = Type.fromInterned(opaque_ty);
2142421413
21425 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);21414 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
21426 try mod.finalizeAnonDecl(new_decl_index);21415 try mod.finalizeAnonDecl(new_decl_index);
...@@ -21614,10 +21603,9 @@ fn zirReify(...@@ -21614,10 +21603,9 @@ fn zirReify(
2161421603
21615 const new_namespace_index = try mod.createNamespace(.{21604 const new_namespace_index = try mod.createNamespace(.{
21616 .parent = block.namespace.toOptional(),21605 .parent = block.namespace.toOptional(),
21617 .ty = undefined,21606 .decl_index = new_decl_index,
21618 .file_scope = block.getFileScope(mod),21607 .file_scope = block.getFileScope(mod),
21619 });21608 });
21620 const new_namespace = mod.namespacePtr(new_namespace_index);
21621 errdefer mod.destroyNamespace(new_namespace_index);21609 errdefer mod.destroyNamespace(new_namespace_index);
2162221610
21623 const union_ty = try ip.getUnionType(gpa, .{21611 const union_ty = try ip.getUnionType(gpa, .{
...@@ -21649,7 +21637,6 @@ fn zirReify(...@@ -21649,7 +21637,6 @@ fn zirReify(
2164921637
21650 new_decl.ty = Type.type;21638 new_decl.ty = Type.type;
21651 new_decl.val = Value.fromInterned(union_ty);21639 new_decl.val = Value.fromInterned(union_ty);
21652 new_namespace.ty = Type.fromInterned(union_ty);
2165321640
21654 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);21641 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
21655 try mod.finalizeAnonDecl(new_decl_index);21642 try mod.finalizeAnonDecl(new_decl_index);
...@@ -37260,7 +37247,7 @@ fn generateUnionTagTypeNumbered(...@@ -37260,7 +37247,7 @@ fn generateUnionTagTypeNumbered(
37260 const src_decl = mod.declPtr(block.src_decl);37247 const src_decl = mod.declPtr(block.src_decl);
37261 const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);37248 const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);
37262 errdefer mod.destroyDecl(new_decl_index);37249 errdefer mod.destroyDecl(new_decl_index);
37263 const fqn = try decl.getFullyQualifiedName(mod);37250 const fqn = try decl.fullyQualifiedName(mod);
37264 const name = try ip.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(ip)});37251 const name = try ip.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(ip)});
37265 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, .{37252 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, .{
37266 .ty = Type.noreturn,37253 .ty = Type.noreturn,
...@@ -37269,7 +37256,6 @@ fn generateUnionTagTypeNumbered(...@@ -37269,7 +37256,6 @@ fn generateUnionTagTypeNumbered(
37269 errdefer mod.abortAnonDecl(new_decl_index);37256 errdefer mod.abortAnonDecl(new_decl_index);
3727037257
37271 const new_decl = mod.declPtr(new_decl_index);37258 const new_decl = mod.declPtr(new_decl_index);
37272 new_decl.name_fully_qualified = true;
37273 new_decl.owns_tv = true;37259 new_decl.owns_tv = true;
37274 new_decl.name_fully_qualified = true;37260 new_decl.name_fully_qualified = true;
3727537261
...@@ -37310,7 +37296,7 @@ fn generateUnionTagTypeSimple(...@@ -37310,7 +37296,7 @@ fn generateUnionTagTypeSimple(
37310 .val = Value.@"unreachable",37296 .val = Value.@"unreachable",
37311 });37297 });
37312 };37298 };
37313 const fqn = try mod.declPtr(decl_index).getFullyQualifiedName(mod);37299 const fqn = try mod.declPtr(decl_index).fullyQualifiedName(mod);
37314 const src_decl = mod.declPtr(block.src_decl);37300 const src_decl = mod.declPtr(block.src_decl);
37315 const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);37301 const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);
37316 errdefer mod.destroyDecl(new_decl_index);37302 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 {...@@ -7223,7 +7223,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
7223 defer arena_allocator.deinit();7223 defer arena_allocator.deinit();
7224 const arena = arena_allocator.allocator();7224 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));
7227 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});7227 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});
72287228
7229 // check if we already generated code for this.7229 // check if we already generated code for this.
src/codegen/llvm.zig+11-13
...@@ -1163,7 +1163,7 @@ pub const Object = struct {...@@ -1163,7 +1163,7 @@ pub const Object = struct {
1163 const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i];1163 const fwd_ref = self.debug_unresolved_namespace_scopes.values()[i];
11641164
1165 const namespace = self.module.namespacePtr(namespace_index);1165 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
1168 self.builder.debugForwardReferenceSetType(fwd_ref, debug_type);1168 self.builder.debugForwardReferenceSetType(fwd_ref, debug_type);
1169 }1169 }
...@@ -1797,7 +1797,7 @@ pub const Object = struct {...@@ -1797,7 +1797,7 @@ pub const Object = struct {
1797 return updateExportedGlobal(self, mod, global_index, exports);1797 return updateExportedGlobal(self, mod, global_index, exports);
1798 } else {1798 } else {
1799 const fqn = try self.builder.string(1799 const fqn = try self.builder.string(
1800 mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)),1800 mod.intern_pool.stringToSlice(try decl.fullyQualifiedName(mod)),
1801 );1801 );
1802 try global_index.rename(fqn, &self.builder);1802 try global_index.rename(fqn, &self.builder);
1803 global_index.setLinkage(.internal, &self.builder);1803 global_index.setLinkage(.internal, &self.builder);
...@@ -2835,15 +2835,13 @@ pub const Object = struct {...@@ -2835,15 +2835,13 @@ pub const Object = struct {
28352835
2836 const builtin_str = try mod.intern_pool.getOrPutString(mod.gpa, "builtin");2836 const builtin_str = try mod.intern_pool.getOrPutString(mod.gpa, "builtin");
2837 const std_namespace = mod.namespacePtr(mod.declPtr(std_file.root_decl.unwrap().?).src_namespace);2837 const std_namespace = mod.namespacePtr(mod.declPtr(std_file.root_decl.unwrap().?).src_namespace);
2838 const builtin_decl = std_namespace.decls2838 const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Module.DeclAdapter{ .zcu = mod }).?;
2839 .getKeyAdapted(builtin_str, Module.DeclAdapter{ .mod = mod }).?;
28402839
2841 const stack_trace_str = try mod.intern_pool.getOrPutString(mod.gpa, "StackTrace");2840 const stack_trace_str = try mod.intern_pool.getOrPutString(mod.gpa, "StackTrace");
2842 // buffer is only used for int_type, `builtin` is a struct.2841 // buffer is only used for int_type, `builtin` is a struct.
2843 const builtin_ty = mod.declPtr(builtin_decl).val.toType();2842 const builtin_ty = mod.declPtr(builtin_decl).val.toType();
2844 const builtin_namespace = builtin_ty.getNamespace(mod).?;2843 const builtin_namespace = builtin_ty.getNamespace(mod).?;
2845 const stack_trace_decl_index = builtin_namespace.decls2844 const stack_trace_decl_index = builtin_namespace.decls.getKeyAdapted(stack_trace_str, Module.DeclAdapter{ .zcu = mod }).?;
2846 .getKeyAdapted(stack_trace_str, Module.DeclAdapter{ .mod = mod }).?;
2847 const stack_trace_decl = mod.declPtr(stack_trace_decl_index);2845 const stack_trace_decl = mod.declPtr(stack_trace_decl_index);
28482846
2849 // Sema should have ensured that StackTrace was analyzed.2847 // Sema should have ensured that StackTrace was analyzed.
...@@ -2886,7 +2884,7 @@ pub const Object = struct {...@@ -2886,7 +2884,7 @@ pub const Object = struct {
2886 try o.builder.string(ip.stringToSlice(if (is_extern)2884 try o.builder.string(ip.stringToSlice(if (is_extern)
2887 decl.name2885 decl.name
2888 else2886 else
2889 try decl.getFullyQualifiedName(zcu))),2887 try decl.fullyQualifiedName(zcu))),
2890 toLlvmAddressSpace(decl.@"addrspace", target),2888 toLlvmAddressSpace(decl.@"addrspace", target),
2891 );2889 );
2892 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;2890 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
...@@ -3100,7 +3098,7 @@ pub const Object = struct {...@@ -3100,7 +3098,7 @@ pub const Object = struct {
31003098
3101 const variable_index = try o.builder.addVariable(3099 const variable_index = try o.builder.addVariable(
3102 try o.builder.string(mod.intern_pool.stringToSlice(3100 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),
3104 )),3102 )),
3105 try o.lowerType(decl.ty),3103 try o.lowerType(decl.ty),
3106 toLlvmGlobalAddressSpace(decl.@"addrspace", mod.getTarget()),3104 toLlvmGlobalAddressSpace(decl.@"addrspace", mod.getTarget()),
...@@ -3325,7 +3323,7 @@ pub const Object = struct {...@@ -3325,7 +3323,7 @@ pub const Object = struct {
3325 }3323 }
33263324
3327 const name = try o.builder.string(ip.stringToSlice(3325 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),
3329 ));3327 ));
33303328
3331 var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};3329 var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};
...@@ -3481,7 +3479,7 @@ pub const Object = struct {...@@ -3481,7 +3479,7 @@ pub const Object = struct {
3481 }3479 }
34823480
3483 const name = try o.builder.string(ip.stringToSlice(3481 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),
3485 ));3483 ));
34863484
3487 const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);3485 const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);
...@@ -4599,7 +4597,7 @@ pub const Object = struct {...@@ -4599,7 +4597,7 @@ pub const Object = struct {
45994597
4600 const usize_ty = try o.lowerType(Type.usize);4598 const usize_ty = try o.lowerType(Type.usize);
4601 const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);4599 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);
4603 const target = zcu.root_mod.resolved_target.result;4601 const target = zcu.root_mod.resolved_target.result;
4604 const function_index = try o.builder.addFunction(4602 const function_index = try o.builder.addFunction(
4605 try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),4603 try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
...@@ -6613,7 +6611,7 @@ pub const FuncGen = struct {...@@ -6613,7 +6611,7 @@ pub const FuncGen = struct {
6613 .base_line = self.base_line,6611 .base_line = self.base_line,
6614 });6612 });
66156613
6616 const fqn = try decl.getFullyQualifiedName(zcu);6614 const fqn = try decl.fullyQualifiedName(zcu);
66176615
6618 const is_internal_linkage = !zcu.decl_exports.contains(decl_index);6616 const is_internal_linkage = !zcu.decl_exports.contains(decl_index);
6619 const fn_ty = try zcu.funcType(.{6617 const fn_ty = try zcu.funcType(.{
...@@ -9643,7 +9641,7 @@ pub const FuncGen = struct {...@@ -9643,7 +9641,7 @@ pub const FuncGen = struct {
9643 if (gop.found_existing) return gop.value_ptr.*;9641 if (gop.found_existing) return gop.value_ptr.*;
9644 errdefer assert(o.named_enum_map.remove(enum_type.decl));9642 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);
9647 const target = zcu.root_mod.resolved_target.result;9645 const target = zcu.root_mod.resolved_target.result;
9648 const function_index = try o.builder.addFunction(9646 const function_index = try o.builder.addFunction(
9649 try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),9647 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 {...@@ -2019,7 +2019,7 @@ const DeclGen = struct {
2019 // Append the actual code into the functions section.2019 // Append the actual code into the functions section.
2020 try self.spv.addFunction(spv_decl_index, self.func);2020 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));
2023 try self.spv.debugName(decl_id, fqn);2023 try self.spv.debugName(decl_id, fqn);
20242024
2025 // Temporarily generate a test kernel declaration if this is a test function.2025 // Temporarily generate a test kernel declaration if this is a test function.
...@@ -2055,7 +2055,7 @@ const DeclGen = struct {...@@ -2055,7 +2055,7 @@ const DeclGen = struct {
2055 .id_result = decl_id,2055 .id_result = decl_id,
2056 .storage_class = actual_storage_class,2056 .storage_class = actual_storage_class,
2057 });2057 });
2058 const fqn = ip.stringToSlice(try decl.getFullyQualifiedName(self.module));2058 const fqn = ip.stringToSlice(try decl.fullyQualifiedName(self.module));
2059 try self.spv.debugName(decl_id, fqn);2059 try self.spv.debugName(decl_id, fqn);
20602060
2061 if (opt_init_val) |init_val| {2061 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...@@ -1176,7 +1176,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: InternPool.Dec
1176 gop.value_ptr.* = .{};1176 gop.value_ptr.* = .{};
1177 }1177 }
1178 const unnamed_consts = gop.value_ptr;1178 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));
1180 const index = unnamed_consts.items.len;1180 const index = unnamed_consts.items.len;
1181 const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });1181 const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
1182 defer gpa.free(sym_name);1182 defer gpa.free(sym_name);
...@@ -1427,7 +1427,7 @@ fn updateDeclCode(self: *Coff, decl_index: InternPool.DeclIndex, code: []u8, com...@@ -1427,7 +1427,7 @@ fn updateDeclCode(self: *Coff, decl_index: InternPool.DeclIndex, code: []u8, com
1427 const mod = self.base.comp.module.?;1427 const mod = self.base.comp.module.?;
1428 const decl = mod.declPtr(decl_index);1428 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
1432 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });1432 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
1433 const required_alignment: u32 = @intCast(decl.getAlignment(mod).toByteUnits(0));1433 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...@@ -1082,7 +1082,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde
1082 defer tracy.end();1082 defer tracy.end();
10831083
1084 const decl = mod.declPtr(decl_index);1084 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
1087 log.debug("initDeclState {}{*}", .{ decl_linkage_name.fmt(&mod.intern_pool), decl });1087 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(...@@ -903,7 +903,7 @@ fn updateDeclCode(
903 const gpa = elf_file.base.comp.gpa;903 const gpa = elf_file.base.comp.gpa;
904 const mod = elf_file.base.comp.module.?;904 const mod = elf_file.base.comp.module.?;
905 const decl = mod.declPtr(decl_index);905 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
908 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });908 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
909909
...@@ -1001,7 +1001,7 @@ fn updateTlv(...@@ -1001,7 +1001,7 @@ fn updateTlv(
1001 const gpa = elf_file.base.comp.gpa;1001 const gpa = elf_file.base.comp.gpa;
1002 const mod = elf_file.base.comp.module.?;1002 const mod = elf_file.base.comp.module.?;
1003 const decl = mod.declPtr(decl_index);1003 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
1006 log.debug("updateTlv {s} ({*})", .{ decl_name, decl });1006 log.debug("updateTlv {s} ({*})", .{ decl_name, decl });
10071007
...@@ -1300,7 +1300,7 @@ pub fn lowerUnnamedConst(...@@ -1300,7 +1300,7 @@ pub fn lowerUnnamedConst(
1300 }1300 }
1301 const unnamed_consts = gop.value_ptr;1301 const unnamed_consts = gop.value_ptr;
1302 const decl = mod.declPtr(decl_index);1302 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));
1304 const index = unnamed_consts.items.len;1304 const index = unnamed_consts.items.len;
1305 const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });1305 const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
1306 defer gpa.free(name);1306 defer gpa.free(name);
...@@ -1482,7 +1482,7 @@ pub fn updateDeclLineNumber(...@@ -1482,7 +1482,7 @@ pub fn updateDeclLineNumber(
1482 defer tracy.end();1482 defer tracy.end();
14831483
1484 const decl = mod.declPtr(decl_index);1484 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
1487 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });1487 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });
14881488
src/link/MachO/ZigObject.zig+3-3
...@@ -792,7 +792,7 @@ fn updateDeclCode(...@@ -792,7 +792,7 @@ fn updateDeclCode(
792 const gpa = macho_file.base.comp.gpa;792 const gpa = macho_file.base.comp.gpa;
793 const mod = macho_file.base.comp.module.?;793 const mod = macho_file.base.comp.module.?;
794 const decl = mod.declPtr(decl_index);794 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
797 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });797 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
798798
...@@ -876,7 +876,7 @@ fn updateTlv(...@@ -876,7 +876,7 @@ fn updateTlv(
876) !void {876) !void {
877 const mod = macho_file.base.comp.module.?;877 const mod = macho_file.base.comp.module.?;
878 const decl = mod.declPtr(decl_index);878 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
881 log.debug("updateTlv {s} ({*})", .{ decl_name, decl });881 log.debug("updateTlv {s} ({*})", .{ decl_name, decl });
882882
...@@ -1079,7 +1079,7 @@ pub fn lowerUnnamedConst(...@@ -1079,7 +1079,7 @@ pub fn lowerUnnamedConst(
1079 }1079 }
1080 const unnamed_consts = gop.value_ptr;1080 const unnamed_consts = gop.value_ptr;
1081 const decl = mod.declPtr(decl_index);1081 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));
1083 const index = unnamed_consts.items.len;1083 const index = unnamed_consts.items.len;
1084 const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });1084 const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
1085 defer gpa.free(name);1085 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...@@ -478,7 +478,7 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: InternPool.De
478 }478 }
479 const unnamed_consts = gop.value_ptr;479 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
483 const index = unnamed_consts.items.len;483 const index = unnamed_consts.items.len;
484 // name is freed when the unnamed const is freed484 // 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...@@ -662,7 +662,7 @@ pub fn getOrCreateAtomForDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) !At
662 const symbol = atom.symbolLoc().getSymbol(wasm);662 const symbol = atom.symbolLoc().getSymbol(wasm);
663 const mod = wasm.base.comp.module.?;663 const mod = wasm.base.comp.module.?;
664 const decl = mod.declPtr(decl_index);664 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));
666 symbol.name = try wasm.string_table.put(gpa, full_name);666 symbol.name = try wasm.string_table.put(gpa, full_name);
667 }667 }
668 return gop.value_ptr.*;668 return gop.value_ptr.*;
...@@ -1598,7 +1598,7 @@ pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl_index: InternPool.De...@@ -1598,7 +1598,7 @@ pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl_index: InternPool.De
1598 defer tracy.end();1598 defer tracy.end();
15991599
1600 const decl = mod.declPtr(decl_index);1600 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
1603 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });1603 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });
1604 try dw.updateDeclLineNumber(mod, decl_index);1604 try dw.updateDeclLineNumber(mod, decl_index);
...@@ -1612,7 +1612,7 @@ fn finishUpdateDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex, code: []const...@@ -1612,7 +1612,7 @@ fn finishUpdateDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex, code: []const
1612 const atom_index = wasm.decls.get(decl_index).?;1612 const atom_index = wasm.decls.get(decl_index).?;
1613 const atom = wasm.getAtomPtr(atom_index);1613 const atom = wasm.getAtomPtr(atom_index);
1614 const symbol = &wasm.symbols.items[atom.sym_index];1614 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));
1616 symbol.name = try wasm.string_table.put(gpa, full_name);1616 symbol.name = try wasm.string_table.put(gpa, full_name);
1617 symbol.tag = symbol_tag;1617 symbol.tag = symbol_tag;
1618 try atom.code.appendSlice(gpa, code);1618 try atom.code.appendSlice(gpa, code);
...@@ -1678,7 +1678,7 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: InternPool.Dec...@@ -1678,7 +1678,7 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: InternPool.Dec
1678 const parent_atom_index = try wasm.getOrCreateAtomForDecl(decl_index);1678 const parent_atom_index = try wasm.getOrCreateAtomForDecl(decl_index);
1679 const parent_atom = wasm.getAtom(parent_atom_index);1679 const parent_atom = wasm.getAtom(parent_atom_index);
1680 const local_index = parent_atom.locals.items.len;1680 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));
1682 const name = try std.fmt.allocPrintZ(gpa, "__unnamed_{s}_{d}", .{1682 const name = try std.fmt.allocPrintZ(gpa, "__unnamed_{s}_{d}", .{
1683 fqn, local_index,1683 fqn, local_index,
1684 });1684 });
src/main.zig+15-18
...@@ -596,7 +596,7 @@ const usage_build_generic =...@@ -596,7 +596,7 @@ const usage_build_generic =
596 \\ --export=[value] (WebAssembly) Force a symbol to be exported596 \\ --export=[value] (WebAssembly) Force a symbol to be exported
597 \\597 \\
598 \\Test Options:598 \\Test Options:
599 \\ --test-filter [text] Skip tests that do not match filter599 \\ --test-filter [text] Skip tests that do not match any filter
600 \\ --test-name-prefix [text] Add prefix to all tests600 \\ --test-name-prefix [text] Add prefix to all tests
601 \\ --test-cmd [arg] Specify test execution command one arg at a time601 \\ --test-cmd [arg] Specify test execution command one arg at a time
602 \\ --test-cmd-bin Appends test binary path to test cmd args602 \\ --test-cmd-bin Appends test binary path to test cmd args
...@@ -869,7 +869,7 @@ fn buildOutputType(...@@ -869,7 +869,7 @@ fn buildOutputType(
869 var link_emit_relocs = false;869 var link_emit_relocs = false;
870 var build_id: ?std.zig.BuildId = null;870 var build_id: ?std.zig.BuildId = null;
871 var runtime_args_start: ?usize = null;871 var runtime_args_start: ?usize = null;
872 var test_filter: ?[]const u8 = null;872 var test_filters: std.ArrayListUnmanaged([]const u8) = .{};
873 var test_name_prefix: ?[]const u8 = null;873 var test_name_prefix: ?[]const u8 = null;
874 var test_runner_path: ?[]const u8 = null;874 var test_runner_path: ?[]const u8 = null;
875 var override_local_cache_dir: ?[]const u8 = try EnvVar.ZIG_LOCAL_CACHE_DIR.get(arena);875 var override_local_cache_dir: ?[]const u8 = try EnvVar.ZIG_LOCAL_CACHE_DIR.get(arena);
...@@ -909,7 +909,7 @@ fn buildOutputType(...@@ -909,7 +909,7 @@ fn buildOutputType(
909 var rc_source_files_owner_index: usize = 0;909 var rc_source_files_owner_index: usize = 0;
910910
911 // null means replace with the test executable binary911 // 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
914 // These get set by CLI flags and then snapshotted when a `--mod` flag is914 // These get set by CLI flags and then snapshotted when a `--mod` flag is
915 // encountered.915 // encountered.
...@@ -1278,13 +1278,13 @@ fn buildOutputType(...@@ -1278,13 +1278,13 @@ fn buildOutputType(
1278 } else if (mem.eql(u8, arg, "--libc")) {1278 } else if (mem.eql(u8, arg, "--libc")) {
1279 create_module.libc_paths_file = args_iter.nextOrFatal();1279 create_module.libc_paths_file = args_iter.nextOrFatal();
1280 } else if (mem.eql(u8, arg, "--test-filter")) {1280 } else if (mem.eql(u8, arg, "--test-filter")) {
1281 test_filter = args_iter.nextOrFatal();1281 try test_filters.append(arena, args_iter.nextOrFatal());
1282 } else if (mem.eql(u8, arg, "--test-name-prefix")) {1282 } else if (mem.eql(u8, arg, "--test-name-prefix")) {
1283 test_name_prefix = args_iter.nextOrFatal();1283 test_name_prefix = args_iter.nextOrFatal();
1284 } else if (mem.eql(u8, arg, "--test-runner")) {1284 } else if (mem.eql(u8, arg, "--test-runner")) {
1285 test_runner_path = args_iter.nextOrFatal();1285 test_runner_path = args_iter.nextOrFatal();
1286 } else if (mem.eql(u8, arg, "--test-cmd")) {1286 } 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());
1288 } else if (mem.eql(u8, arg, "--cache-dir")) {1288 } else if (mem.eql(u8, arg, "--cache-dir")) {
1289 override_local_cache_dir = args_iter.nextOrFatal();1289 override_local_cache_dir = args_iter.nextOrFatal();
1290 } else if (mem.eql(u8, arg, "--global-cache-dir")) {1290 } else if (mem.eql(u8, arg, "--global-cache-dir")) {
...@@ -1334,7 +1334,7 @@ fn buildOutputType(...@@ -1334,7 +1334,7 @@ fn buildOutputType(
1334 } else if (mem.eql(u8, arg, "-fno-each-lib-rpath")) {1334 } else if (mem.eql(u8, arg, "-fno-each-lib-rpath")) {
1335 create_module.each_lib_rpath = false;1335 create_module.each_lib_rpath = false;
1336 } else if (mem.eql(u8, arg, "--test-cmd-bin")) {1336 } else if (mem.eql(u8, arg, "--test-cmd-bin")) {
1337 try test_exec_args.append(null);1337 try test_exec_args.append(arena, null);
1338 } else if (mem.eql(u8, arg, "--test-no-exec")) {1338 } else if (mem.eql(u8, arg, "--test-no-exec")) {
1339 test_no_exec = true;1339 test_no_exec = true;
1340 } else if (mem.eql(u8, arg, "-ftime-report")) {1340 } else if (mem.eql(u8, arg, "-ftime-report")) {
...@@ -3246,7 +3246,7 @@ fn buildOutputType(...@@ -3246,7 +3246,7 @@ fn buildOutputType(
3246 .time_report = time_report,3246 .time_report = time_report,
3247 .stack_report = stack_report,3247 .stack_report = stack_report,
3248 .build_id = build_id,3248 .build_id = build_id,
3249 .test_filter = test_filter,3249 .test_filters = test_filters.items,
3250 .test_name_prefix = test_name_prefix,3250 .test_name_prefix = test_name_prefix,
3251 .test_runner_path = test_runner_path,3251 .test_runner_path = test_runner_path,
3252 .disable_lld_caching = disable_lld_caching,3252 .disable_lld_caching = disable_lld_caching,
...@@ -3369,16 +3369,15 @@ fn buildOutputType(...@@ -3369,16 +3369,15 @@ fn buildOutputType(
3369 const c_code_path = try fs.path.join(arena, &[_][]const u8{3369 const c_code_path = try fs.path.join(arena, &[_][]const u8{
3370 c_code_directory.path orelse ".", c_code_loc.basename,3370 c_code_directory.path orelse ".", c_code_loc.basename,
3371 });3371 });
3372 try test_exec_args.append(self_exe_path);3372 try test_exec_args.appendSlice(arena, &.{ self_exe_path, "run" });
3373 try test_exec_args.append("run");
3374 if (zig_lib_directory.path) |p| {3373 if (zig_lib_directory.path) |p| {
3375 try test_exec_args.appendSlice(&.{ "-I", p });3374 try test_exec_args.appendSlice(arena, &.{ "-I", p });
3376 }3375 }
33773376
3378 if (create_module.resolved_options.link_libc) {3377 if (create_module.resolved_options.link_libc) {
3379 try test_exec_args.append("-lc");3378 try test_exec_args.append(arena, "-lc");
3380 } else if (target.os.tag == .windows) {3379 } else if (target.os.tag == .windows) {
3381 try test_exec_args.appendSlice(&.{3380 try test_exec_args.appendSlice(arena, &.{
3382 "--subsystem", "console",3381 "--subsystem", "console",
3383 "-lkernel32", "-lntdll",3382 "-lkernel32", "-lntdll",
3384 });3383 });
...@@ -3386,17 +3385,15 @@ fn buildOutputType(...@@ -3386,17 +3385,15 @@ fn buildOutputType(
33863385
3387 const first_cli_mod = create_module.modules.values()[0];3386 const first_cli_mod = create_module.modules.values()[0];
3388 if (first_cli_mod.target_arch_os_abi) |triple| {3387 if (first_cli_mod.target_arch_os_abi) |triple| {
3389 try test_exec_args.append("-target");3388 try test_exec_args.appendSlice(arena, &.{ "-target", triple });
3390 try test_exec_args.append(triple);
3391 }3389 }
3392 if (first_cli_mod.target_mcpu) |mcpu| {3390 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}));
3394 }3392 }
3395 if (create_module.dynamic_linker) |dl| {3393 if (create_module.dynamic_linker) |dl| {
3396 try test_exec_args.append("--dynamic-linker");3394 try test_exec_args.appendSlice(arena, &.{ "--dynamic-linker", dl });
3397 try test_exec_args.append(dl);
3398 }3395 }
3399 try test_exec_args.append(c_code_path);3396 try test_exec_args.append(arena, c_code_path);
3400 }3397 }
34013398
3402 const run_or_test = switch (arg_mode) {3399 const run_or_test = switch (arg_mode) {
test/src/Cases.zig+16-16
...@@ -537,7 +537,7 @@ pub fn lowerToBuildSteps(...@@ -537,7 +537,7 @@ pub fn lowerToBuildSteps(
537 self: *Cases,537 self: *Cases,
538 b: *std.Build,538 b: *std.Build,
539 parent_step: *std.Build.Step,539 parent_step: *std.Build.Step,
540 opt_test_filter: ?[]const u8,540 test_filters: []const []const u8,
541 cases_dir_path: []const u8,541 cases_dir_path: []const u8,
542 incremental_exe: *std.Build.Step.Compile,542 incremental_exe: *std.Build.Step.Compile,
543) void {543) void {
...@@ -552,9 +552,9 @@ pub fn lowerToBuildSteps(...@@ -552,9 +552,9 @@ pub fn lowerToBuildSteps(
552 // compilation is in a happier state.552 // compilation is in a happier state.
553 continue;553 continue;
554 }554 }
555 if (opt_test_filter) |test_filter| {555 for (test_filters) |test_filter| {
556 if (std.mem.indexOf(u8, incr_case.base_path, test_filter) == null) continue;556 if (std.mem.indexOf(u8, incr_case.base_path, test_filter)) |_| break;
557 }557 } else if (test_filters.len > 0) continue;
558 const case_base_path_with_dir = std.fs.path.join(b.allocator, &.{558 const case_base_path_with_dir = std.fs.path.join(b.allocator, &.{
559 cases_dir_path, incr_case.base_path,559 cases_dir_path, incr_case.base_path,
560 }) catch @panic("OOM");560 }) catch @panic("OOM");
...@@ -573,9 +573,9 @@ pub fn lowerToBuildSteps(...@@ -573,9 +573,9 @@ pub fn lowerToBuildSteps(
573 assert(case.updates.items.len == 1);573 assert(case.updates.items.len == 1);
574 const update = case.updates.items[0];574 const update = case.updates.items[0];
575575
576 if (opt_test_filter) |test_filter| {576 for (test_filters) |test_filter| {
577 if (std.mem.indexOf(u8, case.name, test_filter) == null) continue;577 if (std.mem.indexOf(u8, case.name, test_filter)) |_| break;
578 }578 } else if (test_filters.len > 0) continue;
579579
580 const writefiles = b.addWriteFiles();580 const writefiles = b.addWriteFiles();
581 var file_sources = std.StringHashMap(std.Build.LazyPath).init(b.allocator);581 var file_sources = std.StringHashMap(std.Build.LazyPath).init(b.allocator);
...@@ -685,9 +685,9 @@ pub fn lowerToBuildSteps(...@@ -685,9 +685,9 @@ pub fn lowerToBuildSteps(
685 for (self.translate.items) |case| switch (case.kind) {685 for (self.translate.items) |case| switch (case.kind) {
686 .run => |output| {686 .run => |output| {
687 const annotated_case_name = b.fmt("run-translated-c {s}", .{case.name});687 const annotated_case_name = b.fmt("run-translated-c {s}", .{case.name});
688 if (opt_test_filter) |filter| {688 for (test_filters) |test_filter| {
689 if (std.mem.indexOf(u8, annotated_case_name, filter) == null) continue;689 if (std.mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
690 }690 } else if (test_filters.len > 0) continue;
691 if (!std.process.can_spawn) {691 if (!std.process.can_spawn) {
692 std.debug.print("Unable to spawn child processes on {s}, skipping test.\n", .{@tagName(builtin.os.tag)});692 std.debug.print("Unable to spawn child processes on {s}, skipping test.\n", .{@tagName(builtin.os.tag)});
693 continue; // Pass test.693 continue; // Pass test.
...@@ -721,9 +721,9 @@ pub fn lowerToBuildSteps(...@@ -721,9 +721,9 @@ pub fn lowerToBuildSteps(
721 },721 },
722 .translate => |output| {722 .translate => |output| {
723 const annotated_case_name = b.fmt("zig translate-c {s}", .{case.name});723 const annotated_case_name = b.fmt("zig translate-c {s}", .{case.name});
724 if (opt_test_filter) |filter| {724 for (test_filters) |test_filter| {
725 if (std.mem.indexOf(u8, annotated_case_name, filter) == null) continue;725 if (std.mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
726 }726 } else if (test_filters.len > 0) continue;
727727
728 const write_src = b.addWriteFiles();728 const write_src = b.addWriteFiles();
729 const file_source = write_src.add("tmp.c", case.input);729 const file_source = write_src.add("tmp.c", case.input);
...@@ -1440,9 +1440,9 @@ fn runCases(self: *Cases, zig_exe_path: []const u8) !void {...@@ -1440,9 +1440,9 @@ fn runCases(self: *Cases, zig_exe_path: []const u8) !void {
14401440
1441 assert(case.backend != .stage1);1441 assert(case.backend != .stage1);
14421442
1443 if (build_options.test_filter) |test_filter| {1443 for (build_options.test_filters) |test_filter| {
1444 if (std.mem.indexOf(u8, case.name, test_filter) == null) continue;1444 if (std.mem.indexOf(u8, case.name, test_filter)) |_| break;
1445 }1445 } else if (build_options.test_filters.len > 0) continue;
14461446
1447 var prg_node = root_node.start(case.name, case.updates.items.len);1447 var prg_node = root_node.start(case.name, case.updates.items.len);
1448 prg_node.activate();1448 prg_node.activate();
test/src/CompareOutput.zig+10-10
...@@ -4,7 +4,7 @@...@@ -4,7 +4,7 @@
4b: *std.Build,4b: *std.Build,
5step: *std.Build.Step,5step: *std.Build.Step,
6test_index: usize,6test_index: usize,
7test_filter: ?[]const u8,7test_filters: []const []const u8,
8optimize_modes: []const OptimizeMode,8optimize_modes: []const OptimizeMode,
99
10const Special = enum {10const Special = enum {
...@@ -90,9 +90,9 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {...@@ -90,9 +90,9 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {
90 const annotated_case_name = fmt.allocPrint(self.b.allocator, "run assemble-and-link {s}", .{90 const annotated_case_name = fmt.allocPrint(self.b.allocator, "run assemble-and-link {s}", .{
91 case.name,91 case.name,
92 }) catch @panic("OOM");92 }) catch @panic("OOM");
93 if (self.test_filter) |filter| {93 for (self.test_filters) |test_filter| {
94 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;94 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
95 }95 } else if (self.test_filters.len > 0) return;
9696
97 const exe = b.addExecutable(.{97 const exe = b.addExecutable(.{
98 .name = "test",98 .name = "test",
...@@ -113,9 +113,9 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {...@@ -113,9 +113,9 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {
113 const annotated_case_name = fmt.allocPrint(self.b.allocator, "run compare-output {s} ({s})", .{113 const annotated_case_name = fmt.allocPrint(self.b.allocator, "run compare-output {s} ({s})", .{
114 case.name, @tagName(optimize),114 case.name, @tagName(optimize),
115 }) catch @panic("OOM");115 }) catch @panic("OOM");
116 if (self.test_filter) |filter| {116 for (self.test_filters) |test_filter| {
117 if (mem.indexOf(u8, annotated_case_name, filter) == null) continue;117 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
118 }118 } else if (self.test_filters.len > 0) return;
119119
120 const exe = b.addExecutable(.{120 const exe = b.addExecutable(.{
121 .name = "test",121 .name = "test",
...@@ -139,9 +139,9 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {...@@ -139,9 +139,9 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {
139 // TODO iterate over self.optimize_modes and test this in both139 // TODO iterate over self.optimize_modes and test this in both
140 // debug and release safe mode140 // debug and release safe mode
141 const annotated_case_name = fmt.allocPrint(self.b.allocator, "run safety {s}", .{case.name}) catch @panic("OOM");141 const annotated_case_name = fmt.allocPrint(self.b.allocator, "run safety {s}", .{case.name}) catch @panic("OOM");
142 if (self.test_filter) |filter| {142 for (self.test_filters) |test_filter| {
143 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;143 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
144 }144 } else if (self.test_filters.len > 0) return;
145145
146 const exe = b.addExecutable(.{146 const exe = b.addExecutable(.{
147 .name = "test",147 .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 @@...@@ -1,7 +1,7 @@
1b: *std.Build,1b: *std.Build,
2step: *Step,2step: *Step,
3test_index: usize,3test_index: usize,
4test_filter: ?[]const u8,4test_filters: []const []const u8,
5optimize_modes: []const OptimizeMode,5optimize_modes: []const OptimizeMode,
6check_exe: *std.Build.Step.Compile,6check_exe: *std.Build.Step.Compile,
77
...@@ -47,9 +47,9 @@ fn addExpect(...@@ -47,9 +47,9 @@ fn addExpect(
47 const annotated_case_name = fmt.allocPrint(b.allocator, "check {s} ({s})", .{47 const annotated_case_name = fmt.allocPrint(b.allocator, "check {s} ({s})", .{
48 name, @tagName(optimize_mode),48 name, @tagName(optimize_mode),
49 }) catch @panic("OOM");49 }) catch @panic("OOM");
50 if (self.test_filter) |filter| {50 for (self.test_filters) |test_filter| {
51 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;51 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
52 }52 } else if (self.test_filters.len > 0) return;
5353
54 const write_src = b.addWriteFile("source.zig", source);54 const write_src = b.addWriteFile("source.zig", source);
55 const exe = b.addExecutable(.{55 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");...@@ -15,8 +15,8 @@ const run_translated_c = @import("run_translated_c.zig");
15const link = @import("link.zig");15const link = @import("link.zig");
1616
17// Implementations17// Implementations
18pub const TranslateCContext = @import("src/translate_c.zig").TranslateCContext;18pub const TranslateCContext = @import("src/TranslateC.zig");
19pub const RunTranslatedCContext = @import("src/run_translated_c.zig").RunTranslatedCContext;19pub const RunTranslatedCContext = @import("src/RunTranslatedC.zig");
20pub const CompareOutputContext = @import("src/CompareOutput.zig");20pub const CompareOutputContext = @import("src/CompareOutput.zig");
21pub const StackTracesContext = @import("src/StackTrace.zig");21pub const StackTracesContext = @import("src/StackTrace.zig");
2222
...@@ -619,7 +619,7 @@ const c_abi_targets = [_]CAbiTarget{...@@ -619,7 +619,7 @@ const c_abi_targets = [_]CAbiTarget{
619619
620pub fn addCompareOutputTests(620pub fn addCompareOutputTests(
621 b: *std.Build,621 b: *std.Build,
622 test_filter: ?[]const u8,622 test_filters: []const []const u8,
623 optimize_modes: []const OptimizeMode,623 optimize_modes: []const OptimizeMode,
624) *Step {624) *Step {
625 const cases = b.allocator.create(CompareOutputContext) catch @panic("OOM");625 const cases = b.allocator.create(CompareOutputContext) catch @panic("OOM");
...@@ -627,7 +627,7 @@ pub fn addCompareOutputTests(...@@ -627,7 +627,7 @@ pub fn addCompareOutputTests(
627 .b = b,627 .b = b,
628 .step = b.step("test-compare-output", "Run the compare output tests"),628 .step = b.step("test-compare-output", "Run the compare output tests"),
629 .test_index = 0,629 .test_index = 0,
630 .test_filter = test_filter,630 .test_filters = test_filters,
631 .optimize_modes = optimize_modes,631 .optimize_modes = optimize_modes,
632 };632 };
633633
...@@ -638,7 +638,7 @@ pub fn addCompareOutputTests(...@@ -638,7 +638,7 @@ pub fn addCompareOutputTests(
638638
639pub fn addStackTraceTests(639pub fn addStackTraceTests(
640 b: *std.Build,640 b: *std.Build,
641 test_filter: ?[]const u8,641 test_filters: []const []const u8,
642 optimize_modes: []const OptimizeMode,642 optimize_modes: []const OptimizeMode,
643) *Step {643) *Step {
644 const check_exe = b.addExecutable(.{644 const check_exe = b.addExecutable(.{
...@@ -653,7 +653,7 @@ pub fn addStackTraceTests(...@@ -653,7 +653,7 @@ pub fn addStackTraceTests(
653 .b = b,653 .b = b,
654 .step = b.step("test-stack-traces", "Run the stack trace tests"),654 .step = b.step("test-stack-traces", "Run the stack trace tests"),
655 .test_index = 0,655 .test_index = 0,
656 .test_filter = test_filter,656 .test_filters = test_filters,
657 .optimize_modes = optimize_modes,657 .optimize_modes = optimize_modes,
658 .check_exe = check_exe,658 .check_exe = check_exe,
659 };659 };
...@@ -983,13 +983,13 @@ pub fn addCliTests(b: *std.Build) *Step {...@@ -983,13 +983,13 @@ pub fn addCliTests(b: *std.Build) *Step {
983 return step;983 return step;
984}984}
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 {
987 const cases = b.allocator.create(CompareOutputContext) catch @panic("OOM");987 const cases = b.allocator.create(CompareOutputContext) catch @panic("OOM");
988 cases.* = CompareOutputContext{988 cases.* = CompareOutputContext{
989 .b = b,989 .b = b,
990 .step = b.step("test-asm-link", "Run the assemble and link tests"),990 .step = b.step("test-asm-link", "Run the assemble and link tests"),
991 .test_index = 0,991 .test_index = 0,
992 .test_filter = test_filter,992 .test_filters = test_filters,
993 .optimize_modes = optimize_modes,993 .optimize_modes = optimize_modes,
994 };994 };
995995
...@@ -998,13 +998,13 @@ pub fn addAssembleAndLinkTests(b: *std.Build, test_filter: ?[]const u8, optimize...@@ -998,13 +998,13 @@ pub fn addAssembleAndLinkTests(b: *std.Build, test_filter: ?[]const u8, optimize
998 return cases.step;998 return cases.step;
999}999}
10001000
1001pub fn addTranslateCTests(b: *std.Build, test_filter: ?[]const u8) *Step {1001pub fn addTranslateCTests(b: *std.Build, test_filters: []const []const u8) *Step {
1002 const cases = b.allocator.create(TranslateCContext) catch @panic("OOM");1002 const cases = b.allocator.create(TranslateCContext) catch @panic("OOM");
1003 cases.* = TranslateCContext{1003 cases.* = TranslateCContext{
1004 .b = b,1004 .b = b,
1005 .step = b.step("test-translate-c", "Run the C translation tests"),1005 .step = b.step("test-translate-c", "Run the C translation tests"),
1006 .test_index = 0,1006 .test_index = 0,
1007 .test_filter = test_filter,1007 .test_filters = test_filters,
1008 };1008 };
10091009
1010 translate_c.addCases(cases);1010 translate_c.addCases(cases);
...@@ -1014,7 +1014,7 @@ pub fn addTranslateCTests(b: *std.Build, test_filter: ?[]const u8) *Step {...@@ -1014,7 +1014,7 @@ pub fn addTranslateCTests(b: *std.Build, test_filter: ?[]const u8) *Step {
10141014
1015pub fn addRunTranslatedCTests(1015pub fn addRunTranslatedCTests(
1016 b: *std.Build,1016 b: *std.Build,
1017 test_filter: ?[]const u8,1017 test_filters: []const []const u8,
1018 target: std.Build.ResolvedTarget,1018 target: std.Build.ResolvedTarget,
1019) *Step {1019) *Step {
1020 const cases = b.allocator.create(RunTranslatedCContext) catch @panic("OOM");1020 const cases = b.allocator.create(RunTranslatedCContext) catch @panic("OOM");
...@@ -1022,7 +1022,7 @@ pub fn addRunTranslatedCTests(...@@ -1022,7 +1022,7 @@ pub fn addRunTranslatedCTests(
1022 .b = b,1022 .b = b,
1023 .step = b.step("test-run-translated-c", "Run the Run-Translated-C tests"),1023 .step = b.step("test-run-translated-c", "Run the Run-Translated-C tests"),
1024 .test_index = 0,1024 .test_index = 0,
1025 .test_filter = test_filter,1025 .test_filters = test_filters,
1026 .target = target,1026 .target = target,
1027 };1027 };
10281028
...@@ -1032,7 +1032,7 @@ pub fn addRunTranslatedCTests(...@@ -1032,7 +1032,7 @@ pub fn addRunTranslatedCTests(
1032}1032}
10331033
1034const ModuleTestOptions = struct {1034const ModuleTestOptions = struct {
1035 test_filter: ?[]const u8,1035 test_filters: []const []const u8,
1036 root_src: []const u8,1036 root_src: []const u8,
1037 name: []const u8,1037 name: []const u8,
1038 desc: []const u8,1038 desc: []const u8,
...@@ -1115,7 +1115,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {...@@ -1115,7 +1115,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
1115 .optimize = test_target.optimize_mode,1115 .optimize = test_target.optimize_mode,
1116 .target = resolved_target,1116 .target = resolved_target,
1117 .max_rss = max_rss,1117 .max_rss = max_rss,
1118 .filter = options.test_filter,1118 .filters = options.test_filters,
1119 .link_libc = test_target.link_libc,1119 .link_libc = test_target.link_libc,
1120 .single_threaded = test_target.single_threaded,1120 .single_threaded = test_target.single_threaded,
1121 .use_llvm = test_target.use_llvm,1121 .use_llvm = test_target.use_llvm,
...@@ -1291,7 +1291,7 @@ pub fn addCAbiTests(b: *std.Build, skip_non_native: bool, skip_release: bool) *S...@@ -1291,7 +1291,7 @@ pub fn addCAbiTests(b: *std.Build, skip_non_native: bool, skip_release: bool) *S
1291pub fn addCases(1291pub fn addCases(
1292 b: *std.Build,1292 b: *std.Build,
1293 parent_step: *Step,1293 parent_step: *Step,
1294 opt_test_filter: ?[]const u8,1294 test_filters: []const []const u8,
1295 check_case_exe: *std.Build.Step.Compile,1295 check_case_exe: *std.Build.Step.Compile,
1296 build_options: @import("cases.zig").BuildOptions,1296 build_options: @import("cases.zig").BuildOptions,
1297) !void {1297) !void {
...@@ -1310,7 +1310,7 @@ pub fn addCases(...@@ -1310,7 +1310,7 @@ pub fn addCases(
1310 cases.lowerToBuildSteps(1310 cases.lowerToBuildSteps(
1311 b,1311 b,
1312 parent_step,1312 parent_step,
1313 opt_test_filter,1313 test_filters,
1314 cases_dir_path,1314 cases_dir_path,
1315 check_case_exe,1315 check_case_exe,
1316 );1316 );