From 8ec34eb0463d489f109a228d4528ebfbec2dc733 Mon Sep 17 00:00:00 2001 From: Loris Cro Date: Sun, 12 Jun 2022 19:01:08 +0200 Subject: [PATCH] autodoc: handle result location instructions --- lib/docs/main.js | 21 ++++++++++++++--- src/Autodoc.zig | 60 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 66 insertions(+), 15 deletions(-) diff --git a/lib/docs/main.js b/lib/docs/main.js index 01d58c0db0..99f5f84d3b 100644 --- a/lib/docs/main.js +++ b/lib/docs/main.js @@ -529,6 +529,16 @@ var zigAnalysis; if (typeIsGenericFn(value.expr.type)) { // does the generic_ret contain a container? var resolvedGenericRet = resolveValue({expr: typeObj.generic_ret}); + + if ("call" in resolvedGenericRet.expr){ + let call = zigAnalysis.calls[resolvedGenericRet.expr.call]; + let resolvedFunc = resolveValue({expr: call.func}); + if (!("type" in resolvedFunc.expr)) return; + let callee = zigAnalysis.types[resolvedFunc.expr.type]; + if (!callee.generic_ret) return; + resolvedGenericRet = resolveValue({expr: callee.generic_ret}); + } + // TODO: see if unwrapping the `as` here is a good idea or not. if ("as" in resolvedGenericRet.expr) { resolvedGenericRet = { @@ -753,7 +763,6 @@ var zigAnalysis; function navLinkPkg(pkgIndex) { - console.log(canonPkgPaths); return navLink(canonPkgPaths[pkgIndex], []); } @@ -825,7 +834,7 @@ var zigAnalysis; } case "enumLiteral": { let literal = expr.enumLiteral; - return literal; + return "." + literal; } case "void": { return "void"; @@ -923,7 +932,13 @@ var zigAnalysis; const declRef = expr.refPath[0].declRef; let name = zigAnalysis.decls[declRef].name; for (let i = 1; i < expr.refPath.length; i++) { - name += "." + exprName(expr.refPath[i]); + let component = undefined; + if ("string" in expr.refPath[i]) { + component = expr.refPath[i].string; + } else { + component = exprName(expr.refPath[i]); + } + name += "." + component; } return name; } diff --git a/src/Autodoc.zig b/src/Autodoc.zig index 095eec4564..1c4beed4a1 100644 --- a/src/Autodoc.zig +++ b/src/Autodoc.zig @@ -738,18 +738,6 @@ fn walkInstruction( ); return self.cteTodo(@tagName(tags[inst_index])); }, - .ret_node => { - const un_node = data[inst_index].un_node; - return self.walkRef(file, parent_scope, un_node.operand, false); - }, - .closure_get => { - const inst_node = data[inst_index].inst_node; - return try self.walkInstruction(file, parent_scope, inst_node.inst, need_type); - }, - .closure_capture => { - const un_tok = data[inst_index].un_tok; - return try self.walkRef(file, parent_scope, un_tok.operand, need_type); - }, .import => { const str_tok = data[inst_index].str_tok; var path = str_tok.get(file.zir); @@ -848,6 +836,54 @@ fn walkInstruction( need_type, ); }, + .ret_node => { + const un_node = data[inst_index].un_node; + return self.walkRef(file, parent_scope, un_node.operand, false); + }, + .ret_load => { + const un_node = data[inst_index].un_node; + const res_ptr_ref = un_node.operand; + const res_ptr_inst = @enumToInt(res_ptr_ref) - Ref.typed_value_map.len; + // TODO: this instruction doesn't let us know trivially if there's + // branching involved or not. For now here's the strat: + // We search backwarts until `ret_ptr` for `store_node`, + // if we find only one, then that's our value, if we find more + // than one, then it means that there's branching involved. + // Maybe. + + var i = inst_index - 1; + var result_ref: ?Ref = null; + while (i > res_ptr_inst) : (i -= 1) { + if (tags[i] == .store_node) { + const pl_node = data[i].pl_node; + const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index); + if (extra.data.lhs == res_ptr_ref) { + // this store_load instruction is indeed pointing at + // the result location that we care about! + if (result_ref != null) return DocData.WalkResult{ + .expr = .{ .comptimeExpr = 0 }, + }; + result_ref = extra.data.rhs; + } + } + } + + if (result_ref) |rr| { + return self.walkRef(file, parent_scope, rr, need_type); + } + + return DocData.WalkResult{ + .expr = .{ .comptimeExpr = 0 }, + }; + }, + .closure_get => { + const inst_node = data[inst_index].inst_node; + return try self.walkInstruction(file, parent_scope, inst_node.inst, need_type); + }, + .closure_capture => { + const un_tok = data[inst_index].un_tok; + return try self.walkRef(file, parent_scope, un_tok.operand, need_type); + }, .cmpxchg_strong, .cmpxchg_weak => { const pl_node = data[inst_index].pl_node; const extra = file.zir.extraData(Zir.Inst.Cmpxchg, pl_node.payload_index);