Fix error references across inline and comptime functions

This commit is contained in:
Martin Wickham 2021-09-23 18:09:35 -05:00 committed by Andrew Kelley
parent 8f58e2d779
commit 1e7009a9d9
2 changed files with 24 additions and 28 deletions

View File

@ -248,6 +248,9 @@ pub const Export = struct {
link: link.File.Export,
/// The Decl that performs the export. Note that this is *not* the Decl being exported.
owner_decl: *Decl,
/// The Decl containing the export statement. Inline function calls
/// may cause this to be different from the owner_decl.
src_decl: *Decl,
/// The Decl being exported. Note this is *not* the Decl performing the export.
exported_decl: *Decl,
status: enum {
@ -261,8 +264,8 @@ pub const Export = struct {
pub fn getSrcLoc(exp: Export) SrcLoc {
return .{
.file_scope = exp.owner_decl.namespace.file_scope,
.parent_decl_node = exp.owner_decl.src_node,
.file_scope = exp.src_decl.namespace.file_scope,
.parent_decl_node = exp.src_decl.src_node,
.lazy = exp.src,
};
}
@ -1014,15 +1017,6 @@ pub const Scope = struct {
return @fieldParentPtr(T, "base", base);
}
/// Get the decl that is currently being analyzed
pub fn ownerDecl(scope: *Scope) ?*Decl {
return switch (scope.tag) {
.block => scope.cast(Block).?.sema.owner_decl,
.file => null,
.namespace => null,
};
}
/// Get the decl which contains this decl, for the purposes of source reporting
pub fn srcDecl(scope: *Scope) ?*Decl {
return switch (scope.tag) {
@ -3402,7 +3396,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
}
// The scope needs to have the decl in it.
const options: std.builtin.ExportOptions = .{ .name = mem.spanZ(decl.name) };
try mod.analyzeExport(&block_scope.base, export_src, options, decl);
try mod.analyzeExport(&block_scope, export_src, options, decl);
}
return type_changed or is_inline != prev_is_inline;
}
@ -3462,7 +3456,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
const export_src = src; // TODO point to the export token
// The scope needs to have the decl in it.
const options: std.builtin.ExportOptions = .{ .name = mem.spanZ(decl.name) };
try mod.analyzeExport(&block_scope.base, export_src, options, decl);
try mod.analyzeExport(&block_scope, export_src, options, decl);
}
return type_changed;
@ -3931,7 +3925,7 @@ pub fn deleteUnusedDecl(mod: *Module, decl: *Decl) void {
pub fn deleteAnonDecl(mod: *Module, scope: *Scope, decl: *Decl) void {
log.debug("deleteAnonDecl {*} ({s})", .{ decl, decl.name });
const scope_decl = scope.ownerDecl().?;
const scope_decl = scope.srcDecl().?;
assert(scope_decl.namespace.anon_decls.swapRemove(decl));
decl.destroy(mod);
}
@ -4209,7 +4203,7 @@ pub fn getErrorValue(mod: *Module, name: []const u8) !std.StringHashMapUnmanaged
pub fn analyzeExport(
mod: *Module,
scope: *Scope,
block: *Scope.Block,
src: LazySrcLoc,
borrowed_options: std.builtin.ExportOptions,
exported_decl: *Decl,
@ -4217,7 +4211,7 @@ pub fn analyzeExport(
try mod.ensureDeclAnalyzed(exported_decl);
switch (exported_decl.ty.zigTypeTag()) {
.Fn => {},
else => return mod.fail(scope, src, "unable to export type '{}'", .{exported_decl.ty}),
else => return mod.fail(&block.base, src, "unable to export type '{}'", .{exported_decl.ty}),
}
const gpa = mod.gpa;
@ -4234,7 +4228,8 @@ pub fn analyzeExport(
const section: ?[]const u8 = if (borrowed_options.section) |s| try gpa.dupe(u8, s) else null;
errdefer if (section) |s| gpa.free(s);
const owner_decl = scope.ownerDecl().?;
const src_decl = block.src_decl;
const owner_decl = block.sema.owner_decl;
log.debug("exporting Decl '{s}' as symbol '{s}' from Decl '{s}'", .{
exported_decl.name, symbol_name, owner_decl.name,
@ -4257,6 +4252,7 @@ pub fn analyzeExport(
.spirv => .{ .spirv = {} },
},
.owner_decl = owner_decl,
.src_decl = src_decl,
.exported_decl = exported_decl,
.status = .in_progress,
};
@ -4287,38 +4283,38 @@ pub fn createAnonymousDeclNamed(
typed_value: TypedValue,
name: [:0]u8,
) !*Decl {
return mod.createAnonymousDeclFromDeclNamed(scope.ownerDecl().?, scope.srcScope(), typed_value, name);
return mod.createAnonymousDeclFromDeclNamed(scope.srcDecl().?, scope.srcScope(), typed_value, name);
}
pub fn createAnonymousDecl(mod: *Module, scope: *Scope, typed_value: TypedValue) !*Decl {
return mod.createAnonymousDeclFromDecl(scope.ownerDecl().?, scope.srcScope(), typed_value);
return mod.createAnonymousDeclFromDecl(scope.srcDecl().?, scope.srcScope(), typed_value);
}
pub fn createAnonymousDeclFromDecl(mod: *Module, owner_decl: *Decl, src_scope: ?*CaptureScope, tv: TypedValue) !*Decl {
pub fn createAnonymousDeclFromDecl(mod: *Module, src_decl: *Decl, src_scope: ?*CaptureScope, tv: TypedValue) !*Decl {
const name_index = mod.getNextAnonNameIndex();
const name = try std.fmt.allocPrintZ(mod.gpa, "{s}__anon_{d}", .{
owner_decl.name, name_index,
src_decl.name, name_index,
});
return mod.createAnonymousDeclFromDeclNamed(owner_decl, src_scope, tv, name);
return mod.createAnonymousDeclFromDeclNamed(src_decl, src_scope, tv, name);
}
/// Takes ownership of `name` even if it returns an error.
pub fn createAnonymousDeclFromDeclNamed(
mod: *Module,
owner_decl: *Decl,
src_decl: *Decl,
src_scope: ?*CaptureScope,
typed_value: TypedValue,
name: [:0]u8,
) !*Decl {
errdefer mod.gpa.free(name);
const namespace = owner_decl.namespace;
const namespace = src_decl.namespace;
try namespace.anon_decls.ensureUnusedCapacity(mod.gpa, 1);
const new_decl = try mod.allocateNewDecl(namespace, owner_decl.src_node, src_scope);
const new_decl = try mod.allocateNewDecl(namespace, src_decl.src_node, src_scope);
new_decl.name = name;
new_decl.src_line = owner_decl.src_line;
new_decl.src_line = src_decl.src_line;
new_decl.ty = typed_value.ty;
new_decl.val = typed_value.val;
new_decl.align_val = Value.initTag(.null_value);

View File

@ -2447,7 +2447,7 @@ fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro
}
const decl = try sema.lookupIdentifier(block, operand_src, decl_name);
const options = try sema.resolveExportOptions(block, options_src, extra.options);
try sema.mod.analyzeExport(&block.base, src, options, decl);
try sema.mod.analyzeExport(block, src, options, decl);
}
fn zirExportValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void {
@ -2465,7 +2465,7 @@ fn zirExportValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil
.function => operand.val.castTag(.function).?.data.owner_decl,
else => return sema.mod.fail(&block.base, operand_src, "TODO implement exporting arbitrary Value objects", .{}), // TODO put this Value into an anonymous Decl and then export it.
};
try sema.mod.analyzeExport(&block.base, src, options, decl);
try sema.mod.analyzeExport(block, src, options, decl);
}
fn zirSetAlignStack(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void {