Commit 807a8b6f75

Andrew Kelley <andrew@ziglang.org>
2021-05-03 03:50:01
stage2: make struct field analysis lazy
This commit breaks struct field analysis; will be fixed in a future commit.
1 parent 5f4c522
Changed files (3)
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" });
                 }
             }
         }
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;
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);
 }