authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-30 23:11:20-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-30 23:11:20-07:00
log351b57497b1cf2ea6ee72a3c7cfdb84b924bb368
tree5c5d8c4185edbc6453daa80aa19f307fda0a99d7
parent077b8d3def537b9a36330c14c39bfa77b2e122bc

stage2: implement function body analysis

now with whole-file-astgen

2 files changed, 72 insertions(+), 45 deletions(-)

src/Module.zig+38-42
......@@ -3986,48 +3986,44 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) !void {
39863986 param_inst.* = &arg_inst.base;
39873987 }
39883988
3989 var f = false;
3990 if (f) {
3991 return error.AnalysisFail;
3992 }
3993 @panic("TODO reimplement analyzeFnBody now that ZIR is whole-file");
3994
3995 //var sema: Sema = .{
3996 // .mod = mod,
3997 // .gpa = mod.gpa,
3998 // .arena = &arena.allocator,
3999 // .code = func.zir,
4000 // .inst_map = try mod.gpa.alloc(*ir.Inst, func.zir.instructions.len),
4001 // .owner_decl = decl,
4002 // .namespace = decl.namespace,
4003 // .func = func,
4004 // .owner_func = func,
4005 // .param_inst_list = param_inst_list,
4006 //};
4007 //defer mod.gpa.free(sema.inst_map);
4008
4009 //var inner_block: Scope.Block = .{
4010 // .parent = null,
4011 // .sema = &sema,
4012 // .src_decl = decl,
4013 // .instructions = .{},
4014 // .inlining = null,
4015 // .is_comptime = false,
4016 //};
4017 //defer inner_block.instructions.deinit(mod.gpa);
4018
4019 //// AIR currently requires the arg parameters to be the first N instructions
4020 //try inner_block.instructions.appendSlice(mod.gpa, param_inst_list);
4021
4022 //func.state = .in_progress;
4023 //log.debug("set {s} to in_progress", .{decl.name});
4024
4025 //_ = try sema.root(&inner_block);
4026
4027 //const instructions = try arena.allocator.dupe(*ir.Inst, inner_block.instructions.items);
4028 //func.state = .success;
4029 //func.body = .{ .instructions = instructions };
4030 //log.debug("set {s} to success", .{decl.name});
3989 const zir = decl.namespace.file_scope.zir;
3990
3991 var sema: Sema = .{
3992 .mod = mod,
3993 .gpa = mod.gpa,
3994 .arena = &arena.allocator,
3995 .code = zir,
3996 .inst_map = try mod.gpa.alloc(*ir.Inst, zir.instructions.len),
3997 .owner_decl = decl,
3998 .namespace = decl.namespace,
3999 .func = func,
4000 .owner_func = func,
4001 .param_inst_list = param_inst_list,
4002 };
4003 defer mod.gpa.free(sema.inst_map);
4004
4005 var inner_block: Scope.Block = .{
4006 .parent = null,
4007 .sema = &sema,
4008 .src_decl = decl,
4009 .instructions = .{},
4010 .inlining = null,
4011 .is_comptime = false,
4012 };
4013 defer inner_block.instructions.deinit(mod.gpa);
4014
4015 // AIR currently requires the arg parameters to be the first N instructions
4016 try inner_block.instructions.appendSlice(mod.gpa, param_inst_list);
4017
4018 func.state = .in_progress;
4019 log.debug("set {s} to in_progress", .{decl.name});
4020
4021 try sema.analyzeFnBody(&inner_block, func.zir_body_inst);
4022
4023 const instructions = try arena.allocator.dupe(*ir.Inst, inner_block.instructions.items);
4024 func.state = .success;
4025 func.body = .{ .instructions = instructions };
4026 log.debug("set {s} to success", .{decl.name});
40314027}
40324028
40334029fn markOutdatedDecl(mod: *Module, decl: *Decl) !void {
src/Sema.zig+34-3
......@@ -65,6 +65,39 @@ const LazySrcLoc = Module.LazySrcLoc;
6565const RangeSet = @import("RangeSet.zig");
6666const AstGen = @import("AstGen.zig");
6767
68pub fn analyzeFnBody(
69 sema: *Sema,
70 block: *Scope.Block,
71 fn_body_inst: Zir.Inst.Index,
72) InnerError!void {
73 const tags = sema.code.instructions.items(.tag);
74 const datas = sema.code.instructions.items(.data);
75 const body: []const Zir.Inst.Index = switch (tags[fn_body_inst]) {
76 .func, .func_inferred => blk: {
77 const inst_data = datas[fn_body_inst].pl_node;
78 const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index);
79 const param_types_len = extra.data.param_types_len;
80 const body = sema.code.extra[extra.end + param_types_len ..][0..extra.data.body_len];
81 break :blk body;
82 },
83 .extended => blk: {
84 const extended = datas[fn_body_inst].extended;
85 assert(extended.opcode == .func);
86 const extra = sema.code.extraData(Zir.Inst.ExtendedFunc, extended.operand);
87 const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small);
88 var extra_index: usize = extra.end;
89 extra_index += @boolToInt(small.has_lib_name);
90 extra_index += @boolToInt(small.has_cc);
91 extra_index += @boolToInt(small.has_align);
92 extra_index += extra.data.param_types_len;
93 const body = sema.code.extra[extra_index..][0..extra.data.body_len];
94 break :blk body;
95 },
96 else => unreachable,
97 };
98 _ = try sema.analyzeBody(block, body);
99}
100
68101/// Returns only the result from the body that is specified.
69102/// Only appropriate to call when it is determined at comptime that this body
70103/// has no peers.
......@@ -2088,11 +2121,9 @@ fn analyzeCall(
20882121
20892122 try inline_sema.emitBackwardBranch(&child_block, call_src);
20902123
2091 if (true) @panic("TODO re-implement inline function calls");
2092
20932124 // This will have return instructions analyzed as break instructions to
20942125 // the block_inst above.
2095 _ = try inline_sema.root(&child_block);
2126 try inline_sema.analyzeFnBody(&child_block, module_fn.zir_body_inst);
20962127
20972128 const result = try inline_sema.analyzeBlockBody(block, call_src, &child_block, merges);
20982129