stage2: fix referencing decls which appear later in the file

This commit is contained in:
Andrew Kelley 2020-06-02 17:43:51 -04:00
parent 14d235dd6e
commit 6524a64bda
3 changed files with 53 additions and 13 deletions

View File

@ -743,7 +743,7 @@ pub fn performAllTheWork(self: *Module) error{OutOfMemory}!void {
self.allocator, self.allocator,
decl.src, decl.src,
"unable to load source file '{}': {}", "unable to load source file '{}': {}",
.{decl.scope.sub_file_path, @errorName(err)}, .{ decl.scope.sub_file_path, @errorName(err) },
)); ));
decl.analysis = .codegen_failure_retryable; decl.analysis = .codegen_failure_retryable;
continue; continue;
@ -756,7 +756,7 @@ pub fn performAllTheWork(self: *Module) error{OutOfMemory}!void {
error.OutOfMemory => return error.OutOfMemory, error.OutOfMemory => return error.OutOfMemory,
error.AnalysisFail => continue, error.AnalysisFail => continue,
}; };
} },
}, },
}; };
} }
@ -945,7 +945,7 @@ fn deleteDeclExports(self: *Module, decl: *Decl) void {
var new_len = list.len; var new_len = list.len;
while (i < new_len) { while (i < new_len) {
if (list[i].owner_decl == decl) { 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; new_len -= 1;
} else { } else {
i += 1; 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); const decl_name = try self.resolveConstString(scope, inst.positionals.name);
// This will need to get more fleshed out when there are proper structs & namespaces. // This will need to get more fleshed out when there are proper structs & namespaces.
const zir_module = scope.namespace(); const zir_module = scope.namespace();
for (zir_module.contents.module.decls) |src_decl| { const src_decl = zir_module.contents.module.findDecl(decl_name) orelse
if (mem.eql(u8, src_decl.name, decl_name)) { 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); 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});
} }
fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) InnerError!*Inst { fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) InnerError!*Inst {

View File

@ -964,8 +964,8 @@ const Parser = struct {
self.i = src; self.i = src;
return self.fail("unrecognized identifier: {}", .{bad_name}); return self.fail("unrecognized identifier: {}", .{bad_name});
} else { } else {
const name = try self.arena.allocator.create(Inst.Str); const name_array = try self.arena.allocator.create(Inst.Str);
name.* = .{ name_array.* = .{
.base = .{ .base = .{
.name = try self.generateName(), .name = try self.generateName(),
.src = src, .src = src,
@ -974,6 +974,16 @@ const Parser = struct {
.positionals = .{ .bytes = ident }, .positionals = .{ .bytes = ident },
.kw_args = .{}, .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); const declref = try self.arena.allocator.create(Inst.DeclRef);
declref.* = .{ declref.* = .{
.base = .{ .base = .{
@ -984,7 +994,17 @@ const Parser = struct {
.positionals = .{ .name = &name.base }, .positionals = .{ .name = &name.base },
.kw_args = .{}, .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) { if (local_ref) {

View File

@ -9,6 +9,28 @@ const linux_x64 = std.zig.CrossTarget{
}; };
pub fn addCases(ctx: *TestContext) void { 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, ctx.addZIRTransform("elemptr, add, cmp, condbr, return, breakpoint", linux_x64,
\\@void = primitive(void) \\@void = primitive(void)
\\@usize = primitive(usize) \\@usize = primitive(usize)