diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig index 972aa649f3..5bdd38c693 100644 --- a/src-self-hosted/Module.zig +++ b/src-self-hosted/Module.zig @@ -743,7 +743,7 @@ pub fn performAllTheWork(self: *Module) error{OutOfMemory}!void { self.allocator, decl.src, "unable to load source file '{}': {}", - .{decl.scope.sub_file_path, @errorName(err)}, + .{ decl.scope.sub_file_path, @errorName(err) }, )); decl.analysis = .codegen_failure_retryable; continue; @@ -756,7 +756,7 @@ pub fn performAllTheWork(self: *Module) error{OutOfMemory}!void { error.OutOfMemory => return error.OutOfMemory, error.AnalysisFail => continue, }; - } + }, }, }; } @@ -945,7 +945,7 @@ fn deleteDeclExports(self: *Module, decl: *Decl) void { var new_len = list.len; while (i < new_len) { if (list[i].owner_decl == decl) { - mem.copyBackwards(*Export, list[i..], list[i + 1..new_len]); + mem.copyBackwards(*Export, list[i..], list[i + 1 .. new_len]); new_len -= 1; } else { i += 1; @@ -1494,13 +1494,11 @@ fn analyzeInstDeclRef(self: *Module, scope: *Scope, inst: *zir.Inst.DeclRef) Inn const decl_name = try self.resolveConstString(scope, inst.positionals.name); // This will need to get more fleshed out when there are proper structs & namespaces. const zir_module = scope.namespace(); - for (zir_module.contents.module.decls) |src_decl| { - if (mem.eql(u8, src_decl.name, decl_name)) { - const decl = try self.resolveCompleteDecl(scope, src_decl); - return self.analyzeDeclRef(scope, inst.base.src, decl); - } - } - return self.fail(scope, inst.positionals.name.src, "use of undeclared identifier '{}'", .{decl_name}); + const src_decl = zir_module.contents.module.findDecl(decl_name) orelse + return self.fail(scope, inst.positionals.name.src, "use of undeclared identifier '{}'", .{decl_name}); + + const decl = try self.resolveCompleteDecl(scope, src_decl); + return self.analyzeDeclRef(scope, inst.base.src, decl); } fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) InnerError!*Inst { diff --git a/src-self-hosted/zir.zig b/src-self-hosted/zir.zig index 769f0d89b9..b8a1421996 100644 --- a/src-self-hosted/zir.zig +++ b/src-self-hosted/zir.zig @@ -964,8 +964,8 @@ const Parser = struct { self.i = src; return self.fail("unrecognized identifier: {}", .{bad_name}); } else { - const name = try self.arena.allocator.create(Inst.Str); - name.* = .{ + const name_array = try self.arena.allocator.create(Inst.Str); + name_array.* = .{ .base = .{ .name = try self.generateName(), .src = src, @@ -974,6 +974,16 @@ const Parser = struct { .positionals = .{ .bytes = ident }, .kw_args = .{}, }; + const name = try self.arena.allocator.create(Inst.Ref); + name.* = .{ + .base = .{ + .name = try self.generateName(), + .src = src, + .tag = Inst.Ref.base_tag, + }, + .positionals = .{ .operand = &name_array.base }, + .kw_args = .{}, + }; const declref = try self.arena.allocator.create(Inst.DeclRef); declref.* = .{ .base = .{ @@ -984,7 +994,17 @@ const Parser = struct { .positionals = .{ .name = &name.base }, .kw_args = .{}, }; - return &declref.base; + const deref = try self.arena.allocator.create(Inst.Deref); + deref.* = .{ + .base = .{ + .name = try self.generateName(), + .src = src, + .tag = Inst.Deref.base_tag, + }, + .positionals = .{ .ptr = &declref.base }, + .kw_args = .{}, + }; + return &deref.base; } }; if (local_ref) { diff --git a/test/stage2/zir.zig b/test/stage2/zir.zig index 3778c99fb7..f8b9d797d5 100644 --- a/test/stage2/zir.zig +++ b/test/stage2/zir.zig @@ -9,6 +9,28 @@ const linux_x64 = std.zig.CrossTarget{ }; pub fn addCases(ctx: *TestContext) void { + ctx.addZIRTransform("referencing decls which appear later in the file", linux_x64, + \\@void = primitive(void) + \\@fnty = fntype([], @void, cc=C) + \\ + \\@9 = str("entry") + \\@10 = ref(@9) + \\@11 = export(@10, @entry) + \\ + \\@entry = fn(@fnty, { + \\ %11 = return() + \\}) + , + \\@0 = primitive(void) + \\@1 = fntype([], @0, cc=C) + \\@2 = fn(@1, { + \\ %0 = return() + \\}) + \\@3 = str("entry") + \\@4 = ref(@3) + \\@5 = export(@4, @2) + \\ + ); ctx.addZIRTransform("elemptr, add, cmp, condbr, return, breakpoint", linux_x64, \\@void = primitive(void) \\@usize = primitive(usize)