mirror of
https://github.com/ziglang/zig.git
synced 2025-12-14 18:23:12 +00:00
Change *Scope to *Scope.Block, use Sema when required
This commit is contained in:
parent
01e08c92b3
commit
fd60012c21
181
src/Module.zig
181
src/Module.zig
@ -2372,7 +2372,7 @@ pub const LazySrcLoc = union(enum) {
|
|||||||
node_offset_lib_name: i32,
|
node_offset_lib_name: i32,
|
||||||
|
|
||||||
/// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope.
|
/// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope.
|
||||||
pub fn toSrcLoc(lazy: LazySrcLoc, scope: *Scope) SrcLoc {
|
pub fn toSrcLoc(lazy: LazySrcLoc, block: *Scope.Block) SrcLoc {
|
||||||
return switch (lazy) {
|
return switch (lazy) {
|
||||||
.unneeded,
|
.unneeded,
|
||||||
.entire_file,
|
.entire_file,
|
||||||
@ -2380,7 +2380,7 @@ pub const LazySrcLoc = union(enum) {
|
|||||||
.token_abs,
|
.token_abs,
|
||||||
.node_abs,
|
.node_abs,
|
||||||
=> .{
|
=> .{
|
||||||
.file_scope = scope.getFileScope(),
|
.file_scope = block.getFileScope(),
|
||||||
.parent_decl_node = 0,
|
.parent_decl_node = 0,
|
||||||
.lazy = lazy,
|
.lazy = lazy,
|
||||||
},
|
},
|
||||||
@ -2416,8 +2416,8 @@ pub const LazySrcLoc = union(enum) {
|
|||||||
.node_offset_anyframe_type,
|
.node_offset_anyframe_type,
|
||||||
.node_offset_lib_name,
|
.node_offset_lib_name,
|
||||||
=> .{
|
=> .{
|
||||||
.file_scope = scope.getFileScope(),
|
.file_scope = block.getFileScope(),
|
||||||
.parent_decl_node = scope.srcDecl().?.src_node,
|
.parent_decl_node = block.src_decl.src_node,
|
||||||
.lazy = lazy,
|
.lazy = lazy,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -3464,12 +3464,12 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
|
|||||||
if (decl.is_usingnamespace) {
|
if (decl.is_usingnamespace) {
|
||||||
const ty_ty = Type.initTag(.type);
|
const ty_ty = Type.initTag(.type);
|
||||||
if (!decl_tv.ty.eql(ty_ty)) {
|
if (!decl_tv.ty.eql(ty_ty)) {
|
||||||
return mod.fail(&block_scope.base, src, "expected type, found {}", .{decl_tv.ty});
|
return sema.fail(&block_scope, src, "expected type, found {}", .{decl_tv.ty});
|
||||||
}
|
}
|
||||||
var buffer: Value.ToTypeBuffer = undefined;
|
var buffer: Value.ToTypeBuffer = undefined;
|
||||||
const ty = decl_tv.val.toType(&buffer);
|
const ty = decl_tv.val.toType(&buffer);
|
||||||
if (ty.getNamespace() == null) {
|
if (ty.getNamespace() == null) {
|
||||||
return mod.fail(&block_scope.base, src, "type {} has no namespace", .{ty});
|
return sema.fail(&block_scope, src, "type {} has no namespace", .{ty});
|
||||||
}
|
}
|
||||||
|
|
||||||
decl.ty = ty_ty;
|
decl.ty = ty_ty;
|
||||||
@ -3532,11 +3532,11 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
|
|||||||
if (decl.is_exported) {
|
if (decl.is_exported) {
|
||||||
const export_src = src; // TODO make this point at `export` token
|
const export_src = src; // TODO make this point at `export` token
|
||||||
if (is_inline) {
|
if (is_inline) {
|
||||||
return mod.fail(&block_scope.base, export_src, "export of inline function", .{});
|
return sema.fail(&block_scope, export_src, "export of inline function", .{});
|
||||||
}
|
}
|
||||||
// The scope needs to have the decl in it.
|
// The scope needs to have the decl in it.
|
||||||
const options: std.builtin.ExportOptions = .{ .name = mem.spanZ(decl.name) };
|
const options: std.builtin.ExportOptions = .{ .name = mem.spanZ(decl.name) };
|
||||||
try mod.analyzeExport(&block_scope, export_src, options, decl);
|
try sema.analyzeExport(&block_scope, export_src, options, decl);
|
||||||
}
|
}
|
||||||
return type_changed or is_inline != prev_is_inline;
|
return type_changed or is_inline != prev_is_inline;
|
||||||
}
|
}
|
||||||
@ -3590,7 +3590,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
|
|||||||
const export_src = src; // TODO point to the export token
|
const export_src = src; // TODO point to the export token
|
||||||
// The scope needs to have the decl in it.
|
// The scope needs to have the decl in it.
|
||||||
const options: std.builtin.ExportOptions = .{ .name = mem.spanZ(decl.name) };
|
const options: std.builtin.ExportOptions = .{ .name = mem.spanZ(decl.name) };
|
||||||
try mod.analyzeExport(&block_scope, export_src, options, decl);
|
try sema.analyzeExport(&block_scope, export_src, options, decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return type_changed;
|
return type_changed;
|
||||||
@ -4347,81 +4347,6 @@ pub fn getErrorValue(mod: *Module, name: []const u8) !std.StringHashMapUnmanaged
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn analyzeExport(
|
|
||||||
mod: *Module,
|
|
||||||
block: *Scope.Block,
|
|
||||||
src: LazySrcLoc,
|
|
||||||
borrowed_options: std.builtin.ExportOptions,
|
|
||||||
exported_decl: *Decl,
|
|
||||||
) !void {
|
|
||||||
try mod.ensureDeclAnalyzed(exported_decl);
|
|
||||||
switch (exported_decl.ty.zigTypeTag()) {
|
|
||||||
.Fn => {},
|
|
||||||
else => return mod.fail(&block.base, src, "unable to export type '{}'", .{exported_decl.ty}),
|
|
||||||
}
|
|
||||||
|
|
||||||
const gpa = mod.gpa;
|
|
||||||
|
|
||||||
try mod.decl_exports.ensureUnusedCapacity(gpa, 1);
|
|
||||||
try mod.export_owners.ensureUnusedCapacity(gpa, 1);
|
|
||||||
|
|
||||||
const new_export = try gpa.create(Export);
|
|
||||||
errdefer gpa.destroy(new_export);
|
|
||||||
|
|
||||||
const symbol_name = try gpa.dupe(u8, borrowed_options.name);
|
|
||||||
errdefer gpa.free(symbol_name);
|
|
||||||
|
|
||||||
const section: ?[]const u8 = if (borrowed_options.section) |s| try gpa.dupe(u8, s) else null;
|
|
||||||
errdefer if (section) |s| gpa.free(s);
|
|
||||||
|
|
||||||
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,
|
|
||||||
});
|
|
||||||
|
|
||||||
new_export.* = .{
|
|
||||||
.options = .{
|
|
||||||
.name = symbol_name,
|
|
||||||
.linkage = borrowed_options.linkage,
|
|
||||||
.section = section,
|
|
||||||
},
|
|
||||||
.src = src,
|
|
||||||
.link = switch (mod.comp.bin_file.tag) {
|
|
||||||
.coff => .{ .coff = {} },
|
|
||||||
.elf => .{ .elf = link.File.Elf.Export{} },
|
|
||||||
.macho => .{ .macho = link.File.MachO.Export{} },
|
|
||||||
.plan9 => .{ .plan9 = null },
|
|
||||||
.c => .{ .c = {} },
|
|
||||||
.wasm => .{ .wasm = {} },
|
|
||||||
.spirv => .{ .spirv = {} },
|
|
||||||
},
|
|
||||||
.owner_decl = owner_decl,
|
|
||||||
.src_decl = src_decl,
|
|
||||||
.exported_decl = exported_decl,
|
|
||||||
.status = .in_progress,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add to export_owners table.
|
|
||||||
const eo_gop = mod.export_owners.getOrPutAssumeCapacity(owner_decl);
|
|
||||||
if (!eo_gop.found_existing) {
|
|
||||||
eo_gop.value_ptr.* = &[0]*Export{};
|
|
||||||
}
|
|
||||||
eo_gop.value_ptr.* = try gpa.realloc(eo_gop.value_ptr.*, eo_gop.value_ptr.len + 1);
|
|
||||||
eo_gop.value_ptr.*[eo_gop.value_ptr.len - 1] = new_export;
|
|
||||||
errdefer eo_gop.value_ptr.* = gpa.shrink(eo_gop.value_ptr.*, eo_gop.value_ptr.len - 1);
|
|
||||||
|
|
||||||
// Add to exported_decl table.
|
|
||||||
const de_gop = mod.decl_exports.getOrPutAssumeCapacity(exported_decl);
|
|
||||||
if (!de_gop.found_existing) {
|
|
||||||
de_gop.value_ptr.* = &[0]*Export{};
|
|
||||||
}
|
|
||||||
de_gop.value_ptr.* = try gpa.realloc(de_gop.value_ptr.*, de_gop.value_ptr.len + 1);
|
|
||||||
de_gop.value_ptr.*[de_gop.value_ptr.len - 1] = new_export;
|
|
||||||
errdefer de_gop.value_ptr.* = gpa.shrink(de_gop.value_ptr.*, de_gop.value_ptr.len - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Takes ownership of `name` even if it returns an error.
|
/// Takes ownership of `name` even if it returns an error.
|
||||||
pub fn createAnonymousDeclNamed(
|
pub fn createAnonymousDeclNamed(
|
||||||
mod: *Module,
|
mod: *Module,
|
||||||
@ -4506,19 +4431,6 @@ pub fn makeIntType(arena: *Allocator, signedness: std.builtin.Signedness, bits:
|
|||||||
return Type.initPayload(&int_payload.base);
|
return Type.initPayload(&int_payload.base);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We don't return a pointer to the new error note because the pointer
|
|
||||||
/// becomes invalid when you add another one.
|
|
||||||
pub fn errNote(
|
|
||||||
mod: *Module,
|
|
||||||
scope: *Scope,
|
|
||||||
src: LazySrcLoc,
|
|
||||||
parent: *ErrorMsg,
|
|
||||||
comptime format: []const u8,
|
|
||||||
args: anytype,
|
|
||||||
) error{OutOfMemory}!void {
|
|
||||||
return mod.errNoteNonLazy(src.toSrcLoc(scope), parent, format, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn errNoteNonLazy(
|
pub fn errNoteNonLazy(
|
||||||
mod: *Module,
|
mod: *Module,
|
||||||
src_loc: SrcLoc,
|
src_loc: SrcLoc,
|
||||||
@ -4536,81 +4448,6 @@ pub fn errNoteNonLazy(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn errMsg(
|
|
||||||
mod: *Module,
|
|
||||||
scope: *Scope,
|
|
||||||
src: LazySrcLoc,
|
|
||||||
comptime format: []const u8,
|
|
||||||
args: anytype,
|
|
||||||
) error{OutOfMemory}!*ErrorMsg {
|
|
||||||
return ErrorMsg.create(mod.gpa, src.toSrcLoc(scope), format, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fail(
|
|
||||||
mod: *Module,
|
|
||||||
scope: *Scope,
|
|
||||||
src: LazySrcLoc,
|
|
||||||
comptime format: []const u8,
|
|
||||||
args: anytype,
|
|
||||||
) CompileError {
|
|
||||||
const err_msg = try mod.errMsg(scope, src, format, args);
|
|
||||||
return mod.failWithOwnedErrorMsg(scope, err_msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Same as `fail`, except given a token index, and the function sets up the `LazySrcLoc`
|
|
||||||
/// for pointing at it relatively by subtracting from the containing `Decl`.
|
|
||||||
pub fn failTok(
|
|
||||||
mod: *Module,
|
|
||||||
scope: *Scope,
|
|
||||||
token_index: Ast.TokenIndex,
|
|
||||||
comptime format: []const u8,
|
|
||||||
args: anytype,
|
|
||||||
) CompileError {
|
|
||||||
const src = scope.srcDecl().?.tokSrcLoc(token_index);
|
|
||||||
return mod.fail(scope, src, format, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Same as `fail`, except given an AST node index, and the function sets up the `LazySrcLoc`
|
|
||||||
/// for pointing at it relatively by subtracting from the containing `Decl`.
|
|
||||||
pub fn failNode(
|
|
||||||
mod: *Module,
|
|
||||||
scope: *Scope,
|
|
||||||
node_index: Ast.Node.Index,
|
|
||||||
comptime format: []const u8,
|
|
||||||
args: anytype,
|
|
||||||
) CompileError {
|
|
||||||
const src = scope.srcDecl().?.nodeSrcLoc(node_index);
|
|
||||||
return mod.fail(scope, src, format, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn failWithOwnedErrorMsg(mod: *Module, scope: *Scope, err_msg: *ErrorMsg) CompileError {
|
|
||||||
@setCold(true);
|
|
||||||
|
|
||||||
{
|
|
||||||
errdefer err_msg.destroy(mod.gpa);
|
|
||||||
if (err_msg.src_loc.lazy == .unneeded) {
|
|
||||||
return error.NeededSourceLocation;
|
|
||||||
}
|
|
||||||
try mod.failed_decls.ensureUnusedCapacity(mod.gpa, 1);
|
|
||||||
try mod.failed_files.ensureUnusedCapacity(mod.gpa, 1);
|
|
||||||
}
|
|
||||||
switch (scope.tag) {
|
|
||||||
.block => {
|
|
||||||
const block = scope.cast(Scope.Block).?;
|
|
||||||
if (block.sema.owner_func) |func| {
|
|
||||||
func.state = .sema_failure;
|
|
||||||
} else {
|
|
||||||
block.sema.owner_decl.analysis = .sema_failure;
|
|
||||||
block.sema.owner_decl.generation = mod.generation;
|
|
||||||
}
|
|
||||||
mod.failed_decls.putAssumeCapacityNoClobber(block.sema.owner_decl, err_msg);
|
|
||||||
},
|
|
||||||
.file => unreachable,
|
|
||||||
.namespace => unreachable,
|
|
||||||
}
|
|
||||||
return error.AnalysisFail;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn optionalType(arena: *Allocator, child_type: Type) Allocator.Error!Type {
|
pub fn optionalType(arena: *Allocator, child_type: Type) Allocator.Error!Type {
|
||||||
switch (child_type.tag()) {
|
switch (child_type.tag()) {
|
||||||
.single_const_pointer => return Type.Tag.optional_single_const_pointer.create(
|
.single_const_pointer => return Type.Tag.optional_single_const_pointer.create(
|
||||||
|
|||||||
1037
src/Sema.zig
1037
src/Sema.zig
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user