diff --git a/src/Module.zig b/src/Module.zig index a64fb491e1..7bf117b875 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -3986,48 +3986,44 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) !void { param_inst.* = &arg_inst.base; } - var f = false; - if (f) { - return error.AnalysisFail; - } - @panic("TODO reimplement analyzeFnBody now that ZIR is whole-file"); + const zir = decl.namespace.file_scope.zir; - //var sema: Sema = .{ - // .mod = mod, - // .gpa = mod.gpa, - // .arena = &arena.allocator, - // .code = func.zir, - // .inst_map = try mod.gpa.alloc(*ir.Inst, func.zir.instructions.len), - // .owner_decl = decl, - // .namespace = decl.namespace, - // .func = func, - // .owner_func = func, - // .param_inst_list = param_inst_list, - //}; - //defer mod.gpa.free(sema.inst_map); + var sema: Sema = .{ + .mod = mod, + .gpa = mod.gpa, + .arena = &arena.allocator, + .code = zir, + .inst_map = try mod.gpa.alloc(*ir.Inst, zir.instructions.len), + .owner_decl = decl, + .namespace = decl.namespace, + .func = func, + .owner_func = func, + .param_inst_list = param_inst_list, + }; + defer mod.gpa.free(sema.inst_map); - //var inner_block: Scope.Block = .{ - // .parent = null, - // .sema = &sema, - // .src_decl = decl, - // .instructions = .{}, - // .inlining = null, - // .is_comptime = false, - //}; - //defer inner_block.instructions.deinit(mod.gpa); + var inner_block: Scope.Block = .{ + .parent = null, + .sema = &sema, + .src_decl = decl, + .instructions = .{}, + .inlining = null, + .is_comptime = false, + }; + defer inner_block.instructions.deinit(mod.gpa); - //// AIR currently requires the arg parameters to be the first N instructions - //try inner_block.instructions.appendSlice(mod.gpa, param_inst_list); + // AIR currently requires the arg parameters to be the first N instructions + try inner_block.instructions.appendSlice(mod.gpa, param_inst_list); - //func.state = .in_progress; - //log.debug("set {s} to in_progress", .{decl.name}); + func.state = .in_progress; + log.debug("set {s} to in_progress", .{decl.name}); - //_ = try sema.root(&inner_block); + try sema.analyzeFnBody(&inner_block, func.zir_body_inst); - //const instructions = try arena.allocator.dupe(*ir.Inst, inner_block.instructions.items); - //func.state = .success; - //func.body = .{ .instructions = instructions }; - //log.debug("set {s} to success", .{decl.name}); + const instructions = try arena.allocator.dupe(*ir.Inst, inner_block.instructions.items); + func.state = .success; + func.body = .{ .instructions = instructions }; + log.debug("set {s} to success", .{decl.name}); } fn markOutdatedDecl(mod: *Module, decl: *Decl) !void { diff --git a/src/Sema.zig b/src/Sema.zig index 298541cb08..44f8c7d370 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -65,6 +65,39 @@ const LazySrcLoc = Module.LazySrcLoc; const RangeSet = @import("RangeSet.zig"); const AstGen = @import("AstGen.zig"); +pub fn analyzeFnBody( + sema: *Sema, + block: *Scope.Block, + fn_body_inst: Zir.Inst.Index, +) InnerError!void { + const tags = sema.code.instructions.items(.tag); + const datas = sema.code.instructions.items(.data); + const body: []const Zir.Inst.Index = switch (tags[fn_body_inst]) { + .func, .func_inferred => blk: { + const inst_data = datas[fn_body_inst].pl_node; + const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index); + const param_types_len = extra.data.param_types_len; + const body = sema.code.extra[extra.end + param_types_len ..][0..extra.data.body_len]; + break :blk body; + }, + .extended => blk: { + const extended = datas[fn_body_inst].extended; + assert(extended.opcode == .func); + const extra = sema.code.extraData(Zir.Inst.ExtendedFunc, extended.operand); + const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small); + var extra_index: usize = extra.end; + extra_index += @boolToInt(small.has_lib_name); + extra_index += @boolToInt(small.has_cc); + extra_index += @boolToInt(small.has_align); + extra_index += extra.data.param_types_len; + const body = sema.code.extra[extra_index..][0..extra.data.body_len]; + break :blk body; + }, + else => unreachable, + }; + _ = try sema.analyzeBody(block, body); +} + /// Returns only the result from the body that is specified. /// Only appropriate to call when it is determined at comptime that this body /// has no peers. @@ -2088,11 +2121,9 @@ fn analyzeCall( try inline_sema.emitBackwardBranch(&child_block, call_src); - if (true) @panic("TODO re-implement inline function calls"); - // This will have return instructions analyzed as break instructions to // the block_inst above. - _ = try inline_sema.root(&child_block); + try inline_sema.analyzeFnBody(&child_block, module_fn.zir_body_inst); const result = try inline_sema.analyzeBlockBody(block, call_src, &child_block, merges);