| ... | ... | @@ -350,7 +350,7 @@ const Scope = struct { |
| 350 | 350 | parent: ?*Scope, |
| 351 | 351 | map: std.AutoHashMapUnmanaged( |
| 352 | 352 | u32, // index into the current file's string table (decl name) |
| 353 | | DeclStatus, |
| 353 | *DeclStatus, |
| 354 | 354 | ) = .{}, |
| 355 | 355 | |
| 356 | 356 | enclosing_type: usize, // index into `types` |
| ... | ... | @@ -359,15 +359,17 @@ const Scope = struct { |
| 359 | 359 | Analyzed: usize, // index into `decls` |
| 360 | 360 | Pending, |
| 361 | 361 | NotRequested: u32, // instr_index |
| 362 | | |
| 363 | 362 | }; |
| 364 | 363 | |
| 365 | 364 | /// Returns a pointer so that the caller has a chance to modify the value |
| 366 | 365 | /// in case they decide to start analyzing a previously not requested decl. |
| 366 | /// Another reason is that in some places we use the pointer to uniquely |
| 367 | /// refer to a decl, as we wait for it to be analyzed. This means that |
| 368 | /// those pointers must stay stable. |
| 367 | 369 | pub fn resolveDeclName(self: Scope, string_table_idx: u32, file: *File, inst_index: usize) *DeclStatus { |
| 368 | 370 | var cur: ?*const Scope = &self; |
| 369 | 371 | return while (cur) |s| : (cur = s.parent) { |
| 370 | | break s.map.getPtr(string_table_idx) orelse continue; |
| 372 | break s.map.get(string_table_idx) orelse continue; |
| 371 | 373 | } else { |
| 372 | 374 | printWithContext( |
| 373 | 375 | file, |
| ... | ... | @@ -385,7 +387,11 @@ const Scope = struct { |
| 385 | 387 | decl_name_index: u32, // index into the current file's string table |
| 386 | 388 | decl_status: DeclStatus, |
| 387 | 389 | ) !void { |
| 388 | | try self.map.put(arena, decl_name_index, decl_status); |
| 390 | const decl_status_ptr = try arena.create(DeclStatus); |
| 391 | errdefer arena.destroy(decl_status_ptr); |
| 392 | |
| 393 | decl_status_ptr.* = decl_status; |
| 394 | try self.map.put(arena, decl_name_index, decl_status_ptr); |
| 389 | 395 | } |
| 390 | 396 | }; |
| 391 | 397 | |