stage2: make struct field analysis lazy

This commit breaks struct field analysis; will be fixed in a future
commit.
This commit is contained in:
Andrew Kelley 2021-05-02 18:50:01 -07:00
parent 5f4c52209e
commit 807a8b6f75
3 changed files with 30 additions and 14 deletions

View File

@ -29,10 +29,10 @@ comptime {
if (builtin.zig_is_stage2) {
if (builtin.output_mode == .Exe) {
if (builtin.link_libc or builtin.object_format == .c) {
@export(main2, "main");
@export(main2, .{ .name = "main" });
} else {
if (!@hasDecl(root, "_start")) {
@export(_start2, "_start");
@export(_start2, .{ .name = "_start" });
}
}
}

View File

@ -497,12 +497,22 @@ pub const Struct = struct {
/// Offset from `owner_decl`, points to the struct AST node.
node_offset: i32,
layout: std.builtin.TypeInfo.ContainerLayout,
status: enum {
none,
have_field_types,
have_layout,
},
pub const Field = struct {
/// Uses `noreturn` to indicate `anytype`.
/// undefined until `status` is `have_field_types` or `have_layout`.
ty: Type,
abi_align: Value,
/// Uses `unreachable_value` to indicate no default.
default_val: Value,
/// undefined until `status` is `have_layout`.
offset: u32,
is_comptime: bool,
};
@ -2408,6 +2418,8 @@ pub fn semaFile(mod: *Module, file: *Scope.File) InnerError!void {
.owner_decl = undefined, // set below
.fields = .{},
.node_offset = 0, // it's the struct for the root file
.layout = .Auto,
.status = .none,
.namespace = .{
.parent = null,
.ty = struct_ty,
@ -2458,7 +2470,7 @@ pub fn semaFile(mod: *Module, file: *Scope.File) InnerError!void {
const main_struct_inst = file.zir.extra[@enumToInt(Zir.ExtraIndex.main_struct)] -
@intCast(u32, Zir.Inst.Ref.typed_value_map.len);
try sema.analyzeStructDecl(&block_scope, &new_decl_arena, new_decl, main_struct_inst, .Auto, struct_obj);
try sema.analyzeStructDecl(new_decl, main_struct_inst, struct_obj);
try new_decl.finalizeNewArena(&new_decl_arena);
file.status = .success_air;

View File

@ -664,12 +664,21 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) In
pub fn analyzeStructDecl(
sema: *Sema,
block: *Scope.Block,
new_decl_arena: *std.heap.ArenaAllocator,
new_decl: *Decl,
inst: Zir.Inst.Index,
layout: std.builtin.TypeInfo.ContainerLayout,
struct_obj: *Module.Struct,
) InnerError!void {
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
const extra = sema.code.extraData(Zir.Inst.StructDecl, inst_data.payload_index);
const decls_len = extra.data.decls_len;
_ = try sema.mod.scanNamespace(&struct_obj.namespace, extra.end, decls_len, new_decl);
}
pub fn analyzeStructFields(
sema: *Sema,
block: *Scope.Block,
new_decl_arena: *std.heap.ArenaAllocator,
) InnerError!void {
const tracy = trace(@src());
defer tracy.end();
@ -682,13 +691,6 @@ pub fn analyzeStructDecl(
const fields_len = extra.data.fields_len;
const decls_len = extra.data.decls_len;
var extra_index: usize = try mod.scanNamespace(
&struct_obj.namespace,
extra.end,
decls_len,
new_decl,
);
const body = sema.code.extra[extra_index..][0..extra.data.body_len];
if (fields_len == 0) {
assert(body.len == 0);
@ -824,13 +826,15 @@ fn zirStructDecl(
.owner_decl = sema.owner_decl,
.fields = .{},
.node_offset = inst_data.src_node,
.layout = layout,
.status = .none,
.namespace = .{
.parent = sema.owner_decl.namespace,
.ty = struct_ty,
.file_scope = block.getFileScope(),
},
};
try sema.analyzeStructDecl(block, &new_decl_arena, new_decl, inst, layout, struct_obj);
try sema.analyzeStructDecl(new_decl, inst, struct_obj);
try new_decl.finalizeNewArena(&new_decl_arena);
return sema.analyzeDeclVal(block, src, new_decl);
}