From 807a8b6f7549732d73239a649886cc64f0303f34 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 2 May 2021 18:50:01 -0700 Subject: [PATCH] stage2: make struct field analysis lazy This commit breaks struct field analysis; will be fixed in a future commit. --- lib/std/start.zig | 4 ++-- src/Module.zig | 14 +++++++++++++- src/Sema.zig | 26 +++++++++++++++----------- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/lib/std/start.zig b/lib/std/start.zig index ccd7ae410d..68fcd1955d 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -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" }); } } } diff --git a/src/Module.zig b/src/Module.zig index 86b15e9b0b..57bb2435fb 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -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; diff --git a/src/Sema.zig b/src/Sema.zig index 0bc739f352..178de4f9bf 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -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); }