| ... | ... | @@ -154,13 +154,9 @@ pub const DeclPlusEmitH = struct { |
| 154 | 154 | }; |
| 155 | 155 | |
| 156 | 156 | pub const Decl = struct { |
| 157 | | /// This name is relative to the containing namespace of the decl. |
| 158 | | /// All Decls have names, even values that are not bound to a zig namespace. |
| 159 | | /// This is necessary for mapping them to an address in the output file. |
| 160 | | /// Memory is owned by this decl, using Module's allocator. |
| 161 | | /// Note that this cannot be changed to reference ZIR memory because when |
| 162 | | /// ZIR updates, it would change the Decl name, but we still need the previous |
| 163 | | /// name to delete the Decl from the hash maps it has been inserted into. |
| 157 | /// For declarations that have corresponding source code, this is identical to |
| 158 | /// `getName().?`. For anonymous declarations this is allocated with Module's |
| 159 | /// allocator. |
| 164 | 160 | name: [*:0]const u8, |
| 165 | 161 | /// The most recent Type of the Decl after a successful semantic analysis. |
| 166 | 162 | /// Populated when `has_tv`. |
| ... | ... | @@ -186,10 +182,10 @@ pub const Decl = struct { |
| 186 | 182 | /// The AST node index of this declaration. |
| 187 | 183 | /// Must be recomputed when the corresponding source file is modified. |
| 188 | 184 | src_node: ast.Node.Index, |
| 189 | | /// Index to ZIR `extra` array to the block of ZIR code that encodes the Decl expression. |
| 190 | | zir_block_index: Zir.Inst.Index, |
| 191 | | zir_align_ref: Zir.Inst.Ref = .none, |
| 192 | | zir_linksection_ref: Zir.Inst.Ref = .none, |
| 185 | /// Index to ZIR `extra` array to the entry in the parent's decl structure |
| 186 | /// (the part that says "for every decls_len"). The first item at this index is |
| 187 | /// the contents hash, followed by the name. |
| 188 | zir_decl_index: Zir.Inst.Index, |
| 193 | 189 | |
| 194 | 190 | /// Represents the "shallow" analysis status. For example, for decls that are functions, |
| 195 | 191 | /// the function type is analyzed with this set to `in_progress`, however, the semantic |
| ... | ... | @@ -234,6 +230,10 @@ pub const Decl = struct { |
| 234 | 230 | is_pub: bool, |
| 235 | 231 | /// Whether the corresponding AST decl has a `export` keyword. |
| 236 | 232 | is_exported: bool, |
| 233 | /// Whether the ZIR code provides an align instruction. |
| 234 | has_align: bool, |
| 235 | /// Whether the ZIR code provides a linksection instruction. |
| 236 | has_linksection: bool, |
| 237 | 237 | |
| 238 | 238 | /// Represents the position of the code in the output file. |
| 239 | 239 | /// This is populated regardless of semantic analysis and code generation. |
| ... | ... | @@ -246,11 +246,6 @@ pub const Decl = struct { |
| 246 | 246 | /// to save on memory usage. |
| 247 | 247 | fn_link: link.File.LinkFn, |
| 248 | 248 | |
| 249 | | /// This is stored separately in addition to being available via `zir_decl_index` |
| 250 | | /// because when the underlying ZIR code is updated, this field is used to find |
| 251 | | /// out if anything changed. |
| 252 | | contents_hash: std.zig.SrcHash, |
| 253 | | |
| 254 | 249 | /// The shallow set of other decls whose typed_value could possibly change if this Decl's |
| 255 | 250 | /// typed_value is modified. |
| 256 | 251 | dependants: DepsTable = .{}, |
| ... | ... | @@ -260,7 +255,13 @@ pub const Decl = struct { |
| 260 | 255 | |
| 261 | 256 | /// The reason this is not `std.AutoArrayHashMapUnmanaged` is a workaround for |
| 262 | 257 | /// stage1 compiler giving me: `error: struct 'Module.Decl' depends on itself` |
| 263 | | pub const DepsTable = std.ArrayHashMapUnmanaged(*Decl, void, std.array_hash_map.getAutoHashFn(*Decl), std.array_hash_map.getAutoEqlFn(*Decl), false); |
| 258 | pub const DepsTable = std.ArrayHashMapUnmanaged( |
| 259 | *Decl, |
| 260 | void, |
| 261 | std.array_hash_map.getAutoHashFn(*Decl), |
| 262 | std.array_hash_map.getAutoEqlFn(*Decl), |
| 263 | false, |
| 264 | ); |
| 264 | 265 | |
| 265 | 266 | pub fn destroy(decl: *Decl, module: *Module) void { |
| 266 | 267 | const gpa = module.gpa; |
| ... | ... | @@ -283,6 +284,48 @@ pub const Decl = struct { |
| 283 | 284 | } |
| 284 | 285 | } |
| 285 | 286 | |
| 287 | /// This name is relative to the containing namespace of the decl. |
| 288 | /// The memory is owned by the containing File ZIR. |
| 289 | pub fn getName(decl: Decl) ?[:0]const u8 { |
| 290 | const zir = decl.namespace.file_scope.zir; |
| 291 | return decl.getNameZir(zir); |
| 292 | } |
| 293 | |
| 294 | pub fn getNameZir(decl: Decl, zir: Zir) ?[:0]const u8 { |
| 295 | const name_index = zir.extra[decl.zir_decl_index + 4]; |
| 296 | if (name_index <= 1) return null; |
| 297 | return zir.nullTerminatedString(name_index); |
| 298 | } |
| 299 | |
| 300 | pub fn contentsHash(decl: Decl) std.zig.SrcHash { |
| 301 | const zir = decl.namespace.file_scope.zir; |
| 302 | return decl.contentsHashZir(zir); |
| 303 | } |
| 304 | |
| 305 | pub fn contentsHashZir(decl: Decl, zir: Zir) std.zig.SrcHash { |
| 306 | const hash_u32s = zir.extra[decl.zir_decl_index..][0..4]; |
| 307 | const contents_hash = @bitCast(std.zig.SrcHash, hash_u32s.*); |
| 308 | return contents_hash; |
| 309 | } |
| 310 | |
| 311 | pub fn zirBlockIndex(decl: Decl) Zir.Inst.Index { |
| 312 | const zir = decl.namespace.file_scope.zir; |
| 313 | return zir.extra[decl.zir_decl_index + 5]; |
| 314 | } |
| 315 | |
| 316 | pub fn zirAlignRef(decl: Decl) Zir.Inst.Ref { |
| 317 | if (!decl.has_align) return .none; |
| 318 | const zir = decl.namespace.file_scope.zir; |
| 319 | return @intToEnum(Zir.Inst.Ref, zir.extra[decl.zir_decl_index + 6]); |
| 320 | } |
| 321 | |
| 322 | pub fn zirLinkSectionRef(decl: Decl) Zir.Inst.Ref { |
| 323 | if (!decl.has_linksection) return .none; |
| 324 | const zir = decl.namespace.file_scope.zir; |
| 325 | const extra_index = decl.zir_decl_index + 6 + @boolToInt(decl.has_align); |
| 326 | return @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]); |
| 327 | } |
| 328 | |
| 286 | 329 | pub fn relativeToNodeIndex(decl: Decl, offset: i32) ast.Node.Index { |
| 287 | 330 | return @bitCast(ast.Node.Index, offset + @bitCast(i32, decl.src_node)); |
| 288 | 331 | } |
| ... | ... | @@ -653,9 +696,6 @@ pub const Scope = struct { |
| 653 | 696 | /// TODO save memory with https://github.com/ziglang/zig/issues/8619. |
| 654 | 697 | /// Does not contain anonymous decls. |
| 655 | 698 | decls: std.StringArrayHashMapUnmanaged(*Decl) = .{}, |
| 656 | | /// Names imported into the namespace via `usingnamespace`. |
| 657 | | /// The key memory is owned by the ZIR of the `File` containing the `Namespace`. |
| 658 | | usingnamespace_decls: std.StringArrayHashMapUnmanaged(*Namespace) = .{}, |
| 659 | 699 | |
| 660 | 700 | pub fn deinit(ns: *Namespace, mod: *Module) void { |
| 661 | 701 | const gpa = mod.gpa; |
| ... | ... | @@ -715,6 +755,11 @@ pub const Scope = struct { |
| 715 | 755 | /// The namespace of the struct that represents this file. |
| 716 | 756 | /// Populated only when status is success. |
| 717 | 757 | namespace: *Namespace, |
| 758 | /// All namespaces that this file contains. This is here so that |
| 759 | /// when a file is updated, and new ZIR code is generated, the |
| 760 | /// old and new ZIR code can be compared side by side and references |
| 761 | /// to old ZIR updated to new ZIR, and a changelist generated. |
| 762 | namespace_set: std.AutoArrayHashMapUnmanaged(*Namespace, void) = .{}, |
| 718 | 763 | |
| 719 | 764 | pub fn unload(file: *File, gpa: *Allocator) void { |
| 720 | 765 | file.unloadTree(gpa); |
| ... | ... | @@ -2919,17 +2964,15 @@ pub fn astGenFile(mod: *Module, file: *Scope.File, prog_node: *std.Progress.Node |
| 2919 | 2964 | }, |
| 2920 | 2965 | }; |
| 2921 | 2966 | |
| 2922 | | // Clear compile error for this file. |
| 2923 | | switch (file.status) { |
| 2924 | | .success, .retryable_failure => {}, |
| 2925 | | .never_loaded, .parse_failure, .astgen_failure => { |
| 2926 | | const lock = comp.mutex.acquire(); |
| 2927 | | defer lock.release(); |
| 2928 | | if (mod.failed_files.swapRemove(file)) |entry| { |
| 2929 | | if (entry.value) |msg| msg.destroy(gpa); // Delete previous error message. |
| 2930 | | } |
| 2931 | | }, |
| 2932 | | } |
| 2967 | mod.lockAndClearFileCompileError(file); |
| 2968 | |
| 2969 | // Move previous ZIR to a local variable so we can compare it with the new one. |
| 2970 | var prev_zir = file.zir; |
| 2971 | const prev_zir_loaded = file.zir_loaded; |
| 2972 | file.zir_loaded = false; |
| 2973 | file.zir = undefined; |
| 2974 | defer if (prev_zir_loaded) prev_zir.deinit(gpa); |
| 2975 | |
| 2933 | 2976 | file.unload(gpa); |
| 2934 | 2977 | |
| 2935 | 2978 | if (stat.size > std.math.maxInt(u32)) |
| ... | ... | @@ -3041,6 +3084,18 @@ pub fn astGenFile(mod: *Module, file: *Scope.File, prog_node: *std.Progress.Node |
| 3041 | 3084 | }); |
| 3042 | 3085 | }; |
| 3043 | 3086 | |
| 3087 | if (prev_zir_loaded) { |
| 3088 | // Iterate over all Namespace objects contained within this File, looking at the |
| 3089 | // previous and new ZIR together and update the references to point |
| 3090 | // to the new one. For example, Decl name, Decl zir_decl_index, and Namespace |
| 3091 | // decl_table keys need to get updated to point to the new memory, even if the |
| 3092 | // underlying source code is unchanged. |
| 3093 | // We do not need to hold any locks at this time because all the Decl and Namespace |
| 3094 | // objects being touched are specific to this File, and the only other concurrent |
| 3095 | // tasks are touching other File objects. |
| 3096 | @panic("TODO implement update references from old ZIR to new ZIR"); |
| 3097 | } |
| 3098 | |
| 3044 | 3099 | // TODO don't report compile errors until Sema @importFile |
| 3045 | 3100 | if (file.zir.hasCompileErrors()) { |
| 3046 | 3101 | { |
| ... | ... | @@ -3168,10 +3223,11 @@ pub fn semaFile(mod: *Module, file: *Scope.File) InnerError!void { |
| 3168 | 3223 | .deletion_flag = false, |
| 3169 | 3224 | .is_pub = true, |
| 3170 | 3225 | .is_exported = false, |
| 3226 | .has_linksection = false, |
| 3227 | .has_align = false, |
| 3171 | 3228 | .link = undefined, // don't try to codegen this |
| 3172 | 3229 | .fn_link = undefined, // not a function |
| 3173 | | .contents_hash = undefined, // top-level struct has no contents hash |
| 3174 | | .zir_block_index = undefined, |
| 3230 | .zir_decl_index = undefined, |
| 3175 | 3231 | |
| 3176 | 3232 | .has_tv = false, |
| 3177 | 3233 | .ty = undefined, |
| ... | ... | @@ -3263,15 +3319,16 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { |
| 3263 | 3319 | }; |
| 3264 | 3320 | defer block_scope.instructions.deinit(gpa); |
| 3265 | 3321 | |
| 3266 | | const inst_data = zir.instructions.items(.data)[decl.zir_block_index].pl_node; |
| 3322 | const zir_block_index = decl.zirBlockIndex(); |
| 3323 | const inst_data = zir.instructions.items(.data)[zir_block_index].pl_node; |
| 3267 | 3324 | const extra = zir.extraData(Zir.Inst.Block, inst_data.payload_index); |
| 3268 | 3325 | const body = zir.extra[extra.end..][0..extra.data.body_len]; |
| 3269 | 3326 | const break_index = try sema.analyzeBody(&block_scope, body); |
| 3270 | 3327 | |
| 3271 | | if (decl.zir_align_ref != .none) { |
| 3328 | if (decl.zirAlignRef() != .none) { |
| 3272 | 3329 | @panic("TODO implement decl align"); |
| 3273 | 3330 | } |
| 3274 | | if (decl.zir_linksection_ref != .none) { |
| 3331 | if (decl.zirLinkSectionRef() != .none) { |
| 3275 | 3332 | @panic("TODO implement decl linksection"); |
| 3276 | 3333 | } |
| 3277 | 3334 | |
| ... | ... | @@ -3457,51 +3514,25 @@ pub fn scanNamespace( |
| 3457 | 3514 | var bit_bag_index: usize = extra_start; |
| 3458 | 3515 | var cur_bit_bag: u32 = undefined; |
| 3459 | 3516 | var decl_i: u32 = 0; |
| 3517 | var scan_decl_iter: ScanDeclIter = .{ |
| 3518 | .module = mod, |
| 3519 | .namespace = namespace, |
| 3520 | .deleted_decls = &deleted_decls, |
| 3521 | .outdated_decls = &outdated_decls, |
| 3522 | .parent_decl = parent_decl, |
| 3523 | }; |
| 3460 | 3524 | while (decl_i < decls_len) : (decl_i += 1) { |
| 3461 | 3525 | if (decl_i % 8 == 0) { |
| 3462 | 3526 | cur_bit_bag = zir.extra[bit_bag_index]; |
| 3463 | 3527 | bit_bag_index += 1; |
| 3464 | 3528 | } |
| 3465 | | const is_pub = @truncate(u1, cur_bit_bag) != 0; |
| 3466 | | cur_bit_bag >>= 1; |
| 3467 | | const is_exported = @truncate(u1, cur_bit_bag) != 0; |
| 3468 | | cur_bit_bag >>= 1; |
| 3469 | | const has_align = @truncate(u1, cur_bit_bag) != 0; |
| 3470 | | cur_bit_bag >>= 1; |
| 3471 | | const has_section = @truncate(u1, cur_bit_bag) != 0; |
| 3472 | | cur_bit_bag >>= 1; |
| 3473 | | |
| 3474 | | const hash_u32s = zir.extra[extra_index..][0..4]; |
| 3475 | | extra_index += 4; |
| 3476 | | const decl_name_index = zir.extra[extra_index]; |
| 3477 | | extra_index += 1; |
| 3478 | | const decl_index = zir.extra[extra_index]; |
| 3479 | | extra_index += 1; |
| 3480 | | const align_inst: Zir.Inst.Ref = if (!has_align) .none else inst: { |
| 3481 | | const inst = @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]); |
| 3482 | | extra_index += 1; |
| 3483 | | break :inst inst; |
| 3484 | | }; |
| 3485 | | const section_inst: Zir.Inst.Ref = if (!has_section) .none else inst: { |
| 3486 | | const inst = @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]); |
| 3487 | | extra_index += 1; |
| 3488 | | break :inst inst; |
| 3489 | | }; |
| 3490 | | const contents_hash = @bitCast(std.zig.SrcHash, hash_u32s.*); |
| 3529 | const flags = @truncate(u4, cur_bit_bag); |
| 3530 | const decl_sub_index = extra_index; |
| 3531 | extra_index += 6; |
| 3532 | extra_index += @truncate(u1, flags >> 2); |
| 3533 | extra_index += @truncate(u1, flags >> 3); |
| 3491 | 3534 | |
| 3492 | | try mod.scanDecl( |
| 3493 | | namespace, |
| 3494 | | &deleted_decls, |
| 3495 | | &outdated_decls, |
| 3496 | | contents_hash, |
| 3497 | | decl_name_index, |
| 3498 | | decl_index, |
| 3499 | | is_pub, |
| 3500 | | is_exported, |
| 3501 | | align_inst, |
| 3502 | | section_inst, |
| 3503 | | parent_decl, |
| 3504 | | ); |
| 3535 | try scanDecl(&scan_decl_iter, decl_sub_index, flags); |
| 3505 | 3536 | } |
| 3506 | 3537 | // Handle explicitly deleted decls from the source code. This is one of two |
| 3507 | 3538 | // places that Decl deletions happen. The other is in `Compilation`, after |
| ... | ... | @@ -3528,62 +3559,80 @@ pub fn scanNamespace( |
| 3528 | 3559 | return extra_index; |
| 3529 | 3560 | } |
| 3530 | 3561 | |
| 3531 | | fn scanDecl( |
| 3532 | | mod: *Module, |
| 3562 | const ScanDeclIter = struct { |
| 3563 | module: *Module, |
| 3533 | 3564 | namespace: *Scope.Namespace, |
| 3534 | 3565 | deleted_decls: *std.AutoArrayHashMap(*Decl, void), |
| 3535 | 3566 | outdated_decls: *std.AutoArrayHashMap(*Decl, void), |
| 3536 | | contents_hash: std.zig.SrcHash, |
| 3537 | | decl_name_index: u32, |
| 3538 | | decl_index: Zir.Inst.Index, |
| 3539 | | is_pub: bool, |
| 3540 | | is_exported: bool, |
| 3541 | | align_inst: Zir.Inst.Ref, |
| 3542 | | section_inst: Zir.Inst.Ref, |
| 3543 | 3567 | parent_decl: *Decl, |
| 3544 | | ) InnerError!void { |
| 3568 | usingnamespace_index: usize = 0, |
| 3569 | comptime_index: usize = 0, |
| 3570 | unnamed_test_index: usize = 0, |
| 3571 | }; |
| 3572 | |
| 3573 | fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) InnerError!void { |
| 3545 | 3574 | const tracy = trace(@src()); |
| 3546 | 3575 | defer tracy.end(); |
| 3547 | 3576 | |
| 3577 | const mod = iter.module; |
| 3578 | const namespace = iter.namespace; |
| 3548 | 3579 | const gpa = mod.gpa; |
| 3549 | 3580 | const zir = namespace.file_scope.zir; |
| 3550 | 3581 | |
| 3551 | | const decl_block_inst_data = zir.instructions.items(.data)[decl_index].pl_node; |
| 3552 | | const decl_node = parent_decl.relativeToNodeIndex(decl_block_inst_data.src_node); |
| 3582 | // zig fmt: off |
| 3583 | const is_pub = (flags & 0b0001) != 0; |
| 3584 | const is_exported = (flags & 0b0010) != 0; |
| 3585 | const has_align = (flags & 0b0100) != 0; |
| 3586 | const has_linksection = (flags & 0b1000) != 0; |
| 3587 | // zig fmt: on |
| 3553 | 3588 | |
| 3554 | | const decl_name: ?[]const u8 = if (decl_name_index > 1) |
| 3555 | | zir.nullTerminatedString(decl_name_index) |
| 3556 | | else |
| 3557 | | null; |
| 3589 | const decl_name_index = zir.extra[decl_sub_index + 4]; |
| 3590 | const decl_index = zir.extra[decl_sub_index + 5]; |
| 3591 | const decl_block_inst_data = zir.instructions.items(.data)[decl_index].pl_node; |
| 3592 | const decl_node = iter.parent_decl.relativeToNodeIndex(decl_block_inst_data.src_node); |
| 3593 | |
| 3594 | // Every Decl needs a name. |
| 3595 | const decl_name: [:0]const u8 = switch (decl_name_index) { |
| 3596 | 0 => name: { |
| 3597 | if (is_exported) { |
| 3598 | const i = iter.usingnamespace_index; |
| 3599 | iter.usingnamespace_index += 1; |
| 3600 | break :name try std.fmt.allocPrintZ(gpa, "usingnamespace${d}", .{i}); |
| 3601 | } else { |
| 3602 | const i = iter.comptime_index; |
| 3603 | iter.comptime_index += 1; |
| 3604 | break :name try std.fmt.allocPrintZ(gpa, "comptime${d}", .{i}); |
| 3605 | } |
| 3606 | }, |
| 3607 | 1 => name: { |
| 3608 | const i = iter.unnamed_test_index; |
| 3609 | iter.unnamed_test_index += 1; |
| 3610 | break :name try std.fmt.allocPrintZ(gpa, "test${d}", .{i}); |
| 3611 | }, |
| 3612 | else => zir.nullTerminatedString(decl_name_index), |
| 3613 | }; |
| 3558 | 3614 | |
| 3559 | 3615 | // We create a Decl for it regardless of analysis status. |
| 3560 | | // Decls that have names are keyed in the namespace by the name. Decls without |
| 3561 | | // names are keyed by their contents hash. This way we can detect if, for example, |
| 3562 | | // a comptime decl gets moved around in the file. |
| 3563 | | const decl_key = decl_name orelse &contents_hash; |
| 3564 | | const gop = try namespace.decls.getOrPut(gpa, decl_key); |
| 3616 | const gop = try namespace.decls.getOrPut(gpa, decl_name); |
| 3565 | 3617 | if (!gop.found_existing) { |
| 3566 | 3618 | const new_decl = try mod.allocateNewDecl(namespace, decl_node); |
| 3567 | | new_decl.contents_hash = contents_hash; |
| 3568 | | new_decl.name = try gpa.dupeZ(u8, decl_key); |
| 3569 | | // Update the key reference to the longer-lived memory. |
| 3570 | | gop.entry.key = &new_decl.contents_hash; |
| 3619 | new_decl.name = decl_name; |
| 3571 | 3620 | gop.entry.value = new_decl; |
| 3572 | 3621 | // Exported decls, comptime decls, usingnamespace decls, and |
| 3573 | 3622 | // test decls if in test mode, get analyzed. |
| 3574 | 3623 | const want_analysis = is_exported or switch (decl_name_index) { |
| 3575 | 3624 | 0 => true, // comptime decl |
| 3576 | 3625 | 1 => mod.comp.bin_file.options.is_test, // test decl |
| 3577 | | else => false, |
| 3626 | else => false, // TODO set to true for named tests when testing |
| 3578 | 3627 | }; |
| 3579 | 3628 | if (want_analysis) { |
| 3580 | 3629 | mod.comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl }); |
| 3581 | 3630 | } |
| 3582 | | new_decl.is_exported = is_exported; |
| 3583 | 3631 | new_decl.is_pub = is_pub; |
| 3584 | | new_decl.zir_block_index = decl_index; |
| 3585 | | new_decl.zir_align_ref = align_inst; |
| 3586 | | new_decl.zir_linksection_ref = section_inst; |
| 3632 | new_decl.is_exported = is_exported; |
| 3633 | new_decl.has_align = has_align; |
| 3634 | new_decl.has_linksection = has_linksection; |
| 3635 | new_decl.zir_decl_index = @intCast(u32, decl_sub_index); |
| 3587 | 3636 | return; |
| 3588 | 3637 | } |
| 3589 | 3638 | const decl = gop.entry.value; |
| ... | ... | @@ -3591,12 +3640,13 @@ fn scanDecl( |
| 3591 | 3640 | // have been re-ordered. |
| 3592 | 3641 | const prev_src_node = decl.src_node; |
| 3593 | 3642 | decl.src_node = decl_node; |
| 3643 | |
| 3594 | 3644 | decl.is_pub = is_pub; |
| 3595 | 3645 | decl.is_exported = is_exported; |
| 3596 | | decl.zir_block_index = decl_index; |
| 3597 | | decl.zir_align_ref = align_inst; |
| 3598 | | decl.zir_linksection_ref = section_inst; |
| 3599 | | if (deleted_decls.swapRemove(decl) == null) { |
| 3646 | decl.has_align = has_align; |
| 3647 | decl.has_linksection = has_linksection; |
| 3648 | decl.zir_decl_index = @intCast(u32, decl_sub_index); |
| 3649 | if (iter.deleted_decls.swapRemove(decl) == null) { |
| 3600 | 3650 | if (true) { |
| 3601 | 3651 | @panic("TODO I think this code path is unreachable; should be caught by AstGen."); |
| 3602 | 3652 | } |
| ... | ... | @@ -3615,8 +3665,11 @@ fn scanDecl( |
| 3615 | 3665 | try mod.errNoteNonLazy(other_src_loc, msg, "previously declared here", .{}); |
| 3616 | 3666 | try mod.failed_decls.putNoClobber(gpa, decl, msg); |
| 3617 | 3667 | } else { |
| 3668 | if (true) { |
| 3669 | @panic("TODO reimplement scanDecl with regards to incremental compilation."); |
| 3670 | } |
| 3618 | 3671 | if (!std.zig.srcHashEql(decl.contents_hash, contents_hash)) { |
| 3619 | | try outdated_decls.put(decl, {}); |
| 3672 | try iter.outdated_decls.put(decl, {}); |
| 3620 | 3673 | decl.contents_hash = contents_hash; |
| 3621 | 3674 | } else if (try decl.isFunction()) switch (mod.comp.bin_file.tag) { |
| 3622 | 3675 | .coff => { |
| ... | ... | @@ -3848,8 +3901,7 @@ fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: ast.Node |
| 3848 | 3901 | .linksection_val = undefined, |
| 3849 | 3902 | .analysis = .unreferenced, |
| 3850 | 3903 | .deletion_flag = false, |
| 3851 | | .contents_hash = undefined, |
| 3852 | | .zir_block_index = undefined, |
| 3904 | .zir_decl_index = undefined, |
| 3853 | 3905 | .link = switch (mod.comp.bin_file.tag) { |
| 3854 | 3906 | .coff => .{ .coff = link.File.Coff.TextBlock.empty }, |
| 3855 | 3907 | .elf => .{ .elf = link.File.Elf.TextBlock.empty }, |
| ... | ... | @@ -3869,6 +3921,8 @@ fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: ast.Node |
| 3869 | 3921 | .generation = 0, |
| 3870 | 3922 | .is_pub = false, |
| 3871 | 3923 | .is_exported = false, |
| 3924 | .has_linksection = false, |
| 3925 | .has_align = false, |
| 3872 | 3926 | }; |
| 3873 | 3927 | return new_decl; |
| 3874 | 3928 | } |
| ... | ... | @@ -4602,3 +4656,16 @@ pub fn getTarget(mod: Module) Target { |
| 4602 | 4656 | pub fn optimizeMode(mod: Module) std.builtin.Mode { |
| 4603 | 4657 | return mod.comp.bin_file.options.optimize_mode; |
| 4604 | 4658 | } |
| 4659 | |
| 4660 | fn lockAndClearFileCompileError(mod: *Module, file: *Scope.File) void { |
| 4661 | switch (file.status) { |
| 4662 | .success, .retryable_failure => {}, |
| 4663 | .never_loaded, .parse_failure, .astgen_failure => { |
| 4664 | const lock = mod.comp.mutex.acquire(); |
| 4665 | defer lock.release(); |
| 4666 | if (mod.failed_files.swapRemove(file)) |entry| { |
| 4667 | if (entry.value) |msg| msg.destroy(mod.gpa); // Delete previous error message. |
| 4668 | } |
| 4669 | }, |
| 4670 | } |
| 4671 | } |