aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Module.zig80
-rw-r--r--src/Sema.zig37
2 files changed, 72 insertions, 45 deletions
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");
-
- //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 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);
-
- //func.state = .in_progress;
- //log.debug("set {s} to in_progress", .{decl.name});
-
- //_ = try sema.root(&inner_block);
-
- //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 zir = decl.namespace.file_scope.zir;
+
+ 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);
+
+ // 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});
+
+ 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});
}
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);