Commit 54fe5ea4f3

Loris Cro <kappaloris@gmail.com>
2022-06-11 17:20:08
autodoc: add support for new func-related Zir
1 parent fed9dcf
Changed files (1)
src/Autodoc.zig
@@ -2068,20 +2068,20 @@ fn walkInstruction(
 
             return result;
         },
-        // .func_extended => {
-        //     const type_slot_index = self.types.items.len;
-        //     try self.types.append(self.arena, .{ .Unanalyzed = .{} });
+        .func_fancy => {
+            const type_slot_index = self.types.items.len;
+            try self.types.append(self.arena, .{ .Unanalyzed = .{} });
 
-        //     const result = self.analyzeFunctionExtended(
-        //         file,
-        //         parent_scope,
-        //         inst_index,
-        //         self_ast_node_index,
-        //         type_slot_index,
-        //     );
+            const result = self.analyzeFancyFunction(
+                file,
+                parent_scope,
+                inst_index,
+                self_ast_node_index,
+                type_slot_index,
+            );
 
-        //     return result;
-        // },
+            return result;
+        },
         .extended => {
             const extended = data[inst_index].extended;
             switch (extended.opcode) {
@@ -3129,7 +3129,7 @@ fn tryResolveRefPath(
         //       that said, we might want to store it elsewhere and reclaim memory asap
     }
 }
-fn analyzeFunctionExtended(
+fn analyzeFancyFunction(
     self: *Autodoc,
     file: *File,
     scope: *Scope,
@@ -3204,19 +3204,10 @@ fn analyzeFunctionExtended(
         }
     }
 
-    // ret
-    const ret_type_ref = blk: {
-        const last_instr_index = fn_info.ret_ty_body[fn_info.ret_ty_body.len - 1];
-        const break_operand = data[last_instr_index].@"break".operand;
-        const wr = try self.walkRef(file, scope, break_operand, false);
-
-        break :blk wr;
-    };
-
     self.ast_nodes.items[self_ast_node_index].fields = param_ast_indexes.items;
 
     const inst_data = data[inst_index].pl_node;
-    const extra = file.zir.extraData(Zir.Inst.ExtendedFunc, inst_data.payload_index);
+    const extra = file.zir.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);
 
     var extra_index: usize = extra.end;
 
@@ -3226,25 +3217,96 @@ fn analyzeFunctionExtended(
         extra_index += 1;
     }
 
-    var cc_index: ?usize = null;
     var align_index: ?usize = null;
-    if (extra.data.bits.has_cc) {
+    if (extra.data.bits.has_align_ref) {
+        const align_ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
+        align_index = self.exprs.items.len;
+        _ = try self.walkRef(file, scope, align_ref, false);
+        extra_index += 1;
+    } else if (extra.data.bits.has_align_body) {
+        const align_body_len = file.zir.extra[extra_index];
+        extra_index += 1;
+        const align_body = file.zir.extra[extra_index .. extra_index + align_body_len];
+        _ = align_body;
+        // TODO: analyze the block (or bail with a comptimeExpr)
+        extra_index += align_body_len;
+    } else {
+        // default alignment
+    }
+
+    var addrspace_index: ?usize = null;
+    if (extra.data.bits.has_addrspace_ref) {
+        const addrspace_ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
+        addrspace_index = self.exprs.items.len;
+        _ = try self.walkRef(file, scope, addrspace_ref, false);
+        extra_index += 1;
+    } else if (extra.data.bits.has_addrspace_body) {
+        const addrspace_body_len = file.zir.extra[extra_index];
+        extra_index += 1;
+        const addrspace_body = file.zir.extra[extra_index .. extra_index + addrspace_body_len];
+        _ = addrspace_body;
+        // TODO: analyze the block (or bail with a comptimeExpr)
+        extra_index += addrspace_body_len;
+    } else {
+        // default alignment
+    }
+
+    var section_index: ?usize = null;
+    if (extra.data.bits.has_section_ref) {
+        const section_ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
+        section_index = self.exprs.items.len;
+        _ = try self.walkRef(file, scope, section_ref, false);
+        extra_index += 1;
+    } else if (extra.data.bits.has_section_body) {
+        const section_body_len = file.zir.extra[extra_index];
+        extra_index += 1;
+        const section_body = file.zir.extra[extra_index .. extra_index + section_body_len];
+        _ = section_body;
+        // TODO: analyze the block (or bail with a comptimeExpr)
+        extra_index += section_body_len;
+    } else {
+        // default alignment
+    }
+
+    var cc_index: ?usize = null;
+    if (extra.data.bits.has_cc_ref) {
         const cc_ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
         cc_index = self.exprs.items.len;
         _ = try self.walkRef(file, scope, cc_ref, false);
         extra_index += 1;
+    } else if (extra.data.bits.has_cc_body) {
+        const cc_body_len = file.zir.extra[extra_index];
+        extra_index += 1;
+        const cc_body = file.zir.extra[extra_index .. extra_index + cc_body_len];
+        _ = cc_body;
+        // TODO: analyze the block (or bail with a comptimeExpr)
+        extra_index += cc_body_len;
+    } else {
+        // auto calling convention
     }
 
-    if (extra.data.bits.has_align) {
-        const align_ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
-        align_index = self.exprs.items.len;
-        _ = try self.walkRef(file, scope, align_ref, false);
-    }
+    // ret
+    const ret_type_ref: DocData.Expr = switch (fn_info.ret_ty_body.len) {
+        0 => switch (fn_info.ret_ty_ref) {
+            .none => DocData.Expr{ .void = .{} },
+            else => blk: {
+                const ref = fn_info.ret_ty_ref;
+                const wr = try self.walkRef(file, scope, ref, false);
+                break :blk wr.expr;
+            },
+        },
+        else => blk: {
+            const last_instr_index = fn_info.ret_ty_body[fn_info.ret_ty_body.len - 1];
+            const break_operand = data[last_instr_index].@"break".operand;
+            const wr = try self.walkRef(file, scope, break_operand, false);
+            break :blk wr.expr;
+        },
+    };
 
     // TODO: a complete version of this will probably need a scope
     //       in order to evaluate correctly closures around funcion
     //       parameters etc.
-    const generic_ret: ?DocData.Expr = switch (ret_type_ref.expr) {
+    const generic_ret: ?DocData.Expr = switch (ret_type_ref) {
         .type => |t| blk: {
             if (fn_info.body.len == 0) break :blk null;
             if (t == @enumToInt(Ref.type_type)) {
@@ -3265,11 +3327,11 @@ fn analyzeFunctionExtended(
             .name = "todo_name func",
             .src = self_ast_node_index,
             .params = param_type_refs.items,
-            .ret = ret_type_ref.expr,
+            .ret = ret_type_ref,
             .generic_ret = generic_ret,
             .is_extern = extra.data.bits.is_extern,
-            .has_cc = extra.data.bits.has_cc,
-            .has_align = extra.data.bits.has_align,
+            .has_cc = cc_index != null,
+            .has_align = align_index != null,
             .has_lib_name = extra.data.bits.has_lib_name,
             .lib_name = lib_name,
             .is_inferred_error = extra.data.bits.is_inferred_error,
@@ -3359,19 +3421,28 @@ fn analyzeFunction(
     }
 
     // ret
-    const ret_type_ref = blk: {
-        // const last_instr_index = fn_info.ret_ty_body[fn_info.ret_ty_body.len - 1];
-        // const break_operand = data[last_instr_index].@"break".operand;
-        // const wr = try self.walkRef(file, scope, break_operand, false);
-        const wr = try self.walkRef(file, scope, fn_info.ret_ty_ref, false);
-
-        break :blk wr;
+    const ret_type_ref: DocData.Expr = switch (fn_info.ret_ty_body.len) {
+        0 => switch (fn_info.ret_ty_ref) {
+            .none => DocData.Expr{ .void = .{} },
+            else => blk: {
+                const ref = fn_info.ret_ty_ref;
+                const wr = try self.walkRef(file, scope, ref, false);
+                break :blk wr.expr;
+            },
+        },
+        else => blk: {
+            //const last_instr_index = fn_info.ret_ty_body[fn_info.ret_ty_body.len - 1];
+            //const break_operand = data[last_instr_index].@"break".operand;
+            //const wr = try self.walkRef(file, scope, break_operand, false);
+            const wr = try self.walkRef(file, scope, fn_info.ret_ty_ref, false);
+            break :blk wr.expr;
+        },
     };
 
     // TODO: a complete version of this will probably need a scope
     //       in order to evaluate correctly closures around funcion
     //       parameters etc.
-    const generic_ret: ?DocData.Expr = switch (ret_type_ref.expr) {
+    const generic_ret: ?DocData.Expr = switch (ret_type_ref) {
         .type => |t| blk: {
             if (fn_info.body.len == 0) break :blk null;
             if (t == @enumToInt(Ref.type_type)) {
@@ -3393,7 +3464,7 @@ fn analyzeFunction(
             .name = "todo_name func",
             .src = self_ast_node_index,
             .params = param_type_refs.items,
-            .ret = ret_type_ref.expr,
+            .ret = ret_type_ref,
             .generic_ret = generic_ret,
         },
     };