| author | |
| committer | |
| log | 9b1aac8a654d1ee3515e2de8d477cf1909e63fdf |
| tree | bfd2fe07757b34890e712e4c60810350be0823af |
| parent | c714a3250f57817ea565f0390cecf12025655376 |
now it walks into functions and blocks to find decls.2 files changed, 152 insertions(+), 11 deletions(-)
src/Module.zig+36-11| ... | @@ -438,13 +438,24 @@ pub const Decl = struct { | ... | @@ -438,13 +438,24 @@ pub const Decl = struct { |
| 438 | 438 | ||
| 439 | /// If the Decl has a value and it is a struct, return it, | 439 | /// If the Decl has a value and it is a struct, return it, |
| 440 | /// otherwise null. | 440 | /// otherwise null. |
| 441 | pub fn getStruct(decl: Decl) ?*Struct { | 441 | pub fn getStruct(decl: *Decl) ?*Struct { |
| 442 | if (!decl.has_tv) return null; | 442 | if (!decl.has_tv) return null; |
| 443 | const ty = (decl.val.castTag(.ty) orelse return null).data; | 443 | const ty = (decl.val.castTag(.ty) orelse return null).data; |
| 444 | const struct_obj = (ty.castTag(.@"struct") orelse return null).data; | 444 | const struct_obj = (ty.castTag(.@"struct") orelse return null).data; |
| 445 | if (struct_obj.owner_decl != decl) return null; | ||
| 445 | return struct_obj; | 446 | return struct_obj; |
| 446 | } | 447 | } |
| 447 | 448 | ||
| 449 | /// If the Decl has a value and it is a function, return it, | ||
| 450 | /// otherwise null. | ||
| 451 | pub fn getFunction(decl: *Decl) ?*Fn { | ||
| 452 | if (!decl.has_tv) return null; | ||
| 453 | if (decl.ty.zigTypeTag() != .Fn) return null; | ||
| 454 | const func = (decl.val.castTag(.function) orelse return null).data; | ||
| 455 | if (func.owner_decl != decl) return null; | ||
| 456 | return func; | ||
| 457 | } | ||
| 458 | |||
| 448 | pub fn dump(decl: *Decl) void { | 459 | pub fn dump(decl: *Decl) void { |
| 449 | const loc = std.zig.findLineColumn(decl.scope.source.bytes, decl.src); | 460 | const loc = std.zig.findLineColumn(decl.scope.source.bytes, decl.src); |
| 450 | std.debug.print("{s}:{d}:{d} name={s} status={s}", .{ | 461 | std.debug.print("{s}:{d}:{d} name={s} status={s}", .{ |
| ... | @@ -2378,6 +2389,7 @@ const UpdateChangeList = struct { | ... | @@ -2378,6 +2389,7 @@ const UpdateChangeList = struct { |
| 2378 | 2389 | ||
| 2379 | /// Patch ups: | 2390 | /// Patch ups: |
| 2380 | /// * Struct.zir_index | 2391 | /// * Struct.zir_index |
| 2392 | /// * Fn.zir_body_inst | ||
| 2381 | /// * Decl.zir_decl_index | 2393 | /// * Decl.zir_decl_index |
| 2382 | /// * Decl.name | 2394 | /// * Decl.name |
| 2383 | /// * Namespace.decl keys | 2395 | /// * Namespace.decl keys |
| ... | @@ -2454,6 +2466,13 @@ fn updateZirRefs(gpa: *Allocator, file: *Scope.File, old_zir: Zir) !UpdateChange | ... | @@ -2454,6 +2466,13 @@ fn updateZirRefs(gpa: *Allocator, file: *Scope.File, old_zir: Zir) !UpdateChange |
| 2454 | }; | 2466 | }; |
| 2455 | } | 2467 | } |
| 2456 | 2468 | ||
| 2469 | if (decl.getFunction()) |func| { | ||
| 2470 | func.zir_body_inst = inst_map.get(func.zir_body_inst) orelse { | ||
| 2471 | try deleted_decls.append(gpa, decl); | ||
| 2472 | continue; | ||
| 2473 | }; | ||
| 2474 | } | ||
| 2475 | |||
| 2457 | if (decl.val.getTypeNamespace()) |namespace| { | 2476 | if (decl.val.getTypeNamespace()) |namespace| { |
| 2458 | for (namespace.decls.items()) |*entry| { | 2477 | for (namespace.decls.items()) |*entry| { |
| 2459 | const sub_decl = entry.value; | 2478 | const sub_decl = entry.value; |
| ... | @@ -2503,6 +2522,11 @@ pub fn mapOldZirToNew( | ... | @@ -2503,6 +2522,11 @@ pub fn mapOldZirToNew( |
| 2503 | .new_inst = new_main_struct_inst, | 2522 | .new_inst = new_main_struct_inst, |
| 2504 | }); | 2523 | }); |
| 2505 | 2524 | ||
| 2525 | var old_decls = std.ArrayList(Zir.Inst.Index).init(gpa); | ||
| 2526 | defer old_decls.deinit(); | ||
| 2527 | var new_decls = std.ArrayList(Zir.Inst.Index).init(gpa); | ||
| 2528 | defer new_decls.deinit(); | ||
| 2529 | |||
| 2506 | while (match_stack.popOrNull()) |match_item| { | 2530 | while (match_stack.popOrNull()) |match_item| { |
| 2507 | try inst_map.put(gpa, match_item.old_inst, match_item.new_inst); | 2531 | try inst_map.put(gpa, match_item.old_inst, match_item.new_inst); |
| 2508 | 2532 | ||
| ... | @@ -2523,16 +2547,17 @@ pub fn mapOldZirToNew( | ... | @@ -2523,16 +2547,17 @@ pub fn mapOldZirToNew( |
| 2523 | const new_extra_index = new_decl.sub_index; | 2547 | const new_extra_index = new_decl.sub_index; |
| 2524 | try extra_map.put(gpa, old_extra_index, new_extra_index); | 2548 | try extra_map.put(gpa, old_extra_index, new_extra_index); |
| 2525 | 2549 | ||
| 2526 | //var old_it = declInstIterator(old_zir, old_extra_index); | 2550 | try old_zir.findDecls(&old_decls, old_extra_index); |
| 2527 | //var new_it = declInstIterator(new_zir, new_extra_index); | 2551 | try new_zir.findDecls(&new_decls, new_extra_index); |
| 2528 | //while (true) { | 2552 | var i: usize = 0; |
| 2529 | // const old_decl_inst = old_it.next() orelse break; | 2553 | while (true) : (i += 1) { |
| 2530 | // const new_decl_inst = new_it.next() orelse break; | 2554 | if (i >= old_decls.items.len) break; |
| 2531 | // try match_stack.append(gpa, .{ | 2555 | if (i >= new_decls.items.len) break; |
| 2532 | // .old_inst = old_decl_inst, | 2556 | try match_stack.append(gpa, .{ |
| 2533 | // .new_inst = new_decl_inst, | 2557 | .old_inst = old_decls.items[i], |
| 2534 | // }); | 2558 | .new_inst = new_decls.items[i], |
| 2535 | //} | 2559 | }); |
| 2560 | } | ||
| 2536 | } | 2561 | } |
| 2537 | } | 2562 | } |
| 2538 | } | 2563 | } |
src/Zir.zig+116| ... | @@ -4427,6 +4427,15 @@ pub fn declIterator(zir: Zir, decl_inst: u32) DeclIterator { | ... | @@ -4427,6 +4427,15 @@ pub fn declIterator(zir: Zir, decl_inst: u32) DeclIterator { |
| 4427 | }; | 4427 | }; |
| 4428 | }, | 4428 | }, |
| 4429 | 4429 | ||
| 4430 | // Functions are allowed and yield no iterations. | ||
| 4431 | .func, | ||
| 4432 | .func_inferred, | ||
| 4433 | .extended, // assume also a function | ||
| 4434 | => .{ | ||
| 4435 | .extra_index = 0, | ||
| 4436 | .decls_len = 0, | ||
| 4437 | }, | ||
| 4438 | |||
| 4430 | else => unreachable, | 4439 | else => unreachable, |
| 4431 | }; | 4440 | }; |
| 4432 | 4441 | ||
| ... | @@ -4441,3 +4450,110 @@ pub fn declIterator(zir: Zir, decl_inst: u32) DeclIterator { | ... | @@ -4441,3 +4450,110 @@ pub fn declIterator(zir: Zir, decl_inst: u32) DeclIterator { |
| 4441 | .decls_len = decl_info.decls_len, | 4450 | .decls_len = decl_info.decls_len, |
| 4442 | }; | 4451 | }; |
| 4443 | } | 4452 | } |
| 4453 | |||
| 4454 | /// The iterator would have to allocate memory anyway to iterate. So here we populate | ||
| 4455 | /// an ArrayList as the result. | ||
| 4456 | pub fn findDecls(zir: Zir, list: *std.ArrayList(Zir.Inst.Index), decl_sub_index: u32) !void { | ||
| 4457 | const block_inst = zir.extra[decl_sub_index + 6]; | ||
| 4458 | list.clearRetainingCapacity(); | ||
| 4459 | |||
| 4460 | return zir.findDeclsInner(list, block_inst); | ||
| 4461 | } | ||
| 4462 | |||
| 4463 | fn findDeclsInner( | ||
| 4464 | zir: Zir, | ||
| 4465 | list: *std.ArrayList(Zir.Inst.Index), | ||
| 4466 | inst: Zir.Inst.Index, | ||
| 4467 | ) Allocator.Error!void { | ||
| 4468 | const tags = zir.instructions.items(.tag); | ||
| 4469 | const datas = zir.instructions.items(.data); | ||
| 4470 | |||
| 4471 | switch (tags[inst]) { | ||
| 4472 | // Decl instructions are interesting but have no body. | ||
| 4473 | .struct_decl, | ||
| 4474 | .struct_decl_packed, | ||
| 4475 | .struct_decl_extern, | ||
| 4476 | .union_decl, | ||
| 4477 | .union_decl_packed, | ||
| 4478 | .union_decl_extern, | ||
| 4479 | .enum_decl, | ||
| 4480 | .enum_decl_nonexhaustive, | ||
| 4481 | .opaque_decl, | ||
| 4482 | => return list.append(inst), | ||
| 4483 | |||
| 4484 | // Functions instructions are interesting and have a body. | ||
| 4485 | .func, | ||
| 4486 | .func_inferred, | ||
| 4487 | => { | ||
| 4488 | try list.append(inst); | ||
| 4489 | |||
| 4490 | const inst_data = datas[inst].pl_node; | ||
| 4491 | const extra = zir.extraData(Inst.Func, inst_data.payload_index); | ||
| 4492 | const param_types_len = extra.data.param_types_len; | ||
| 4493 | const body = zir.extra[extra.end + param_types_len ..][0..extra.data.body_len]; | ||
| 4494 | return zir.findDeclsBody(list, body); | ||
| 4495 | }, | ||
| 4496 | .extended => { | ||
| 4497 | const extended = datas[inst].extended; | ||
| 4498 | if (extended.opcode != .func) return; | ||
| 4499 | |||
| 4500 | try list.append(inst); | ||
| 4501 | |||
| 4502 | const extra = zir.extraData(Inst.ExtendedFunc, extended.operand); | ||
| 4503 | const small = @bitCast(Inst.ExtendedFunc.Small, extended.small); | ||
| 4504 | var extra_index: usize = extra.end; | ||
| 4505 | extra_index += @boolToInt(small.has_lib_name); | ||
| 4506 | extra_index += @boolToInt(small.has_cc); | ||
| 4507 | extra_index += @boolToInt(small.has_align); | ||
| 4508 | extra_index += extra.data.param_types_len; | ||
| 4509 | const body = zir.extra[extra_index..][0..extra.data.body_len]; | ||
| 4510 | return zir.findDeclsBody(list, body); | ||
| 4511 | }, | ||
| 4512 | |||
| 4513 | // Block instructions, recurse over the bodies. | ||
| 4514 | |||
| 4515 | .block, .block_inline => { | ||
| 4516 | const inst_data = datas[inst].pl_node; | ||
| 4517 | const extra = zir.extraData(Inst.Block, inst_data.payload_index); | ||
| 4518 | const body = zir.extra[extra.end..][0..extra.data.body_len]; | ||
| 4519 | return zir.findDeclsBody(list, body); | ||
| 4520 | }, | ||
| 4521 | .condbr, .condbr_inline => { | ||
| 4522 | const inst_data = datas[inst].pl_node; | ||
| 4523 | const extra = zir.extraData(Inst.CondBr, inst_data.payload_index); | ||
| 4524 | const then_body = zir.extra[extra.end..][0..extra.data.then_body_len]; | ||
| 4525 | const else_body = zir.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]; | ||
| 4526 | try zir.findDeclsBody(list, then_body); | ||
| 4527 | try zir.findDeclsBody(list, else_body); | ||
| 4528 | }, | ||
| 4529 | .switch_block, | ||
| 4530 | .switch_block_else, | ||
| 4531 | .switch_block_under, | ||
| 4532 | .switch_block_ref, | ||
| 4533 | .switch_block_ref_else, | ||
| 4534 | .switch_block_ref_under, | ||
| 4535 | => @panic("TODO iterate switch block"), | ||
| 4536 | |||
| 4537 | .switch_block_multi, | ||
| 4538 | .switch_block_else_multi, | ||
| 4539 | .switch_block_under_multi, | ||
| 4540 | .switch_block_ref_multi, | ||
| 4541 | .switch_block_ref_else_multi, | ||
| 4542 | .switch_block_ref_under_multi, | ||
| 4543 | => @panic("TODO iterate switch block multi"), | ||
| 4544 | |||
| 4545 | .suspend_block => @panic("TODO iterate suspend block"), | ||
| 4546 | |||
| 4547 | else => return, // Regular instruction, not interesting. | ||
| 4548 | } | ||
| 4549 | } | ||
| 4550 | |||
| 4551 | fn findDeclsBody( | ||
| 4552 | zir: Zir, | ||
| 4553 | list: *std.ArrayList(Zir.Inst.Index), | ||
| 4554 | body: []const Zir.Inst.Index, | ||
| 4555 | ) Allocator.Error!void { | ||
| 4556 | for (body) |member| { | ||
| 4557 | try zir.findDeclsInner(list, member); | ||
| 4558 | } | ||
| 4559 | } |